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