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