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