R600/SI: Define a separate MIMG instruction for each possible output value type
[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 : ImmLeaf <
79   i32, [{
80     return (Imm & ~0x3FC) == 0;
81   }], SDNodeXForm<imm, [{
82     return CurDAG->getTargetConstant(
83       N->getZExtValue() >> 2, MVT::i32);
84   }]>
85 >;
86
87 def as_i1imm : SDNodeXForm<imm, [{
88   return CurDAG->getTargetConstant(N->getZExtValue(), MVT::i1);
89 }]>;
90
91 def as_i8imm : SDNodeXForm<imm, [{
92   return CurDAG->getTargetConstant(N->getZExtValue(), MVT::i8);
93 }]>;
94
95 def as_i16imm : SDNodeXForm<imm, [{
96   return CurDAG->getTargetConstant(N->getSExtValue(), MVT::i16);
97 }]>;
98
99 def IMM12bit : PatLeaf <(imm),
100   [{return isUInt<12>(N->getZExtValue());}]
101 >;
102
103 class InlineImm <ValueType vt> : PatLeaf <(vt imm), [{
104   return
105     (*(const SITargetLowering *)getTargetLowering()).analyzeImmediate(N) == 0;
106 }]>;
107
108 class SGPRImm <dag frag> : PatLeaf<frag, [{
109   if (TM.getSubtarget<AMDGPUSubtarget>().getGeneration() <
110       AMDGPUSubtarget::SOUTHERN_ISLANDS) {
111     return false;
112   }
113   const SIRegisterInfo *SIRI =
114                        static_cast<const SIRegisterInfo*>(TM.getRegisterInfo());
115   for (SDNode::use_iterator U = N->use_begin(), E = SDNode::use_end();
116                                                 U != E; ++U) {
117     if (SIRI->isSGPRClass(getOperandRegClass(*U, U.getOperandNo()))) {
118       return true;
119     }
120   }
121   return false;
122 }]>;
123
124 //===----------------------------------------------------------------------===//
125 // SI assembler operands
126 //===----------------------------------------------------------------------===//
127
128 def SIOperand {
129   int ZERO = 0x80;
130   int VCC = 0x6A;
131 }
132
133 include "SIInstrFormats.td"
134
135 //===----------------------------------------------------------------------===//
136 //
137 // SI Instruction multiclass helpers.
138 //
139 // Instructions with _32 take 32-bit operands.
140 // Instructions with _64 take 64-bit operands.
141 //
142 // VOP_* instructions can use either a 32-bit or 64-bit encoding.  The 32-bit
143 // encoding is the standard encoding, but instruction that make use of
144 // any of the instruction modifiers must use the 64-bit encoding.
145 //
146 // Instructions with _e32 use the 32-bit encoding.
147 // Instructions with _e64 use the 64-bit encoding.
148 //
149 //===----------------------------------------------------------------------===//
150
151 //===----------------------------------------------------------------------===//
152 // Scalar classes
153 //===----------------------------------------------------------------------===//
154
155 class SOP1_32 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
156   op, (outs SReg_32:$dst), (ins SSrc_32:$src0),
157   opName#" $dst, $src0", pattern
158 >;
159
160 class SOP1_64 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
161   op, (outs SReg_64:$dst), (ins SSrc_64:$src0),
162   opName#" $dst, $src0", pattern
163 >;
164
165 class SOP2_32 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
166   op, (outs SReg_32:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
167   opName#" $dst, $src0, $src1", pattern
168 >;
169
170 class SOP2_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
171   op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
172   opName#" $dst, $src0, $src1", pattern
173 >;
174
175 class SOPC_32 <bits<7> op, string opName, list<dag> pattern> : SOPC <
176   op, (outs SCCReg:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
177   opName#" $dst, $src0, $src1", pattern
178 >;
179
180 class SOPC_64 <bits<7> op, string opName, list<dag> pattern> : SOPC <
181   op, (outs SCCReg:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
182   opName#" $dst, $src0, $src1", pattern
183 >;
184
185 class SOPK_32 <bits<5> op, string opName, list<dag> pattern> : SOPK <
186   op, (outs SReg_32:$dst), (ins i16imm:$src0),
187   opName#" $dst, $src0", pattern
188 >;
189
190 class SOPK_64 <bits<5> op, string opName, list<dag> pattern> : SOPK <
191   op, (outs SReg_64:$dst), (ins i16imm:$src0),
192   opName#" $dst, $src0", pattern
193 >;
194
195 multiclass SMRD_Helper <bits<5> op, string asm, RegisterClass baseClass,
196                         RegisterClass dstClass> {
197   def _IMM : SMRD <
198     op, 1, (outs dstClass:$dst),
199     (ins baseClass:$sbase, i32imm:$offset),
200     asm#" $dst, $sbase, $offset", []
201   >;
202
203   def _SGPR : SMRD <
204     op, 0, (outs dstClass:$dst),
205     (ins baseClass:$sbase, SReg_32:$soff),
206     asm#" $dst, $sbase, $soff", []
207   >;
208 }
209
210 //===----------------------------------------------------------------------===//
211 // Vector ALU classes
212 //===----------------------------------------------------------------------===//
213
214 class VOP <string opName> {
215   string OpName = opName;
216 }
217
218 class VOP2_REV <string revOp, bit isOrig> {
219   string RevOp = revOp;
220   bit IsOrig = isOrig;
221 }
222
223 multiclass VOP1_Helper <bits<8> op, RegisterClass drc, RegisterClass src,
224                         string opName, list<dag> pattern> {
225
226   def _e32 : VOP1 <
227     op, (outs drc:$dst), (ins src:$src0),
228     opName#"_e32 $dst, $src0", pattern
229   >, VOP <opName>;
230
231   def _e64 : VOP3 <
232     {1, 1, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
233     (outs drc:$dst),
234     (ins src:$src0,
235          i32imm:$abs, i32imm:$clamp,
236          i32imm:$omod, i32imm:$neg),
237     opName#"_e64 $dst, $src0, $abs, $clamp, $omod, $neg", []
238   >, VOP <opName> {
239     let src1 = SIOperand.ZERO;
240     let src2 = SIOperand.ZERO;
241   }
242 }
243
244 multiclass VOP1_32 <bits<8> op, string opName, list<dag> pattern>
245   : VOP1_Helper <op, VReg_32, VSrc_32, opName, pattern>;
246
247 multiclass VOP1_64 <bits<8> op, string opName, list<dag> pattern>
248   : VOP1_Helper <op, VReg_64, VSrc_64, opName, pattern>;
249
250 multiclass VOP1_32_64 <bits<8> op, string opName, list<dag> pattern>
251   : VOP1_Helper <op, VReg_32, VSrc_64, opName, pattern>;
252
253 multiclass VOP1_64_32 <bits<8> op, string opName, list<dag> pattern>
254   : VOP1_Helper <op, VReg_64, VSrc_32, opName, pattern>;
255
256 multiclass VOP2_Helper <bits<6> op, RegisterClass vrc, RegisterClass arc,
257                         string opName, list<dag> pattern, string revOp> {
258   def _e32 : VOP2 <
259     op, (outs vrc:$dst), (ins arc:$src0, vrc:$src1),
260     opName#"_e32 $dst, $src0, $src1", pattern
261   >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
262
263   def _e64 : VOP3 <
264     {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
265     (outs vrc:$dst),
266     (ins arc:$src0, arc:$src1,
267          i32imm:$abs, i32imm:$clamp,
268          i32imm:$omod, i32imm:$neg),
269     opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg", []
270   >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
271     let src2 = SIOperand.ZERO;
272   }
273 }
274
275 multiclass VOP2_32 <bits<6> op, string opName, list<dag> pattern,
276                     string revOp = opName>
277   : VOP2_Helper <op, VReg_32, VSrc_32, opName, pattern, revOp>;
278
279 multiclass VOP2_64 <bits<6> op, string opName, list<dag> pattern,
280                     string revOp = opName>
281   : VOP2_Helper <op, VReg_64, VSrc_64, opName, pattern, revOp>;
282
283 multiclass VOP2b_32 <bits<6> op, string opName, list<dag> pattern,
284                      string revOp = opName> {
285
286   def _e32 : VOP2 <
287     op, (outs VReg_32:$dst), (ins VSrc_32:$src0, VReg_32:$src1),
288     opName#"_e32 $dst, $src0, $src1", pattern
289   >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
290
291   def _e64 : VOP3b <
292     {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
293     (outs VReg_32:$dst),
294     (ins VSrc_32:$src0, VSrc_32:$src1,
295          i32imm:$abs, i32imm:$clamp,
296          i32imm:$omod, i32imm:$neg),
297     opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg", []
298   >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
299     let src2 = SIOperand.ZERO;
300     /* the VOP2 variant puts the carry out into VCC, the VOP3 variant
301        can write it into any SGPR. We currently don't use the carry out,
302        so for now hardcode it to VCC as well */
303     let sdst = SIOperand.VCC;
304   }
305 }
306
307 multiclass VOPC_Helper <bits<8> op, RegisterClass vrc, RegisterClass arc,
308                         string opName, ValueType vt, PatLeaf cond> {
309
310   def _e32 : VOPC <
311     op, (ins arc:$src0, vrc:$src1),
312     opName#"_e32 $dst, $src0, $src1", []
313   >, VOP <opName>;
314
315   def _e64 : VOP3 <
316     {0, op{7}, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
317     (outs SReg_64:$dst),
318     (ins arc:$src0, arc:$src1,
319          InstFlag:$abs, InstFlag:$clamp,
320          InstFlag:$omod, InstFlag:$neg),
321     opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg",
322     !if(!eq(!cast<string>(cond), "COND_NULL"), []<dag>,
323       [(set SReg_64:$dst, (i1 (setcc (vt arc:$src0), arc:$src1, cond)))]
324     )
325   >, VOP <opName> {
326     let src2 = SIOperand.ZERO;
327   }
328 }
329
330 multiclass VOPC_32 <bits<8> op, string opName,
331   ValueType vt = untyped, PatLeaf cond = COND_NULL>
332   : VOPC_Helper <op, VReg_32, VSrc_32, opName, vt, cond>;
333
334 multiclass VOPC_64 <bits<8> op, string opName,
335   ValueType vt = untyped, PatLeaf cond = COND_NULL>
336   : VOPC_Helper <op, VReg_64, VSrc_64, opName, vt, cond>;
337
338 class VOP3_32 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
339   op, (outs VReg_32:$dst),
340   (ins VSrc_32:$src0, VSrc_32:$src1, VSrc_32:$src2,
341    InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg),
342   opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
343 >, VOP <opName>;
344
345 class VOP3_64_Shift <bits <9> op, string opName, list<dag> pattern> : VOP3 <
346   op, (outs VReg_64:$dst),
347   (ins VSrc_64:$src0, VSrc_32:$src1),
348   opName#" $dst, $src0, $src1", pattern
349 >, VOP <opName> {
350
351   let src2 = SIOperand.ZERO;
352   let abs = 0;
353   let clamp = 0;
354   let omod = 0;
355   let neg = 0;
356 }
357
358 class VOP3_64 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
359   op, (outs VReg_64:$dst),
360   (ins VSrc_64:$src0, VSrc_64:$src1, VSrc_64:$src2,
361    InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg),
362   opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
363 >, VOP <opName>;
364
365 //===----------------------------------------------------------------------===//
366 // Vector I/O classes
367 //===----------------------------------------------------------------------===//
368
369 class DS_Load_Helper <bits<8> op, string asm, RegisterClass regClass> : DS <
370   op,
371   (outs regClass:$vdst),
372   (ins i1imm:$gds, VReg_32:$addr, VReg_32:$data0, VReg_32:$data1,
373        i8imm:$offset0, i8imm:$offset1),
374   asm#" $vdst, $gds, $addr, $data0, $data1, $offset0, $offset1, [M0]",
375   []> {
376   let mayLoad = 1;
377   let mayStore = 0;
378 }
379
380 class DS_Store_Helper <bits<8> op, string asm, RegisterClass regClass> : DS <
381   op,
382   (outs),
383   (ins i1imm:$gds, VReg_32:$addr, VReg_32:$data0, VReg_32:$data1,
384        i8imm:$offset0, i8imm:$offset1),
385   asm#" $gds, $addr, $data0, $data1, $offset0, $offset1, [M0]",
386   []> {
387   let mayStore = 1;
388   let mayLoad = 0;
389   let vdst = 0;
390 }
391
392 class DS_1A1D_RET <bits<8> op, string asm, RegisterClass rc> : DS <
393   op,
394   (outs rc:$vdst),
395   (ins i1imm:$gds, VReg_32:$addr, VReg_32:$data0, i8imm:$offset0,
396        i8imm:$offset1),
397   asm#" $gds, $vdst, $addr, $data0, $offset0, $offset1, [M0]",
398   []> {
399   let mayStore = 1;
400   let mayLoad = 1;
401   let data1 = 0;
402 }
403
404 class MTBUF_Store_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
405   op,
406   (outs),
407   (ins regClass:$vdata, i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
408    i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr,
409    SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
410   asm#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
411      #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
412   []> {
413   let mayStore = 1;
414   let mayLoad = 0;
415 }
416
417 multiclass MUBUF_Load_Helper <bits<7> op, string asm, RegisterClass regClass> {
418
419   let glc = 0, lds = 0, slc = 0, tfe = 0, soffset = 128 /* ZERO */,
420                                           mayLoad = 1 in {
421
422   let offen = 1, idxen = 0, addr64 = 0, offset = 0 in {
423     def _OFFEN  : MUBUF <op, (outs regClass:$vdata),
424                          (ins SReg_128:$srsrc, VReg_32:$vaddr),
425                          asm#" $vdata, $srsrc + $vaddr", []>;
426   }
427
428   let offen = 0, idxen = 1, addr64 = 0 in {
429     def _IDXEN  : MUBUF <op, (outs regClass:$vdata),
430                          (ins SReg_128:$srsrc, VReg_32:$vaddr, i16imm:$offset),
431                          asm#" $vdata, $srsrc[$vaddr] + $offset", []>;
432   }
433
434   let offen = 0, idxen = 0, addr64 = 1 in {
435     def _ADDR64 : MUBUF <op, (outs regClass:$vdata),
436                          (ins SReg_128:$srsrc, VReg_64:$vaddr, i16imm:$offset),
437                          asm#" $vdata, $srsrc + $vaddr + $offset", []>;
438   }
439   }
440 }
441
442 class MUBUF_Store_Helper <bits<7> op, string name, RegisterClass vdataClass> :
443     MUBUF <op, (outs), (ins vdataClass:$vdata, SReg_128:$srsrc, VReg_64:$vaddr,
444                             i16imm:$offset),
445           name#" $vdata, $srsrc + $vaddr + $offset",
446          []> {
447
448   let mayLoad = 0;
449   let mayStore = 1;
450
451   // Encoding
452   let offen = 0;
453   let idxen = 0;
454   let glc = 0;
455   let addr64 = 1;
456   let lds = 0;
457   let slc = 0;
458   let tfe = 0;
459   let soffset = 128; // ZERO
460 }
461
462 class MTBUF_Load_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
463   op,
464   (outs regClass:$dst),
465   (ins i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
466        i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, SReg_128:$srsrc,
467        i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
468   asm#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
469      #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
470   []> {
471   let mayLoad = 1;
472   let mayStore = 0;
473 }
474
475 class MIMG_Mask <string op, int channels> {
476   string Op = op;
477   int Channels = channels;
478 }
479
480 class MIMG_NoSampler_Helper <bits<7> op, string asm,
481                              RegisterClass dst_rc,
482                              RegisterClass src_rc> : MIMG <
483   op,
484   (outs dst_rc:$vdata),
485   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
486        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
487        SReg_256:$srsrc),
488   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
489      #" $tfe, $lwe, $slc, $vaddr, $srsrc",
490   []> {
491   let SSAMP = 0;
492   let mayLoad = 1;
493   let mayStore = 0;
494   let hasPostISelHook = 1;
495 }
496
497 multiclass MIMG_NoSampler_Src_Helper <bits<7> op, string asm,
498                                       RegisterClass dst_rc,
499                                       int channels> {
500   def _V1 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_32>,
501             MIMG_Mask<asm#"_V1", channels>;
502   def _V2 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_64>,
503             MIMG_Mask<asm#"_V2", channels>;
504   def _V4 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_128>,
505             MIMG_Mask<asm#"_V4", channels>;
506 }
507
508 multiclass MIMG_NoSampler <bits<7> op, string asm> {
509   defm _V1 : MIMG_NoSampler_Src_Helper <op, asm, VReg_32, 1>;
510   defm _V2 : MIMG_NoSampler_Src_Helper <op, asm, VReg_64, 2>;
511   defm _V3 : MIMG_NoSampler_Src_Helper <op, asm, VReg_96, 3>;
512   defm _V4 : MIMG_NoSampler_Src_Helper <op, asm, VReg_128, 4>;
513 }
514
515 class MIMG_Sampler_Helper <bits<7> op, string asm,
516                            RegisterClass dst_rc,
517                            RegisterClass src_rc> : MIMG <
518   op,
519   (outs dst_rc:$vdata),
520   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
521        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
522        SReg_256:$srsrc, SReg_128:$ssamp),
523   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
524      #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
525   []> {
526   let mayLoad = 1;
527   let mayStore = 0;
528   let hasPostISelHook = 1;
529 }
530
531 multiclass MIMG_Sampler_Src_Helper <bits<7> op, string asm,
532                                     RegisterClass dst_rc,
533                                     int channels> {
534   def _V1 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_32>,
535             MIMG_Mask<asm#"_V1", channels>;
536   def _V2 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_64>,
537             MIMG_Mask<asm#"_V2", channels>;
538   def _V4 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_128>,
539             MIMG_Mask<asm#"_V4", channels>;
540   def _V8 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_256>,
541             MIMG_Mask<asm#"_V8", channels>;
542   def _V16 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_512>,
543             MIMG_Mask<asm#"_V16", channels>;
544 }
545
546 multiclass MIMG_Sampler <bits<7> op, string asm> {
547   defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VReg_32, 1>;
548   defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2>;
549   defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3>;
550   defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4>;
551 }
552
553 //===----------------------------------------------------------------------===//
554 // Vector instruction mappings
555 //===----------------------------------------------------------------------===//
556
557 // Maps an opcode in e32 form to its e64 equivalent
558 def getVOPe64 : InstrMapping {
559   let FilterClass = "VOP";
560   let RowFields = ["OpName"];
561   let ColFields = ["Size"];
562   let KeyCol = ["4"];
563   let ValueCols = [["8"]];
564 }
565
566 // Maps an original opcode to its commuted version
567 def getCommuteRev : InstrMapping {
568   let FilterClass = "VOP2_REV";
569   let RowFields = ["RevOp"];
570   let ColFields = ["IsOrig"];
571   let KeyCol = ["1"];
572   let ValueCols = [["0"]];
573 }
574
575 def getMaskedMIMGOp : InstrMapping {
576   let FilterClass = "MIMG_Mask";
577   let RowFields = ["Op"];
578   let ColFields = ["Channels"];
579   let KeyCol = ["4"];
580   let ValueCols = [["1"], ["2"], ["3"] ];
581 }
582
583 // Maps an commuted opcode to its original version
584 def getCommuteOrig : InstrMapping {
585   let FilterClass = "VOP2_REV";
586   let RowFields = ["RevOp"];
587   let ColFields = ["IsOrig"];
588   let KeyCol = ["0"];
589   let ValueCols = [["1"]];
590 }
591
592 include "SIInstructions.td"