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 // Transformation function, extract the upper 32bit of a 64bit immediate
25 def HI32 : SDNodeXForm<imm, [{
26 return CurDAG->getTargetConstant(N->getZExtValue() >> 32, MVT::i32);
29 def SIbuffer_store : SDNode<"AMDGPUISD::BUFFER_STORE",
30 SDTypeProfile<0, 3, [SDTCisPtrTy<1>, SDTCisInt<2>]>,
31 [SDNPHasChain, SDNPMayStore]>;
33 def IMM8bitDWORD : ImmLeaf <
35 return (Imm & ~0x3FC) == 0;
36 }], SDNodeXForm<imm, [{
37 return CurDAG->getTargetConstant(
38 N->getZExtValue() >> 2, MVT::i32);
42 def IMM12bit : ImmLeaf <
44 [{return isUInt<12>(Imm);}]
47 class InlineImm <ValueType vt> : PatLeaf <(vt imm), [{
48 return ((const SITargetLowering &)TLI).analyzeImmediate(N) == 0;
51 //===----------------------------------------------------------------------===//
52 // SI assembler operands
53 //===----------------------------------------------------------------------===//
60 include "SIInstrFormats.td"
62 //===----------------------------------------------------------------------===//
64 // SI Instruction multiclass helpers.
66 // Instructions with _32 take 32-bit operands.
67 // Instructions with _64 take 64-bit operands.
69 // VOP_* instructions can use either a 32-bit or 64-bit encoding. The 32-bit
70 // encoding is the standard encoding, but instruction that make use of
71 // any of the instruction modifiers must use the 64-bit encoding.
73 // Instructions with _e32 use the 32-bit encoding.
74 // Instructions with _e64 use the 64-bit encoding.
76 //===----------------------------------------------------------------------===//
78 //===----------------------------------------------------------------------===//
80 //===----------------------------------------------------------------------===//
82 class SOP1_32 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
83 op, (outs SReg_32:$dst), (ins SSrc_32:$src0),
84 opName#" $dst, $src0", pattern
87 class SOP1_64 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
88 op, (outs SReg_64:$dst), (ins SSrc_64:$src0),
89 opName#" $dst, $src0", pattern
92 class SOP2_32 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
93 op, (outs SReg_32:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
94 opName#" $dst, $src0, $src1", pattern
97 class SOP2_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
98 op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
99 opName#" $dst, $src0, $src1", pattern
102 class SOPC_32 <bits<7> op, string opName, list<dag> pattern> : SOPC <
103 op, (outs SCCReg:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
104 opName#" $dst, $src0, $src1", pattern
107 class SOPC_64 <bits<7> op, string opName, list<dag> pattern> : SOPC <
108 op, (outs SCCReg:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
109 opName#" $dst, $src0, $src1", pattern
112 class SOPK_32 <bits<5> op, string opName, list<dag> pattern> : SOPK <
113 op, (outs SReg_32:$dst), (ins i16imm:$src0),
114 opName#" $dst, $src0", pattern
117 class SOPK_64 <bits<5> op, string opName, list<dag> pattern> : SOPK <
118 op, (outs SReg_64:$dst), (ins i16imm:$src0),
119 opName#" $dst, $src0", pattern
122 multiclass SMRD_Helper <bits<5> op, string asm, RegisterClass baseClass,
123 RegisterClass dstClass> {
125 op, 1, (outs dstClass:$dst),
126 (ins baseClass:$sbase, i32imm:$offset),
127 asm#" $dst, $sbase, $offset", []
131 op, 0, (outs dstClass:$dst),
132 (ins baseClass:$sbase, SReg_32:$soff),
133 asm#" $dst, $sbase, $soff", []
137 //===----------------------------------------------------------------------===//
138 // Vector ALU classes
139 //===----------------------------------------------------------------------===//
141 class VOP <string opName> {
142 string OpName = opName;
145 class VOP2_REV <string revOp, bit isOrig> {
146 string RevOp = revOp;
150 multiclass VOP1_Helper <bits<8> op, RegisterClass drc, RegisterClass src,
151 string opName, list<dag> pattern> {
154 op, (outs drc:$dst), (ins src:$src0),
155 opName#"_e32 $dst, $src0", pattern
159 {1, 1, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
162 i32imm:$abs, i32imm:$clamp,
163 i32imm:$omod, i32imm:$neg),
164 opName#"_e64 $dst, $src0, $abs, $clamp, $omod, $neg", []
166 let src1 = SIOperand.ZERO;
167 let src2 = SIOperand.ZERO;
171 multiclass VOP1_32 <bits<8> op, string opName, list<dag> pattern>
172 : VOP1_Helper <op, VReg_32, VSrc_32, opName, pattern>;
174 multiclass VOP1_64 <bits<8> op, string opName, list<dag> pattern>
175 : VOP1_Helper <op, VReg_64, VSrc_64, opName, pattern>;
177 multiclass VOP2_Helper <bits<6> op, RegisterClass vrc, RegisterClass arc,
178 string opName, list<dag> pattern, string revOp> {
180 op, (outs vrc:$dst), (ins arc:$src0, vrc:$src1),
181 opName#"_e32 $dst, $src0, $src1", pattern
182 >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
185 {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
187 (ins arc:$src0, arc:$src1,
188 i32imm:$abs, i32imm:$clamp,
189 i32imm:$omod, i32imm:$neg),
190 opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg", []
191 >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
192 let src2 = SIOperand.ZERO;
196 multiclass VOP2_32 <bits<6> op, string opName, list<dag> pattern,
197 string revOp = opName>
198 : VOP2_Helper <op, VReg_32, VSrc_32, opName, pattern, revOp>;
200 multiclass VOP2_64 <bits<6> op, string opName, list<dag> pattern,
201 string revOp = opName>
202 : VOP2_Helper <op, VReg_64, VSrc_64, opName, pattern, revOp>;
204 multiclass VOP2b_32 <bits<6> op, string opName, list<dag> pattern,
205 string revOp = opName> {
208 op, (outs VReg_32:$dst), (ins VSrc_32:$src0, VReg_32:$src1),
209 opName#"_e32 $dst, $src0, $src1", pattern
210 >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
213 {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
215 (ins VSrc_32:$src0, VSrc_32:$src1,
216 i32imm:$abs, i32imm:$clamp,
217 i32imm:$omod, i32imm:$neg),
218 opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg", []
219 >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
220 let src2 = SIOperand.ZERO;
221 /* the VOP2 variant puts the carry out into VCC, the VOP3 variant
222 can write it into any SGPR. We currently don't use the carry out,
223 so for now hardcode it to VCC as well */
224 let sdst = SIOperand.VCC;
228 multiclass VOPC_Helper <bits<8> op, RegisterClass vrc, RegisterClass arc,
229 string opName, ValueType vt, PatLeaf cond> {
232 op, (ins arc:$src0, vrc:$src1),
233 opName#"_e32 $dst, $src0, $src1", []
237 {0, op{7}, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
239 (ins arc:$src0, arc:$src1,
240 InstFlag:$abs, InstFlag:$clamp,
241 InstFlag:$omod, InstFlag:$neg),
242 opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg",
243 !if(!eq(!cast<string>(cond), "COND_NULL"), []<dag>,
244 [(set SReg_64:$dst, (i1 (setcc (vt arc:$src0), arc:$src1, cond)))]
247 let src2 = SIOperand.ZERO;
251 multiclass VOPC_32 <bits<8> op, string opName,
252 ValueType vt = untyped, PatLeaf cond = COND_NULL>
253 : VOPC_Helper <op, VReg_32, VSrc_32, opName, vt, cond>;
255 multiclass VOPC_64 <bits<8> op, string opName,
256 ValueType vt = untyped, PatLeaf cond = COND_NULL>
257 : VOPC_Helper <op, VReg_64, VSrc_64, opName, vt, cond>;
259 class VOP3_32 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
260 op, (outs VReg_32:$dst),
261 (ins VSrc_32:$src0, VSrc_32:$src1, VSrc_32:$src2,
262 InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg),
263 opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
266 class VOP3_64_Shift <bits <9> op, string opName, list<dag> pattern> : VOP3 <
267 op, (outs VReg_64:$dst),
268 (ins VSrc_64:$src0, VSrc_32:$src1),
269 opName#" $dst, $src0, $src1", pattern
272 let src2 = SIOperand.ZERO;
279 class VOP3_64 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
280 op, (outs VReg_64:$dst),
281 (ins VSrc_64:$src0, VSrc_64:$src1, VSrc_64:$src2,
282 InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg),
283 opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
286 //===----------------------------------------------------------------------===//
287 // Vector I/O classes
288 //===----------------------------------------------------------------------===//
290 class MTBUF_Store_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
293 (ins regClass:$vdata, i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
294 i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr,
295 SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
296 asm#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
297 #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
303 multiclass MUBUF_Load_Helper <bits<7> op, string asm, RegisterClass regClass> {
305 let glc = 0, lds = 0, slc = 0, tfe = 0, soffset = 128 /* ZERO */,
308 let offen = 1, idxen = 0, addr64 = 0, offset = 0 in {
309 def _OFFEN : MUBUF <op, (outs regClass:$vdata),
310 (ins SReg_128:$srsrc, VReg_32:$vaddr),
311 asm#" $vdata, $srsrc + $vaddr", []>;
314 let offen = 0, idxen = 1, addr64 = 0 in {
315 def _IDXEN : MUBUF <op, (outs regClass:$vdata),
316 (ins SReg_128:$srsrc, VReg_32:$vaddr, i16imm:$offset),
317 asm#" $vdata, $srsrc[$vaddr] + $offset", []>;
320 let offen = 0, idxen = 0, addr64 = 1 in {
321 def _ADDR64 : MUBUF <op, (outs regClass:$vdata),
322 (ins SReg_128:$srsrc, VReg_64:$vaddr, i16imm:$offset),
323 asm#" $vdata, $srsrc + $vaddr + $offset", []>;
328 class MUBUF_Store_Helper <bits<7> op, string name, RegisterClass vdataClass,
330 MUBUF <op, (outs), (ins vdataClass:$vdata, SReg_128:$srsrc, VReg_64:$vaddr),
331 name#" $vdata, $srsrc + $vaddr",
332 [(SIbuffer_store (VT vdataClass:$vdata), (i128 SReg_128:$srsrc),
333 (i64 VReg_64:$vaddr))]> {
347 let soffset = 128; // ZERO
350 class MTBUF_Load_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
352 (outs regClass:$dst),
353 (ins i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
354 i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, SReg_128:$srsrc,
355 i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
356 asm#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
357 #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
363 class MIMG_NoSampler_Helper <bits<7> op, string asm> : MIMG <
365 (outs VReg_128:$vdata),
366 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
367 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, unknown:$vaddr,
369 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
370 #" $tfe, $lwe, $slc, $vaddr, $srsrc",
375 let hasPostISelHook = 1;
378 class MIMG_Sampler_Helper <bits<7> op, string asm> : MIMG <
380 (outs VReg_128:$vdata),
381 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
382 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, unknown:$vaddr,
383 SReg_256:$srsrc, SReg_128:$ssamp),
384 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
385 #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
389 let hasPostISelHook = 1;
392 //===----------------------------------------------------------------------===//
393 // Vector instruction mappings
394 //===----------------------------------------------------------------------===//
396 // Maps an opcode in e32 form to its e64 equivalent
397 def getVOPe64 : InstrMapping {
398 let FilterClass = "VOP";
399 let RowFields = ["OpName"];
400 let ColFields = ["Size"];
402 let ValueCols = [["8"]];
405 // Maps an original opcode to its commuted version
406 def getCommuteRev : InstrMapping {
407 let FilterClass = "VOP2_REV";
408 let RowFields = ["RevOp"];
409 let ColFields = ["IsOrig"];
411 let ValueCols = [["0"]];
414 // Maps an commuted opcode to its original version
415 def getCommuteOrig : InstrMapping {
416 let FilterClass = "VOP2_REV";
417 let RowFields = ["RevOp"];
418 let ColFields = ["IsOrig"];
420 let ValueCols = [["1"]];
423 // Test if the supplied opcode is an MIMG instruction
424 def isMIMG : InstrMapping {
425 let FilterClass = "MIMG";
426 let RowFields = ["Inst"];
427 let ColFields = ["Size"];
429 let ValueCols = [["8"]];
432 include "SIInstructions.td"