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