1 //===-- SIInstrInfo.td - SI Instruction Infos -------------*- tablegen -*--===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 //===----------------------------------------------------------------------===//
12 //===----------------------------------------------------------------------===//
14 // SMRD takes a 64bit memory address and can only add an 32bit offset
15 def SIadd64bit32bit : SDNode<"ISD::ADD",
16 SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>, SDTCisVT<0, i64>, SDTCisVT<2, i32>]>
19 // Transformation function, extract the lower 32bit of a 64bit immediate
20 def LO32 : SDNodeXForm<imm, [{
21 return CurDAG->getTargetConstant(N->getZExtValue() & 0xffffffff, MVT::i32);
24 def LO32f : SDNodeXForm<fpimm, [{
25 APInt V = N->getValueAPF().bitcastToAPInt().trunc(32);
26 return CurDAG->getTargetConstantFP(APFloat(APFloat::IEEEsingle, V), MVT::f32);
29 // Transformation function, extract the upper 32bit of a 64bit immediate
30 def HI32 : SDNodeXForm<imm, [{
31 return CurDAG->getTargetConstant(N->getZExtValue() >> 32, MVT::i32);
34 def HI32f : SDNodeXForm<fpimm, [{
35 APInt V = N->getValueAPF().bitcastToAPInt().lshr(32).trunc(32);
36 return CurDAG->getTargetConstantFP(APFloat(APFloat::IEEEsingle, V), MVT::f32);
39 def IMM8bitDWORD : ImmLeaf <
41 return (Imm & ~0x3FC) == 0;
42 }], SDNodeXForm<imm, [{
43 return CurDAG->getTargetConstant(
44 N->getZExtValue() >> 2, MVT::i32);
48 def as_i16imm : SDNodeXForm<imm, [{
49 return CurDAG->getTargetConstant(N->getSExtValue(), MVT::i16);
52 def IMM12bit : PatLeaf <(imm),
53 [{return isUInt<12>(N->getZExtValue());}]
56 class InlineImm <ValueType vt> : PatLeaf <(vt imm), [{
58 (*(const SITargetLowering *)getTargetLowering()).analyzeImmediate(N) == 0;
61 //===----------------------------------------------------------------------===//
62 // SI assembler operands
63 //===----------------------------------------------------------------------===//
70 include "SIInstrFormats.td"
72 //===----------------------------------------------------------------------===//
74 // SI Instruction multiclass helpers.
76 // Instructions with _32 take 32-bit operands.
77 // Instructions with _64 take 64-bit operands.
79 // VOP_* instructions can use either a 32-bit or 64-bit encoding. The 32-bit
80 // encoding is the standard encoding, but instruction that make use of
81 // any of the instruction modifiers must use the 64-bit encoding.
83 // Instructions with _e32 use the 32-bit encoding.
84 // Instructions with _e64 use the 64-bit encoding.
86 //===----------------------------------------------------------------------===//
88 //===----------------------------------------------------------------------===//
90 //===----------------------------------------------------------------------===//
92 class SOP1_32 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
93 op, (outs SReg_32:$dst), (ins SSrc_32:$src0),
94 opName#" $dst, $src0", pattern
97 class SOP1_64 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
98 op, (outs SReg_64:$dst), (ins SSrc_64:$src0),
99 opName#" $dst, $src0", pattern
102 class SOP2_32 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
103 op, (outs SReg_32:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
104 opName#" $dst, $src0, $src1", pattern
107 class SOP2_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
108 op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
109 opName#" $dst, $src0, $src1", pattern
112 class SOPC_32 <bits<7> op, string opName, list<dag> pattern> : SOPC <
113 op, (outs SCCReg:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
114 opName#" $dst, $src0, $src1", pattern
117 class SOPC_64 <bits<7> op, string opName, list<dag> pattern> : SOPC <
118 op, (outs SCCReg:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
119 opName#" $dst, $src0, $src1", pattern
122 class SOPK_32 <bits<5> op, string opName, list<dag> pattern> : SOPK <
123 op, (outs SReg_32:$dst), (ins i16imm:$src0),
124 opName#" $dst, $src0", pattern
127 class SOPK_64 <bits<5> op, string opName, list<dag> pattern> : SOPK <
128 op, (outs SReg_64:$dst), (ins i16imm:$src0),
129 opName#" $dst, $src0", pattern
132 multiclass SMRD_Helper <bits<5> op, string asm, RegisterClass baseClass,
133 RegisterClass dstClass> {
135 op, 1, (outs dstClass:$dst),
136 (ins baseClass:$sbase, i32imm:$offset),
137 asm#" $dst, $sbase, $offset", []
141 op, 0, (outs dstClass:$dst),
142 (ins baseClass:$sbase, SReg_32:$soff),
143 asm#" $dst, $sbase, $soff", []
147 //===----------------------------------------------------------------------===//
148 // Vector ALU classes
149 //===----------------------------------------------------------------------===//
151 class VOP <string opName> {
152 string OpName = opName;
155 class VOP2_REV <string revOp, bit isOrig> {
156 string RevOp = revOp;
160 multiclass VOP1_Helper <bits<8> op, RegisterClass drc, RegisterClass src,
161 string opName, list<dag> pattern> {
164 op, (outs drc:$dst), (ins src:$src0),
165 opName#"_e32 $dst, $src0", pattern
169 {1, 1, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
172 i32imm:$abs, i32imm:$clamp,
173 i32imm:$omod, i32imm:$neg),
174 opName#"_e64 $dst, $src0, $abs, $clamp, $omod, $neg", []
176 let src1 = SIOperand.ZERO;
177 let src2 = SIOperand.ZERO;
181 multiclass VOP1_32 <bits<8> op, string opName, list<dag> pattern>
182 : VOP1_Helper <op, VReg_32, VSrc_32, opName, pattern>;
184 multiclass VOP1_64 <bits<8> op, string opName, list<dag> pattern>
185 : VOP1_Helper <op, VReg_64, VSrc_64, opName, pattern>;
187 multiclass VOP1_32_64 <bits<8> op, string opName, list<dag> pattern>
188 : VOP1_Helper <op, VReg_32, VSrc_64, opName, pattern>;
190 multiclass VOP1_64_32 <bits<8> op, string opName, list<dag> pattern>
191 : VOP1_Helper <op, VReg_64, VSrc_32, opName, pattern>;
193 multiclass VOP2_Helper <bits<6> op, RegisterClass vrc, RegisterClass arc,
194 string opName, list<dag> pattern, string revOp> {
196 op, (outs vrc:$dst), (ins arc:$src0, vrc:$src1),
197 opName#"_e32 $dst, $src0, $src1", pattern
198 >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
201 {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
203 (ins arc:$src0, arc:$src1,
204 i32imm:$abs, i32imm:$clamp,
205 i32imm:$omod, i32imm:$neg),
206 opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg", []
207 >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
208 let src2 = SIOperand.ZERO;
212 multiclass VOP2_32 <bits<6> op, string opName, list<dag> pattern,
213 string revOp = opName>
214 : VOP2_Helper <op, VReg_32, VSrc_32, opName, pattern, revOp>;
216 multiclass VOP2_64 <bits<6> op, string opName, list<dag> pattern,
217 string revOp = opName>
218 : VOP2_Helper <op, VReg_64, VSrc_64, opName, pattern, revOp>;
220 multiclass VOP2b_32 <bits<6> op, string opName, list<dag> pattern,
221 string revOp = opName> {
224 op, (outs VReg_32:$dst), (ins VSrc_32:$src0, VReg_32:$src1),
225 opName#"_e32 $dst, $src0, $src1", pattern
226 >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
229 {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
231 (ins VSrc_32:$src0, VSrc_32:$src1,
232 i32imm:$abs, i32imm:$clamp,
233 i32imm:$omod, i32imm:$neg),
234 opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg", []
235 >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
236 let src2 = SIOperand.ZERO;
237 /* the VOP2 variant puts the carry out into VCC, the VOP3 variant
238 can write it into any SGPR. We currently don't use the carry out,
239 so for now hardcode it to VCC as well */
240 let sdst = SIOperand.VCC;
244 multiclass VOPC_Helper <bits<8> op, RegisterClass vrc, RegisterClass arc,
245 string opName, ValueType vt, PatLeaf cond> {
248 op, (ins arc:$src0, vrc:$src1),
249 opName#"_e32 $dst, $src0, $src1", []
253 {0, op{7}, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
255 (ins arc:$src0, arc:$src1,
256 InstFlag:$abs, InstFlag:$clamp,
257 InstFlag:$omod, InstFlag:$neg),
258 opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg",
259 !if(!eq(!cast<string>(cond), "COND_NULL"), []<dag>,
260 [(set SReg_64:$dst, (i1 (setcc (vt arc:$src0), arc:$src1, cond)))]
263 let src2 = SIOperand.ZERO;
267 multiclass VOPC_32 <bits<8> op, string opName,
268 ValueType vt = untyped, PatLeaf cond = COND_NULL>
269 : VOPC_Helper <op, VReg_32, VSrc_32, opName, vt, cond>;
271 multiclass VOPC_64 <bits<8> op, string opName,
272 ValueType vt = untyped, PatLeaf cond = COND_NULL>
273 : VOPC_Helper <op, VReg_64, VSrc_64, opName, vt, cond>;
275 class VOP3_32 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
276 op, (outs VReg_32:$dst),
277 (ins VSrc_32:$src0, VSrc_32:$src1, VSrc_32:$src2,
278 InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg),
279 opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
282 class VOP3_64_Shift <bits <9> op, string opName, list<dag> pattern> : VOP3 <
283 op, (outs VReg_64:$dst),
284 (ins VSrc_64:$src0, VSrc_32:$src1),
285 opName#" $dst, $src0, $src1", pattern
288 let src2 = SIOperand.ZERO;
295 class VOP3_64 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
296 op, (outs VReg_64:$dst),
297 (ins VSrc_64:$src0, VSrc_64:$src1, VSrc_64:$src2,
298 InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg),
299 opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
302 //===----------------------------------------------------------------------===//
303 // Vector I/O classes
304 //===----------------------------------------------------------------------===//
306 class DS_Load_Helper <bits<8> op, string asm, RegisterClass regClass> : DS <
308 (outs regClass:$vdst),
309 (ins i1imm:$gds, VReg_32:$addr, VReg_32:$data0, VReg_32:$data1,
310 i8imm:$offset0, i8imm:$offset1),
311 asm#" $vdst, $gds, $addr, $data0, $data1, $offset0, $offset1, [M0]",
317 class DS_Store_Helper <bits<8> op, string asm, RegisterClass regClass> : DS <
320 (ins i1imm:$gds, VReg_32:$addr, VReg_32:$data0, VReg_32:$data1,
321 i8imm:$offset0, i8imm:$offset1),
322 asm#" $gds, $addr, $data0, $data1, $offset0, $offset1, [M0]",
329 class MTBUF_Store_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
332 (ins regClass:$vdata, i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
333 i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr,
334 SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
335 asm#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
336 #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
342 multiclass MUBUF_Load_Helper <bits<7> op, string asm, RegisterClass regClass> {
344 let glc = 0, lds = 0, slc = 0, tfe = 0, soffset = 128 /* ZERO */,
347 let offen = 1, idxen = 0, addr64 = 0, offset = 0 in {
348 def _OFFEN : MUBUF <op, (outs regClass:$vdata),
349 (ins SReg_128:$srsrc, VReg_32:$vaddr),
350 asm#" $vdata, $srsrc + $vaddr", []>;
353 let offen = 0, idxen = 1, addr64 = 0 in {
354 def _IDXEN : MUBUF <op, (outs regClass:$vdata),
355 (ins SReg_128:$srsrc, VReg_32:$vaddr, i16imm:$offset),
356 asm#" $vdata, $srsrc[$vaddr] + $offset", []>;
359 let offen = 0, idxen = 0, addr64 = 1 in {
360 def _ADDR64 : MUBUF <op, (outs regClass:$vdata),
361 (ins SReg_128:$srsrc, VReg_64:$vaddr, i16imm:$offset),
362 asm#" $vdata, $srsrc + $vaddr + $offset", []>;
367 class MUBUF_Store_Helper <bits<7> op, string name, RegisterClass vdataClass,
369 MUBUF <op, (outs), (ins vdataClass:$vdata, SReg_128:$srsrc, VReg_64:$vaddr, i16imm:$offset),
370 name#" $vdata, $srsrc + $vaddr + $offset",
384 let soffset = 128; // ZERO
387 class MTBUF_Load_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
389 (outs regClass:$dst),
390 (ins i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
391 i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, SReg_128:$srsrc,
392 i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
393 asm#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
394 #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
400 class MIMG_NoSampler_Helper <bits<7> op, string asm> : MIMG <
402 (outs VReg_128:$vdata),
403 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
404 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, unknown:$vaddr,
406 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
407 #" $tfe, $lwe, $slc, $vaddr, $srsrc",
412 let hasPostISelHook = 1;
415 class MIMG_Sampler_Helper <bits<7> op, string asm> : MIMG <
417 (outs VReg_128:$vdata),
418 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
419 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, unknown:$vaddr,
420 SReg_256:$srsrc, SReg_128:$ssamp),
421 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
422 #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
426 let hasPostISelHook = 1;
429 //===----------------------------------------------------------------------===//
430 // Vector instruction mappings
431 //===----------------------------------------------------------------------===//
433 // Maps an opcode in e32 form to its e64 equivalent
434 def getVOPe64 : InstrMapping {
435 let FilterClass = "VOP";
436 let RowFields = ["OpName"];
437 let ColFields = ["Size"];
439 let ValueCols = [["8"]];
442 // Maps an original opcode to its commuted version
443 def getCommuteRev : InstrMapping {
444 let FilterClass = "VOP2_REV";
445 let RowFields = ["RevOp"];
446 let ColFields = ["IsOrig"];
448 let ValueCols = [["0"]];
451 // Maps an commuted opcode to its original version
452 def getCommuteOrig : InstrMapping {
453 let FilterClass = "VOP2_REV";
454 let RowFields = ["RevOp"];
455 let ColFields = ["IsOrig"];
457 let ValueCols = [["1"]];
460 // Test if the supplied opcode is an MIMG instruction
461 def isMIMG : InstrMapping {
462 let FilterClass = "MIMG";
463 let RowFields = ["Inst"];
464 let ColFields = ["Size"];
466 let ValueCols = [["8"]];
469 include "SIInstructions.td"