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 def FRAMEri32 : Operand<iPTR> {
125 let MIOperandInfo = (ops SReg_32:$ptr, i32imm:$index);
128 //===----------------------------------------------------------------------===//
129 // SI assembler operands
130 //===----------------------------------------------------------------------===//
137 include "SIInstrFormats.td"
139 //===----------------------------------------------------------------------===//
141 // SI Instruction multiclass helpers.
143 // Instructions with _32 take 32-bit operands.
144 // Instructions with _64 take 64-bit operands.
146 // VOP_* instructions can use either a 32-bit or 64-bit encoding. The 32-bit
147 // encoding is the standard encoding, but instruction that make use of
148 // any of the instruction modifiers must use the 64-bit encoding.
150 // Instructions with _e32 use the 32-bit encoding.
151 // Instructions with _e64 use the 64-bit encoding.
153 //===----------------------------------------------------------------------===//
155 //===----------------------------------------------------------------------===//
157 //===----------------------------------------------------------------------===//
159 class SOP1_32 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
160 op, (outs SReg_32:$dst), (ins SSrc_32:$src0),
161 opName#" $dst, $src0", pattern
164 class SOP1_64 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
165 op, (outs SReg_64:$dst), (ins SSrc_64:$src0),
166 opName#" $dst, $src0", pattern
169 class SOP2_32 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
170 op, (outs SReg_32:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
171 opName#" $dst, $src0, $src1", pattern
174 class SOP2_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
175 op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
176 opName#" $dst, $src0, $src1", pattern
179 class SOP2_SHIFT_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
180 op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_32:$src1),
181 opName#" $dst, $src0, $src1", pattern
184 class SOPC_32 <bits<7> op, string opName, list<dag> pattern> : SOPC <
185 op, (outs SCCReg:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
186 opName#" $dst, $src0, $src1", pattern
189 class SOPC_64 <bits<7> op, string opName, list<dag> pattern> : SOPC <
190 op, (outs SCCReg:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
191 opName#" $dst, $src0, $src1", pattern
194 class SOPK_32 <bits<5> op, string opName, list<dag> pattern> : SOPK <
195 op, (outs SReg_32:$dst), (ins i16imm:$src0),
196 opName#" $dst, $src0", pattern
199 class SOPK_64 <bits<5> op, string opName, list<dag> pattern> : SOPK <
200 op, (outs SReg_64:$dst), (ins i16imm:$src0),
201 opName#" $dst, $src0", pattern
204 multiclass SMRD_Helper <bits<5> op, string asm, RegisterClass baseClass,
205 RegisterClass dstClass> {
207 op, 1, (outs dstClass:$dst),
208 (ins baseClass:$sbase, i32imm:$offset),
209 asm#" $dst, $sbase, $offset", []
213 op, 0, (outs dstClass:$dst),
214 (ins baseClass:$sbase, SReg_32:$soff),
215 asm#" $dst, $sbase, $soff", []
219 //===----------------------------------------------------------------------===//
220 // Vector ALU classes
221 //===----------------------------------------------------------------------===//
223 class VOP <string opName> {
224 string OpName = opName;
227 class VOP2_REV <string revOp, bit isOrig> {
228 string RevOp = revOp;
232 multiclass VOP1_Helper <bits<8> op, RegisterClass drc, RegisterClass src,
233 string opName, list<dag> pattern> {
236 op, (outs drc:$dst), (ins src:$src0),
237 opName#"_e32 $dst, $src0", pattern
241 {1, 1, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
244 i32imm:$abs, i32imm:$clamp,
245 i32imm:$omod, i32imm:$neg),
246 opName#"_e64 $dst, $src0, $abs, $clamp, $omod, $neg", []
248 let src1 = SIOperand.ZERO;
249 let src2 = SIOperand.ZERO;
253 multiclass VOP1_32 <bits<8> op, string opName, list<dag> pattern>
254 : VOP1_Helper <op, VReg_32, VSrc_32, opName, pattern>;
256 multiclass VOP1_64 <bits<8> op, string opName, list<dag> pattern>
257 : VOP1_Helper <op, VReg_64, VSrc_64, opName, pattern>;
259 multiclass VOP1_32_64 <bits<8> op, string opName, list<dag> pattern>
260 : VOP1_Helper <op, VReg_32, VSrc_64, opName, pattern>;
262 multiclass VOP1_64_32 <bits<8> op, string opName, list<dag> pattern>
263 : VOP1_Helper <op, VReg_64, VSrc_32, opName, pattern>;
265 multiclass VOP2_Helper <bits<6> op, RegisterClass vrc, RegisterClass arc,
266 string opName, list<dag> pattern, string revOp> {
268 op, (outs vrc:$dst), (ins arc:$src0, vrc:$src1),
269 opName#"_e32 $dst, $src0, $src1", pattern
270 >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
273 {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
275 (ins arc:$src0, arc:$src1,
276 i32imm:$abs, i32imm:$clamp,
277 i32imm:$omod, i32imm:$neg),
278 opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg", []
279 >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
280 let src2 = SIOperand.ZERO;
284 multiclass VOP2_32 <bits<6> op, string opName, list<dag> pattern,
285 string revOp = opName>
286 : VOP2_Helper <op, VReg_32, VSrc_32, opName, pattern, revOp>;
288 multiclass VOP2_64 <bits<6> op, string opName, list<dag> pattern,
289 string revOp = opName>
290 : VOP2_Helper <op, VReg_64, VSrc_64, opName, pattern, revOp>;
292 multiclass VOP2b_32 <bits<6> op, string opName, list<dag> pattern,
293 string revOp = opName> {
296 op, (outs VReg_32:$dst), (ins VSrc_32:$src0, VReg_32:$src1),
297 opName#"_e32 $dst, $src0, $src1", pattern
298 >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
301 {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
303 (ins VSrc_32:$src0, VSrc_32:$src1,
304 i32imm:$abs, i32imm:$clamp,
305 i32imm:$omod, i32imm:$neg),
306 opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg", []
307 >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
308 let src2 = SIOperand.ZERO;
309 /* the VOP2 variant puts the carry out into VCC, the VOP3 variant
310 can write it into any SGPR. We currently don't use the carry out,
311 so for now hardcode it to VCC as well */
312 let sdst = SIOperand.VCC;
316 multiclass VOPC_Helper <bits<8> op, RegisterClass vrc, RegisterClass arc,
317 string opName, ValueType vt, PatLeaf cond> {
320 op, (ins arc:$src0, vrc:$src1),
321 opName#"_e32 $dst, $src0, $src1", []
325 {0, op{7}, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
327 (ins arc:$src0, arc:$src1,
328 InstFlag:$abs, InstFlag:$clamp,
329 InstFlag:$omod, InstFlag:$neg),
330 opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg",
331 !if(!eq(!cast<string>(cond), "COND_NULL"), []<dag>,
332 [(set SReg_64:$dst, (i1 (setcc (vt arc:$src0), arc:$src1, cond)))]
335 let src2 = SIOperand.ZERO;
339 multiclass VOPC_32 <bits<8> op, string opName,
340 ValueType vt = untyped, PatLeaf cond = COND_NULL>
341 : VOPC_Helper <op, VReg_32, VSrc_32, opName, vt, cond>;
343 multiclass VOPC_64 <bits<8> op, string opName,
344 ValueType vt = untyped, PatLeaf cond = COND_NULL>
345 : VOPC_Helper <op, VReg_64, VSrc_64, opName, vt, cond>;
347 class VOP3_32 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
348 op, (outs VReg_32:$dst),
349 (ins VSrc_32:$src0, VSrc_32:$src1, VSrc_32:$src2,
350 InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg),
351 opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
354 class VOP3_64_Shift <bits <9> op, string opName, list<dag> pattern> : VOP3 <
355 op, (outs VReg_64:$dst),
356 (ins VSrc_64:$src0, VSrc_32:$src1),
357 opName#" $dst, $src0, $src1", pattern
360 let src2 = SIOperand.ZERO;
367 class VOP3_64 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
368 op, (outs VReg_64:$dst),
369 (ins VSrc_64:$src0, VSrc_64:$src1, VSrc_64:$src2,
370 InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg),
371 opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
374 //===----------------------------------------------------------------------===//
375 // Vector I/O classes
376 //===----------------------------------------------------------------------===//
378 class DS_Load_Helper <bits<8> op, string asm, RegisterClass regClass> : DS <
380 (outs regClass:$vdst),
381 (ins i1imm:$gds, VReg_32:$addr, VReg_32:$data0, VReg_32:$data1,
382 i8imm:$offset0, i8imm:$offset1),
383 asm#" $vdst, $gds, $addr, $data0, $data1, $offset0, $offset1, [M0]",
389 class DS_Store_Helper <bits<8> op, string asm, RegisterClass regClass> : DS <
392 (ins i1imm:$gds, VReg_32:$addr, VReg_32:$data0, VReg_32:$data1,
393 i8imm:$offset0, i8imm:$offset1),
394 asm#" $gds, $addr, $data0, $data1, $offset0, $offset1, [M0]",
401 class DS_1A1D_RET <bits<8> op, string asm, RegisterClass rc> : DS <
404 (ins i1imm:$gds, VReg_32:$addr, VReg_32:$data0, i8imm:$offset0,
406 asm#" $gds, $vdst, $addr, $data0, $offset0, $offset1, [M0]",
413 class MTBUF_Store_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
416 (ins regClass:$vdata, i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
417 i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr,
418 SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
419 asm#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
420 #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
426 multiclass MUBUF_Load_Helper <bits<7> op, string asm, RegisterClass regClass> {
428 let glc = 0, lds = 0, slc = 0, tfe = 0, soffset = 128 /* ZERO */,
431 let offen = 1, idxen = 0, addr64 = 0, offset = 0 in {
432 def _OFFEN : MUBUF <op, (outs regClass:$vdata),
433 (ins SReg_128:$srsrc, VReg_32:$vaddr),
434 asm#" $vdata, $srsrc + $vaddr", []>;
437 let offen = 0, idxen = 1, addr64 = 0 in {
438 def _IDXEN : MUBUF <op, (outs regClass:$vdata),
439 (ins SReg_128:$srsrc, VReg_32:$vaddr, i16imm:$offset),
440 asm#" $vdata, $srsrc[$vaddr] + $offset", []>;
443 let offen = 0, idxen = 0, addr64 = 1 in {
444 def _ADDR64 : MUBUF <op, (outs regClass:$vdata),
445 (ins SReg_128:$srsrc, VReg_64:$vaddr, i16imm:$offset),
446 asm#" $vdata, $srsrc + $vaddr + $offset", []>;
451 class MUBUF_Store_Helper <bits<7> op, string name, RegisterClass vdataClass> :
452 MUBUF <op, (outs), (ins vdataClass:$vdata, SReg_128:$srsrc, VReg_64:$vaddr,
454 name#" $vdata, $srsrc + $vaddr + $offset",
468 let soffset = 128; // ZERO
471 class MTBUF_Load_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
473 (outs regClass:$dst),
474 (ins i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
475 i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, SReg_128:$srsrc,
476 i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
477 asm#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
478 #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
484 class MIMG_Mask <string op, int channels> {
486 int Channels = channels;
489 class MIMG_NoSampler_Helper <bits<7> op, string asm,
490 RegisterClass dst_rc,
491 RegisterClass src_rc> : MIMG <
493 (outs dst_rc:$vdata),
494 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
495 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
497 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
498 #" $tfe, $lwe, $slc, $vaddr, $srsrc",
503 let hasPostISelHook = 1;
506 multiclass MIMG_NoSampler_Src_Helper <bits<7> op, string asm,
507 RegisterClass dst_rc,
509 def _V1 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_32>,
510 MIMG_Mask<asm#"_V1", channels>;
511 def _V2 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_64>,
512 MIMG_Mask<asm#"_V2", channels>;
513 def _V4 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_128>,
514 MIMG_Mask<asm#"_V4", channels>;
517 multiclass MIMG_NoSampler <bits<7> op, string asm> {
518 defm _V1 : MIMG_NoSampler_Src_Helper <op, asm, VReg_32, 1>;
519 defm _V2 : MIMG_NoSampler_Src_Helper <op, asm, VReg_64, 2>;
520 defm _V3 : MIMG_NoSampler_Src_Helper <op, asm, VReg_96, 3>;
521 defm _V4 : MIMG_NoSampler_Src_Helper <op, asm, VReg_128, 4>;
524 class MIMG_Sampler_Helper <bits<7> op, string asm,
525 RegisterClass dst_rc,
526 RegisterClass src_rc> : MIMG <
528 (outs dst_rc:$vdata),
529 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
530 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
531 SReg_256:$srsrc, SReg_128:$ssamp),
532 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
533 #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
537 let hasPostISelHook = 1;
540 multiclass MIMG_Sampler_Src_Helper <bits<7> op, string asm,
541 RegisterClass dst_rc,
543 def _V1 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_32>,
544 MIMG_Mask<asm#"_V1", channels>;
545 def _V2 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_64>,
546 MIMG_Mask<asm#"_V2", channels>;
547 def _V4 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_128>,
548 MIMG_Mask<asm#"_V4", channels>;
549 def _V8 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_256>,
550 MIMG_Mask<asm#"_V8", channels>;
551 def _V16 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_512>,
552 MIMG_Mask<asm#"_V16", channels>;
555 multiclass MIMG_Sampler <bits<7> op, string asm> {
556 defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VReg_32, 1>;
557 defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2>;
558 defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3>;
559 defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4>;
562 //===----------------------------------------------------------------------===//
563 // Vector instruction mappings
564 //===----------------------------------------------------------------------===//
566 // Maps an opcode in e32 form to its e64 equivalent
567 def getVOPe64 : InstrMapping {
568 let FilterClass = "VOP";
569 let RowFields = ["OpName"];
570 let ColFields = ["Size"];
572 let ValueCols = [["8"]];
575 // Maps an original opcode to its commuted version
576 def getCommuteRev : InstrMapping {
577 let FilterClass = "VOP2_REV";
578 let RowFields = ["RevOp"];
579 let ColFields = ["IsOrig"];
581 let ValueCols = [["0"]];
584 def getMaskedMIMGOp : InstrMapping {
585 let FilterClass = "MIMG_Mask";
586 let RowFields = ["Op"];
587 let ColFields = ["Channels"];
589 let ValueCols = [["1"], ["2"], ["3"] ];
592 // Maps an commuted opcode to its original version
593 def getCommuteOrig : InstrMapping {
594 let FilterClass = "VOP2_REV";
595 let RowFields = ["RevOp"];
596 let ColFields = ["IsOrig"];
598 let ValueCols = [["1"]];
601 include "SIInstructions.td"