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