d68fbff667f112712466351b93fe8f8e27b9a28f
[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 IMM12bit : ImmLeaf <
39   i16,
40   [{return isUInt<12>(Imm);}]
41 >;
42
43 class InlineImm <ValueType vt> : ImmLeaf <vt, [{
44   return -16 <= Imm && Imm <= 64;
45 }]>;
46
47
48 //===----------------------------------------------------------------------===//
49 // SI assembler operands
50 //===----------------------------------------------------------------------===//
51
52 def SIOperand {
53   int ZERO = 0x80;
54   int VCC = 0x6A;
55 }
56
57 class GPR4Align <RegisterClass rc> : Operand <vAny> {
58   let EncoderMethod = "GPR4AlignEncode";
59   let MIOperandInfo = (ops rc:$reg); 
60 }
61
62 class GPR2Align <RegisterClass rc> : Operand <iPTR> {
63   let EncoderMethod = "GPR2AlignEncode";
64   let MIOperandInfo = (ops rc:$reg);
65 }
66
67 include "SIInstrFormats.td"
68
69 //===----------------------------------------------------------------------===//
70 //
71 // SI Instruction multiclass helpers.
72 //
73 // Instructions with _32 take 32-bit operands.
74 // Instructions with _64 take 64-bit operands.
75 //
76 // VOP_* instructions can use either a 32-bit or 64-bit encoding.  The 32-bit
77 // encoding is the standard encoding, but instruction that make use of
78 // any of the instruction modifiers must use the 64-bit encoding.
79 //
80 // Instructions with _e32 use the 32-bit encoding.
81 // Instructions with _e64 use the 64-bit encoding.
82 //
83 //===----------------------------------------------------------------------===//
84
85 //===----------------------------------------------------------------------===//
86 // Scalar classes
87 //===----------------------------------------------------------------------===//
88
89 class SOP1_32 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
90   op, (outs SReg_32:$dst), (ins SSrc_32:$src0),
91   opName#" $dst, $src0", pattern
92 >;
93
94 class SOP1_64 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
95   op, (outs SReg_64:$dst), (ins SSrc_64:$src0),
96   opName#" $dst, $src0", pattern
97 >;
98
99 class SOP2_32 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
100   op, (outs SReg_32:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
101   opName#" $dst, $src0, $src1", pattern
102 >;
103
104 class SOP2_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
105   op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
106   opName#" $dst, $src0, $src1", pattern
107 >;
108
109 class SOPC_32 <bits<7> op, string opName, list<dag> pattern> : SOPC <
110   op, (outs SCCReg:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
111   opName#" $dst, $src0, $src1", pattern
112 >;
113
114 class SOPC_64 <bits<7> op, string opName, list<dag> pattern> : SOPC <
115   op, (outs SCCReg:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
116   opName#" $dst, $src0, $src1", pattern
117 >;
118
119 class SOPK_32 <bits<5> op, string opName, list<dag> pattern> : SOPK <
120   op, (outs SReg_32:$dst), (ins i16imm:$src0),
121   opName#" $dst, $src0", pattern
122 >;
123
124 class SOPK_64 <bits<5> op, string opName, list<dag> pattern> : SOPK <
125   op, (outs SReg_64:$dst), (ins i16imm:$src0),
126   opName#" $dst, $src0", pattern
127 >;
128
129 multiclass SMRD_Helper <bits<5> op, string asm, RegisterClass dstClass> {
130   def _IMM : SMRD <
131     op, 1, (outs dstClass:$dst),
132     (ins GPR2Align<SReg_64>:$sbase, i32imm:$offset),
133     asm#" $dst, $sbase, $offset", []
134   >;
135
136   def _SGPR : SMRD <
137     op, 0, (outs dstClass:$dst),
138     (ins GPR2Align<SReg_64>:$sbase, SReg_32:$soff),
139     asm#" $dst, $sbase, $soff", []
140   >;
141 }
142
143 //===----------------------------------------------------------------------===//
144 // Vector ALU classes
145 //===----------------------------------------------------------------------===//
146
147 multiclass VOP1_Helper <bits<8> op, RegisterClass drc, RegisterClass src,
148                         string opName, list<dag> pattern> {
149
150   def _e32: VOP1 <
151     op, (outs drc:$dst), (ins src:$src0),
152     opName#"_e32 $dst, $src0", pattern
153   >;
154
155   def _e64 : VOP3 <
156     {1, 1, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
157     (outs drc:$dst),
158     (ins src:$src0,
159          i32imm:$abs, i32imm:$clamp,
160          i32imm:$omod, i32imm:$neg),
161     opName#"_e64 $dst, $src0, $abs, $clamp, $omod, $neg", []
162   > {
163     let SRC1 = SIOperand.ZERO;
164     let SRC2 = SIOperand.ZERO;
165   }
166 }
167
168 multiclass VOP1_32 <bits<8> op, string opName, list<dag> pattern>
169   : VOP1_Helper <op, VReg_32, VSrc_32, opName, pattern>;
170
171 multiclass VOP1_64 <bits<8> op, string opName, list<dag> pattern>
172   : VOP1_Helper <op, VReg_64, VSrc_64, opName, pattern>;
173
174 multiclass VOP2_Helper <bits<6> op, RegisterClass vrc, RegisterClass arc,
175                         string opName, list<dag> pattern> {
176   def _e32 : VOP2 <
177     op, (outs vrc:$dst), (ins arc:$src0, vrc:$src1),
178     opName#"_e32 $dst, $src0, $src1", pattern
179   >;
180
181   def _e64 : VOP3 <
182     {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
183     (outs vrc:$dst),
184     (ins arc:$src0, vrc:$src1,
185          i32imm:$abs, i32imm:$clamp,
186          i32imm:$omod, i32imm:$neg),
187     opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg", []
188   > {
189     let SRC2 = SIOperand.ZERO;
190   }
191 }
192
193 multiclass VOP2_32 <bits<6> op, string opName, list<dag> pattern>
194   : VOP2_Helper <op, VReg_32, VSrc_32, opName, pattern>;
195
196 multiclass VOP2_64 <bits<6> op, string opName, list<dag> pattern>
197   : VOP2_Helper <op, VReg_64, VSrc_64, opName, pattern>;
198
199 multiclass VOP2b_32 <bits<6> op, string opName, list<dag> pattern> {
200
201   def _e32 : VOP2 <
202     op, (outs VReg_32:$dst), (ins VSrc_32:$src0, VReg_32:$src1),
203     opName#"_e32 $dst, $src0, $src1", pattern
204   >;
205
206   def _e64 : VOP3b <
207     {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
208     (outs VReg_32:$dst),
209     (ins VSrc_32:$src0, VReg_32:$src1,
210          i32imm:$abs, i32imm:$clamp,
211          i32imm:$omod, i32imm:$neg),
212     opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg", []
213   > {
214     let SRC2 = SIOperand.ZERO;
215     /* the VOP2 variant puts the carry out into VCC, the VOP3 variant
216        can write it into any SGPR. We currently don't use the carry out,
217        so for now hardcode it to VCC as well */
218     let SDST = SIOperand.VCC;
219   }
220 }
221
222 multiclass VOPC_Helper <bits<8> op, RegisterClass vrc, RegisterClass arc,
223                         string opName, ValueType vt, PatLeaf cond> {
224
225   def _e32 : VOPC <
226     op, (ins arc:$src0, vrc:$src1),
227     opName#"_e32 $dst, $src0, $src1", []
228   >;
229
230   def _e64 : VOP3 <
231     {0, op{7}, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
232     (outs SReg_64:$dst),
233     (ins arc:$src0, vrc:$src1,
234          InstFlag:$abs, InstFlag:$clamp,
235          InstFlag:$omod, InstFlag:$neg),
236     opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg",
237     !if(!eq(!cast<string>(cond), "COND_NULL"), []<dag>,
238       [(set SReg_64:$dst, (i1 (setcc (vt arc:$src0), vrc:$src1, cond)))]
239     )
240   > {
241     let SRC2 = SIOperand.ZERO;
242   }
243 }
244
245 multiclass VOPC_32 <bits<8> op, string opName,
246   ValueType vt = untyped, PatLeaf cond = COND_NULL>
247   : VOPC_Helper <op, VReg_32, VSrc_32, opName, vt, cond>;
248
249 multiclass VOPC_64 <bits<8> op, string opName,
250   ValueType vt = untyped, PatLeaf cond = COND_NULL>
251   : VOPC_Helper <op, VReg_64, VSrc_64, opName, vt, cond>;
252
253 class VOP3_32 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
254   op, (outs VReg_32:$dst),
255   (ins VSrc_32:$src0, VReg_32:$src1, VReg_32:$src2,
256    i32imm:$abs, i32imm:$clamp, i32imm:$omod, i32imm:$neg),
257   opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
258 >;
259
260 class VOP3_64 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
261   op, (outs VReg_64:$dst),
262   (ins VSrc_64:$src0, VReg_64:$src1, VReg_64:$src2,
263    i32imm:$abs, i32imm:$clamp, i32imm:$omod, i32imm:$neg),
264   opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
265 >;
266
267 //===----------------------------------------------------------------------===//
268 // Vector I/O classes
269 //===----------------------------------------------------------------------===//
270
271 class MTBUF_Store_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
272   op,
273   (outs),
274   (ins regClass:$vdata, i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
275    i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr,
276    GPR4Align<SReg_128>:$srsrc, i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
277   asm#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
278      #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
279   []> {
280   let mayStore = 1;
281   let mayLoad = 0;
282 }
283
284 class MUBUF_Load_Helper <bits<7> op, string asm, RegisterClass regClass> : MUBUF <
285   op,
286   (outs regClass:$dst),
287   (ins i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
288        i1imm:$lds, VReg_32:$vaddr, GPR4Align<SReg_128>:$srsrc, i1imm:$slc,
289        i1imm:$tfe, SSrc_32:$soffset),
290   asm#" $dst, $offset, $offen, $idxen, $glc, $addr64, "
291      #"$lds, $vaddr, $srsrc, $slc, $tfe, $soffset",
292   []> {
293   let mayLoad = 1;
294   let mayStore = 0;
295 }
296
297 class MTBUF_Load_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
298   op,
299   (outs regClass:$dst),
300   (ins i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
301        i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, GPR4Align<SReg_128>:$srsrc,
302        i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
303   asm#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
304      #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
305   []> {
306   let mayLoad = 1;
307   let mayStore = 0;
308 }
309
310 class MIMG_Load_Helper <bits<7> op, string asm> : MIMG <
311   op,
312   (outs VReg_128:$vdata),
313   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
314        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, VReg_32:$vaddr,
315        GPR4Align<SReg_256>:$srsrc, GPR4Align<SReg_128>:$ssamp),
316   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
317      #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
318   []> {
319   let mayLoad = 1;
320   let mayStore = 0;
321 }
322
323 include "SIInstructions.td"