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 def LO32f : SDNodeXForm<fpimm, [{
25 uint64_t val = N->getValueAPF().bitcastToAPInt().getZExtValue() & 0xffffffff;
26 float *fval = reinterpret_cast<float *>(&val);
27 return CurDAG->getTargetConstantFP(*fval, MVT::f32);
30 // Transformation function, extract the upper 32bit of a 64bit immediate
31 def HI32 : SDNodeXForm<imm, [{
32 return CurDAG->getTargetConstant(N->getZExtValue() >> 32, MVT::i32);
35 def HI32f : SDNodeXForm<fpimm, [{
36 uint64_t val = N->getValueAPF().bitcastToAPInt().getZExtValue() >> 32;
37 float *fval = reinterpret_cast<float *>(&val);
38 return CurDAG->getTargetConstantFP(*fval, MVT::f32);
41 def IMM8bitDWORD : ImmLeaf <
43 return (Imm & ~0x3FC) == 0;
44 }], SDNodeXForm<imm, [{
45 return CurDAG->getTargetConstant(
46 N->getZExtValue() >> 2, MVT::i32);
50 def as_i16imm : SDNodeXForm<imm, [{
51 return CurDAG->getTargetConstant(N->getSExtValue(), MVT::i16);
54 def IMM12bit : PatLeaf <(imm),
55 [{return isUInt<12>(N->getZExtValue());}]
58 class InlineImm <ValueType vt> : PatLeaf <(vt imm), [{
60 (*(const SITargetLowering *)getTargetLowering()).analyzeImmediate(N) == 0;
63 //===----------------------------------------------------------------------===//
64 // SI assembler operands
65 //===----------------------------------------------------------------------===//
72 include "SIInstrFormats.td"
74 //===----------------------------------------------------------------------===//
76 // SI Instruction multiclass helpers.
78 // Instructions with _32 take 32-bit operands.
79 // Instructions with _64 take 64-bit operands.
81 // VOP_* instructions can use either a 32-bit or 64-bit encoding. The 32-bit
82 // encoding is the standard encoding, but instruction that make use of
83 // any of the instruction modifiers must use the 64-bit encoding.
85 // Instructions with _e32 use the 32-bit encoding.
86 // Instructions with _e64 use the 64-bit encoding.
88 //===----------------------------------------------------------------------===//
90 //===----------------------------------------------------------------------===//
92 //===----------------------------------------------------------------------===//
94 class SOP1_32 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
95 op, (outs SReg_32:$dst), (ins SSrc_32:$src0),
96 opName#" $dst, $src0", pattern
99 class SOP1_64 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
100 op, (outs SReg_64:$dst), (ins SSrc_64:$src0),
101 opName#" $dst, $src0", pattern
104 class SOP2_32 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
105 op, (outs SReg_32:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
106 opName#" $dst, $src0, $src1", pattern
109 class SOP2_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
110 op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
111 opName#" $dst, $src0, $src1", pattern
114 class SOPC_32 <bits<7> op, string opName, list<dag> pattern> : SOPC <
115 op, (outs SCCReg:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
116 opName#" $dst, $src0, $src1", pattern
119 class SOPC_64 <bits<7> op, string opName, list<dag> pattern> : SOPC <
120 op, (outs SCCReg:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
121 opName#" $dst, $src0, $src1", pattern
124 class SOPK_32 <bits<5> op, string opName, list<dag> pattern> : SOPK <
125 op, (outs SReg_32:$dst), (ins i16imm:$src0),
126 opName#" $dst, $src0", pattern
129 class SOPK_64 <bits<5> op, string opName, list<dag> pattern> : SOPK <
130 op, (outs SReg_64:$dst), (ins i16imm:$src0),
131 opName#" $dst, $src0", pattern
134 multiclass SMRD_Helper <bits<5> op, string asm, RegisterClass baseClass,
135 RegisterClass dstClass> {
137 op, 1, (outs dstClass:$dst),
138 (ins baseClass:$sbase, i32imm:$offset),
139 asm#" $dst, $sbase, $offset", []
143 op, 0, (outs dstClass:$dst),
144 (ins baseClass:$sbase, SReg_32:$soff),
145 asm#" $dst, $sbase, $soff", []
149 //===----------------------------------------------------------------------===//
150 // Vector ALU classes
151 //===----------------------------------------------------------------------===//
153 class VOP <string opName> {
154 string OpName = opName;
157 class VOP2_REV <string revOp, bit isOrig> {
158 string RevOp = revOp;
162 multiclass VOP1_Helper <bits<8> op, RegisterClass drc, RegisterClass src,
163 string opName, list<dag> pattern> {
166 op, (outs drc:$dst), (ins src:$src0),
167 opName#"_e32 $dst, $src0", pattern
171 {1, 1, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
174 i32imm:$abs, i32imm:$clamp,
175 i32imm:$omod, i32imm:$neg),
176 opName#"_e64 $dst, $src0, $abs, $clamp, $omod, $neg", []
178 let src1 = SIOperand.ZERO;
179 let src2 = SIOperand.ZERO;
183 multiclass VOP1_32 <bits<8> op, string opName, list<dag> pattern>
184 : VOP1_Helper <op, VReg_32, VSrc_32, opName, pattern>;
186 multiclass VOP1_64 <bits<8> op, string opName, list<dag> pattern>
187 : VOP1_Helper <op, VReg_64, VSrc_64, opName, pattern>;
189 multiclass VOP2_Helper <bits<6> op, RegisterClass vrc, RegisterClass arc,
190 string opName, list<dag> pattern, string revOp> {
192 op, (outs vrc:$dst), (ins arc:$src0, vrc:$src1),
193 opName#"_e32 $dst, $src0, $src1", pattern
194 >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
197 {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
199 (ins arc:$src0, arc:$src1,
200 i32imm:$abs, i32imm:$clamp,
201 i32imm:$omod, i32imm:$neg),
202 opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg", []
203 >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
204 let src2 = SIOperand.ZERO;
208 multiclass VOP2_32 <bits<6> op, string opName, list<dag> pattern,
209 string revOp = opName>
210 : VOP2_Helper <op, VReg_32, VSrc_32, opName, pattern, revOp>;
212 multiclass VOP2_64 <bits<6> op, string opName, list<dag> pattern,
213 string revOp = opName>
214 : VOP2_Helper <op, VReg_64, VSrc_64, opName, pattern, revOp>;
216 multiclass VOP2b_32 <bits<6> op, string opName, list<dag> pattern,
217 string revOp = opName> {
220 op, (outs VReg_32:$dst), (ins VSrc_32:$src0, VReg_32:$src1),
221 opName#"_e32 $dst, $src0, $src1", pattern
222 >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
225 {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
227 (ins VSrc_32:$src0, VSrc_32:$src1,
228 i32imm:$abs, i32imm:$clamp,
229 i32imm:$omod, i32imm:$neg),
230 opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg", []
231 >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
232 let src2 = SIOperand.ZERO;
233 /* the VOP2 variant puts the carry out into VCC, the VOP3 variant
234 can write it into any SGPR. We currently don't use the carry out,
235 so for now hardcode it to VCC as well */
236 let sdst = SIOperand.VCC;
240 multiclass VOPC_Helper <bits<8> op, RegisterClass vrc, RegisterClass arc,
241 string opName, ValueType vt, PatLeaf cond> {
244 op, (ins arc:$src0, vrc:$src1),
245 opName#"_e32 $dst, $src0, $src1", []
249 {0, op{7}, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
251 (ins arc:$src0, arc:$src1,
252 InstFlag:$abs, InstFlag:$clamp,
253 InstFlag:$omod, InstFlag:$neg),
254 opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg",
255 !if(!eq(!cast<string>(cond), "COND_NULL"), []<dag>,
256 [(set SReg_64:$dst, (i1 (setcc (vt arc:$src0), arc:$src1, cond)))]
259 let src2 = SIOperand.ZERO;
263 multiclass VOPC_32 <bits<8> op, string opName,
264 ValueType vt = untyped, PatLeaf cond = COND_NULL>
265 : VOPC_Helper <op, VReg_32, VSrc_32, opName, vt, cond>;
267 multiclass VOPC_64 <bits<8> op, string opName,
268 ValueType vt = untyped, PatLeaf cond = COND_NULL>
269 : VOPC_Helper <op, VReg_64, VSrc_64, opName, vt, cond>;
271 class VOP3_32 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
272 op, (outs VReg_32:$dst),
273 (ins VSrc_32:$src0, VSrc_32:$src1, VSrc_32:$src2,
274 InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg),
275 opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
278 class VOP3_64_Shift <bits <9> op, string opName, list<dag> pattern> : VOP3 <
279 op, (outs VReg_64:$dst),
280 (ins VSrc_64:$src0, VSrc_32:$src1),
281 opName#" $dst, $src0, $src1", pattern
284 let src2 = SIOperand.ZERO;
291 class VOP3_64 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
292 op, (outs VReg_64:$dst),
293 (ins VSrc_64:$src0, VSrc_64:$src1, VSrc_64:$src2,
294 InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg),
295 opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
298 //===----------------------------------------------------------------------===//
299 // Vector I/O classes
300 //===----------------------------------------------------------------------===//
302 class DS_Load_Helper <bits<8> op, string asm, RegisterClass regClass> : DS <
304 (outs regClass:$vdst),
305 (ins i1imm:$gds, VReg_32:$addr, VReg_32:$data0, VReg_32:$data1,
306 i8imm:$offset0, i8imm:$offset1),
307 asm#" $vdst, $gds, $addr, $data0, $data1, $offset0, $offset1, [M0]",
313 class DS_Store_Helper <bits<8> op, string asm, RegisterClass regClass> : DS <
316 (ins i1imm:$gds, VReg_32:$addr, VReg_32:$data0, VReg_32:$data1,
317 i8imm:$offset0, i8imm:$offset1),
318 asm#" $gds, $addr, $data0, $data1, $offset0, $offset1, [M0]",
325 class MTBUF_Store_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
328 (ins regClass:$vdata, i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
329 i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr,
330 SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
331 asm#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
332 #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
338 multiclass MUBUF_Load_Helper <bits<7> op, string asm, RegisterClass regClass> {
340 let glc = 0, lds = 0, slc = 0, tfe = 0, soffset = 128 /* ZERO */,
343 let offen = 1, idxen = 0, addr64 = 0, offset = 0 in {
344 def _OFFEN : MUBUF <op, (outs regClass:$vdata),
345 (ins SReg_128:$srsrc, VReg_32:$vaddr),
346 asm#" $vdata, $srsrc + $vaddr", []>;
349 let offen = 0, idxen = 1, addr64 = 0 in {
350 def _IDXEN : MUBUF <op, (outs regClass:$vdata),
351 (ins SReg_128:$srsrc, VReg_32:$vaddr, i16imm:$offset),
352 asm#" $vdata, $srsrc[$vaddr] + $offset", []>;
355 let offen = 0, idxen = 0, addr64 = 1 in {
356 def _ADDR64 : MUBUF <op, (outs regClass:$vdata),
357 (ins SReg_128:$srsrc, VReg_64:$vaddr, i16imm:$offset),
358 asm#" $vdata, $srsrc + $vaddr + $offset", []>;
363 class MUBUF_Store_Helper <bits<7> op, string name, RegisterClass vdataClass,
365 MUBUF <op, (outs), (ins vdataClass:$vdata, SReg_128:$srsrc, VReg_64:$vaddr, i16imm:$offset),
366 name#" $vdata, $srsrc + $vaddr + $offset",
380 let soffset = 128; // ZERO
383 class MTBUF_Load_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
385 (outs regClass:$dst),
386 (ins i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
387 i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, SReg_128:$srsrc,
388 i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
389 asm#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
390 #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
396 class MIMG_NoSampler_Helper <bits<7> op, string asm> : MIMG <
398 (outs VReg_128:$vdata),
399 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
400 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, unknown:$vaddr,
402 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
403 #" $tfe, $lwe, $slc, $vaddr, $srsrc",
408 let hasPostISelHook = 1;
411 class MIMG_Sampler_Helper <bits<7> op, string asm> : MIMG <
413 (outs VReg_128:$vdata),
414 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
415 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, unknown:$vaddr,
416 SReg_256:$srsrc, SReg_128:$ssamp),
417 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
418 #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
422 let hasPostISelHook = 1;
425 //===----------------------------------------------------------------------===//
426 // Vector instruction mappings
427 //===----------------------------------------------------------------------===//
429 // Maps an opcode in e32 form to its e64 equivalent
430 def getVOPe64 : InstrMapping {
431 let FilterClass = "VOP";
432 let RowFields = ["OpName"];
433 let ColFields = ["Size"];
435 let ValueCols = [["8"]];
438 // Maps an original opcode to its commuted version
439 def getCommuteRev : InstrMapping {
440 let FilterClass = "VOP2_REV";
441 let RowFields = ["RevOp"];
442 let ColFields = ["IsOrig"];
444 let ValueCols = [["0"]];
447 // Maps an commuted opcode to its original version
448 def getCommuteOrig : InstrMapping {
449 let FilterClass = "VOP2_REV";
450 let RowFields = ["RevOp"];
451 let ColFields = ["IsOrig"];
453 let ValueCols = [["1"]];
456 // Test if the supplied opcode is an MIMG instruction
457 def isMIMG : InstrMapping {
458 let FilterClass = "MIMG";
459 let RowFields = ["Inst"];
460 let ColFields = ["Size"];
462 let ValueCols = [["8"]];
465 include "SIInstructions.td"