R600/SI: Add instruction definitions for more LDS ops
[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 // 64-bit input, 32-bit output.
191 class SOP1_32_64 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
192   op, (outs SReg_32:$dst), (ins SSrc_64:$src0),
193   opName#" $dst, $src0", pattern
194 >;
195
196 class SOP2_32 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
197   op, (outs SReg_32:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
198   opName#" $dst, $src0, $src1", pattern
199 >;
200
201 class SOP2_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
202   op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
203   opName#" $dst, $src0, $src1", pattern
204 >;
205
206 class SOP2_SHIFT_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
207   op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_32:$src1),
208   opName#" $dst, $src0, $src1", pattern
209 >;
210
211
212 class SOPC_Helper <bits<7> op, RegisterClass rc, ValueType vt,
213                     string opName, PatLeaf cond> : SOPC <
214   op, (outs SCCReg:$dst), (ins rc:$src0, rc:$src1),
215   opName#" $dst, $src0, $src1", []>;
216
217 class SOPC_32<bits<7> op, string opName, PatLeaf cond = COND_NULL>
218   : SOPC_Helper<op, SSrc_32, i32, opName, cond>;
219
220 class SOPC_64<bits<7> op, string opName, PatLeaf cond = COND_NULL>
221   : SOPC_Helper<op, SSrc_64, i64, opName, cond>;
222
223 class SOPK_32 <bits<5> op, string opName, list<dag> pattern> : SOPK <
224   op, (outs SReg_32:$dst), (ins i16imm:$src0),
225   opName#" $dst, $src0", pattern
226 >;
227
228 class SOPK_64 <bits<5> op, string opName, list<dag> pattern> : SOPK <
229   op, (outs SReg_64:$dst), (ins i16imm:$src0),
230   opName#" $dst, $src0", pattern
231 >;
232
233 multiclass SMRD_Helper <bits<5> op, string asm, RegisterClass baseClass,
234                         RegisterClass dstClass> {
235   def _IMM : SMRD <
236     op, 1, (outs dstClass:$dst),
237     (ins baseClass:$sbase, u32imm:$offset),
238     asm#" $dst, $sbase, $offset", []
239   >;
240
241   def _SGPR : SMRD <
242     op, 0, (outs dstClass:$dst),
243     (ins baseClass:$sbase, SReg_32:$soff),
244     asm#" $dst, $sbase, $soff", []
245   >;
246 }
247
248 //===----------------------------------------------------------------------===//
249 // Vector ALU classes
250 //===----------------------------------------------------------------------===//
251
252 class VOP <string opName> {
253   string OpName = opName;
254 }
255
256 class VOP2_REV <string revOp, bit isOrig> {
257   string RevOp = revOp;
258   bit IsOrig = isOrig;
259 }
260
261 class SIMCInstr <string pseudo, int subtarget> {
262   string PseudoInstr = pseudo;
263   int Subtarget = subtarget;
264 }
265
266 multiclass VOP3_m <bits<9> op, dag outs, dag ins, string asm, list<dag> pattern,
267                    string opName> {
268
269   def "" : InstSI <outs, ins, "", pattern>, VOP <opName>,
270            SIMCInstr<OpName, SISubtarget.NONE> {
271     let isPseudo = 1;
272   }
273
274   def _si : VOP3 <op, outs, ins, asm, []>, SIMCInstr<opName, SISubtarget.SI>;
275
276 }
277
278 // This must always be right before the operand being input modified.
279 def InputMods : OperandWithDefaultOps <i32, (ops (i32 0))> {
280   let PrintMethod = "printOperandAndMods";
281 }
282
283 multiclass VOP1_Helper <bits<8> op, RegisterClass drc, RegisterClass src,
284                         string opName, list<dag> pattern> {
285
286   def _e32 : VOP1 <
287     op, (outs drc:$dst), (ins src:$src0),
288     opName#"_e32 $dst, $src0", pattern
289   >, VOP <opName>;
290
291   def _e64 : VOP3 <
292     {1, 1, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
293     (outs drc:$dst),
294     (ins InputMods:$src0_modifiers, src:$src0, i32imm:$clamp, i32imm:$omod),
295     opName#"_e64 $dst, $src0_modifiers, $clamp, $omod", []
296   >, VOP <opName> {
297     let src1 = SIOperand.ZERO;
298     let src2 = SIOperand.ZERO;
299   }
300 }
301
302 multiclass VOP1_32 <bits<8> op, string opName, list<dag> pattern>
303   : VOP1_Helper <op, VReg_32, VSrc_32, opName, pattern>;
304
305 multiclass VOP1_64 <bits<8> op, string opName, list<dag> pattern>
306   : VOP1_Helper <op, VReg_64, VSrc_64, opName, pattern>;
307
308 multiclass VOP1_32_64 <bits<8> op, string opName, list<dag> pattern>
309   : VOP1_Helper <op, VReg_32, VSrc_64, opName, pattern>;
310
311 multiclass VOP1_64_32 <bits<8> op, string opName, list<dag> pattern>
312   : VOP1_Helper <op, VReg_64, VSrc_32, opName, pattern>;
313
314 multiclass VOP2_Helper <bits<6> op, RegisterClass vrc, RegisterClass arc,
315                         string opName, list<dag> pattern, string revOp> {
316   def _e32 : VOP2 <
317     op, (outs vrc:$dst), (ins arc:$src0, vrc:$src1),
318     opName#"_e32 $dst, $src0, $src1", pattern
319   >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
320
321   def _e64 : VOP3 <
322     {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
323     (outs vrc:$dst),
324     (ins InputMods:$src0_modifiers, arc:$src0,
325          InputMods:$src1_modifiers, arc:$src1,
326          i32imm:$clamp, i32imm:$omod),
327     opName#"_e64 $dst, $src0_modifiers, $src1_modifiers, $clamp, $omod", []
328   >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
329     let src2 = SIOperand.ZERO;
330   }
331 }
332
333 multiclass VOP2_32 <bits<6> op, string opName, list<dag> pattern,
334                     string revOp = opName>
335   : VOP2_Helper <op, VReg_32, VSrc_32, opName, pattern, revOp>;
336
337 multiclass VOP2_64 <bits<6> op, string opName, list<dag> pattern,
338                     string revOp = opName>
339   : VOP2_Helper <op, VReg_64, VSrc_64, opName, pattern, revOp>;
340
341 multiclass VOP2b_32 <bits<6> op, string opName, list<dag> pattern,
342                      RegisterClass src0_rc, string revOp = opName> {
343
344   def _e32 : VOP2 <
345     op, (outs VReg_32:$dst), (ins src0_rc:$src0, VReg_32:$src1),
346     opName#"_e32 $dst, $src0, $src1", pattern
347   >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
348
349   def _e64 : VOP3b <
350     {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
351     (outs VReg_32:$dst),
352     (ins InputMods: $src0_modifiers, VSrc_32:$src0,
353          InputMods:$src1_modifiers, VSrc_32:$src1,
354          i32imm:$clamp, i32imm:$omod),
355     opName#"_e64 $dst, $src0_modifiers, $src1_modifiers, $clamp, $omod", []
356   >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
357     let src2 = SIOperand.ZERO;
358     /* the VOP2 variant puts the carry out into VCC, the VOP3 variant
359        can write it into any SGPR. We currently don't use the carry out,
360        so for now hardcode it to VCC as well */
361     let sdst = SIOperand.VCC;
362   }
363 }
364
365 multiclass VOPC_Helper <bits<8> op, RegisterClass vrc, RegisterClass arc,
366                         string opName, ValueType vt, PatLeaf cond> {
367
368   def _e32 : VOPC <
369     op, (ins arc:$src0, vrc:$src1),
370     opName#"_e32 $dst, $src0, $src1", []
371   >, VOP <opName>;
372
373   def _e64 : VOP3 <
374     {0, op{7}, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
375     (outs SReg_64:$dst),
376     (ins InputMods:$src0_modifiers, arc:$src0,
377          InputMods:$src1_modifiers, arc:$src1,
378          InstFlag:$clamp, InstFlag:$omod),
379     opName#"_e64 $dst, $src0_modifiers, $src1_modifiers, $clamp, $omod",
380     !if(!eq(!cast<string>(cond), "COND_NULL"), []<dag>,
381       [(set SReg_64:$dst, (i1 (setcc (vt arc:$src0), arc:$src1, cond)))]
382     )
383   >, VOP <opName> {
384     let src2 = SIOperand.ZERO;
385     let src2_modifiers = 0;
386   }
387 }
388
389 multiclass VOPC_32 <bits<8> op, string opName,
390   ValueType vt = untyped, PatLeaf cond = COND_NULL>
391   : VOPC_Helper <op, VReg_32, VSrc_32, opName, vt, cond>;
392
393 multiclass VOPC_64 <bits<8> op, string opName,
394   ValueType vt = untyped, PatLeaf cond = COND_NULL>
395   : VOPC_Helper <op, VReg_64, VSrc_64, opName, vt, cond>;
396
397 multiclass VOP3_32 <bits<9> op, string opName, list<dag> pattern> : VOP3_m <
398   op, (outs VReg_32:$dst),
399   (ins InputMods: $src0_modifiers, VSrc_32:$src0, InputMods:$src1_modifiers,
400    VSrc_32:$src1, InputMods:$src2_modifiers, VSrc_32:$src2,
401    InstFlag:$clamp, InstFlag:$omod),
402   opName#" $dst, $src0_modifiers, $src1, $src2, $clamp, $omod", pattern, opName
403 >;
404
405 class VOP3_64_32 <bits <9> op, string opName, list<dag> pattern> : VOP3 <
406   op, (outs VReg_64:$dst),
407   (ins VSrc_64:$src0, VSrc_32:$src1),
408   opName#" $dst, $src0, $src1", pattern
409 >, VOP <opName> {
410
411   let src2 = SIOperand.ZERO;
412   let src0_modifiers = 0;
413   let clamp = 0;
414   let omod = 0;
415 }
416
417 class VOP3_64 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
418   op, (outs VReg_64:$dst),
419   (ins VSrc_64:$src0, VSrc_64:$src1, VSrc_64:$src2,
420    InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg),
421   opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
422 >, VOP <opName>;
423
424 //===----------------------------------------------------------------------===//
425 // Vector I/O classes
426 //===----------------------------------------------------------------------===//
427
428 class DS_1A <bits<8> op, dag outs, dag ins, string asm, list<dag> pat> :
429     DS <op, outs, ins, asm, pat> {
430   bits<16> offset;
431
432   // Single load interpret the 2 i8imm operands as a single i16 offset.
433   let offset0 = offset{7-0};
434   let offset1 = offset{15-8};
435 }
436
437 class DS_Load_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
438   op,
439   (outs regClass:$vdst),
440   (ins i1imm:$gds, VReg_32:$addr, u16imm:$offset),
441   asm#" $vdst, $addr, $offset, [M0]",
442   []> {
443   let data0 = 0;
444   let data1 = 0;
445   let mayLoad = 1;
446   let mayStore = 0;
447 }
448
449 class DS_Load2_Helper <bits<8> op, string asm, RegisterClass regClass> : DS <
450   op,
451   (outs regClass:$vdst),
452   (ins i1imm:$gds, VReg_32:$addr, u8imm:$offset0, u8imm:$offset1),
453   asm#" $gds, $vdst, $addr, $offset0, $offset1, [M0]",
454   []> {
455   let data0 = 0;
456   let data1 = 0;
457   let mayLoad = 1;
458   let mayStore = 0;
459 }
460
461 class DS_Store_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
462   op,
463   (outs),
464   (ins i1imm:$gds, VReg_32:$addr, regClass:$data0, u16imm:$offset),
465   asm#" $addr, $data0, $offset [M0]",
466   []> {
467   let data1 = 0;
468   let mayStore = 1;
469   let mayLoad = 0;
470   let vdst = 0;
471 }
472
473 class DS_Store2_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
474   op,
475   (outs),
476   (ins i1imm:$gds, VReg_32:$addr, regClass:$data0, u8imm:$offset0, u8imm:$offset1),
477   asm#" $addr, $data0, $data1, $offset0, $offset1 [M0]",
478   []> {
479   let mayStore = 1;
480   let mayLoad = 0;
481   let vdst = 0;
482 }
483
484 // 1 address, 1 data.
485 class DS_1A1D_RET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
486   op,
487   (outs rc:$vdst),
488   (ins i1imm:$gds, VReg_32:$addr, VReg_32:$data0, u16imm:$offset),
489   asm#" $vdst, $addr, $data0, $offset, [M0]",
490   []> {
491
492   let data1 = 0;
493   let mayStore = 1;
494   let mayLoad = 1;
495 }
496
497 // 1 address, 0 data.
498 class DS_1A0D_RET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
499   op,
500   (outs rc:$vdst),
501   (ins i1imm:$gds, VReg_32:$addr, u16imm:$offset),
502   asm#" $vdst, $addr, $offset, [M0]",
503   []> {
504   let data0 = 0;
505   let data1 = 0;
506   let mayStore = 1;
507   let mayLoad = 1;
508 }
509
510 // 1 address, 0 data.
511 class DS_1A0D_NORET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
512   op,
513   (outs ),
514   (ins i1imm:$gds, VReg_32:$addr, u16imm:$offset),
515   asm#" $addr, $offset, [M0]",
516   []> {
517   let data0 = 0;
518   let data1 = 0;
519   let mayStore = 1;
520   let mayLoad = 1;
521 }
522
523 // 1 address, 2 data.
524 class DS_1A2D_RET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
525   op,
526   (outs rc:$vdst),
527   (ins i1imm:$gds, VReg_32:$addr, VReg_32:$data0, VReg_32:$data1, u16imm:$offset),
528   asm#" $vdst, $addr, $data0, $data1, $offset, [M0]",
529   []> {
530   let mayStore = 1;
531   let mayLoad = 1;
532 }
533
534 // 1 address, 2 data.
535 class DS_1A2D_NORET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
536   op,
537   (outs),
538   (ins i1imm:$gds, VReg_32:$addr, VReg_32:$data0, VReg_32:$data1, u16imm:$offset),
539   asm#" $addr, $data0, $data1, $offset, [M0]",
540   []> {
541   let mayStore = 1;
542   let mayLoad = 1;
543 }
544
545 // 1 address, 1 data.
546 class DS_1A1D_NORET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
547   op,
548   (outs),
549   (ins i1imm:$gds, VReg_32:$addr, VReg_32:$data0, u16imm:$offset),
550   asm#" $addr, $data0, $offset, [M0]",
551   []> {
552
553   let data1 = 0;
554   let mayStore = 1;
555   let mayLoad = 1;
556 }
557
558 class MTBUF_Store_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
559   op,
560   (outs),
561   (ins regClass:$vdata, u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
562    i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr,
563    SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
564   asm#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
565      #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
566   []> {
567   let mayStore = 1;
568   let mayLoad = 0;
569 }
570
571 multiclass MUBUF_Load_Helper <bits<7> op, string asm, RegisterClass regClass> {
572
573   let lds = 0, mayLoad = 1 in {
574
575     let addr64 = 0 in {
576
577       let offen = 0, idxen = 0 in {
578         def _OFFSET : MUBUF <op, (outs regClass:$vdata),
579                              (ins SReg_128:$srsrc, VReg_32:$vaddr,
580                              u16imm:$offset, SSrc_32:$soffset, i1imm:$glc,
581                              i1imm:$slc, i1imm:$tfe),
582                              asm#" $vdata, $srsrc + $offset + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
583       }
584
585       let offen = 1, idxen = 0, offset = 0 in {
586         def _OFFEN  : MUBUF <op, (outs regClass:$vdata),
587                              (ins SReg_128:$srsrc, VReg_32:$vaddr,
588                              SSrc_32:$soffset, i1imm:$glc, i1imm:$slc,
589                              i1imm:$tfe),
590                              asm#" $vdata, $srsrc + $vaddr + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
591       }
592
593       let offen = 0, idxen = 1 in {
594         def _IDXEN  : MUBUF <op, (outs regClass:$vdata),
595                              (ins SReg_128:$srsrc, VReg_32:$vaddr,
596                              u16imm:$offset, SSrc_32:$soffset, i1imm:$glc,
597                              i1imm:$slc, i1imm:$tfe),
598                              asm#" $vdata, $srsrc[$vaddr] + $offset + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
599       }
600
601       let offen = 1, idxen = 1 in {
602         def _BOTHEN : MUBUF <op, (outs regClass:$vdata),
603                              (ins SReg_128:$srsrc, VReg_64:$vaddr,
604                              SSrc_32:$soffset, i1imm:$glc,
605                              i1imm:$slc, i1imm:$tfe),
606                              asm#" $vdata, $srsrc[$vaddr[0]] + $vaddr[1] + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
607       }
608     }
609
610     let offen = 0, idxen = 0, addr64 = 1, glc = 0, slc = 0, tfe = 0, soffset = 128 /* ZERO */ in {
611       def _ADDR64 : MUBUF <op, (outs regClass:$vdata),
612                            (ins SReg_128:$srsrc, VReg_64:$vaddr, u16imm:$offset),
613                            asm#" $vdata, $srsrc + $vaddr + $offset", []>;
614     }
615   }
616 }
617
618 class MUBUF_Store_Helper <bits<7> op, string name, RegisterClass vdataClass> :
619     MUBUF <op, (outs), (ins vdataClass:$vdata, SReg_128:$srsrc, VReg_64:$vaddr,
620                             u16imm:$offset),
621           name#" $vdata, $srsrc + $vaddr + $offset",
622          []> {
623
624   let mayLoad = 0;
625   let mayStore = 1;
626
627   // Encoding
628   let offen = 0;
629   let idxen = 0;
630   let glc = 0;
631   let addr64 = 1;
632   let lds = 0;
633   let slc = 0;
634   let tfe = 0;
635   let soffset = 128; // ZERO
636 }
637
638 class MTBUF_Load_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
639   op,
640   (outs regClass:$dst),
641   (ins u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
642        i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, SReg_128:$srsrc,
643        i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
644   asm#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
645      #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
646   []> {
647   let mayLoad = 1;
648   let mayStore = 0;
649 }
650
651 class MIMG_Mask <string op, int channels> {
652   string Op = op;
653   int Channels = channels;
654 }
655
656 class MIMG_NoSampler_Helper <bits<7> op, string asm,
657                              RegisterClass dst_rc,
658                              RegisterClass src_rc> : MIMG <
659   op,
660   (outs dst_rc:$vdata),
661   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
662        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
663        SReg_256:$srsrc),
664   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
665      #" $tfe, $lwe, $slc, $vaddr, $srsrc",
666   []> {
667   let SSAMP = 0;
668   let mayLoad = 1;
669   let mayStore = 0;
670   let hasPostISelHook = 1;
671 }
672
673 multiclass MIMG_NoSampler_Src_Helper <bits<7> op, string asm,
674                                       RegisterClass dst_rc,
675                                       int channels> {
676   def _V1 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_32>,
677             MIMG_Mask<asm#"_V1", channels>;
678   def _V2 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_64>,
679             MIMG_Mask<asm#"_V2", channels>;
680   def _V4 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_128>,
681             MIMG_Mask<asm#"_V4", channels>;
682 }
683
684 multiclass MIMG_NoSampler <bits<7> op, string asm> {
685   defm _V1 : MIMG_NoSampler_Src_Helper <op, asm, VReg_32, 1>;
686   defm _V2 : MIMG_NoSampler_Src_Helper <op, asm, VReg_64, 2>;
687   defm _V3 : MIMG_NoSampler_Src_Helper <op, asm, VReg_96, 3>;
688   defm _V4 : MIMG_NoSampler_Src_Helper <op, asm, VReg_128, 4>;
689 }
690
691 class MIMG_Sampler_Helper <bits<7> op, string asm,
692                            RegisterClass dst_rc,
693                            RegisterClass src_rc> : MIMG <
694   op,
695   (outs dst_rc:$vdata),
696   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
697        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
698        SReg_256:$srsrc, SReg_128:$ssamp),
699   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
700      #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
701   []> {
702   let mayLoad = 1;
703   let mayStore = 0;
704   let hasPostISelHook = 1;
705 }
706
707 multiclass MIMG_Sampler_Src_Helper <bits<7> op, string asm,
708                                     RegisterClass dst_rc,
709                                     int channels> {
710   def _V1 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_32>,
711             MIMG_Mask<asm#"_V1", channels>;
712   def _V2 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_64>,
713             MIMG_Mask<asm#"_V2", channels>;
714   def _V4 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_128>,
715             MIMG_Mask<asm#"_V4", channels>;
716   def _V8 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_256>,
717             MIMG_Mask<asm#"_V8", channels>;
718   def _V16 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_512>,
719             MIMG_Mask<asm#"_V16", channels>;
720 }
721
722 multiclass MIMG_Sampler <bits<7> op, string asm> {
723   defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VReg_32, 1>;
724   defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2>;
725   defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3>;
726   defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4>;
727 }
728
729 //===----------------------------------------------------------------------===//
730 // Vector instruction mappings
731 //===----------------------------------------------------------------------===//
732
733 // Maps an opcode in e32 form to its e64 equivalent
734 def getVOPe64 : InstrMapping {
735   let FilterClass = "VOP";
736   let RowFields = ["OpName"];
737   let ColFields = ["Size"];
738   let KeyCol = ["4"];
739   let ValueCols = [["8"]];
740 }
741
742 // Maps an original opcode to its commuted version
743 def getCommuteRev : InstrMapping {
744   let FilterClass = "VOP2_REV";
745   let RowFields = ["RevOp"];
746   let ColFields = ["IsOrig"];
747   let KeyCol = ["1"];
748   let ValueCols = [["0"]];
749 }
750
751 def getMaskedMIMGOp : InstrMapping {
752   let FilterClass = "MIMG_Mask";
753   let RowFields = ["Op"];
754   let ColFields = ["Channels"];
755   let KeyCol = ["4"];
756   let ValueCols = [["1"], ["2"], ["3"] ];
757 }
758
759 // Maps an commuted opcode to its original version
760 def getCommuteOrig : InstrMapping {
761   let FilterClass = "VOP2_REV";
762   let RowFields = ["RevOp"];
763   let ColFields = ["IsOrig"];
764   let KeyCol = ["0"];
765   let ValueCols = [["1"]];
766 }
767
768 def isDS : InstrMapping {
769   let FilterClass = "DS";
770   let RowFields = ["Inst"];
771   let ColFields = ["Size"];
772   let KeyCol = ["8"];
773   let ValueCols = [["8"]];
774 }
775
776 def getMCOpcode : InstrMapping {
777   let FilterClass = "SIMCInstr";
778   let RowFields = ["PseudoInstr"];
779   let ColFields = ["Subtarget"];
780   let KeyCol = [!cast<string>(SISubtarget.NONE)];
781   let ValueCols = [[!cast<string>(SISubtarget.SI)]];
782 }
783
784 include "SIInstructions.td"