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