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