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