R600/SI: rework VOP2_* pattern v2
[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 multiclass VOP1_Helper <bits<8> op, RegisterClass drc, RegisterClass src,
145                         string opName, list<dag> pattern> {
146
147   def _e32: VOP1 <
148     op, (outs drc:$dst), (ins src:$src0),
149     opName#"_e32 $dst, $src0", pattern
150   >;
151
152   def _e64 : VOP3 <
153     {1, 1, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
154     (outs drc:$dst),
155     (ins src:$src0,
156          i32imm:$abs, i32imm:$clamp,
157          i32imm:$omod, i32imm:$neg),
158     opName#"_e64 $dst, $src0, $abs, $clamp, $omod, $neg", []
159   > {
160     let SRC1 = SIOperand.ZERO;
161     let SRC2 = SIOperand.ZERO;
162   }
163 }
164
165 multiclass VOP1_32 <bits<8> op, string opName, list<dag> pattern>
166   : VOP1_Helper <op, VReg_32, VSrc_32, opName, pattern>;
167
168 multiclass VOP1_64 <bits<8> op, string opName, list<dag> pattern>
169   : VOP1_Helper <op, VReg_64, VSrc_64, opName, pattern>;
170
171 multiclass VOP2_Helper <bits<6> op, RegisterClass vrc, RegisterClass arc,
172                         string opName, list<dag> pattern> {
173   def _e32 : VOP2 <
174     op, (outs vrc:$dst), (ins arc:$src0, vrc:$src1),
175     opName#"_e32 $dst, $src0, $src1", pattern
176   >;
177
178   def _e64 : VOP3 <
179     {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
180     (outs vrc:$dst),
181     (ins arc:$src0, vrc:$src1,
182          i32imm:$abs, i32imm:$clamp,
183          i32imm:$omod, i32imm:$neg),
184     opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg", []
185   > {
186     let SRC2 = SIOperand.ZERO;
187   }
188 }
189
190 multiclass VOP2_32 <bits<6> op, string opName, list<dag> pattern>
191   : VOP2_Helper <op, VReg_32, VSrc_32, opName, pattern>;
192
193 multiclass VOP2_64 <bits<6> op, string opName, list<dag> pattern>
194   : VOP2_Helper <op, VReg_64, VSrc_64, opName, pattern>;
195
196 multiclass VOPC_Helper <bits<8> op, RegisterClass vrc, RegisterClass arc,
197                         string opName, list<dag> pattern> {
198
199   def _e32 : VOPC <op, (ins arc:$src0, vrc:$src1), opName, pattern>;
200   def _e64 : VOP3 <
201     {0, op{7}, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
202     (outs SReg_64:$dst),
203     (ins arc:$src0, vrc:$src1,
204          InstFlag:$abs, InstFlag:$clamp,
205          InstFlag:$omod, InstFlag:$neg),
206     opName, pattern
207   > {
208     let SRC2 = SIOperand.ZERO;
209   }
210 }
211
212 multiclass VOPC_32 <bits<8> op, string opName, list<dag> pattern>
213   : VOPC_Helper <op, VReg_32, VSrc_32, opName, pattern>;
214
215 multiclass VOPC_64 <bits<8> op, string opName, list<dag> pattern>
216   : VOPC_Helper <op, VReg_64, VSrc_64, opName, pattern>;
217
218 //===----------------------------------------------------------------------===//
219 // Vector I/O classes
220 //===----------------------------------------------------------------------===//
221
222 class MTBUF_Store_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
223   op,
224   (outs),
225   (ins regClass:$vdata, i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
226    i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr,
227    GPR4Align<SReg_128>:$srsrc, i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
228   asm,
229   []> {
230   let mayStore = 1;
231   let mayLoad = 0;
232 }
233
234 class MUBUF_Load_Helper <bits<7> op, string asm, RegisterClass regClass> : MUBUF <
235   op,
236   (outs regClass:$dst),
237   (ins i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
238        i1imm:$lds, VReg_32:$vaddr, GPR4Align<SReg_128>:$srsrc, i1imm:$slc,
239        i1imm:$tfe, SSrc_32:$soffset),
240   asm,
241   []> {
242   let mayLoad = 1;
243   let mayStore = 0;
244 }
245
246 class MTBUF_Load_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
247   op,
248   (outs regClass:$dst),
249   (ins i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
250        i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, GPR4Align<SReg_128>:$srsrc,
251        i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
252   asm,
253   []> {
254   let mayLoad = 1;
255   let mayStore = 0;
256 }
257
258 class MIMG_Load_Helper <bits<7> op, string asm> : MIMG <
259   op,
260   (outs VReg_128:$vdata),
261   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
262        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, VReg_32:$vaddr,
263        GPR4Align<SReg_256>:$srsrc, GPR4Align<SReg_128>:$ssamp),
264   asm,
265   []> {
266   let mayLoad = 1;
267   let mayStore = 0;
268 }
269
270 include "SIInstructions.td"