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