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 SOP2_SHIFT_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
176 op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_32:$src1),
177 opName#" $dst, $src0, $src1", pattern
180 class SOPC_32 <bits<7> op, string opName, list<dag> pattern> : SOPC <
181 op, (outs SCCReg:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
182 opName#" $dst, $src0, $src1", pattern
185 class SOPC_64 <bits<7> op, string opName, list<dag> pattern> : SOPC <
186 op, (outs SCCReg:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
187 opName#" $dst, $src0, $src1", pattern
190 class SOPK_32 <bits<5> op, string opName, list<dag> pattern> : SOPK <
191 op, (outs SReg_32:$dst), (ins i16imm:$src0),
192 opName#" $dst, $src0", pattern
195 class SOPK_64 <bits<5> op, string opName, list<dag> pattern> : SOPK <
196 op, (outs SReg_64:$dst), (ins i16imm:$src0),
197 opName#" $dst, $src0", pattern
200 multiclass SMRD_Helper <bits<5> op, string asm, RegisterClass baseClass,
201 RegisterClass dstClass> {
203 op, 1, (outs dstClass:$dst),
204 (ins baseClass:$sbase, i32imm:$offset),
205 asm#" $dst, $sbase, $offset", []
209 op, 0, (outs dstClass:$dst),
210 (ins baseClass:$sbase, SReg_32:$soff),
211 asm#" $dst, $sbase, $soff", []
215 //===----------------------------------------------------------------------===//
216 // Vector ALU classes
217 //===----------------------------------------------------------------------===//
219 class VOP <string opName> {
220 string OpName = opName;
223 class VOP2_REV <string revOp, bit isOrig> {
224 string RevOp = revOp;
228 multiclass VOP1_Helper <bits<8> op, RegisterClass drc, RegisterClass src,
229 string opName, list<dag> pattern> {
232 op, (outs drc:$dst), (ins src:$src0),
233 opName#"_e32 $dst, $src0", pattern
237 {1, 1, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
240 i32imm:$abs, i32imm:$clamp,
241 i32imm:$omod, i32imm:$neg),
242 opName#"_e64 $dst, $src0, $abs, $clamp, $omod, $neg", []
244 let src1 = SIOperand.ZERO;
245 let src2 = SIOperand.ZERO;
249 multiclass VOP1_32 <bits<8> op, string opName, list<dag> pattern>
250 : VOP1_Helper <op, VReg_32, VSrc_32, opName, pattern>;
252 multiclass VOP1_64 <bits<8> op, string opName, list<dag> pattern>
253 : VOP1_Helper <op, VReg_64, VSrc_64, opName, pattern>;
255 multiclass VOP1_32_64 <bits<8> op, string opName, list<dag> pattern>
256 : VOP1_Helper <op, VReg_32, VSrc_64, opName, pattern>;
258 multiclass VOP1_64_32 <bits<8> op, string opName, list<dag> pattern>
259 : VOP1_Helper <op, VReg_64, VSrc_32, opName, pattern>;
261 multiclass VOP2_Helper <bits<6> op, RegisterClass vrc, RegisterClass arc,
262 string opName, list<dag> pattern, string revOp> {
264 op, (outs vrc:$dst), (ins arc:$src0, vrc:$src1),
265 opName#"_e32 $dst, $src0, $src1", pattern
266 >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
269 {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
271 (ins arc:$src0, arc:$src1,
272 i32imm:$abs, i32imm:$clamp,
273 i32imm:$omod, i32imm:$neg),
274 opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg", []
275 >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
276 let src2 = SIOperand.ZERO;
280 multiclass VOP2_32 <bits<6> op, string opName, list<dag> pattern,
281 string revOp = opName>
282 : VOP2_Helper <op, VReg_32, VSrc_32, opName, pattern, revOp>;
284 multiclass VOP2_64 <bits<6> op, string opName, list<dag> pattern,
285 string revOp = opName>
286 : VOP2_Helper <op, VReg_64, VSrc_64, opName, pattern, revOp>;
288 multiclass VOP2b_32 <bits<6> op, string opName, list<dag> pattern,
289 string revOp = opName> {
292 op, (outs VReg_32:$dst), (ins VSrc_32:$src0, VReg_32:$src1),
293 opName#"_e32 $dst, $src0, $src1", pattern
294 >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
297 {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
299 (ins VSrc_32:$src0, VSrc_32:$src1,
300 i32imm:$abs, i32imm:$clamp,
301 i32imm:$omod, i32imm:$neg),
302 opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg", []
303 >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
304 let src2 = SIOperand.ZERO;
305 /* the VOP2 variant puts the carry out into VCC, the VOP3 variant
306 can write it into any SGPR. We currently don't use the carry out,
307 so for now hardcode it to VCC as well */
308 let sdst = SIOperand.VCC;
312 multiclass VOPC_Helper <bits<8> op, RegisterClass vrc, RegisterClass arc,
313 string opName, ValueType vt, PatLeaf cond> {
316 op, (ins arc:$src0, vrc:$src1),
317 opName#"_e32 $dst, $src0, $src1", []
321 {0, op{7}, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
323 (ins arc:$src0, arc:$src1,
324 InstFlag:$abs, InstFlag:$clamp,
325 InstFlag:$omod, InstFlag:$neg),
326 opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg",
327 !if(!eq(!cast<string>(cond), "COND_NULL"), []<dag>,
328 [(set SReg_64:$dst, (i1 (setcc (vt arc:$src0), arc:$src1, cond)))]
331 let src2 = SIOperand.ZERO;
335 multiclass VOPC_32 <bits<8> op, string opName,
336 ValueType vt = untyped, PatLeaf cond = COND_NULL>
337 : VOPC_Helper <op, VReg_32, VSrc_32, opName, vt, cond>;
339 multiclass VOPC_64 <bits<8> op, string opName,
340 ValueType vt = untyped, PatLeaf cond = COND_NULL>
341 : VOPC_Helper <op, VReg_64, VSrc_64, opName, vt, cond>;
343 class VOP3_32 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
344 op, (outs VReg_32:$dst),
345 (ins VSrc_32:$src0, VSrc_32:$src1, VSrc_32:$src2,
346 InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg),
347 opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
350 class VOP3_64_Shift <bits <9> op, string opName, list<dag> pattern> : VOP3 <
351 op, (outs VReg_64:$dst),
352 (ins VSrc_64:$src0, VSrc_32:$src1),
353 opName#" $dst, $src0, $src1", pattern
356 let src2 = SIOperand.ZERO;
363 class VOP3_64 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
364 op, (outs VReg_64:$dst),
365 (ins VSrc_64:$src0, VSrc_64:$src1, VSrc_64:$src2,
366 InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg),
367 opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
370 //===----------------------------------------------------------------------===//
371 // Vector I/O classes
372 //===----------------------------------------------------------------------===//
374 class DS_Load_Helper <bits<8> op, string asm, RegisterClass regClass> : DS <
376 (outs regClass:$vdst),
377 (ins i1imm:$gds, VReg_32:$addr, VReg_32:$data0, VReg_32:$data1,
378 i8imm:$offset0, i8imm:$offset1),
379 asm#" $vdst, $gds, $addr, $data0, $data1, $offset0, $offset1, [M0]",
385 class DS_Store_Helper <bits<8> op, string asm, RegisterClass regClass> : DS <
388 (ins i1imm:$gds, VReg_32:$addr, VReg_32:$data0, VReg_32:$data1,
389 i8imm:$offset0, i8imm:$offset1),
390 asm#" $gds, $addr, $data0, $data1, $offset0, $offset1, [M0]",
397 class DS_1A1D_RET <bits<8> op, string asm, RegisterClass rc> : DS <
400 (ins i1imm:$gds, VReg_32:$addr, VReg_32:$data0, i8imm:$offset0,
402 asm#" $gds, $vdst, $addr, $data0, $offset0, $offset1, [M0]",
409 class MTBUF_Store_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
412 (ins regClass:$vdata, i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
413 i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr,
414 SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
415 asm#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
416 #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
422 multiclass MUBUF_Load_Helper <bits<7> op, string asm, RegisterClass regClass> {
424 let glc = 0, lds = 0, slc = 0, tfe = 0, soffset = 128 /* ZERO */,
427 let offen = 1, idxen = 0, addr64 = 0, offset = 0 in {
428 def _OFFEN : MUBUF <op, (outs regClass:$vdata),
429 (ins SReg_128:$srsrc, VReg_32:$vaddr),
430 asm#" $vdata, $srsrc + $vaddr", []>;
433 let offen = 0, idxen = 1, addr64 = 0 in {
434 def _IDXEN : MUBUF <op, (outs regClass:$vdata),
435 (ins SReg_128:$srsrc, VReg_32:$vaddr, i16imm:$offset),
436 asm#" $vdata, $srsrc[$vaddr] + $offset", []>;
439 let offen = 0, idxen = 0, addr64 = 1 in {
440 def _ADDR64 : MUBUF <op, (outs regClass:$vdata),
441 (ins SReg_128:$srsrc, VReg_64:$vaddr, i16imm:$offset),
442 asm#" $vdata, $srsrc + $vaddr + $offset", []>;
447 class MUBUF_Store_Helper <bits<7> op, string name, RegisterClass vdataClass> :
448 MUBUF <op, (outs), (ins vdataClass:$vdata, SReg_128:$srsrc, VReg_64:$vaddr,
450 name#" $vdata, $srsrc + $vaddr + $offset",
464 let soffset = 128; // ZERO
467 class MTBUF_Load_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
469 (outs regClass:$dst),
470 (ins i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
471 i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, SReg_128:$srsrc,
472 i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
473 asm#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
474 #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
480 class MIMG_Mask <string op, int channels> {
482 int Channels = channels;
485 class MIMG_NoSampler_Helper <bits<7> op, string asm,
486 RegisterClass dst_rc,
487 RegisterClass src_rc> : MIMG <
489 (outs dst_rc:$vdata),
490 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
491 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
493 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
494 #" $tfe, $lwe, $slc, $vaddr, $srsrc",
499 let hasPostISelHook = 1;
502 multiclass MIMG_NoSampler_Src_Helper <bits<7> op, string asm,
503 RegisterClass dst_rc,
505 def _V1 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_32>,
506 MIMG_Mask<asm#"_V1", channels>;
507 def _V2 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_64>,
508 MIMG_Mask<asm#"_V2", channels>;
509 def _V4 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_128>,
510 MIMG_Mask<asm#"_V4", channels>;
513 multiclass MIMG_NoSampler <bits<7> op, string asm> {
514 defm _V1 : MIMG_NoSampler_Src_Helper <op, asm, VReg_32, 1>;
515 defm _V2 : MIMG_NoSampler_Src_Helper <op, asm, VReg_64, 2>;
516 defm _V3 : MIMG_NoSampler_Src_Helper <op, asm, VReg_96, 3>;
517 defm _V4 : MIMG_NoSampler_Src_Helper <op, asm, VReg_128, 4>;
520 class MIMG_Sampler_Helper <bits<7> op, string asm,
521 RegisterClass dst_rc,
522 RegisterClass src_rc> : MIMG <
524 (outs dst_rc:$vdata),
525 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
526 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
527 SReg_256:$srsrc, SReg_128:$ssamp),
528 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
529 #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
533 let hasPostISelHook = 1;
536 multiclass MIMG_Sampler_Src_Helper <bits<7> op, string asm,
537 RegisterClass dst_rc,
539 def _V1 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_32>,
540 MIMG_Mask<asm#"_V1", channels>;
541 def _V2 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_64>,
542 MIMG_Mask<asm#"_V2", channels>;
543 def _V4 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_128>,
544 MIMG_Mask<asm#"_V4", channels>;
545 def _V8 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_256>,
546 MIMG_Mask<asm#"_V8", channels>;
547 def _V16 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_512>,
548 MIMG_Mask<asm#"_V16", channels>;
551 multiclass MIMG_Sampler <bits<7> op, string asm> {
552 defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VReg_32, 1>;
553 defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2>;
554 defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3>;
555 defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4>;
558 //===----------------------------------------------------------------------===//
559 // Vector instruction mappings
560 //===----------------------------------------------------------------------===//
562 // Maps an opcode in e32 form to its e64 equivalent
563 def getVOPe64 : InstrMapping {
564 let FilterClass = "VOP";
565 let RowFields = ["OpName"];
566 let ColFields = ["Size"];
568 let ValueCols = [["8"]];
571 // Maps an original opcode to its commuted version
572 def getCommuteRev : InstrMapping {
573 let FilterClass = "VOP2_REV";
574 let RowFields = ["RevOp"];
575 let ColFields = ["IsOrig"];
577 let ValueCols = [["0"]];
580 def getMaskedMIMGOp : InstrMapping {
581 let FilterClass = "MIMG_Mask";
582 let RowFields = ["Op"];
583 let ColFields = ["Channels"];
585 let ValueCols = [["1"], ["2"], ["3"] ];
588 // Maps an commuted opcode to its original version
589 def getCommuteOrig : InstrMapping {
590 let FilterClass = "VOP2_REV";
591 let RowFields = ["RevOp"];
592 let ColFields = ["IsOrig"];
594 let ValueCols = [["1"]];
597 include "SIInstructions.td"