R600/SI: Refactor VOP2 instruction defs
[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 }
13
14 class vop1 <bits<8> si> : vop {
15   field bits<8> SI  = si;
16
17   field bits<9> SI3 = {1, 1, si{6-0}};
18 }
19
20 class vop2 <bits<6> si> : vop {
21   field bits<6> SI = si;
22
23   field bits<9> SI3 = {1, 0, 0, si{5-0}};
24 }
25
26 // Execpt for the NONE field, this must be kept in sync with the SISubtarget enum
27 // in AMDGPUMCInstLower.h
28 def SISubtarget {
29   int NONE = -1;
30   int SI = 0;
31 }
32
33 //===----------------------------------------------------------------------===//
34 // SI DAG Nodes
35 //===----------------------------------------------------------------------===//
36
37 def SIload_constant : SDNode<"AMDGPUISD::LOAD_CONSTANT",
38   SDTypeProfile<1, 2, [SDTCisVT<0, f32>, SDTCisVT<1, v4i32>, SDTCisVT<2, i32>]>,
39                       [SDNPMayLoad, SDNPMemOperand]
40 >;
41
42 def SItbuffer_store : SDNode<"AMDGPUISD::TBUFFER_STORE_FORMAT",
43   SDTypeProfile<0, 13,
44     [SDTCisVT<0, v4i32>,   // rsrc(SGPR)
45      SDTCisVT<1, iAny>,   // vdata(VGPR)
46      SDTCisVT<2, i32>,    // num_channels(imm)
47      SDTCisVT<3, i32>,    // vaddr(VGPR)
48      SDTCisVT<4, i32>,    // soffset(SGPR)
49      SDTCisVT<5, i32>,    // inst_offset(imm)
50      SDTCisVT<6, i32>,    // dfmt(imm)
51      SDTCisVT<7, i32>,    // nfmt(imm)
52      SDTCisVT<8, i32>,    // offen(imm)
53      SDTCisVT<9, i32>,    // idxen(imm)
54      SDTCisVT<10, i32>,   // glc(imm)
55      SDTCisVT<11, i32>,   // slc(imm)
56      SDTCisVT<12, i32>    // tfe(imm)
57     ]>,
58   [SDNPMayStore, SDNPMemOperand, SDNPHasChain]
59 >;
60
61 def SIload_input : SDNode<"AMDGPUISD::LOAD_INPUT",
62   SDTypeProfile<1, 3, [SDTCisVT<0, v4f32>, SDTCisVT<1, v4i32>, SDTCisVT<2, i16>,
63                        SDTCisVT<3, i32>]>
64 >;
65
66 class SDSample<string opcode> : SDNode <opcode,
67   SDTypeProfile<1, 4, [SDTCisVT<0, v4f32>, SDTCisVT<2, v32i8>,
68                        SDTCisVT<3, v4i32>, SDTCisVT<4, i32>]>
69 >;
70
71 def SIsample : SDSample<"AMDGPUISD::SAMPLE">;
72 def SIsampleb : SDSample<"AMDGPUISD::SAMPLEB">;
73 def SIsampled : SDSample<"AMDGPUISD::SAMPLED">;
74 def SIsamplel : SDSample<"AMDGPUISD::SAMPLEL">;
75
76 def SIconstdata_ptr : SDNode<
77   "AMDGPUISD::CONST_DATA_PTR", SDTypeProfile <1, 0, [SDTCisVT<0, i64>]>
78 >;
79
80 // Transformation function, extract the lower 32bit of a 64bit immediate
81 def LO32 : SDNodeXForm<imm, [{
82   return CurDAG->getTargetConstant(N->getZExtValue() & 0xffffffff, MVT::i32);
83 }]>;
84
85 def LO32f : SDNodeXForm<fpimm, [{
86   APInt V = N->getValueAPF().bitcastToAPInt().trunc(32);
87   return CurDAG->getTargetConstantFP(APFloat(APFloat::IEEEsingle, V), MVT::f32);
88 }]>;
89
90 // Transformation function, extract the upper 32bit of a 64bit immediate
91 def HI32 : SDNodeXForm<imm, [{
92   return CurDAG->getTargetConstant(N->getZExtValue() >> 32, MVT::i32);
93 }]>;
94
95 def HI32f : SDNodeXForm<fpimm, [{
96   APInt V = N->getValueAPF().bitcastToAPInt().lshr(32).trunc(32);
97   return CurDAG->getTargetConstantFP(APFloat(APFloat::IEEEsingle, V), MVT::f32);
98 }]>;
99
100 def IMM8bitDWORD : PatLeaf <(imm),
101   [{return (N->getZExtValue() & ~0x3FC) == 0;}]
102 >;
103
104 def as_dword_i32imm : SDNodeXForm<imm, [{
105   return CurDAG->getTargetConstant(N->getZExtValue() >> 2, MVT::i32);
106 }]>;
107
108 def as_i1imm : SDNodeXForm<imm, [{
109   return CurDAG->getTargetConstant(N->getZExtValue(), MVT::i1);
110 }]>;
111
112 def as_i8imm : SDNodeXForm<imm, [{
113   return CurDAG->getTargetConstant(N->getZExtValue(), MVT::i8);
114 }]>;
115
116 def as_i16imm : SDNodeXForm<imm, [{
117   return CurDAG->getTargetConstant(N->getSExtValue(), MVT::i16);
118 }]>;
119
120 def as_i32imm: SDNodeXForm<imm, [{
121   return CurDAG->getTargetConstant(N->getSExtValue(), MVT::i32);
122 }]>;
123
124 def IMM8bit : PatLeaf <(imm),
125   [{return isUInt<8>(N->getZExtValue());}]
126 >;
127
128 def IMM12bit : PatLeaf <(imm),
129   [{return isUInt<12>(N->getZExtValue());}]
130 >;
131
132 def IMM16bit : PatLeaf <(imm),
133   [{return isUInt<16>(N->getZExtValue());}]
134 >;
135
136 def IMM32bit : PatLeaf <(imm),
137   [{return isUInt<32>(N->getZExtValue());}]
138 >;
139
140 def mubuf_vaddr_offset : PatFrag<
141   (ops node:$ptr, node:$offset, node:$imm_offset),
142   (add (add node:$ptr, node:$offset), node:$imm_offset)
143 >;
144
145 class InlineImm <ValueType vt> : PatLeaf <(vt imm), [{
146   return isInlineImmediate(N);
147 }]>;
148
149 class SGPRImm <dag frag> : PatLeaf<frag, [{
150   if (TM.getSubtarget<AMDGPUSubtarget>().getGeneration() <
151       AMDGPUSubtarget::SOUTHERN_ISLANDS) {
152     return false;
153   }
154   const SIRegisterInfo *SIRI =
155                        static_cast<const SIRegisterInfo*>(TM.getSubtargetImpl()->getRegisterInfo());
156   for (SDNode::use_iterator U = N->use_begin(), E = SDNode::use_end();
157                                                 U != E; ++U) {
158     if (SIRI->isSGPRClass(getOperandRegClass(*U, U.getOperandNo()))) {
159       return true;
160     }
161   }
162   return false;
163 }]>;
164
165 //===----------------------------------------------------------------------===//
166 // Custom Operands
167 //===----------------------------------------------------------------------===//
168
169 def FRAMEri32 : Operand<iPTR> {
170   let MIOperandInfo = (ops i32:$ptr, i32imm:$index);
171 }
172
173 def sopp_brtarget : Operand<OtherVT> {
174   let EncoderMethod = "getSOPPBrEncoding";
175   let OperandType = "OPERAND_PCREL";
176 }
177
178 include "SIInstrFormats.td"
179
180 let OperandType = "OPERAND_IMMEDIATE" in {
181
182 def offen : Operand<i1> {
183   let PrintMethod = "printOffen";
184 }
185 def idxen : Operand<i1> {
186   let PrintMethod = "printIdxen";
187 }
188 def addr64 : Operand<i1> {
189   let PrintMethod = "printAddr64";
190 }
191 def mbuf_offset : Operand<i16> {
192   let PrintMethod = "printMBUFOffset";
193 }
194 def glc : Operand <i1> {
195   let PrintMethod = "printGLC";
196 }
197 def slc : Operand <i1> {
198   let PrintMethod = "printSLC";
199 }
200 def tfe : Operand <i1> {
201   let PrintMethod = "printTFE";
202 }
203
204 def omod : Operand <i32> {
205   let PrintMethod = "printOModSI";
206 }
207
208 def ClampMod : Operand <i1> {
209   let PrintMethod = "printClampSI";
210 }
211
212 } // End OperandType = "OPERAND_IMMEDIATE"
213
214 //===----------------------------------------------------------------------===//
215 // Complex patterns
216 //===----------------------------------------------------------------------===//
217
218 def DS1Addr1Offset : ComplexPattern<i32, 2, "SelectDS1Addr1Offset">;
219 def DS64Bit4ByteAligned : ComplexPattern<i32, 3, "SelectDS64Bit4ByteAligned">;
220
221 def MUBUFAddr32 : ComplexPattern<i64, 9, "SelectMUBUFAddr32">;
222 def MUBUFAddr64 : ComplexPattern<i64, 3, "SelectMUBUFAddr64">;
223 def MUBUFAddr64Atomic : ComplexPattern<i64, 4, "SelectMUBUFAddr64">;
224 def MUBUFScratch : ComplexPattern<i64, 4, "SelectMUBUFScratch">;
225 def MUBUFOffset : ComplexPattern<i64, 6, "SelectMUBUFOffset">;
226 def MUBUFOffsetAtomic : ComplexPattern<i64, 4, "SelectMUBUFOffset">;
227
228 def VOP3Mods0 : ComplexPattern<untyped, 4, "SelectVOP3Mods0">;
229 def VOP3Mods  : ComplexPattern<untyped, 2, "SelectVOP3Mods">;
230
231 //===----------------------------------------------------------------------===//
232 // SI assembler operands
233 //===----------------------------------------------------------------------===//
234
235 def SIOperand {
236   int ZERO = 0x80;
237   int VCC = 0x6A;
238   int FLAT_SCR = 0x68;
239 }
240
241 def SRCMODS {
242   int NONE = 0;
243 }
244
245 def DSTCLAMP {
246   int NONE = 0;
247 }
248
249 def DSTOMOD {
250   int NONE = 0;
251 }
252
253 //===----------------------------------------------------------------------===//
254 //
255 // SI Instruction multiclass helpers.
256 //
257 // Instructions with _32 take 32-bit operands.
258 // Instructions with _64 take 64-bit operands.
259 //
260 // VOP_* instructions can use either a 32-bit or 64-bit encoding.  The 32-bit
261 // encoding is the standard encoding, but instruction that make use of
262 // any of the instruction modifiers must use the 64-bit encoding.
263 //
264 // Instructions with _e32 use the 32-bit encoding.
265 // Instructions with _e64 use the 64-bit encoding.
266 //
267 //===----------------------------------------------------------------------===//
268
269 class SIMCInstr <string pseudo, int subtarget> {
270   string PseudoInstr = pseudo;
271   int Subtarget = subtarget;
272 }
273
274 //===----------------------------------------------------------------------===//
275 // EXP classes
276 //===----------------------------------------------------------------------===//
277
278 class EXPCommon : InstSI<
279   (outs),
280   (ins i32imm:$en, i32imm:$tgt, i32imm:$compr, i32imm:$done, i32imm:$vm,
281        VReg_32:$src0, VReg_32:$src1, VReg_32:$src2, VReg_32:$src3),
282   "EXP $en, $tgt, $compr, $done, $vm, $src0, $src1, $src2, $src3",
283   [] > {
284
285   let EXP_CNT = 1;
286   let Uses = [EXEC];
287 }
288
289 multiclass EXP_m {
290
291   let isPseudo = 1 in {
292     def "" : EXPCommon, SIMCInstr <"EXP", SISubtarget.NONE> ;
293   }
294
295   def _si : EXPCommon, SIMCInstr <"EXP", SISubtarget.SI>, EXPe;
296 }
297
298 //===----------------------------------------------------------------------===//
299 // Scalar classes
300 //===----------------------------------------------------------------------===//
301
302 class SOP1_32 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
303   op, (outs SReg_32:$dst), (ins SSrc_32:$src0),
304   opName#" $dst, $src0", pattern
305 >;
306
307 class SOP1_64 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
308   op, (outs SReg_64:$dst), (ins SSrc_64:$src0),
309   opName#" $dst, $src0", pattern
310 >;
311
312 // 64-bit input, 32-bit output.
313 class SOP1_32_64 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
314   op, (outs SReg_32:$dst), (ins SSrc_64:$src0),
315   opName#" $dst, $src0", pattern
316 >;
317
318 class SOP2_32 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
319   op, (outs SReg_32:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
320   opName#" $dst, $src0, $src1", pattern
321 >;
322
323 class SOP2_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
324   op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
325   opName#" $dst, $src0, $src1", pattern
326 >;
327
328 class SOP2_SHIFT_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
329   op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_32:$src1),
330   opName#" $dst, $src0, $src1", pattern
331 >;
332
333
334 class SOPC_Helper <bits<7> op, RegisterClass rc, ValueType vt,
335                     string opName, PatLeaf cond> : SOPC <
336   op, (outs SCCReg:$dst), (ins rc:$src0, rc:$src1),
337   opName#" $dst, $src0, $src1", []>;
338
339 class SOPC_32<bits<7> op, string opName, PatLeaf cond = COND_NULL>
340   : SOPC_Helper<op, SSrc_32, i32, opName, cond>;
341
342 class SOPC_64<bits<7> op, string opName, PatLeaf cond = COND_NULL>
343   : SOPC_Helper<op, SSrc_64, i64, opName, cond>;
344
345 class SOPK_32 <bits<5> op, string opName, list<dag> pattern> : SOPK <
346   op, (outs SReg_32:$dst), (ins i16imm:$src0),
347   opName#" $dst, $src0", pattern
348 >;
349
350 class SOPK_64 <bits<5> op, string opName, list<dag> pattern> : SOPK <
351   op, (outs SReg_64:$dst), (ins i16imm:$src0),
352   opName#" $dst, $src0", pattern
353 >;
354
355 //===----------------------------------------------------------------------===//
356 // SMRD classes
357 //===----------------------------------------------------------------------===//
358
359 class SMRD_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
360   SMRD <outs, ins, "", pattern>,
361   SIMCInstr<opName, SISubtarget.NONE> {
362   let isPseudo = 1;
363 }
364
365 class SMRD_Real_si <bits<5> op, string opName, bit imm, dag outs, dag ins,
366                     string asm> :
367   SMRD <outs, ins, asm, []>,
368   SMRDe <op, imm>,
369   SIMCInstr<opName, SISubtarget.SI>;
370
371 multiclass SMRD_m <bits<5> op, string opName, bit imm, dag outs, dag ins,
372                    string asm, list<dag> pattern> {
373
374   def "" : SMRD_Pseudo <opName, outs, ins, pattern>;
375
376   def _si : SMRD_Real_si <op, opName, imm, outs, ins, asm>;
377
378 }
379
380 multiclass SMRD_Helper <bits<5> op, string opName, RegisterClass baseClass,
381                         RegisterClass dstClass> {
382   defm _IMM : SMRD_m <
383     op, opName#"_IMM", 1, (outs dstClass:$dst),
384     (ins baseClass:$sbase, u32imm:$offset),
385     opName#" $dst, $sbase, $offset", []
386   >;
387
388   defm _SGPR : SMRD_m <
389     op, opName#"_SGPR", 0, (outs dstClass:$dst),
390     (ins baseClass:$sbase, SReg_32:$soff),
391     opName#" $dst, $sbase, $soff", []
392   >;
393 }
394
395 //===----------------------------------------------------------------------===//
396 // Vector ALU classes
397 //===----------------------------------------------------------------------===//
398
399 // This must always be right before the operand being input modified.
400 def InputMods : OperandWithDefaultOps <i32, (ops (i32 0))> {
401   let PrintMethod = "printOperandAndMods";
402 }
403 def InputModsNoDefault : Operand <i32> {
404   let PrintMethod = "printOperandAndMods";
405 }
406
407 class getNumSrcArgs<ValueType Src1, ValueType Src2> {
408   int ret =
409     !if (!eq(Src1.Value, untyped.Value),      1,   // VOP1
410          !if (!eq(Src2.Value, untyped.Value), 2,   // VOP2
411                                               3)); // VOP3
412 }
413
414 // Returns the register class to use for the destination of VOP[123C]
415 // instructions for the given VT.
416 class getVALUDstForVT<ValueType VT> {
417   RegisterClass ret = !if(!eq(VT.Size, 32), VReg_32, VReg_64);
418 }
419
420 // Returns the register class to use for source 0 of VOP[12C]
421 // instructions for the given VT.
422 class getVOPSrc0ForVT<ValueType VT> {
423   RegisterClass ret = !if(!eq(VT.Size, 32), VSrc_32, VSrc_64);
424 }
425
426 // Returns the register class to use for source 1 of VOP[12C] for the
427 // given VT.
428 class getVOPSrc1ForVT<ValueType VT> {
429   RegisterClass ret = !if(!eq(VT.Size, 32), VReg_32, VReg_64);
430 }
431
432 // Returns the register classes for the source arguments of a VOP[12C]
433 // instruction for the given SrcVTs.
434 class getInRC32 <list<ValueType> SrcVT> {
435   list<RegisterClass> ret = [
436     getVOPSrc0ForVT<SrcVT[0]>.ret,
437     getVOPSrc1ForVT<SrcVT[1]>.ret
438   ];
439 }
440
441 // Returns the register class to use for sources of VOP3 instructions for the
442 // given VT.
443 class getVOP3SrcForVT<ValueType VT> {
444   RegisterClass ret = !if(!eq(VT.Size, 32), VCSrc_32, VCSrc_64);
445 }
446
447 // Returns the register classes for the source arguments of a VOP3
448 // instruction for the given SrcVTs.
449 class getInRC64 <list<ValueType> SrcVT> {
450   list<RegisterClass> ret = [
451     getVOP3SrcForVT<SrcVT[0]>.ret,
452     getVOP3SrcForVT<SrcVT[1]>.ret,
453     getVOP3SrcForVT<SrcVT[2]>.ret
454   ];
455 }
456
457 // Returns 1 if the source arguments have modifiers, 0 if they do not.
458 class hasModifiers<ValueType SrcVT> {
459   bit ret = !if(!eq(SrcVT.Value, f32.Value), 1,
460             !if(!eq(SrcVT.Value, f64.Value), 1, 0));
461 }
462
463 // Returns the input arguments for VOP[12C] instructions for the given SrcVT.
464 class getIns32 <RegisterClass Src0RC, RegisterClass Src1RC, int NumSrcArgs> {
465   dag ret = !if(!eq(NumSrcArgs, 1), (ins Src0RC:$src0),               // VOP1
466             !if(!eq(NumSrcArgs, 2), (ins Src0RC:$src0, Src1RC:$src1), // VOP2
467                                     (ins)));
468 }
469
470 // Returns the input arguments for VOP3 instructions for the given SrcVT.
471 class getIns64 <RegisterClass Src0RC, RegisterClass Src1RC,
472                 RegisterClass Src2RC, int NumSrcArgs,
473                 bit HasModifiers> {
474
475   dag ret =
476     !if (!eq(NumSrcArgs, 1),
477       !if (!eq(HasModifiers, 1),
478         // VOP1 with modifiers
479         (ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0,
480              ClampMod:$clamp, omod:$omod)
481       /* else */,
482         // VOP1 without modifiers
483         (ins Src0RC:$src0)
484       /* endif */ ),
485     !if (!eq(NumSrcArgs, 2),
486       !if (!eq(HasModifiers, 1),
487         // VOP 2 with modifiers
488         (ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0,
489              InputModsNoDefault:$src1_modifiers, Src1RC:$src1,
490              ClampMod:$clamp, omod:$omod)
491       /* else */,
492         // VOP2 without modifiers
493         (ins Src0RC:$src0, Src1RC:$src1)
494       /* endif */ )
495     /* NumSrcArgs == 3 */,
496       !if (!eq(HasModifiers, 1),
497         // VOP3 with modifiers
498         (ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0,
499              InputModsNoDefault:$src1_modifiers, Src1RC:$src1,
500              InputModsNoDefault:$src2_modifiers, Src2RC:$src2,
501              ClampMod:$clamp, omod:$omod)
502       /* else */,
503         // VOP3 without modifiers
504         (ins Src0RC:$src0, Src1RC:$src1, Src2RC:$src2)
505       /* endif */ )));
506 }
507
508 // Returns the assembly string for the inputs and outputs of a VOP[12C]
509 // instruction.  This does not add the _e32 suffix, so it can be reused
510 // by getAsm64.
511 class getAsm32 <int NumSrcArgs> {
512   string src1 = ", $src1";
513   string src2 = ", $src2";
514   string ret = " $dst, $src0"#
515                !if(!eq(NumSrcArgs, 1), "", src1)#
516                !if(!eq(NumSrcArgs, 3), src2, "");
517 }
518
519 // Returns the assembly string for the inputs and outputs of a VOP3
520 // instruction.
521 class getAsm64 <int NumSrcArgs, bit HasModifiers> {
522   string src0 = "$src0_modifiers,";
523   string src1 = !if(!eq(NumSrcArgs, 1), "",
524                    !if(!eq(NumSrcArgs, 2), " $src1_modifiers",
525                                            " $src1_modifiers,"));
526   string src2 = !if(!eq(NumSrcArgs, 3), " $src2_modifiers", "");
527   string ret =
528   !if(!eq(HasModifiers, 0),
529       getAsm32<NumSrcArgs>.ret,
530       " $dst, "#src0#src1#src2#"$clamp"#"$omod");
531 }
532
533
534 class VOPProfile <list<ValueType> _ArgVT> {
535
536   field list<ValueType> ArgVT = _ArgVT;
537
538   field ValueType DstVT = ArgVT[0];
539   field ValueType Src0VT = ArgVT[1];
540   field ValueType Src1VT = ArgVT[2];
541   field ValueType Src2VT = ArgVT[3];
542   field RegisterClass DstRC = getVALUDstForVT<DstVT>.ret;
543   field RegisterClass Src0RC32 = getVOPSrc0ForVT<Src0VT>.ret;
544   field RegisterClass Src1RC32 = getVOPSrc1ForVT<Src1VT>.ret;
545   field RegisterClass Src0RC64 = getVOP3SrcForVT<Src0VT>.ret;
546   field RegisterClass Src1RC64 = getVOP3SrcForVT<Src1VT>.ret;
547   field RegisterClass Src2RC64 = getVOP3SrcForVT<Src2VT>.ret;
548
549   field int NumSrcArgs = getNumSrcArgs<Src1VT, Src2VT>.ret;
550   field bit HasModifiers = hasModifiers<Src0VT>.ret;
551
552   field dag Outs = (outs DstRC:$dst);
553
554   field dag Ins32 = getIns32<Src0RC32, Src1RC32, NumSrcArgs>.ret;
555   field dag Ins64 = getIns64<Src0RC64, Src1RC64, Src2RC64, NumSrcArgs,
556                              HasModifiers>.ret;
557
558   field string Asm32 = "_e32"#getAsm32<NumSrcArgs>.ret;
559   field string Asm64 = getAsm64<NumSrcArgs, HasModifiers>.ret;
560 }
561
562 def VOP_F32_F32 : VOPProfile <[f32, f32, untyped, untyped]>;
563 def VOP_F32_F64 : VOPProfile <[f32, f64, untyped, untyped]>;
564 def VOP_F32_I32 : VOPProfile <[f32, i32, untyped, untyped]>;
565 def VOP_F64_F32 : VOPProfile <[f64, f32, untyped, untyped]>;
566 def VOP_F64_F64 : VOPProfile <[f64, f64, untyped, untyped]>;
567 def VOP_F64_I32 : VOPProfile <[f64, i32, untyped, untyped]>;
568 def VOP_I32_F32 : VOPProfile <[i32, f32, untyped, untyped]>;
569 def VOP_I32_F64 : VOPProfile <[i32, f64, untyped, untyped]>;
570 def VOP_I32_I32 : VOPProfile <[i32, i32, untyped, untyped]>;
571
572 def VOP_F32_F32_F32 : VOPProfile <[f32, f32, f32, untyped]>;
573 def VOP_F32_F32_I32 : VOPProfile <[f32, f32, i32, untyped]>;
574 def VOP_F64_F64_F64 : VOPProfile <[f64, f64, f64, untyped]>;
575 def VOP_F64_F64_I32 : VOPProfile <[f64, f64, i32, untyped]>;
576 def VOP_I32_F32_F32 : VOPProfile <[i32, f32, f32, untyped]>;
577 def VOP_I32_I32_I32 : VOPProfile <[i32, i32, i32, untyped]>;
578 def VOP_I32_I32_I32_VCC : VOPProfile <[i32, i32, i32, untyped]> {
579   let Src0RC32 = VCSrc_32;
580 }
581 def VOP_I64_I64_I32 : VOPProfile <[i64, i64, i32, untyped]>;
582 def VOP_I64_I64_I64 : VOPProfile <[i64, i64, i64, untyped]>;
583
584 def VOP_F32_F32_F32_F32 : VOPProfile <[f32, f32, f32, f32]>;
585 def VOP_F64_F64_F64_F64 : VOPProfile <[f64, f64, f64, f64]>;
586 def VOP_I32_I32_I32_I32 : VOPProfile <[i32, i32, i32, i32]>;
587 def VOP_I64_I32_I32_I64 : VOPProfile <[i64, i32, i32, i64]>;
588
589
590 class VOP <string opName> {
591   string OpName = opName;
592 }
593
594 class VOP2_REV <string revOp, bit isOrig> {
595   string RevOp = revOp;
596   bit IsOrig = isOrig;
597 }
598
599 class AtomicNoRet <string noRetOp, bit isRet> {
600   string NoRetOp = noRetOp;
601   bit IsRet = isRet;
602 }
603
604 class VOP1_Pseudo <dag outs, dag ins, list<dag> pattern, string opName> :
605   VOP1Common <outs, ins, "", pattern>,
606   SIMCInstr<opName, SISubtarget.NONE> {
607   let isPseudo = 1;
608 }
609
610 multiclass VOP1_m <vop1 op, dag outs, dag ins, string asm, list<dag> pattern,
611                    string opName> {
612   def "" : VOP1_Pseudo <outs, ins, pattern, opName>;
613
614   def _si : VOP1<op.SI, outs, ins, asm, []>,
615             SIMCInstr <opName, SISubtarget.SI>;
616 }
617
618 class VOP3DisableFields <bit HasSrc1, bit HasSrc2, bit HasModifiers> {
619
620   bits<2> src0_modifiers = !if(HasModifiers, ?, 0);
621   bits<2> src1_modifiers = !if(HasModifiers, !if(HasSrc1, ?, 0), 0);
622   bits<2> src2_modifiers = !if(HasModifiers, !if(HasSrc2, ? ,0) ,0);
623   bits<2> omod = !if(HasModifiers, ?, 0);
624   bits<1> clamp = !if(HasModifiers, ?, 0);
625   bits<9> src1 = !if(HasSrc1, ?, 0);
626   bits<9> src2 = !if(HasSrc2, ?, 0);
627 }
628
629 class VOP3_Pseudo <dag outs, dag ins, list<dag> pattern, string opName> :
630   VOP3Common <outs, ins, "", pattern>,
631   VOP <opName>,
632   SIMCInstr<opName, SISubtarget.NONE> {
633   let isPseudo = 1;
634 }
635
636 class VOP3_Real_si <bits<9> op, dag outs, dag ins, string asm, string opName> :
637   VOP3 <op, outs, ins, asm, []>,
638   SIMCInstr<opName, SISubtarget.SI>;
639
640 multiclass VOP3_m <bits<9> op, dag outs, dag ins, string asm, list<dag> pattern,
641                    string opName, int NumSrcArgs, bit HasMods = 1> {
642
643   def "" : VOP3_Pseudo <outs, ins, pattern, opName>;
644
645   def _si : VOP3_Real_si <op, outs, ins, asm, opName>,
646             VOP3DisableFields<!if(!eq(NumSrcArgs, 1), 0, 1),
647                               !if(!eq(NumSrcArgs, 2), 0, 1),
648                               HasMods>;
649
650 }
651
652 multiclass VOP3_1_m <vop op, dag outs, dag ins, string asm,
653                      list<dag> pattern, string opName, bit HasMods = 1> {
654
655   def "" : VOP3_Pseudo <outs, ins, pattern, opName>;
656
657   def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>,
658             VOP3DisableFields<0, 0, HasMods>;
659 }
660
661 multiclass VOP3_2_m <vop op, dag outs, dag ins, string asm,
662                      list<dag> pattern, string opName, string revOp,
663                      bit HasMods = 1, bit UseFullOp = 0> {
664
665   def "" : VOP3_Pseudo <outs, ins, pattern, opName>,
666            VOP2_REV<revOp#"_e64", !eq(revOp, opName)>;
667
668   def _si : VOP3_Real_si <op.SI3,
669               outs, ins, asm, opName>,
670             VOP2_REV<revOp#"_e64_si", !eq(revOp, opName)>,
671             VOP3DisableFields<1, 0, HasMods>;
672 }
673
674 multiclass VOP3b_2_m <bits<9> op, dag outs, dag ins, string asm,
675                       list<dag> pattern, string opName, string revOp,
676                       bit HasMods = 1, bit UseFullOp = 0> {
677   def "" : VOP3_Pseudo <outs, ins, pattern, opName>,
678            VOP2_REV<revOp#"_e64", !eq(revOp, opName)>;
679
680   // The VOP2 variant puts the carry out into VCC, the VOP3 variant
681   // can write it into any SGPR. We currently don't use the carry out,
682   // so for now hardcode it to VCC as well.
683   let sdst = SIOperand.VCC, Defs = [VCC] in {
684     def _si : VOP3b <op, outs, ins, asm, pattern>,
685               VOP3DisableFields<1, 0, HasMods>,
686               SIMCInstr<opName, SISubtarget.SI>,
687               VOP2_REV<revOp#"_e64_si", !eq(revOp, opName)>;
688   } // End sdst = SIOperand.VCC, Defs = [VCC]
689 }
690
691 multiclass VOP3_C_m <bits<8> op, dag outs, dag ins, string asm,
692                      list<dag> pattern, string opName,
693                      bit HasMods, bit defExec> {
694
695   def "" : VOP3_Pseudo <outs, ins, pattern, opName>;
696
697     def _si : VOP3_Real_si <
698                 {0, op{7}, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
699                 outs, ins, asm, opName>,
700               VOP3DisableFields<1, 0, HasMods> {
701   let Defs = !if(defExec, [EXEC], []);
702   }
703 }
704
705 multiclass VOP1_Helper <vop1 op, string opName, dag outs,
706                         dag ins32, string asm32, list<dag> pat32,
707                         dag ins64, string asm64, list<dag> pat64,
708                         bit HasMods> {
709
710   def _e32 : VOP1 <op.SI, outs, ins32, opName#asm32, pat32>, VOP<opName>;
711
712   defm _e64 : VOP3_1_m <op, outs, ins64, opName#"_e64"#asm64, pat64, opName, HasMods>;
713 }
714
715 multiclass VOP1Inst <vop1 op, string opName, VOPProfile P,
716                      SDPatternOperator node = null_frag> : VOP1_Helper <
717   op, opName, P.Outs,
718   P.Ins32, P.Asm32, [],
719   P.Ins64, P.Asm64,
720   !if(P.HasModifiers,
721       [(set P.DstVT:$dst, (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0,
722                                 i32:$src0_modifiers, i1:$clamp, i32:$omod))))],
723       [(set P.DstVT:$dst, (node P.Src0VT:$src0))]),
724   P.HasModifiers
725 >;
726
727 class VOP2_e32 <bits<6> op, string opName, dag outs, dag ins, string asm,
728                 list<dag> pattern, string revOp> :
729   VOP2 <op, outs, ins, opName#asm, pattern>,
730   VOP <opName>,
731   VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
732
733 multiclass VOP2_Helper <vop2 op, string opName, dag outs,
734                         dag ins32, string asm32, list<dag> pat32,
735                         dag ins64, string asm64, list<dag> pat64,
736                         string revOp, bit HasMods> {
737   def _e32 : VOP2_e32 <op.SI, opName, outs, ins32, asm32, pat32, revOp>;
738
739   defm _e64 : VOP3_2_m <op,
740     outs, ins64, opName#"_e64"#asm64, pat64, opName, revOp, HasMods
741   >;
742 }
743
744 multiclass VOP2Inst <vop2 op, string opName, VOPProfile P,
745                      SDPatternOperator node = null_frag,
746                      string revOp = opName> : VOP2_Helper <
747   op, opName, P.Outs,
748   P.Ins32, P.Asm32, [],
749   P.Ins64, P.Asm64,
750   !if(P.HasModifiers,
751       [(set P.DstVT:$dst,
752            (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
753                                       i1:$clamp, i32:$omod)),
754                  (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
755       [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1))]),
756   revOp, P.HasModifiers
757 >;
758
759 multiclass VOP2b_Helper <bits<6> op, string opName, dag outs,
760                          dag ins32, string asm32, list<dag> pat32,
761                          dag ins64, string asm64, list<dag> pat64,
762                          string revOp, bit HasMods> {
763
764   def _e32 : VOP2_e32 <op, opName, outs, ins32, asm32, pat32, revOp>;
765
766   defm _e64 : VOP3b_2_m <
767     {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
768     outs, ins64, opName#"_e64"#asm64, pat64, opName, revOp, HasMods
769   >;
770 }
771
772 multiclass VOP2bInst <bits<6> op, string opName, VOPProfile P,
773                       SDPatternOperator node = null_frag,
774                       string revOp = opName> : VOP2b_Helper <
775   op, opName, P.Outs,
776   P.Ins32, P.Asm32, [],
777   P.Ins64, P.Asm64,
778   !if(P.HasModifiers,
779       [(set P.DstVT:$dst,
780            (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
781                                       i1:$clamp, i32:$omod)),
782                  (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
783       [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1))]),
784   revOp, P.HasModifiers
785 >;
786
787 multiclass VOPC_Helper <bits<8> op, string opName,
788                         dag ins32, string asm32, list<dag> pat32,
789                         dag out64, dag ins64, string asm64, list<dag> pat64,
790                         bit HasMods, bit DefExec> {
791   def _e32 : VOPC <op, ins32, opName#asm32, pat32>, VOP <opName> {
792     let Defs = !if(DefExec, [EXEC], []);
793   }
794
795   defm _e64 : VOP3_C_m <op, out64, ins64, opName#"_e64"#asm64, pat64, opName,
796                         HasMods, DefExec>;
797 }
798
799 multiclass VOPCInst <bits<8> op, string opName,
800                      VOPProfile P, PatLeaf cond = COND_NULL,
801                      bit DefExec = 0> : VOPC_Helper <
802   op, opName,
803   P.Ins32, P.Asm32, [],
804   (outs SReg_64:$dst), P.Ins64, P.Asm64,
805   !if(P.HasModifiers,
806       [(set i1:$dst,
807           (setcc (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
808                                       i1:$clamp, i32:$omod)),
809                  (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)),
810                  cond))],
811       [(set i1:$dst, (setcc P.Src0VT:$src0, P.Src1VT:$src1, cond))]),
812   P.HasModifiers, DefExec
813 >;
814
815 multiclass VOPC_F32 <bits<8> op, string opName, PatLeaf cond = COND_NULL> :
816   VOPCInst <op, opName, VOP_F32_F32_F32, cond>;
817
818 multiclass VOPC_F64 <bits<8> op, string opName, PatLeaf cond = COND_NULL> :
819   VOPCInst <op, opName, VOP_F64_F64_F64, cond>;
820
821 multiclass VOPC_I32 <bits<8> op, string opName, PatLeaf cond = COND_NULL> :
822   VOPCInst <op, opName, VOP_I32_I32_I32, cond>;
823
824 multiclass VOPC_I64 <bits<8> op, string opName, PatLeaf cond = COND_NULL> :
825   VOPCInst <op, opName, VOP_I64_I64_I64, cond>;
826
827
828 multiclass VOPCX <bits<8> op, string opName, VOPProfile P,
829                   PatLeaf cond = COND_NULL>
830   : VOPCInst <op, opName, P, cond, 1>;
831
832 multiclass VOPCX_F32 <bits<8> op, string opName, PatLeaf cond = COND_NULL> :
833   VOPCX <op, opName, VOP_F32_F32_F32, cond>;
834
835 multiclass VOPCX_F64 <bits<8> op, string opName, PatLeaf cond = COND_NULL> :
836   VOPCX <op, opName, VOP_F64_F64_F64, cond>;
837
838 multiclass VOPCX_I32 <bits<8> op, string opName, PatLeaf cond = COND_NULL> :
839   VOPCX <op, opName, VOP_I32_I32_I32, cond>;
840
841 multiclass VOPCX_I64 <bits<8> op, string opName, PatLeaf cond = COND_NULL> :
842   VOPCX <op, opName, VOP_I64_I64_I64, cond>;
843
844 multiclass VOP3_Helper <bits<9> op, string opName, dag outs, dag ins, string asm,
845                         list<dag> pat, int NumSrcArgs, bit HasMods> : VOP3_m <
846     op, outs, ins, opName#asm, pat, opName, NumSrcArgs, HasMods
847 >;
848
849 multiclass VOP3Inst <bits<9> op, string opName, VOPProfile P,
850                      SDPatternOperator node = null_frag> : VOP3_Helper <
851   op, opName, P.Outs, P.Ins64, P.Asm64,
852   !if(!eq(P.NumSrcArgs, 3),
853     !if(P.HasModifiers,
854         [(set P.DstVT:$dst,
855             (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
856                                        i1:$clamp, i32:$omod)),
857                   (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)),
858                   (P.Src2VT (VOP3Mods P.Src2VT:$src2, i32:$src2_modifiers))))],
859         [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1,
860                                   P.Src2VT:$src2))]),
861   !if(!eq(P.NumSrcArgs, 2),
862     !if(P.HasModifiers,
863         [(set P.DstVT:$dst,
864             (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
865                                        i1:$clamp, i32:$omod)),
866                   (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
867         [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1))])
868   /* P.NumSrcArgs == 1 */,
869     !if(P.HasModifiers,
870         [(set P.DstVT:$dst,
871             (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
872                                        i1:$clamp, i32:$omod))))],
873         [(set P.DstVT:$dst, (node P.Src0VT:$src0))]))),
874   P.NumSrcArgs, P.HasModifiers
875 >;
876
877 multiclass VOP3b_Helper <bits<9> op, RegisterClass vrc, RegisterClass arc,
878                     string opName, list<dag> pattern> :
879   VOP3b_2_m <
880   op, (outs vrc:$dst0, SReg_64:$dst1),
881       (ins InputModsNoDefault:$src0_modifiers, arc:$src0,
882            InputModsNoDefault:$src1_modifiers, arc:$src1,
883            InputModsNoDefault:$src2_modifiers, arc:$src2,
884            ClampMod:$clamp, i32imm:$omod),
885   opName#" $dst0, $dst1, $src0_modifiers, $src1_modifiers, $src2_modifiers"#"$clamp"#"$omod", pattern,
886   opName, opName, 1, 1
887 >;
888
889 multiclass VOP3b_64 <bits<9> op, string opName, list<dag> pattern> :
890   VOP3b_Helper <op, VReg_64, VSrc_64, opName, pattern>;
891
892 multiclass VOP3b_32 <bits<9> op, string opName, list<dag> pattern> :
893   VOP3b_Helper <op, VReg_32, VSrc_32, opName, pattern>;
894
895
896 class Vop3ModPat<Instruction Inst, VOPProfile P, SDPatternOperator node> : Pat<
897   (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i1:$clamp, i32:$omod)),
898         (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)),
899         (P.Src2VT (VOP3Mods P.Src2VT:$src2, i32:$src2_modifiers))),
900   (Inst i32:$src0_modifiers, P.Src0VT:$src0,
901         i32:$src1_modifiers, P.Src1VT:$src1,
902         i32:$src2_modifiers, P.Src2VT:$src2,
903         i1:$clamp,
904         i32:$omod)>;
905
906 //===----------------------------------------------------------------------===//
907 // Vector I/O classes
908 //===----------------------------------------------------------------------===//
909
910 class DS_1A <bits<8> op, dag outs, dag ins, string asm, list<dag> pat> :
911     DS <op, outs, ins, asm, pat> {
912   bits<16> offset;
913
914   // Single load interpret the 2 i8imm operands as a single i16 offset.
915   let offset0 = offset{7-0};
916   let offset1 = offset{15-8};
917 }
918
919 class DS_Load_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
920   op,
921   (outs regClass:$vdst),
922   (ins i1imm:$gds, VReg_32:$addr, u16imm:$offset),
923   asm#" $vdst, $addr, $offset, [M0]",
924   []> {
925   let data0 = 0;
926   let data1 = 0;
927   let mayLoad = 1;
928   let mayStore = 0;
929 }
930
931 class DS_Load2_Helper <bits<8> op, string asm, RegisterClass regClass> : DS <
932   op,
933   (outs regClass:$vdst),
934   (ins i1imm:$gds, VReg_32:$addr, u8imm:$offset0, u8imm:$offset1),
935   asm#" $vdst, $addr, $offset0, $offset1, [M0]",
936   []> {
937   let data0 = 0;
938   let data1 = 0;
939   let mayLoad = 1;
940   let mayStore = 0;
941 }
942
943 class DS_Store_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
944   op,
945   (outs),
946   (ins i1imm:$gds, VReg_32:$addr, regClass:$data0, u16imm:$offset),
947   asm#" $addr, $data0, $offset [M0]",
948   []> {
949   let data1 = 0;
950   let mayStore = 1;
951   let mayLoad = 0;
952   let vdst = 0;
953 }
954
955 class DS_Store2_Helper <bits<8> op, string asm, RegisterClass regClass> : DS <
956   op,
957   (outs),
958   (ins i1imm:$gds, VReg_32:$addr, regClass:$data0, regClass:$data1,
959        u8imm:$offset0, u8imm:$offset1),
960   asm#" $addr, $data0, $data1, $offset0, $offset1 [M0]",
961   []> {
962   let mayStore = 1;
963   let mayLoad = 0;
964   let vdst = 0;
965 }
966
967 // 1 address, 1 data.
968 class DS_1A1D_RET <bits<8> op, string asm, RegisterClass rc, string noRetOp = ""> : DS_1A <
969   op,
970   (outs rc:$vdst),
971   (ins i1imm:$gds, VReg_32:$addr, rc:$data0, u16imm:$offset),
972   asm#" $vdst, $addr, $data0, $offset, [M0]", []>,
973   AtomicNoRet<noRetOp, 1> {
974
975   let data1 = 0;
976   let mayStore = 1;
977   let mayLoad = 1;
978
979   let hasPostISelHook = 1; // Adjusted to no return version.
980 }
981
982 // 1 address, 2 data.
983 class DS_1A2D_RET <bits<8> op, string asm, RegisterClass rc, string noRetOp = ""> : DS_1A <
984   op,
985   (outs rc:$vdst),
986   (ins i1imm:$gds, VReg_32:$addr, rc:$data0, rc:$data1, u16imm:$offset),
987   asm#" $vdst, $addr, $data0, $data1, $offset, [M0]",
988   []>,
989   AtomicNoRet<noRetOp, 1> {
990   let mayStore = 1;
991   let mayLoad = 1;
992
993   let hasPostISelHook = 1; // Adjusted to no return version.
994 }
995
996 // 1 address, 2 data.
997 class DS_1A2D_NORET <bits<8> op, string asm, RegisterClass rc, string noRetOp = asm> : DS_1A <
998   op,
999   (outs),
1000   (ins i1imm:$gds, VReg_32:$addr, rc:$data0, rc:$data1, u16imm:$offset),
1001   asm#" $addr, $data0, $data1, $offset, [M0]",
1002   []>,
1003   AtomicNoRet<noRetOp, 0> {
1004   let mayStore = 1;
1005   let mayLoad = 1;
1006 }
1007
1008 // 1 address, 1 data.
1009 class DS_1A1D_NORET <bits<8> op, string asm, RegisterClass rc, string noRetOp = asm> : DS_1A <
1010   op,
1011   (outs),
1012   (ins i1imm:$gds, VReg_32:$addr, rc:$data0, u16imm:$offset),
1013   asm#" $addr, $data0, $offset, [M0]",
1014   []>,
1015   AtomicNoRet<noRetOp, 0> {
1016
1017   let data1 = 0;
1018   let mayStore = 1;
1019   let mayLoad = 1;
1020 }
1021
1022 //===----------------------------------------------------------------------===//
1023 // MTBUF classes
1024 //===----------------------------------------------------------------------===//
1025
1026 class MTBUF_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
1027   MTBUF <outs, ins, "", pattern>,
1028   SIMCInstr<opName, SISubtarget.NONE> {
1029   let isPseudo = 1;
1030 }
1031
1032 class MTBUF_Real_si <bits<3> op, string opName, dag outs, dag ins,
1033                     string asm> :
1034   MTBUF <outs, ins, asm, []>,
1035   MTBUFe <op>,
1036   SIMCInstr<opName, SISubtarget.SI>;
1037
1038 multiclass MTBUF_m <bits<3> op, string opName, dag outs, dag ins, string asm,
1039                     list<dag> pattern> {
1040
1041   def "" : MTBUF_Pseudo <opName, outs, ins, pattern>;
1042
1043   def _si : MTBUF_Real_si <op, opName, outs, ins, asm>;
1044
1045 }
1046
1047 let mayStore = 1, mayLoad = 0 in {
1048
1049 multiclass MTBUF_Store_Helper <bits<3> op, string opName,
1050                                RegisterClass regClass> : MTBUF_m <
1051   op, opName, (outs),
1052   (ins regClass:$vdata, u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
1053    i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr,
1054    SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
1055   opName#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
1056         #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset", []
1057 >;
1058
1059 } // mayStore = 1, mayLoad = 0
1060
1061 let mayLoad = 1, mayStore = 0 in {
1062
1063 multiclass MTBUF_Load_Helper <bits<3> op, string opName,
1064                               RegisterClass regClass> : MTBUF_m <
1065   op, opName, (outs regClass:$dst),
1066   (ins u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
1067        i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, SReg_128:$srsrc,
1068        i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
1069   opName#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
1070         #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset", []
1071 >;
1072
1073 } // mayLoad = 1, mayStore = 0
1074
1075 class MUBUFAddr64Table <bit is_addr64, string suffix = ""> {
1076
1077   bit IsAddr64 = is_addr64;
1078   string OpName = NAME # suffix;
1079 }
1080
1081 class MUBUFAtomicAddr64 <bits<7> op, dag outs, dag ins, string asm, list<dag> pattern>
1082     : MUBUF <op, outs, ins, asm, pattern> {
1083
1084   let offen = 0;
1085   let idxen = 0;
1086   let addr64 = 1;
1087   let tfe = 0;
1088   let lds = 0;
1089   let soffset = 128;
1090 }
1091
1092 class MUBUFAtomicOffset <bits<7> op, dag outs, dag ins, string asm, list<dag> pattern>
1093     : MUBUF <op, outs, ins, asm, pattern> {
1094
1095   let offen = 0;
1096   let idxen = 0;
1097   let addr64 = 0;
1098   let tfe = 0;
1099   let lds = 0;
1100   let vaddr = 0;
1101 }
1102
1103 multiclass MUBUF_Atomic <bits<7> op, string name, RegisterClass rc,
1104                          ValueType vt, SDPatternOperator atomic> {
1105
1106   let mayStore = 1, mayLoad = 1, hasPostISelHook = 1 in {
1107
1108     // No return variants
1109     let glc = 0 in {
1110
1111       def _ADDR64 : MUBUFAtomicAddr64 <
1112         op, (outs),
1113         (ins rc:$vdata, SReg_128:$srsrc, VReg_64:$vaddr,
1114              mbuf_offset:$offset, slc:$slc),
1115         name#" $vdata, $vaddr, $srsrc, 0 addr64"#"$offset"#"$slc", []
1116       >, MUBUFAddr64Table<1>, AtomicNoRet<NAME#"_ADDR64", 0>;
1117
1118       def _OFFSET : MUBUFAtomicOffset <
1119         op, (outs),
1120         (ins rc:$vdata, SReg_128:$srsrc, mbuf_offset:$offset,
1121              SSrc_32:$soffset, slc:$slc),
1122         name#" $vdata, $srsrc, $soffset"#"$offset"#"$slc", []
1123       >, MUBUFAddr64Table<0>, AtomicNoRet<NAME#"_OFFSET", 0>;
1124     } // glc = 0
1125
1126     // Variant that return values
1127     let glc = 1, Constraints = "$vdata = $vdata_in",
1128         DisableEncoding = "$vdata_in"  in {
1129
1130       def _RTN_ADDR64 : MUBUFAtomicAddr64 <
1131         op, (outs rc:$vdata),
1132         (ins rc:$vdata_in, SReg_128:$srsrc, VReg_64:$vaddr,
1133              mbuf_offset:$offset, slc:$slc),
1134         name#" $vdata, $vaddr, $srsrc, 0 addr64"#"$offset"#" glc"#"$slc",
1135         [(set vt:$vdata,
1136          (atomic (MUBUFAddr64Atomic v4i32:$srsrc, i64:$vaddr, i16:$offset,
1137                                     i1:$slc), vt:$vdata_in))]
1138       >, MUBUFAddr64Table<1, "_RTN">, AtomicNoRet<NAME#"_ADDR64", 1>;
1139
1140       def _RTN_OFFSET : MUBUFAtomicOffset <
1141         op, (outs rc:$vdata),
1142         (ins rc:$vdata_in, SReg_128:$srsrc, mbuf_offset:$offset,
1143              SSrc_32:$soffset, slc:$slc),
1144         name#" $vdata, $srsrc, $soffset"#"$offset"#" glc $slc",
1145         [(set vt:$vdata,
1146          (atomic (MUBUFOffsetAtomic v4i32:$srsrc, i32:$soffset, i16:$offset,
1147                                     i1:$slc), vt:$vdata_in))]
1148       >, MUBUFAddr64Table<0, "_RTN">, AtomicNoRet<NAME#"_OFFSET", 1>;
1149
1150     } // glc = 1
1151
1152   } // mayStore = 1, mayLoad = 1, hasPostISelHook = 1
1153 }
1154
1155 multiclass MUBUF_Load_Helper <bits<7> op, string asm, RegisterClass regClass,
1156                               ValueType load_vt = i32,
1157                               SDPatternOperator ld = null_frag> {
1158
1159   let lds = 0, mayLoad = 1 in {
1160
1161     let addr64 = 0 in {
1162
1163       let offen = 0, idxen = 0, vaddr = 0 in {
1164         def _OFFSET : MUBUF <op, (outs regClass:$vdata),
1165                              (ins SReg_128:$srsrc,
1166                              mbuf_offset:$offset, SSrc_32:$soffset, glc:$glc,
1167                              slc:$slc, tfe:$tfe),
1168                              asm#" $vdata, $srsrc, $soffset"#"$offset"#"$glc"#"$slc"#"$tfe",
1169                              [(set load_vt:$vdata, (ld (MUBUFOffset v4i32:$srsrc,
1170                                                        i32:$soffset, i16:$offset,
1171                                                        i1:$glc, i1:$slc, i1:$tfe)))]>,
1172                      MUBUFAddr64Table<0>;
1173       }
1174
1175       let offen = 1, idxen = 0  in {
1176         def _OFFEN  : MUBUF <op, (outs regClass:$vdata),
1177                              (ins SReg_128:$srsrc, VReg_32:$vaddr,
1178                              SSrc_32:$soffset, mbuf_offset:$offset, glc:$glc, slc:$slc,
1179                              tfe:$tfe),
1180                              asm#" $vdata, $vaddr, $srsrc, $soffset offen"#"$offset"#"$glc"#"$slc"#"$tfe", []>;
1181       }
1182
1183       let offen = 0, idxen = 1 in {
1184         def _IDXEN  : MUBUF <op, (outs regClass:$vdata),
1185                              (ins SReg_128:$srsrc, VReg_32:$vaddr,
1186                              mbuf_offset:$offset, SSrc_32:$soffset, glc:$glc,
1187                              slc:$slc, tfe:$tfe),
1188                              asm#" $vdata, $vaddr, $srsrc, $soffset idxen"#"$offset"#"$glc"#"$slc"#"$tfe", []>;
1189       }
1190
1191       let offen = 1, idxen = 1 in {
1192         def _BOTHEN : MUBUF <op, (outs regClass:$vdata),
1193                              (ins SReg_128:$srsrc, VReg_64:$vaddr,
1194                              SSrc_32:$soffset, glc:$glc, slc:$slc, tfe:$tfe),
1195                              asm#" $vdata, $vaddr, $srsrc, $soffset, idxen offen"#"$glc"#"$slc"#"$tfe", []>;
1196       }
1197     }
1198
1199     let offen = 0, idxen = 0, addr64 = 1, glc = 0, slc = 0, tfe = 0, soffset = 128 /* ZERO */ in {
1200       def _ADDR64 : MUBUF <op, (outs regClass:$vdata),
1201                            (ins SReg_128:$srsrc, VReg_64:$vaddr, mbuf_offset:$offset),
1202                            asm#" $vdata, $vaddr, $srsrc, 0 addr64"#"$offset",
1203                            [(set load_vt:$vdata, (ld (MUBUFAddr64 v4i32:$srsrc,
1204                                                   i64:$vaddr, i16:$offset)))]>, MUBUFAddr64Table<1>;
1205     }
1206   }
1207 }
1208
1209 multiclass MUBUF_Store_Helper <bits<7> op, string name, RegisterClass vdataClass,
1210                           ValueType store_vt, SDPatternOperator st> {
1211
1212   let addr64 = 0, lds = 0 in {
1213
1214     def "" : MUBUF <
1215       op, (outs),
1216       (ins vdataClass:$vdata, SReg_128:$srsrc, VReg_32:$vaddr, SSrc_32:$soffset,
1217            mbuf_offset:$offset, offen:$offen, idxen:$idxen, glc:$glc, slc:$slc,
1218            tfe:$tfe),
1219       name#" $vdata, $vaddr, $srsrc, $soffset"#"$offen"#"$idxen"#"$offset"#
1220            "$glc"#"$slc"#"$tfe",
1221       []
1222     >;
1223
1224     let offen = 0, idxen = 0, vaddr = 0 in {
1225       def _OFFSET : MUBUF <
1226         op, (outs),
1227         (ins vdataClass:$vdata, SReg_128:$srsrc, mbuf_offset:$offset,
1228               SSrc_32:$soffset, glc:$glc, slc:$slc, tfe:$tfe),
1229         name#" $vdata, $srsrc, $soffset"#"$offset"#"$glc"#"$slc"#"$tfe",
1230         [(st store_vt:$vdata, (MUBUFOffset v4i32:$srsrc, i32:$soffset,
1231                                            i16:$offset, i1:$glc, i1:$slc,
1232                                            i1:$tfe))]
1233       >, MUBUFAddr64Table<0>;
1234     } // offen = 0, idxen = 0, vaddr = 0
1235
1236     let offen = 1, idxen = 0  in {
1237       def _OFFEN  : MUBUF <
1238         op, (outs),
1239         (ins vdataClass:$vdata, SReg_128:$srsrc, VReg_32:$vaddr, SSrc_32:$soffset,
1240              mbuf_offset:$offset, glc:$glc, slc:$slc, tfe:$tfe),
1241         name#" $vdata, $vaddr, $srsrc, $soffset offen"#"$offset"#
1242             "$glc"#"$slc"#"$tfe",
1243         []
1244       >;
1245     } // end offen = 1, idxen = 0
1246
1247   } // End addr64 = 0, lds = 0
1248
1249   def _ADDR64 : MUBUF <
1250     op, (outs),
1251     (ins vdataClass:$vdata, SReg_128:$srsrc, VReg_64:$vaddr, mbuf_offset:$offset),
1252     name#" $vdata, $vaddr, $srsrc, 0 addr64"#"$offset",
1253     [(st store_vt:$vdata,
1254      (MUBUFAddr64 v4i32:$srsrc, i64:$vaddr, i16:$offset))]>, MUBUFAddr64Table<1>
1255      {
1256
1257       let mayLoad = 0;
1258       let mayStore = 1;
1259
1260       // Encoding
1261       let offen = 0;
1262       let idxen = 0;
1263       let glc = 0;
1264       let addr64 = 1;
1265       let lds = 0;
1266       let slc = 0;
1267       let tfe = 0;
1268       let soffset = 128; // ZERO
1269    }
1270 }
1271
1272 class FLAT_Load_Helper <bits<7> op, string asm, RegisterClass regClass> :
1273       FLAT <op, (outs regClass:$data),
1274                 (ins VReg_64:$addr),
1275             asm#" $data, $addr, [M0, FLAT_SCRATCH]", []> {
1276   let glc = 0;
1277   let slc = 0;
1278   let tfe = 0;
1279   let mayLoad = 1;
1280 }
1281
1282 class FLAT_Store_Helper <bits<7> op, string name, RegisterClass vdataClass> :
1283       FLAT <op, (outs), (ins vdataClass:$data, VReg_64:$addr),
1284           name#" $data, $addr, [M0, FLAT_SCRATCH]",
1285          []> {
1286
1287   let mayLoad = 0;
1288   let mayStore = 1;
1289
1290   // Encoding
1291   let glc = 0;
1292   let slc = 0;
1293   let tfe = 0;
1294 }
1295
1296 class MIMG_Mask <string op, int channels> {
1297   string Op = op;
1298   int Channels = channels;
1299 }
1300
1301 class MIMG_NoSampler_Helper <bits<7> op, string asm,
1302                              RegisterClass dst_rc,
1303                              RegisterClass src_rc> : MIMG <
1304   op,
1305   (outs dst_rc:$vdata),
1306   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
1307        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
1308        SReg_256:$srsrc),
1309   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
1310      #" $tfe, $lwe, $slc, $vaddr, $srsrc",
1311   []> {
1312   let SSAMP = 0;
1313   let mayLoad = 1;
1314   let mayStore = 0;
1315   let hasPostISelHook = 1;
1316 }
1317
1318 multiclass MIMG_NoSampler_Src_Helper <bits<7> op, string asm,
1319                                       RegisterClass dst_rc,
1320                                       int channels> {
1321   def _V1 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_32>,
1322             MIMG_Mask<asm#"_V1", channels>;
1323   def _V2 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_64>,
1324             MIMG_Mask<asm#"_V2", channels>;
1325   def _V4 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_128>,
1326             MIMG_Mask<asm#"_V4", channels>;
1327 }
1328
1329 multiclass MIMG_NoSampler <bits<7> op, string asm> {
1330   defm _V1 : MIMG_NoSampler_Src_Helper <op, asm, VReg_32, 1>;
1331   defm _V2 : MIMG_NoSampler_Src_Helper <op, asm, VReg_64, 2>;
1332   defm _V3 : MIMG_NoSampler_Src_Helper <op, asm, VReg_96, 3>;
1333   defm _V4 : MIMG_NoSampler_Src_Helper <op, asm, VReg_128, 4>;
1334 }
1335
1336 class MIMG_Sampler_Helper <bits<7> op, string asm,
1337                            RegisterClass dst_rc,
1338                            RegisterClass src_rc> : MIMG <
1339   op,
1340   (outs dst_rc:$vdata),
1341   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
1342        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
1343        SReg_256:$srsrc, SReg_128:$ssamp),
1344   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
1345      #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
1346   []> {
1347   let mayLoad = 1;
1348   let mayStore = 0;
1349   let hasPostISelHook = 1;
1350 }
1351
1352 multiclass MIMG_Sampler_Src_Helper <bits<7> op, string asm,
1353                                     RegisterClass dst_rc,
1354                                     int channels> {
1355   def _V1 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_32>,
1356             MIMG_Mask<asm#"_V1", channels>;
1357   def _V2 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_64>,
1358             MIMG_Mask<asm#"_V2", channels>;
1359   def _V4 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_128>,
1360             MIMG_Mask<asm#"_V4", channels>;
1361   def _V8 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_256>,
1362             MIMG_Mask<asm#"_V8", channels>;
1363   def _V16 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_512>,
1364             MIMG_Mask<asm#"_V16", channels>;
1365 }
1366
1367 multiclass MIMG_Sampler <bits<7> op, string asm> {
1368   defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VReg_32, 1>;
1369   defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2>;
1370   defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3>;
1371   defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4>;
1372 }
1373
1374 class MIMG_Gather_Helper <bits<7> op, string asm,
1375                           RegisterClass dst_rc,
1376                           RegisterClass src_rc> : MIMG <
1377   op,
1378   (outs dst_rc:$vdata),
1379   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
1380        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
1381        SReg_256:$srsrc, SReg_128:$ssamp),
1382   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
1383      #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
1384   []> {
1385   let mayLoad = 1;
1386   let mayStore = 0;
1387
1388   // DMASK was repurposed for GATHER4. 4 components are always
1389   // returned and DMASK works like a swizzle - it selects
1390   // the component to fetch. The only useful DMASK values are
1391   // 1=red, 2=green, 4=blue, 8=alpha. (e.g. 1 returns
1392   // (red,red,red,red) etc.) The ISA document doesn't mention
1393   // this.
1394   // Therefore, disable all code which updates DMASK by setting these two:
1395   let MIMG = 0;
1396   let hasPostISelHook = 0;
1397 }
1398
1399 multiclass MIMG_Gather_Src_Helper <bits<7> op, string asm,
1400                                     RegisterClass dst_rc,
1401                                     int channels> {
1402   def _V1 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_32>,
1403             MIMG_Mask<asm#"_V1", channels>;
1404   def _V2 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_64>,
1405             MIMG_Mask<asm#"_V2", channels>;
1406   def _V4 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_128>,
1407             MIMG_Mask<asm#"_V4", channels>;
1408   def _V8 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_256>,
1409             MIMG_Mask<asm#"_V8", channels>;
1410   def _V16 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_512>,
1411             MIMG_Mask<asm#"_V16", channels>;
1412 }
1413
1414 multiclass MIMG_Gather <bits<7> op, string asm> {
1415   defm _V1 : MIMG_Gather_Src_Helper<op, asm, VReg_32, 1>;
1416   defm _V2 : MIMG_Gather_Src_Helper<op, asm, VReg_64, 2>;
1417   defm _V3 : MIMG_Gather_Src_Helper<op, asm, VReg_96, 3>;
1418   defm _V4 : MIMG_Gather_Src_Helper<op, asm, VReg_128, 4>;
1419 }
1420
1421 //===----------------------------------------------------------------------===//
1422 // Vector instruction mappings
1423 //===----------------------------------------------------------------------===//
1424
1425 // Maps an opcode in e32 form to its e64 equivalent
1426 def getVOPe64 : InstrMapping {
1427   let FilterClass = "VOP";
1428   let RowFields = ["OpName"];
1429   let ColFields = ["Size"];
1430   let KeyCol = ["4"];
1431   let ValueCols = [["8"]];
1432 }
1433
1434 // Maps an opcode in e64 form to its e32 equivalent
1435 def getVOPe32 : InstrMapping {
1436   let FilterClass = "VOP";
1437   let RowFields = ["OpName"];
1438   let ColFields = ["Size"];
1439   let KeyCol = ["8"];
1440   let ValueCols = [["4"]];
1441 }
1442
1443 // Maps an original opcode to its commuted version
1444 def getCommuteRev : InstrMapping {
1445   let FilterClass = "VOP2_REV";
1446   let RowFields = ["RevOp"];
1447   let ColFields = ["IsOrig"];
1448   let KeyCol = ["1"];
1449   let ValueCols = [["0"]];
1450 }
1451
1452 def getMaskedMIMGOp : InstrMapping {
1453   let FilterClass = "MIMG_Mask";
1454   let RowFields = ["Op"];
1455   let ColFields = ["Channels"];
1456   let KeyCol = ["4"];
1457   let ValueCols = [["1"], ["2"], ["3"] ];
1458 }
1459
1460 // Maps an commuted opcode to its original version
1461 def getCommuteOrig : InstrMapping {
1462   let FilterClass = "VOP2_REV";
1463   let RowFields = ["RevOp"];
1464   let ColFields = ["IsOrig"];
1465   let KeyCol = ["0"];
1466   let ValueCols = [["1"]];
1467 }
1468
1469 def isDS : InstrMapping {
1470   let FilterClass = "DS";
1471   let RowFields = ["Inst"];
1472   let ColFields = ["Size"];
1473   let KeyCol = ["8"];
1474   let ValueCols = [["8"]];
1475 }
1476
1477 def getMCOpcode : InstrMapping {
1478   let FilterClass = "SIMCInstr";
1479   let RowFields = ["PseudoInstr"];
1480   let ColFields = ["Subtarget"];
1481   let KeyCol = [!cast<string>(SISubtarget.NONE)];
1482   let ValueCols = [[!cast<string>(SISubtarget.SI)]];
1483 }
1484
1485 def getAddr64Inst : InstrMapping {
1486   let FilterClass = "MUBUFAddr64Table";
1487   let RowFields = ["OpName"];
1488   let ColFields = ["IsAddr64"];
1489   let KeyCol = ["0"];
1490   let ValueCols = [["1"]];
1491 }
1492
1493 // Maps an atomic opcode to its version with a return value.
1494 def getAtomicRetOp : InstrMapping {
1495   let FilterClass = "AtomicNoRet";
1496   let RowFields = ["NoRetOp"];
1497   let ColFields = ["IsRet"];
1498   let KeyCol = ["0"];
1499   let ValueCols = [["1"]];
1500 }
1501
1502 // Maps an atomic opcode to its returnless version.
1503 def getAtomicNoRetOp : InstrMapping {
1504   let FilterClass = "AtomicNoRet";
1505   let RowFields = ["NoRetOp"];
1506   let ColFields = ["IsRet"];
1507   let KeyCol = ["1"];
1508   let ValueCols = [["0"]];
1509 }
1510
1511 include "SIInstructions.td"