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