19d9de1ffc89ce2b22d1689b053906a0295353a5
[oota-llvm.git] / lib / Target / R600 / SIInstrInfo.td
1 //===-- SIInstrInfo.td - SI Instruction Infos -------------*- tablegen -*--===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 //===----------------------------------------------------------------------===//
11 // SI DAG Nodes
12 //===----------------------------------------------------------------------===//
13
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>]>
17 >;
18
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);
22 }]>;
23
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);
27 }]>;
28
29 def IMM8bitDWORD : ImmLeaf <
30   i32, [{
31     return (Imm & ~0x3FC) == 0;
32   }], SDNodeXForm<imm, [{
33     return CurDAG->getTargetConstant(
34       N->getZExtValue() >> 2, MVT::i32);
35   }]>
36 >;
37
38 def IMM12bit : ImmLeaf <
39   i16,
40   [{return isUInt<12>(Imm);}]
41 >;
42
43 class InlineImm <ValueType vt> : PatLeaf <(vt imm), [{
44   return ((const SITargetLowering &)TLI).analyzeImmediate(N) == 0;
45 }]>;
46
47 //===----------------------------------------------------------------------===//
48 // SI assembler operands
49 //===----------------------------------------------------------------------===//
50
51 def SIOperand {
52   int ZERO = 0x80;
53   int VCC = 0x6A;
54 }
55
56 include "SIInstrFormats.td"
57
58 //===----------------------------------------------------------------------===//
59 //
60 // SI Instruction multiclass helpers.
61 //
62 // Instructions with _32 take 32-bit operands.
63 // Instructions with _64 take 64-bit operands.
64 //
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.
68 //
69 // Instructions with _e32 use the 32-bit encoding.
70 // Instructions with _e64 use the 64-bit encoding.
71 //
72 //===----------------------------------------------------------------------===//
73
74 //===----------------------------------------------------------------------===//
75 // Scalar classes
76 //===----------------------------------------------------------------------===//
77
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
81 >;
82
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
86 >;
87
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
91 >;
92
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
96 >;
97
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
101 >;
102
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
106 >;
107
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
111 >;
112
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
116 >;
117
118 multiclass SMRD_Helper <bits<5> op, string asm, RegisterClass baseClass,
119                         RegisterClass dstClass> {
120   def _IMM : SMRD <
121     op, 1, (outs dstClass:$dst),
122     (ins baseClass:$sbase, i32imm:$offset),
123     asm#" $dst, $sbase, $offset", []
124   >;
125
126   def _SGPR : SMRD <
127     op, 0, (outs dstClass:$dst),
128     (ins baseClass:$sbase, SReg_32:$soff),
129     asm#" $dst, $sbase, $soff", []
130   >;
131 }
132
133 //===----------------------------------------------------------------------===//
134 // Vector ALU classes
135 //===----------------------------------------------------------------------===//
136
137 class VOP <string opName> {
138   string OpName = opName;
139 }
140
141 class VOP2_REV <string revOp, bit isOrig> {
142   string RevOp = revOp;
143   bit IsOrig = isOrig;
144 }
145
146 multiclass VOP1_Helper <bits<8> op, RegisterClass drc, RegisterClass src,
147                         string opName, list<dag> pattern> {
148
149   def _e32 : VOP1 <
150     op, (outs drc:$dst), (ins src:$src0),
151     opName#"_e32 $dst, $src0", pattern
152   >, VOP <opName>;
153
154   def _e64 : VOP3 <
155     {1, 1, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
156     (outs drc:$dst),
157     (ins src:$src0,
158          i32imm:$abs, i32imm:$clamp,
159          i32imm:$omod, i32imm:$neg),
160     opName#"_e64 $dst, $src0, $abs, $clamp, $omod, $neg", []
161   >, VOP <opName> {
162     let src1 = SIOperand.ZERO;
163     let src2 = SIOperand.ZERO;
164   }
165 }
166
167 multiclass VOP1_32 <bits<8> op, string opName, list<dag> pattern>
168   : VOP1_Helper <op, VReg_32, VSrc_32, opName, pattern>;
169
170 multiclass VOP1_64 <bits<8> op, string opName, list<dag> pattern>
171   : VOP1_Helper <op, VReg_64, VSrc_64, opName, pattern>;
172
173 multiclass VOP2_Helper <bits<6> op, RegisterClass vrc, RegisterClass arc,
174                         string opName, list<dag> pattern, string revOp> {
175   def _e32 : VOP2 <
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)>;
179
180   def _e64 : VOP3 <
181     {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
182     (outs vrc:$dst),
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;
189   }
190 }
191
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>;
195
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>;
199
200 multiclass VOP2b_32 <bits<6> op, string opName, list<dag> pattern,
201                      string revOp = opName> {
202
203   def _e32 : VOP2 <
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)>;
207
208   def _e64 : VOP3b <
209     {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
210     (outs VReg_32:$dst),
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;
221   }
222 }
223
224 multiclass VOPC_Helper <bits<8> op, RegisterClass vrc, RegisterClass arc,
225                         string opName, ValueType vt, PatLeaf cond> {
226
227   def _e32 : VOPC <
228     op, (ins arc:$src0, vrc:$src1),
229     opName#"_e32 $dst, $src0, $src1", []
230   >, VOP <opName>;
231
232   def _e64 : VOP3 <
233     {0, op{7}, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
234     (outs SReg_64:$dst),
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)))]
241     )
242   >, VOP <opName> {
243     let src2 = SIOperand.ZERO;
244   }
245 }
246
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>;
250
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>;
254
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    InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg),
259   opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
260 >, VOP <opName>;
261
262 class VOP3_64_Shift <bits <9> op, string opName, list<dag> pattern> : VOP3 <
263   op, (outs VReg_64:$dst),
264   (ins VSrc_64:$src0, VSrc_32:$src1),
265   opName#" $dst, $src0, $src1", pattern
266 >, VOP <opName> {
267
268   let src2 = SIOperand.ZERO;
269   let abs = 0;
270   let clamp = 0;
271   let omod = 0;
272   let neg = 0;
273 }
274
275 class VOP3_64 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
276   op, (outs VReg_64:$dst),
277   (ins VSrc_64:$src0, VSrc_64:$src1, VSrc_64:$src2,
278    InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg),
279   opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
280 >, VOP <opName>;
281
282 //===----------------------------------------------------------------------===//
283 // Vector I/O classes
284 //===----------------------------------------------------------------------===//
285
286 class MTBUF_Store_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
287   op,
288   (outs),
289   (ins regClass:$vdata, i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
290    i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr,
291    SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
292   asm#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
293      #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
294   []> {
295   let mayStore = 1;
296   let mayLoad = 0;
297 }
298
299 multiclass MUBUF_Load_Helper <bits<7> op, string asm, RegisterClass regClass> {
300
301   let glc = 0, lds = 0, slc = 0, tfe = 0, soffset = 128 /* ZERO */,
302                                           mayLoad = 1 in {
303
304   let offen = 1, idxen = 0, addr64 = 0, offset = 0 in {
305     def _OFFEN  : MUBUF <op, (outs regClass:$vdata),
306                          (ins SReg_128:$srsrc, VReg_32:$vaddr),
307                          asm#" $vdata, $srsrc + $vaddr", []>;
308   }
309
310   let offen = 0, idxen = 1, addr64 = 0 in {
311     def _IDXEN  : MUBUF <op, (outs regClass:$vdata),
312                          (ins SReg_128:$srsrc, VReg_32:$vaddr, i16imm:$offset),
313                          asm#" $vdata, $srsrc[$vaddr] + $offset", []>;
314   }
315
316   let offen = 0, idxen = 0, addr64 = 1 in {
317     def _ADDR64 : MUBUF <op, (outs regClass:$vdata),
318                          (ins SReg_128:$srsrc, VReg_64:$vaddr, i16imm:$offset),
319                          asm#" $vdata, $srsrc + $vaddr + $offset", []>;
320   }
321   }
322 }
323
324 class MUBUF_Store_Helper <bits<7> op, string name, RegisterClass vdataClass,
325                          ValueType VT> :
326     MUBUF <op, (outs), (ins vdataClass:$vdata, SReg_128:$srsrc, VReg_64:$vaddr, i16imm:$offset),
327           name#" $vdata, $srsrc + $vaddr + $offset",
328          []> {
329
330   let mayLoad = 0;
331   let mayStore = 1;
332
333   // Encoding
334   let offen = 0;
335   let idxen = 0;
336   let glc = 0;
337   let addr64 = 1;
338   let lds = 0;
339   let slc = 0;
340   let tfe = 0;
341   let soffset = 128; // ZERO
342 }
343
344 class MTBUF_Load_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
345   op,
346   (outs regClass:$dst),
347   (ins i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
348        i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, SReg_128:$srsrc,
349        i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
350   asm#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
351      #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
352   []> {
353   let mayLoad = 1;
354   let mayStore = 0;
355 }
356
357 class MIMG_NoSampler_Helper <bits<7> op, string asm> : MIMG <
358   op,
359   (outs VReg_128:$vdata),
360   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
361        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, unknown:$vaddr,
362        SReg_256:$srsrc),
363   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
364      #" $tfe, $lwe, $slc, $vaddr, $srsrc",
365   []> {
366   let SSAMP = 0;
367   let mayLoad = 1;
368   let mayStore = 0;
369   let hasPostISelHook = 1;
370 }
371
372 class MIMG_Sampler_Helper <bits<7> op, string asm> : MIMG <
373   op,
374   (outs VReg_128:$vdata),
375   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
376        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, unknown:$vaddr,
377        SReg_256:$srsrc, SReg_128:$ssamp),
378   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
379      #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
380   []> {
381   let mayLoad = 1;
382   let mayStore = 0;
383   let hasPostISelHook = 1;
384 }
385
386 //===----------------------------------------------------------------------===//
387 // Vector instruction mappings
388 //===----------------------------------------------------------------------===//
389
390 // Maps an opcode in e32 form to its e64 equivalent
391 def getVOPe64 : InstrMapping {
392   let FilterClass = "VOP";
393   let RowFields = ["OpName"];
394   let ColFields = ["Size"];
395   let KeyCol = ["4"];
396   let ValueCols = [["8"]];
397 }
398
399 // Maps an original opcode to its commuted version
400 def getCommuteRev : InstrMapping {
401   let FilterClass = "VOP2_REV";
402   let RowFields = ["RevOp"];
403   let ColFields = ["IsOrig"];
404   let KeyCol = ["1"];
405   let ValueCols = [["0"]];
406 }
407
408 // Maps an commuted opcode to its original version
409 def getCommuteOrig : InstrMapping {
410   let FilterClass = "VOP2_REV";
411   let RowFields = ["RevOp"];
412   let ColFields = ["IsOrig"];
413   let KeyCol = ["0"];
414   let ValueCols = [["1"]];
415 }
416
417 // Test if the supplied opcode is an MIMG instruction
418 def isMIMG : InstrMapping {
419   let FilterClass = "MIMG";
420   let RowFields = ["Inst"];
421   let ColFields = ["Size"];
422   let KeyCol = ["8"];
423   let ValueCols = [["8"]];
424 }
425
426 include "SIInstructions.td"