R600/SI: add constant for inline zero operand
[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 }
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>
89   : SOP1 <op, (outs SReg_32:$dst), (ins SSrc_32:$src0), opName, pattern>;
90
91 class SOP1_64 <bits<8> op, string opName, list<dag> pattern>
92   : SOP1 <op, (outs SReg_64:$dst), (ins SSrc_64:$src0), opName, pattern>;
93
94 class SOP2_32 <bits<7> op, string opName, list<dag> pattern>
95   : SOP2 <op, (outs SReg_32:$dst), (ins SSrc_32:$src0, SSrc_32:$src1), opName, pattern>;
96
97 class SOP2_64 <bits<7> op, string opName, list<dag> pattern>
98   : SOP2 <op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_64:$src1), opName, pattern>;
99
100 class SOPC_32 <bits<7> op, string opName, list<dag> pattern>
101   : SOPC <op, (outs SCCReg:$dst), (ins SSrc_32:$src0, SSrc_32:$src1), opName, pattern>;
102
103 class SOPC_64 <bits<7> op, string opName, list<dag> pattern>
104   : SOPC <op, (outs SCCReg:$dst), (ins SSrc_64:$src0, SSrc_64:$src1), opName, pattern>;
105
106 class SOPK_32 <bits<5> op, string opName, list<dag> pattern>
107   : SOPK <op, (outs SReg_32:$dst), (ins i16imm:$src0), opName, pattern>;
108
109 class SOPK_64 <bits<5> op, string opName, list<dag> pattern>
110   : SOPK <op, (outs SReg_64:$dst), (ins i16imm:$src0), opName, pattern>;
111
112 multiclass SMRD_Helper <bits<5> op, string asm, RegisterClass dstClass> {
113   def _IMM : SMRD <
114     op, 1, (outs dstClass:$dst),
115     (ins GPR2Align<SReg_64>:$sbase, i32imm:$offset),
116     asm, []
117   >;
118
119   def _SGPR : SMRD <
120     op, 0, (outs dstClass:$dst),
121     (ins GPR2Align<SReg_64>:$sbase, SReg_32:$soff),
122     asm, []
123   >;
124 }
125
126 //===----------------------------------------------------------------------===//
127 // Vector ALU classes
128 //===----------------------------------------------------------------------===//
129
130 class VOP3_32 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
131   op, (outs VReg_32:$dst),
132   (ins VSrc_32:$src0, VReg_32:$src1, VReg_32:$src2, i32imm:$src3,
133    i32imm:$src4, i32imm:$src5, i32imm:$src6),
134   opName, pattern
135 >;
136
137 class VOP3_64 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
138   op, (outs VReg_64:$dst),
139   (ins VSrc_64:$src0, VReg_64:$src1, VReg_64:$src2,
140    i32imm:$src3, i32imm:$src4, i32imm:$src5, i32imm:$src6),
141   opName, pattern
142 >;
143
144 class VOP1_Helper <bits<8> op, RegisterClass vrc, RegisterClass arc,
145                    string opName, list<dag> pattern> : 
146   VOP1 <
147     op, (outs vrc:$dst), (ins arc:$src0), opName, pattern
148   >;
149
150 multiclass VOP1_32 <bits<8> op, string opName, list<dag> pattern> {
151   def _e32: VOP1_Helper <op, VReg_32, VSrc_32, opName, pattern>;
152   def _e64 : VOP3_32 <{1, 1, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
153                       opName, []
154   >;
155 }
156
157 multiclass VOP1_64 <bits<8> op, string opName, list<dag> pattern> {
158
159   def _e32 : VOP1_Helper <op, VReg_64, VSrc_64, opName, pattern>;
160
161   def _e64 : VOP3_64 <
162     {1, 1, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
163     opName, []
164   >;
165 }
166
167 class VOP2_Helper <bits<6> op, RegisterClass vrc, RegisterClass arc,
168                    string opName, list<dag> pattern> :
169   VOP2 <
170     op, (outs vrc:$dst), (ins arc:$src0, vrc:$src1), opName, pattern
171   >;
172
173 multiclass VOP2_32 <bits<6> op, string opName, list<dag> pattern> {
174
175   def _e32 : VOP2_Helper <op, VReg_32, VSrc_32, opName, pattern>;
176
177   def _e64 : VOP3_32 <{1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
178                       opName, []
179   >;
180 }
181
182 multiclass VOP2_64 <bits<6> op, string opName, list<dag> pattern> {
183   def _e32: VOP2_Helper <op, VReg_64, VSrc_64, opName, pattern>;
184
185   def _e64 : VOP3_64 <
186     {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
187     opName, []
188   >;
189 }
190
191 multiclass VOPC_Helper <bits<8> op, RegisterClass vrc, RegisterClass arc,
192                         string opName, list<dag> pattern> {
193
194   def _e32 : VOPC <op, (ins arc:$src0, vrc:$src1), opName, pattern>;
195   def _e64 : VOP3 <
196     {0, op{7}, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
197     (outs SReg_64:$dst),
198     (ins arc:$src0, vrc:$src1,
199          InstFlag:$abs, InstFlag:$clamp,
200          InstFlag:$omod, InstFlag:$neg),
201     opName, pattern
202   > {
203     let SRC2 = SIOperand.ZERO;
204   }
205 }
206
207 multiclass VOPC_32 <bits<8> op, string opName, list<dag> pattern>
208   : VOPC_Helper <op, VReg_32, VSrc_32, opName, pattern>;
209
210 multiclass VOPC_64 <bits<8> op, string opName, list<dag> pattern>
211   : VOPC_Helper <op, VReg_64, VSrc_64, opName, pattern>;
212
213 //===----------------------------------------------------------------------===//
214 // Vector I/O classes
215 //===----------------------------------------------------------------------===//
216
217 class MTBUF_Store_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
218   op,
219   (outs),
220   (ins regClass:$vdata, i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
221    i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr,
222    GPR4Align<SReg_128>:$srsrc, i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
223   asm,
224   []> {
225   let mayStore = 1;
226   let mayLoad = 0;
227 }
228
229 class MUBUF_Load_Helper <bits<7> op, string asm, RegisterClass regClass> : MUBUF <
230   op,
231   (outs regClass:$dst),
232   (ins i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
233        i1imm:$lds, VReg_32:$vaddr, GPR4Align<SReg_128>:$srsrc, i1imm:$slc,
234        i1imm:$tfe, SSrc_32:$soffset),
235   asm,
236   []> {
237   let mayLoad = 1;
238   let mayStore = 0;
239 }
240
241 class MTBUF_Load_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
242   op,
243   (outs regClass:$dst),
244   (ins i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
245        i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, GPR4Align<SReg_128>:$srsrc,
246        i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
247   asm,
248   []> {
249   let mayLoad = 1;
250   let mayStore = 0;
251 }
252
253 class MIMG_Load_Helper <bits<7> op, string asm> : MIMG <
254   op,
255   (outs VReg_128:$vdata),
256   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
257        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, VReg_32:$vaddr,
258        GPR4Align<SReg_256>:$srsrc, GPR4Align<SReg_128>:$ssamp),
259   asm,
260   []> {
261   let mayLoad = 1;
262   let mayStore = 0;
263 }
264
265 include "SIInstructions.td"