R600/SI: Refactor SOPC classes slightly.
[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 def SIload_constant : SDNode<"AMDGPUISD::LOAD_CONSTANT",
20   SDTypeProfile<1, 2, [SDTCisVT<0, f32>, SDTCisVT<1, i128>, SDTCisVT<2, i32>]>,
21                       [SDNPMayLoad, SDNPMemOperand]
22 >;
23
24 def SItbuffer_store : SDNode<"AMDGPUISD::TBUFFER_STORE_FORMAT",
25   SDTypeProfile<0, 13,
26     [SDTCisVT<0, i128>,   // rsrc(SGPR)
27      SDTCisVT<1, iAny>,   // vdata(VGPR)
28      SDTCisVT<2, i32>,    // num_channels(imm)
29      SDTCisVT<3, i32>,    // vaddr(VGPR)
30      SDTCisVT<4, i32>,    // soffset(SGPR)
31      SDTCisVT<5, i32>,    // inst_offset(imm)
32      SDTCisVT<6, i32>,    // dfmt(imm)
33      SDTCisVT<7, i32>,    // nfmt(imm)
34      SDTCisVT<8, i32>,    // offen(imm)
35      SDTCisVT<9, i32>,    // idxen(imm)
36      SDTCisVT<10, i32>,   // glc(imm)
37      SDTCisVT<11, i32>,   // slc(imm)
38      SDTCisVT<12, i32>    // tfe(imm)
39     ]>,
40   [SDNPMayStore, SDNPMemOperand, SDNPHasChain]
41 >;
42
43 def SIload_input : SDNode<"AMDGPUISD::LOAD_INPUT",
44   SDTypeProfile<1, 3, [SDTCisVT<0, v4f32>, SDTCisVT<1, i128>, SDTCisVT<2, i16>,
45                        SDTCisVT<3, i32>]>
46 >;
47
48 class SDSample<string opcode> : SDNode <opcode,
49   SDTypeProfile<1, 4, [SDTCisVT<0, v4f32>, SDTCisVT<2, v32i8>,
50                        SDTCisVT<3, i128>, SDTCisVT<4, i32>]>
51 >;
52
53 def SIsample : SDSample<"AMDGPUISD::SAMPLE">;
54 def SIsampleb : SDSample<"AMDGPUISD::SAMPLEB">;
55 def SIsampled : SDSample<"AMDGPUISD::SAMPLED">;
56 def SIsamplel : SDSample<"AMDGPUISD::SAMPLEL">;
57
58 // Transformation function, extract the lower 32bit of a 64bit immediate
59 def LO32 : SDNodeXForm<imm, [{
60   return CurDAG->getTargetConstant(N->getZExtValue() & 0xffffffff, MVT::i32);
61 }]>;
62
63 def LO32f : SDNodeXForm<fpimm, [{
64   APInt V = N->getValueAPF().bitcastToAPInt().trunc(32);
65   return CurDAG->getTargetConstantFP(APFloat(APFloat::IEEEsingle, V), MVT::f32);
66 }]>;
67
68 // Transformation function, extract the upper 32bit of a 64bit immediate
69 def HI32 : SDNodeXForm<imm, [{
70   return CurDAG->getTargetConstant(N->getZExtValue() >> 32, MVT::i32);
71 }]>;
72
73 def HI32f : SDNodeXForm<fpimm, [{
74   APInt V = N->getValueAPF().bitcastToAPInt().lshr(32).trunc(32);
75   return CurDAG->getTargetConstantFP(APFloat(APFloat::IEEEsingle, V), MVT::f32);
76 }]>;
77
78 def IMM8bitDWORD : PatLeaf <(imm),
79   [{return (N->getZExtValue() & ~0x3FC) == 0;}]
80 >;
81
82 def as_dword_i32imm : SDNodeXForm<imm, [{
83   return CurDAG->getTargetConstant(N->getZExtValue() >> 2, MVT::i32);
84 }]>;
85
86 def as_i1imm : SDNodeXForm<imm, [{
87   return CurDAG->getTargetConstant(N->getZExtValue(), MVT::i1);
88 }]>;
89
90 def as_i8imm : SDNodeXForm<imm, [{
91   return CurDAG->getTargetConstant(N->getZExtValue(), MVT::i8);
92 }]>;
93
94 def as_i16imm : SDNodeXForm<imm, [{
95   return CurDAG->getTargetConstant(N->getSExtValue(), MVT::i16);
96 }]>;
97
98 def as_i32imm: SDNodeXForm<imm, [{
99   return CurDAG->getTargetConstant(N->getSExtValue(), MVT::i32);
100 }]>;
101
102 def IMM8bit : PatLeaf <(imm),
103   [{return isUInt<8>(N->getZExtValue());}]
104 >;
105
106 def IMM12bit : PatLeaf <(imm),
107   [{return isUInt<12>(N->getZExtValue());}]
108 >;
109
110 def IMM16bit : PatLeaf <(imm),
111   [{return isUInt<16>(N->getZExtValue());}]
112 >;
113
114 def mubuf_vaddr_offset : PatFrag<
115   (ops node:$ptr, node:$offset, node:$imm_offset),
116   (add (add node:$ptr, node:$offset), node:$imm_offset)
117 >;
118
119 class InlineImm <ValueType vt> : PatLeaf <(vt imm), [{
120   return isInlineImmediate(N);
121 }]>;
122
123 class SGPRImm <dag frag> : PatLeaf<frag, [{
124   if (TM.getSubtarget<AMDGPUSubtarget>().getGeneration() <
125       AMDGPUSubtarget::SOUTHERN_ISLANDS) {
126     return false;
127   }
128   const SIRegisterInfo *SIRI =
129                        static_cast<const SIRegisterInfo*>(TM.getRegisterInfo());
130   for (SDNode::use_iterator U = N->use_begin(), E = SDNode::use_end();
131                                                 U != E; ++U) {
132     if (SIRI->isSGPRClass(getOperandRegClass(*U, U.getOperandNo()))) {
133       return true;
134     }
135   }
136   return false;
137 }]>;
138
139 def FRAMEri32 : Operand<iPTR> {
140   let MIOperandInfo = (ops SReg_32:$ptr, i32imm:$index);
141 }
142
143 //===----------------------------------------------------------------------===//
144 // SI assembler operands
145 //===----------------------------------------------------------------------===//
146
147 def SIOperand {
148   int ZERO = 0x80;
149   int VCC = 0x6A;
150 }
151
152 include "SIInstrFormats.td"
153
154 //===----------------------------------------------------------------------===//
155 //
156 // SI Instruction multiclass helpers.
157 //
158 // Instructions with _32 take 32-bit operands.
159 // Instructions with _64 take 64-bit operands.
160 //
161 // VOP_* instructions can use either a 32-bit or 64-bit encoding.  The 32-bit
162 // encoding is the standard encoding, but instruction that make use of
163 // any of the instruction modifiers must use the 64-bit encoding.
164 //
165 // Instructions with _e32 use the 32-bit encoding.
166 // Instructions with _e64 use the 64-bit encoding.
167 //
168 //===----------------------------------------------------------------------===//
169
170 //===----------------------------------------------------------------------===//
171 // Scalar classes
172 //===----------------------------------------------------------------------===//
173
174 class SOP1_32 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
175   op, (outs SReg_32:$dst), (ins SSrc_32:$src0),
176   opName#" $dst, $src0", pattern
177 >;
178
179 class SOP1_64 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
180   op, (outs SReg_64:$dst), (ins SSrc_64:$src0),
181   opName#" $dst, $src0", pattern
182 >;
183
184 class SOP2_32 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
185   op, (outs SReg_32:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
186   opName#" $dst, $src0, $src1", pattern
187 >;
188
189 class SOP2_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
190   op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
191   opName#" $dst, $src0, $src1", pattern
192 >;
193
194 class SOP2_SHIFT_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
195   op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_32:$src1),
196   opName#" $dst, $src0, $src1", pattern
197 >;
198
199
200 class SOPC_Helper <bits<7> op, RegisterClass rc, ValueType vt,
201                     string opName, PatLeaf cond> : SOPC <
202   op, (outs SCCReg:$dst), (ins rc:$src0, rc:$src1),
203   opName#" $dst, $src0, $src1", []>;
204
205 class SOPC_32<bits<7> op, string opName, PatLeaf cond = COND_NULL>
206   : SOPC_Helper<op, SSrc_32, i32, opName, cond>;
207
208 class SOPC_64<bits<7> op, string opName, PatLeaf cond = COND_NULL>
209   : SOPC_Helper<op, SSrc_64, i64, opName, cond>;
210
211 class SOPK_32 <bits<5> op, string opName, list<dag> pattern> : SOPK <
212   op, (outs SReg_32:$dst), (ins i16imm:$src0),
213   opName#" $dst, $src0", pattern
214 >;
215
216 class SOPK_64 <bits<5> op, string opName, list<dag> pattern> : SOPK <
217   op, (outs SReg_64:$dst), (ins i16imm:$src0),
218   opName#" $dst, $src0", pattern
219 >;
220
221 multiclass SMRD_Helper <bits<5> op, string asm, RegisterClass baseClass,
222                         RegisterClass dstClass> {
223   def _IMM : SMRD <
224     op, 1, (outs dstClass:$dst),
225     (ins baseClass:$sbase, i32imm:$offset),
226     asm#" $dst, $sbase, $offset", []
227   >;
228
229   def _SGPR : SMRD <
230     op, 0, (outs dstClass:$dst),
231     (ins baseClass:$sbase, SReg_32:$soff),
232     asm#" $dst, $sbase, $soff", []
233   >;
234 }
235
236 //===----------------------------------------------------------------------===//
237 // Vector ALU classes
238 //===----------------------------------------------------------------------===//
239
240 class VOP <string opName> {
241   string OpName = opName;
242 }
243
244 class VOP2_REV <string revOp, bit isOrig> {
245   string RevOp = revOp;
246   bit IsOrig = isOrig;
247 }
248
249 multiclass VOP1_Helper <bits<8> op, RegisterClass drc, RegisterClass src,
250                         string opName, list<dag> pattern> {
251
252   def _e32 : VOP1 <
253     op, (outs drc:$dst), (ins src:$src0),
254     opName#"_e32 $dst, $src0", pattern
255   >, VOP <opName>;
256
257   def _e64 : VOP3 <
258     {1, 1, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
259     (outs drc:$dst),
260     (ins src:$src0,
261          i32imm:$abs, i32imm:$clamp,
262          i32imm:$omod, i32imm:$neg),
263     opName#"_e64 $dst, $src0, $abs, $clamp, $omod, $neg", []
264   >, VOP <opName> {
265     let src1 = SIOperand.ZERO;
266     let src2 = SIOperand.ZERO;
267   }
268 }
269
270 multiclass VOP1_32 <bits<8> op, string opName, list<dag> pattern>
271   : VOP1_Helper <op, VReg_32, VSrc_32, opName, pattern>;
272
273 multiclass VOP1_64 <bits<8> op, string opName, list<dag> pattern>
274   : VOP1_Helper <op, VReg_64, VSrc_64, opName, pattern>;
275
276 multiclass VOP1_32_64 <bits<8> op, string opName, list<dag> pattern>
277   : VOP1_Helper <op, VReg_32, VSrc_64, opName, pattern>;
278
279 multiclass VOP1_64_32 <bits<8> op, string opName, list<dag> pattern>
280   : VOP1_Helper <op, VReg_64, VSrc_32, opName, pattern>;
281
282 multiclass VOP2_Helper <bits<6> op, RegisterClass vrc, RegisterClass arc,
283                         string opName, list<dag> pattern, string revOp> {
284   def _e32 : VOP2 <
285     op, (outs vrc:$dst), (ins arc:$src0, vrc:$src1),
286     opName#"_e32 $dst, $src0, $src1", pattern
287   >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
288
289   def _e64 : VOP3 <
290     {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
291     (outs vrc:$dst),
292     (ins arc:$src0, arc:$src1,
293          i32imm:$abs, i32imm:$clamp,
294          i32imm:$omod, i32imm:$neg),
295     opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg", []
296   >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
297     let src2 = SIOperand.ZERO;
298   }
299 }
300
301 multiclass VOP2_32 <bits<6> op, string opName, list<dag> pattern,
302                     string revOp = opName>
303   : VOP2_Helper <op, VReg_32, VSrc_32, opName, pattern, revOp>;
304
305 multiclass VOP2_64 <bits<6> op, string opName, list<dag> pattern,
306                     string revOp = opName>
307   : VOP2_Helper <op, VReg_64, VSrc_64, opName, pattern, revOp>;
308
309 multiclass VOP2b_32 <bits<6> op, string opName, list<dag> pattern,
310                      RegisterClass src0_rc, string revOp = opName> {
311
312   def _e32 : VOP2 <
313     op, (outs VReg_32:$dst), (ins src0_rc:$src0, VReg_32:$src1),
314     opName#"_e32 $dst, $src0, $src1", pattern
315   >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
316
317   def _e64 : VOP3b <
318     {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
319     (outs VReg_32:$dst),
320     (ins VSrc_32:$src0, VSrc_32:$src1,
321          i32imm:$abs, i32imm:$clamp,
322          i32imm:$omod, i32imm:$neg),
323     opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg", []
324   >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
325     let src2 = SIOperand.ZERO;
326     /* the VOP2 variant puts the carry out into VCC, the VOP3 variant
327        can write it into any SGPR. We currently don't use the carry out,
328        so for now hardcode it to VCC as well */
329     let sdst = SIOperand.VCC;
330   }
331 }
332
333 multiclass VOPC_Helper <bits<8> op, RegisterClass vrc, RegisterClass arc,
334                         string opName, ValueType vt, PatLeaf cond> {
335
336   def _e32 : VOPC <
337     op, (ins arc:$src0, vrc:$src1),
338     opName#"_e32 $dst, $src0, $src1", []
339   >, VOP <opName>;
340
341   def _e64 : VOP3 <
342     {0, op{7}, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
343     (outs SReg_64:$dst),
344     (ins arc:$src0, arc:$src1,
345          InstFlag:$abs, InstFlag:$clamp,
346          InstFlag:$omod, InstFlag:$neg),
347     opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg",
348     !if(!eq(!cast<string>(cond), "COND_NULL"), []<dag>,
349       [(set SReg_64:$dst, (i1 (setcc (vt arc:$src0), arc:$src1, cond)))]
350     )
351   >, VOP <opName> {
352     let src2 = SIOperand.ZERO;
353   }
354 }
355
356 multiclass VOPC_32 <bits<8> op, string opName,
357   ValueType vt = untyped, PatLeaf cond = COND_NULL>
358   : VOPC_Helper <op, VReg_32, VSrc_32, opName, vt, cond>;
359
360 multiclass VOPC_64 <bits<8> op, string opName,
361   ValueType vt = untyped, PatLeaf cond = COND_NULL>
362   : VOPC_Helper <op, VReg_64, VSrc_64, opName, vt, cond>;
363
364 class VOP3_32 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
365   op, (outs VReg_32:$dst),
366   (ins VSrc_32:$src0, VSrc_32:$src1, VSrc_32:$src2,
367    InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg),
368   opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
369 >, VOP <opName>;
370
371 class VOP3_64_Shift <bits <9> op, string opName, list<dag> pattern> : VOP3 <
372   op, (outs VReg_64:$dst),
373   (ins VSrc_64:$src0, VSrc_32:$src1),
374   opName#" $dst, $src0, $src1", pattern
375 >, VOP <opName> {
376
377   let src2 = SIOperand.ZERO;
378   let abs = 0;
379   let clamp = 0;
380   let omod = 0;
381   let neg = 0;
382 }
383
384 class VOP3_64 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
385   op, (outs VReg_64:$dst),
386   (ins VSrc_64:$src0, VSrc_64:$src1, VSrc_64:$src2,
387    InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg),
388   opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
389 >, VOP <opName>;
390
391 //===----------------------------------------------------------------------===//
392 // Vector I/O classes
393 //===----------------------------------------------------------------------===//
394
395 class DS_1A <bits<8> op, dag outs, dag ins, string asm, list<dag> pat> :
396     DS <op, outs, ins, asm, pat> {
397   bits<16> offset;
398
399   // Single load interpret the 2 i8imm operands as a single i16 offset.
400   let offset0 = offset{7-0};
401   let offset1 = offset{15-8};
402 }
403
404 class DS_Load_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
405   op,
406   (outs regClass:$vdst),
407   (ins i1imm:$gds, VReg_32:$addr, i16imm:$offset),
408   asm#" $vdst, $addr, $offset, [M0]",
409   []> {
410   let data0 = 0;
411   let data1 = 0;
412   let mayLoad = 1;
413   let mayStore = 0;
414 }
415
416 class DS_Load2_Helper <bits<8> op, string asm, RegisterClass regClass> : DS <
417   op,
418   (outs regClass:$vdst),
419   (ins i1imm:$gds, VReg_32:$addr, i8imm:$offset0, i8imm:$offset1),
420   asm#" $gds, $vdst, $addr, $offset0, $offset1, [M0]",
421   []> {
422   let data0 = 0;
423   let data1 = 0;
424   let mayLoad = 1;
425   let mayStore = 0;
426 }
427
428 class DS_Store_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
429   op,
430   (outs),
431   (ins i1imm:$gds, VReg_32:$addr, regClass:$data0, i16imm:$offset),
432   asm#" $addr, $data0, $offset [M0]",
433   []> {
434   let data1 = 0;
435   let mayStore = 1;
436   let mayLoad = 0;
437   let vdst = 0;
438 }
439
440 class DS_Store2_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
441   op,
442   (outs),
443   (ins i1imm:$gds, VReg_32:$addr, regClass:$data0, i8imm:$offset0, i8imm:$offset1),
444   asm#" $addr, $data0, $data1, $offset0, $offset1 [M0]",
445   []> {
446   let mayStore = 1;
447   let mayLoad = 0;
448   let vdst = 0;
449 }
450
451 class DS_1A1D_RET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
452   op,
453   (outs rc:$vdst),
454   (ins i1imm:$gds, VReg_32:$addr, VReg_32:$data0, i16imm:$offset),
455   asm#" $vdst, $addr, $data0, $offset, [M0]",
456   []> {
457
458   let data1 = 0;
459   let mayStore = 1;
460   let mayLoad = 1;
461 }
462
463 class MTBUF_Store_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
464   op,
465   (outs),
466   (ins regClass:$vdata, i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
467    i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr,
468    SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
469   asm#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
470      #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
471   []> {
472   let mayStore = 1;
473   let mayLoad = 0;
474 }
475
476 multiclass MUBUF_Load_Helper <bits<7> op, string asm, RegisterClass regClass> {
477
478   let lds = 0, mayLoad = 1 in {
479
480     let addr64 = 0 in {
481
482       let offen = 0, idxen = 0 in {
483         def _OFFSET : MUBUF <op, (outs regClass:$vdata),
484                              (ins SReg_128:$srsrc, VReg_32:$vaddr,
485                              i16imm:$offset, SSrc_32:$soffset, i1imm:$glc,
486                              i1imm:$slc, i1imm:$tfe),
487                              asm#" $vdata, $srsrc + $offset + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
488       }
489
490       let offen = 1, idxen = 0, offset = 0 in {
491         def _OFFEN  : MUBUF <op, (outs regClass:$vdata),
492                              (ins SReg_128:$srsrc, VReg_32:$vaddr,
493                              SSrc_32:$soffset, i1imm:$glc, i1imm:$slc,
494                              i1imm:$tfe),
495                              asm#" $vdata, $srsrc + $vaddr + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
496       }
497
498       let offen = 0, idxen = 1 in {
499         def _IDXEN  : MUBUF <op, (outs regClass:$vdata),
500                              (ins SReg_128:$srsrc, VReg_32:$vaddr,
501                              i16imm:$offset, SSrc_32:$soffset, i1imm:$glc,
502                              i1imm:$slc, i1imm:$tfe),
503                              asm#" $vdata, $srsrc[$vaddr] + $offset + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
504       }
505
506       let offen = 1, idxen = 1 in {
507         def _BOTHEN : MUBUF <op, (outs regClass:$vdata),
508                              (ins SReg_128:$srsrc, VReg_64:$vaddr,
509                              SSrc_32:$soffset, i1imm:$glc,
510                              i1imm:$slc, i1imm:$tfe),
511                              asm#" $vdata, $srsrc[$vaddr[0]] + $vaddr[1] + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
512       }
513     }
514
515     let offen = 0, idxen = 0, addr64 = 1, glc = 0, slc = 0, tfe = 0, soffset = 128 /* ZERO */ in {
516       def _ADDR64 : MUBUF <op, (outs regClass:$vdata),
517                            (ins SReg_128:$srsrc, VReg_64:$vaddr, i16imm:$offset),
518                            asm#" $vdata, $srsrc + $vaddr + $offset", []>;
519     }
520   }
521 }
522
523 class MUBUF_Store_Helper <bits<7> op, string name, RegisterClass vdataClass> :
524     MUBUF <op, (outs), (ins vdataClass:$vdata, SReg_128:$srsrc, VReg_64:$vaddr,
525                             i16imm:$offset),
526           name#" $vdata, $srsrc + $vaddr + $offset",
527          []> {
528
529   let mayLoad = 0;
530   let mayStore = 1;
531
532   // Encoding
533   let offen = 0;
534   let idxen = 0;
535   let glc = 0;
536   let addr64 = 1;
537   let lds = 0;
538   let slc = 0;
539   let tfe = 0;
540   let soffset = 128; // ZERO
541 }
542
543 class MTBUF_Load_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
544   op,
545   (outs regClass:$dst),
546   (ins i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
547        i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, SReg_128:$srsrc,
548        i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
549   asm#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
550      #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
551   []> {
552   let mayLoad = 1;
553   let mayStore = 0;
554 }
555
556 class MIMG_Mask <string op, int channels> {
557   string Op = op;
558   int Channels = channels;
559 }
560
561 class MIMG_NoSampler_Helper <bits<7> op, string asm,
562                              RegisterClass dst_rc,
563                              RegisterClass src_rc> : MIMG <
564   op,
565   (outs dst_rc:$vdata),
566   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
567        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
568        SReg_256:$srsrc),
569   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
570      #" $tfe, $lwe, $slc, $vaddr, $srsrc",
571   []> {
572   let SSAMP = 0;
573   let mayLoad = 1;
574   let mayStore = 0;
575   let hasPostISelHook = 1;
576 }
577
578 multiclass MIMG_NoSampler_Src_Helper <bits<7> op, string asm,
579                                       RegisterClass dst_rc,
580                                       int channels> {
581   def _V1 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_32>,
582             MIMG_Mask<asm#"_V1", channels>;
583   def _V2 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_64>,
584             MIMG_Mask<asm#"_V2", channels>;
585   def _V4 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_128>,
586             MIMG_Mask<asm#"_V4", channels>;
587 }
588
589 multiclass MIMG_NoSampler <bits<7> op, string asm> {
590   defm _V1 : MIMG_NoSampler_Src_Helper <op, asm, VReg_32, 1>;
591   defm _V2 : MIMG_NoSampler_Src_Helper <op, asm, VReg_64, 2>;
592   defm _V3 : MIMG_NoSampler_Src_Helper <op, asm, VReg_96, 3>;
593   defm _V4 : MIMG_NoSampler_Src_Helper <op, asm, VReg_128, 4>;
594 }
595
596 class MIMG_Sampler_Helper <bits<7> op, string asm,
597                            RegisterClass dst_rc,
598                            RegisterClass src_rc> : MIMG <
599   op,
600   (outs dst_rc:$vdata),
601   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
602        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
603        SReg_256:$srsrc, SReg_128:$ssamp),
604   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
605      #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
606   []> {
607   let mayLoad = 1;
608   let mayStore = 0;
609   let hasPostISelHook = 1;
610 }
611
612 multiclass MIMG_Sampler_Src_Helper <bits<7> op, string asm,
613                                     RegisterClass dst_rc,
614                                     int channels> {
615   def _V1 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_32>,
616             MIMG_Mask<asm#"_V1", channels>;
617   def _V2 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_64>,
618             MIMG_Mask<asm#"_V2", channels>;
619   def _V4 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_128>,
620             MIMG_Mask<asm#"_V4", channels>;
621   def _V8 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_256>,
622             MIMG_Mask<asm#"_V8", channels>;
623   def _V16 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_512>,
624             MIMG_Mask<asm#"_V16", channels>;
625 }
626
627 multiclass MIMG_Sampler <bits<7> op, string asm> {
628   defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VReg_32, 1>;
629   defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2>;
630   defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3>;
631   defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4>;
632 }
633
634 //===----------------------------------------------------------------------===//
635 // Vector instruction mappings
636 //===----------------------------------------------------------------------===//
637
638 // Maps an opcode in e32 form to its e64 equivalent
639 def getVOPe64 : InstrMapping {
640   let FilterClass = "VOP";
641   let RowFields = ["OpName"];
642   let ColFields = ["Size"];
643   let KeyCol = ["4"];
644   let ValueCols = [["8"]];
645 }
646
647 // Maps an original opcode to its commuted version
648 def getCommuteRev : InstrMapping {
649   let FilterClass = "VOP2_REV";
650   let RowFields = ["RevOp"];
651   let ColFields = ["IsOrig"];
652   let KeyCol = ["1"];
653   let ValueCols = [["0"]];
654 }
655
656 def getMaskedMIMGOp : InstrMapping {
657   let FilterClass = "MIMG_Mask";
658   let RowFields = ["Op"];
659   let ColFields = ["Channels"];
660   let KeyCol = ["4"];
661   let ValueCols = [["1"], ["2"], ["3"] ];
662 }
663
664 // Maps an commuted opcode to its original version
665 def getCommuteOrig : InstrMapping {
666   let FilterClass = "VOP2_REV";
667   let RowFields = ["RevOp"];
668   let ColFields = ["IsOrig"];
669   let KeyCol = ["0"];
670   let ValueCols = [["1"]];
671 }
672
673 def isDS : InstrMapping {
674   let FilterClass = "DS";
675   let RowFields = ["Inst"];
676   let ColFields = ["Size"];
677   let KeyCol = ["8"];
678   let ValueCols = [["8"]];
679 }
680
681 include "SIInstructions.td"