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 def SIload_constant : SDNode<"AMDGPUISD::LOAD_CONSTANT",
20 SDTypeProfile<1, 2, [SDTCisVT<0, f32>, SDTCisVT<1, i128>, SDTCisVT<2, i32>]>,
21 [SDNPMayLoad, SDNPMemOperand]
24 def SItbuffer_store : SDNode<"AMDGPUISD::TBUFFER_STORE_FORMAT",
26 [SDTCisVT<0, i128>, // rsrc(SGPR)
27 SDTCisVT<1, iAny>, // vdata(VGPR)
28 SDTCisVT<2, i32>, // num_channels(imm)
29 SDTCisVT<3, i32>, // vaddr(VGPR)
30 SDTCisVT<4, i32>, // soffset(SGPR)
31 SDTCisVT<5, i32>, // inst_offset(imm)
32 SDTCisVT<6, i32>, // dfmt(imm)
33 SDTCisVT<7, i32>, // nfmt(imm)
34 SDTCisVT<8, i32>, // offen(imm)
35 SDTCisVT<9, i32>, // idxen(imm)
36 SDTCisVT<10, i32>, // glc(imm)
37 SDTCisVT<11, i32>, // slc(imm)
38 SDTCisVT<12, i32> // tfe(imm)
40 [SDNPMayStore, SDNPMemOperand, SDNPHasChain]
43 def SIload_input : SDNode<"AMDGPUISD::LOAD_INPUT",
44 SDTypeProfile<1, 3, [SDTCisVT<0, v4f32>, SDTCisVT<1, i128>, SDTCisVT<2, i16>,
48 class SDSample<string opcode> : SDNode <opcode,
49 SDTypeProfile<1, 4, [SDTCisVT<0, v4f32>, SDTCisVT<2, v32i8>,
50 SDTCisVT<3, i128>, SDTCisVT<4, i32>]>
53 def SIsample : SDSample<"AMDGPUISD::SAMPLE">;
54 def SIsampleb : SDSample<"AMDGPUISD::SAMPLEB">;
55 def SIsampled : SDSample<"AMDGPUISD::SAMPLED">;
56 def SIsamplel : SDSample<"AMDGPUISD::SAMPLEL">;
58 // Transformation function, extract the lower 32bit of a 64bit immediate
59 def LO32 : SDNodeXForm<imm, [{
60 return CurDAG->getTargetConstant(N->getZExtValue() & 0xffffffff, MVT::i32);
63 def LO32f : SDNodeXForm<fpimm, [{
64 APInt V = N->getValueAPF().bitcastToAPInt().trunc(32);
65 return CurDAG->getTargetConstantFP(APFloat(APFloat::IEEEsingle, V), MVT::f32);
68 // Transformation function, extract the upper 32bit of a 64bit immediate
69 def HI32 : SDNodeXForm<imm, [{
70 return CurDAG->getTargetConstant(N->getZExtValue() >> 32, MVT::i32);
73 def HI32f : SDNodeXForm<fpimm, [{
74 APInt V = N->getValueAPF().bitcastToAPInt().lshr(32).trunc(32);
75 return CurDAG->getTargetConstantFP(APFloat(APFloat::IEEEsingle, V), MVT::f32);
78 def IMM8bitDWORD : ImmLeaf <
80 return (Imm & ~0x3FC) == 0;
81 }], SDNodeXForm<imm, [{
82 return CurDAG->getTargetConstant(
83 N->getZExtValue() >> 2, MVT::i32);
87 def as_i1imm : SDNodeXForm<imm, [{
88 return CurDAG->getTargetConstant(N->getZExtValue(), MVT::i1);
91 def as_i8imm : SDNodeXForm<imm, [{
92 return CurDAG->getTargetConstant(N->getZExtValue(), MVT::i8);
95 def as_i16imm : SDNodeXForm<imm, [{
96 return CurDAG->getTargetConstant(N->getSExtValue(), MVT::i16);
99 def IMM12bit : PatLeaf <(imm),
100 [{return isUInt<12>(N->getZExtValue());}]
103 class InlineImm <ValueType vt> : PatLeaf <(vt imm), [{
105 (*(const SITargetLowering *)getTargetLowering()).analyzeImmediate(N) == 0;
108 class SGPRImm <dag frag> : PatLeaf<frag, [{
109 if (TM.getSubtarget<AMDGPUSubtarget>().getGeneration() <
110 AMDGPUSubtarget::SOUTHERN_ISLANDS) {
113 const SIRegisterInfo *SIRI =
114 static_cast<const SIRegisterInfo*>(TM.getRegisterInfo());
115 for (SDNode::use_iterator U = N->use_begin(), E = SDNode::use_end();
117 if (SIRI->isSGPRClass(getOperandRegClass(*U, U.getOperandNo()))) {
124 //===----------------------------------------------------------------------===//
125 // SI assembler operands
126 //===----------------------------------------------------------------------===//
133 include "SIInstrFormats.td"
135 //===----------------------------------------------------------------------===//
137 // SI Instruction multiclass helpers.
139 // Instructions with _32 take 32-bit operands.
140 // Instructions with _64 take 64-bit operands.
142 // VOP_* instructions can use either a 32-bit or 64-bit encoding. The 32-bit
143 // encoding is the standard encoding, but instruction that make use of
144 // any of the instruction modifiers must use the 64-bit encoding.
146 // Instructions with _e32 use the 32-bit encoding.
147 // Instructions with _e64 use the 64-bit encoding.
149 //===----------------------------------------------------------------------===//
151 //===----------------------------------------------------------------------===//
153 //===----------------------------------------------------------------------===//
155 class SOP1_32 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
156 op, (outs SReg_32:$dst), (ins SSrc_32:$src0),
157 opName#" $dst, $src0", pattern
160 class SOP1_64 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
161 op, (outs SReg_64:$dst), (ins SSrc_64:$src0),
162 opName#" $dst, $src0", pattern
165 class SOP2_32 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
166 op, (outs SReg_32:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
167 opName#" $dst, $src0, $src1", pattern
170 class SOP2_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
171 op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
172 opName#" $dst, $src0, $src1", pattern
175 class SOPC_32 <bits<7> op, string opName, list<dag> pattern> : SOPC <
176 op, (outs SCCReg:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
177 opName#" $dst, $src0, $src1", pattern
180 class SOPC_64 <bits<7> op, string opName, list<dag> pattern> : SOPC <
181 op, (outs SCCReg:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
182 opName#" $dst, $src0, $src1", pattern
185 class SOPK_32 <bits<5> op, string opName, list<dag> pattern> : SOPK <
186 op, (outs SReg_32:$dst), (ins i16imm:$src0),
187 opName#" $dst, $src0", pattern
190 class SOPK_64 <bits<5> op, string opName, list<dag> pattern> : SOPK <
191 op, (outs SReg_64:$dst), (ins i16imm:$src0),
192 opName#" $dst, $src0", pattern
195 multiclass SMRD_Helper <bits<5> op, string asm, RegisterClass baseClass,
196 RegisterClass dstClass> {
198 op, 1, (outs dstClass:$dst),
199 (ins baseClass:$sbase, i32imm:$offset),
200 asm#" $dst, $sbase, $offset", []
204 op, 0, (outs dstClass:$dst),
205 (ins baseClass:$sbase, SReg_32:$soff),
206 asm#" $dst, $sbase, $soff", []
210 //===----------------------------------------------------------------------===//
211 // Vector ALU classes
212 //===----------------------------------------------------------------------===//
214 class VOP <string opName> {
215 string OpName = opName;
218 class VOP2_REV <string revOp, bit isOrig> {
219 string RevOp = revOp;
223 multiclass VOP1_Helper <bits<8> op, RegisterClass drc, RegisterClass src,
224 string opName, list<dag> pattern> {
227 op, (outs drc:$dst), (ins src:$src0),
228 opName#"_e32 $dst, $src0", pattern
232 {1, 1, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
235 i32imm:$abs, i32imm:$clamp,
236 i32imm:$omod, i32imm:$neg),
237 opName#"_e64 $dst, $src0, $abs, $clamp, $omod, $neg", []
239 let src1 = SIOperand.ZERO;
240 let src2 = SIOperand.ZERO;
244 multiclass VOP1_32 <bits<8> op, string opName, list<dag> pattern>
245 : VOP1_Helper <op, VReg_32, VSrc_32, opName, pattern>;
247 multiclass VOP1_64 <bits<8> op, string opName, list<dag> pattern>
248 : VOP1_Helper <op, VReg_64, VSrc_64, opName, pattern>;
250 multiclass VOP1_32_64 <bits<8> op, string opName, list<dag> pattern>
251 : VOP1_Helper <op, VReg_32, VSrc_64, opName, pattern>;
253 multiclass VOP1_64_32 <bits<8> op, string opName, list<dag> pattern>
254 : VOP1_Helper <op, VReg_64, VSrc_32, opName, pattern>;
256 multiclass VOP2_Helper <bits<6> op, RegisterClass vrc, RegisterClass arc,
257 string opName, list<dag> pattern, string revOp> {
259 op, (outs vrc:$dst), (ins arc:$src0, vrc:$src1),
260 opName#"_e32 $dst, $src0, $src1", pattern
261 >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
264 {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
266 (ins arc:$src0, arc:$src1,
267 i32imm:$abs, i32imm:$clamp,
268 i32imm:$omod, i32imm:$neg),
269 opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg", []
270 >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
271 let src2 = SIOperand.ZERO;
275 multiclass VOP2_32 <bits<6> op, string opName, list<dag> pattern,
276 string revOp = opName>
277 : VOP2_Helper <op, VReg_32, VSrc_32, opName, pattern, revOp>;
279 multiclass VOP2_64 <bits<6> op, string opName, list<dag> pattern,
280 string revOp = opName>
281 : VOP2_Helper <op, VReg_64, VSrc_64, opName, pattern, revOp>;
283 multiclass VOP2b_32 <bits<6> op, string opName, list<dag> pattern,
284 string revOp = opName> {
287 op, (outs VReg_32:$dst), (ins VSrc_32:$src0, VReg_32:$src1),
288 opName#"_e32 $dst, $src0, $src1", pattern
289 >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
292 {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
294 (ins VSrc_32:$src0, VSrc_32:$src1,
295 i32imm:$abs, i32imm:$clamp,
296 i32imm:$omod, i32imm:$neg),
297 opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg", []
298 >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
299 let src2 = SIOperand.ZERO;
300 /* the VOP2 variant puts the carry out into VCC, the VOP3 variant
301 can write it into any SGPR. We currently don't use the carry out,
302 so for now hardcode it to VCC as well */
303 let sdst = SIOperand.VCC;
307 multiclass VOPC_Helper <bits<8> op, RegisterClass vrc, RegisterClass arc,
308 string opName, ValueType vt, PatLeaf cond> {
311 op, (ins arc:$src0, vrc:$src1),
312 opName#"_e32 $dst, $src0, $src1", []
316 {0, op{7}, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
318 (ins arc:$src0, arc:$src1,
319 InstFlag:$abs, InstFlag:$clamp,
320 InstFlag:$omod, InstFlag:$neg),
321 opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg",
322 !if(!eq(!cast<string>(cond), "COND_NULL"), []<dag>,
323 [(set SReg_64:$dst, (i1 (setcc (vt arc:$src0), arc:$src1, cond)))]
326 let src2 = SIOperand.ZERO;
330 multiclass VOPC_32 <bits<8> op, string opName,
331 ValueType vt = untyped, PatLeaf cond = COND_NULL>
332 : VOPC_Helper <op, VReg_32, VSrc_32, opName, vt, cond>;
334 multiclass VOPC_64 <bits<8> op, string opName,
335 ValueType vt = untyped, PatLeaf cond = COND_NULL>
336 : VOPC_Helper <op, VReg_64, VSrc_64, opName, vt, cond>;
338 class VOP3_32 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
339 op, (outs VReg_32:$dst),
340 (ins VSrc_32:$src0, VSrc_32:$src1, VSrc_32:$src2,
341 InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg),
342 opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
345 class VOP3_64_Shift <bits <9> op, string opName, list<dag> pattern> : VOP3 <
346 op, (outs VReg_64:$dst),
347 (ins VSrc_64:$src0, VSrc_32:$src1),
348 opName#" $dst, $src0, $src1", pattern
351 let src2 = SIOperand.ZERO;
358 class VOP3_64 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
359 op, (outs VReg_64:$dst),
360 (ins VSrc_64:$src0, VSrc_64:$src1, VSrc_64:$src2,
361 InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg),
362 opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
365 //===----------------------------------------------------------------------===//
366 // Vector I/O classes
367 //===----------------------------------------------------------------------===//
369 class DS_Load_Helper <bits<8> op, string asm, RegisterClass regClass> : DS <
371 (outs regClass:$vdst),
372 (ins i1imm:$gds, VReg_32:$addr, VReg_32:$data0, VReg_32:$data1,
373 i8imm:$offset0, i8imm:$offset1),
374 asm#" $vdst, $gds, $addr, $data0, $data1, $offset0, $offset1, [M0]",
380 class DS_Store_Helper <bits<8> op, string asm, RegisterClass regClass> : DS <
383 (ins i1imm:$gds, VReg_32:$addr, VReg_32:$data0, VReg_32:$data1,
384 i8imm:$offset0, i8imm:$offset1),
385 asm#" $gds, $addr, $data0, $data1, $offset0, $offset1, [M0]",
392 class DS_1A1D_RET <bits<8> op, string asm, RegisterClass rc> : DS <
395 (ins i1imm:$gds, VReg_32:$addr, VReg_32:$data0, i8imm:$offset0,
397 asm#" $gds, $vdst, $addr, $data0, $offset0, $offset1, [M0]",
404 class MTBUF_Store_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
407 (ins regClass:$vdata, i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
408 i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr,
409 SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
410 asm#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
411 #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
417 multiclass MUBUF_Load_Helper <bits<7> op, string asm, RegisterClass regClass> {
419 let glc = 0, lds = 0, slc = 0, tfe = 0, soffset = 128 /* ZERO */,
422 let offen = 1, idxen = 0, addr64 = 0, offset = 0 in {
423 def _OFFEN : MUBUF <op, (outs regClass:$vdata),
424 (ins SReg_128:$srsrc, VReg_32:$vaddr),
425 asm#" $vdata, $srsrc + $vaddr", []>;
428 let offen = 0, idxen = 1, addr64 = 0 in {
429 def _IDXEN : MUBUF <op, (outs regClass:$vdata),
430 (ins SReg_128:$srsrc, VReg_32:$vaddr, i16imm:$offset),
431 asm#" $vdata, $srsrc[$vaddr] + $offset", []>;
434 let offen = 0, idxen = 0, addr64 = 1 in {
435 def _ADDR64 : MUBUF <op, (outs regClass:$vdata),
436 (ins SReg_128:$srsrc, VReg_64:$vaddr, i16imm:$offset),
437 asm#" $vdata, $srsrc + $vaddr + $offset", []>;
442 class MUBUF_Store_Helper <bits<7> op, string name, RegisterClass vdataClass> :
443 MUBUF <op, (outs), (ins vdataClass:$vdata, SReg_128:$srsrc, VReg_64:$vaddr,
445 name#" $vdata, $srsrc + $vaddr + $offset",
459 let soffset = 128; // ZERO
462 class MTBUF_Load_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
464 (outs regClass:$dst),
465 (ins i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
466 i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, SReg_128:$srsrc,
467 i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
468 asm#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
469 #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
475 class MIMG_Mask <string op, int channels> {
477 int Channels = channels;
480 class MIMG_NoSampler_Helper <bits<7> op, string asm,
481 RegisterClass dst_rc,
482 RegisterClass src_rc> : MIMG <
484 (outs dst_rc:$vdata),
485 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
486 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
488 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
489 #" $tfe, $lwe, $slc, $vaddr, $srsrc",
494 let hasPostISelHook = 1;
497 multiclass MIMG_NoSampler_Src_Helper <bits<7> op, string asm,
498 RegisterClass dst_rc,
500 def _V1 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_32>,
501 MIMG_Mask<asm#"_V1", channels>;
502 def _V2 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_64>,
503 MIMG_Mask<asm#"_V2", channels>;
504 def _V4 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_128>,
505 MIMG_Mask<asm#"_V4", channels>;
508 multiclass MIMG_NoSampler <bits<7> op, string asm> {
509 defm _V1 : MIMG_NoSampler_Src_Helper <op, asm, VReg_32, 1>;
510 defm _V2 : MIMG_NoSampler_Src_Helper <op, asm, VReg_64, 2>;
511 defm _V3 : MIMG_NoSampler_Src_Helper <op, asm, VReg_96, 3>;
512 defm _V4 : MIMG_NoSampler_Src_Helper <op, asm, VReg_128, 4>;
515 class MIMG_Sampler_Helper <bits<7> op, string asm,
516 RegisterClass dst_rc,
517 RegisterClass src_rc> : MIMG <
519 (outs dst_rc:$vdata),
520 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
521 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
522 SReg_256:$srsrc, SReg_128:$ssamp),
523 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
524 #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
528 let hasPostISelHook = 1;
531 multiclass MIMG_Sampler_Src_Helper <bits<7> op, string asm,
532 RegisterClass dst_rc,
534 def _V1 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_32>,
535 MIMG_Mask<asm#"_V1", channels>;
536 def _V2 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_64>,
537 MIMG_Mask<asm#"_V2", channels>;
538 def _V4 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_128>,
539 MIMG_Mask<asm#"_V4", channels>;
540 def _V8 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_256>,
541 MIMG_Mask<asm#"_V8", channels>;
542 def _V16 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_512>,
543 MIMG_Mask<asm#"_V16", channels>;
546 multiclass MIMG_Sampler <bits<7> op, string asm> {
547 defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VReg_32, 1>;
548 defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2>;
549 defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3>;
550 defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4>;
553 //===----------------------------------------------------------------------===//
554 // Vector instruction mappings
555 //===----------------------------------------------------------------------===//
557 // Maps an opcode in e32 form to its e64 equivalent
558 def getVOPe64 : InstrMapping {
559 let FilterClass = "VOP";
560 let RowFields = ["OpName"];
561 let ColFields = ["Size"];
563 let ValueCols = [["8"]];
566 // Maps an original opcode to its commuted version
567 def getCommuteRev : InstrMapping {
568 let FilterClass = "VOP2_REV";
569 let RowFields = ["RevOp"];
570 let ColFields = ["IsOrig"];
572 let ValueCols = [["0"]];
575 def getMaskedMIMGOp : InstrMapping {
576 let FilterClass = "MIMG_Mask";
577 let RowFields = ["Op"];
578 let ColFields = ["Channels"];
580 let ValueCols = [["1"], ["2"], ["3"] ];
583 // Maps an commuted opcode to its original version
584 def getCommuteOrig : InstrMapping {
585 let FilterClass = "VOP2_REV";
586 let RowFields = ["RevOp"];
587 let ColFields = ["IsOrig"];
589 let ValueCols = [["1"]];
592 include "SIInstructions.td"