Set REQUIRES shell on the test cases for r186044
[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 as_i16imm : SDNodeXForm<imm, [{
39   return CurDAG->getTargetConstant(N->getSExtValue(), MVT::i16);
40 }]>;
41
42 def IMM12bit : PatLeaf <(imm),
43   [{return isUInt<12>(N->getZExtValue());}]
44 >;
45
46 class InlineImm <ValueType vt> : PatLeaf <(vt imm), [{
47   return
48     (*(const SITargetLowering *)getTargetLowering()).analyzeImmediate(N) == 0;
49 }]>;
50
51 //===----------------------------------------------------------------------===//
52 // SI assembler operands
53 //===----------------------------------------------------------------------===//
54
55 def SIOperand {
56   int ZERO = 0x80;
57   int VCC = 0x6A;
58 }
59
60 include "SIInstrFormats.td"
61
62 //===----------------------------------------------------------------------===//
63 //
64 // SI Instruction multiclass helpers.
65 //
66 // Instructions with _32 take 32-bit operands.
67 // Instructions with _64 take 64-bit operands.
68 //
69 // VOP_* instructions can use either a 32-bit or 64-bit encoding.  The 32-bit
70 // encoding is the standard encoding, but instruction that make use of
71 // any of the instruction modifiers must use the 64-bit encoding.
72 //
73 // Instructions with _e32 use the 32-bit encoding.
74 // Instructions with _e64 use the 64-bit encoding.
75 //
76 //===----------------------------------------------------------------------===//
77
78 //===----------------------------------------------------------------------===//
79 // Scalar classes
80 //===----------------------------------------------------------------------===//
81
82 class SOP1_32 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
83   op, (outs SReg_32:$dst), (ins SSrc_32:$src0),
84   opName#" $dst, $src0", pattern
85 >;
86
87 class SOP1_64 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
88   op, (outs SReg_64:$dst), (ins SSrc_64:$src0),
89   opName#" $dst, $src0", pattern
90 >;
91
92 class SOP2_32 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
93   op, (outs SReg_32:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
94   opName#" $dst, $src0, $src1", pattern
95 >;
96
97 class SOP2_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
98   op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
99   opName#" $dst, $src0, $src1", pattern
100 >;
101
102 class SOPC_32 <bits<7> op, string opName, list<dag> pattern> : SOPC <
103   op, (outs SCCReg:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
104   opName#" $dst, $src0, $src1", pattern
105 >;
106
107 class SOPC_64 <bits<7> op, string opName, list<dag> pattern> : SOPC <
108   op, (outs SCCReg:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
109   opName#" $dst, $src0, $src1", pattern
110 >;
111
112 class SOPK_32 <bits<5> op, string opName, list<dag> pattern> : SOPK <
113   op, (outs SReg_32:$dst), (ins i16imm:$src0),
114   opName#" $dst, $src0", pattern
115 >;
116
117 class SOPK_64 <bits<5> op, string opName, list<dag> pattern> : SOPK <
118   op, (outs SReg_64:$dst), (ins i16imm:$src0),
119   opName#" $dst, $src0", pattern
120 >;
121
122 multiclass SMRD_Helper <bits<5> op, string asm, RegisterClass baseClass,
123                         RegisterClass dstClass> {
124   def _IMM : SMRD <
125     op, 1, (outs dstClass:$dst),
126     (ins baseClass:$sbase, i32imm:$offset),
127     asm#" $dst, $sbase, $offset", []
128   >;
129
130   def _SGPR : SMRD <
131     op, 0, (outs dstClass:$dst),
132     (ins baseClass:$sbase, SReg_32:$soff),
133     asm#" $dst, $sbase, $soff", []
134   >;
135 }
136
137 //===----------------------------------------------------------------------===//
138 // Vector ALU classes
139 //===----------------------------------------------------------------------===//
140
141 class VOP <string opName> {
142   string OpName = opName;
143 }
144
145 class VOP2_REV <string revOp, bit isOrig> {
146   string RevOp = revOp;
147   bit IsOrig = isOrig;
148 }
149
150 multiclass VOP1_Helper <bits<8> op, RegisterClass drc, RegisterClass src,
151                         string opName, list<dag> pattern> {
152
153   def _e32 : VOP1 <
154     op, (outs drc:$dst), (ins src:$src0),
155     opName#"_e32 $dst, $src0", pattern
156   >, VOP <opName>;
157
158   def _e64 : VOP3 <
159     {1, 1, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
160     (outs drc:$dst),
161     (ins src:$src0,
162          i32imm:$abs, i32imm:$clamp,
163          i32imm:$omod, i32imm:$neg),
164     opName#"_e64 $dst, $src0, $abs, $clamp, $omod, $neg", []
165   >, VOP <opName> {
166     let src1 = SIOperand.ZERO;
167     let src2 = SIOperand.ZERO;
168   }
169 }
170
171 multiclass VOP1_32 <bits<8> op, string opName, list<dag> pattern>
172   : VOP1_Helper <op, VReg_32, VSrc_32, opName, pattern>;
173
174 multiclass VOP1_64 <bits<8> op, string opName, list<dag> pattern>
175   : VOP1_Helper <op, VReg_64, VSrc_64, opName, pattern>;
176
177 multiclass VOP2_Helper <bits<6> op, RegisterClass vrc, RegisterClass arc,
178                         string opName, list<dag> pattern, string revOp> {
179   def _e32 : VOP2 <
180     op, (outs vrc:$dst), (ins arc:$src0, vrc:$src1),
181     opName#"_e32 $dst, $src0, $src1", pattern
182   >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
183
184   def _e64 : VOP3 <
185     {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
186     (outs vrc:$dst),
187     (ins arc:$src0, arc:$src1,
188          i32imm:$abs, i32imm:$clamp,
189          i32imm:$omod, i32imm:$neg),
190     opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg", []
191   >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
192     let src2 = SIOperand.ZERO;
193   }
194 }
195
196 multiclass VOP2_32 <bits<6> op, string opName, list<dag> pattern,
197                     string revOp = opName>
198   : VOP2_Helper <op, VReg_32, VSrc_32, opName, pattern, revOp>;
199
200 multiclass VOP2_64 <bits<6> op, string opName, list<dag> pattern,
201                     string revOp = opName>
202   : VOP2_Helper <op, VReg_64, VSrc_64, opName, pattern, revOp>;
203
204 multiclass VOP2b_32 <bits<6> op, string opName, list<dag> pattern,
205                      string revOp = opName> {
206
207   def _e32 : VOP2 <
208     op, (outs VReg_32:$dst), (ins VSrc_32:$src0, VReg_32:$src1),
209     opName#"_e32 $dst, $src0, $src1", pattern
210   >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
211
212   def _e64 : VOP3b <
213     {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
214     (outs VReg_32:$dst),
215     (ins VSrc_32:$src0, VSrc_32:$src1,
216          i32imm:$abs, i32imm:$clamp,
217          i32imm:$omod, i32imm:$neg),
218     opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg", []
219   >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
220     let src2 = SIOperand.ZERO;
221     /* the VOP2 variant puts the carry out into VCC, the VOP3 variant
222        can write it into any SGPR. We currently don't use the carry out,
223        so for now hardcode it to VCC as well */
224     let sdst = SIOperand.VCC;
225   }
226 }
227
228 multiclass VOPC_Helper <bits<8> op, RegisterClass vrc, RegisterClass arc,
229                         string opName, ValueType vt, PatLeaf cond> {
230
231   def _e32 : VOPC <
232     op, (ins arc:$src0, vrc:$src1),
233     opName#"_e32 $dst, $src0, $src1", []
234   >, VOP <opName>;
235
236   def _e64 : VOP3 <
237     {0, op{7}, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
238     (outs SReg_64:$dst),
239     (ins arc:$src0, arc:$src1,
240          InstFlag:$abs, InstFlag:$clamp,
241          InstFlag:$omod, InstFlag:$neg),
242     opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg",
243     !if(!eq(!cast<string>(cond), "COND_NULL"), []<dag>,
244       [(set SReg_64:$dst, (i1 (setcc (vt arc:$src0), arc:$src1, cond)))]
245     )
246   >, VOP <opName> {
247     let src2 = SIOperand.ZERO;
248   }
249 }
250
251 multiclass VOPC_32 <bits<8> op, string opName,
252   ValueType vt = untyped, PatLeaf cond = COND_NULL>
253   : VOPC_Helper <op, VReg_32, VSrc_32, opName, vt, cond>;
254
255 multiclass VOPC_64 <bits<8> op, string opName,
256   ValueType vt = untyped, PatLeaf cond = COND_NULL>
257   : VOPC_Helper <op, VReg_64, VSrc_64, opName, vt, cond>;
258
259 class VOP3_32 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
260   op, (outs VReg_32:$dst),
261   (ins VSrc_32:$src0, VSrc_32:$src1, VSrc_32:$src2,
262    InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg),
263   opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
264 >, VOP <opName>;
265
266 class VOP3_64_Shift <bits <9> op, string opName, list<dag> pattern> : VOP3 <
267   op, (outs VReg_64:$dst),
268   (ins VSrc_64:$src0, VSrc_32:$src1),
269   opName#" $dst, $src0, $src1", pattern
270 >, VOP <opName> {
271
272   let src2 = SIOperand.ZERO;
273   let abs = 0;
274   let clamp = 0;
275   let omod = 0;
276   let neg = 0;
277 }
278
279 class VOP3_64 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
280   op, (outs VReg_64:$dst),
281   (ins VSrc_64:$src0, VSrc_64:$src1, VSrc_64:$src2,
282    InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg),
283   opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
284 >, VOP <opName>;
285
286 //===----------------------------------------------------------------------===//
287 // Vector I/O classes
288 //===----------------------------------------------------------------------===//
289
290 class DS_Load_Helper <bits<8> op, string asm, RegisterClass regClass> : DS <
291   op,
292   (outs regClass:$vdst),
293   (ins i1imm:$gds, VReg_32:$addr, VReg_32:$data0, VReg_32:$data1,
294        i8imm:$offset0, i8imm:$offset1),
295   asm#" $vdst, $gds, $addr, $data0, $data1, $offset0, $offset1, [M0]",
296   []> {
297   let mayLoad = 1;
298   let mayStore = 0;
299 }
300
301 class DS_Store_Helper <bits<8> op, string asm, RegisterClass regClass> : DS <
302   op,
303   (outs),
304   (ins i1imm:$gds, VReg_32:$addr, VReg_32:$data0, VReg_32:$data1,
305        i8imm:$offset0, i8imm:$offset1),
306   asm#" $gds, $addr, $data0, $data1, $offset0, $offset1, [M0]",
307   []> {
308   let mayStore = 1;
309   let mayLoad = 0;
310   let vdst = 0;
311 }
312
313 class MTBUF_Store_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
314   op,
315   (outs),
316   (ins regClass:$vdata, i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
317    i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr,
318    SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
319   asm#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
320      #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
321   []> {
322   let mayStore = 1;
323   let mayLoad = 0;
324 }
325
326 multiclass MUBUF_Load_Helper <bits<7> op, string asm, RegisterClass regClass> {
327
328   let glc = 0, lds = 0, slc = 0, tfe = 0, soffset = 128 /* ZERO */,
329                                           mayLoad = 1 in {
330
331   let offen = 1, idxen = 0, addr64 = 0, offset = 0 in {
332     def _OFFEN  : MUBUF <op, (outs regClass:$vdata),
333                          (ins SReg_128:$srsrc, VReg_32:$vaddr),
334                          asm#" $vdata, $srsrc + $vaddr", []>;
335   }
336
337   let offen = 0, idxen = 1, addr64 = 0 in {
338     def _IDXEN  : MUBUF <op, (outs regClass:$vdata),
339                          (ins SReg_128:$srsrc, VReg_32:$vaddr, i16imm:$offset),
340                          asm#" $vdata, $srsrc[$vaddr] + $offset", []>;
341   }
342
343   let offen = 0, idxen = 0, addr64 = 1 in {
344     def _ADDR64 : MUBUF <op, (outs regClass:$vdata),
345                          (ins SReg_128:$srsrc, VReg_64:$vaddr, i16imm:$offset),
346                          asm#" $vdata, $srsrc + $vaddr + $offset", []>;
347   }
348   }
349 }
350
351 class MUBUF_Store_Helper <bits<7> op, string name, RegisterClass vdataClass,
352                          ValueType VT> :
353     MUBUF <op, (outs), (ins vdataClass:$vdata, SReg_128:$srsrc, VReg_64:$vaddr, i16imm:$offset),
354           name#" $vdata, $srsrc + $vaddr + $offset",
355          []> {
356
357   let mayLoad = 0;
358   let mayStore = 1;
359
360   // Encoding
361   let offen = 0;
362   let idxen = 0;
363   let glc = 0;
364   let addr64 = 1;
365   let lds = 0;
366   let slc = 0;
367   let tfe = 0;
368   let soffset = 128; // ZERO
369 }
370
371 class MTBUF_Load_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
372   op,
373   (outs regClass:$dst),
374   (ins i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
375        i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, SReg_128:$srsrc,
376        i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
377   asm#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
378      #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
379   []> {
380   let mayLoad = 1;
381   let mayStore = 0;
382 }
383
384 class MIMG_NoSampler_Helper <bits<7> op, string asm> : MIMG <
385   op,
386   (outs VReg_128:$vdata),
387   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
388        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, unknown:$vaddr,
389        SReg_256:$srsrc),
390   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
391      #" $tfe, $lwe, $slc, $vaddr, $srsrc",
392   []> {
393   let SSAMP = 0;
394   let mayLoad = 1;
395   let mayStore = 0;
396   let hasPostISelHook = 1;
397 }
398
399 class MIMG_Sampler_Helper <bits<7> op, string asm> : MIMG <
400   op,
401   (outs VReg_128:$vdata),
402   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
403        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, unknown:$vaddr,
404        SReg_256:$srsrc, SReg_128:$ssamp),
405   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
406      #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
407   []> {
408   let mayLoad = 1;
409   let mayStore = 0;
410   let hasPostISelHook = 1;
411 }
412
413 //===----------------------------------------------------------------------===//
414 // Vector instruction mappings
415 //===----------------------------------------------------------------------===//
416
417 // Maps an opcode in e32 form to its e64 equivalent
418 def getVOPe64 : InstrMapping {
419   let FilterClass = "VOP";
420   let RowFields = ["OpName"];
421   let ColFields = ["Size"];
422   let KeyCol = ["4"];
423   let ValueCols = [["8"]];
424 }
425
426 // Maps an original opcode to its commuted version
427 def getCommuteRev : InstrMapping {
428   let FilterClass = "VOP2_REV";
429   let RowFields = ["RevOp"];
430   let ColFields = ["IsOrig"];
431   let KeyCol = ["1"];
432   let ValueCols = [["0"]];
433 }
434
435 // Maps an commuted opcode to its original version
436 def getCommuteOrig : InstrMapping {
437   let FilterClass = "VOP2_REV";
438   let RowFields = ["RevOp"];
439   let ColFields = ["IsOrig"];
440   let KeyCol = ["0"];
441   let ValueCols = [["1"]];
442 }
443
444 // Test if the supplied opcode is an MIMG instruction
445 def isMIMG : InstrMapping {
446   let FilterClass = "MIMG";
447   let RowFields = ["Inst"];
448   let ColFields = ["Size"];
449   let KeyCol = ["8"];
450   let ValueCols = [["8"]];
451 }
452
453 include "SIInstructions.td"