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_NoSampler_Helper <bits<7> op, string asm,
476 RegisterClass src_rc> : MIMG <
478 (outs VReg_128:$vdata),
479 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
480 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
482 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
483 #" $tfe, $lwe, $slc, $vaddr, $srsrc",
488 let hasPostISelHook = 1;
491 multiclass MIMG_NoSampler <bits<7> op, string asm> {
492 def _V1 : MIMG_NoSampler_Helper <op, asm, VReg_32>;
493 def _V2 : MIMG_NoSampler_Helper <op, asm, VReg_64>;
494 def _V4 : MIMG_NoSampler_Helper <op, asm, VReg_128>;
497 class MIMG_Sampler_Helper <bits<7> op, string asm,
498 RegisterClass src_rc> : MIMG <
500 (outs VReg_128:$vdata),
501 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
502 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
503 SReg_256:$srsrc, SReg_128:$ssamp),
504 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
505 #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
509 let hasPostISelHook = 1;
512 multiclass MIMG_Sampler <bits<7> op, string asm> {
513 def _V1 : MIMG_Sampler_Helper <op, asm, VReg_32>;
514 def _V2 : MIMG_Sampler_Helper <op, asm, VReg_64>;
515 def _V4 : MIMG_Sampler_Helper <op, asm, VReg_128>;
516 def _V8 : MIMG_Sampler_Helper <op, asm, VReg_256>;
517 def _V16 : MIMG_Sampler_Helper <op, asm, VReg_512>;
520 //===----------------------------------------------------------------------===//
521 // Vector instruction mappings
522 //===----------------------------------------------------------------------===//
524 // Maps an opcode in e32 form to its e64 equivalent
525 def getVOPe64 : InstrMapping {
526 let FilterClass = "VOP";
527 let RowFields = ["OpName"];
528 let ColFields = ["Size"];
530 let ValueCols = [["8"]];
533 // Maps an original opcode to its commuted version
534 def getCommuteRev : InstrMapping {
535 let FilterClass = "VOP2_REV";
536 let RowFields = ["RevOp"];
537 let ColFields = ["IsOrig"];
539 let ValueCols = [["0"]];
542 // Maps an commuted opcode to its original version
543 def getCommuteOrig : InstrMapping {
544 let FilterClass = "VOP2_REV";
545 let RowFields = ["RevOp"];
546 let ColFields = ["IsOrig"];
548 let ValueCols = [["1"]];
551 include "SIInstructions.td"