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 // Transformation function, extract the upper 32bit of a 64bit immediate
25 def HI32 : SDNodeXForm<imm, [{
26 return CurDAG->getTargetConstant(N->getZExtValue() >> 32, MVT::i32);
29 def IMM8bitDWORD : ImmLeaf <
31 return (Imm & ~0x3FC) == 0;
32 }], SDNodeXForm<imm, [{
33 return CurDAG->getTargetConstant(
34 N->getZExtValue() >> 2, MVT::i32);
38 def IMM12bit : ImmLeaf <
40 [{return isUInt<12>(Imm);}]
43 class InlineImm <ValueType vt> : PatLeaf <(vt imm), [{
44 return ((const SITargetLowering &)TLI).analyzeImmediate(N) == 0;
47 //===----------------------------------------------------------------------===//
48 // SI assembler operands
49 //===----------------------------------------------------------------------===//
56 include "SIInstrFormats.td"
58 //===----------------------------------------------------------------------===//
60 // SI Instruction multiclass helpers.
62 // Instructions with _32 take 32-bit operands.
63 // Instructions with _64 take 64-bit operands.
65 // VOP_* instructions can use either a 32-bit or 64-bit encoding. The 32-bit
66 // encoding is the standard encoding, but instruction that make use of
67 // any of the instruction modifiers must use the 64-bit encoding.
69 // Instructions with _e32 use the 32-bit encoding.
70 // Instructions with _e64 use the 64-bit encoding.
72 //===----------------------------------------------------------------------===//
74 //===----------------------------------------------------------------------===//
76 //===----------------------------------------------------------------------===//
78 class SOP1_32 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
79 op, (outs SReg_32:$dst), (ins SSrc_32:$src0),
80 opName#" $dst, $src0", pattern
83 class SOP1_64 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
84 op, (outs SReg_64:$dst), (ins SSrc_64:$src0),
85 opName#" $dst, $src0", pattern
88 class SOP2_32 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
89 op, (outs SReg_32:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
90 opName#" $dst, $src0, $src1", pattern
93 class SOP2_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
94 op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
95 opName#" $dst, $src0, $src1", pattern
98 class SOPC_32 <bits<7> op, string opName, list<dag> pattern> : SOPC <
99 op, (outs SCCReg:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
100 opName#" $dst, $src0, $src1", pattern
103 class SOPC_64 <bits<7> op, string opName, list<dag> pattern> : SOPC <
104 op, (outs SCCReg:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
105 opName#" $dst, $src0, $src1", pattern
108 class SOPK_32 <bits<5> op, string opName, list<dag> pattern> : SOPK <
109 op, (outs SReg_32:$dst), (ins i16imm:$src0),
110 opName#" $dst, $src0", pattern
113 class SOPK_64 <bits<5> op, string opName, list<dag> pattern> : SOPK <
114 op, (outs SReg_64:$dst), (ins i16imm:$src0),
115 opName#" $dst, $src0", pattern
118 multiclass SMRD_Helper <bits<5> op, string asm, RegisterClass baseClass,
119 RegisterClass dstClass> {
121 op, 1, (outs dstClass:$dst),
122 (ins baseClass:$sbase, i32imm:$offset),
123 asm#" $dst, $sbase, $offset", []
127 op, 0, (outs dstClass:$dst),
128 (ins baseClass:$sbase, SReg_32:$soff),
129 asm#" $dst, $sbase, $soff", []
133 //===----------------------------------------------------------------------===//
134 // Vector ALU classes
135 //===----------------------------------------------------------------------===//
137 class VOP <string opName> {
138 string OpName = opName;
141 class VOP2_REV <string revOp, bit isOrig> {
142 string RevOp = revOp;
146 multiclass VOP1_Helper <bits<8> op, RegisterClass drc, RegisterClass src,
147 string opName, list<dag> pattern> {
150 op, (outs drc:$dst), (ins src:$src0),
151 opName#"_e32 $dst, $src0", pattern
155 {1, 1, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
158 i32imm:$abs, i32imm:$clamp,
159 i32imm:$omod, i32imm:$neg),
160 opName#"_e64 $dst, $src0, $abs, $clamp, $omod, $neg", []
162 let SRC1 = SIOperand.ZERO;
163 let SRC2 = SIOperand.ZERO;
167 multiclass VOP1_32 <bits<8> op, string opName, list<dag> pattern>
168 : VOP1_Helper <op, VReg_32, VSrc_32, opName, pattern>;
170 multiclass VOP1_64 <bits<8> op, string opName, list<dag> pattern>
171 : VOP1_Helper <op, VReg_64, VSrc_64, opName, pattern>;
173 multiclass VOP2_Helper <bits<6> op, RegisterClass vrc, RegisterClass arc,
174 string opName, list<dag> pattern, string revOp> {
176 op, (outs vrc:$dst), (ins arc:$src0, vrc:$src1),
177 opName#"_e32 $dst, $src0, $src1", pattern
178 >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
181 {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
183 (ins arc:$src0, arc:$src1,
184 i32imm:$abs, i32imm:$clamp,
185 i32imm:$omod, i32imm:$neg),
186 opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg", []
187 >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
188 let SRC2 = SIOperand.ZERO;
192 multiclass VOP2_32 <bits<6> op, string opName, list<dag> pattern,
193 string revOp = opName>
194 : VOP2_Helper <op, VReg_32, VSrc_32, opName, pattern, revOp>;
196 multiclass VOP2_64 <bits<6> op, string opName, list<dag> pattern,
197 string revOp = opName>
198 : VOP2_Helper <op, VReg_64, VSrc_64, opName, pattern, revOp>;
200 multiclass VOP2b_32 <bits<6> op, string opName, list<dag> pattern,
201 string revOp = opName> {
204 op, (outs VReg_32:$dst), (ins VSrc_32:$src0, VReg_32:$src1),
205 opName#"_e32 $dst, $src0, $src1", pattern
206 >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
209 {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
211 (ins VSrc_32:$src0, VSrc_32:$src1,
212 i32imm:$abs, i32imm:$clamp,
213 i32imm:$omod, i32imm:$neg),
214 opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg", []
215 >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
216 let SRC2 = SIOperand.ZERO;
217 /* the VOP2 variant puts the carry out into VCC, the VOP3 variant
218 can write it into any SGPR. We currently don't use the carry out,
219 so for now hardcode it to VCC as well */
220 let SDST = SIOperand.VCC;
224 multiclass VOPC_Helper <bits<8> op, RegisterClass vrc, RegisterClass arc,
225 string opName, ValueType vt, PatLeaf cond> {
228 op, (ins arc:$src0, vrc:$src1),
229 opName#"_e32 $dst, $src0, $src1", []
233 {0, op{7}, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
235 (ins arc:$src0, arc:$src1,
236 InstFlag:$abs, InstFlag:$clamp,
237 InstFlag:$omod, InstFlag:$neg),
238 opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg",
239 !if(!eq(!cast<string>(cond), "COND_NULL"), []<dag>,
240 [(set SReg_64:$dst, (i1 (setcc (vt arc:$src0), arc:$src1, cond)))]
243 let SRC2 = SIOperand.ZERO;
247 multiclass VOPC_32 <bits<8> op, string opName,
248 ValueType vt = untyped, PatLeaf cond = COND_NULL>
249 : VOPC_Helper <op, VReg_32, VSrc_32, opName, vt, cond>;
251 multiclass VOPC_64 <bits<8> op, string opName,
252 ValueType vt = untyped, PatLeaf cond = COND_NULL>
253 : VOPC_Helper <op, VReg_64, VSrc_64, opName, vt, cond>;
255 class VOP3_32 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
256 op, (outs VReg_32:$dst),
257 (ins VSrc_32:$src0, VSrc_32:$src1, VSrc_32:$src2,
258 i32imm:$abs, i32imm:$clamp, i32imm:$omod, i32imm:$neg),
259 opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
262 class VOP3_64 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
263 op, (outs VReg_64:$dst),
264 (ins VSrc_64:$src0, VSrc_64:$src1, VSrc_64:$src2,
265 i32imm:$abs, i32imm:$clamp, i32imm:$omod, i32imm:$neg),
266 opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
269 //===----------------------------------------------------------------------===//
270 // Vector I/O classes
271 //===----------------------------------------------------------------------===//
273 class MTBUF_Store_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
276 (ins regClass:$vdata, i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
277 i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr,
278 SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
279 asm#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
280 #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
286 class MUBUF_Load_Helper <bits<7> op, string asm, RegisterClass regClass> : MUBUF <
288 (outs regClass:$vdata),
289 (ins i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
290 i1imm:$lds, VReg_32:$vaddr, SReg_128:$srsrc, i1imm:$slc,
291 i1imm:$tfe, SSrc_32:$soffset),
292 asm#" $vdata, $offset, $offen, $idxen, $glc, $addr64, "
293 #"$lds, $vaddr, $srsrc, $slc, $tfe, $soffset",
299 class MTBUF_Load_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
301 (outs regClass:$dst),
302 (ins i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
303 i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, SReg_128:$srsrc,
304 i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
305 asm#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
306 #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
312 class MIMG_Load_Helper <bits<7> op, string asm> : MIMG <
314 (outs VReg_128:$vdata),
315 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
316 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, unknown:$vaddr,
317 SReg_256:$srsrc, SReg_128:$ssamp),
318 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
319 #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
325 //===----------------------------------------------------------------------===//
326 // Vector instruction mappings
327 //===----------------------------------------------------------------------===//
329 // Maps an opcode in e32 form to its e64 equivalent
330 def getVOPe64 : InstrMapping {
331 let FilterClass = "VOP";
332 let RowFields = ["OpName"];
333 let ColFields = ["Size"];
335 let ValueCols = [["8"]];
338 // Maps an original opcode to its commuted version
339 def getCommuteRev : InstrMapping {
340 let FilterClass = "VOP2_REV";
341 let RowFields = ["RevOp"];
342 let ColFields = ["IsOrig"];
344 let ValueCols = [["0"]];
347 // Maps an commuted opcode to its original version
348 def getCommuteOrig : InstrMapping {
349 let FilterClass = "VOP2_REV";
350 let RowFields = ["RevOp"];
351 let ColFields = ["IsOrig"];
353 let ValueCols = [["1"]];
356 include "SIInstructions.td"