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