R600/SI: Use RegisterOperands to specify which operands can accept immediates
[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 class vop {
11   field bits<9> SI3;
12   field bits<10> VI3;
13 }
14
15 class vopc <bits<8> si, bits<8> vi = !add(0x40, si)> : vop {
16   field bits<8> SI = si;
17   field bits<8> VI = vi;
18
19   field bits<9>  SI3 = {0, si{7-0}};
20   field bits<10> VI3 = {0, 0, vi{7-0}};
21 }
22
23 class vop1 <bits<8> si, bits<8> vi = si> : vop {
24   field bits<8> SI = si;
25   field bits<8> VI = vi;
26
27   field bits<9>  SI3 = {1, 1, si{6-0}};
28   field bits<10> VI3 = !add(0x140, vi);
29 }
30
31 class vop2 <bits<6> si, bits<6> vi = si> : vop {
32   field bits<6> SI = si;
33   field bits<6> VI = vi;
34
35   field bits<9>  SI3 = {1, 0, 0, si{5-0}};
36   field bits<10> VI3 = {0, 1, 0, 0, vi{5-0}};
37 }
38
39 class vop3 <bits<9> si, bits<10> vi = {0, si}> : vop {
40   let SI3 = si;
41   let VI3 = vi;
42 }
43
44 class sop1 <bits<8> si, bits<8> vi = si> {
45   field bits<8> SI = si;
46   field bits<8> VI = vi;
47 }
48
49 class sop2 <bits<7> si, bits<7> vi = si> {
50   field bits<7> SI = si;
51   field bits<7> VI = vi;
52 }
53
54 class sopk <bits<5> si, bits<5> vi = si> {
55   field bits<5> SI = si;
56   field bits<5> VI = vi;
57 }
58
59 // Execpt for the NONE field, this must be kept in sync with the SISubtarget enum
60 // in AMDGPUMCInstLower.h
61 def SISubtarget {
62   int NONE = -1;
63   int SI = 0;
64   int VI = 1;
65 }
66
67 //===----------------------------------------------------------------------===//
68 // SI DAG Nodes
69 //===----------------------------------------------------------------------===//
70
71 def SIload_constant : SDNode<"AMDGPUISD::LOAD_CONSTANT",
72   SDTypeProfile<1, 2, [SDTCisVT<0, f32>, SDTCisVT<1, v4i32>, SDTCisVT<2, i32>]>,
73                       [SDNPMayLoad, SDNPMemOperand]
74 >;
75
76 def SItbuffer_store : SDNode<"AMDGPUISD::TBUFFER_STORE_FORMAT",
77   SDTypeProfile<0, 13,
78     [SDTCisVT<0, v4i32>,   // rsrc(SGPR)
79      SDTCisVT<1, iAny>,   // vdata(VGPR)
80      SDTCisVT<2, i32>,    // num_channels(imm)
81      SDTCisVT<3, i32>,    // vaddr(VGPR)
82      SDTCisVT<4, i32>,    // soffset(SGPR)
83      SDTCisVT<5, i32>,    // inst_offset(imm)
84      SDTCisVT<6, i32>,    // dfmt(imm)
85      SDTCisVT<7, i32>,    // nfmt(imm)
86      SDTCisVT<8, i32>,    // offen(imm)
87      SDTCisVT<9, i32>,    // idxen(imm)
88      SDTCisVT<10, i32>,   // glc(imm)
89      SDTCisVT<11, i32>,   // slc(imm)
90      SDTCisVT<12, i32>    // tfe(imm)
91     ]>,
92   [SDNPMayStore, SDNPMemOperand, SDNPHasChain]
93 >;
94
95 def SIload_input : SDNode<"AMDGPUISD::LOAD_INPUT",
96   SDTypeProfile<1, 3, [SDTCisVT<0, v4f32>, SDTCisVT<1, v4i32>, SDTCisVT<2, i16>,
97                        SDTCisVT<3, i32>]>
98 >;
99
100 class SDSample<string opcode> : SDNode <opcode,
101   SDTypeProfile<1, 4, [SDTCisVT<0, v4f32>, SDTCisVT<2, v32i8>,
102                        SDTCisVT<3, v4i32>, SDTCisVT<4, i32>]>
103 >;
104
105 def SIsample : SDSample<"AMDGPUISD::SAMPLE">;
106 def SIsampleb : SDSample<"AMDGPUISD::SAMPLEB">;
107 def SIsampled : SDSample<"AMDGPUISD::SAMPLED">;
108 def SIsamplel : SDSample<"AMDGPUISD::SAMPLEL">;
109
110 def SIconstdata_ptr : SDNode<
111   "AMDGPUISD::CONST_DATA_PTR", SDTypeProfile <1, 0, [SDTCisVT<0, i64>]>
112 >;
113
114 // Transformation function, extract the lower 32bit of a 64bit immediate
115 def LO32 : SDNodeXForm<imm, [{
116   return CurDAG->getTargetConstant(N->getZExtValue() & 0xffffffff, MVT::i32);
117 }]>;
118
119 def LO32f : SDNodeXForm<fpimm, [{
120   APInt V = N->getValueAPF().bitcastToAPInt().trunc(32);
121   return CurDAG->getTargetConstantFP(APFloat(APFloat::IEEEsingle, V), MVT::f32);
122 }]>;
123
124 // Transformation function, extract the upper 32bit of a 64bit immediate
125 def HI32 : SDNodeXForm<imm, [{
126   return CurDAG->getTargetConstant(N->getZExtValue() >> 32, MVT::i32);
127 }]>;
128
129 def HI32f : SDNodeXForm<fpimm, [{
130   APInt V = N->getValueAPF().bitcastToAPInt().lshr(32).trunc(32);
131   return CurDAG->getTargetConstantFP(APFloat(APFloat::IEEEsingle, V), MVT::f32);
132 }]>;
133
134 def IMM8bitDWORD : PatLeaf <(imm),
135   [{return (N->getZExtValue() & ~0x3FC) == 0;}]
136 >;
137
138 def as_dword_i32imm : SDNodeXForm<imm, [{
139   return CurDAG->getTargetConstant(N->getZExtValue() >> 2, MVT::i32);
140 }]>;
141
142 def as_i1imm : SDNodeXForm<imm, [{
143   return CurDAG->getTargetConstant(N->getZExtValue(), MVT::i1);
144 }]>;
145
146 def as_i8imm : SDNodeXForm<imm, [{
147   return CurDAG->getTargetConstant(N->getZExtValue(), MVT::i8);
148 }]>;
149
150 def as_i16imm : SDNodeXForm<imm, [{
151   return CurDAG->getTargetConstant(N->getSExtValue(), MVT::i16);
152 }]>;
153
154 def as_i32imm: SDNodeXForm<imm, [{
155   return CurDAG->getTargetConstant(N->getSExtValue(), MVT::i32);
156 }]>;
157
158 def as_i64imm: SDNodeXForm<imm, [{
159   return CurDAG->getTargetConstant(N->getSExtValue(), MVT::i64);
160 }]>;
161
162 def IMM8bit : PatLeaf <(imm),
163   [{return isUInt<8>(N->getZExtValue());}]
164 >;
165
166 def IMM12bit : PatLeaf <(imm),
167   [{return isUInt<12>(N->getZExtValue());}]
168 >;
169
170 def IMM16bit : PatLeaf <(imm),
171   [{return isUInt<16>(N->getZExtValue());}]
172 >;
173
174 def IMM20bit : PatLeaf <(imm),
175   [{return isUInt<20>(N->getZExtValue());}]
176 >;
177
178 def IMM32bit : PatLeaf <(imm),
179   [{return isUInt<32>(N->getZExtValue());}]
180 >;
181
182 def mubuf_vaddr_offset : PatFrag<
183   (ops node:$ptr, node:$offset, node:$imm_offset),
184   (add (add node:$ptr, node:$offset), node:$imm_offset)
185 >;
186
187 class InlineImm <ValueType vt> : PatLeaf <(vt imm), [{
188   return isInlineImmediate(N);
189 }]>;
190
191 class InlineFPImm <ValueType vt> : PatLeaf <(vt fpimm), [{
192   return isInlineImmediate(N);
193 }]>;
194
195 class SGPRImm <dag frag> : PatLeaf<frag, [{
196   if (TM.getSubtarget<AMDGPUSubtarget>().getGeneration() <
197       AMDGPUSubtarget::SOUTHERN_ISLANDS) {
198     return false;
199   }
200   const SIRegisterInfo *SIRI =
201                        static_cast<const SIRegisterInfo*>(TM.getSubtargetImpl()->getRegisterInfo());
202   for (SDNode::use_iterator U = N->use_begin(), E = SDNode::use_end();
203                                                 U != E; ++U) {
204     if (SIRI->isSGPRClass(getOperandRegClass(*U, U.getOperandNo()))) {
205       return true;
206     }
207   }
208   return false;
209 }]>;
210
211 //===----------------------------------------------------------------------===//
212 // Custom Operands
213 //===----------------------------------------------------------------------===//
214
215 def FRAMEri32 : Operand<iPTR> {
216   let MIOperandInfo = (ops i32:$ptr, i32imm:$index);
217 }
218
219 def sopp_brtarget : Operand<OtherVT> {
220   let EncoderMethod = "getSOPPBrEncoding";
221   let OperandType = "OPERAND_PCREL";
222 }
223
224 include "SIInstrFormats.td"
225 include "VIInstrFormats.td"
226
227 let OperandType = "OPERAND_IMMEDIATE" in {
228
229 def offen : Operand<i1> {
230   let PrintMethod = "printOffen";
231 }
232 def idxen : Operand<i1> {
233   let PrintMethod = "printIdxen";
234 }
235 def addr64 : Operand<i1> {
236   let PrintMethod = "printAddr64";
237 }
238 def mbuf_offset : Operand<i16> {
239   let PrintMethod = "printMBUFOffset";
240 }
241 def ds_offset : Operand<i16> {
242   let PrintMethod = "printDSOffset";
243 }
244 def ds_offset0 : Operand<i8> {
245   let PrintMethod = "printDSOffset0";
246 }
247 def ds_offset1 : Operand<i8> {
248   let PrintMethod = "printDSOffset1";
249 }
250 def glc : Operand <i1> {
251   let PrintMethod = "printGLC";
252 }
253 def slc : Operand <i1> {
254   let PrintMethod = "printSLC";
255 }
256 def tfe : Operand <i1> {
257   let PrintMethod = "printTFE";
258 }
259
260 def omod : Operand <i32> {
261   let PrintMethod = "printOModSI";
262 }
263
264 def ClampMod : Operand <i1> {
265   let PrintMethod = "printClampSI";
266 }
267
268 } // End OperandType = "OPERAND_IMMEDIATE"
269
270 //===----------------------------------------------------------------------===//
271 // Complex patterns
272 //===----------------------------------------------------------------------===//
273
274 def DS1Addr1Offset : ComplexPattern<i32, 2, "SelectDS1Addr1Offset">;
275 def DS64Bit4ByteAligned : ComplexPattern<i32, 3, "SelectDS64Bit4ByteAligned">;
276
277 def MUBUFAddr32 : ComplexPattern<i64, 9, "SelectMUBUFAddr32">;
278 def MUBUFAddr64 : ComplexPattern<i64, 3, "SelectMUBUFAddr64">;
279 def MUBUFAddr64Atomic : ComplexPattern<i64, 4, "SelectMUBUFAddr64">;
280 def MUBUFScratch : ComplexPattern<i64, 4, "SelectMUBUFScratch">;
281 def MUBUFOffset : ComplexPattern<i64, 6, "SelectMUBUFOffset">;
282 def MUBUFOffsetAtomic : ComplexPattern<i64, 4, "SelectMUBUFOffset">;
283
284 def VOP3Mods0 : ComplexPattern<untyped, 4, "SelectVOP3Mods0">;
285 def VOP3Mods0Clamp : ComplexPattern<untyped, 3, "SelectVOP3Mods0Clamp">;
286 def VOP3Mods0Clamp0OMod : ComplexPattern<untyped, 4, "SelectVOP3Mods0Clamp0OMod">;
287 def VOP3Mods  : ComplexPattern<untyped, 2, "SelectVOP3Mods">;
288
289 //===----------------------------------------------------------------------===//
290 // SI assembler operands
291 //===----------------------------------------------------------------------===//
292
293 def SIOperand {
294   int ZERO = 0x80;
295   int VCC = 0x6A;
296   int FLAT_SCR = 0x68;
297 }
298
299 def SRCMODS {
300   int NONE = 0;
301 }
302
303 def DSTCLAMP {
304   int NONE = 0;
305 }
306
307 def DSTOMOD {
308   int NONE = 0;
309 }
310
311 //===----------------------------------------------------------------------===//
312 //
313 // SI Instruction multiclass helpers.
314 //
315 // Instructions with _32 take 32-bit operands.
316 // Instructions with _64 take 64-bit operands.
317 //
318 // VOP_* instructions can use either a 32-bit or 64-bit encoding.  The 32-bit
319 // encoding is the standard encoding, but instruction that make use of
320 // any of the instruction modifiers must use the 64-bit encoding.
321 //
322 // Instructions with _e32 use the 32-bit encoding.
323 // Instructions with _e64 use the 64-bit encoding.
324 //
325 //===----------------------------------------------------------------------===//
326
327 class SIMCInstr <string pseudo, int subtarget> {
328   string PseudoInstr = pseudo;
329   int Subtarget = subtarget;
330 }
331
332 //===----------------------------------------------------------------------===//
333 // EXP classes
334 //===----------------------------------------------------------------------===//
335
336 class EXPCommon : InstSI<
337   (outs),
338   (ins i32imm:$en, i32imm:$tgt, i32imm:$compr, i32imm:$done, i32imm:$vm,
339        VGPR_32:$src0, VGPR_32:$src1, VGPR_32:$src2, VGPR_32:$src3),
340   "exp $en, $tgt, $compr, $done, $vm, $src0, $src1, $src2, $src3",
341   [] > {
342
343   let EXP_CNT = 1;
344   let Uses = [EXEC];
345 }
346
347 multiclass EXP_m {
348
349   let isPseudo = 1 in {
350     def "" : EXPCommon, SIMCInstr <"exp", SISubtarget.NONE> ;
351   }
352
353   def _si : EXPCommon, SIMCInstr <"exp", SISubtarget.SI>, EXPe;
354
355   def _vi : EXPCommon, SIMCInstr <"exp", SISubtarget.VI>, EXPe_vi;
356 }
357
358 //===----------------------------------------------------------------------===//
359 // Scalar classes
360 //===----------------------------------------------------------------------===//
361
362 class SOP1_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
363   SOP1 <outs, ins, "", pattern>,
364   SIMCInstr<opName, SISubtarget.NONE> {
365   let isPseudo = 1;
366 }
367
368 class SOP1_Real_si <sop1 op, string opName, dag outs, dag ins, string asm,
369                     list<dag> pattern> :
370   SOP1 <outs, ins, asm, pattern>,
371   SOP1e <op.SI>,
372   SIMCInstr<opName, SISubtarget.SI>;
373
374 class SOP1_Real_vi <sop1 op, string opName, dag outs, dag ins, string asm,
375                     list<dag> pattern> :
376   SOP1 <outs, ins, asm, pattern>,
377   SOP1e <op.VI>,
378   SIMCInstr<opName, SISubtarget.VI>;
379
380 multiclass SOP1_32 <sop1 op, string opName, list<dag> pattern> {
381   def "" : SOP1_Pseudo <opName, (outs SReg_32:$dst), (ins SSrc_32:$src0),
382     pattern>;
383
384   def _si : SOP1_Real_si <op, opName, (outs SReg_32:$dst), (ins SSrc_32:$src0),
385     opName#" $dst, $src0", pattern>;
386
387   def _vi : SOP1_Real_vi <op, opName, (outs SReg_32:$dst), (ins SSrc_32:$src0),
388     opName#" $dst, $src0", pattern>;
389 }
390
391 multiclass SOP1_64 <sop1 op, string opName, list<dag> pattern> {
392   def "" : SOP1_Pseudo <opName, (outs SReg_64:$dst), (ins SSrc_64:$src0),
393     pattern>;
394
395   def _si : SOP1_Real_si <op, opName, (outs SReg_64:$dst), (ins SSrc_64:$src0),
396     opName#" $dst, $src0", pattern>;
397
398   def _vi : SOP1_Real_vi <op, opName, (outs SReg_64:$dst), (ins SSrc_64:$src0),
399     opName#" $dst, $src0", pattern>;
400 }
401
402 // no input, 64-bit output.
403 multiclass SOP1_64_0 <sop1 op, string opName, list<dag> pattern> {
404   def "" : SOP1_Pseudo <opName, (outs SReg_64:$dst), (ins), pattern>;
405
406   def _si : SOP1_Real_si <op, opName, (outs SReg_64:$dst), (ins),
407     opName#" $dst", pattern> {
408     let SSRC0 = 0;
409   }
410
411   def _vi : SOP1_Real_vi <op, opName, (outs SReg_64:$dst), (ins),
412     opName#" $dst", pattern> {
413     let SSRC0 = 0;
414   }
415 }
416
417 // 64-bit input, 32-bit output.
418 multiclass SOP1_32_64 <sop1 op, string opName, list<dag> pattern> {
419   def "" : SOP1_Pseudo <opName, (outs SReg_32:$dst), (ins SSrc_64:$src0),
420     pattern>;
421
422   def _si : SOP1_Real_si <op, opName, (outs SReg_32:$dst), (ins SSrc_64:$src0),
423     opName#" $dst, $src0", pattern>;
424
425   def _vi : SOP1_Real_vi <op, opName, (outs SReg_32:$dst), (ins SSrc_64:$src0),
426     opName#" $dst, $src0", pattern>;
427 }
428
429 class SOP2_Pseudo<string opName, dag outs, dag ins, list<dag> pattern> :
430   SOP2<outs, ins, "", pattern>,
431   SIMCInstr<opName, SISubtarget.NONE> {
432   let isPseudo = 1;
433   let Size = 4;
434 }
435
436 class SOP2_Real_si<sop2 op, string opName, dag outs, dag ins, string asm,
437                    list<dag> pattern> :
438   SOP2<outs, ins, asm, pattern>,
439   SOP2e<op.SI>,
440   SIMCInstr<opName, SISubtarget.SI>;
441
442 class SOP2_Real_vi<sop2 op, string opName, dag outs, dag ins, string asm,
443                    list<dag> pattern> :
444   SOP2<outs, ins, asm, pattern>,
445   SOP2e<op.VI>,
446   SIMCInstr<opName, SISubtarget.VI>;
447
448 multiclass SOP2_SELECT_32 <sop2 op, string opName, list<dag> pattern> {
449   def "" : SOP2_Pseudo <opName, (outs SReg_32:$dst),
450     (ins SSrc_32:$src0, SSrc_32:$src1, SCCReg:$scc), pattern>;
451
452   def _si : SOP2_Real_si <op, opName, (outs SReg_32:$dst),
453     (ins SSrc_32:$src0, SSrc_32:$src1, SCCReg:$scc),
454     opName#" $dst, $src0, $src1 [$scc]", pattern>;
455
456   def _vi : SOP2_Real_vi <op, opName, (outs SReg_32:$dst),
457     (ins SSrc_32:$src0, SSrc_32:$src1, SCCReg:$scc),
458     opName#" $dst, $src0, $src1 [$scc]", pattern>;
459 }
460
461 multiclass SOP2_32 <sop2 op, string opName, list<dag> pattern> {
462   def "" : SOP2_Pseudo <opName, (outs SReg_32:$dst),
463     (ins SSrc_32:$src0, SSrc_32:$src1), pattern>;
464
465   def _si : SOP2_Real_si <op, opName, (outs SReg_32:$dst),
466     (ins SSrc_32:$src0, SSrc_32:$src1), opName#" $dst, $src0, $src1", pattern>;
467
468   def _vi : SOP2_Real_vi <op, opName, (outs SReg_32:$dst),
469     (ins SSrc_32:$src0, SSrc_32:$src1), opName#" $dst, $src0, $src1", pattern>;
470 }
471
472 multiclass SOP2_64 <sop2 op, string opName, list<dag> pattern> {
473   def "" : SOP2_Pseudo <opName, (outs SReg_64:$dst),
474     (ins SSrc_64:$src0, SSrc_64:$src1), pattern>;
475
476   def _si : SOP2_Real_si <op, opName, (outs SReg_64:$dst),
477     (ins SSrc_64:$src0, SSrc_64:$src1), opName#" $dst, $src0, $src1", pattern>;
478
479   def _vi : SOP2_Real_vi <op, opName, (outs SReg_64:$dst),
480     (ins SSrc_64:$src0, SSrc_64:$src1), opName#" $dst, $src0, $src1", pattern>;
481 }
482
483 multiclass SOP2_64_32 <sop2 op, string opName, list<dag> pattern> {
484   def "" : SOP2_Pseudo <opName, (outs SReg_64:$dst),
485     (ins SSrc_64:$src0, SSrc_32:$src1), pattern>;
486
487   def _si : SOP2_Real_si <op, opName, (outs SReg_64:$dst),
488     (ins SSrc_64:$src0, SSrc_32:$src1), opName#" $dst, $src0, $src1", pattern>;
489
490   def _vi : SOP2_Real_vi <op, opName, (outs SReg_64:$dst),
491     (ins SSrc_64:$src0, SSrc_32:$src1), opName#" $dst, $src0, $src1", pattern>;
492 }
493
494
495 class SOPC_Helper <bits<7> op, RegisterOperand rc, ValueType vt,
496                     string opName, PatLeaf cond> : SOPC <
497   op, (outs SCCReg:$dst), (ins rc:$src0, rc:$src1),
498   opName#" $dst, $src0, $src1", []>;
499
500 class SOPC_32<bits<7> op, string opName, PatLeaf cond = COND_NULL>
501   : SOPC_Helper<op, SSrc_32, i32, opName, cond>;
502
503 class SOPC_64<bits<7> op, string opName, PatLeaf cond = COND_NULL>
504   : SOPC_Helper<op, SSrc_64, i64, opName, cond>;
505
506 class SOPK_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
507   SOPK <outs, ins, "", pattern>,
508   SIMCInstr<opName, SISubtarget.NONE> {
509   let isPseudo = 1;
510 }
511
512 class SOPK_Real_si <sopk op, string opName, dag outs, dag ins, string asm,
513                     list<dag> pattern> :
514   SOPK <outs, ins, asm, pattern>,
515   SOPKe <op.SI>,
516   SIMCInstr<opName, SISubtarget.SI>;
517
518 class SOPK_Real_vi <sopk op, string opName, dag outs, dag ins, string asm,
519                     list<dag> pattern> :
520   SOPK <outs, ins, asm, pattern>,
521   SOPKe <op.VI>,
522   SIMCInstr<opName, SISubtarget.VI>;
523
524 multiclass SOPK_32 <sopk op, string opName, list<dag> pattern> {
525   def "" : SOPK_Pseudo <opName, (outs SReg_32:$dst), (ins u16imm:$src0),
526     pattern>;
527
528   def _si : SOPK_Real_si <op, opName, (outs SReg_32:$dst), (ins u16imm:$src0),
529     opName#" $dst, $src0", pattern>;
530
531   def _vi : SOPK_Real_vi <op, opName, (outs SReg_32:$dst), (ins u16imm:$src0),
532     opName#" $dst, $src0", pattern>;
533 }
534
535 multiclass SOPK_SCC <sopk op, string opName, list<dag> pattern> {
536   def "" : SOPK_Pseudo <opName, (outs SCCReg:$dst),
537     (ins SReg_32:$src0, u16imm:$src1), pattern>;
538
539   def _si : SOPK_Real_si <op, opName, (outs SCCReg:$dst),
540     (ins SReg_32:$src0, u16imm:$src1), opName#" $dst, $src0", pattern>;
541
542   def _vi : SOPK_Real_vi <op, opName, (outs SCCReg:$dst),
543     (ins SReg_32:$src0, u16imm:$src1), opName#" $dst, $src0", pattern>;
544 }
545
546 //===----------------------------------------------------------------------===//
547 // SMRD classes
548 //===----------------------------------------------------------------------===//
549
550 class SMRD_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
551   SMRD <outs, ins, "", pattern>,
552   SIMCInstr<opName, SISubtarget.NONE> {
553   let isPseudo = 1;
554 }
555
556 class SMRD_Real_si <bits<5> op, string opName, bit imm, dag outs, dag ins,
557                     string asm> :
558   SMRD <outs, ins, asm, []>,
559   SMRDe <op, imm>,
560   SIMCInstr<opName, SISubtarget.SI>;
561
562 class SMRD_Real_vi <bits<8> op, string opName, bit imm, dag outs, dag ins,
563                     string asm> :
564   SMRD <outs, ins, asm, []>,
565   SMEMe_vi <op, imm>,
566   SIMCInstr<opName, SISubtarget.VI>;
567
568 multiclass SMRD_m <bits<5> op, string opName, bit imm, dag outs, dag ins,
569                    string asm, list<dag> pattern> {
570
571   def "" : SMRD_Pseudo <opName, outs, ins, pattern>;
572
573   def _si : SMRD_Real_si <op, opName, imm, outs, ins, asm>;
574
575   def _vi : SMRD_Real_vi <{0, 0, 0, op}, opName, imm, outs, ins, asm>;
576 }
577
578 multiclass SMRD_Helper <bits<5> op, string opName, RegisterClass baseClass,
579                         RegisterClass dstClass> {
580   defm _IMM : SMRD_m <
581     op, opName#"_IMM", 1, (outs dstClass:$dst),
582     (ins baseClass:$sbase, u32imm:$offset),
583     opName#" $dst, $sbase, $offset", []
584   >;
585
586   defm _SGPR : SMRD_m <
587     op, opName#"_SGPR", 0, (outs dstClass:$dst),
588     (ins baseClass:$sbase, SReg_32:$soff),
589     opName#" $dst, $sbase, $soff", []
590   >;
591 }
592
593 //===----------------------------------------------------------------------===//
594 // Vector ALU classes
595 //===----------------------------------------------------------------------===//
596
597 // This must always be right before the operand being input modified.
598 def InputMods : OperandWithDefaultOps <i32, (ops (i32 0))> {
599   let PrintMethod = "printOperandAndMods";
600 }
601 def InputModsNoDefault : Operand <i32> {
602   let PrintMethod = "printOperandAndMods";
603 }
604
605 class getNumSrcArgs<ValueType Src1, ValueType Src2> {
606   int ret =
607     !if (!eq(Src1.Value, untyped.Value),      1,   // VOP1
608          !if (!eq(Src2.Value, untyped.Value), 2,   // VOP2
609                                               3)); // VOP3
610 }
611
612 // Returns the register class to use for the destination of VOP[123C]
613 // instructions for the given VT.
614 class getVALUDstForVT<ValueType VT> {
615   RegisterClass ret = !if(!eq(VT.Size, 32), VGPR_32,
616                           !if(!eq(VT.Size, 64), VReg_64,
617                             SReg_64)); // else VT == i1
618 }
619
620 // Returns the register class to use for source 0 of VOP[12C]
621 // instructions for the given VT.
622 class getVOPSrc0ForVT<ValueType VT> {
623   RegisterOperand ret = !if(!eq(VT.Size, 32), VSrc_32, VSrc_64);
624 }
625
626 // Returns the register class to use for source 1 of VOP[12C] for the
627 // given VT.
628 class getVOPSrc1ForVT<ValueType VT> {
629   RegisterClass ret = !if(!eq(VT.Size, 32), VGPR_32, VReg_64);
630 }
631
632 // Returns the register classes for the source arguments of a VOP[12C]
633 // instruction for the given SrcVTs.
634 class getInRC32 <list<ValueType> SrcVT> {
635   list<DAGOperand> ret = [
636     getVOPSrc0ForVT<SrcVT[0]>.ret,
637     getVOPSrc1ForVT<SrcVT[1]>.ret
638   ];
639 }
640
641 // Returns the register class to use for sources of VOP3 instructions for the
642 // given VT.
643 class getVOP3SrcForVT<ValueType VT> {
644   RegisterOperand ret = !if(!eq(VT.Size, 32), VCSrc_32, VCSrc_64);
645 }
646
647 // Returns the register classes for the source arguments of a VOP3
648 // instruction for the given SrcVTs.
649 class getInRC64 <list<ValueType> SrcVT> {
650   list<DAGOperand> ret = [
651     getVOP3SrcForVT<SrcVT[0]>.ret,
652     getVOP3SrcForVT<SrcVT[1]>.ret,
653     getVOP3SrcForVT<SrcVT[2]>.ret
654   ];
655 }
656
657 // Returns 1 if the source arguments have modifiers, 0 if they do not.
658 class hasModifiers<ValueType SrcVT> {
659   bit ret = !if(!eq(SrcVT.Value, f32.Value), 1,
660             !if(!eq(SrcVT.Value, f64.Value), 1, 0));
661 }
662
663 // Returns the input arguments for VOP[12C] instructions for the given SrcVT.
664 class getIns32 <RegisterOperand Src0RC, RegisterClass Src1RC, int NumSrcArgs> {
665   dag ret = !if(!eq(NumSrcArgs, 1), (ins Src0RC:$src0),               // VOP1
666             !if(!eq(NumSrcArgs, 2), (ins Src0RC:$src0, Src1RC:$src1), // VOP2
667                                     (ins)));
668 }
669
670 // Returns the input arguments for VOP3 instructions for the given SrcVT.
671 class getIns64 <RegisterOperand Src0RC, RegisterOperand Src1RC,
672                 RegisterOperand Src2RC, int NumSrcArgs,
673                 bit HasModifiers> {
674
675   dag ret =
676     !if (!eq(NumSrcArgs, 1),
677       !if (!eq(HasModifiers, 1),
678         // VOP1 with modifiers
679         (ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0,
680              ClampMod:$clamp, omod:$omod)
681       /* else */,
682         // VOP1 without modifiers
683         (ins Src0RC:$src0)
684       /* endif */ ),
685     !if (!eq(NumSrcArgs, 2),
686       !if (!eq(HasModifiers, 1),
687         // VOP 2 with modifiers
688         (ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0,
689              InputModsNoDefault:$src1_modifiers, Src1RC:$src1,
690              ClampMod:$clamp, omod:$omod)
691       /* else */,
692         // VOP2 without modifiers
693         (ins Src0RC:$src0, Src1RC:$src1)
694       /* endif */ )
695     /* NumSrcArgs == 3 */,
696       !if (!eq(HasModifiers, 1),
697         // VOP3 with modifiers
698         (ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0,
699              InputModsNoDefault:$src1_modifiers, Src1RC:$src1,
700              InputModsNoDefault:$src2_modifiers, Src2RC:$src2,
701              ClampMod:$clamp, omod:$omod)
702       /* else */,
703         // VOP3 without modifiers
704         (ins Src0RC:$src0, Src1RC:$src1, Src2RC:$src2)
705       /* endif */ )));
706 }
707
708 // Returns the assembly string for the inputs and outputs of a VOP[12C]
709 // instruction.  This does not add the _e32 suffix, so it can be reused
710 // by getAsm64.
711 class getAsm32 <int NumSrcArgs> {
712   string src1 = ", $src1";
713   string src2 = ", $src2";
714   string ret = " $dst, $src0"#
715                !if(!eq(NumSrcArgs, 1), "", src1)#
716                !if(!eq(NumSrcArgs, 3), src2, "");
717 }
718
719 // Returns the assembly string for the inputs and outputs of a VOP3
720 // instruction.
721 class getAsm64 <int NumSrcArgs, bit HasModifiers> {
722   string src0 = "$src0_modifiers,";
723   string src1 = !if(!eq(NumSrcArgs, 1), "",
724                    !if(!eq(NumSrcArgs, 2), " $src1_modifiers",
725                                            " $src1_modifiers,"));
726   string src2 = !if(!eq(NumSrcArgs, 3), " $src2_modifiers", "");
727   string ret =
728   !if(!eq(HasModifiers, 0),
729       getAsm32<NumSrcArgs>.ret,
730       " $dst, "#src0#src1#src2#"$clamp"#"$omod");
731 }
732
733
734 class VOPProfile <list<ValueType> _ArgVT> {
735
736   field list<ValueType> ArgVT = _ArgVT;
737
738   field ValueType DstVT = ArgVT[0];
739   field ValueType Src0VT = ArgVT[1];
740   field ValueType Src1VT = ArgVT[2];
741   field ValueType Src2VT = ArgVT[3];
742   field RegisterClass DstRC = getVALUDstForVT<DstVT>.ret;
743   field RegisterOperand Src0RC32 = getVOPSrc0ForVT<Src0VT>.ret;
744   field RegisterClass Src1RC32 = getVOPSrc1ForVT<Src1VT>.ret;
745   field RegisterOperand Src0RC64 = getVOP3SrcForVT<Src0VT>.ret;
746   field RegisterOperand Src1RC64 = getVOP3SrcForVT<Src1VT>.ret;
747   field RegisterOperand Src2RC64 = getVOP3SrcForVT<Src2VT>.ret;
748
749   field int NumSrcArgs = getNumSrcArgs<Src1VT, Src2VT>.ret;
750   field bit HasModifiers = hasModifiers<Src0VT>.ret;
751
752   field dag Outs = (outs DstRC:$dst);
753
754   field dag Ins32 = getIns32<Src0RC32, Src1RC32, NumSrcArgs>.ret;
755   field dag Ins64 = getIns64<Src0RC64, Src1RC64, Src2RC64, NumSrcArgs,
756                              HasModifiers>.ret;
757
758   field string Asm32 = "_e32"#getAsm32<NumSrcArgs>.ret;
759   field string Asm64 = getAsm64<NumSrcArgs, HasModifiers>.ret;
760 }
761
762 def VOP_F32_F32 : VOPProfile <[f32, f32, untyped, untyped]>;
763 def VOP_F32_F64 : VOPProfile <[f32, f64, untyped, untyped]>;
764 def VOP_F32_I32 : VOPProfile <[f32, i32, untyped, untyped]>;
765 def VOP_F64_F32 : VOPProfile <[f64, f32, untyped, untyped]>;
766 def VOP_F64_F64 : VOPProfile <[f64, f64, untyped, untyped]>;
767 def VOP_F64_I32 : VOPProfile <[f64, i32, untyped, untyped]>;
768 def VOP_I32_F32 : VOPProfile <[i32, f32, untyped, untyped]>;
769 def VOP_I32_F64 : VOPProfile <[i32, f64, untyped, untyped]>;
770 def VOP_I32_I32 : VOPProfile <[i32, i32, untyped, untyped]>;
771
772 def VOP_F32_F32_F32 : VOPProfile <[f32, f32, f32, untyped]>;
773 def VOP_F32_F32_I32 : VOPProfile <[f32, f32, i32, untyped]>;
774 def VOP_F64_F64_F64 : VOPProfile <[f64, f64, f64, untyped]>;
775 def VOP_F64_F64_I32 : VOPProfile <[f64, f64, i32, untyped]>;
776 def VOP_I32_F32_F32 : VOPProfile <[i32, f32, f32, untyped]>;
777 def VOP_I32_I32_I32 : VOPProfile <[i32, i32, i32, untyped]>;
778 def VOP_I32_I32_I32_VCC : VOPProfile <[i32, i32, i32, untyped]> {
779   let Src0RC32 = VCSrc_32;
780 }
781
782 def VOP_I1_F32_I32 : VOPProfile <[i1, f32, i32, untyped]> {
783   let Ins64 = (ins InputModsNoDefault:$src0_modifiers, Src0RC64:$src0, Src1RC64:$src1);
784   let Asm64 = " $dst, $src0_modifiers, $src1";
785 }
786
787 def VOP_I1_F64_I32 : VOPProfile <[i1, f64, i32, untyped]> {
788   let Ins64 = (ins InputModsNoDefault:$src0_modifiers, Src0RC64:$src0, Src1RC64:$src1);
789   let Asm64 = " $dst, $src0_modifiers, $src1";
790 }
791
792 def VOP_I64_I64_I32 : VOPProfile <[i64, i64, i32, untyped]>;
793 def VOP_I64_I64_I64 : VOPProfile <[i64, i64, i64, untyped]>;
794
795 def VOP_F32_F32_F32_F32 : VOPProfile <[f32, f32, f32, f32]>;
796 def VOP_F64_F64_F64_F64 : VOPProfile <[f64, f64, f64, f64]>;
797 def VOP_I32_I32_I32_I32 : VOPProfile <[i32, i32, i32, i32]>;
798 def VOP_I64_I32_I32_I64 : VOPProfile <[i64, i32, i32, i64]>;
799
800
801 class VOP <string opName> {
802   string OpName = opName;
803 }
804
805 class VOP2_REV <string revOp, bit isOrig> {
806   string RevOp = revOp;
807   bit IsOrig = isOrig;
808 }
809
810 class AtomicNoRet <string noRetOp, bit isRet> {
811   string NoRetOp = noRetOp;
812   bit IsRet = isRet;
813 }
814
815 class VOP1_Pseudo <dag outs, dag ins, list<dag> pattern, string opName> :
816   VOP1Common <outs, ins, "", pattern>,
817   VOP <opName>,
818   SIMCInstr <opName#"_e32", SISubtarget.NONE> {
819   let isPseudo = 1;
820 }
821
822 multiclass VOP1_m <vop1 op, dag outs, dag ins, string asm, list<dag> pattern,
823                    string opName> {
824   def "" : VOP1_Pseudo <outs, ins, pattern, opName>;
825
826   def _si : VOP1<op.SI, outs, ins, asm, []>,
827             SIMCInstr <opName#"_e32", SISubtarget.SI>;
828   def _vi : VOP1<op.VI, outs, ins, asm, []>,
829             SIMCInstr <opName#"_e32", SISubtarget.VI>;
830 }
831
832 class VOP2_Pseudo <dag outs, dag ins, list<dag> pattern, string opName> :
833   VOP2Common <outs, ins, "", pattern>,
834   VOP <opName>,
835   SIMCInstr<opName#"_e32", SISubtarget.NONE> {
836   let isPseudo = 1;
837 }
838
839 multiclass VOP2_m <vop2 op, dag outs, dag ins, string asm, list<dag> pattern,
840                    string opName, string revOpSI, string revOpVI> {
841   def "" : VOP2_Pseudo <outs, ins, pattern, opName>,
842            VOP2_REV<revOpSI#"_e32", !eq(revOpSI, opName)>;
843
844   def _si : VOP2 <op.SI, outs, ins, opName#asm, []>,
845             VOP2_REV<revOpSI#"_e32_si", !eq(revOpSI, opName)>,
846             SIMCInstr <opName#"_e32", SISubtarget.SI>;
847   def _vi : VOP2 <op.VI, outs, ins, opName#asm, []>,
848             VOP2_REV<revOpVI#"_e32_vi", !eq(revOpVI, opName)>,
849             SIMCInstr <opName#"_e32", SISubtarget.VI>;
850 }
851
852 class VOP3DisableFields <bit HasSrc1, bit HasSrc2, bit HasModifiers> {
853
854   bits<2> src0_modifiers = !if(HasModifiers, ?, 0);
855   bits<2> src1_modifiers = !if(HasModifiers, !if(HasSrc1, ?, 0), 0);
856   bits<2> src2_modifiers = !if(HasModifiers, !if(HasSrc2, ? ,0) ,0);
857   bits<2> omod = !if(HasModifiers, ?, 0);
858   bits<1> clamp = !if(HasModifiers, ?, 0);
859   bits<9> src1 = !if(HasSrc1, ?, 0);
860   bits<9> src2 = !if(HasSrc2, ?, 0);
861 }
862
863 class VOP3_Pseudo <dag outs, dag ins, list<dag> pattern, string opName> :
864   VOP3Common <outs, ins, "", pattern>,
865   VOP <opName>,
866   SIMCInstr<opName#"_e64", SISubtarget.NONE> {
867   let isPseudo = 1;
868 }
869
870 class VOP3_Real_si <bits<9> op, dag outs, dag ins, string asm, string opName> :
871   VOP3Common <outs, ins, asm, []>,
872   VOP3e <op>,
873   SIMCInstr<opName#"_e64", SISubtarget.SI>;
874
875 class VOP3_Real_vi <bits<10> op, dag outs, dag ins, string asm, string opName> :
876   VOP3Common <outs, ins, asm, []>,
877   VOP3e_vi <op>,
878   SIMCInstr <opName#"_e64", SISubtarget.VI>;
879
880 // VI only instruction
881 class VOP3_vi <bits<10> op, string opName, dag outs, dag ins, string asm,
882                list<dag> pattern, int NumSrcArgs, bit HasMods = 1> :
883   VOP3Common <outs, ins, asm, pattern>,
884   VOP <opName>,
885   VOP3e_vi <op>,
886   VOP3DisableFields<!if(!eq(NumSrcArgs, 1), 0, 1),
887                     !if(!eq(NumSrcArgs, 2), 0, 1),
888                     HasMods>;
889
890 multiclass VOP3_m <vop op, dag outs, dag ins, string asm, list<dag> pattern,
891                    string opName, int NumSrcArgs, bit HasMods = 1> {
892
893   def "" : VOP3_Pseudo <outs, ins, pattern, opName>;
894
895   def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>,
896             VOP3DisableFields<!if(!eq(NumSrcArgs, 1), 0, 1),
897                               !if(!eq(NumSrcArgs, 2), 0, 1),
898                               HasMods>;
899   def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName>,
900             VOP3DisableFields<!if(!eq(NumSrcArgs, 1), 0, 1),
901                               !if(!eq(NumSrcArgs, 2), 0, 1),
902                               HasMods>;
903 }
904
905 // VOP3_m without source modifiers
906 multiclass VOP3_m_nosrcmod <vop op, dag outs, dag ins, string asm, list<dag> pattern,
907                    string opName, int NumSrcArgs, bit HasMods = 1> {
908
909   def "" : VOP3_Pseudo <outs, ins, pattern, opName>;
910
911   let src0_modifiers = 0,
912       src1_modifiers = 0,
913       src2_modifiers = 0 in {
914     def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>;
915     def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName>;
916   }
917 }
918
919 multiclass VOP3_1_m <vop op, dag outs, dag ins, string asm,
920                      list<dag> pattern, string opName, bit HasMods = 1> {
921
922   def "" : VOP3_Pseudo <outs, ins, pattern, opName>;
923
924   def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>,
925             VOP3DisableFields<0, 0, HasMods>;
926
927   def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName>,
928             VOP3DisableFields<0, 0, HasMods>;
929 }
930
931 multiclass VOP3_2_m <vop op, dag outs, dag ins, string asm,
932                      list<dag> pattern, string opName, string revOpSI, string revOpVI,
933                      bit HasMods = 1, bit UseFullOp = 0> {
934
935   def "" : VOP3_Pseudo <outs, ins, pattern, opName>,
936            VOP2_REV<revOpSI#"_e64", !eq(revOpSI, opName)>;
937
938   def _si : VOP3_Real_si <op.SI3,
939               outs, ins, asm, opName>,
940             VOP2_REV<revOpSI#"_e64_si", !eq(revOpSI, opName)>,
941             VOP3DisableFields<1, 0, HasMods>;
942
943   def _vi : VOP3_Real_vi <op.VI3,
944               outs, ins, asm, opName>,
945             VOP2_REV<revOpVI#"_e64_vi", !eq(revOpVI, opName)>,
946             VOP3DisableFields<1, 0, HasMods>;
947 }
948
949 multiclass VOP3b_2_m <vop op, dag outs, dag ins, string asm,
950                       list<dag> pattern, string opName, string revOp,
951                       bit HasMods = 1, bit UseFullOp = 0> {
952   def "" : VOP3_Pseudo <outs, ins, pattern, opName>,
953            VOP2_REV<revOp#"_e64", !eq(revOp, opName)>;
954
955   // The VOP2 variant puts the carry out into VCC, the VOP3 variant
956   // can write it into any SGPR. We currently don't use the carry out,
957   // so for now hardcode it to VCC as well.
958   let sdst = SIOperand.VCC, Defs = [VCC] in {
959     def _si : VOP3b <op.SI3, outs, ins, asm, pattern>,
960               VOP3DisableFields<1, 0, HasMods>,
961               SIMCInstr<opName#"_e64", SISubtarget.SI>,
962               VOP2_REV<revOp#"_e64_si", !eq(revOp, opName)>;
963
964     // TODO: Do we need this VI variant here?
965     /*def _vi : VOP3b_vi <op.VI3, outs, ins, asm, pattern>,
966               VOP3DisableFields<1, 0, HasMods>,
967               SIMCInstr<opName#"_e64", SISubtarget.VI>,
968               VOP2_REV<revOp#"_e64_vi", !eq(revOp, opName)>;*/
969   } // End sdst = SIOperand.VCC, Defs = [VCC]
970 }
971
972 multiclass VOP3_C_m <vop op, dag outs, dag ins, string asm,
973                      list<dag> pattern, string opName,
974                      bit HasMods, bit defExec> {
975
976   def "" : VOP3_Pseudo <outs, ins, pattern, opName>;
977
978   def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>,
979             VOP3DisableFields<1, 0, HasMods> {
980     let Defs = !if(defExec, [EXEC], []);
981   }
982
983   def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName>,
984             VOP3DisableFields<1, 0, HasMods> {
985     let Defs = !if(defExec, [EXEC], []);
986   }
987 }
988
989 multiclass VOP1_Helper <vop1 op, string opName, dag outs,
990                         dag ins32, string asm32, list<dag> pat32,
991                         dag ins64, string asm64, list<dag> pat64,
992                         bit HasMods> {
993
994   defm _e32 : VOP1_m <op, outs, ins32, opName#asm32, pat32, opName>;
995
996   defm _e64 : VOP3_1_m <op, outs, ins64, opName#"_e64"#asm64, pat64, opName, HasMods>;
997 }
998
999 multiclass VOP1Inst <vop1 op, string opName, VOPProfile P,
1000                      SDPatternOperator node = null_frag> : VOP1_Helper <
1001   op, opName, P.Outs,
1002   P.Ins32, P.Asm32, [],
1003   P.Ins64, P.Asm64,
1004   !if(P.HasModifiers,
1005       [(set P.DstVT:$dst, (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0,
1006                                 i32:$src0_modifiers, i1:$clamp, i32:$omod))))],
1007       [(set P.DstVT:$dst, (node P.Src0VT:$src0))]),
1008   P.HasModifiers
1009 >;
1010
1011 multiclass VOP1InstSI <vop1 op, string opName, VOPProfile P,
1012                        SDPatternOperator node = null_frag> {
1013
1014   def _e32 : VOP1 <op.SI, P.Outs, P.Ins32, opName#P.Asm32, []>,
1015              VOP <opName>;
1016
1017   def _e64 : VOP3Common <P.Outs, P.Ins64, opName#P.Asm64,
1018     !if(P.HasModifiers,
1019       [(set P.DstVT:$dst, (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0,
1020                                 i32:$src0_modifiers, i1:$clamp, i32:$omod))))],
1021       [(set P.DstVT:$dst, (node P.Src0VT:$src0))])>,
1022             VOP <opName>,
1023             VOP3e <op.SI3>,
1024             VOP3DisableFields<0, 0, P.HasModifiers>;
1025 }
1026
1027 multiclass VOP2_Helper <vop2 op, string opName, dag outs,
1028                         dag ins32, string asm32, list<dag> pat32,
1029                         dag ins64, string asm64, list<dag> pat64,
1030                         string revOpSI, string revOpVI, bit HasMods> {
1031   defm _e32 : VOP2_m <op, outs, ins32, asm32, pat32, opName, revOpSI, revOpVI>;
1032
1033   defm _e64 : VOP3_2_m <op,
1034     outs, ins64, opName#"_e64"#asm64, pat64, opName, revOpSI, revOpVI, HasMods
1035   >;
1036 }
1037
1038 multiclass VOP2Inst <vop2 op, string opName, VOPProfile P,
1039                      SDPatternOperator node = null_frag,
1040                      string revOpSI = opName, string revOpVI = revOpSI> : VOP2_Helper <
1041   op, opName, P.Outs,
1042   P.Ins32, P.Asm32, [],
1043   P.Ins64, P.Asm64,
1044   !if(P.HasModifiers,
1045       [(set P.DstVT:$dst,
1046            (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1047                                       i1:$clamp, i32:$omod)),
1048                  (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
1049       [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1))]),
1050   revOpSI, revOpVI, P.HasModifiers
1051 >;
1052
1053 multiclass VOP2b_Helper <vop2 op, string opName, dag outs,
1054                          dag ins32, string asm32, list<dag> pat32,
1055                          dag ins64, string asm64, list<dag> pat64,
1056                          string revOp, bit HasMods> {
1057
1058   defm _e32 : VOP2_m <op, outs, ins32, asm32, pat32, opName, revOp, revOp>;
1059
1060   defm _e64 : VOP3b_2_m <op,
1061     outs, ins64, opName#"_e64"#asm64, pat64, opName, revOp, HasMods
1062   >;
1063 }
1064
1065 multiclass VOP2bInst <vop2 op, string opName, VOPProfile P,
1066                       SDPatternOperator node = null_frag,
1067                       string revOp = opName> : VOP2b_Helper <
1068   op, opName, P.Outs,
1069   P.Ins32, P.Asm32, [],
1070   P.Ins64, P.Asm64,
1071   !if(P.HasModifiers,
1072       [(set P.DstVT:$dst,
1073            (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1074                                       i1:$clamp, i32:$omod)),
1075                  (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
1076       [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1))]),
1077   revOp, P.HasModifiers
1078 >;
1079
1080 class VOPC_Pseudo <dag outs, dag ins, list<dag> pattern, string opName> :
1081   VOPCCommon <ins, "", pattern>,
1082   VOP <opName>,
1083   SIMCInstr<opName#"_e32", SISubtarget.NONE> {
1084   let isPseudo = 1;
1085 }
1086
1087 multiclass VOPC_m <vopc op, dag outs, dag ins, string asm, list<dag> pattern,
1088                    string opName, bit DefExec> {
1089   def "" : VOPC_Pseudo <outs, ins, pattern, opName>;
1090
1091   def _si : VOPC<op.SI, ins, asm, []>,
1092             SIMCInstr <opName#"_e32", SISubtarget.SI> {
1093     let Defs = !if(DefExec, [EXEC], []);
1094   }
1095
1096   def _vi : VOPC<op.VI, ins, asm, []>,
1097             SIMCInstr <opName#"_e32", SISubtarget.VI> {
1098     let Defs = !if(DefExec, [EXEC], []);
1099   }
1100 }
1101
1102 multiclass VOPC_Helper <vopc op, string opName,
1103                         dag ins32, string asm32, list<dag> pat32,
1104                         dag out64, dag ins64, string asm64, list<dag> pat64,
1105                         bit HasMods, bit DefExec> {
1106   defm _e32 : VOPC_m <op, (outs), ins32, opName#asm32, pat32, opName, DefExec>;
1107
1108   defm _e64 : VOP3_C_m <op, out64, ins64, opName#"_e64"#asm64, pat64,
1109                         opName, HasMods, DefExec>;
1110 }
1111
1112 multiclass VOPCInst <vopc op, string opName,
1113                      VOPProfile P, PatLeaf cond = COND_NULL,
1114                      bit DefExec = 0> : VOPC_Helper <
1115   op, opName,
1116   P.Ins32, P.Asm32, [],
1117   (outs SReg_64:$dst), P.Ins64, P.Asm64,
1118   !if(P.HasModifiers,
1119       [(set i1:$dst,
1120           (setcc (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1121                                       i1:$clamp, i32:$omod)),
1122                  (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)),
1123                  cond))],
1124       [(set i1:$dst, (setcc P.Src0VT:$src0, P.Src1VT:$src1, cond))]),
1125   P.HasModifiers, DefExec
1126 >;
1127
1128 multiclass VOPCClassInst <vopc op, string opName, VOPProfile P,
1129                      bit DefExec = 0> : VOPC_Helper <
1130   op, opName,
1131   P.Ins32, P.Asm32, [],
1132   (outs SReg_64:$dst), P.Ins64, P.Asm64,
1133   !if(P.HasModifiers,
1134       [(set i1:$dst,
1135           (AMDGPUfp_class (P.Src0VT (VOP3Mods0Clamp0OMod P.Src0VT:$src0, i32:$src0_modifiers)), P.Src1VT:$src1))],
1136       [(set i1:$dst, (AMDGPUfp_class P.Src0VT:$src0, P.Src1VT:$src1))]),
1137   P.HasModifiers, DefExec
1138 >;
1139
1140
1141 multiclass VOPC_F32 <vopc op, string opName, PatLeaf cond = COND_NULL> :
1142   VOPCInst <op, opName, VOP_F32_F32_F32, cond>;
1143
1144 multiclass VOPC_F64 <vopc op, string opName, PatLeaf cond = COND_NULL> :
1145   VOPCInst <op, opName, VOP_F64_F64_F64, cond>;
1146
1147 multiclass VOPC_I32 <vopc op, string opName, PatLeaf cond = COND_NULL> :
1148   VOPCInst <op, opName, VOP_I32_I32_I32, cond>;
1149
1150 multiclass VOPC_I64 <vopc op, string opName, PatLeaf cond = COND_NULL> :
1151   VOPCInst <op, opName, VOP_I64_I64_I64, cond>;
1152
1153
1154 multiclass VOPCX <vopc op, string opName, VOPProfile P,
1155                   PatLeaf cond = COND_NULL>
1156   : VOPCInst <op, opName, P, cond, 1>;
1157
1158 multiclass VOPCX_F32 <vopc op, string opName, PatLeaf cond = COND_NULL> :
1159   VOPCX <op, opName, VOP_F32_F32_F32, cond>;
1160
1161 multiclass VOPCX_F64 <vopc op, string opName, PatLeaf cond = COND_NULL> :
1162   VOPCX <op, opName, VOP_F64_F64_F64, cond>;
1163
1164 multiclass VOPCX_I32 <vopc op, string opName, PatLeaf cond = COND_NULL> :
1165   VOPCX <op, opName, VOP_I32_I32_I32, cond>;
1166
1167 multiclass VOPCX_I64 <vopc op, string opName, PatLeaf cond = COND_NULL> :
1168   VOPCX <op, opName, VOP_I64_I64_I64, cond>;
1169
1170 multiclass VOP3_Helper <vop3 op, string opName, dag outs, dag ins, string asm,
1171                         list<dag> pat, int NumSrcArgs, bit HasMods> : VOP3_m <
1172     op, outs, ins, opName#asm, pat, opName, NumSrcArgs, HasMods
1173 >;
1174
1175 multiclass VOPC_CLASS_F32 <vopc op, string opName> :
1176   VOPCClassInst <op, opName, VOP_I1_F32_I32, 0>;
1177
1178 multiclass VOPCX_CLASS_F32 <vopc op, string opName> :
1179   VOPCClassInst <op, opName, VOP_I1_F32_I32, 1>;
1180
1181 multiclass VOPC_CLASS_F64 <vopc op, string opName> :
1182   VOPCClassInst <op, opName, VOP_I1_F64_I32, 0>;
1183
1184 multiclass VOPCX_CLASS_F64 <vopc op, string opName> :
1185   VOPCClassInst <op, opName, VOP_I1_F64_I32, 1>;
1186
1187 multiclass VOP3Inst <vop3 op, string opName, VOPProfile P,
1188                      SDPatternOperator node = null_frag> : VOP3_Helper <
1189   op, opName, P.Outs, P.Ins64, P.Asm64,
1190   !if(!eq(P.NumSrcArgs, 3),
1191     !if(P.HasModifiers,
1192         [(set P.DstVT:$dst,
1193             (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1194                                        i1:$clamp, i32:$omod)),
1195                   (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)),
1196                   (P.Src2VT (VOP3Mods P.Src2VT:$src2, i32:$src2_modifiers))))],
1197         [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1,
1198                                   P.Src2VT:$src2))]),
1199   !if(!eq(P.NumSrcArgs, 2),
1200     !if(P.HasModifiers,
1201         [(set P.DstVT:$dst,
1202             (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1203                                        i1:$clamp, i32:$omod)),
1204                   (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
1205         [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1))])
1206   /* P.NumSrcArgs == 1 */,
1207     !if(P.HasModifiers,
1208         [(set P.DstVT:$dst,
1209             (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1210                                        i1:$clamp, i32:$omod))))],
1211         [(set P.DstVT:$dst, (node P.Src0VT:$src0))]))),
1212   P.NumSrcArgs, P.HasModifiers
1213 >;
1214
1215 class VOP3InstVI <bits<10> op, string opName, VOPProfile P,
1216                   SDPatternOperator node = null_frag> : VOP3_vi <
1217   op, opName#"_vi", P.Outs, P.Ins64, opName#P.Asm64,
1218   !if(!eq(P.NumSrcArgs, 3),
1219     !if(P.HasModifiers,
1220         [(set P.DstVT:$dst,
1221             (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1222                                        i1:$clamp, i32:$omod)),
1223                   (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)),
1224                   (P.Src2VT (VOP3Mods P.Src2VT:$src2, i32:$src2_modifiers))))],
1225         [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1,
1226                                   P.Src2VT:$src2))]),
1227   !if(!eq(P.NumSrcArgs, 2),
1228     !if(P.HasModifiers,
1229         [(set P.DstVT:$dst,
1230             (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1231                                        i1:$clamp, i32:$omod)),
1232                   (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
1233         [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1))])
1234   /* P.NumSrcArgs == 1 */,
1235     !if(P.HasModifiers,
1236         [(set P.DstVT:$dst,
1237             (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1238                                        i1:$clamp, i32:$omod))))],
1239         [(set P.DstVT:$dst, (node P.Src0VT:$src0))]))),
1240   P.NumSrcArgs, P.HasModifiers
1241 >;
1242
1243 multiclass VOP3b_Helper <vop op, RegisterClass vrc, RegisterOperand arc,
1244                     string opName, list<dag> pattern> :
1245   VOP3b_2_m <
1246   op, (outs vrc:$vdst, SReg_64:$sdst),
1247       (ins InputModsNoDefault:$src0_modifiers, arc:$src0,
1248            InputModsNoDefault:$src1_modifiers, arc:$src1,
1249            InputModsNoDefault:$src2_modifiers, arc:$src2,
1250            ClampMod:$clamp, omod:$omod),
1251   opName#" $vdst, $sdst, $src0_modifiers, $src1_modifiers, $src2_modifiers"#"$clamp"#"$omod", pattern,
1252   opName, opName, 1, 1
1253 >;
1254
1255 multiclass VOP3b_64 <vop3 op, string opName, list<dag> pattern> :
1256   VOP3b_Helper <op, VReg_64, VSrc_64, opName, pattern>;
1257
1258 multiclass VOP3b_32 <vop3 op, string opName, list<dag> pattern> :
1259   VOP3b_Helper <op, VGPR_32, VSrc_32, opName, pattern>;
1260
1261
1262 class Vop3ModPat<Instruction Inst, VOPProfile P, SDPatternOperator node> : Pat<
1263   (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i1:$clamp, i32:$omod)),
1264         (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)),
1265         (P.Src2VT (VOP3Mods P.Src2VT:$src2, i32:$src2_modifiers))),
1266   (Inst i32:$src0_modifiers, P.Src0VT:$src0,
1267         i32:$src1_modifiers, P.Src1VT:$src1,
1268         i32:$src2_modifiers, P.Src2VT:$src2,
1269         i1:$clamp,
1270         i32:$omod)>;
1271
1272 //===----------------------------------------------------------------------===//
1273 // Interpolation opcodes
1274 //===----------------------------------------------------------------------===//
1275
1276 class VINTRP_Pseudo <string opName, dag outs, dag ins, string asm,
1277                      list<dag> pattern> :
1278   VINTRPCommon <outs, ins, asm, pattern>,
1279   SIMCInstr<opName, SISubtarget.NONE> {
1280   let isPseudo = 1;
1281 }
1282
1283 class VINTRP_Real_si <bits <2> op, string opName, dag outs, dag ins,
1284                       string asm, list<dag> pattern> :
1285   VINTRPCommon <outs, ins, asm, pattern>,
1286   VINTRPe <op>,
1287   SIMCInstr<opName, SISubtarget.SI>;
1288
1289 class VINTRP_Real_vi <bits <2> op, string opName, dag outs, dag ins,
1290                       string asm, list<dag> pattern> :
1291   VINTRPCommon <outs, ins, asm, pattern>,
1292   VINTRPe_vi <op>,
1293   SIMCInstr<opName, SISubtarget.VI>;
1294
1295 multiclass VINTRP_m <bits <2> op, string opName, dag outs, dag ins, string asm,
1296                      string disableEncoding = "", string constraints = "",
1297                      list<dag> pattern = []> {
1298   let DisableEncoding = disableEncoding,
1299       Constraints = constraints in {
1300     def "" : VINTRP_Pseudo <opName, outs, ins, asm, pattern>;
1301
1302     def _si : VINTRP_Real_si <op, opName, outs, ins, asm, pattern>;
1303
1304     def _vi : VINTRP_Real_vi <op, opName, outs, ins, asm, pattern>;
1305   }
1306 }
1307
1308 //===----------------------------------------------------------------------===//
1309 // Vector I/O classes
1310 //===----------------------------------------------------------------------===//
1311
1312 class DS_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
1313   DS <outs, ins, "", pattern>,
1314   SIMCInstr <opName, SISubtarget.NONE> {
1315   let isPseudo = 1;
1316 }
1317
1318 class DS_Real_si <bits<8> op, string opName, dag outs, dag ins, string asm> :
1319   DS <outs, ins, asm, []>,
1320   DSe <op>,
1321   SIMCInstr <opName, SISubtarget.SI>;
1322
1323 class DS_Real_vi <bits<8> op, string opName, dag outs, dag ins, string asm> :
1324   DS <outs, ins, asm, []>,
1325   DSe_vi <op>,
1326   SIMCInstr <opName, SISubtarget.VI>;
1327
1328 class DS_1A_Real_si <bits<8> op, string opName, dag outs, dag ins, string asm> :
1329   DS <outs, ins, asm, []>,
1330   DSe <op>,
1331   SIMCInstr <opName, SISubtarget.SI> {
1332
1333   // Single load interpret the 2 i8imm operands as a single i16 offset.
1334   bits<16> offset;
1335   let offset0 = offset{7-0};
1336   let offset1 = offset{15-8};
1337 }
1338
1339 class DS_1A_Real_vi <bits<8> op, string opName, dag outs, dag ins, string asm> :
1340   DS <outs, ins, asm, []>,
1341   DSe_vi <op>,
1342   SIMCInstr <opName, SISubtarget.VI> {
1343
1344   // Single load interpret the 2 i8imm operands as a single i16 offset.
1345   bits<16> offset;
1346   let offset0 = offset{7-0};
1347   let offset1 = offset{15-8};
1348 }
1349
1350 multiclass DS_1A_Load_m <bits<8> op, string opName, dag outs, dag ins, string asm,
1351                          list<dag> pat> {
1352   let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
1353     def "" : DS_Pseudo <opName, outs, ins, pat>;
1354
1355     let data0 = 0, data1 = 0 in {
1356       def _si : DS_1A_Real_si <op, opName, outs, ins, asm>;
1357       def _vi : DS_1A_Real_vi <op, opName, outs, ins, asm>;
1358     }
1359   }
1360 }
1361
1362 multiclass DS_Load_Helper <bits<8> op, string asm, RegisterClass regClass>
1363     : DS_1A_Load_m <
1364   op,
1365   asm,
1366   (outs regClass:$vdst),
1367   (ins i1imm:$gds, VGPR_32:$addr, ds_offset:$offset, M0Reg:$m0),
1368   asm#" $vdst, $addr"#"$offset"#" [M0]",
1369   []>;
1370
1371 multiclass DS_Load2_m <bits<8> op, string opName, dag outs, dag ins, string asm,
1372                        list<dag> pat> {
1373   let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
1374     def "" : DS_Pseudo <opName, outs, ins, pat>;
1375
1376     let data0 = 0, data1 = 0 in {
1377       def _si : DS_Real_si <op, opName, outs, ins, asm>;
1378       def _vi : DS_Real_vi <op, opName, outs, ins, asm>;
1379     }
1380   }
1381 }
1382
1383 multiclass DS_Load2_Helper <bits<8> op, string asm, RegisterClass regClass>
1384     : DS_Load2_m <
1385   op,
1386   asm,
1387   (outs regClass:$vdst),
1388   (ins i1imm:$gds, VGPR_32:$addr, ds_offset0:$offset0, ds_offset1:$offset1,
1389         M0Reg:$m0),
1390   asm#" $vdst, $addr"#"$offset0"#"$offset1 [M0]",
1391   []>;
1392
1393 multiclass DS_1A_Store_m <bits<8> op, string opName, dag outs, dag ins,
1394                           string asm, list<dag> pat> {
1395   let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
1396     def "" : DS_Pseudo <opName, outs, ins, pat>;
1397
1398     let data1 = 0, vdst = 0 in {
1399       def _si : DS_1A_Real_si <op, opName, outs, ins, asm>;
1400       def _vi : DS_1A_Real_vi <op, opName, outs, ins, asm>;
1401     }
1402   }
1403 }
1404
1405 multiclass DS_Store_Helper <bits<8> op, string asm, RegisterClass regClass>
1406     : DS_1A_Store_m <
1407   op,
1408   asm,
1409   (outs),
1410   (ins i1imm:$gds, VGPR_32:$addr, regClass:$data0, ds_offset:$offset, M0Reg:$m0),
1411   asm#" $addr, $data0"#"$offset"#" [M0]",
1412   []>;
1413
1414 multiclass DS_Store_m <bits<8> op, string opName, dag outs, dag ins,
1415                        string asm, list<dag> pat> {
1416   let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
1417     def "" : DS_Pseudo <opName, outs, ins, pat>;
1418
1419     let vdst = 0 in {
1420       def _si : DS_Real_si <op, opName, outs, ins, asm>;
1421       def _vi : DS_Real_vi <op, opName, outs, ins, asm>;
1422     }
1423   }
1424 }
1425
1426 multiclass DS_Store2_Helper <bits<8> op, string asm, RegisterClass regClass>
1427     : DS_Store_m <
1428   op,
1429   asm,
1430   (outs),
1431   (ins i1imm:$gds, VGPR_32:$addr, regClass:$data0, regClass:$data1,
1432        ds_offset0:$offset0, ds_offset1:$offset1, M0Reg:$m0),
1433   asm#" $addr, $data0, $data1"#"$offset0"#"$offset1 [M0]",
1434   []>;
1435
1436 class DS_1A_si <bits<8> op, dag outs, dag ins, string asm, list<dag> pat> :
1437     DS_si <op, outs, ins, asm, pat> {
1438   bits<16> offset;
1439
1440   // Single load interpret the 2 i8imm operands as a single i16 offset.
1441   let offset0 = offset{7-0};
1442   let offset1 = offset{15-8};
1443
1444   let hasSideEffects = 0;
1445 }
1446
1447 // 1 address, 1 data.
1448 class DS_1A1D_RET <bits<8> op, string asm, RegisterClass rc, string noRetOp = ""> : DS_1A_si <
1449   op,
1450   (outs rc:$vdst),
1451   (ins i1imm:$gds, VGPR_32:$addr, rc:$data0, ds_offset:$offset, M0Reg:$m0),
1452   asm#" $vdst, $addr, $data0"#"$offset"#" [M0]", []>,
1453   AtomicNoRet<noRetOp, 1> {
1454
1455   let data1 = 0;
1456   let mayStore = 1;
1457   let mayLoad = 1;
1458
1459   let hasPostISelHook = 1; // Adjusted to no return version.
1460 }
1461
1462 // 1 address, 2 data.
1463 class DS_1A2D_RET <bits<8> op, string asm, RegisterClass rc, string noRetOp = ""> : DS_1A_si <
1464   op,
1465   (outs rc:$vdst),
1466   (ins i1imm:$gds, VGPR_32:$addr, rc:$data0, rc:$data1, ds_offset:$offset, M0Reg:$m0),
1467   asm#" $vdst, $addr, $data0, $data1"#"$offset"#" [M0]",
1468   []>,
1469   AtomicNoRet<noRetOp, 1> {
1470   let mayStore = 1;
1471   let mayLoad = 1;
1472   let hasPostISelHook = 1; // Adjusted to no return version.
1473 }
1474
1475 // 1 address, 2 data.
1476 class DS_1A2D_NORET <bits<8> op, string asm, RegisterClass rc, string noRetOp = asm> : DS_1A_si <
1477   op,
1478   (outs),
1479   (ins i1imm:$gds, VGPR_32:$addr, rc:$data0, rc:$data1, ds_offset:$offset, M0Reg:$m0),
1480   asm#" $addr, $data0, $data1"#"$offset"#" [M0]",
1481   []>,
1482   AtomicNoRet<noRetOp, 0> {
1483   let mayStore = 1;
1484   let mayLoad = 1;
1485 }
1486
1487 // 1 address, 1 data.
1488 class DS_1A1D_NORET <bits<8> op, string asm, RegisterClass rc, string noRetOp = asm> : DS_1A_si <
1489   op,
1490   (outs),
1491   (ins i1imm:$gds, VGPR_32:$addr, rc:$data0, ds_offset:$offset, M0Reg:$m0),
1492   asm#" $addr, $data0"#"$offset"#" [M0]",
1493   []>,
1494   AtomicNoRet<noRetOp, 0> {
1495
1496   let data1 = 0;
1497   let mayStore = 1;
1498   let mayLoad = 1;
1499 }
1500
1501 //===----------------------------------------------------------------------===//
1502 // MTBUF classes
1503 //===----------------------------------------------------------------------===//
1504
1505 class MTBUF_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
1506   MTBUF <outs, ins, "", pattern>,
1507   SIMCInstr<opName, SISubtarget.NONE> {
1508   let isPseudo = 1;
1509 }
1510
1511 class MTBUF_Real_si <bits<3> op, string opName, dag outs, dag ins,
1512                     string asm> :
1513   MTBUF <outs, ins, asm, []>,
1514   MTBUFe <op>,
1515   SIMCInstr<opName, SISubtarget.SI>;
1516
1517 class MTBUF_Real_vi <bits<4> op, string opName, dag outs, dag ins, string asm> :
1518   MTBUF <outs, ins, asm, []>,
1519   MTBUFe_vi <op>,
1520   SIMCInstr <opName, SISubtarget.VI>;
1521
1522 multiclass MTBUF_m <bits<3> op, string opName, dag outs, dag ins, string asm,
1523                     list<dag> pattern> {
1524
1525   def "" : MTBUF_Pseudo <opName, outs, ins, pattern>;
1526
1527   def _si : MTBUF_Real_si <op, opName, outs, ins, asm>;
1528
1529   def _vi : MTBUF_Real_vi <{0, op{2}, op{1}, op{0}}, opName, outs, ins, asm>;
1530
1531 }
1532
1533 let mayStore = 1, mayLoad = 0 in {
1534
1535 multiclass MTBUF_Store_Helper <bits<3> op, string opName,
1536                                RegisterClass regClass> : MTBUF_m <
1537   op, opName, (outs),
1538   (ins regClass:$vdata, u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
1539    i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VGPR_32:$vaddr,
1540    SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SCSrc_32:$soffset),
1541   opName#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
1542         #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset", []
1543 >;
1544
1545 } // mayStore = 1, mayLoad = 0
1546
1547 let mayLoad = 1, mayStore = 0 in {
1548
1549 multiclass MTBUF_Load_Helper <bits<3> op, string opName,
1550                               RegisterClass regClass> : MTBUF_m <
1551   op, opName, (outs regClass:$dst),
1552   (ins u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
1553        i8imm:$dfmt, i8imm:$nfmt, VGPR_32:$vaddr, SReg_128:$srsrc,
1554        i1imm:$slc, i1imm:$tfe, SCSrc_32:$soffset),
1555   opName#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
1556         #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset", []
1557 >;
1558
1559 } // mayLoad = 1, mayStore = 0
1560
1561 //===----------------------------------------------------------------------===//
1562 // MUBUF classes
1563 //===----------------------------------------------------------------------===//
1564
1565 class MUBUF_si <bits<7> op, dag outs, dag ins, string asm, list<dag> pattern> :
1566   MUBUF <outs, ins, asm, pattern>, MUBUFe <op> {
1567   let lds  = 0;
1568 }
1569
1570 class MUBUF_vi <bits<7> op, dag outs, dag ins, string asm, list<dag> pattern> :
1571   MUBUF <outs, ins, asm, pattern>, MUBUFe_vi <op> {
1572   let lds = 0;
1573 }
1574
1575 class MUBUFAddr64Table <bit is_addr64, string suffix = ""> {
1576
1577   bit IsAddr64 = is_addr64;
1578   string OpName = NAME # suffix;
1579 }
1580
1581 class MUBUFAtomicAddr64 <bits<7> op, dag outs, dag ins, string asm, list<dag> pattern>
1582     : MUBUF_si <op, outs, ins, asm, pattern> {
1583
1584   let offen = 0;
1585   let idxen = 0;
1586   let addr64 = 1;
1587   let tfe = 0;
1588   let lds = 0;
1589   let soffset = 128;
1590 }
1591
1592 class MUBUFAtomicOffset <bits<7> op, dag outs, dag ins, string asm, list<dag> pattern>
1593     : MUBUF_si <op, outs, ins, asm, pattern> {
1594
1595   let offen = 0;
1596   let idxen = 0;
1597   let addr64 = 0;
1598   let tfe = 0;
1599   let lds = 0;
1600   let vaddr = 0;
1601 }
1602
1603 multiclass MUBUF_Atomic <bits<7> op, string name, RegisterClass rc,
1604                          ValueType vt, SDPatternOperator atomic> {
1605
1606   let mayStore = 1, mayLoad = 1, hasPostISelHook = 1 in {
1607
1608     // No return variants
1609     let glc = 0 in {
1610
1611       def _ADDR64 : MUBUFAtomicAddr64 <
1612         op, (outs),
1613         (ins rc:$vdata, SReg_128:$srsrc, VReg_64:$vaddr,
1614              mbuf_offset:$offset, slc:$slc),
1615         name#" $vdata, $vaddr, $srsrc, 0 addr64"#"$offset"#"$slc", []
1616       >, MUBUFAddr64Table<1>, AtomicNoRet<NAME#"_ADDR64", 0>;
1617
1618       def _OFFSET : MUBUFAtomicOffset <
1619         op, (outs),
1620         (ins rc:$vdata, SReg_128:$srsrc, mbuf_offset:$offset,
1621              SCSrc_32:$soffset, slc:$slc),
1622         name#" $vdata, $srsrc, $soffset"#"$offset"#"$slc", []
1623       >, MUBUFAddr64Table<0>, AtomicNoRet<NAME#"_OFFSET", 0>;
1624     } // glc = 0
1625
1626     // Variant that return values
1627     let glc = 1, Constraints = "$vdata = $vdata_in",
1628         DisableEncoding = "$vdata_in"  in {
1629
1630       def _RTN_ADDR64 : MUBUFAtomicAddr64 <
1631         op, (outs rc:$vdata),
1632         (ins rc:$vdata_in, SReg_128:$srsrc, VReg_64:$vaddr,
1633              mbuf_offset:$offset, slc:$slc),
1634         name#" $vdata, $vaddr, $srsrc, 0 addr64"#"$offset"#" glc"#"$slc",
1635         [(set vt:$vdata,
1636          (atomic (MUBUFAddr64Atomic v4i32:$srsrc, i64:$vaddr, i16:$offset,
1637                                     i1:$slc), vt:$vdata_in))]
1638       >, MUBUFAddr64Table<1, "_RTN">, AtomicNoRet<NAME#"_ADDR64", 1>;
1639
1640       def _RTN_OFFSET : MUBUFAtomicOffset <
1641         op, (outs rc:$vdata),
1642         (ins rc:$vdata_in, SReg_128:$srsrc, mbuf_offset:$offset,
1643              SCSrc_32:$soffset, slc:$slc),
1644         name#" $vdata, $srsrc, $soffset"#"$offset"#" glc $slc",
1645         [(set vt:$vdata,
1646          (atomic (MUBUFOffsetAtomic v4i32:$srsrc, i32:$soffset, i16:$offset,
1647                                     i1:$slc), vt:$vdata_in))]
1648       >, MUBUFAddr64Table<0, "_RTN">, AtomicNoRet<NAME#"_OFFSET", 1>;
1649
1650     } // glc = 1
1651
1652   } // mayStore = 1, mayLoad = 1, hasPostISelHook = 1
1653 }
1654
1655 multiclass MUBUF_Load_Helper <bits<7> op, string asm, RegisterClass regClass,
1656                               ValueType load_vt = i32,
1657                               SDPatternOperator ld = null_frag> {
1658
1659   let mayLoad = 1, mayStore = 0 in {
1660
1661     let addr64 = 0 in {
1662
1663       let offen = 0, idxen = 0, vaddr = 0 in {
1664         def _OFFSET : MUBUF_si <op, (outs regClass:$vdata),
1665                              (ins SReg_128:$srsrc,
1666                              mbuf_offset:$offset, SCSrc_32:$soffset, glc:$glc,
1667                              slc:$slc, tfe:$tfe),
1668                              asm#" $vdata, $srsrc, $soffset"#"$offset"#"$glc"#"$slc"#"$tfe",
1669                              [(set load_vt:$vdata, (ld (MUBUFOffset v4i32:$srsrc,
1670                                                        i32:$soffset, i16:$offset,
1671                                                        i1:$glc, i1:$slc, i1:$tfe)))]>,
1672                      MUBUFAddr64Table<0>;
1673       }
1674
1675       let offen = 1, idxen = 0  in {
1676         def _OFFEN  : MUBUF_si <op, (outs regClass:$vdata),
1677                              (ins SReg_128:$srsrc, VGPR_32:$vaddr,
1678                              SCSrc_32:$soffset, mbuf_offset:$offset, glc:$glc, slc:$slc,
1679                              tfe:$tfe),
1680                              asm#" $vdata, $vaddr, $srsrc, $soffset offen"#"$offset"#"$glc"#"$slc"#"$tfe", []>;
1681       }
1682
1683       let offen = 0, idxen = 1 in {
1684         def _IDXEN  : MUBUF_si <op, (outs regClass:$vdata),
1685                              (ins SReg_128:$srsrc, VGPR_32:$vaddr,
1686                              mbuf_offset:$offset, SCSrc_32:$soffset, glc:$glc,
1687                              slc:$slc, tfe:$tfe),
1688                              asm#" $vdata, $vaddr, $srsrc, $soffset idxen"#"$offset"#"$glc"#"$slc"#"$tfe", []>;
1689       }
1690
1691       let offen = 1, idxen = 1 in {
1692         def _BOTHEN : MUBUF_si <op, (outs regClass:$vdata),
1693                              (ins SReg_128:$srsrc, VReg_64:$vaddr,
1694                              SCSrc_32:$soffset, glc:$glc, slc:$slc, tfe:$tfe),
1695                              asm#" $vdata, $vaddr, $srsrc, $soffset, idxen offen"#"$glc"#"$slc"#"$tfe", []>;
1696       }
1697     }
1698
1699     let offen = 0, idxen = 0, addr64 = 1, glc = 0, slc = 0, tfe = 0, soffset = 128 /* ZERO */ in {
1700       def _ADDR64 : MUBUF_si <op, (outs regClass:$vdata),
1701                            (ins SReg_128:$srsrc, VReg_64:$vaddr, mbuf_offset:$offset),
1702                            asm#" $vdata, $vaddr, $srsrc, 0 addr64"#"$offset",
1703                            [(set load_vt:$vdata, (ld (MUBUFAddr64 v4i32:$srsrc,
1704                                                   i64:$vaddr, i16:$offset)))]>, MUBUFAddr64Table<1>;
1705     }
1706   }
1707 }
1708
1709 multiclass MUBUF_Load_Helper_vi <bits<7> op, string asm, RegisterClass regClass,
1710                               ValueType load_vt = i32,
1711                               SDPatternOperator ld = null_frag> {
1712
1713   let lds = 0, mayLoad = 1 in {
1714     let offen = 0, idxen = 0, vaddr = 0 in {
1715       def _OFFSET : MUBUF_vi <op, (outs regClass:$vdata),
1716                            (ins SReg_128:$srsrc,
1717                            mbuf_offset:$offset, SCSrc_32:$soffset, glc:$glc,
1718                            slc:$slc, tfe:$tfe),
1719                            asm#" $vdata, $srsrc, $soffset"#"$offset"#"$glc"#"$slc"#"$tfe",
1720                            [(set load_vt:$vdata, (ld (MUBUFOffset v4i32:$srsrc,
1721                                                      i32:$soffset, i16:$offset,
1722                                                      i1:$glc, i1:$slc, i1:$tfe)))]>,
1723                            MUBUFAddr64Table<0>;
1724     }
1725
1726     let offen = 1, idxen = 0  in {
1727       def _OFFEN  : MUBUF_vi <op, (outs regClass:$vdata),
1728                            (ins SReg_128:$srsrc, VGPR_32:$vaddr,
1729                            SCSrc_32:$soffset, mbuf_offset:$offset, glc:$glc, slc:$slc,
1730                            tfe:$tfe),
1731                            asm#" $vdata, $vaddr, $srsrc, $soffset offen"#"$offset"#"$glc"#"$slc"#"$tfe", []>;
1732     }
1733
1734     let offen = 0, idxen = 1 in {
1735       def _IDXEN  : MUBUF_vi <op, (outs regClass:$vdata),
1736                            (ins SReg_128:$srsrc, VGPR_32:$vaddr,
1737                            mbuf_offset:$offset, SCSrc_32:$soffset, glc:$glc,
1738                            slc:$slc, tfe:$tfe),
1739                            asm#" $vdata, $vaddr, $srsrc, $soffset idxen"#"$offset"#"$glc"#"$slc"#"$tfe", []>;
1740     }
1741
1742     let offen = 1, idxen = 1 in {
1743       def _BOTHEN : MUBUF_vi <op, (outs regClass:$vdata),
1744                            (ins SReg_128:$srsrc, VReg_64:$vaddr,
1745                            SCSrc_32:$soffset, glc:$glc, slc:$slc, tfe:$tfe),
1746                            asm#" $vdata, $vaddr, $srsrc, $soffset, idxen offen"#"$glc"#"$slc"#"$tfe", []>;
1747     }
1748   }
1749 }
1750
1751 multiclass MUBUF_Store_Helper <bits<7> op, string name, RegisterClass vdataClass,
1752                           ValueType store_vt, SDPatternOperator st> {
1753
1754   let addr64 = 0 in {
1755
1756     def "" : MUBUF_si <
1757       op, (outs),
1758       (ins vdataClass:$vdata, SReg_128:$srsrc, VGPR_32:$vaddr, SCSrc_32:$soffset,
1759            mbuf_offset:$offset, offen:$offen, idxen:$idxen, glc:$glc, slc:$slc,
1760            tfe:$tfe),
1761       name#" $vdata, $vaddr, $srsrc, $soffset"#"$offen"#"$idxen"#"$offset"#
1762            "$glc"#"$slc"#"$tfe",
1763       []
1764     >;
1765
1766     let offen = 0, idxen = 0, vaddr = 0 in {
1767       def _OFFSET : MUBUF_si <
1768         op, (outs),
1769         (ins vdataClass:$vdata, SReg_128:$srsrc, mbuf_offset:$offset,
1770               SCSrc_32:$soffset, glc:$glc, slc:$slc, tfe:$tfe),
1771         name#" $vdata, $srsrc, $soffset"#"$offset"#"$glc"#"$slc"#"$tfe",
1772         [(st store_vt:$vdata, (MUBUFOffset v4i32:$srsrc, i32:$soffset,
1773                                            i16:$offset, i1:$glc, i1:$slc,
1774                                            i1:$tfe))]
1775       >, MUBUFAddr64Table<0>;
1776     } // offen = 0, idxen = 0, vaddr = 0
1777
1778     let offen = 1, idxen = 0  in {
1779       def _OFFEN  : MUBUF_si <
1780         op, (outs),
1781         (ins vdataClass:$vdata, SReg_128:$srsrc, VGPR_32:$vaddr, SCSrc_32:$soffset,
1782              mbuf_offset:$offset, glc:$glc, slc:$slc, tfe:$tfe),
1783         name#" $vdata, $vaddr, $srsrc, $soffset offen"#"$offset"#
1784             "$glc"#"$slc"#"$tfe",
1785         []
1786       >;
1787     } // end offen = 1, idxen = 0
1788
1789   } // End addr64 = 0
1790
1791   def _ADDR64 : MUBUF_si <
1792     op, (outs),
1793     (ins vdataClass:$vdata, SReg_128:$srsrc, VReg_64:$vaddr, mbuf_offset:$offset),
1794     name#" $vdata, $vaddr, $srsrc, 0 addr64"#"$offset",
1795     [(st store_vt:$vdata,
1796      (MUBUFAddr64 v4i32:$srsrc, i64:$vaddr, i16:$offset))]>, MUBUFAddr64Table<1>
1797      {
1798
1799       let mayLoad = 0;
1800       let mayStore = 1;
1801
1802       // Encoding
1803       let offen = 0;
1804       let idxen = 0;
1805       let glc = 0;
1806       let addr64 = 1;
1807       let slc = 0;
1808       let tfe = 0;
1809       let soffset = 128; // ZERO
1810    }
1811 }
1812
1813 class FLAT_Load_Helper <bits<7> op, string asm, RegisterClass regClass> :
1814       FLAT <op, (outs regClass:$data),
1815                 (ins VReg_64:$addr),
1816             asm#" $data, $addr, [M0, FLAT_SCRATCH]", []> {
1817   let glc = 0;
1818   let slc = 0;
1819   let tfe = 0;
1820   let mayLoad = 1;
1821 }
1822
1823 class FLAT_Store_Helper <bits<7> op, string name, RegisterClass vdataClass> :
1824       FLAT <op, (outs), (ins vdataClass:$data, VReg_64:$addr),
1825           name#" $data, $addr, [M0, FLAT_SCRATCH]",
1826          []> {
1827
1828   let mayLoad = 0;
1829   let mayStore = 1;
1830
1831   // Encoding
1832   let glc = 0;
1833   let slc = 0;
1834   let tfe = 0;
1835 }
1836
1837 class MIMG_Mask <string op, int channels> {
1838   string Op = op;
1839   int Channels = channels;
1840 }
1841
1842 class MIMG_NoSampler_Helper <bits<7> op, string asm,
1843                              RegisterClass dst_rc,
1844                              RegisterClass src_rc> : MIMG <
1845   op,
1846   (outs dst_rc:$vdata),
1847   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
1848        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
1849        SReg_256:$srsrc),
1850   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
1851      #" $tfe, $lwe, $slc, $vaddr, $srsrc",
1852   []> {
1853   let SSAMP = 0;
1854   let mayLoad = 1;
1855   let mayStore = 0;
1856   let hasPostISelHook = 1;
1857 }
1858
1859 multiclass MIMG_NoSampler_Src_Helper <bits<7> op, string asm,
1860                                       RegisterClass dst_rc,
1861                                       int channels> {
1862   def _V1 : MIMG_NoSampler_Helper <op, asm, dst_rc, VGPR_32>,
1863             MIMG_Mask<asm#"_V1", channels>;
1864   def _V2 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_64>,
1865             MIMG_Mask<asm#"_V2", channels>;
1866   def _V4 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_128>,
1867             MIMG_Mask<asm#"_V4", channels>;
1868 }
1869
1870 multiclass MIMG_NoSampler <bits<7> op, string asm> {
1871   defm _V1 : MIMG_NoSampler_Src_Helper <op, asm, VGPR_32, 1>;
1872   defm _V2 : MIMG_NoSampler_Src_Helper <op, asm, VReg_64, 2>;
1873   defm _V3 : MIMG_NoSampler_Src_Helper <op, asm, VReg_96, 3>;
1874   defm _V4 : MIMG_NoSampler_Src_Helper <op, asm, VReg_128, 4>;
1875 }
1876
1877 class MIMG_Sampler_Helper <bits<7> op, string asm,
1878                            RegisterClass dst_rc,
1879                            RegisterClass src_rc> : MIMG <
1880   op,
1881   (outs dst_rc:$vdata),
1882   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
1883        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
1884        SReg_256:$srsrc, SReg_128:$ssamp),
1885   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
1886      #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
1887   []> {
1888   let mayLoad = 1;
1889   let mayStore = 0;
1890   let hasPostISelHook = 1;
1891 }
1892
1893 multiclass MIMG_Sampler_Src_Helper <bits<7> op, string asm,
1894                                     RegisterClass dst_rc,
1895                                     int channels> {
1896   def _V1 : MIMG_Sampler_Helper <op, asm, dst_rc, VGPR_32>,
1897             MIMG_Mask<asm#"_V1", channels>;
1898   def _V2 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_64>,
1899             MIMG_Mask<asm#"_V2", channels>;
1900   def _V4 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_128>,
1901             MIMG_Mask<asm#"_V4", channels>;
1902   def _V8 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_256>,
1903             MIMG_Mask<asm#"_V8", channels>;
1904   def _V16 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_512>,
1905             MIMG_Mask<asm#"_V16", channels>;
1906 }
1907
1908 multiclass MIMG_Sampler <bits<7> op, string asm> {
1909   defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VGPR_32, 1>;
1910   defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2>;
1911   defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3>;
1912   defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4>;
1913 }
1914
1915 class MIMG_Gather_Helper <bits<7> op, string asm,
1916                           RegisterClass dst_rc,
1917                           RegisterClass src_rc> : MIMG <
1918   op,
1919   (outs dst_rc:$vdata),
1920   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
1921        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
1922        SReg_256:$srsrc, SReg_128:$ssamp),
1923   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
1924      #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
1925   []> {
1926   let mayLoad = 1;
1927   let mayStore = 0;
1928
1929   // DMASK was repurposed for GATHER4. 4 components are always
1930   // returned and DMASK works like a swizzle - it selects
1931   // the component to fetch. The only useful DMASK values are
1932   // 1=red, 2=green, 4=blue, 8=alpha. (e.g. 1 returns
1933   // (red,red,red,red) etc.) The ISA document doesn't mention
1934   // this.
1935   // Therefore, disable all code which updates DMASK by setting these two:
1936   let MIMG = 0;
1937   let hasPostISelHook = 0;
1938 }
1939
1940 multiclass MIMG_Gather_Src_Helper <bits<7> op, string asm,
1941                                     RegisterClass dst_rc,
1942                                     int channels> {
1943   def _V1 : MIMG_Gather_Helper <op, asm, dst_rc, VGPR_32>,
1944             MIMG_Mask<asm#"_V1", channels>;
1945   def _V2 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_64>,
1946             MIMG_Mask<asm#"_V2", channels>;
1947   def _V4 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_128>,
1948             MIMG_Mask<asm#"_V4", channels>;
1949   def _V8 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_256>,
1950             MIMG_Mask<asm#"_V8", channels>;
1951   def _V16 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_512>,
1952             MIMG_Mask<asm#"_V16", channels>;
1953 }
1954
1955 multiclass MIMG_Gather <bits<7> op, string asm> {
1956   defm _V1 : MIMG_Gather_Src_Helper<op, asm, VGPR_32, 1>;
1957   defm _V2 : MIMG_Gather_Src_Helper<op, asm, VReg_64, 2>;
1958   defm _V3 : MIMG_Gather_Src_Helper<op, asm, VReg_96, 3>;
1959   defm _V4 : MIMG_Gather_Src_Helper<op, asm, VReg_128, 4>;
1960 }
1961
1962 //===----------------------------------------------------------------------===//
1963 // Vector instruction mappings
1964 //===----------------------------------------------------------------------===//
1965
1966 // Maps an opcode in e32 form to its e64 equivalent
1967 def getVOPe64 : InstrMapping {
1968   let FilterClass = "VOP";
1969   let RowFields = ["OpName"];
1970   let ColFields = ["Size"];
1971   let KeyCol = ["4"];
1972   let ValueCols = [["8"]];
1973 }
1974
1975 // Maps an opcode in e64 form to its e32 equivalent
1976 def getVOPe32 : InstrMapping {
1977   let FilterClass = "VOP";
1978   let RowFields = ["OpName"];
1979   let ColFields = ["Size"];
1980   let KeyCol = ["8"];
1981   let ValueCols = [["4"]];
1982 }
1983
1984 // Maps an original opcode to its commuted version
1985 def getCommuteRev : InstrMapping {
1986   let FilterClass = "VOP2_REV";
1987   let RowFields = ["RevOp"];
1988   let ColFields = ["IsOrig"];
1989   let KeyCol = ["1"];
1990   let ValueCols = [["0"]];
1991 }
1992
1993 def getMaskedMIMGOp : InstrMapping {
1994   let FilterClass = "MIMG_Mask";
1995   let RowFields = ["Op"];
1996   let ColFields = ["Channels"];
1997   let KeyCol = ["4"];
1998   let ValueCols = [["1"], ["2"], ["3"] ];
1999 }
2000
2001 // Maps an commuted opcode to its original version
2002 def getCommuteOrig : InstrMapping {
2003   let FilterClass = "VOP2_REV";
2004   let RowFields = ["RevOp"];
2005   let ColFields = ["IsOrig"];
2006   let KeyCol = ["0"];
2007   let ValueCols = [["1"]];
2008 }
2009
2010 def getMCOpcodeGen : InstrMapping {
2011   let FilterClass = "SIMCInstr";
2012   let RowFields = ["PseudoInstr"];
2013   let ColFields = ["Subtarget"];
2014   let KeyCol = [!cast<string>(SISubtarget.NONE)];
2015   let ValueCols = [[!cast<string>(SISubtarget.SI)],[!cast<string>(SISubtarget.VI)]];
2016 }
2017
2018 def getAddr64Inst : InstrMapping {
2019   let FilterClass = "MUBUFAddr64Table";
2020   let RowFields = ["OpName"];
2021   let ColFields = ["IsAddr64"];
2022   let KeyCol = ["0"];
2023   let ValueCols = [["1"]];
2024 }
2025
2026 // Maps an atomic opcode to its version with a return value.
2027 def getAtomicRetOp : InstrMapping {
2028   let FilterClass = "AtomicNoRet";
2029   let RowFields = ["NoRetOp"];
2030   let ColFields = ["IsRet"];
2031   let KeyCol = ["0"];
2032   let ValueCols = [["1"]];
2033 }
2034
2035 // Maps an atomic opcode to its returnless version.
2036 def getAtomicNoRetOp : InstrMapping {
2037   let FilterClass = "AtomicNoRet";
2038   let RowFields = ["NoRetOp"];
2039   let ColFields = ["IsRet"];
2040   let KeyCol = ["1"];
2041   let ValueCols = [["0"]];
2042 }
2043
2044 include "SIInstructions.td"
2045 include "CIInstructions.td"
2046 include "VIInstructions.td"