R600/SI: Add instruction shrinking pass
[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 // Execpt for the NONE field, this must be kept in sync with the SISubtarget enum
11 // in AMDGPUMCInstLower.h
12 def SISubtarget {
13   int NONE = -1;
14   int SI = 0;
15 }
16
17 //===----------------------------------------------------------------------===//
18 // SI DAG Nodes
19 //===----------------------------------------------------------------------===//
20
21 def SIload_constant : SDNode<"AMDGPUISD::LOAD_CONSTANT",
22   SDTypeProfile<1, 2, [SDTCisVT<0, f32>, SDTCisVT<1, v4i32>, SDTCisVT<2, i32>]>,
23                       [SDNPMayLoad, SDNPMemOperand]
24 >;
25
26 def SItbuffer_store : SDNode<"AMDGPUISD::TBUFFER_STORE_FORMAT",
27   SDTypeProfile<0, 13,
28     [SDTCisVT<0, v4i32>,   // rsrc(SGPR)
29      SDTCisVT<1, iAny>,   // vdata(VGPR)
30      SDTCisVT<2, i32>,    // num_channels(imm)
31      SDTCisVT<3, i32>,    // vaddr(VGPR)
32      SDTCisVT<4, i32>,    // soffset(SGPR)
33      SDTCisVT<5, i32>,    // inst_offset(imm)
34      SDTCisVT<6, i32>,    // dfmt(imm)
35      SDTCisVT<7, i32>,    // nfmt(imm)
36      SDTCisVT<8, i32>,    // offen(imm)
37      SDTCisVT<9, i32>,    // idxen(imm)
38      SDTCisVT<10, i32>,   // glc(imm)
39      SDTCisVT<11, i32>,   // slc(imm)
40      SDTCisVT<12, i32>    // tfe(imm)
41     ]>,
42   [SDNPMayStore, SDNPMemOperand, SDNPHasChain]
43 >;
44
45 def SIload_input : SDNode<"AMDGPUISD::LOAD_INPUT",
46   SDTypeProfile<1, 3, [SDTCisVT<0, v4f32>, SDTCisVT<1, v4i32>, SDTCisVT<2, i16>,
47                        SDTCisVT<3, i32>]>
48 >;
49
50 class SDSample<string opcode> : SDNode <opcode,
51   SDTypeProfile<1, 4, [SDTCisVT<0, v4f32>, SDTCisVT<2, v32i8>,
52                        SDTCisVT<3, v4i32>, SDTCisVT<4, i32>]>
53 >;
54
55 def SIsample : SDSample<"AMDGPUISD::SAMPLE">;
56 def SIsampleb : SDSample<"AMDGPUISD::SAMPLEB">;
57 def SIsampled : SDSample<"AMDGPUISD::SAMPLED">;
58 def SIsamplel : SDSample<"AMDGPUISD::SAMPLEL">;
59
60 def SIconstdata_ptr : SDNode<
61   "AMDGPUISD::CONST_DATA_PTR", SDTypeProfile <1, 0, [SDTCisVT<0, i64>]>
62 >;
63
64 // Transformation function, extract the lower 32bit of a 64bit immediate
65 def LO32 : SDNodeXForm<imm, [{
66   return CurDAG->getTargetConstant(N->getZExtValue() & 0xffffffff, MVT::i32);
67 }]>;
68
69 def LO32f : SDNodeXForm<fpimm, [{
70   APInt V = N->getValueAPF().bitcastToAPInt().trunc(32);
71   return CurDAG->getTargetConstantFP(APFloat(APFloat::IEEEsingle, V), MVT::f32);
72 }]>;
73
74 // Transformation function, extract the upper 32bit of a 64bit immediate
75 def HI32 : SDNodeXForm<imm, [{
76   return CurDAG->getTargetConstant(N->getZExtValue() >> 32, MVT::i32);
77 }]>;
78
79 def HI32f : SDNodeXForm<fpimm, [{
80   APInt V = N->getValueAPF().bitcastToAPInt().lshr(32).trunc(32);
81   return CurDAG->getTargetConstantFP(APFloat(APFloat::IEEEsingle, V), MVT::f32);
82 }]>;
83
84 def IMM8bitDWORD : PatLeaf <(imm),
85   [{return (N->getZExtValue() & ~0x3FC) == 0;}]
86 >;
87
88 def as_dword_i32imm : SDNodeXForm<imm, [{
89   return CurDAG->getTargetConstant(N->getZExtValue() >> 2, MVT::i32);
90 }]>;
91
92 def as_i1imm : SDNodeXForm<imm, [{
93   return CurDAG->getTargetConstant(N->getZExtValue(), MVT::i1);
94 }]>;
95
96 def as_i8imm : SDNodeXForm<imm, [{
97   return CurDAG->getTargetConstant(N->getZExtValue(), MVT::i8);
98 }]>;
99
100 def as_i16imm : SDNodeXForm<imm, [{
101   return CurDAG->getTargetConstant(N->getSExtValue(), MVT::i16);
102 }]>;
103
104 def as_i32imm: SDNodeXForm<imm, [{
105   return CurDAG->getTargetConstant(N->getSExtValue(), MVT::i32);
106 }]>;
107
108 def IMM8bit : PatLeaf <(imm),
109   [{return isUInt<8>(N->getZExtValue());}]
110 >;
111
112 def IMM12bit : PatLeaf <(imm),
113   [{return isUInt<12>(N->getZExtValue());}]
114 >;
115
116 def IMM16bit : PatLeaf <(imm),
117   [{return isUInt<16>(N->getZExtValue());}]
118 >;
119
120 def IMM32bit : PatLeaf <(imm),
121   [{return isUInt<32>(N->getZExtValue());}]
122 >;
123
124 def mubuf_vaddr_offset : PatFrag<
125   (ops node:$ptr, node:$offset, node:$imm_offset),
126   (add (add node:$ptr, node:$offset), node:$imm_offset)
127 >;
128
129 class InlineImm <ValueType vt> : PatLeaf <(vt imm), [{
130   return isInlineImmediate(N);
131 }]>;
132
133 class SGPRImm <dag frag> : PatLeaf<frag, [{
134   if (TM.getSubtarget<AMDGPUSubtarget>().getGeneration() <
135       AMDGPUSubtarget::SOUTHERN_ISLANDS) {
136     return false;
137   }
138   const SIRegisterInfo *SIRI =
139                        static_cast<const SIRegisterInfo*>(TM.getRegisterInfo());
140   for (SDNode::use_iterator U = N->use_begin(), E = SDNode::use_end();
141                                                 U != E; ++U) {
142     if (SIRI->isSGPRClass(getOperandRegClass(*U, U.getOperandNo()))) {
143       return true;
144     }
145   }
146   return false;
147 }]>;
148
149 //===----------------------------------------------------------------------===//
150 // Custom Operands
151 //===----------------------------------------------------------------------===//
152
153 def FRAMEri32 : Operand<iPTR> {
154   let MIOperandInfo = (ops i32:$ptr, i32imm:$index);
155 }
156
157 def sopp_brtarget : Operand<OtherVT> {
158   let EncoderMethod = "getSOPPBrEncoding";
159   let OperandType = "OPERAND_PCREL";
160 }
161
162 //===----------------------------------------------------------------------===//
163 // Complex patterns
164 //===----------------------------------------------------------------------===//
165
166 def MUBUFAddr32 : ComplexPattern<i64, 9, "SelectMUBUFAddr32">;
167 def MUBUFAddr64 : ComplexPattern<i64, 3, "SelectMUBUFAddr64">;
168 def MUBUFScratch : ComplexPattern<i64, 4, "SelectMUBUFScratch">;
169
170 //===----------------------------------------------------------------------===//
171 // SI assembler operands
172 //===----------------------------------------------------------------------===//
173
174 def SIOperand {
175   int ZERO = 0x80;
176   int VCC = 0x6A;
177 }
178
179 include "SIInstrFormats.td"
180
181 //===----------------------------------------------------------------------===//
182 //
183 // SI Instruction multiclass helpers.
184 //
185 // Instructions with _32 take 32-bit operands.
186 // Instructions with _64 take 64-bit operands.
187 //
188 // VOP_* instructions can use either a 32-bit or 64-bit encoding.  The 32-bit
189 // encoding is the standard encoding, but instruction that make use of
190 // any of the instruction modifiers must use the 64-bit encoding.
191 //
192 // Instructions with _e32 use the 32-bit encoding.
193 // Instructions with _e64 use the 64-bit encoding.
194 //
195 //===----------------------------------------------------------------------===//
196
197 //===----------------------------------------------------------------------===//
198 // Scalar classes
199 //===----------------------------------------------------------------------===//
200
201 class SOP1_32 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
202   op, (outs SReg_32:$dst), (ins SSrc_32:$src0),
203   opName#" $dst, $src0", pattern
204 >;
205
206 class SOP1_64 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
207   op, (outs SReg_64:$dst), (ins SSrc_64:$src0),
208   opName#" $dst, $src0", pattern
209 >;
210
211 // 64-bit input, 32-bit output.
212 class SOP1_32_64 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
213   op, (outs SReg_32:$dst), (ins SSrc_64:$src0),
214   opName#" $dst, $src0", pattern
215 >;
216
217 class SOP2_32 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
218   op, (outs SReg_32:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
219   opName#" $dst, $src0, $src1", pattern
220 >;
221
222 class SOP2_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
223   op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
224   opName#" $dst, $src0, $src1", pattern
225 >;
226
227 class SOP2_SHIFT_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
228   op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_32:$src1),
229   opName#" $dst, $src0, $src1", pattern
230 >;
231
232
233 class SOPC_Helper <bits<7> op, RegisterClass rc, ValueType vt,
234                     string opName, PatLeaf cond> : SOPC <
235   op, (outs SCCReg:$dst), (ins rc:$src0, rc:$src1),
236   opName#" $dst, $src0, $src1", []>;
237
238 class SOPC_32<bits<7> op, string opName, PatLeaf cond = COND_NULL>
239   : SOPC_Helper<op, SSrc_32, i32, opName, cond>;
240
241 class SOPC_64<bits<7> op, string opName, PatLeaf cond = COND_NULL>
242   : SOPC_Helper<op, SSrc_64, i64, opName, cond>;
243
244 class SOPK_32 <bits<5> op, string opName, list<dag> pattern> : SOPK <
245   op, (outs SReg_32:$dst), (ins i16imm:$src0),
246   opName#" $dst, $src0", pattern
247 >;
248
249 class SOPK_64 <bits<5> op, string opName, list<dag> pattern> : SOPK <
250   op, (outs SReg_64:$dst), (ins i16imm:$src0),
251   opName#" $dst, $src0", pattern
252 >;
253
254 multiclass SMRD_Helper <bits<5> op, string asm, RegisterClass baseClass,
255                         RegisterClass dstClass> {
256   def _IMM : SMRD <
257     op, 1, (outs dstClass:$dst),
258     (ins baseClass:$sbase, u32imm:$offset),
259     asm#" $dst, $sbase, $offset", []
260   >;
261
262   def _SGPR : SMRD <
263     op, 0, (outs dstClass:$dst),
264     (ins baseClass:$sbase, SReg_32:$soff),
265     asm#" $dst, $sbase, $soff", []
266   >;
267 }
268
269 //===----------------------------------------------------------------------===//
270 // Vector ALU classes
271 //===----------------------------------------------------------------------===//
272
273 class VOP <string opName> {
274   string OpName = opName;
275 }
276
277 class VOP2_REV <string revOp, bit isOrig> {
278   string RevOp = revOp;
279   bit IsOrig = isOrig;
280 }
281
282 class SIMCInstr <string pseudo, int subtarget> {
283   string PseudoInstr = pseudo;
284   int Subtarget = subtarget;
285 }
286
287 multiclass VOP3_m <bits<9> op, dag outs, dag ins, string asm, list<dag> pattern,
288                    string opName> {
289
290   def "" : VOP3Common <outs, ins, "", pattern>, VOP <opName>,
291            SIMCInstr<OpName, SISubtarget.NONE> {
292     let isPseudo = 1;
293   }
294
295   def _si : VOP3 <op, outs, ins, asm, []>, SIMCInstr<opName, SISubtarget.SI>;
296
297 }
298
299 // This must always be right before the operand being input modified.
300 def InputMods : OperandWithDefaultOps <i32, (ops (i32 0))> {
301   let PrintMethod = "printOperandAndMods";
302 }
303
304 multiclass VOP1_Helper <bits<8> op, RegisterClass drc, RegisterClass src,
305                         string opName, list<dag> pattern> {
306
307   def _e32 : VOP1 <
308     op, (outs drc:$dst), (ins src:$src0),
309     opName#"_e32 $dst, $src0", pattern
310   >, VOP <opName>;
311
312   def _e64 : VOP3 <
313     {1, 1, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
314     (outs drc:$dst),
315     (ins InputMods:$src0_modifiers, src:$src0, i32imm:$clamp, i32imm:$omod),
316     opName#"_e64 $dst, $src0_modifiers, $clamp, $omod", []
317   >, VOP <opName> {
318     let src1 = SIOperand.ZERO;
319     let src2 = SIOperand.ZERO;
320   }
321 }
322
323 multiclass VOP1_32 <bits<8> op, string opName, list<dag> pattern>
324   : VOP1_Helper <op, VReg_32, VSrc_32, opName, pattern>;
325
326 multiclass VOP1_64 <bits<8> op, string opName, list<dag> pattern>
327   : VOP1_Helper <op, VReg_64, VSrc_64, opName, pattern>;
328
329 multiclass VOP1_32_64 <bits<8> op, string opName, list<dag> pattern>
330   : VOP1_Helper <op, VReg_32, VSrc_64, opName, pattern>;
331
332 multiclass VOP1_64_32 <bits<8> op, string opName, list<dag> pattern>
333   : VOP1_Helper <op, VReg_64, VSrc_32, opName, pattern>;
334
335 multiclass VOP2_Helper <bits<6> op, RegisterClass vrc, RegisterClass arc,
336                         string opName, list<dag> pattern, string revOp> {
337   def _e32 : VOP2 <
338     op, (outs vrc:$dst), (ins arc:$src0, vrc:$src1),
339     opName#"_e32 $dst, $src0, $src1", pattern
340   >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
341
342   def _e64 : VOP3 <
343     {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
344     (outs vrc:$dst),
345     (ins InputMods:$src0_modifiers, arc:$src0,
346          InputMods:$src1_modifiers, arc:$src1,
347          i32imm:$clamp, i32imm:$omod),
348     opName#"_e64 $dst, $src0_modifiers, $src1_modifiers, $clamp, $omod", []
349   >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
350     let src2 = SIOperand.ZERO;
351   }
352 }
353
354 multiclass VOP2_32 <bits<6> op, string opName, list<dag> pattern,
355                     string revOp = opName>
356   : VOP2_Helper <op, VReg_32, VSrc_32, opName, pattern, revOp>;
357
358 multiclass VOP2_64 <bits<6> op, string opName, list<dag> pattern,
359                     string revOp = opName>
360   : VOP2_Helper <op, VReg_64, VSrc_64, opName, pattern, revOp>;
361
362 multiclass VOP2b_32 <bits<6> op, string opName, list<dag> pattern,
363                      RegisterClass src0_rc, string revOp = opName> {
364
365   def _e32 : VOP2 <
366     op, (outs VReg_32:$dst), (ins src0_rc:$src0, VReg_32:$src1),
367     opName#"_e32 $dst, $src0, $src1", pattern
368   >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
369
370   def _e64 : VOP3b <
371     {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
372     (outs VReg_32:$dst),
373     (ins InputMods: $src0_modifiers, VSrc_32:$src0,
374          InputMods:$src1_modifiers, VSrc_32:$src1,
375          i32imm:$clamp, i32imm:$omod),
376     opName#"_e64 $dst, $src0_modifiers, $src1_modifiers, $clamp, $omod", []
377   >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
378     let src2 = SIOperand.ZERO;
379     /* the VOP2 variant puts the carry out into VCC, the VOP3 variant
380        can write it into any SGPR. We currently don't use the carry out,
381        so for now hardcode it to VCC as well */
382     let sdst = SIOperand.VCC;
383   }
384 }
385
386 multiclass VOPC_Helper <bits<8> op, RegisterClass vrc, RegisterClass arc,
387                         string opName, ValueType vt, PatLeaf cond, bit defExec = 0> {
388   def _e32 : VOPC <
389     op, (ins arc:$src0, vrc:$src1),
390     opName#"_e32 $dst, $src0, $src1", []
391   >, VOP <opName> {
392     let Defs = !if(defExec, [EXEC], []);
393   }
394
395   def _e64 : VOP3 <
396     {0, op{7}, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
397     (outs SReg_64:$dst),
398     (ins InputMods:$src0_modifiers, arc:$src0,
399          InputMods:$src1_modifiers, arc:$src1,
400          InstFlag:$clamp, InstFlag:$omod),
401     opName#"_e64 $dst, $src0_modifiers, $src1_modifiers, $clamp, $omod",
402     !if(!eq(!cast<string>(cond), "COND_NULL"), []<dag>,
403       [(set SReg_64:$dst, (i1 (setcc (vt arc:$src0), arc:$src1, cond)))]
404     )
405   >, VOP <opName> {
406     let Defs = !if(defExec, [EXEC], []);
407     let src2 = SIOperand.ZERO;
408     let src2_modifiers = 0;
409   }
410 }
411
412 multiclass VOPC_32 <bits<8> op, string opName,
413   ValueType vt = untyped, PatLeaf cond = COND_NULL>
414   : VOPC_Helper <op, VReg_32, VSrc_32, opName, vt, cond>;
415
416 multiclass VOPC_64 <bits<8> op, string opName,
417   ValueType vt = untyped, PatLeaf cond = COND_NULL>
418   : VOPC_Helper <op, VReg_64, VSrc_64, opName, vt, cond>;
419
420 multiclass VOPCX_32 <bits<8> op, string opName,
421   ValueType vt = untyped, PatLeaf cond = COND_NULL>
422   : VOPC_Helper <op, VReg_32, VSrc_32, opName, vt, cond, 1>;
423
424 multiclass VOPCX_64 <bits<8> op, string opName,
425   ValueType vt = untyped, PatLeaf cond = COND_NULL>
426   : VOPC_Helper <op, VReg_64, VSrc_64, opName, vt, cond, 1>;
427
428 multiclass VOP3_32 <bits<9> op, string opName, list<dag> pattern> : VOP3_m <
429   op, (outs VReg_32:$dst),
430   (ins InputMods: $src0_modifiers, VSrc_32:$src0, InputMods:$src1_modifiers,
431    VSrc_32:$src1, InputMods:$src2_modifiers, VSrc_32:$src2,
432    InstFlag:$clamp, InstFlag:$omod),
433   opName#" $dst, $src0_modifiers, $src1, $src2, $clamp, $omod", pattern, opName
434 >;
435
436 class VOP3_64_32 <bits <9> op, string opName, list<dag> pattern> : VOP3 <
437   op, (outs VReg_64:$dst),
438   (ins VSrc_64:$src0, VSrc_32:$src1),
439   opName#" $dst, $src0, $src1", pattern
440 >, VOP <opName> {
441
442   let src2 = SIOperand.ZERO;
443   let src0_modifiers = 0;
444   let clamp = 0;
445   let omod = 0;
446 }
447
448 class VOP3_64 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
449   op, (outs VReg_64:$dst),
450   (ins InputMods:$src0_modifiers, VSrc_64:$src0,
451        InputMods:$src1_modifiers, VSrc_64:$src1,
452        InputMods:$src2_modifiers, VSrc_64:$src2,
453        InstFlag:$clamp, InstFlag:$omod),
454   opName#" $dst, $src0_modifiers, $src1_modifiers, $src2_modifiers, $clamp, $omod", pattern
455 >, VOP <opName>;
456
457
458 class VOP3b_Helper <bits<9> op, RegisterClass vrc, RegisterClass arc,
459                     string opName, list<dag> pattern> : VOP3 <
460   op, (outs vrc:$dst0, SReg_64:$dst1),
461   (ins arc:$src0, arc:$src1, arc:$src2,
462    InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg),
463   opName#" $dst0, $dst1, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
464 >, VOP <opName>;
465
466
467 class VOP3b_64 <bits<9> op, string opName, list<dag> pattern> :
468   VOP3b_Helper <op, VReg_64, VSrc_64, opName, pattern>;
469
470 class VOP3b_32 <bits<9> op, string opName, list<dag> pattern> :
471   VOP3b_Helper <op, VReg_32, VSrc_32, opName, pattern>;
472
473 //===----------------------------------------------------------------------===//
474 // Vector I/O classes
475 //===----------------------------------------------------------------------===//
476
477 class DS_1A <bits<8> op, dag outs, dag ins, string asm, list<dag> pat> :
478     DS <op, outs, ins, asm, pat> {
479   bits<16> offset;
480
481   // Single load interpret the 2 i8imm operands as a single i16 offset.
482   let offset0 = offset{7-0};
483   let offset1 = offset{15-8};
484 }
485
486 class DS_Load_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
487   op,
488   (outs regClass:$vdst),
489   (ins i1imm:$gds, VReg_32:$addr, u16imm:$offset),
490   asm#" $vdst, $addr, $offset, [M0]",
491   []> {
492   let data0 = 0;
493   let data1 = 0;
494   let mayLoad = 1;
495   let mayStore = 0;
496 }
497
498 class DS_Load2_Helper <bits<8> op, string asm, RegisterClass regClass> : DS <
499   op,
500   (outs regClass:$vdst),
501   (ins i1imm:$gds, VReg_32:$addr, u8imm:$offset0, u8imm:$offset1),
502   asm#" $gds, $vdst, $addr, $offset0, $offset1, [M0]",
503   []> {
504   let data0 = 0;
505   let data1 = 0;
506   let mayLoad = 1;
507   let mayStore = 0;
508 }
509
510 class DS_Store_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
511   op,
512   (outs),
513   (ins i1imm:$gds, VReg_32:$addr, regClass:$data0, u16imm:$offset),
514   asm#" $addr, $data0, $offset [M0]",
515   []> {
516   let data1 = 0;
517   let mayStore = 1;
518   let mayLoad = 0;
519   let vdst = 0;
520 }
521
522 class DS_Store2_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
523   op,
524   (outs),
525   (ins i1imm:$gds, VReg_32:$addr, regClass:$data0, u8imm:$offset0, u8imm:$offset1),
526   asm#" $addr, $data0, $data1, $offset0, $offset1 [M0]",
527   []> {
528   let mayStore = 1;
529   let mayLoad = 0;
530   let vdst = 0;
531 }
532
533 // 1 address, 1 data.
534 class DS_1A1D_RET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
535   op,
536   (outs rc:$vdst),
537   (ins i1imm:$gds, VReg_32:$addr, rc:$data0, u16imm:$offset),
538   asm#" $vdst, $addr, $data0, $offset, [M0]",
539   []> {
540
541   let data1 = 0;
542   let mayStore = 1;
543   let mayLoad = 1;
544 }
545
546 // 1 address, 2 data.
547 class DS_1A2D_RET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
548   op,
549   (outs rc:$vdst),
550   (ins i1imm:$gds, VReg_32:$addr, rc:$data0, rc:$data1, u16imm:$offset),
551   asm#" $vdst, $addr, $data0, $data1, $offset, [M0]",
552   []> {
553   let mayStore = 1;
554   let mayLoad = 1;
555 }
556
557 // 1 address, 2 data.
558 class DS_1A2D_NORET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
559   op,
560   (outs),
561   (ins i1imm:$gds, VReg_32:$addr, rc:$data0, rc:$data1, u16imm:$offset),
562   asm#" $addr, $data0, $data1, $offset, [M0]",
563   []> {
564   let mayStore = 1;
565   let mayLoad = 1;
566 }
567
568 // 1 address, 1 data.
569 class DS_1A1D_NORET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
570   op,
571   (outs),
572   (ins i1imm:$gds, VReg_32:$addr, rc:$data0, u16imm:$offset),
573   asm#" $addr, $data0, $offset, [M0]",
574   []> {
575
576   let data1 = 0;
577   let mayStore = 1;
578   let mayLoad = 1;
579 }
580
581 class MTBUF_Store_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
582   op,
583   (outs),
584   (ins regClass:$vdata, u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
585    i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr,
586    SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
587   asm#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
588      #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
589   []> {
590   let mayStore = 1;
591   let mayLoad = 0;
592 }
593
594 multiclass MUBUF_Load_Helper <bits<7> op, string asm, RegisterClass regClass,
595                               ValueType load_vt = i32,
596                               SDPatternOperator ld = null_frag> {
597
598   let lds = 0, mayLoad = 1 in {
599
600     let addr64 = 0 in {
601
602       let offen = 0, idxen = 0, vaddr = 0 in {
603         def _OFFSET : MUBUF <op, (outs regClass:$vdata),
604                              (ins SReg_128:$srsrc,
605                              u16imm:$offset, SSrc_32:$soffset, i1imm:$glc,
606                              i1imm:$slc, i1imm:$tfe),
607                              asm#" $vdata, $srsrc + $offset + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
608       }
609
610       let offen = 1, idxen = 0  in {
611         def _OFFEN  : MUBUF <op, (outs regClass:$vdata),
612                              (ins SReg_128:$srsrc, VReg_32:$vaddr,
613                              SSrc_32:$soffset, u16imm:$offset, i1imm:$glc, i1imm:$slc,
614                              i1imm:$tfe),
615                              asm#" $vdata, $srsrc + $vaddr + $soffset + $offset, glc=$glc, slc=$slc, tfe=$tfe", []>;
616       }
617
618       let offen = 0, idxen = 1 in {
619         def _IDXEN  : MUBUF <op, (outs regClass:$vdata),
620                              (ins SReg_128:$srsrc, VReg_32:$vaddr,
621                              u16imm:$offset, SSrc_32:$soffset, i1imm:$glc,
622                              i1imm:$slc, i1imm:$tfe),
623                              asm#" $vdata, $srsrc[$vaddr] + $offset + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
624       }
625
626       let offen = 1, idxen = 1 in {
627         def _BOTHEN : MUBUF <op, (outs regClass:$vdata),
628                              (ins SReg_128:$srsrc, VReg_64:$vaddr,
629                              SSrc_32:$soffset, i1imm:$glc,
630                              i1imm:$slc, i1imm:$tfe),
631                              asm#" $vdata, $srsrc[$vaddr[0]] + $vaddr[1] + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
632       }
633     }
634
635     let offen = 0, idxen = 0, addr64 = 1, glc = 0, slc = 0, tfe = 0, soffset = 128 /* ZERO */ in {
636       def _ADDR64 : MUBUF <op, (outs regClass:$vdata),
637                            (ins SReg_128:$srsrc, VReg_64:$vaddr, u16imm:$offset),
638                            asm#" $vdata, $srsrc + $vaddr + $offset",
639                            [(set load_vt:$vdata, (ld (MUBUFAddr64 v4i32:$srsrc,
640                                                   i64:$vaddr, u16imm:$offset)))]>;
641     }
642   }
643 }
644
645 multiclass MUBUF_Store_Helper <bits<7> op, string name, RegisterClass vdataClass,
646                           ValueType store_vt, SDPatternOperator st> {
647
648   def "" : MUBUF <
649     op, (outs),
650     (ins vdataClass:$vdata, SReg_128:$srsrc, VReg_32:$vaddr, SSrc_32:$soffset,
651          u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$slc,
652          i1imm:$tfe),
653     name#" $vdata, $srsrc, $vaddr, $soffset, $offset $offen $idxen $glc $slc $tfe",
654     []
655   > {
656     let addr64 = 0;
657   }
658
659   def _ADDR64 : MUBUF <
660     op, (outs),
661     (ins vdataClass:$vdata, SReg_128:$srsrc, VReg_64:$vaddr, u16imm:$offset),
662     name#" $vdata, $srsrc + $vaddr + $offset",
663     [(st store_vt:$vdata,
664      (MUBUFAddr64 v4i32:$srsrc, i64:$vaddr, u16imm:$offset))]> {
665
666       let mayLoad = 0;
667       let mayStore = 1;
668
669       // Encoding
670       let offen = 0;
671       let idxen = 0;
672       let glc = 0;
673       let addr64 = 1;
674       let lds = 0;
675       let slc = 0;
676       let tfe = 0;
677       let soffset = 128; // ZERO
678    }
679 }
680
681 class MTBUF_Load_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
682   op,
683   (outs regClass:$dst),
684   (ins u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
685        i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, SReg_128:$srsrc,
686        i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
687   asm#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
688      #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
689   []> {
690   let mayLoad = 1;
691   let mayStore = 0;
692 }
693
694 class MIMG_Mask <string op, int channels> {
695   string Op = op;
696   int Channels = channels;
697 }
698
699 class MIMG_NoSampler_Helper <bits<7> op, string asm,
700                              RegisterClass dst_rc,
701                              RegisterClass src_rc> : MIMG <
702   op,
703   (outs dst_rc:$vdata),
704   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
705        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
706        SReg_256:$srsrc),
707   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
708      #" $tfe, $lwe, $slc, $vaddr, $srsrc",
709   []> {
710   let SSAMP = 0;
711   let mayLoad = 1;
712   let mayStore = 0;
713   let hasPostISelHook = 1;
714 }
715
716 multiclass MIMG_NoSampler_Src_Helper <bits<7> op, string asm,
717                                       RegisterClass dst_rc,
718                                       int channels> {
719   def _V1 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_32>,
720             MIMG_Mask<asm#"_V1", channels>;
721   def _V2 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_64>,
722             MIMG_Mask<asm#"_V2", channels>;
723   def _V4 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_128>,
724             MIMG_Mask<asm#"_V4", channels>;
725 }
726
727 multiclass MIMG_NoSampler <bits<7> op, string asm> {
728   defm _V1 : MIMG_NoSampler_Src_Helper <op, asm, VReg_32, 1>;
729   defm _V2 : MIMG_NoSampler_Src_Helper <op, asm, VReg_64, 2>;
730   defm _V3 : MIMG_NoSampler_Src_Helper <op, asm, VReg_96, 3>;
731   defm _V4 : MIMG_NoSampler_Src_Helper <op, asm, VReg_128, 4>;
732 }
733
734 class MIMG_Sampler_Helper <bits<7> op, string asm,
735                            RegisterClass dst_rc,
736                            RegisterClass src_rc> : MIMG <
737   op,
738   (outs dst_rc:$vdata),
739   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
740        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
741        SReg_256:$srsrc, SReg_128:$ssamp),
742   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
743      #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
744   []> {
745   let mayLoad = 1;
746   let mayStore = 0;
747   let hasPostISelHook = 1;
748 }
749
750 multiclass MIMG_Sampler_Src_Helper <bits<7> op, string asm,
751                                     RegisterClass dst_rc,
752                                     int channels> {
753   def _V1 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_32>,
754             MIMG_Mask<asm#"_V1", channels>;
755   def _V2 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_64>,
756             MIMG_Mask<asm#"_V2", channels>;
757   def _V4 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_128>,
758             MIMG_Mask<asm#"_V4", channels>;
759   def _V8 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_256>,
760             MIMG_Mask<asm#"_V8", channels>;
761   def _V16 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_512>,
762             MIMG_Mask<asm#"_V16", channels>;
763 }
764
765 multiclass MIMG_Sampler <bits<7> op, string asm> {
766   defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VReg_32, 1>;
767   defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2>;
768   defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3>;
769   defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4>;
770 }
771
772 class MIMG_Gather_Helper <bits<7> op, string asm,
773                           RegisterClass dst_rc,
774                           RegisterClass src_rc> : MIMG <
775   op,
776   (outs dst_rc:$vdata),
777   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
778        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
779        SReg_256:$srsrc, SReg_128:$ssamp),
780   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
781      #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
782   []> {
783   let mayLoad = 1;
784   let mayStore = 0;
785
786   // DMASK was repurposed for GATHER4. 4 components are always
787   // returned and DMASK works like a swizzle - it selects
788   // the component to fetch. The only useful DMASK values are
789   // 1=red, 2=green, 4=blue, 8=alpha. (e.g. 1 returns
790   // (red,red,red,red) etc.) The ISA document doesn't mention
791   // this.
792   // Therefore, disable all code which updates DMASK by setting these two:
793   let MIMG = 0;
794   let hasPostISelHook = 0;
795 }
796
797 multiclass MIMG_Gather_Src_Helper <bits<7> op, string asm,
798                                     RegisterClass dst_rc,
799                                     int channels> {
800   def _V1 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_32>,
801             MIMG_Mask<asm#"_V1", channels>;
802   def _V2 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_64>,
803             MIMG_Mask<asm#"_V2", channels>;
804   def _V4 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_128>,
805             MIMG_Mask<asm#"_V4", channels>;
806   def _V8 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_256>,
807             MIMG_Mask<asm#"_V8", channels>;
808   def _V16 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_512>,
809             MIMG_Mask<asm#"_V16", channels>;
810 }
811
812 multiclass MIMG_Gather <bits<7> op, string asm> {
813   defm _V1 : MIMG_Gather_Src_Helper<op, asm, VReg_32, 1>;
814   defm _V2 : MIMG_Gather_Src_Helper<op, asm, VReg_64, 2>;
815   defm _V3 : MIMG_Gather_Src_Helper<op, asm, VReg_96, 3>;
816   defm _V4 : MIMG_Gather_Src_Helper<op, asm, VReg_128, 4>;
817 }
818
819 //===----------------------------------------------------------------------===//
820 // Vector instruction mappings
821 //===----------------------------------------------------------------------===//
822
823 // Maps an opcode in e32 form to its e64 equivalent
824 def getVOPe64 : InstrMapping {
825   let FilterClass = "VOP";
826   let RowFields = ["OpName"];
827   let ColFields = ["Size"];
828   let KeyCol = ["4"];
829   let ValueCols = [["8"]];
830 }
831
832 // Maps an opcode in e64 form to its e32 equivalent
833 def getVOPe32 : InstrMapping {
834   let FilterClass = "VOP";
835   let RowFields = ["OpName"];
836   let ColFields = ["Size"];
837   let KeyCol = ["8"];
838   let ValueCols = [["4"]];
839 }
840
841 // Maps an original opcode to its commuted version
842 def getCommuteRev : InstrMapping {
843   let FilterClass = "VOP2_REV";
844   let RowFields = ["RevOp"];
845   let ColFields = ["IsOrig"];
846   let KeyCol = ["1"];
847   let ValueCols = [["0"]];
848 }
849
850 def getMaskedMIMGOp : InstrMapping {
851   let FilterClass = "MIMG_Mask";
852   let RowFields = ["Op"];
853   let ColFields = ["Channels"];
854   let KeyCol = ["4"];
855   let ValueCols = [["1"], ["2"], ["3"] ];
856 }
857
858 // Maps an commuted opcode to its original version
859 def getCommuteOrig : InstrMapping {
860   let FilterClass = "VOP2_REV";
861   let RowFields = ["RevOp"];
862   let ColFields = ["IsOrig"];
863   let KeyCol = ["0"];
864   let ValueCols = [["1"]];
865 }
866
867 def isDS : InstrMapping {
868   let FilterClass = "DS";
869   let RowFields = ["Inst"];
870   let ColFields = ["Size"];
871   let KeyCol = ["8"];
872   let ValueCols = [["8"]];
873 }
874
875 def getMCOpcode : InstrMapping {
876   let FilterClass = "SIMCInstr";
877   let RowFields = ["PseudoInstr"];
878   let ColFields = ["Subtarget"];
879   let KeyCol = [!cast<string>(SISubtarget.NONE)];
880   let ValueCols = [[!cast<string>(SISubtarget.SI)]];
881 }
882
883 include "SIInstructions.td"