SIInstrInfo.td revision 249259
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
29249259Sdimdef IMM8bitDWORD : ImmLeaf <
30249259Sdim  i32, [{
31249259Sdim    return (Imm & ~0x3FC) == 0;
32249259Sdim  }], SDNodeXForm<imm, [{
33249259Sdim    return CurDAG->getTargetConstant(
34249259Sdim      N->getZExtValue() >> 2, MVT::i32);
35249259Sdim  }]>
36249259Sdim>;
37249259Sdim
38249259Sdimdef IMM12bit : ImmLeaf <
39249259Sdim  i16,
40249259Sdim  [{return isUInt<12>(Imm);}]
41249259Sdim>;
42249259Sdim
43249259Sdimclass InlineImm <ValueType vt> : PatLeaf <(vt imm), [{
44249259Sdim  return ((const SITargetLowering &)TLI).analyzeImmediate(N) == 0;
45249259Sdim}]>;
46249259Sdim
47249259Sdim//===----------------------------------------------------------------------===//
48249259Sdim// SI assembler operands
49249259Sdim//===----------------------------------------------------------------------===//
50249259Sdim
51249259Sdimdef SIOperand {
52249259Sdim  int ZERO = 0x80;
53249259Sdim  int VCC = 0x6A;
54249259Sdim}
55249259Sdim
56249259Sdiminclude "SIInstrFormats.td"
57249259Sdim
58249259Sdim//===----------------------------------------------------------------------===//
59249259Sdim//
60249259Sdim// SI Instruction multiclass helpers.
61249259Sdim//
62249259Sdim// Instructions with _32 take 32-bit operands.
63249259Sdim// Instructions with _64 take 64-bit operands.
64249259Sdim//
65249259Sdim// VOP_* instructions can use either a 32-bit or 64-bit encoding.  The 32-bit
66249259Sdim// encoding is the standard encoding, but instruction that make use of
67249259Sdim// any of the instruction modifiers must use the 64-bit encoding.
68249259Sdim//
69249259Sdim// Instructions with _e32 use the 32-bit encoding.
70249259Sdim// Instructions with _e64 use the 64-bit encoding.
71249259Sdim//
72249259Sdim//===----------------------------------------------------------------------===//
73249259Sdim
74249259Sdim//===----------------------------------------------------------------------===//
75249259Sdim// Scalar classes
76249259Sdim//===----------------------------------------------------------------------===//
77249259Sdim
78249259Sdimclass SOP1_32 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
79249259Sdim  op, (outs SReg_32:$dst), (ins SSrc_32:$src0),
80249259Sdim  opName#" $dst, $src0", pattern
81249259Sdim>;
82249259Sdim
83249259Sdimclass SOP1_64 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
84249259Sdim  op, (outs SReg_64:$dst), (ins SSrc_64:$src0),
85249259Sdim  opName#" $dst, $src0", pattern
86249259Sdim>;
87249259Sdim
88249259Sdimclass SOP2_32 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
89249259Sdim  op, (outs SReg_32:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
90249259Sdim  opName#" $dst, $src0, $src1", pattern
91249259Sdim>;
92249259Sdim
93249259Sdimclass SOP2_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
94249259Sdim  op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
95249259Sdim  opName#" $dst, $src0, $src1", pattern
96249259Sdim>;
97249259Sdim
98249259Sdimclass SOPC_32 <bits<7> op, string opName, list<dag> pattern> : SOPC <
99249259Sdim  op, (outs SCCReg:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
100249259Sdim  opName#" $dst, $src0, $src1", pattern
101249259Sdim>;
102249259Sdim
103249259Sdimclass SOPC_64 <bits<7> op, string opName, list<dag> pattern> : SOPC <
104249259Sdim  op, (outs SCCReg:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
105249259Sdim  opName#" $dst, $src0, $src1", pattern
106249259Sdim>;
107249259Sdim
108249259Sdimclass SOPK_32 <bits<5> op, string opName, list<dag> pattern> : SOPK <
109249259Sdim  op, (outs SReg_32:$dst), (ins i16imm:$src0),
110249259Sdim  opName#" $dst, $src0", pattern
111249259Sdim>;
112249259Sdim
113249259Sdimclass SOPK_64 <bits<5> op, string opName, list<dag> pattern> : SOPK <
114249259Sdim  op, (outs SReg_64:$dst), (ins i16imm:$src0),
115249259Sdim  opName#" $dst, $src0", pattern
116249259Sdim>;
117249259Sdim
118249259Sdimmulticlass SMRD_Helper <bits<5> op, string asm, RegisterClass baseClass,
119249259Sdim                        RegisterClass dstClass> {
120249259Sdim  def _IMM : SMRD <
121249259Sdim    op, 1, (outs dstClass:$dst),
122249259Sdim    (ins baseClass:$sbase, i32imm:$offset),
123249259Sdim    asm#" $dst, $sbase, $offset", []
124249259Sdim  >;
125249259Sdim
126249259Sdim  def _SGPR : SMRD <
127249259Sdim    op, 0, (outs dstClass:$dst),
128249259Sdim    (ins baseClass:$sbase, SReg_32:$soff),
129249259Sdim    asm#" $dst, $sbase, $soff", []
130249259Sdim  >;
131249259Sdim}
132249259Sdim
133249259Sdim//===----------------------------------------------------------------------===//
134249259Sdim// Vector ALU classes
135249259Sdim//===----------------------------------------------------------------------===//
136249259Sdim
137249259Sdimclass VOP <string opName> {
138249259Sdim  string OpName = opName;
139249259Sdim}
140249259Sdim
141249259Sdimclass VOP2_REV <string revOp, bit isOrig> {
142249259Sdim  string RevOp = revOp;
143249259Sdim  bit IsOrig = isOrig;
144249259Sdim}
145249259Sdim
146249259Sdimmulticlass VOP1_Helper <bits<8> op, RegisterClass drc, RegisterClass src,
147249259Sdim                        string opName, list<dag> pattern> {
148249259Sdim
149249259Sdim  def _e32 : VOP1 <
150249259Sdim    op, (outs drc:$dst), (ins src:$src0),
151249259Sdim    opName#"_e32 $dst, $src0", pattern
152249259Sdim  >, VOP <opName>;
153249259Sdim
154249259Sdim  def _e64 : VOP3 <
155249259Sdim    {1, 1, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
156249259Sdim    (outs drc:$dst),
157249259Sdim    (ins src:$src0,
158249259Sdim         i32imm:$abs, i32imm:$clamp,
159249259Sdim         i32imm:$omod, i32imm:$neg),
160249259Sdim    opName#"_e64 $dst, $src0, $abs, $clamp, $omod, $neg", []
161249259Sdim  >, VOP <opName> {
162249259Sdim    let SRC1 = SIOperand.ZERO;
163249259Sdim    let SRC2 = SIOperand.ZERO;
164249259Sdim  }
165249259Sdim}
166249259Sdim
167249259Sdimmulticlass VOP1_32 <bits<8> op, string opName, list<dag> pattern>
168249259Sdim  : VOP1_Helper <op, VReg_32, VSrc_32, opName, pattern>;
169249259Sdim
170249259Sdimmulticlass VOP1_64 <bits<8> op, string opName, list<dag> pattern>
171249259Sdim  : VOP1_Helper <op, VReg_64, VSrc_64, opName, pattern>;
172249259Sdim
173249259Sdimmulticlass VOP2_Helper <bits<6> op, RegisterClass vrc, RegisterClass arc,
174249259Sdim                        string opName, list<dag> pattern, string revOp> {
175249259Sdim  def _e32 : VOP2 <
176249259Sdim    op, (outs vrc:$dst), (ins arc:$src0, vrc:$src1),
177249259Sdim    opName#"_e32 $dst, $src0, $src1", pattern
178249259Sdim  >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
179249259Sdim
180249259Sdim  def _e64 : VOP3 <
181249259Sdim    {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
182249259Sdim    (outs vrc:$dst),
183249259Sdim    (ins arc:$src0, arc:$src1,
184249259Sdim         i32imm:$abs, i32imm:$clamp,
185249259Sdim         i32imm:$omod, i32imm:$neg),
186249259Sdim    opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg", []
187249259Sdim  >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
188249259Sdim    let SRC2 = SIOperand.ZERO;
189249259Sdim  }
190249259Sdim}
191249259Sdim
192249259Sdimmulticlass VOP2_32 <bits<6> op, string opName, list<dag> pattern,
193249259Sdim                    string revOp = opName>
194249259Sdim  : VOP2_Helper <op, VReg_32, VSrc_32, opName, pattern, revOp>;
195249259Sdim
196249259Sdimmulticlass VOP2_64 <bits<6> op, string opName, list<dag> pattern,
197249259Sdim                    string revOp = opName>
198249259Sdim  : VOP2_Helper <op, VReg_64, VSrc_64, opName, pattern, revOp>;
199249259Sdim
200249259Sdimmulticlass VOP2b_32 <bits<6> op, string opName, list<dag> pattern,
201249259Sdim                     string revOp = opName> {
202249259Sdim
203249259Sdim  def _e32 : VOP2 <
204249259Sdim    op, (outs VReg_32:$dst), (ins VSrc_32:$src0, VReg_32:$src1),
205249259Sdim    opName#"_e32 $dst, $src0, $src1", pattern
206249259Sdim  >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
207249259Sdim
208249259Sdim  def _e64 : VOP3b <
209249259Sdim    {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
210249259Sdim    (outs VReg_32:$dst),
211249259Sdim    (ins VSrc_32:$src0, VSrc_32:$src1,
212249259Sdim         i32imm:$abs, i32imm:$clamp,
213249259Sdim         i32imm:$omod, i32imm:$neg),
214249259Sdim    opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg", []
215249259Sdim  >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
216249259Sdim    let SRC2 = SIOperand.ZERO;
217249259Sdim    /* the VOP2 variant puts the carry out into VCC, the VOP3 variant
218249259Sdim       can write it into any SGPR. We currently don't use the carry out,
219249259Sdim       so for now hardcode it to VCC as well */
220249259Sdim    let SDST = SIOperand.VCC;
221249259Sdim  }
222249259Sdim}
223249259Sdim
224249259Sdimmulticlass VOPC_Helper <bits<8> op, RegisterClass vrc, RegisterClass arc,
225249259Sdim                        string opName, ValueType vt, PatLeaf cond> {
226249259Sdim
227249259Sdim  def _e32 : VOPC <
228249259Sdim    op, (ins arc:$src0, vrc:$src1),
229249259Sdim    opName#"_e32 $dst, $src0, $src1", []
230249259Sdim  >, VOP <opName>;
231249259Sdim
232249259Sdim  def _e64 : VOP3 <
233249259Sdim    {0, op{7}, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
234249259Sdim    (outs SReg_64:$dst),
235249259Sdim    (ins arc:$src0, arc:$src1,
236249259Sdim         InstFlag:$abs, InstFlag:$clamp,
237249259Sdim         InstFlag:$omod, InstFlag:$neg),
238249259Sdim    opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg",
239249259Sdim    !if(!eq(!cast<string>(cond), "COND_NULL"), []<dag>,
240249259Sdim      [(set SReg_64:$dst, (i1 (setcc (vt arc:$src0), arc:$src1, cond)))]
241249259Sdim    )
242249259Sdim  >, VOP <opName> {
243249259Sdim    let SRC2 = SIOperand.ZERO;
244249259Sdim  }
245249259Sdim}
246249259Sdim
247249259Sdimmulticlass VOPC_32 <bits<8> op, string opName,
248249259Sdim  ValueType vt = untyped, PatLeaf cond = COND_NULL>
249249259Sdim  : VOPC_Helper <op, VReg_32, VSrc_32, opName, vt, cond>;
250249259Sdim
251249259Sdimmulticlass VOPC_64 <bits<8> op, string opName,
252249259Sdim  ValueType vt = untyped, PatLeaf cond = COND_NULL>
253249259Sdim  : VOPC_Helper <op, VReg_64, VSrc_64, opName, vt, cond>;
254249259Sdim
255249259Sdimclass VOP3_32 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
256249259Sdim  op, (outs VReg_32:$dst),
257249259Sdim  (ins VSrc_32:$src0, VSrc_32:$src1, VSrc_32:$src2,
258249259Sdim   i32imm:$abs, i32imm:$clamp, i32imm:$omod, i32imm:$neg),
259249259Sdim  opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
260249259Sdim>, VOP <opName>;
261249259Sdim
262249259Sdimclass VOP3_64 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
263249259Sdim  op, (outs VReg_64:$dst),
264249259Sdim  (ins VSrc_64:$src0, VSrc_64:$src1, VSrc_64:$src2,
265249259Sdim   i32imm:$abs, i32imm:$clamp, i32imm:$omod, i32imm:$neg),
266249259Sdim  opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
267249259Sdim>, VOP <opName>;
268249259Sdim
269249259Sdim//===----------------------------------------------------------------------===//
270249259Sdim// Vector I/O classes
271249259Sdim//===----------------------------------------------------------------------===//
272249259Sdim
273249259Sdimclass MTBUF_Store_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
274249259Sdim  op,
275249259Sdim  (outs),
276249259Sdim  (ins regClass:$vdata, i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
277249259Sdim   i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr,
278249259Sdim   SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
279249259Sdim  asm#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
280249259Sdim     #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
281249259Sdim  []> {
282249259Sdim  let mayStore = 1;
283249259Sdim  let mayLoad = 0;
284249259Sdim}
285249259Sdim
286249259Sdimclass MUBUF_Load_Helper <bits<7> op, string asm, RegisterClass regClass> : MUBUF <
287249259Sdim  op,
288249259Sdim  (outs regClass:$dst),
289249259Sdim  (ins i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
290249259Sdim       i1imm:$lds, VReg_32:$vaddr, SReg_128:$srsrc, i1imm:$slc,
291249259Sdim       i1imm:$tfe, SSrc_32:$soffset),
292249259Sdim  asm#" $dst, $offset, $offen, $idxen, $glc, $addr64, "
293249259Sdim     #"$lds, $vaddr, $srsrc, $slc, $tfe, $soffset",
294249259Sdim  []> {
295249259Sdim  let mayLoad = 1;
296249259Sdim  let mayStore = 0;
297249259Sdim}
298249259Sdim
299249259Sdimclass MTBUF_Load_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
300249259Sdim  op,
301249259Sdim  (outs regClass:$dst),
302249259Sdim  (ins i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
303249259Sdim       i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, SReg_128:$srsrc,
304249259Sdim       i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
305249259Sdim  asm#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
306249259Sdim     #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
307249259Sdim  []> {
308249259Sdim  let mayLoad = 1;
309249259Sdim  let mayStore = 0;
310249259Sdim}
311249259Sdim
312249259Sdimclass MIMG_Load_Helper <bits<7> op, string asm> : MIMG <
313249259Sdim  op,
314249259Sdim  (outs VReg_128:$vdata),
315249259Sdim  (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
316249259Sdim       i1imm:$tfe, i1imm:$lwe, i1imm:$slc, unknown:$vaddr,
317249259Sdim       SReg_256:$srsrc, SReg_128:$ssamp),
318249259Sdim  asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
319249259Sdim     #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
320249259Sdim  []> {
321249259Sdim  let mayLoad = 1;
322249259Sdim  let mayStore = 0;
323249259Sdim}
324249259Sdim
325249259Sdim//===----------------------------------------------------------------------===//
326249259Sdim// Vector instruction mappings
327249259Sdim//===----------------------------------------------------------------------===//
328249259Sdim
329249259Sdim// Maps an opcode in e32 form to its e64 equivalent
330249259Sdimdef getVOPe64 : InstrMapping {
331249259Sdim  let FilterClass = "VOP";
332249259Sdim  let RowFields = ["OpName"];
333249259Sdim  let ColFields = ["Size"];
334249259Sdim  let KeyCol = ["4"];
335249259Sdim  let ValueCols = [["8"]];
336249259Sdim}
337249259Sdim
338249259Sdim// Maps an original opcode to its commuted version
339249259Sdimdef getCommuteRev : InstrMapping {
340249259Sdim  let FilterClass = "VOP2_REV";
341249259Sdim  let RowFields = ["RevOp"];
342249259Sdim  let ColFields = ["IsOrig"];
343249259Sdim  let KeyCol = ["1"];
344249259Sdim  let ValueCols = [["0"]];
345249259Sdim}
346249259Sdim
347249259Sdim// Maps an commuted opcode to its original version
348249259Sdimdef getCommuteOrig : InstrMapping {
349249259Sdim  let FilterClass = "VOP2_REV";
350249259Sdim  let RowFields = ["RevOp"];
351249259Sdim  let ColFields = ["IsOrig"];
352249259Sdim  let KeyCol = ["0"];
353249259Sdim  let ValueCols = [["1"]];
354249259Sdim}
355249259Sdim
356249259Sdiminclude "SIInstructions.td"
357