R600: Add support for local memory atomic add
[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 DS_1A1D_RET <bits<8> op, string asm, RegisterClass rc> : DS <
366   op,
367   (outs rc:$vdst),
368   (ins i1imm:$gds, VReg_32:$addr, VReg_32:$data0, i8imm:$offset0,
369        i8imm:$offset1),
370   asm#" $gds, $vdst, $addr, $data0, $offset0, $offset1, [M0]",
371   []> {
372   let mayStore = 1;
373   let mayLoad = 1;
374   let data1 = 0;
375 }
376
377 class MTBUF_Store_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
378   op,
379   (outs),
380   (ins regClass:$vdata, i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
381    i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr,
382    SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
383   asm#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
384      #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
385   []> {
386   let mayStore = 1;
387   let mayLoad = 0;
388 }
389
390 multiclass MUBUF_Load_Helper <bits<7> op, string asm, RegisterClass regClass> {
391
392   let glc = 0, lds = 0, slc = 0, tfe = 0, soffset = 128 /* ZERO */,
393                                           mayLoad = 1 in {
394
395   let offen = 1, idxen = 0, addr64 = 0, offset = 0 in {
396     def _OFFEN  : MUBUF <op, (outs regClass:$vdata),
397                          (ins SReg_128:$srsrc, VReg_32:$vaddr),
398                          asm#" $vdata, $srsrc + $vaddr", []>;
399   }
400
401   let offen = 0, idxen = 1, addr64 = 0 in {
402     def _IDXEN  : MUBUF <op, (outs regClass:$vdata),
403                          (ins SReg_128:$srsrc, VReg_32:$vaddr, i16imm:$offset),
404                          asm#" $vdata, $srsrc[$vaddr] + $offset", []>;
405   }
406
407   let offen = 0, idxen = 0, addr64 = 1 in {
408     def _ADDR64 : MUBUF <op, (outs regClass:$vdata),
409                          (ins SReg_128:$srsrc, VReg_64:$vaddr, i16imm:$offset),
410                          asm#" $vdata, $srsrc + $vaddr + $offset", []>;
411   }
412   }
413 }
414
415 class MUBUF_Store_Helper <bits<7> op, string name, RegisterClass vdataClass> :
416     MUBUF <op, (outs), (ins vdataClass:$vdata, SReg_128:$srsrc, VReg_64:$vaddr,
417                             i16imm:$offset),
418           name#" $vdata, $srsrc + $vaddr + $offset",
419          []> {
420
421   let mayLoad = 0;
422   let mayStore = 1;
423
424   // Encoding
425   let offen = 0;
426   let idxen = 0;
427   let glc = 0;
428   let addr64 = 1;
429   let lds = 0;
430   let slc = 0;
431   let tfe = 0;
432   let soffset = 128; // ZERO
433 }
434
435 class MTBUF_Load_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
436   op,
437   (outs regClass:$dst),
438   (ins i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
439        i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, SReg_128:$srsrc,
440        i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
441   asm#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
442      #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
443   []> {
444   let mayLoad = 1;
445   let mayStore = 0;
446 }
447
448 class MIMG_NoSampler_Helper <bits<7> op, string asm,
449                              RegisterClass src_rc> : MIMG <
450   op,
451   (outs VReg_128:$vdata),
452   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
453        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
454        SReg_256:$srsrc),
455   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
456      #" $tfe, $lwe, $slc, $vaddr, $srsrc",
457   []> {
458   let SSAMP = 0;
459   let mayLoad = 1;
460   let mayStore = 0;
461   let hasPostISelHook = 1;
462 }
463
464 multiclass MIMG_NoSampler <bits<7> op, string asm> {
465   def _V1 : MIMG_NoSampler_Helper <op, asm, VReg_32>;
466   def _V2 : MIMG_NoSampler_Helper <op, asm, VReg_64>;
467   def _V4 : MIMG_NoSampler_Helper <op, asm, VReg_128>;
468 }
469
470 class MIMG_Sampler_Helper <bits<7> op, string asm,
471                            RegisterClass src_rc> : MIMG <
472   op,
473   (outs VReg_128:$vdata),
474   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
475        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
476        SReg_256:$srsrc, SReg_128:$ssamp),
477   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
478      #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
479   []> {
480   let mayLoad = 1;
481   let mayStore = 0;
482   let hasPostISelHook = 1;
483 }
484
485 multiclass MIMG_Sampler <bits<7> op, string asm> {
486   def _V1 : MIMG_Sampler_Helper <op, asm, VReg_32>;
487   def _V2 : MIMG_Sampler_Helper <op, asm, VReg_64>;
488   def _V4 : MIMG_Sampler_Helper <op, asm, VReg_128>;
489   def _V8 : MIMG_Sampler_Helper <op, asm, VReg_256>;
490   def _V16 : MIMG_Sampler_Helper <op, asm, VReg_512>;
491 }
492
493 //===----------------------------------------------------------------------===//
494 // Vector instruction mappings
495 //===----------------------------------------------------------------------===//
496
497 // Maps an opcode in e32 form to its e64 equivalent
498 def getVOPe64 : InstrMapping {
499   let FilterClass = "VOP";
500   let RowFields = ["OpName"];
501   let ColFields = ["Size"];
502   let KeyCol = ["4"];
503   let ValueCols = [["8"]];
504 }
505
506 // Maps an original opcode to its commuted version
507 def getCommuteRev : InstrMapping {
508   let FilterClass = "VOP2_REV";
509   let RowFields = ["RevOp"];
510   let ColFields = ["IsOrig"];
511   let KeyCol = ["1"];
512   let ValueCols = [["0"]];
513 }
514
515 // Maps an commuted opcode to its original version
516 def getCommuteOrig : InstrMapping {
517   let FilterClass = "VOP2_REV";
518   let RowFields = ["RevOp"];
519   let ColFields = ["IsOrig"];
520   let KeyCol = ["0"];
521   let ValueCols = [["1"]];
522 }
523
524 include "SIInstructions.td"