SIInstrInfo.td revision 251662
1249259Sdim//===-- SIInstrInfo.td - SI Instruction Infos -------------*- tablegen -*--===//
2249259Sdim//
3249259Sdim//                     The LLVM Compiler Infrastructure
4249259Sdim//
5249259Sdim// This file is distributed under the University of Illinois Open Source
6249259Sdim// License. See LICENSE.TXT for details.
7249259Sdim//
8249259Sdim//===----------------------------------------------------------------------===//
9249259Sdim
10249259Sdim//===----------------------------------------------------------------------===//
11249259Sdim// SI DAG Nodes
12249259Sdim//===----------------------------------------------------------------------===//
13249259Sdim
14249259Sdim// SMRD takes a 64bit memory address and can only add an 32bit offset
15249259Sdimdef SIadd64bit32bit : SDNode<"ISD::ADD",
16249259Sdim  SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>, SDTCisVT<0, i64>, SDTCisVT<2, i32>]>
17249259Sdim>;
18249259Sdim
19249259Sdim// Transformation function, extract the lower 32bit of a 64bit immediate
20249259Sdimdef LO32 : SDNodeXForm<imm, [{
21249259Sdim  return CurDAG->getTargetConstant(N->getZExtValue() & 0xffffffff, MVT::i32);
22249259Sdim}]>;
23249259Sdim
24249259Sdim// Transformation function, extract the upper 32bit of a 64bit immediate
25249259Sdimdef HI32 : SDNodeXForm<imm, [{
26249259Sdim  return CurDAG->getTargetConstant(N->getZExtValue() >> 32, MVT::i32);
27249259Sdim}]>;
28249259Sdim
29251662Sdimdef SIbuffer_store : SDNode<"AMDGPUISD::BUFFER_STORE",
30251662Sdim                           SDTypeProfile<0, 3, [SDTCisPtrTy<1>, SDTCisInt<2>]>,
31251662Sdim                           [SDNPHasChain, SDNPMayStore]>;
32251662Sdim
33249259Sdimdef IMM8bitDWORD : ImmLeaf <
34249259Sdim  i32, [{
35249259Sdim    return (Imm & ~0x3FC) == 0;
36249259Sdim  }], SDNodeXForm<imm, [{
37249259Sdim    return CurDAG->getTargetConstant(
38249259Sdim      N->getZExtValue() >> 2, MVT::i32);
39249259Sdim  }]>
40249259Sdim>;
41249259Sdim
42249259Sdimdef IMM12bit : ImmLeaf <
43249259Sdim  i16,
44249259Sdim  [{return isUInt<12>(Imm);}]
45249259Sdim>;
46249259Sdim
47249259Sdimclass InlineImm <ValueType vt> : PatLeaf <(vt imm), [{
48249259Sdim  return ((const SITargetLowering &)TLI).analyzeImmediate(N) == 0;
49249259Sdim}]>;
50249259Sdim
51249259Sdim//===----------------------------------------------------------------------===//
52249259Sdim// SI assembler operands
53249259Sdim//===----------------------------------------------------------------------===//
54249259Sdim
55249259Sdimdef SIOperand {
56249259Sdim  int ZERO = 0x80;
57249259Sdim  int VCC = 0x6A;
58249259Sdim}
59249259Sdim
60249259Sdiminclude "SIInstrFormats.td"
61249259Sdim
62249259Sdim//===----------------------------------------------------------------------===//
63249259Sdim//
64249259Sdim// SI Instruction multiclass helpers.
65249259Sdim//
66249259Sdim// Instructions with _32 take 32-bit operands.
67249259Sdim// Instructions with _64 take 64-bit operands.
68249259Sdim//
69249259Sdim// VOP_* instructions can use either a 32-bit or 64-bit encoding.  The 32-bit
70249259Sdim// encoding is the standard encoding, but instruction that make use of
71249259Sdim// any of the instruction modifiers must use the 64-bit encoding.
72249259Sdim//
73249259Sdim// Instructions with _e32 use the 32-bit encoding.
74249259Sdim// Instructions with _e64 use the 64-bit encoding.
75249259Sdim//
76249259Sdim//===----------------------------------------------------------------------===//
77249259Sdim
78249259Sdim//===----------------------------------------------------------------------===//
79249259Sdim// Scalar classes
80249259Sdim//===----------------------------------------------------------------------===//
81249259Sdim
82249259Sdimclass SOP1_32 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
83249259Sdim  op, (outs SReg_32:$dst), (ins SSrc_32:$src0),
84249259Sdim  opName#" $dst, $src0", pattern
85249259Sdim>;
86249259Sdim
87249259Sdimclass SOP1_64 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
88249259Sdim  op, (outs SReg_64:$dst), (ins SSrc_64:$src0),
89249259Sdim  opName#" $dst, $src0", pattern
90249259Sdim>;
91249259Sdim
92249259Sdimclass SOP2_32 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
93249259Sdim  op, (outs SReg_32:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
94249259Sdim  opName#" $dst, $src0, $src1", pattern
95249259Sdim>;
96249259Sdim
97249259Sdimclass SOP2_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
98249259Sdim  op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
99249259Sdim  opName#" $dst, $src0, $src1", pattern
100249259Sdim>;
101249259Sdim
102249259Sdimclass SOPC_32 <bits<7> op, string opName, list<dag> pattern> : SOPC <
103249259Sdim  op, (outs SCCReg:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
104249259Sdim  opName#" $dst, $src0, $src1", pattern
105249259Sdim>;
106249259Sdim
107249259Sdimclass SOPC_64 <bits<7> op, string opName, list<dag> pattern> : SOPC <
108249259Sdim  op, (outs SCCReg:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
109249259Sdim  opName#" $dst, $src0, $src1", pattern
110249259Sdim>;
111249259Sdim
112249259Sdimclass SOPK_32 <bits<5> op, string opName, list<dag> pattern> : SOPK <
113249259Sdim  op, (outs SReg_32:$dst), (ins i16imm:$src0),
114249259Sdim  opName#" $dst, $src0", pattern
115249259Sdim>;
116249259Sdim
117249259Sdimclass SOPK_64 <bits<5> op, string opName, list<dag> pattern> : SOPK <
118249259Sdim  op, (outs SReg_64:$dst), (ins i16imm:$src0),
119249259Sdim  opName#" $dst, $src0", pattern
120249259Sdim>;
121249259Sdim
122249259Sdimmulticlass SMRD_Helper <bits<5> op, string asm, RegisterClass baseClass,
123249259Sdim                        RegisterClass dstClass> {
124249259Sdim  def _IMM : SMRD <
125249259Sdim    op, 1, (outs dstClass:$dst),
126249259Sdim    (ins baseClass:$sbase, i32imm:$offset),
127249259Sdim    asm#" $dst, $sbase, $offset", []
128249259Sdim  >;
129249259Sdim
130249259Sdim  def _SGPR : SMRD <
131249259Sdim    op, 0, (outs dstClass:$dst),
132249259Sdim    (ins baseClass:$sbase, SReg_32:$soff),
133249259Sdim    asm#" $dst, $sbase, $soff", []
134249259Sdim  >;
135249259Sdim}
136249259Sdim
137249259Sdim//===----------------------------------------------------------------------===//
138249259Sdim// Vector ALU classes
139249259Sdim//===----------------------------------------------------------------------===//
140249259Sdim
141249259Sdimclass VOP <string opName> {
142249259Sdim  string OpName = opName;
143249259Sdim}
144249259Sdim
145249259Sdimclass VOP2_REV <string revOp, bit isOrig> {
146249259Sdim  string RevOp = revOp;
147249259Sdim  bit IsOrig = isOrig;
148249259Sdim}
149249259Sdim
150249259Sdimmulticlass VOP1_Helper <bits<8> op, RegisterClass drc, RegisterClass src,
151249259Sdim                        string opName, list<dag> pattern> {
152249259Sdim
153249259Sdim  def _e32 : VOP1 <
154249259Sdim    op, (outs drc:$dst), (ins src:$src0),
155249259Sdim    opName#"_e32 $dst, $src0", pattern
156249259Sdim  >, VOP <opName>;
157249259Sdim
158249259Sdim  def _e64 : VOP3 <
159249259Sdim    {1, 1, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
160249259Sdim    (outs drc:$dst),
161249259Sdim    (ins src:$src0,
162249259Sdim         i32imm:$abs, i32imm:$clamp,
163249259Sdim         i32imm:$omod, i32imm:$neg),
164249259Sdim    opName#"_e64 $dst, $src0, $abs, $clamp, $omod, $neg", []
165249259Sdim  >, VOP <opName> {
166249259Sdim    let SRC1 = SIOperand.ZERO;
167249259Sdim    let SRC2 = SIOperand.ZERO;
168249259Sdim  }
169249259Sdim}
170249259Sdim
171249259Sdimmulticlass VOP1_32 <bits<8> op, string opName, list<dag> pattern>
172249259Sdim  : VOP1_Helper <op, VReg_32, VSrc_32, opName, pattern>;
173249259Sdim
174249259Sdimmulticlass VOP1_64 <bits<8> op, string opName, list<dag> pattern>
175249259Sdim  : VOP1_Helper <op, VReg_64, VSrc_64, opName, pattern>;
176249259Sdim
177249259Sdimmulticlass VOP2_Helper <bits<6> op, RegisterClass vrc, RegisterClass arc,
178249259Sdim                        string opName, list<dag> pattern, string revOp> {
179249259Sdim  def _e32 : VOP2 <
180249259Sdim    op, (outs vrc:$dst), (ins arc:$src0, vrc:$src1),
181249259Sdim    opName#"_e32 $dst, $src0, $src1", pattern
182249259Sdim  >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
183249259Sdim
184249259Sdim  def _e64 : VOP3 <
185249259Sdim    {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
186249259Sdim    (outs vrc:$dst),
187249259Sdim    (ins arc:$src0, arc:$src1,
188249259Sdim         i32imm:$abs, i32imm:$clamp,
189249259Sdim         i32imm:$omod, i32imm:$neg),
190249259Sdim    opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg", []
191249259Sdim  >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
192249259Sdim    let SRC2 = SIOperand.ZERO;
193249259Sdim  }
194249259Sdim}
195249259Sdim
196249259Sdimmulticlass VOP2_32 <bits<6> op, string opName, list<dag> pattern,
197249259Sdim                    string revOp = opName>
198249259Sdim  : VOP2_Helper <op, VReg_32, VSrc_32, opName, pattern, revOp>;
199249259Sdim
200249259Sdimmulticlass VOP2_64 <bits<6> op, string opName, list<dag> pattern,
201249259Sdim                    string revOp = opName>
202249259Sdim  : VOP2_Helper <op, VReg_64, VSrc_64, opName, pattern, revOp>;
203249259Sdim
204249259Sdimmulticlass VOP2b_32 <bits<6> op, string opName, list<dag> pattern,
205249259Sdim                     string revOp = opName> {
206249259Sdim
207249259Sdim  def _e32 : VOP2 <
208249259Sdim    op, (outs VReg_32:$dst), (ins VSrc_32:$src0, VReg_32:$src1),
209249259Sdim    opName#"_e32 $dst, $src0, $src1", pattern
210249259Sdim  >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
211249259Sdim
212249259Sdim  def _e64 : VOP3b <
213249259Sdim    {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
214249259Sdim    (outs VReg_32:$dst),
215249259Sdim    (ins VSrc_32:$src0, VSrc_32:$src1,
216249259Sdim         i32imm:$abs, i32imm:$clamp,
217249259Sdim         i32imm:$omod, i32imm:$neg),
218249259Sdim    opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg", []
219249259Sdim  >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
220249259Sdim    let SRC2 = SIOperand.ZERO;
221249259Sdim    /* the VOP2 variant puts the carry out into VCC, the VOP3 variant
222249259Sdim       can write it into any SGPR. We currently don't use the carry out,
223249259Sdim       so for now hardcode it to VCC as well */
224249259Sdim    let SDST = SIOperand.VCC;
225249259Sdim  }
226249259Sdim}
227249259Sdim
228249259Sdimmulticlass VOPC_Helper <bits<8> op, RegisterClass vrc, RegisterClass arc,
229249259Sdim                        string opName, ValueType vt, PatLeaf cond> {
230249259Sdim
231249259Sdim  def _e32 : VOPC <
232249259Sdim    op, (ins arc:$src0, vrc:$src1),
233249259Sdim    opName#"_e32 $dst, $src0, $src1", []
234249259Sdim  >, VOP <opName>;
235249259Sdim
236249259Sdim  def _e64 : VOP3 <
237249259Sdim    {0, op{7}, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
238249259Sdim    (outs SReg_64:$dst),
239249259Sdim    (ins arc:$src0, arc:$src1,
240249259Sdim         InstFlag:$abs, InstFlag:$clamp,
241249259Sdim         InstFlag:$omod, InstFlag:$neg),
242249259Sdim    opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg",
243249259Sdim    !if(!eq(!cast<string>(cond), "COND_NULL"), []<dag>,
244249259Sdim      [(set SReg_64:$dst, (i1 (setcc (vt arc:$src0), arc:$src1, cond)))]
245249259Sdim    )
246249259Sdim  >, VOP <opName> {
247249259Sdim    let SRC2 = SIOperand.ZERO;
248249259Sdim  }
249249259Sdim}
250249259Sdim
251249259Sdimmulticlass VOPC_32 <bits<8> op, string opName,
252249259Sdim  ValueType vt = untyped, PatLeaf cond = COND_NULL>
253249259Sdim  : VOPC_Helper <op, VReg_32, VSrc_32, opName, vt, cond>;
254249259Sdim
255249259Sdimmulticlass VOPC_64 <bits<8> op, string opName,
256249259Sdim  ValueType vt = untyped, PatLeaf cond = COND_NULL>
257249259Sdim  : VOPC_Helper <op, VReg_64, VSrc_64, opName, vt, cond>;
258249259Sdim
259249259Sdimclass VOP3_32 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
260249259Sdim  op, (outs VReg_32:$dst),
261249259Sdim  (ins VSrc_32:$src0, VSrc_32:$src1, VSrc_32:$src2,
262251662Sdim   InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg),
263249259Sdim  opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
264249259Sdim>, VOP <opName>;
265249259Sdim
266249259Sdimclass VOP3_64 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
267249259Sdim  op, (outs VReg_64:$dst),
268249259Sdim  (ins VSrc_64:$src0, VSrc_64:$src1, VSrc_64:$src2,
269251662Sdim   InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg),
270249259Sdim  opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
271249259Sdim>, VOP <opName>;
272249259Sdim
273249259Sdim//===----------------------------------------------------------------------===//
274249259Sdim// Vector I/O classes
275249259Sdim//===----------------------------------------------------------------------===//
276249259Sdim
277249259Sdimclass MTBUF_Store_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
278249259Sdim  op,
279249259Sdim  (outs),
280249259Sdim  (ins regClass:$vdata, i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
281249259Sdim   i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr,
282249259Sdim   SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
283249259Sdim  asm#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
284249259Sdim     #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
285249259Sdim  []> {
286249259Sdim  let mayStore = 1;
287249259Sdim  let mayLoad = 0;
288249259Sdim}
289249259Sdim
290249259Sdimclass MUBUF_Load_Helper <bits<7> op, string asm, RegisterClass regClass> : MUBUF <
291249259Sdim  op,
292251662Sdim  (outs regClass:$vdata),
293249259Sdim  (ins i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
294249259Sdim       i1imm:$lds, VReg_32:$vaddr, SReg_128:$srsrc, i1imm:$slc,
295249259Sdim       i1imm:$tfe, SSrc_32:$soffset),
296251662Sdim  asm#" $vdata, $offset, $offen, $idxen, $glc, $addr64, "
297249259Sdim     #"$lds, $vaddr, $srsrc, $slc, $tfe, $soffset",
298249259Sdim  []> {
299249259Sdim  let mayLoad = 1;
300249259Sdim  let mayStore = 0;
301249259Sdim}
302249259Sdim
303251662Sdimclass MUBUF_Store_Helper <bits<7> op, string name, RegisterClass vdataClass,
304251662Sdim                         ValueType VT> :
305251662Sdim    MUBUF <op, (outs), (ins vdataClass:$vdata, SReg_128:$srsrc, VReg_64:$vaddr),
306251662Sdim          name#" $vdata, $srsrc + $vaddr",
307251662Sdim          [(SIbuffer_store (VT vdataClass:$vdata), (i128 SReg_128:$srsrc),
308251662Sdim                                                    (i64 VReg_64:$vaddr))]> {
309251662Sdim
310251662Sdim  let mayLoad = 0;
311251662Sdim  let mayStore = 1;
312251662Sdim
313251662Sdim  // Encoding
314251662Sdim  let offset = 0;
315251662Sdim  let offen = 0;
316251662Sdim  let idxen = 0;
317251662Sdim  let glc = 0;
318251662Sdim  let addr64 = 1;
319251662Sdim  let lds = 0;
320251662Sdim  let slc = 0;
321251662Sdim  let tfe = 0;
322251662Sdim  let soffset = 128; // ZERO
323251662Sdim}
324251662Sdim
325249259Sdimclass MTBUF_Load_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
326249259Sdim  op,
327249259Sdim  (outs regClass:$dst),
328249259Sdim  (ins i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
329249259Sdim       i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, SReg_128:$srsrc,
330249259Sdim       i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
331249259Sdim  asm#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
332249259Sdim     #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
333249259Sdim  []> {
334249259Sdim  let mayLoad = 1;
335249259Sdim  let mayStore = 0;
336249259Sdim}
337249259Sdim
338251662Sdimclass MIMG_NoSampler_Helper <bits<7> op, string asm> : MIMG <
339249259Sdim  op,
340249259Sdim  (outs VReg_128:$vdata),
341249259Sdim  (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
342249259Sdim       i1imm:$tfe, i1imm:$lwe, i1imm:$slc, unknown:$vaddr,
343251662Sdim       SReg_256:$srsrc),
344251662Sdim  asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
345251662Sdim     #" $tfe, $lwe, $slc, $vaddr, $srsrc",
346251662Sdim  []> {
347251662Sdim  let SSAMP = 0;
348251662Sdim  let mayLoad = 1;
349251662Sdim  let mayStore = 0;
350251662Sdim  let hasPostISelHook = 1;
351251662Sdim}
352251662Sdim
353251662Sdimclass MIMG_Sampler_Helper <bits<7> op, string asm> : MIMG <
354251662Sdim  op,
355251662Sdim  (outs VReg_128:$vdata),
356251662Sdim  (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
357251662Sdim       i1imm:$tfe, i1imm:$lwe, i1imm:$slc, unknown:$vaddr,
358249259Sdim       SReg_256:$srsrc, SReg_128:$ssamp),
359249259Sdim  asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
360249259Sdim     #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
361249259Sdim  []> {
362249259Sdim  let mayLoad = 1;
363249259Sdim  let mayStore = 0;
364251662Sdim  let hasPostISelHook = 1;
365249259Sdim}
366249259Sdim
367249259Sdim//===----------------------------------------------------------------------===//
368249259Sdim// Vector instruction mappings
369249259Sdim//===----------------------------------------------------------------------===//
370249259Sdim
371249259Sdim// Maps an opcode in e32 form to its e64 equivalent
372249259Sdimdef getVOPe64 : InstrMapping {
373249259Sdim  let FilterClass = "VOP";
374249259Sdim  let RowFields = ["OpName"];
375249259Sdim  let ColFields = ["Size"];
376249259Sdim  let KeyCol = ["4"];
377249259Sdim  let ValueCols = [["8"]];
378249259Sdim}
379249259Sdim
380249259Sdim// Maps an original opcode to its commuted version
381249259Sdimdef getCommuteRev : InstrMapping {
382249259Sdim  let FilterClass = "VOP2_REV";
383249259Sdim  let RowFields = ["RevOp"];
384249259Sdim  let ColFields = ["IsOrig"];
385249259Sdim  let KeyCol = ["1"];
386249259Sdim  let ValueCols = [["0"]];
387249259Sdim}
388249259Sdim
389249259Sdim// Maps an commuted opcode to its original version
390249259Sdimdef getCommuteOrig : InstrMapping {
391249259Sdim  let FilterClass = "VOP2_REV";
392249259Sdim  let RowFields = ["RevOp"];
393249259Sdim  let ColFields = ["IsOrig"];
394249259Sdim  let KeyCol = ["0"];
395249259Sdim  let ValueCols = [["1"]];
396249259Sdim}
397249259Sdim
398251662Sdim// Test if the supplied opcode is an MIMG instruction
399251662Sdimdef isMIMG : InstrMapping {
400251662Sdim  let FilterClass = "MIMG";
401251662Sdim  let RowFields = ["Inst"];
402251662Sdim  let ColFields = ["Size"];
403251662Sdim  let KeyCol = ["8"];
404251662Sdim  let ValueCols = [["8"]];
405251662Sdim}
406251662Sdim
407249259Sdiminclude "SIInstructions.td"
408