[PowerPC] Enable interleaved-access vectorization
[oota-llvm.git] / lib / Target / AMDGPU / 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 def isCI : Predicate<"Subtarget->getGeneration() "
10                       ">= AMDGPUSubtarget::SEA_ISLANDS">;
11 def isCIOnly : Predicate<"Subtarget->getGeneration() =="
12                          "AMDGPUSubtarget::SEA_ISLANDS">,
13   AssemblerPredicate <"FeatureSeaIslands">;
14 def isVI : Predicate <
15   "Subtarget->getGeneration() >= AMDGPUSubtarget::VOLCANIC_ISLANDS">,
16   AssemblerPredicate<"FeatureGCN3Encoding">;
17
18 def DisableInst : Predicate <"false">, AssemblerPredicate<"FeatureDisable">;
19
20 class vop {
21   field bits<9> SI3;
22   field bits<10> VI3;
23 }
24
25 class vopc <bits<8> si, bits<8> vi = !add(0x40, si)> : vop {
26   field bits<8> SI = si;
27   field bits<8> VI = vi;
28
29   field bits<9>  SI3 = {0, si{7-0}};
30   field bits<10> VI3 = {0, 0, vi{7-0}};
31 }
32
33 class vop1 <bits<8> si, bits<8> vi = si> : vop {
34   field bits<8> SI = si;
35   field bits<8> VI = vi;
36
37   field bits<9>  SI3 = {1, 1, si{6-0}};
38   field bits<10> VI3 = !add(0x140, vi);
39 }
40
41 class vop2 <bits<6> si, bits<6> vi = si> : vop {
42   field bits<6> SI = si;
43   field bits<6> VI = vi;
44
45   field bits<9>  SI3 = {1, 0, 0, si{5-0}};
46   field bits<10> VI3 = {0, 1, 0, 0, vi{5-0}};
47 }
48
49 // Specify a VOP2 opcode for SI and VOP3 opcode for VI
50 // that doesn't have VOP2 encoding on VI
51 class vop23 <bits<6> si, bits<10> vi> : vop2 <si> {
52   let VI3 = vi;
53 }
54
55 class vop3 <bits<9> si, bits<10> vi = {0, si}> : vop {
56   let SI3 = si;
57   let VI3 = vi;
58 }
59
60 class sop1 <bits<8> si, bits<8> vi = si> {
61   field bits<8> SI = si;
62   field bits<8> VI = vi;
63 }
64
65 class sop2 <bits<7> si, bits<7> vi = si> {
66   field bits<7> SI = si;
67   field bits<7> VI = vi;
68 }
69
70 class sopk <bits<5> si, bits<5> vi = si> {
71   field bits<5> SI = si;
72   field bits<5> VI = vi;
73 }
74
75 // Specify an SMRD opcode for SI and SMEM opcode for VI
76 class smrd<bits<5> si, bits<5> vi = si> {
77   field bits<5> SI = si;
78   field bits<8> VI = { 0, 0, 0, vi };
79 }
80
81 // Execpt for the NONE field, this must be kept in sync with the SISubtarget enum
82 // in AMDGPUInstrInfo.cpp
83 def SISubtarget {
84   int NONE = -1;
85   int SI = 0;
86   int VI = 1;
87 }
88
89 //===----------------------------------------------------------------------===//
90 // SI DAG Nodes
91 //===----------------------------------------------------------------------===//
92
93 def SIload_constant : SDNode<"AMDGPUISD::LOAD_CONSTANT",
94   SDTypeProfile<1, 2, [SDTCisVT<0, f32>, SDTCisVT<1, v4i32>, SDTCisVT<2, i32>]>,
95                       [SDNPMayLoad, SDNPMemOperand]
96 >;
97
98 def SItbuffer_store : SDNode<"AMDGPUISD::TBUFFER_STORE_FORMAT",
99   SDTypeProfile<0, 13,
100     [SDTCisVT<0, v4i32>,   // rsrc(SGPR)
101      SDTCisVT<1, iAny>,   // vdata(VGPR)
102      SDTCisVT<2, i32>,    // num_channels(imm)
103      SDTCisVT<3, i32>,    // vaddr(VGPR)
104      SDTCisVT<4, i32>,    // soffset(SGPR)
105      SDTCisVT<5, i32>,    // inst_offset(imm)
106      SDTCisVT<6, i32>,    // dfmt(imm)
107      SDTCisVT<7, i32>,    // nfmt(imm)
108      SDTCisVT<8, i32>,    // offen(imm)
109      SDTCisVT<9, i32>,    // idxen(imm)
110      SDTCisVT<10, i32>,   // glc(imm)
111      SDTCisVT<11, i32>,   // slc(imm)
112      SDTCisVT<12, i32>    // tfe(imm)
113     ]>,
114   [SDNPMayStore, SDNPMemOperand, SDNPHasChain]
115 >;
116
117 def SIload_input : SDNode<"AMDGPUISD::LOAD_INPUT",
118   SDTypeProfile<1, 3, [SDTCisVT<0, v4f32>, SDTCisVT<1, v4i32>, SDTCisVT<2, i16>,
119                        SDTCisVT<3, i32>]>
120 >;
121
122 class SDSample<string opcode> : SDNode <opcode,
123   SDTypeProfile<1, 4, [SDTCisVT<0, v4f32>, SDTCisVT<2, v32i8>,
124                        SDTCisVT<3, v4i32>, SDTCisVT<4, i32>]>
125 >;
126
127 def SIsample : SDSample<"AMDGPUISD::SAMPLE">;
128 def SIsampleb : SDSample<"AMDGPUISD::SAMPLEB">;
129 def SIsampled : SDSample<"AMDGPUISD::SAMPLED">;
130 def SIsamplel : SDSample<"AMDGPUISD::SAMPLEL">;
131
132 def SIconstdata_ptr : SDNode<
133   "AMDGPUISD::CONST_DATA_PTR", SDTypeProfile <1, 0, [SDTCisVT<0, i64>]>
134 >;
135
136 //===----------------------------------------------------------------------===//
137 // SDNodes and PatFrag for local loads and stores to enable s_mov_b32 m0, -1
138 // to be glued to the memory instructions.
139 //===----------------------------------------------------------------------===//
140
141 def SIld_local : SDNode <"ISD::LOAD", SDTLoad,
142   [SDNPHasChain, SDNPMayLoad, SDNPMemOperand, SDNPInGlue]
143 >;
144
145 def si_ld_local : PatFrag <(ops node:$ptr), (SIld_local node:$ptr), [{
146   return isLocalLoad(cast<LoadSDNode>(N));
147 }]>;
148
149 def si_load_local : PatFrag <(ops node:$ptr), (si_ld_local node:$ptr), [{
150   return cast<LoadSDNode>(N)->getAddressingMode() == ISD::UNINDEXED &&
151          cast<LoadSDNode>(N)->getExtensionType() == ISD::NON_EXTLOAD;
152 }]>;
153
154 def si_load_local_align8 : Aligned8Bytes <
155   (ops node:$ptr), (si_load_local node:$ptr)
156 >;
157
158 def si_sextload_local : PatFrag <(ops node:$ptr), (si_ld_local node:$ptr), [{
159   return cast<LoadSDNode>(N)->getExtensionType() == ISD::SEXTLOAD;
160 }]>;
161 def si_az_extload_local : AZExtLoadBase <si_ld_local>;
162
163 multiclass SIExtLoadLocal <PatFrag ld_node> {
164
165   def _i8 : PatFrag <(ops node:$ptr), (ld_node node:$ptr),
166                      [{return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i8;}]
167   >;
168
169   def _i16 : PatFrag <(ops node:$ptr), (ld_node node:$ptr),
170                      [{return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i16;}]
171   >;
172 }
173
174 defm si_sextload_local : SIExtLoadLocal <si_sextload_local>;
175 defm si_az_extload_local : SIExtLoadLocal <si_az_extload_local>;
176
177 def SIst_local : SDNode <"ISD::STORE", SDTStore,
178   [SDNPHasChain, SDNPMayStore, SDNPMemOperand, SDNPInGlue]
179 >;
180
181 def si_st_local : PatFrag <
182   (ops node:$val, node:$ptr), (SIst_local node:$val, node:$ptr), [{
183   return isLocalStore(cast<StoreSDNode>(N));
184 }]>;
185
186 def si_store_local : PatFrag <
187   (ops node:$val, node:$ptr), (si_st_local node:$val, node:$ptr), [{
188   return cast<StoreSDNode>(N)->getAddressingMode() == ISD::UNINDEXED &&
189          !cast<StoreSDNode>(N)->isTruncatingStore();
190 }]>;
191
192 def si_store_local_align8 : Aligned8Bytes <
193   (ops node:$val, node:$ptr), (si_store_local node:$val, node:$ptr)
194 >;
195
196 def si_truncstore_local : PatFrag <
197   (ops node:$val, node:$ptr), (si_st_local node:$val, node:$ptr), [{
198   return cast<StoreSDNode>(N)->isTruncatingStore();
199 }]>;
200
201 def si_truncstore_local_i8 : PatFrag <
202   (ops node:$val, node:$ptr), (si_truncstore_local node:$val, node:$ptr), [{
203   return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i8;
204 }]>;
205
206 def si_truncstore_local_i16 : PatFrag <
207   (ops node:$val, node:$ptr), (si_truncstore_local node:$val, node:$ptr), [{
208   return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i16;
209 }]>;
210
211 multiclass SIAtomicM0Glue2 <string op_name> {
212
213   def _glue : SDNode <"ISD::ATOMIC_"#op_name, SDTAtomic2,
214     [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand, SDNPInGlue]
215   >;
216
217   def _local : local_binary_atomic_op <!cast<SDNode>(NAME#"_glue")>;
218 }
219
220 defm si_atomic_load_add : SIAtomicM0Glue2 <"LOAD_ADD">;
221 defm si_atomic_load_and : SIAtomicM0Glue2 <"LOAD_AND">;
222 defm si_atomic_load_min : SIAtomicM0Glue2 <"LOAD_MIN">;
223 defm si_atomic_load_max : SIAtomicM0Glue2 <"LOAD_MAX">;
224 defm si_atomic_load_or : SIAtomicM0Glue2 <"LOAD_OR">;
225 defm si_atomic_load_sub : SIAtomicM0Glue2 <"LOAD_SUB">;
226 defm si_atomic_load_xor : SIAtomicM0Glue2 <"LOAD_XOR">;
227 defm si_atomic_load_umin : SIAtomicM0Glue2 <"LOAD_UMIN">;
228 defm si_atomic_load_umax : SIAtomicM0Glue2 <"LOAD_UMAX">;
229 defm si_atomic_swap : SIAtomicM0Glue2 <"SWAP">;
230
231 def si_atomic_cmp_swap_glue : SDNode <"ISD::ATOMIC_CMP_SWAP", SDTAtomic3,
232   [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand, SDNPInGlue]
233 >;
234
235 defm si_atomic_cmp_swap : AtomicCmpSwapLocal <si_atomic_cmp_swap_glue>;
236
237 // Transformation function, extract the lower 32bit of a 64bit immediate
238 def LO32 : SDNodeXForm<imm, [{
239   return CurDAG->getTargetConstant(N->getZExtValue() & 0xffffffff, SDLoc(N),
240                                    MVT::i32);
241 }]>;
242
243 def LO32f : SDNodeXForm<fpimm, [{
244   APInt V = N->getValueAPF().bitcastToAPInt().trunc(32);
245   return CurDAG->getTargetConstantFP(APFloat(APFloat::IEEEsingle, V), MVT::f32);
246 }]>;
247
248 // Transformation function, extract the upper 32bit of a 64bit immediate
249 def HI32 : SDNodeXForm<imm, [{
250   return CurDAG->getTargetConstant(N->getZExtValue() >> 32, SDLoc(N), MVT::i32);
251 }]>;
252
253 def HI32f : SDNodeXForm<fpimm, [{
254   APInt V = N->getValueAPF().bitcastToAPInt().lshr(32).trunc(32);
255   return CurDAG->getTargetConstantFP(APFloat(APFloat::IEEEsingle, V), SDLoc(N),
256                                      MVT::f32);
257 }]>;
258
259 def IMM8bitDWORD : PatLeaf <(imm),
260   [{return (N->getZExtValue() & ~0x3FC) == 0;}]
261 >;
262
263 def as_dword_i32imm : SDNodeXForm<imm, [{
264   return CurDAG->getTargetConstant(N->getZExtValue() >> 2, SDLoc(N), MVT::i32);
265 }]>;
266
267 def as_i1imm : SDNodeXForm<imm, [{
268   return CurDAG->getTargetConstant(N->getZExtValue(), SDLoc(N), MVT::i1);
269 }]>;
270
271 def as_i8imm : SDNodeXForm<imm, [{
272   return CurDAG->getTargetConstant(N->getZExtValue(), SDLoc(N), MVT::i8);
273 }]>;
274
275 def as_i16imm : SDNodeXForm<imm, [{
276   return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i16);
277 }]>;
278
279 def as_i32imm: SDNodeXForm<imm, [{
280   return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i32);
281 }]>;
282
283 def as_i64imm: SDNodeXForm<imm, [{
284   return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i64);
285 }]>;
286
287 // Copied from the AArch64 backend:
288 def bitcast_fpimm_to_i32 : SDNodeXForm<fpimm, [{
289 return CurDAG->getTargetConstant(
290   N->getValueAPF().bitcastToAPInt().getZExtValue(), SDLoc(N), MVT::i32);
291 }]>;
292
293 // Copied from the AArch64 backend:
294 def bitcast_fpimm_to_i64 : SDNodeXForm<fpimm, [{
295 return CurDAG->getTargetConstant(
296   N->getValueAPF().bitcastToAPInt().getZExtValue(), SDLoc(N), MVT::i64);
297 }]>;
298
299 def IMM8bit : PatLeaf <(imm),
300   [{return isUInt<8>(N->getZExtValue());}]
301 >;
302
303 def IMM12bit : PatLeaf <(imm),
304   [{return isUInt<12>(N->getZExtValue());}]
305 >;
306
307 def IMM16bit : PatLeaf <(imm),
308   [{return isUInt<16>(N->getZExtValue());}]
309 >;
310
311 def IMM20bit : PatLeaf <(imm),
312   [{return isUInt<20>(N->getZExtValue());}]
313 >;
314
315 def IMM32bit : PatLeaf <(imm),
316   [{return isUInt<32>(N->getZExtValue());}]
317 >;
318
319 def mubuf_vaddr_offset : PatFrag<
320   (ops node:$ptr, node:$offset, node:$imm_offset),
321   (add (add node:$ptr, node:$offset), node:$imm_offset)
322 >;
323
324 class InlineImm <ValueType vt> : PatLeaf <(vt imm), [{
325   return isInlineImmediate(N);
326 }]>;
327
328 class InlineFPImm <ValueType vt> : PatLeaf <(vt fpimm), [{
329   return isInlineImmediate(N);
330 }]>;
331
332 class SGPRImm <dag frag> : PatLeaf<frag, [{
333   if (Subtarget->getGeneration() < AMDGPUSubtarget::SOUTHERN_ISLANDS) {
334     return false;
335   }
336   const SIRegisterInfo *SIRI =
337       static_cast<const SIRegisterInfo *>(Subtarget->getRegisterInfo());
338   for (SDNode::use_iterator U = N->use_begin(), E = SDNode::use_end();
339                                                 U != E; ++U) {
340     if (SIRI->isSGPRClass(getOperandRegClass(*U, U.getOperandNo()))) {
341       return true;
342     }
343   }
344   return false;
345 }]>;
346
347 //===----------------------------------------------------------------------===//
348 // Custom Operands
349 //===----------------------------------------------------------------------===//
350
351 def FRAMEri32 : Operand<iPTR> {
352   let MIOperandInfo = (ops i32:$ptr, i32imm:$index);
353 }
354
355 def SoppBrTarget : AsmOperandClass {
356   let Name = "SoppBrTarget";
357   let ParserMethod = "parseSOppBrTarget";
358 }
359
360 def sopp_brtarget : Operand<OtherVT> {
361   let EncoderMethod = "getSOPPBrEncoding";
362   let OperandType = "OPERAND_PCREL";
363   let ParserMatchClass = SoppBrTarget;
364 }
365
366 include "SIInstrFormats.td"
367 include "VIInstrFormats.td"
368
369 def MubufOffsetMatchClass : AsmOperandClass {
370   let Name = "MubufOffset";
371   let ParserMethod = "parseMubufOptionalOps";
372   let RenderMethod = "addImmOperands";
373 }
374
375 class DSOffsetBaseMatchClass <string parser> : AsmOperandClass {
376   let Name = "DSOffset"#parser;
377   let ParserMethod = parser;
378   let RenderMethod = "addImmOperands";
379   let PredicateMethod = "isDSOffset";
380 }
381
382 def DSOffsetMatchClass : DSOffsetBaseMatchClass <"parseDSOptionalOps">;
383 def DSOffsetGDSMatchClass : DSOffsetBaseMatchClass <"parseDSOffsetOptional">;
384
385 def DSOffset01MatchClass : AsmOperandClass {
386   let Name = "DSOffset1";
387   let ParserMethod = "parseDSOff01OptionalOps";
388   let RenderMethod = "addImmOperands";
389   let PredicateMethod = "isDSOffset01";
390 }
391
392 class GDSBaseMatchClass <string parser> : AsmOperandClass {
393   let Name = "GDS"#parser;
394   let PredicateMethod = "isImm";
395   let ParserMethod = parser;
396   let RenderMethod = "addImmOperands";
397 }
398
399 def GDSMatchClass : GDSBaseMatchClass <"parseDSOptionalOps">;
400 def GDS01MatchClass : GDSBaseMatchClass <"parseDSOff01OptionalOps">;
401
402 class GLCBaseMatchClass <string parser> : AsmOperandClass {
403   let Name = "GLC"#parser;
404   let PredicateMethod = "isImm";
405   let ParserMethod = parser;
406   let RenderMethod = "addImmOperands";
407 }
408
409 def GLCMubufMatchClass : GLCBaseMatchClass <"parseMubufOptionalOps">;
410 def GLCFlatMatchClass : GLCBaseMatchClass <"parseFlatOptionalOps">;
411
412 class SLCBaseMatchClass <string parser> : AsmOperandClass {
413   let Name = "SLC"#parser;
414   let PredicateMethod = "isImm";
415   let ParserMethod = parser;
416   let RenderMethod = "addImmOperands";
417 }
418
419 def SLCMubufMatchClass : SLCBaseMatchClass <"parseMubufOptionalOps">;
420 def SLCFlatMatchClass : SLCBaseMatchClass <"parseFlatOptionalOps">;
421 def SLCFlatAtomicMatchClass : SLCBaseMatchClass <"parseFlatAtomicOptionalOps">;
422
423 class TFEBaseMatchClass <string parser> : AsmOperandClass {
424   let Name = "TFE"#parser;
425   let PredicateMethod = "isImm";
426   let ParserMethod = parser;
427   let RenderMethod = "addImmOperands";
428 }
429
430 def TFEMubufMatchClass : TFEBaseMatchClass <"parseMubufOptionalOps">;
431 def TFEFlatMatchClass : TFEBaseMatchClass <"parseFlatOptionalOps">;
432 def TFEFlatAtomicMatchClass : TFEBaseMatchClass <"parseFlatAtomicOptionalOps">;
433
434 def OModMatchClass : AsmOperandClass {
435   let Name = "OMod";
436   let PredicateMethod = "isImm";
437   let ParserMethod = "parseVOP3OptionalOps";
438   let RenderMethod = "addImmOperands";
439 }
440
441 def ClampMatchClass : AsmOperandClass {
442   let Name = "Clamp";
443   let PredicateMethod = "isImm";
444   let ParserMethod = "parseVOP3OptionalOps";
445   let RenderMethod = "addImmOperands";
446 }
447
448 class SMRDOffsetBaseMatchClass <string predicate> : AsmOperandClass {
449   let Name = "SMRDOffset"#predicate;
450   let PredicateMethod = predicate;
451   let RenderMethod = "addImmOperands";
452 }
453
454 def SMRDOffsetMatchClass : SMRDOffsetBaseMatchClass <"isSMRDOffset">;
455 def SMRDLiteralOffsetMatchClass : SMRDOffsetBaseMatchClass <
456   "isSMRDLiteralOffset"
457 >;
458
459 let OperandType = "OPERAND_IMMEDIATE" in {
460
461 def offen : Operand<i1> {
462   let PrintMethod = "printOffen";
463 }
464 def idxen : Operand<i1> {
465   let PrintMethod = "printIdxen";
466 }
467 def addr64 : Operand<i1> {
468   let PrintMethod = "printAddr64";
469 }
470 def mbuf_offset : Operand<i16> {
471   let PrintMethod = "printMBUFOffset";
472   let ParserMatchClass = MubufOffsetMatchClass;
473 }
474 class ds_offset_base <AsmOperandClass mc> : Operand<i16> {
475   let PrintMethod = "printDSOffset";
476   let ParserMatchClass = mc;
477 }
478 def ds_offset : ds_offset_base <DSOffsetMatchClass>;
479 def ds_offset_gds : ds_offset_base <DSOffsetGDSMatchClass>;
480
481 def ds_offset0 : Operand<i8> {
482   let PrintMethod = "printDSOffset0";
483   let ParserMatchClass = DSOffset01MatchClass;
484 }
485 def ds_offset1 : Operand<i8> {
486   let PrintMethod = "printDSOffset1";
487   let ParserMatchClass = DSOffset01MatchClass;
488 }
489 class gds_base <AsmOperandClass mc> : Operand <i1> {
490   let PrintMethod = "printGDS";
491   let ParserMatchClass = mc;
492 }
493 def gds : gds_base <GDSMatchClass>;
494
495 def gds01 : gds_base <GDS01MatchClass>;
496
497 class glc_base <AsmOperandClass mc> : Operand <i1> {
498   let PrintMethod = "printGLC";
499   let ParserMatchClass = mc;
500 }
501
502 def glc : glc_base <GLCMubufMatchClass>;
503 def glc_flat : glc_base <GLCFlatMatchClass>;
504
505 class slc_base <AsmOperandClass mc> : Operand <i1> {
506   let PrintMethod = "printSLC";
507   let ParserMatchClass = mc;
508 }
509
510 def slc : slc_base <SLCMubufMatchClass>;
511 def slc_flat : slc_base <SLCFlatMatchClass>;
512 def slc_flat_atomic : slc_base <SLCFlatAtomicMatchClass>;
513
514 class tfe_base <AsmOperandClass mc> : Operand <i1> {
515   let PrintMethod = "printTFE";
516   let ParserMatchClass = mc;
517 }
518
519 def tfe : tfe_base <TFEMubufMatchClass>;
520 def tfe_flat : tfe_base <TFEFlatMatchClass>;
521 def tfe_flat_atomic : tfe_base <TFEFlatAtomicMatchClass>;
522
523 def omod : Operand <i32> {
524   let PrintMethod = "printOModSI";
525   let ParserMatchClass = OModMatchClass;
526 }
527
528 def ClampMod : Operand <i1> {
529   let PrintMethod = "printClampSI";
530   let ParserMatchClass = ClampMatchClass;
531 }
532
533 def smrd_offset : Operand <i32> {
534   let PrintMethod = "printU32ImmOperand";
535   let ParserMatchClass = SMRDOffsetMatchClass;
536 }
537
538 def smrd_literal_offset : Operand <i32> {
539   let PrintMethod = "printU32ImmOperand";
540   let ParserMatchClass = SMRDLiteralOffsetMatchClass;
541 }
542
543 } // End OperandType = "OPERAND_IMMEDIATE"
544
545 def VOPDstS64 : VOPDstOperand <SReg_64>;
546
547 //===----------------------------------------------------------------------===//
548 // Complex patterns
549 //===----------------------------------------------------------------------===//
550
551 def DS1Addr1Offset : ComplexPattern<i32, 2, "SelectDS1Addr1Offset">;
552 def DS64Bit4ByteAligned : ComplexPattern<i32, 3, "SelectDS64Bit4ByteAligned">;
553
554 def MUBUFAddr32 : ComplexPattern<i64, 9, "SelectMUBUFAddr32">;
555 def MUBUFAddr64 : ComplexPattern<i64, 7, "SelectMUBUFAddr64">;
556 def MUBUFAddr64Atomic : ComplexPattern<i64, 5, "SelectMUBUFAddr64">;
557 def MUBUFScratch : ComplexPattern<i64, 4, "SelectMUBUFScratch">;
558 def MUBUFOffset : ComplexPattern<i64, 6, "SelectMUBUFOffset">;
559 def MUBUFOffsetAtomic : ComplexPattern<i64, 4, "SelectMUBUFOffset">;
560
561 def SMRDImm   : ComplexPattern<i64, 2, "SelectSMRDImm">;
562 def SMRDImm32 : ComplexPattern<i64, 2, "SelectSMRDImm32">;
563 def SMRDSgpr  : ComplexPattern<i64, 2, "SelectSMRDSgpr">;
564 def SMRDBufferImm   : ComplexPattern<i32, 1, "SelectSMRDBufferImm">;
565 def SMRDBufferImm32 : ComplexPattern<i32, 1, "SelectSMRDBufferImm32">;
566 def SMRDBufferSgpr  : ComplexPattern<i32, 1, "SelectSMRDBufferSgpr">;
567
568 def VOP3Mods0 : ComplexPattern<untyped, 4, "SelectVOP3Mods0">;
569 def VOP3NoMods0 : ComplexPattern<untyped, 4, "SelectVOP3NoMods0">;
570 def VOP3Mods0Clamp : ComplexPattern<untyped, 3, "SelectVOP3Mods0Clamp">;
571 def VOP3Mods0Clamp0OMod : ComplexPattern<untyped, 4, "SelectVOP3Mods0Clamp0OMod">;
572 def VOP3Mods  : ComplexPattern<untyped, 2, "SelectVOP3Mods">;
573 def VOP3NoMods : ComplexPattern<untyped, 2, "SelectVOP3NoMods">;
574
575 //===----------------------------------------------------------------------===//
576 // SI assembler operands
577 //===----------------------------------------------------------------------===//
578
579 def SIOperand {
580   int ZERO = 0x80;
581   int VCC = 0x6A;
582   int FLAT_SCR = 0x68;
583 }
584
585 def SRCMODS {
586   int NONE = 0;
587   int NEG = 1;
588 }
589
590 def DSTCLAMP {
591   int NONE = 0;
592 }
593
594 def DSTOMOD {
595   int NONE = 0;
596 }
597
598 //===----------------------------------------------------------------------===//
599 //
600 // SI Instruction multiclass helpers.
601 //
602 // Instructions with _32 take 32-bit operands.
603 // Instructions with _64 take 64-bit operands.
604 //
605 // VOP_* instructions can use either a 32-bit or 64-bit encoding.  The 32-bit
606 // encoding is the standard encoding, but instruction that make use of
607 // any of the instruction modifiers must use the 64-bit encoding.
608 //
609 // Instructions with _e32 use the 32-bit encoding.
610 // Instructions with _e64 use the 64-bit encoding.
611 //
612 //===----------------------------------------------------------------------===//
613
614 class SIMCInstr <string pseudo, int subtarget> {
615   string PseudoInstr = pseudo;
616   int Subtarget = subtarget;
617 }
618
619 //===----------------------------------------------------------------------===//
620 // EXP classes
621 //===----------------------------------------------------------------------===//
622
623 class EXPCommon : InstSI<
624   (outs),
625   (ins i32imm:$en, i32imm:$tgt, i32imm:$compr, i32imm:$done, i32imm:$vm,
626        VGPR_32:$src0, VGPR_32:$src1, VGPR_32:$src2, VGPR_32:$src3),
627   "exp $en, $tgt, $compr, $done, $vm, $src0, $src1, $src2, $src3",
628   [] > {
629
630   let EXP_CNT = 1;
631   let Uses = [EXEC];
632 }
633
634 multiclass EXP_m {
635
636   let isPseudo = 1, isCodeGenOnly = 1 in {
637     def "" : EXPCommon, SIMCInstr <"exp", SISubtarget.NONE> ;
638   }
639
640   def _si : EXPCommon, SIMCInstr <"exp", SISubtarget.SI>, EXPe;
641
642   def _vi : EXPCommon, SIMCInstr <"exp", SISubtarget.VI>, EXPe_vi;
643 }
644
645 //===----------------------------------------------------------------------===//
646 // Scalar classes
647 //===----------------------------------------------------------------------===//
648
649 class SOP1_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
650   SOP1 <outs, ins, "", pattern>,
651   SIMCInstr<opName, SISubtarget.NONE> {
652   let isPseudo = 1;
653   let isCodeGenOnly = 1;
654 }
655
656 class SOP1_Real_si <sop1 op, string opName, dag outs, dag ins, string asm> :
657   SOP1 <outs, ins, asm, []>,
658   SOP1e <op.SI>,
659   SIMCInstr<opName, SISubtarget.SI> {
660   let isCodeGenOnly = 0;
661   let AssemblerPredicates = [isSICI];
662 }
663
664 class SOP1_Real_vi <sop1 op, string opName, dag outs, dag ins, string asm> :
665   SOP1 <outs, ins, asm, []>,
666   SOP1e <op.VI>,
667   SIMCInstr<opName, SISubtarget.VI> {
668   let isCodeGenOnly = 0;
669   let AssemblerPredicates = [isVI];
670 }
671
672 multiclass SOP1_m <sop1 op, string opName, dag outs, dag ins, string asm,
673                    list<dag> pattern> {
674
675   def "" : SOP1_Pseudo <opName, outs, ins, pattern>;
676
677   def _si : SOP1_Real_si <op, opName, outs, ins, asm>;
678
679   def _vi : SOP1_Real_vi <op, opName, outs, ins, asm>;
680
681 }
682
683 multiclass SOP1_32 <sop1 op, string opName, list<dag> pattern> : SOP1_m <
684     op, opName, (outs SReg_32:$dst), (ins SSrc_32:$src0),
685     opName#" $dst, $src0", pattern
686 >;
687
688 multiclass SOP1_64 <sop1 op, string opName, list<dag> pattern> : SOP1_m <
689     op, opName, (outs SReg_64:$dst), (ins SSrc_64:$src0),
690     opName#" $dst, $src0", pattern
691 >;
692
693 // no input, 64-bit output.
694 multiclass SOP1_64_0 <sop1 op, string opName, list<dag> pattern> {
695   def "" : SOP1_Pseudo <opName, (outs SReg_64:$dst), (ins), pattern>;
696
697   def _si : SOP1_Real_si <op, opName, (outs SReg_64:$dst), (ins),
698     opName#" $dst"> {
699     let ssrc0 = 0;
700   }
701
702   def _vi : SOP1_Real_vi <op, opName, (outs SReg_64:$dst), (ins),
703     opName#" $dst"> {
704     let ssrc0 = 0;
705   }
706 }
707
708 // 64-bit input, no output
709 multiclass SOP1_1 <sop1 op, string opName, list<dag> pattern> {
710   def "" : SOP1_Pseudo <opName, (outs), (ins SReg_64:$src0), pattern>;
711
712   def _si : SOP1_Real_si <op, opName, (outs), (ins SReg_64:$src0),
713     opName#" $src0"> {
714     let sdst = 0;
715   }
716
717   def _vi : SOP1_Real_vi <op, opName, (outs), (ins SReg_64:$src0),
718     opName#" $src0"> {
719     let sdst = 0;
720   }
721 }
722
723 // 64-bit input, 32-bit output.
724 multiclass SOP1_32_64 <sop1 op, string opName, list<dag> pattern> : SOP1_m <
725     op, opName, (outs SReg_32:$dst), (ins SSrc_64:$src0),
726     opName#" $dst, $src0", pattern
727 >;
728
729 class SOP2_Pseudo<string opName, dag outs, dag ins, list<dag> pattern> :
730   SOP2<outs, ins, "", pattern>,
731   SIMCInstr<opName, SISubtarget.NONE> {
732   let isPseudo = 1;
733   let isCodeGenOnly = 1;
734   let Size = 4;
735
736   // Pseudo instructions have no encodings, but adding this field here allows
737   // us to do:
738   // let sdst = xxx in {
739   // for multiclasses that include both real and pseudo instructions.
740   field bits<7> sdst = 0;
741 }
742
743 class SOP2_Real_si<sop2 op, string opName, dag outs, dag ins, string asm> :
744   SOP2<outs, ins, asm, []>,
745   SOP2e<op.SI>,
746   SIMCInstr<opName, SISubtarget.SI> {
747   let AssemblerPredicates = [isSICI];
748 }
749
750 class SOP2_Real_vi<sop2 op, string opName, dag outs, dag ins, string asm> :
751   SOP2<outs, ins, asm, []>,
752   SOP2e<op.VI>,
753   SIMCInstr<opName, SISubtarget.VI> {
754   let AssemblerPredicates = [isVI];
755 }
756
757 multiclass SOP2_m <sop2 op, string opName, dag outs, dag ins, string asm,
758                    list<dag> pattern> {
759
760   def "" : SOP2_Pseudo <opName, outs, ins, pattern>;
761
762   def _si : SOP2_Real_si <op, opName, outs, ins, asm>;
763
764   def _vi : SOP2_Real_vi <op, opName, outs, ins, asm>;
765
766 }
767
768 multiclass SOP2_32 <sop2 op, string opName, list<dag> pattern> : SOP2_m <
769     op, opName, (outs SReg_32:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
770     opName#" $dst, $src0, $src1", pattern
771 >;
772
773 multiclass SOP2_64 <sop2 op, string opName, list<dag> pattern> : SOP2_m <
774     op, opName, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
775     opName#" $dst, $src0, $src1", pattern
776 >;
777
778 multiclass SOP2_64_32 <sop2 op, string opName, list<dag> pattern> : SOP2_m <
779     op, opName, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_32:$src1),
780     opName#" $dst, $src0, $src1", pattern
781 >;
782
783 class SOPC_Helper <bits<7> op, RegisterOperand rc, ValueType vt,
784                     string opName, PatLeaf cond> : SOPC <
785   op, (outs), (ins rc:$src0, rc:$src1),
786   opName#" $src0, $src1", []> {
787   let Defs = [SCC];
788 }
789
790 class SOPC_32<bits<7> op, string opName, PatLeaf cond = COND_NULL>
791   : SOPC_Helper<op, SSrc_32, i32, opName, cond>;
792
793 class SOPC_64<bits<7> op, string opName, PatLeaf cond = COND_NULL>
794   : SOPC_Helper<op, SSrc_64, i64, opName, cond>;
795
796 class SOPK_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
797   SOPK <outs, ins, "", pattern>,
798   SIMCInstr<opName, SISubtarget.NONE> {
799   let isPseudo = 1;
800   let isCodeGenOnly = 1;
801 }
802
803 class SOPK_Real_si <sopk op, string opName, dag outs, dag ins, string asm> :
804   SOPK <outs, ins, asm, []>,
805   SOPKe <op.SI>,
806   SIMCInstr<opName, SISubtarget.SI> {
807   let AssemblerPredicates = [isSICI];
808   let isCodeGenOnly = 0;
809 }
810
811 class SOPK_Real_vi <sopk op, string opName, dag outs, dag ins, string asm> :
812   SOPK <outs, ins, asm, []>,
813   SOPKe <op.VI>,
814   SIMCInstr<opName, SISubtarget.VI> {
815   let AssemblerPredicates = [isVI];
816   let isCodeGenOnly = 0;
817 }
818
819 multiclass SOPK_m <sopk op, string opName, dag outs, dag ins, string opAsm,
820                    string asm = opName#opAsm> {
821   def "" : SOPK_Pseudo <opName, outs, ins, []>;
822
823   def _si : SOPK_Real_si <op, opName, outs, ins, asm>;
824
825   def _vi : SOPK_Real_vi <op, opName, outs, ins, asm>;
826
827 }
828
829 multiclass SOPK_32 <sopk op, string opName, list<dag> pattern> {
830   def "" : SOPK_Pseudo <opName, (outs SReg_32:$dst), (ins u16imm:$src0),
831     pattern>;
832
833   def _si : SOPK_Real_si <op, opName, (outs SReg_32:$dst), (ins u16imm:$src0),
834     opName#" $dst, $src0">;
835
836   def _vi : SOPK_Real_vi <op, opName, (outs SReg_32:$dst), (ins u16imm:$src0),
837     opName#" $dst, $src0">;
838 }
839
840 multiclass SOPK_SCC <sopk op, string opName, list<dag> pattern> {
841   def "" : SOPK_Pseudo <opName, (outs),
842     (ins SReg_32:$src0, u16imm:$src1), pattern> {
843     let Defs = [SCC];
844   }
845
846
847   def _si : SOPK_Real_si <op, opName, (outs),
848     (ins SReg_32:$sdst, u16imm:$simm16), opName#" $sdst, $simm16"> {
849     let Defs = [SCC];
850   }
851
852   def _vi : SOPK_Real_vi <op, opName, (outs),
853     (ins SReg_32:$sdst, u16imm:$simm16), opName#" $sdst, $simm16"> {
854     let Defs = [SCC];
855   }
856 }
857
858 multiclass SOPK_32TIE <sopk op, string opName, list<dag> pattern> : SOPK_m <
859   op, opName, (outs SReg_32:$sdst), (ins SReg_32:$src0, u16imm:$simm16),
860   " $sdst, $simm16"
861 >;
862
863 multiclass SOPK_IMM32 <sopk op, string opName, dag outs, dag ins,
864                        string argAsm, string asm = opName#argAsm> {
865
866   def "" : SOPK_Pseudo <opName, outs, ins, []>;
867
868   def _si : SOPK <outs, ins, asm, []>,
869             SOPK64e <op.SI>,
870             SIMCInstr<opName, SISubtarget.SI> {
871               let AssemblerPredicates = [isSICI];
872               let isCodeGenOnly = 0;
873             }
874
875   def _vi : SOPK <outs, ins, asm, []>,
876             SOPK64e <op.VI>,
877             SIMCInstr<opName, SISubtarget.VI> {
878               let AssemblerPredicates = [isVI];
879               let isCodeGenOnly = 0;
880             }
881 }
882 //===----------------------------------------------------------------------===//
883 // SMRD classes
884 //===----------------------------------------------------------------------===//
885
886 class SMRD_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
887   SMRD <outs, ins, "", pattern>,
888   SIMCInstr<opName, SISubtarget.NONE> {
889   let isPseudo = 1;
890   let isCodeGenOnly = 1;
891 }
892
893 class SMRD_Real_si <bits<5> op, string opName, bit imm, dag outs, dag ins,
894                     string asm> :
895   SMRD <outs, ins, asm, []>,
896   SMRDe <op, imm>,
897   SIMCInstr<opName, SISubtarget.SI> {
898   let AssemblerPredicates = [isSICI];
899 }
900
901 class SMRD_Real_vi <bits<8> op, string opName, bit imm, dag outs, dag ins,
902                     string asm> :
903   SMRD <outs, ins, asm, []>,
904   SMEMe_vi <op, imm>,
905   SIMCInstr<opName, SISubtarget.VI> {
906   let AssemblerPredicates = [isVI];
907 }
908
909 multiclass SMRD_m <smrd op, string opName, bit imm, dag outs, dag ins,
910                    string asm, list<dag> pattern> {
911
912   def "" : SMRD_Pseudo <opName, outs, ins, pattern>;
913
914   def _si : SMRD_Real_si <op.SI, opName, imm, outs, ins, asm>;
915
916   // glc is only applicable to scalar stores, which are not yet
917   // implemented.
918   let glc = 0 in {
919     def _vi : SMRD_Real_vi <op.VI, opName, imm, outs, ins, asm>;
920   }
921 }
922
923 multiclass SMRD_Helper <smrd op, string opName, RegisterClass baseClass,
924                         RegisterClass dstClass> {
925   defm _IMM : SMRD_m <
926     op, opName#"_IMM", 1, (outs dstClass:$dst),
927     (ins baseClass:$sbase, smrd_offset:$offset),
928     opName#" $dst, $sbase, $offset", []
929   >;
930
931   def _IMM_ci : SMRD <
932     (outs dstClass:$dst), (ins baseClass:$sbase, smrd_literal_offset:$offset),
933     opName#" $dst, $sbase, $offset", []>, SMRD_IMMe_ci <op.SI> {
934     let AssemblerPredicates = [isCIOnly];
935   }
936
937   defm _SGPR : SMRD_m <
938     op, opName#"_SGPR", 0, (outs dstClass:$dst),
939     (ins baseClass:$sbase, SReg_32:$soff),
940     opName#" $dst, $sbase, $soff", []
941   >;
942 }
943
944 //===----------------------------------------------------------------------===//
945 // Vector ALU classes
946 //===----------------------------------------------------------------------===//
947
948 // This must always be right before the operand being input modified.
949 def InputMods : OperandWithDefaultOps <i32, (ops (i32 0))> {
950   let PrintMethod = "printOperandAndMods";
951 }
952
953 def InputModsMatchClass : AsmOperandClass {
954   let Name = "RegWithInputMods";
955 }
956
957 def InputModsNoDefault : Operand <i32> {
958   let PrintMethod = "printOperandAndMods";
959   let ParserMatchClass = InputModsMatchClass;
960 }
961
962 class getNumSrcArgs<ValueType Src1, ValueType Src2> {
963   int ret =
964     !if (!eq(Src1.Value, untyped.Value),      1,   // VOP1
965          !if (!eq(Src2.Value, untyped.Value), 2,   // VOP2
966                                               3)); // VOP3
967 }
968
969 // Returns the register class to use for the destination of VOP[123C]
970 // instructions for the given VT.
971 class getVALUDstForVT<ValueType VT> {
972   RegisterOperand ret = !if(!eq(VT.Size, 32), VOPDstOperand<VGPR_32>,
973                           !if(!eq(VT.Size, 64), VOPDstOperand<VReg_64>,
974                             !if(!eq(VT.Size, 16), VOPDstOperand<VGPR_32>,
975                             VOPDstOperand<SReg_64>))); // else VT == i1
976 }
977
978 // Returns the register class to use for source 0 of VOP[12C]
979 // instructions for the given VT.
980 class getVOPSrc0ForVT<ValueType VT> {
981   RegisterOperand ret = !if(!eq(VT.Size, 64), VSrc_64, VSrc_32);
982 }
983
984 // Returns the register class to use for source 1 of VOP[12C] for the
985 // given VT.
986 class getVOPSrc1ForVT<ValueType VT> {
987   RegisterClass ret = !if(!eq(VT.Size, 64), VReg_64, VGPR_32);
988 }
989
990 // Returns the register class to use for sources of VOP3 instructions for the
991 // given VT.
992 class getVOP3SrcForVT<ValueType VT> {
993   RegisterOperand ret = !if(!eq(VT.Size, 64), VCSrc_64, VCSrc_32);
994 }
995
996 // Returns 1 if the source arguments have modifiers, 0 if they do not.
997 // XXX - do f16 instructions?
998 class hasModifiers<ValueType SrcVT> {
999   bit ret = !if(!eq(SrcVT.Value, f32.Value), 1,
1000             !if(!eq(SrcVT.Value, f64.Value), 1, 0));
1001 }
1002
1003 // Returns the input arguments for VOP[12C] instructions for the given SrcVT.
1004 class getIns32 <RegisterOperand Src0RC, RegisterClass Src1RC, int NumSrcArgs> {
1005   dag ret = !if(!eq(NumSrcArgs, 1), (ins Src0RC:$src0),               // VOP1
1006             !if(!eq(NumSrcArgs, 2), (ins Src0RC:$src0, Src1RC:$src1), // VOP2
1007                                     (ins)));
1008 }
1009
1010 // Returns the input arguments for VOP3 instructions for the given SrcVT.
1011 class getIns64 <RegisterOperand Src0RC, RegisterOperand Src1RC,
1012                 RegisterOperand Src2RC, int NumSrcArgs,
1013                 bit HasModifiers> {
1014
1015   dag ret =
1016     !if (!eq(NumSrcArgs, 1),
1017       !if (!eq(HasModifiers, 1),
1018         // VOP1 with modifiers
1019         (ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0,
1020              ClampMod:$clamp, omod:$omod)
1021       /* else */,
1022         // VOP1 without modifiers
1023         (ins Src0RC:$src0)
1024       /* endif */ ),
1025     !if (!eq(NumSrcArgs, 2),
1026       !if (!eq(HasModifiers, 1),
1027         // VOP 2 with modifiers
1028         (ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0,
1029              InputModsNoDefault:$src1_modifiers, Src1RC:$src1,
1030              ClampMod:$clamp, omod:$omod)
1031       /* else */,
1032         // VOP2 without modifiers
1033         (ins Src0RC:$src0, Src1RC:$src1)
1034       /* endif */ )
1035     /* NumSrcArgs == 3 */,
1036       !if (!eq(HasModifiers, 1),
1037         // VOP3 with modifiers
1038         (ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0,
1039              InputModsNoDefault:$src1_modifiers, Src1RC:$src1,
1040              InputModsNoDefault:$src2_modifiers, Src2RC:$src2,
1041              ClampMod:$clamp, omod:$omod)
1042       /* else */,
1043         // VOP3 without modifiers
1044         (ins Src0RC:$src0, Src1RC:$src1, Src2RC:$src2)
1045       /* endif */ )));
1046 }
1047
1048 // Returns the assembly string for the inputs and outputs of a VOP[12C]
1049 // instruction.  This does not add the _e32 suffix, so it can be reused
1050 // by getAsm64.
1051 class getAsm32 <int NumSrcArgs> {
1052   string src1 = ", $src1";
1053   string src2 = ", $src2";
1054   string ret = "$dst, $src0"#
1055                !if(!eq(NumSrcArgs, 1), "", src1)#
1056                !if(!eq(NumSrcArgs, 3), src2, "");
1057 }
1058
1059 // Returns the assembly string for the inputs and outputs of a VOP3
1060 // instruction.
1061 class getAsm64 <int NumSrcArgs, bit HasModifiers> {
1062   string src0 = !if(!eq(NumSrcArgs, 1), "$src0_modifiers", "$src0_modifiers,");
1063   string src1 = !if(!eq(NumSrcArgs, 1), "",
1064                    !if(!eq(NumSrcArgs, 2), " $src1_modifiers",
1065                                            " $src1_modifiers,"));
1066   string src2 = !if(!eq(NumSrcArgs, 3), " $src2_modifiers", "");
1067   string ret =
1068   !if(!eq(HasModifiers, 0),
1069       getAsm32<NumSrcArgs>.ret,
1070       "$dst, "#src0#src1#src2#"$clamp"#"$omod");
1071 }
1072
1073
1074 class VOPProfile <list<ValueType> _ArgVT> {
1075
1076   field list<ValueType> ArgVT = _ArgVT;
1077
1078   field ValueType DstVT = ArgVT[0];
1079   field ValueType Src0VT = ArgVT[1];
1080   field ValueType Src1VT = ArgVT[2];
1081   field ValueType Src2VT = ArgVT[3];
1082   field RegisterOperand DstRC = getVALUDstForVT<DstVT>.ret;
1083   field RegisterOperand Src0RC32 = getVOPSrc0ForVT<Src0VT>.ret;
1084   field RegisterClass Src1RC32 = getVOPSrc1ForVT<Src1VT>.ret;
1085   field RegisterOperand Src0RC64 = getVOP3SrcForVT<Src0VT>.ret;
1086   field RegisterOperand Src1RC64 = getVOP3SrcForVT<Src1VT>.ret;
1087   field RegisterOperand Src2RC64 = getVOP3SrcForVT<Src2VT>.ret;
1088
1089   field int NumSrcArgs = getNumSrcArgs<Src1VT, Src2VT>.ret;
1090   field bit HasModifiers = hasModifiers<Src0VT>.ret;
1091
1092   field dag Outs = (outs DstRC:$dst);
1093
1094   // VOP3b instructions are a special case with a second explicit
1095   // output. This is manually overridden for them.
1096   field dag Outs32 = Outs;
1097   field dag Outs64 = Outs;
1098
1099   field dag Ins32 = getIns32<Src0RC32, Src1RC32, NumSrcArgs>.ret;
1100   field dag Ins64 = getIns64<Src0RC64, Src1RC64, Src2RC64, NumSrcArgs,
1101                              HasModifiers>.ret;
1102
1103   field string Asm32 = getAsm32<NumSrcArgs>.ret;
1104   field string Asm64 = getAsm64<NumSrcArgs, HasModifiers>.ret;
1105 }
1106
1107 // FIXME: I think these F16/I16 profiles will need to use f16/i16 types in order
1108 //        for the instruction patterns to work.
1109 def VOP_F16_F16 : VOPProfile <[f16, f16, untyped, untyped]>;
1110 def VOP_F16_I16 : VOPProfile <[f16, i32, untyped, untyped]>;
1111 def VOP_I16_F16 : VOPProfile <[i32, f16, untyped, untyped]>;
1112
1113 def VOP_F16_F16_F16 : VOPProfile <[f16, f16, f16, untyped]>;
1114 def VOP_F16_F16_I16 : VOPProfile <[f16, f16, i32, untyped]>;
1115 def VOP_I16_I16_I16 : VOPProfile <[i32, i32, i32, untyped]>;
1116
1117 def VOP_F32_F32 : VOPProfile <[f32, f32, untyped, untyped]>;
1118 def VOP_F32_F64 : VOPProfile <[f32, f64, untyped, untyped]>;
1119 def VOP_F32_I32 : VOPProfile <[f32, i32, untyped, untyped]>;
1120 def VOP_F64_F32 : VOPProfile <[f64, f32, untyped, untyped]>;
1121 def VOP_F64_F64 : VOPProfile <[f64, f64, untyped, untyped]>;
1122 def VOP_F64_I32 : VOPProfile <[f64, i32, untyped, untyped]>;
1123 def VOP_I32_F32 : VOPProfile <[i32, f32, untyped, untyped]>;
1124 def VOP_I32_F64 : VOPProfile <[i32, f64, untyped, untyped]>;
1125 def VOP_I32_I32 : VOPProfile <[i32, i32, untyped, untyped]>;
1126
1127 def VOP_F32_F32_F32 : VOPProfile <[f32, f32, f32, untyped]>;
1128 def VOP_F32_F32_I32 : VOPProfile <[f32, f32, i32, untyped]>;
1129 def VOP_F64_F64_F64 : VOPProfile <[f64, f64, f64, untyped]>;
1130 def VOP_F64_F64_I32 : VOPProfile <[f64, f64, i32, untyped]>;
1131 def VOP_I32_F32_F32 : VOPProfile <[i32, f32, f32, untyped]>;
1132 def VOP_I32_F32_I32 : VOPProfile <[i32, f32, i32, untyped]>;
1133 def VOP_I32_I32_I32 : VOPProfile <[i32, i32, i32, untyped]>;
1134
1135 class VOP2b_Profile<ValueType vt> : VOPProfile<[vt, vt, vt, untyped]> {
1136   let Asm32 = "$dst, vcc, $src0, $src1";
1137   let Asm64 = "$dst, $sdst, $src0, $src1";
1138   let Outs32 = (outs DstRC:$dst);
1139   let Outs64 = (outs DstRC:$dst, SReg_64:$sdst);
1140 }
1141
1142 def VOP2b_I32_I1_I32_I32 : VOP2b_Profile<i32>;
1143
1144 def VOP2b_I32_I1_I32_I32_VCC : VOP2b_Profile<i32> {
1145   let Src0RC32 = VCSrc_32;
1146 }
1147
1148 // VOPC instructions are a special case because for the 32-bit
1149 // encoding, we want to display the implicit vcc write as if it were
1150 // an explicit $dst.
1151 class VOPC_Profile<ValueType vt0, ValueType vt1 = vt0> : VOPProfile <[i1, vt0, vt1, untyped]> {
1152   let Asm32 = "vcc, $src0, $src1";
1153 }
1154
1155 class VOPC_Class_Profile<ValueType vt> : VOPC_Profile<vt, i32> {
1156   let Ins64 = (ins InputModsNoDefault:$src0_modifiers, Src0RC64:$src0, Src1RC64:$src1);
1157   let Asm64 = "$dst, $src0_modifiers, $src1";
1158 }
1159
1160 def VOPC_I1_F32_F32 : VOPC_Profile<f32>;
1161 def VOPC_I1_F64_F64 : VOPC_Profile<f64>;
1162 def VOPC_I1_I32_I32 : VOPC_Profile<i32>;
1163 def VOPC_I1_I64_I64 : VOPC_Profile<i64>;
1164
1165 def VOPC_I1_F32_I32 : VOPC_Class_Profile<f32>;
1166 def VOPC_I1_F64_I32 : VOPC_Class_Profile<f64>;
1167
1168 def VOP_I64_I64_I32 : VOPProfile <[i64, i64, i32, untyped]>;
1169 def VOP_I64_I32_I64 : VOPProfile <[i64, i32, i64, untyped]>;
1170 def VOP_I64_I64_I64 : VOPProfile <[i64, i64, i64, untyped]>;
1171 def VOP_CNDMASK : VOPProfile <[i32, i32, i32, untyped]> {
1172   let Ins32 = (ins Src0RC32:$src0, Src1RC32:$src1);
1173   let Ins64 = (ins Src0RC64:$src0, Src1RC64:$src1, SSrc_64:$src2);
1174   let Asm64 = "$dst, $src0, $src1, $src2";
1175 }
1176
1177 def VOP_F32_F32_F32_F32 : VOPProfile <[f32, f32, f32, f32]>;
1178 def VOP_MADK : VOPProfile <[f32, f32, f32, f32]> {
1179   field dag Ins = (ins VCSrc_32:$src0, VGPR_32:$vsrc1, u32imm:$src2);
1180   field string Asm = "$dst, $src0, $vsrc1, $src2";
1181 }
1182 def VOP_MAC : VOPProfile <[f32, f32, f32, f32]> {
1183   let Ins32 = (ins Src0RC32:$src0, Src1RC32:$src1, VGPR_32:$src2);
1184   let Ins64 = getIns64<Src0RC64, Src1RC64, RegisterOperand<VGPR_32>, 3,
1185                              HasModifiers>.ret;
1186   let Asm32 = getAsm32<2>.ret;
1187   let Asm64 = getAsm64<2, HasModifiers>.ret;
1188 }
1189 def VOP_F64_F64_F64_F64 : VOPProfile <[f64, f64, f64, f64]>;
1190 def VOP_I32_I32_I32_I32 : VOPProfile <[i32, i32, i32, i32]>;
1191 def VOP_I64_I32_I32_I64 : VOPProfile <[i64, i32, i32, i64]>;
1192
1193 class SIInstAlias <string asm, dag result> : InstAlias <asm, result>,
1194                                              PredicateControl {
1195   field bit isCompare;
1196   field bit isCommutable;
1197 }
1198
1199 class VOP <string opName> {
1200   string OpName = opName;
1201 }
1202
1203 class VOP2_REV <string revOp, bit isOrig> {
1204   string RevOp = revOp;
1205   bit IsOrig = isOrig;
1206 }
1207
1208 class AtomicNoRet <string noRetOp, bit isRet> {
1209   string NoRetOp = noRetOp;
1210   bit IsRet = isRet;
1211 }
1212
1213 class VOP1_Pseudo <dag outs, dag ins, list<dag> pattern, string opName> :
1214   VOP1Common <outs, ins, "", pattern>,
1215   VOP <opName>,
1216   SIMCInstr <opName#"_e32", SISubtarget.NONE>,
1217   MnemonicAlias<opName#"_e32", opName> {
1218   let isPseudo = 1;
1219   let isCodeGenOnly = 1;
1220
1221   field bits<8> vdst;
1222   field bits<9> src0;
1223 }
1224
1225 class VOP1_Real_si <string opName, vop1 op, dag outs, dag ins, string asm> :
1226   VOP1<op.SI, outs, ins, asm, []>,
1227   SIMCInstr <opName#"_e32", SISubtarget.SI> {
1228   let AssemblerPredicate = SIAssemblerPredicate;
1229 }
1230
1231 class VOP1_Real_vi <string opName, vop1 op, dag outs, dag ins, string asm> :
1232   VOP1<op.VI, outs, ins, asm, []>,
1233   SIMCInstr <opName#"_e32", SISubtarget.VI> {
1234   let AssemblerPredicates = [isVI];
1235 }
1236
1237 multiclass VOP1_m <vop1 op, dag outs, dag ins, string asm, list<dag> pattern,
1238                    string opName> {
1239   def "" : VOP1_Pseudo <outs, ins, pattern, opName>;
1240
1241   def _si : VOP1_Real_si <opName, op, outs, ins, asm>;
1242
1243   def _vi : VOP1_Real_vi <opName, op, outs, ins, asm>;
1244 }
1245
1246 multiclass VOP1SI_m <vop1 op, dag outs, dag ins, string asm, list<dag> pattern,
1247                    string opName> {
1248   def "" : VOP1_Pseudo <outs, ins, pattern, opName>;
1249
1250   def _si : VOP1_Real_si <opName, op, outs, ins, asm>;
1251 }
1252
1253 class VOP2_Pseudo <dag outs, dag ins, list<dag> pattern, string opName> :
1254   VOP2Common <outs, ins, "", pattern>,
1255   VOP <opName>,
1256   SIMCInstr<opName#"_e32", SISubtarget.NONE>,
1257   MnemonicAlias<opName#"_e32", opName> {
1258   let isPseudo = 1;
1259   let isCodeGenOnly = 1;
1260 }
1261
1262 class VOP2_Real_si <string opName, vop2 op, dag outs, dag ins, string asm> :
1263   VOP2 <op.SI, outs, ins, opName#asm, []>,
1264   SIMCInstr <opName#"_e32", SISubtarget.SI> {
1265   let AssemblerPredicates = [isSICI];
1266 }
1267
1268 class VOP2_Real_vi <string opName, vop2 op, dag outs, dag ins, string asm> :
1269   VOP2 <op.VI, outs, ins, opName#asm, []>,
1270   SIMCInstr <opName#"_e32", SISubtarget.VI> {
1271   let AssemblerPredicates = [isVI];
1272 }
1273
1274 multiclass VOP2SI_m <vop2 op, dag outs, dag ins, string asm, list<dag> pattern,
1275                      string opName, string revOp> {
1276   def "" : VOP2_Pseudo <outs, ins, pattern, opName>,
1277            VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
1278
1279   def _si : VOP2_Real_si <opName, op, outs, ins, asm>;
1280 }
1281
1282 multiclass VOP2_m <vop2 op, dag outs, dag ins, string asm, list<dag> pattern,
1283                    string opName, string revOp> {
1284   def "" : VOP2_Pseudo <outs, ins, pattern, opName>,
1285            VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
1286
1287   def _si : VOP2_Real_si <opName, op, outs, ins, asm>;
1288
1289   def _vi : VOP2_Real_vi <opName, op, outs, ins, asm>;
1290
1291 }
1292
1293 class VOP3DisableFields <bit HasSrc1, bit HasSrc2, bit HasModifiers> {
1294
1295   bits<2> src0_modifiers = !if(HasModifiers, ?, 0);
1296   bits<2> src1_modifiers = !if(HasModifiers, !if(HasSrc1, ?, 0), 0);
1297   bits<2> src2_modifiers = !if(HasModifiers, !if(HasSrc2, ?, 0), 0);
1298   bits<2> omod = !if(HasModifiers, ?, 0);
1299   bits<1> clamp = !if(HasModifiers, ?, 0);
1300   bits<9> src1 = !if(HasSrc1, ?, 0);
1301   bits<9> src2 = !if(HasSrc2, ?, 0);
1302 }
1303
1304 class VOP3DisableModFields <bit HasSrc0Mods,
1305                             bit HasSrc1Mods = 0,
1306                             bit HasSrc2Mods = 0,
1307                             bit HasOutputMods = 0> {
1308   bits<2> src0_modifiers = !if(HasSrc0Mods, ?, 0);
1309   bits<2> src1_modifiers = !if(HasSrc1Mods, ?, 0);
1310   bits<2> src2_modifiers = !if(HasSrc2Mods, ?, 0);
1311   bits<2> omod = !if(HasOutputMods, ?, 0);
1312   bits<1> clamp = !if(HasOutputMods, ?, 0);
1313 }
1314
1315 class VOP3_Pseudo <dag outs, dag ins, list<dag> pattern, string opName> :
1316   VOP3Common <outs, ins, "", pattern>,
1317   VOP <opName>,
1318   SIMCInstr<opName#"_e64", SISubtarget.NONE>,
1319   MnemonicAlias<opName#"_e64", opName> {
1320   let isPseudo = 1;
1321   let isCodeGenOnly = 1;
1322 }
1323
1324 class VOP3_Real_si <bits<9> op, dag outs, dag ins, string asm, string opName> :
1325   VOP3Common <outs, ins, asm, []>,
1326   VOP3e <op>,
1327   SIMCInstr<opName#"_e64", SISubtarget.SI> {
1328   let AssemblerPredicates = [isSICI];
1329 }
1330
1331 class VOP3_Real_vi <bits<10> op, dag outs, dag ins, string asm, string opName> :
1332   VOP3Common <outs, ins, asm, []>,
1333   VOP3e_vi <op>,
1334   SIMCInstr <opName#"_e64", SISubtarget.VI> {
1335   let AssemblerPredicates = [isVI];
1336 }
1337
1338 class VOP3b_Real_si <bits<9> op, dag outs, dag ins, string asm, string opName> :
1339   VOP3Common <outs, ins, asm, []>,
1340   VOP3be <op>,
1341   SIMCInstr<opName#"_e64", SISubtarget.SI> {
1342   let AssemblerPredicates = [isSICI];
1343 }
1344
1345 class VOP3b_Real_vi <bits<10> op, dag outs, dag ins, string asm, string opName> :
1346   VOP3Common <outs, ins, asm, []>,
1347   VOP3be_vi <op>,
1348   SIMCInstr <opName#"_e64", SISubtarget.VI> {
1349   let AssemblerPredicates = [isVI];
1350 }
1351
1352 multiclass VOP3_m <vop op, dag outs, dag ins, string asm, list<dag> pattern,
1353                    string opName, int NumSrcArgs, bit HasMods = 1> {
1354
1355   def "" : VOP3_Pseudo <outs, ins, pattern, opName>;
1356
1357   def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>,
1358             VOP3DisableFields<!if(!eq(NumSrcArgs, 1), 0, 1),
1359                               !if(!eq(NumSrcArgs, 2), 0, 1),
1360                               HasMods>;
1361   def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName>,
1362             VOP3DisableFields<!if(!eq(NumSrcArgs, 1), 0, 1),
1363                               !if(!eq(NumSrcArgs, 2), 0, 1),
1364                               HasMods>;
1365 }
1366
1367 // VOP3_m without source modifiers
1368 multiclass VOP3_m_nomods <vop op, dag outs, dag ins, string asm, list<dag> pattern,
1369                    string opName, int NumSrcArgs, bit HasMods = 1> {
1370
1371   def "" : VOP3_Pseudo <outs, ins, pattern, opName>;
1372
1373   let src0_modifiers = 0,
1374       src1_modifiers = 0,
1375       src2_modifiers = 0,
1376       clamp = 0,
1377       omod = 0 in {
1378     def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>;
1379     def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName>;
1380   }
1381 }
1382
1383 multiclass VOP3_1_m <vop op, dag outs, dag ins, string asm,
1384                      list<dag> pattern, string opName, bit HasMods = 1> {
1385
1386   def "" : VOP3_Pseudo <outs, ins, pattern, opName>;
1387
1388   def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>,
1389             VOP3DisableFields<0, 0, HasMods>;
1390
1391   def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName>,
1392             VOP3DisableFields<0, 0, HasMods>;
1393 }
1394
1395 multiclass VOP3SI_1_m <vop op, dag outs, dag ins, string asm,
1396                      list<dag> pattern, string opName, bit HasMods = 1> {
1397
1398   def "" : VOP3_Pseudo <outs, ins, pattern, opName>;
1399
1400   def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>,
1401             VOP3DisableFields<0, 0, HasMods>;
1402   // No VI instruction. This class is for SI only.
1403 }
1404
1405 multiclass VOP3_2_m <vop op, dag outs, dag ins, string asm,
1406                      list<dag> pattern, string opName, string revOp,
1407                      bit HasMods = 1, bit UseFullOp = 0> {
1408
1409   def "" : VOP3_Pseudo <outs, ins, pattern, opName>,
1410            VOP2_REV<revOp#"_e64", !eq(revOp, opName)>;
1411
1412   def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>,
1413             VOP3DisableFields<1, 0, HasMods>;
1414
1415   def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName>,
1416             VOP3DisableFields<1, 0, HasMods>;
1417 }
1418
1419 multiclass VOP3SI_2_m <vop op, dag outs, dag ins, string asm,
1420                      list<dag> pattern, string opName, string revOp,
1421                      bit HasMods = 1, bit UseFullOp = 0> {
1422
1423   def "" : VOP3_Pseudo <outs, ins, pattern, opName>,
1424            VOP2_REV<revOp#"_e64", !eq(revOp, opName)>;
1425
1426   def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>,
1427             VOP3DisableFields<1, 0, HasMods>;
1428
1429   // No VI instruction. This class is for SI only.
1430 }
1431
1432 // XXX - Is v_div_scale_{f32|f64} only available in vop3b without
1433 // option of implicit vcc use?
1434 multiclass VOP3b_2_m <vop op, dag outs, dag ins, string asm,
1435                       list<dag> pattern, string opName, string revOp,
1436                       bit HasMods = 1, bit UseFullOp = 0> {
1437   def "" : VOP3_Pseudo <outs, ins, pattern, opName>,
1438            VOP2_REV<revOp#"_e64", !eq(revOp, opName)>;
1439
1440   def _si : VOP3b_Real_si <op.SI3, outs, ins, asm, opName>,
1441             VOP3DisableFields<1, 0, HasMods>;
1442
1443   def _vi : VOP3b_Real_vi <op.VI3, outs, ins, asm, opName>,
1444             VOP3DisableFields<1, 0, HasMods>;
1445 }
1446
1447 multiclass VOP3b_3_m <vop op, dag outs, dag ins, string asm,
1448                       list<dag> pattern, string opName, string revOp,
1449                       bit HasMods = 1, bit UseFullOp = 0> {
1450   def "" : VOP3_Pseudo <outs, ins, pattern, opName>;
1451
1452
1453   def _si : VOP3b_Real_si <op.SI3, outs, ins, asm, opName>,
1454             VOP3DisableFields<1, 1, HasMods>;
1455
1456   def _vi : VOP3b_Real_vi <op.VI3, outs, ins, asm, opName>,
1457             VOP3DisableFields<1, 1, HasMods>;
1458 }
1459
1460 multiclass VOP3_C_m <vop op, dag outs, dag ins, string asm,
1461                      list<dag> pattern, string opName,
1462                      bit HasMods, bit defExec, string revOp> {
1463
1464   def "" : VOP3_Pseudo <outs, ins, pattern, opName>,
1465            VOP2_REV<revOp#"_e64", !eq(revOp, opName)>;
1466
1467   def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>,
1468             VOP3DisableFields<1, 0, HasMods> {
1469     let Defs = !if(defExec, [EXEC], []);
1470   }
1471
1472   def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName>,
1473             VOP3DisableFields<1, 0, HasMods> {
1474     let Defs = !if(defExec, [EXEC], []);
1475   }
1476 }
1477
1478 // An instruction that is VOP2 on SI and VOP3 on VI, no modifiers.
1479 multiclass VOP2SI_3VI_m <vop3 op, string opName, dag outs, dag ins,
1480                          string asm, list<dag> pattern = []> {
1481   let isPseudo = 1, isCodeGenOnly = 1 in {
1482     def "" : VOPAnyCommon <outs, ins, "", pattern>,
1483              SIMCInstr<opName, SISubtarget.NONE>;
1484   }
1485
1486   def _si : VOP2 <op.SI3{5-0}, outs, ins, asm, []>,
1487             SIMCInstr <opName, SISubtarget.SI> {
1488             let AssemblerPredicates = [isSICI];
1489   }
1490
1491   def _vi : VOP3Common <outs, ins, asm, []>,
1492             VOP3e_vi <op.VI3>,
1493             VOP3DisableFields <1, 0, 0>,
1494             SIMCInstr <opName, SISubtarget.VI> {
1495             let AssemblerPredicates = [isVI];
1496   }
1497 }
1498
1499 multiclass VOP1_Helper <vop1 op, string opName, dag outs,
1500                         dag ins32, string asm32, list<dag> pat32,
1501                         dag ins64, string asm64, list<dag> pat64,
1502                         bit HasMods> {
1503
1504   defm _e32 : VOP1_m <op, outs, ins32, opName#asm32, pat32, opName>;
1505
1506   defm _e64 : VOP3_1_m <op, outs, ins64, opName#asm64, pat64, opName, HasMods>;
1507 }
1508
1509 multiclass VOP1Inst <vop1 op, string opName, VOPProfile P,
1510                      SDPatternOperator node = null_frag> : VOP1_Helper <
1511   op, opName, P.Outs,
1512   P.Ins32, P.Asm32, [],
1513   P.Ins64, P.Asm64,
1514   !if(P.HasModifiers,
1515       [(set P.DstVT:$dst, (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0,
1516                                 i32:$src0_modifiers, i1:$clamp, i32:$omod))))],
1517       [(set P.DstVT:$dst, (node P.Src0VT:$src0))]),
1518   P.HasModifiers
1519 >;
1520
1521 multiclass VOP1InstSI <vop1 op, string opName, VOPProfile P,
1522                        SDPatternOperator node = null_frag> {
1523
1524   defm _e32 : VOP1SI_m <op, P.Outs, P.Ins32, opName#P.Asm32, [], opName>;
1525
1526   defm _e64 : VOP3SI_1_m <op, P.Outs, P.Ins64, opName#P.Asm64,
1527     !if(P.HasModifiers,
1528       [(set P.DstVT:$dst, (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0,
1529                                 i32:$src0_modifiers, i1:$clamp, i32:$omod))))],
1530       [(set P.DstVT:$dst, (node P.Src0VT:$src0))]),
1531     opName, P.HasModifiers>;
1532 }
1533
1534 multiclass VOP2_Helper <vop2 op, string opName, dag outs,
1535                         dag ins32, string asm32, list<dag> pat32,
1536                         dag ins64, string asm64, list<dag> pat64,
1537                         string revOp, bit HasMods> {
1538   defm _e32 : VOP2_m <op, outs, ins32, asm32, pat32, opName, revOp>;
1539
1540   defm _e64 : VOP3_2_m <op,
1541     outs, ins64, opName#asm64, pat64, opName, revOp, HasMods
1542   >;
1543 }
1544
1545 multiclass VOP2Inst <vop2 op, string opName, VOPProfile P,
1546                      SDPatternOperator node = null_frag,
1547                      string revOp = opName> : VOP2_Helper <
1548   op, opName, P.Outs,
1549   P.Ins32, P.Asm32, [],
1550   P.Ins64, P.Asm64,
1551   !if(P.HasModifiers,
1552       [(set P.DstVT:$dst,
1553            (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1554                                       i1:$clamp, i32:$omod)),
1555                  (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
1556       [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1))]),
1557   revOp, P.HasModifiers
1558 >;
1559
1560 multiclass VOP2InstSI <vop2 op, string opName, VOPProfile P,
1561                        SDPatternOperator node = null_frag,
1562                        string revOp = opName> {
1563   defm _e32 : VOP2SI_m <op, P.Outs, P.Ins32, P.Asm32, [], opName, revOp>;
1564
1565   defm _e64 : VOP3SI_2_m <op, P.Outs, P.Ins64, opName#P.Asm64,
1566     !if(P.HasModifiers,
1567         [(set P.DstVT:$dst,
1568              (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1569                                         i1:$clamp, i32:$omod)),
1570                    (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
1571         [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1))]),
1572     opName, revOp, P.HasModifiers>;
1573 }
1574
1575 multiclass VOP2b_Helper <vop2 op, string opName, dag outs32, dag outs64,
1576                          dag ins32, string asm32, list<dag> pat32,
1577                          dag ins64, string asm64, list<dag> pat64,
1578                          string revOp, bit HasMods> {
1579
1580   defm _e32 : VOP2_m <op, outs32, ins32, asm32, pat32, opName, revOp>;
1581
1582   defm _e64 : VOP3b_2_m <op,
1583     outs64, ins64, opName#asm64, pat64, opName, revOp, HasMods
1584   >;
1585 }
1586
1587 multiclass VOP2bInst <vop2 op, string opName, VOPProfile P,
1588                       SDPatternOperator node = null_frag,
1589                       string revOp = opName> : VOP2b_Helper <
1590   op, opName, P.Outs32, P.Outs64,
1591   P.Ins32, P.Asm32, [],
1592   P.Ins64, P.Asm64,
1593   !if(P.HasModifiers,
1594       [(set P.DstVT:$dst,
1595            (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1596                                       i1:$clamp, i32:$omod)),
1597                  (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
1598       [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1))]),
1599   revOp, P.HasModifiers
1600 >;
1601
1602 // A VOP2 instruction that is VOP3-only on VI.
1603 multiclass VOP2_VI3_Helper <vop23 op, string opName, dag outs,
1604                             dag ins32, string asm32, list<dag> pat32,
1605                             dag ins64, string asm64, list<dag> pat64,
1606                             string revOp, bit HasMods> {
1607   defm _e32 : VOP2SI_m <op, outs, ins32, asm32, pat32, opName, revOp>;
1608
1609   defm _e64 : VOP3_2_m <op, outs, ins64, opName#asm64, pat64, opName,
1610                         revOp, HasMods>;
1611 }
1612
1613 multiclass VOP2_VI3_Inst <vop23 op, string opName, VOPProfile P,
1614                           SDPatternOperator node = null_frag,
1615                           string revOp = opName>
1616                           : VOP2_VI3_Helper <
1617   op, opName, P.Outs,
1618   P.Ins32, P.Asm32, [],
1619   P.Ins64, P.Asm64,
1620   !if(P.HasModifiers,
1621       [(set P.DstVT:$dst,
1622            (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1623                                       i1:$clamp, i32:$omod)),
1624                  (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
1625       [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1))]),
1626   revOp, P.HasModifiers
1627 >;
1628
1629 multiclass VOP2MADK <vop2 op, string opName, list<dag> pattern = []> {
1630
1631   def "" : VOP2_Pseudo <VOP_MADK.Outs, VOP_MADK.Ins, pattern, opName>;
1632
1633 let isCodeGenOnly = 0 in {
1634   def _si : VOP2Common <VOP_MADK.Outs, VOP_MADK.Ins,
1635                         !strconcat(opName, VOP_MADK.Asm), []>,
1636             SIMCInstr <opName#"_e32", SISubtarget.SI>,
1637             VOP2_MADKe <op.SI> {
1638             let AssemblerPredicates = [isSICI];
1639             }
1640
1641   def _vi : VOP2Common <VOP_MADK.Outs, VOP_MADK.Ins,
1642                         !strconcat(opName, VOP_MADK.Asm), []>,
1643             SIMCInstr <opName#"_e32", SISubtarget.VI>,
1644             VOP2_MADKe <op.VI> {
1645             let AssemblerPredicates = [isVI];
1646             }
1647 } // End isCodeGenOnly = 0
1648 }
1649
1650 class VOPC_Pseudo <dag ins, list<dag> pattern, string opName> :
1651   VOPCCommon <ins, "", pattern>,
1652   VOP <opName>,
1653   SIMCInstr<opName#"_e32", SISubtarget.NONE> {
1654   let isPseudo = 1;
1655   let isCodeGenOnly = 1;
1656 }
1657
1658 multiclass VOPC_m <vopc op, dag ins, string op_asm, list<dag> pattern,
1659                    string opName, bit DefExec, VOPProfile p,
1660                    string revOpName = "", string asm = opName#"_e32 "#op_asm,
1661                    string alias_asm = opName#" "#op_asm> {
1662   def "" : VOPC_Pseudo <ins, pattern, opName>;
1663
1664   let AssemblerPredicates = [isSICI] in {
1665
1666   def _si : VOPC<op.SI, ins, asm, []>,
1667             SIMCInstr <opName#"_e32", SISubtarget.SI> {
1668     let Defs = !if(DefExec, [VCC, EXEC], [VCC]);
1669     let hasSideEffects = DefExec;
1670   }
1671
1672   def : SIInstAlias <
1673     alias_asm,
1674     (!cast<Instruction>(NAME#"_e32_si") p.Src0RC32:$src0, p.Src1RC32:$src1)
1675   >;
1676
1677   } // End AssemblerPredicates = [isSICI]
1678
1679
1680   let AssemblerPredicates = [isVI] in {
1681
1682   def _vi : VOPC<op.VI, ins, asm, []>,
1683             SIMCInstr <opName#"_e32", SISubtarget.VI> {
1684     let Defs = !if(DefExec, [VCC, EXEC], [VCC]);
1685     let hasSideEffects = DefExec;
1686   }
1687
1688   def : SIInstAlias <
1689     alias_asm,
1690     (!cast<Instruction>(NAME#"_e32_vi") p.Src0RC32:$src0, p.Src1RC32:$src1)
1691   >;
1692
1693   } // End AssemblerPredicates = [isVI]
1694 }
1695
1696 multiclass VOPC_Helper <vopc op, string opName,
1697                         dag ins32, string asm32, list<dag> pat32,
1698                         dag out64, dag ins64, string asm64, list<dag> pat64,
1699                         bit HasMods, bit DefExec, string revOp,
1700                         VOPProfile p> {
1701   defm _e32 : VOPC_m <op, ins32, asm32, pat32, opName, DefExec, p>;
1702
1703   defm _e64 : VOP3_C_m <op, out64, ins64, opName#asm64, pat64,
1704                         opName, HasMods, DefExec, revOp>;
1705 }
1706
1707 // Special case for class instructions which only have modifiers on
1708 // the 1st source operand.
1709 multiclass VOPC_Class_Helper <vopc op, string opName,
1710                              dag ins32, string asm32, list<dag> pat32,
1711                              dag out64, dag ins64, string asm64, list<dag> pat64,
1712                              bit HasMods, bit DefExec, string revOp,
1713                              VOPProfile p> {
1714   defm _e32 : VOPC_m <op, ins32, asm32, pat32, opName, DefExec, p>;
1715
1716   defm _e64 : VOP3_C_m <op, out64, ins64, opName#asm64, pat64,
1717                         opName, HasMods, DefExec, revOp>,
1718                         VOP3DisableModFields<1, 0, 0>;
1719 }
1720
1721 multiclass VOPCInst <vopc op, string opName,
1722                      VOPProfile P, PatLeaf cond = COND_NULL,
1723                      string revOp = opName,
1724                      bit DefExec = 0> : VOPC_Helper <
1725   op, opName,
1726   P.Ins32, P.Asm32, [],
1727   (outs VOPDstS64:$dst), P.Ins64, P.Asm64,
1728   !if(P.HasModifiers,
1729       [(set i1:$dst,
1730           (setcc (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1731                                       i1:$clamp, i32:$omod)),
1732                  (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)),
1733                  cond))],
1734       [(set i1:$dst, (setcc P.Src0VT:$src0, P.Src1VT:$src1, cond))]),
1735   P.HasModifiers, DefExec, revOp, P
1736 >;
1737
1738 multiclass VOPCClassInst <vopc op, string opName, VOPProfile P,
1739                      bit DefExec = 0> : VOPC_Class_Helper <
1740   op, opName,
1741   P.Ins32, P.Asm32, [],
1742   (outs VOPDstS64:$dst), P.Ins64, P.Asm64,
1743   !if(P.HasModifiers,
1744       [(set i1:$dst,
1745           (AMDGPUfp_class (P.Src0VT (VOP3Mods0Clamp0OMod P.Src0VT:$src0, i32:$src0_modifiers)), P.Src1VT:$src1))],
1746       [(set i1:$dst, (AMDGPUfp_class P.Src0VT:$src0, P.Src1VT:$src1))]),
1747   P.HasModifiers, DefExec, opName, P
1748 >;
1749
1750
1751 multiclass VOPC_F32 <vopc op, string opName, PatLeaf cond = COND_NULL, string revOp = opName> :
1752   VOPCInst <op, opName, VOPC_I1_F32_F32, cond, revOp>;
1753
1754 multiclass VOPC_F64 <vopc op, string opName, PatLeaf cond = COND_NULL, string revOp = opName> :
1755   VOPCInst <op, opName, VOPC_I1_F64_F64, cond, revOp>;
1756
1757 multiclass VOPC_I32 <vopc op, string opName, PatLeaf cond = COND_NULL, string revOp = opName> :
1758   VOPCInst <op, opName, VOPC_I1_I32_I32, cond, revOp>;
1759
1760 multiclass VOPC_I64 <vopc op, string opName, PatLeaf cond = COND_NULL, string revOp = opName> :
1761   VOPCInst <op, opName, VOPC_I1_I64_I64, cond, revOp>;
1762
1763
1764 multiclass VOPCX <vopc op, string opName, VOPProfile P,
1765                   PatLeaf cond = COND_NULL,
1766                   string revOp = "">
1767   : VOPCInst <op, opName, P, cond, revOp, 1>;
1768
1769 multiclass VOPCX_F32 <vopc op, string opName, string revOp = opName> :
1770   VOPCX <op, opName, VOPC_I1_F32_F32, COND_NULL, revOp>;
1771
1772 multiclass VOPCX_F64 <vopc op, string opName, string revOp = opName> :
1773   VOPCX <op, opName, VOPC_I1_F64_F64, COND_NULL, revOp>;
1774
1775 multiclass VOPCX_I32 <vopc op, string opName, string revOp = opName> :
1776   VOPCX <op, opName, VOPC_I1_I32_I32, COND_NULL, revOp>;
1777
1778 multiclass VOPCX_I64 <vopc op, string opName, string revOp = opName> :
1779   VOPCX <op, opName, VOPC_I1_I64_I64, COND_NULL, revOp>;
1780
1781 multiclass VOP3_Helper <vop3 op, string opName, dag outs, dag ins, string asm,
1782                         list<dag> pat, int NumSrcArgs, bit HasMods> : VOP3_m <
1783     op, outs, ins, opName#" "#asm, pat, opName, NumSrcArgs, HasMods
1784 >;
1785
1786 multiclass VOPC_CLASS_F32 <vopc op, string opName> :
1787   VOPCClassInst <op, opName, VOPC_I1_F32_I32, 0>;
1788
1789 multiclass VOPCX_CLASS_F32 <vopc op, string opName> :
1790   VOPCClassInst <op, opName, VOPC_I1_F32_I32, 1>;
1791
1792 multiclass VOPC_CLASS_F64 <vopc op, string opName> :
1793   VOPCClassInst <op, opName, VOPC_I1_F64_I32, 0>;
1794
1795 multiclass VOPCX_CLASS_F64 <vopc op, string opName> :
1796   VOPCClassInst <op, opName, VOPC_I1_F64_I32, 1>;
1797
1798 multiclass VOP3Inst <vop3 op, string opName, VOPProfile P,
1799                      SDPatternOperator node = null_frag> : VOP3_Helper <
1800   op, opName, (outs P.DstRC.RegClass:$dst), P.Ins64, P.Asm64,
1801   !if(!eq(P.NumSrcArgs, 3),
1802     !if(P.HasModifiers,
1803         [(set P.DstVT:$dst,
1804             (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1805                                        i1:$clamp, i32:$omod)),
1806                   (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)),
1807                   (P.Src2VT (VOP3Mods P.Src2VT:$src2, i32:$src2_modifiers))))],
1808         [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1,
1809                                   P.Src2VT:$src2))]),
1810   !if(!eq(P.NumSrcArgs, 2),
1811     !if(P.HasModifiers,
1812         [(set P.DstVT:$dst,
1813             (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1814                                        i1:$clamp, i32:$omod)),
1815                   (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
1816         [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1))])
1817   /* P.NumSrcArgs == 1 */,
1818     !if(P.HasModifiers,
1819         [(set P.DstVT:$dst,
1820             (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1821                                        i1:$clamp, i32:$omod))))],
1822         [(set P.DstVT:$dst, (node P.Src0VT:$src0))]))),
1823   P.NumSrcArgs, P.HasModifiers
1824 >;
1825
1826 // Special case for v_div_fmas_{f32|f64}, since it seems to be the
1827 // only VOP instruction that implicitly reads VCC.
1828 multiclass VOP3_VCC_Inst <vop3 op, string opName,
1829                           VOPProfile P,
1830                           SDPatternOperator node = null_frag> : VOP3_Helper <
1831   op, opName,
1832   (outs P.DstRC.RegClass:$dst),
1833   (ins InputModsNoDefault:$src0_modifiers, P.Src0RC64:$src0,
1834        InputModsNoDefault:$src1_modifiers, P.Src1RC64:$src1,
1835        InputModsNoDefault:$src2_modifiers, P.Src2RC64:$src2,
1836        ClampMod:$clamp,
1837        omod:$omod),
1838   "$dst, $src0_modifiers, $src1_modifiers, $src2_modifiers"#"$clamp"#"$omod",
1839   [(set P.DstVT:$dst,
1840             (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1841                                        i1:$clamp, i32:$omod)),
1842                   (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)),
1843                   (P.Src2VT (VOP3Mods P.Src2VT:$src2, i32:$src2_modifiers)),
1844                   (i1 VCC)))],
1845   3, 1
1846 >;
1847
1848 multiclass VOP3b_Helper <vop op, RegisterClass vrc, RegisterOperand arc,
1849                     string opName, list<dag> pattern> :
1850   VOP3b_3_m <
1851   op, (outs vrc:$vdst, SReg_64:$sdst),
1852       (ins InputModsNoDefault:$src0_modifiers, arc:$src0,
1853            InputModsNoDefault:$src1_modifiers, arc:$src1,
1854            InputModsNoDefault:$src2_modifiers, arc:$src2,
1855            ClampMod:$clamp, omod:$omod),
1856   opName#" $vdst, $sdst, $src0_modifiers, $src1_modifiers, $src2_modifiers"#"$clamp"#"$omod", pattern,
1857   opName, opName, 1, 1
1858 >;
1859
1860 multiclass VOP3b_64 <vop3 op, string opName, list<dag> pattern> :
1861   VOP3b_Helper <op, VReg_64, VSrc_64, opName, pattern>;
1862
1863 multiclass VOP3b_32 <vop3 op, string opName, list<dag> pattern> :
1864   VOP3b_Helper <op, VGPR_32, VSrc_32, opName, pattern>;
1865
1866
1867 class Vop3ModPat<Instruction Inst, VOPProfile P, SDPatternOperator node> : Pat<
1868   (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i1:$clamp, i32:$omod)),
1869         (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)),
1870         (P.Src2VT (VOP3Mods P.Src2VT:$src2, i32:$src2_modifiers))),
1871   (Inst i32:$src0_modifiers, P.Src0VT:$src0,
1872         i32:$src1_modifiers, P.Src1VT:$src1,
1873         i32:$src2_modifiers, P.Src2VT:$src2,
1874         i1:$clamp,
1875         i32:$omod)>;
1876
1877 //===----------------------------------------------------------------------===//
1878 // Interpolation opcodes
1879 //===----------------------------------------------------------------------===//
1880
1881 class VINTRP_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
1882   VINTRPCommon <outs, ins, "", pattern>,
1883   SIMCInstr<opName, SISubtarget.NONE> {
1884   let isPseudo = 1;
1885   let isCodeGenOnly = 1;
1886 }
1887
1888 class VINTRP_Real_si <bits <2> op, string opName, dag outs, dag ins,
1889                       string asm> :
1890   VINTRPCommon <outs, ins, asm, []>,
1891   VINTRPe <op>,
1892   SIMCInstr<opName, SISubtarget.SI>;
1893
1894 class VINTRP_Real_vi <bits <2> op, string opName, dag outs, dag ins,
1895                       string asm> :
1896   VINTRPCommon <outs, ins, asm, []>,
1897   VINTRPe_vi <op>,
1898   SIMCInstr<opName, SISubtarget.VI>;
1899
1900 multiclass VINTRP_m <bits <2> op, dag outs, dag ins, string asm,
1901                      list<dag> pattern = []> {
1902   def "" : VINTRP_Pseudo <NAME, outs, ins, pattern>;
1903
1904   def _si : VINTRP_Real_si <op, NAME, outs, ins, asm>;
1905
1906   def _vi : VINTRP_Real_vi <op, NAME, outs, ins, asm>;
1907 }
1908
1909 //===----------------------------------------------------------------------===//
1910 // Vector I/O classes
1911 //===----------------------------------------------------------------------===//
1912
1913 class DS_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
1914   DS <outs, ins, "", pattern>,
1915   SIMCInstr <opName, SISubtarget.NONE> {
1916   let isPseudo = 1;
1917   let isCodeGenOnly = 1;
1918 }
1919
1920 class DS_Real_si <bits<8> op, string opName, dag outs, dag ins, string asm> :
1921   DS <outs, ins, asm, []>,
1922   DSe <op>,
1923   SIMCInstr <opName, SISubtarget.SI> {
1924   let isCodeGenOnly = 0;
1925 }
1926
1927 class DS_Real_vi <bits<8> op, string opName, dag outs, dag ins, string asm> :
1928   DS <outs, ins, asm, []>,
1929   DSe_vi <op>,
1930   SIMCInstr <opName, SISubtarget.VI>;
1931
1932 class DS_Off16_Real_si <bits<8> op, string opName, dag outs, dag ins, string asm> :
1933   DS_Real_si <op,opName, outs, ins, asm> {
1934
1935   // Single load interpret the 2 i8imm operands as a single i16 offset.
1936   bits<16> offset;
1937   let offset0 = offset{7-0};
1938   let offset1 = offset{15-8};
1939   let isCodeGenOnly = 0;
1940 }
1941
1942 class DS_Off16_Real_vi <bits<8> op, string opName, dag outs, dag ins, string asm> :
1943   DS_Real_vi <op, opName, outs, ins, asm> {
1944
1945   // Single load interpret the 2 i8imm operands as a single i16 offset.
1946   bits<16> offset;
1947   let offset0 = offset{7-0};
1948   let offset1 = offset{15-8};
1949 }
1950
1951 multiclass DS_1A_RET <bits<8> op, string opName, RegisterClass rc,
1952   dag outs = (outs rc:$vdst),
1953   dag ins = (ins VGPR_32:$addr, ds_offset:$offset, gds:$gds),
1954   string asm = opName#" $vdst, $addr"#"$offset$gds"> {
1955
1956   def "" : DS_Pseudo <opName, outs, ins, []>;
1957
1958   let data0 = 0, data1 = 0 in {
1959     def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
1960     def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
1961   }
1962 }
1963
1964 multiclass DS_1A_Off8_RET <bits<8> op, string opName, RegisterClass rc,
1965   dag outs = (outs rc:$vdst),
1966   dag ins = (ins VGPR_32:$addr, ds_offset0:$offset0, ds_offset1:$offset1,
1967                  gds01:$gds),
1968   string asm = opName#" $vdst, $addr"#"$offset0"#"$offset1$gds"> {
1969
1970   def "" : DS_Pseudo <opName, outs, ins, []>;
1971
1972   let data0 = 0, data1 = 0, AsmMatchConverter = "cvtDSOffset01" in {
1973     def _si : DS_Real_si <op, opName, outs, ins, asm>;
1974     def _vi : DS_Real_vi <op, opName, outs, ins, asm>;
1975   }
1976 }
1977
1978 multiclass DS_1A1D_NORET <bits<8> op, string opName, RegisterClass rc,
1979   dag outs = (outs),
1980   dag ins = (ins VGPR_32:$addr, rc:$data0, ds_offset:$offset, gds:$gds),
1981   string asm = opName#" $addr, $data0"#"$offset$gds"> {
1982
1983   def "" : DS_Pseudo <opName, outs, ins, []>,
1984            AtomicNoRet<opName, 0>;
1985
1986   let data1 = 0, vdst = 0 in {
1987     def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
1988     def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
1989   }
1990 }
1991
1992 multiclass DS_1A1D_Off8_NORET <bits<8> op, string opName, RegisterClass rc,
1993   dag outs = (outs),
1994   dag ins = (ins VGPR_32:$addr, rc:$data0, rc:$data1,
1995               ds_offset0:$offset0, ds_offset1:$offset1, gds01:$gds),
1996   string asm = opName#" $addr, $data0, $data1"#"$offset0"#"$offset1"#"$gds"> {
1997
1998   def "" : DS_Pseudo <opName, outs, ins, []>;
1999
2000   let vdst = 0, AsmMatchConverter = "cvtDSOffset01" in {
2001     def _si : DS_Real_si <op, opName, outs, ins, asm>;
2002     def _vi : DS_Real_vi <op, opName, outs, ins, asm>;
2003   }
2004 }
2005
2006 multiclass DS_1A1D_RET <bits<8> op, string opName, RegisterClass rc,
2007                         string noRetOp = "",
2008   dag outs = (outs rc:$vdst),
2009   dag ins = (ins VGPR_32:$addr, rc:$data0, ds_offset:$offset, gds:$gds),
2010   string asm = opName#" $vdst, $addr, $data0"#"$offset$gds"> {
2011
2012   def "" : DS_Pseudo <opName, outs, ins, []>,
2013            AtomicNoRet<noRetOp, 1>;
2014
2015   let data1 = 0 in {
2016     def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
2017     def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
2018   }
2019 }
2020
2021 multiclass DS_1A2D_RET_m <bits<8> op, string opName, RegisterClass rc,
2022                           string noRetOp = "", dag ins,
2023   dag outs = (outs rc:$vdst),
2024   string asm = opName#" $vdst, $addr, $data0, $data1"#"$offset"#"$gds"> {
2025
2026   def "" : DS_Pseudo <opName, outs, ins, []>,
2027            AtomicNoRet<noRetOp, 1>;
2028
2029   def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
2030   def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
2031 }
2032
2033 multiclass DS_1A2D_RET <bits<8> op, string asm, RegisterClass rc,
2034                         string noRetOp = "", RegisterClass src = rc> :
2035   DS_1A2D_RET_m <op, asm, rc, noRetOp,
2036                  (ins VGPR_32:$addr, src:$data0, src:$data1,
2037                       ds_offset:$offset, gds:$gds)
2038 >;
2039
2040 multiclass DS_1A2D_NORET <bits<8> op, string opName, RegisterClass rc,
2041                           string noRetOp = opName,
2042   dag outs = (outs),
2043   dag ins = (ins VGPR_32:$addr, rc:$data0, rc:$data1,
2044                  ds_offset:$offset, gds:$gds),
2045   string asm = opName#" $addr, $data0, $data1"#"$offset"#"$gds"> {
2046
2047   def "" : DS_Pseudo <opName, outs, ins, []>,
2048            AtomicNoRet<noRetOp, 0>;
2049
2050   let vdst = 0 in {
2051     def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
2052     def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
2053   }
2054 }
2055
2056 multiclass DS_0A_RET <bits<8> op, string opName,
2057   dag outs = (outs VGPR_32:$vdst),
2058   dag ins = (ins ds_offset:$offset, gds:$gds),
2059   string asm = opName#" $vdst"#"$offset"#"$gds"> {
2060
2061   let mayLoad = 1, mayStore = 1 in {
2062     def "" : DS_Pseudo <opName, outs, ins, []>;
2063
2064     let addr = 0, data0 = 0, data1 = 0 in {
2065       def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
2066       def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
2067     } // end addr = 0, data0 = 0, data1 = 0
2068   } // end mayLoad = 1, mayStore = 1
2069 }
2070
2071 multiclass DS_1A_RET_GDS <bits<8> op, string opName,
2072   dag outs = (outs VGPR_32:$vdst),
2073   dag ins = (ins VGPR_32:$addr, ds_offset_gds:$offset),
2074   string asm = opName#" $vdst, $addr"#"$offset gds"> {
2075
2076   def "" : DS_Pseudo <opName, outs, ins, []>;
2077
2078   let data0 = 0, data1 = 0, gds = 1 in {
2079     def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
2080     def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
2081   } // end data0 = 0, data1 = 0, gds = 1
2082 }
2083
2084 multiclass DS_1A_GDS <bits<8> op, string opName,
2085   dag outs = (outs),
2086   dag ins = (ins VGPR_32:$addr),
2087   string asm = opName#" $addr gds"> {
2088
2089   def "" : DS_Pseudo <opName, outs, ins, []>;
2090
2091   let vdst = 0, data0 = 0, data1 = 0, offset0 = 0, offset1 = 0, gds = 1 in {
2092     def _si : DS_Real_si <op, opName, outs, ins, asm>;
2093     def _vi : DS_Real_vi <op, opName, outs, ins, asm>;
2094   } // end vdst = 0, data = 0, data1 = 0, gds = 1
2095 }
2096
2097 multiclass DS_1A <bits<8> op, string opName,
2098   dag outs = (outs),
2099   dag ins = (ins VGPR_32:$addr, ds_offset:$offset, gds:$gds),
2100   string asm = opName#" $addr"#"$offset"#"$gds"> {
2101
2102   let mayLoad = 1, mayStore = 1 in {
2103     def "" : DS_Pseudo <opName, outs, ins, []>;
2104
2105     let vdst = 0, data0 = 0, data1 = 0 in {
2106       def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
2107       def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
2108     } // let vdst = 0, data0 = 0, data1 = 0
2109   } // end mayLoad = 1, mayStore = 1
2110 }
2111
2112 //===----------------------------------------------------------------------===//
2113 // MTBUF classes
2114 //===----------------------------------------------------------------------===//
2115
2116 class MTBUF_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
2117   MTBUF <outs, ins, "", pattern>,
2118   SIMCInstr<opName, SISubtarget.NONE> {
2119   let isPseudo = 1;
2120   let isCodeGenOnly = 1;
2121 }
2122
2123 class MTBUF_Real_si <bits<3> op, string opName, dag outs, dag ins,
2124                     string asm> :
2125   MTBUF <outs, ins, asm, []>,
2126   MTBUFe <op>,
2127   SIMCInstr<opName, SISubtarget.SI>;
2128
2129 class MTBUF_Real_vi <bits<4> op, string opName, dag outs, dag ins, string asm> :
2130   MTBUF <outs, ins, asm, []>,
2131   MTBUFe_vi <op>,
2132   SIMCInstr <opName, SISubtarget.VI>;
2133
2134 multiclass MTBUF_m <bits<3> op, string opName, dag outs, dag ins, string asm,
2135                     list<dag> pattern> {
2136
2137   def "" : MTBUF_Pseudo <opName, outs, ins, pattern>;
2138
2139   def _si : MTBUF_Real_si <op, opName, outs, ins, asm>;
2140
2141   def _vi : MTBUF_Real_vi <{0, op{2}, op{1}, op{0}}, opName, outs, ins, asm>;
2142
2143 }
2144
2145 let mayStore = 1, mayLoad = 0 in {
2146
2147 multiclass MTBUF_Store_Helper <bits<3> op, string opName,
2148                                RegisterClass regClass> : MTBUF_m <
2149   op, opName, (outs),
2150   (ins regClass:$vdata, u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
2151    i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VGPR_32:$vaddr,
2152    SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SCSrc_32:$soffset),
2153   opName#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
2154         #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset", []
2155 >;
2156
2157 } // mayStore = 1, mayLoad = 0
2158
2159 let mayLoad = 1, mayStore = 0 in {
2160
2161 multiclass MTBUF_Load_Helper <bits<3> op, string opName,
2162                               RegisterClass regClass> : MTBUF_m <
2163   op, opName, (outs regClass:$dst),
2164   (ins u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
2165        i8imm:$dfmt, i8imm:$nfmt, VGPR_32:$vaddr, SReg_128:$srsrc,
2166        i1imm:$slc, i1imm:$tfe, SCSrc_32:$soffset),
2167   opName#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
2168         #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset", []
2169 >;
2170
2171 } // mayLoad = 1, mayStore = 0
2172
2173 //===----------------------------------------------------------------------===//
2174 // MUBUF classes
2175 //===----------------------------------------------------------------------===//
2176
2177 class mubuf <bits<7> si, bits<7> vi = si> {
2178   field bits<7> SI = si;
2179   field bits<7> VI = vi;
2180 }
2181
2182 let isCodeGenOnly = 0 in {
2183
2184 class MUBUF_si <bits<7> op, dag outs, dag ins, string asm, list<dag> pattern> :
2185   MUBUF <outs, ins, asm, pattern>, MUBUFe <op> {
2186   let lds  = 0;
2187 }
2188
2189 } // End let isCodeGenOnly = 0
2190
2191 class MUBUF_vi <bits<7> op, dag outs, dag ins, string asm, list<dag> pattern> :
2192   MUBUF <outs, ins, asm, pattern>, MUBUFe_vi <op> {
2193   let lds = 0;
2194 }
2195
2196 class MUBUFAddr64Table <bit is_addr64, string suffix = ""> {
2197   bit IsAddr64 = is_addr64;
2198   string OpName = NAME # suffix;
2199 }
2200
2201 class MUBUF_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
2202   MUBUF <outs, ins, "", pattern>,
2203   SIMCInstr<opName, SISubtarget.NONE> {
2204   let isPseudo = 1;
2205   let isCodeGenOnly = 1;
2206
2207   // dummy fields, so that we can use let statements around multiclasses
2208   bits<1> offen;
2209   bits<1> idxen;
2210   bits<8> vaddr;
2211   bits<1> glc;
2212   bits<1> slc;
2213   bits<1> tfe;
2214   bits<8> soffset;
2215 }
2216
2217 class MUBUF_Real_si <mubuf op, string opName, dag outs, dag ins,
2218                      string asm> :
2219   MUBUF <outs, ins, asm, []>,
2220   MUBUFe <op.SI>,
2221   SIMCInstr<opName, SISubtarget.SI> {
2222   let lds = 0;
2223 }
2224
2225 class MUBUF_Real_vi <mubuf op, string opName, dag outs, dag ins,
2226                      string asm> :
2227   MUBUF <outs, ins, asm, []>,
2228   MUBUFe_vi <op.VI>,
2229   SIMCInstr<opName, SISubtarget.VI> {
2230   let lds = 0;
2231 }
2232
2233 multiclass MUBUF_m <mubuf op, string opName, dag outs, dag ins, string asm,
2234                     list<dag> pattern> {
2235
2236   def "" : MUBUF_Pseudo <opName, outs, ins, pattern>,
2237            MUBUFAddr64Table <0>;
2238
2239   let addr64 = 0, isCodeGenOnly = 0 in {
2240     def _si : MUBUF_Real_si <op, opName, outs, ins, asm>;
2241   }
2242
2243   def _vi : MUBUF_Real_vi <op, opName, outs, ins, asm>;
2244 }
2245
2246 multiclass MUBUFAddr64_m <mubuf op, string opName, dag outs,
2247                           dag ins, string asm, list<dag> pattern> {
2248
2249   def "" : MUBUF_Pseudo <opName, outs, ins, pattern>,
2250            MUBUFAddr64Table <1>;
2251
2252   let addr64 = 1, isCodeGenOnly = 0 in {
2253     def _si : MUBUF_Real_si <op, opName, outs, ins, asm>;
2254   }
2255
2256   // There is no VI version. If the pseudo is selected, it should be lowered
2257   // for VI appropriately.
2258 }
2259
2260 multiclass MUBUFAtomicOffset_m <mubuf op, string opName, dag outs, dag ins,
2261                                 string asm, list<dag> pattern, bit is_return> {
2262
2263   def "" : MUBUF_Pseudo <opName, outs, ins, pattern>,
2264            MUBUFAddr64Table <0, !if(is_return, "_RTN", "")>,
2265            AtomicNoRet<NAME#"_OFFSET", is_return>;
2266
2267   let offen = 0, idxen = 0, tfe = 0, vaddr = 0 in {
2268     let addr64 = 0 in {
2269       def _si : MUBUF_Real_si <op, opName, outs, ins, asm>;
2270     }
2271
2272     def _vi : MUBUF_Real_vi <op, opName, outs, ins, asm>;
2273   }
2274 }
2275
2276 multiclass MUBUFAtomicAddr64_m <mubuf op, string opName, dag outs, dag ins,
2277                                 string asm, list<dag> pattern, bit is_return> {
2278
2279   def "" : MUBUF_Pseudo <opName, outs, ins, pattern>,
2280            MUBUFAddr64Table <1, !if(is_return, "_RTN", "")>,
2281            AtomicNoRet<NAME#"_ADDR64", is_return>;
2282
2283   let offen = 0, idxen = 0, addr64 = 1, tfe = 0 in {
2284     def _si : MUBUF_Real_si <op, opName, outs, ins, asm>;
2285   }
2286
2287   // There is no VI version. If the pseudo is selected, it should be lowered
2288   // for VI appropriately.
2289 }
2290
2291 multiclass MUBUF_Atomic <mubuf op, string name, RegisterClass rc,
2292                          ValueType vt, SDPatternOperator atomic> {
2293
2294   let mayStore = 1, mayLoad = 1, hasPostISelHook = 1 in {
2295
2296     // No return variants
2297     let glc = 0 in {
2298
2299       defm _ADDR64 : MUBUFAtomicAddr64_m <
2300         op, name#"_addr64", (outs),
2301         (ins rc:$vdata, SReg_128:$srsrc, VReg_64:$vaddr,
2302              SCSrc_32:$soffset, mbuf_offset:$offset, slc:$slc),
2303         name#" $vdata, $vaddr, $srsrc, $soffset addr64"#"$offset"#"$slc", [], 0
2304       >;
2305
2306       defm _OFFSET : MUBUFAtomicOffset_m <
2307         op, name#"_offset", (outs),
2308         (ins rc:$vdata, SReg_128:$srsrc, SCSrc_32:$soffset, mbuf_offset:$offset,
2309              slc:$slc),
2310         name#" $vdata, $srsrc, $soffset"#"$offset"#"$slc", [], 0
2311       >;
2312     } // glc = 0
2313
2314     // Variant that return values
2315     let glc = 1, Constraints = "$vdata = $vdata_in",
2316         DisableEncoding = "$vdata_in"  in {
2317
2318       defm _RTN_ADDR64 : MUBUFAtomicAddr64_m <
2319         op, name#"_rtn_addr64", (outs rc:$vdata),
2320         (ins rc:$vdata_in, SReg_128:$srsrc, VReg_64:$vaddr,
2321              SCSrc_32:$soffset, mbuf_offset:$offset, slc:$slc),
2322         name#" $vdata, $vaddr, $srsrc, $soffset addr64"#"$offset"#" glc"#"$slc",
2323         [(set vt:$vdata,
2324          (atomic (MUBUFAddr64Atomic v4i32:$srsrc, i64:$vaddr, i32:$soffset,
2325                                     i16:$offset, i1:$slc), vt:$vdata_in))], 1
2326       >;
2327
2328       defm _RTN_OFFSET : MUBUFAtomicOffset_m <
2329         op, name#"_rtn_offset", (outs rc:$vdata),
2330         (ins rc:$vdata_in, SReg_128:$srsrc, SCSrc_32:$soffset,
2331              mbuf_offset:$offset, slc:$slc),
2332         name#" $vdata, $srsrc, $soffset"#"$offset"#" glc $slc",
2333         [(set vt:$vdata,
2334          (atomic (MUBUFOffsetAtomic v4i32:$srsrc, i32:$soffset, i16:$offset,
2335                                     i1:$slc), vt:$vdata_in))], 1
2336       >;
2337
2338     } // glc = 1
2339
2340   } // mayStore = 1, mayLoad = 1, hasPostISelHook = 1
2341 }
2342
2343 multiclass MUBUF_Load_Helper <mubuf op, string name, RegisterClass regClass,
2344                               ValueType load_vt = i32,
2345                               SDPatternOperator ld = null_frag> {
2346
2347   let mayLoad = 1, mayStore = 0 in {
2348     let offen = 0, idxen = 0, vaddr = 0 in {
2349       defm _OFFSET : MUBUF_m <op, name#"_offset", (outs regClass:$vdata),
2350                            (ins SReg_128:$srsrc, SCSrc_32:$soffset,
2351                            mbuf_offset:$offset, glc:$glc, slc:$slc, tfe:$tfe),
2352                            name#" $vdata, $srsrc, $soffset"#"$offset"#"$glc"#"$slc"#"$tfe",
2353                            [(set load_vt:$vdata, (ld (MUBUFOffset v4i32:$srsrc,
2354                                                      i32:$soffset, i16:$offset,
2355                                                      i1:$glc, i1:$slc, i1:$tfe)))]>;
2356     }
2357
2358     let offen = 1, idxen = 0  in {
2359       defm _OFFEN  : MUBUF_m <op, name#"_offen", (outs regClass:$vdata),
2360                            (ins VGPR_32:$vaddr, SReg_128:$srsrc,
2361                            SCSrc_32:$soffset, mbuf_offset:$offset, glc:$glc, slc:$slc,
2362                            tfe:$tfe),
2363                            name#" $vdata, $vaddr, $srsrc, $soffset offen"#"$offset"#"$glc"#"$slc"#"$tfe", []>;
2364     }
2365
2366     let offen = 0, idxen = 1 in {
2367       defm _IDXEN  : MUBUF_m <op, name#"_idxen", (outs regClass:$vdata),
2368                            (ins VGPR_32:$vaddr, SReg_128:$srsrc,
2369                            SCSrc_32:$soffset, mbuf_offset:$offset, glc:$glc,
2370                            slc:$slc, tfe:$tfe),
2371                            name#" $vdata, $vaddr, $srsrc, $soffset idxen"#"$offset"#"$glc"#"$slc"#"$tfe", []>;
2372     }
2373
2374     let offen = 1, idxen = 1 in {
2375       defm _BOTHEN : MUBUF_m <op, name#"_bothen", (outs regClass:$vdata),
2376                            (ins VReg_64:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset,
2377                            mbuf_offset:$offset, glc:$glc, slc:$slc, tfe:$tfe),
2378                            name#" $vdata, $vaddr, $srsrc, $soffset idxen offen"#"$offset"#"$glc"#"$slc"#"$tfe", []>;
2379     }
2380
2381     let offen = 0, idxen = 0 in {
2382       defm _ADDR64 : MUBUFAddr64_m <op, name#"_addr64", (outs regClass:$vdata),
2383                            (ins VReg_64:$vaddr, SReg_128:$srsrc,
2384                                 SCSrc_32:$soffset, mbuf_offset:$offset,
2385                                 glc:$glc, slc:$slc, tfe:$tfe),
2386                            name#" $vdata, $vaddr, $srsrc, $soffset addr64"#"$offset"#
2387                                 "$glc"#"$slc"#"$tfe",
2388                            [(set load_vt:$vdata, (ld (MUBUFAddr64 v4i32:$srsrc,
2389                                                   i64:$vaddr, i32:$soffset,
2390                                                   i16:$offset, i1:$glc, i1:$slc,
2391                                                   i1:$tfe)))]>;
2392     }
2393   }
2394 }
2395
2396 multiclass MUBUF_Store_Helper <mubuf op, string name, RegisterClass vdataClass,
2397                           ValueType store_vt = i32, SDPatternOperator st = null_frag> {
2398   let mayLoad = 0, mayStore = 1 in {
2399     defm : MUBUF_m <op, name, (outs),
2400                     (ins vdataClass:$vdata, VGPR_32:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset,
2401                     mbuf_offset:$offset, offen:$offen, idxen:$idxen, glc:$glc, slc:$slc,
2402                     tfe:$tfe),
2403                     name#" $vdata, $vaddr, $srsrc, $soffset"#"$offen"#"$idxen"#"$offset"#
2404                          "$glc"#"$slc"#"$tfe", []>;
2405
2406     let offen = 0, idxen = 0, vaddr = 0 in {
2407       defm _OFFSET : MUBUF_m <op, name#"_offset",(outs),
2408                               (ins vdataClass:$vdata, SReg_128:$srsrc, SCSrc_32:$soffset,
2409                               mbuf_offset:$offset, glc:$glc, slc:$slc, tfe:$tfe),
2410                               name#" $vdata, $srsrc, $soffset"#"$offset"#"$glc"#"$slc"#"$tfe",
2411                               [(st store_vt:$vdata, (MUBUFOffset v4i32:$srsrc, i32:$soffset,
2412                                    i16:$offset, i1:$glc, i1:$slc, i1:$tfe))]>;
2413     } // offen = 0, idxen = 0, vaddr = 0
2414
2415     let offen = 1, idxen = 0  in {
2416       defm _OFFEN : MUBUF_m <op, name#"_offen", (outs),
2417                              (ins vdataClass:$vdata, VGPR_32:$vaddr, SReg_128:$srsrc,
2418                               SCSrc_32:$soffset, mbuf_offset:$offset, glc:$glc,
2419                               slc:$slc, tfe:$tfe),
2420                              name#" $vdata, $vaddr, $srsrc, $soffset offen"#"$offset"#
2421                              "$glc"#"$slc"#"$tfe", []>;
2422     } // end offen = 1, idxen = 0
2423
2424     let offen = 0, idxen = 1 in {
2425       defm _IDXEN  : MUBUF_m <op, name#"_idxen", (outs),
2426                            (ins vdataClass:$vdata, VGPR_32:$vaddr, SReg_128:$srsrc,
2427                            SCSrc_32:$soffset, mbuf_offset:$offset, glc:$glc,
2428                            slc:$slc, tfe:$tfe),
2429                            name#" $vdata, $vaddr, $srsrc, $soffset idxen"#"$offset"#"$glc"#"$slc"#"$tfe", []>;
2430     }
2431
2432     let offen = 1, idxen = 1 in {
2433       defm _BOTHEN : MUBUF_m <op, name#"_bothen", (outs),
2434                            (ins vdataClass:$vdata, VReg_64:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset,
2435                            mbuf_offset:$offset, glc:$glc, slc:$slc, tfe:$tfe),
2436                            name#" $vdata, $vaddr, $srsrc, $soffset idxen offen"#"$offset"#"$glc"#"$slc"#"$tfe", []>;
2437     }
2438
2439     let offen = 0, idxen = 0 in {
2440       defm _ADDR64 : MUBUFAddr64_m <op, name#"_addr64", (outs),
2441                                     (ins vdataClass:$vdata, VReg_64:$vaddr, SReg_128:$srsrc,
2442                                          SCSrc_32:$soffset,
2443                                          mbuf_offset:$offset, glc:$glc, slc:$slc,
2444                                          tfe:$tfe),
2445                                     name#" $vdata, $vaddr, $srsrc, $soffset addr64"#
2446                                          "$offset"#"$glc"#"$slc"#"$tfe",
2447                                     [(st store_vt:$vdata,
2448                                       (MUBUFAddr64 v4i32:$srsrc, i64:$vaddr,
2449                                                    i32:$soffset, i16:$offset,
2450                                                    i1:$glc, i1:$slc, i1:$tfe))]>;
2451     }
2452   } // End mayLoad = 0, mayStore = 1
2453 }
2454
2455 class FLAT_Load_Helper <bits<7> op, string asm, RegisterClass regClass> :
2456       FLAT <op, (outs regClass:$vdst),
2457                 (ins VReg_64:$addr, glc_flat:$glc, slc_flat:$slc, tfe_flat:$tfe),
2458             asm#" $vdst, $addr"#"$glc"#"$slc"#"$tfe", []> {
2459   let data = 0;
2460   let mayLoad = 1;
2461 }
2462
2463 class FLAT_Store_Helper <bits<7> op, string name, RegisterClass vdataClass> :
2464       FLAT <op, (outs), (ins vdataClass:$data, VReg_64:$addr,
2465                              glc_flat:$glc, slc_flat:$slc, tfe_flat:$tfe),
2466           name#" $data, $addr"#"$glc"#"$slc"#"$tfe",
2467          []> {
2468
2469   let mayLoad = 0;
2470   let mayStore = 1;
2471
2472   // Encoding
2473   let vdst = 0;
2474 }
2475
2476 multiclass FLAT_ATOMIC <bits<7> op, string name, RegisterClass vdst_rc,
2477                         RegisterClass data_rc = vdst_rc> {
2478
2479   let mayLoad = 1, mayStore = 1 in {
2480     def "" : FLAT <op, (outs),
2481                   (ins VReg_64:$addr, data_rc:$data, slc_flat_atomic:$slc,
2482                        tfe_flat_atomic:$tfe),
2483                    name#" $addr, $data"#"$slc"#"$tfe", []>,
2484              AtomicNoRet <NAME, 0> {
2485       let glc = 0;
2486       let vdst = 0;
2487     }
2488
2489     def _RTN : FLAT <op, (outs vdst_rc:$vdst),
2490                      (ins VReg_64:$addr, data_rc:$data, slc_flat_atomic:$slc,
2491                           tfe_flat_atomic:$tfe),
2492                      name#" $vdst, $addr, $data glc"#"$slc"#"$tfe", []>,
2493                AtomicNoRet <NAME, 1> {
2494       let glc = 1;
2495     }
2496   }
2497 }
2498
2499 class MIMG_Mask <string op, int channels> {
2500   string Op = op;
2501   int Channels = channels;
2502 }
2503
2504 class MIMG_NoSampler_Helper <bits<7> op, string asm,
2505                              RegisterClass dst_rc,
2506                              RegisterClass src_rc> : MIMG <
2507   op,
2508   (outs dst_rc:$vdata),
2509   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
2510        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
2511        SReg_256:$srsrc),
2512   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
2513      #" $tfe, $lwe, $slc, $vaddr, $srsrc",
2514   []> {
2515   let ssamp = 0;
2516   let mayLoad = 1;
2517   let mayStore = 0;
2518   let hasPostISelHook = 1;
2519 }
2520
2521 multiclass MIMG_NoSampler_Src_Helper <bits<7> op, string asm,
2522                                       RegisterClass dst_rc,
2523                                       int channels> {
2524   def _V1 : MIMG_NoSampler_Helper <op, asm, dst_rc, VGPR_32>,
2525             MIMG_Mask<asm#"_V1", channels>;
2526   def _V2 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_64>,
2527             MIMG_Mask<asm#"_V2", channels>;
2528   def _V4 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_128>,
2529             MIMG_Mask<asm#"_V4", channels>;
2530 }
2531
2532 multiclass MIMG_NoSampler <bits<7> op, string asm> {
2533   defm _V1 : MIMG_NoSampler_Src_Helper <op, asm, VGPR_32, 1>;
2534   defm _V2 : MIMG_NoSampler_Src_Helper <op, asm, VReg_64, 2>;
2535   defm _V3 : MIMG_NoSampler_Src_Helper <op, asm, VReg_96, 3>;
2536   defm _V4 : MIMG_NoSampler_Src_Helper <op, asm, VReg_128, 4>;
2537 }
2538
2539 class MIMG_Sampler_Helper <bits<7> op, string asm,
2540                            RegisterClass dst_rc,
2541                            RegisterClass src_rc, int wqm> : MIMG <
2542   op,
2543   (outs dst_rc:$vdata),
2544   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
2545        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
2546        SReg_256:$srsrc, SReg_128:$ssamp),
2547   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
2548      #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
2549   []> {
2550   let mayLoad = 1;
2551   let mayStore = 0;
2552   let hasPostISelHook = 1;
2553   let WQM = wqm;
2554 }
2555
2556 multiclass MIMG_Sampler_Src_Helper <bits<7> op, string asm,
2557                                     RegisterClass dst_rc,
2558                                     int channels, int wqm> {
2559   def _V1 : MIMG_Sampler_Helper <op, asm, dst_rc, VGPR_32, wqm>,
2560             MIMG_Mask<asm#"_V1", channels>;
2561   def _V2 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_64, wqm>,
2562             MIMG_Mask<asm#"_V2", channels>;
2563   def _V4 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_128, wqm>,
2564             MIMG_Mask<asm#"_V4", channels>;
2565   def _V8 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_256, wqm>,
2566             MIMG_Mask<asm#"_V8", channels>;
2567   def _V16 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_512, wqm>,
2568             MIMG_Mask<asm#"_V16", channels>;
2569 }
2570
2571 multiclass MIMG_Sampler <bits<7> op, string asm> {
2572   defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VGPR_32, 1, 0>;
2573   defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2, 0>;
2574   defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3, 0>;
2575   defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4, 0>;
2576 }
2577
2578 multiclass MIMG_Sampler_WQM <bits<7> op, string asm> {
2579   defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VGPR_32, 1, 1>;
2580   defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2, 1>;
2581   defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3, 1>;
2582   defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4, 1>;
2583 }
2584
2585 class MIMG_Gather_Helper <bits<7> op, string asm,
2586                           RegisterClass dst_rc,
2587                           RegisterClass src_rc, int wqm> : MIMG <
2588   op,
2589   (outs dst_rc:$vdata),
2590   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
2591        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
2592        SReg_256:$srsrc, SReg_128:$ssamp),
2593   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
2594      #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
2595   []> {
2596   let mayLoad = 1;
2597   let mayStore = 0;
2598
2599   // DMASK was repurposed for GATHER4. 4 components are always
2600   // returned and DMASK works like a swizzle - it selects
2601   // the component to fetch. The only useful DMASK values are
2602   // 1=red, 2=green, 4=blue, 8=alpha. (e.g. 1 returns
2603   // (red,red,red,red) etc.) The ISA document doesn't mention
2604   // this.
2605   // Therefore, disable all code which updates DMASK by setting these two:
2606   let MIMG = 0;
2607   let hasPostISelHook = 0;
2608   let WQM = wqm;
2609 }
2610
2611 multiclass MIMG_Gather_Src_Helper <bits<7> op, string asm,
2612                                     RegisterClass dst_rc,
2613                                     int channels, int wqm> {
2614   def _V1 : MIMG_Gather_Helper <op, asm, dst_rc, VGPR_32, wqm>,
2615             MIMG_Mask<asm#"_V1", channels>;
2616   def _V2 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_64, wqm>,
2617             MIMG_Mask<asm#"_V2", channels>;
2618   def _V4 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_128, wqm>,
2619             MIMG_Mask<asm#"_V4", channels>;
2620   def _V8 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_256, wqm>,
2621             MIMG_Mask<asm#"_V8", channels>;
2622   def _V16 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_512, wqm>,
2623             MIMG_Mask<asm#"_V16", channels>;
2624 }
2625
2626 multiclass MIMG_Gather <bits<7> op, string asm> {
2627   defm _V1 : MIMG_Gather_Src_Helper<op, asm, VGPR_32, 1, 0>;
2628   defm _V2 : MIMG_Gather_Src_Helper<op, asm, VReg_64, 2, 0>;
2629   defm _V3 : MIMG_Gather_Src_Helper<op, asm, VReg_96, 3, 0>;
2630   defm _V4 : MIMG_Gather_Src_Helper<op, asm, VReg_128, 4, 0>;
2631 }
2632
2633 multiclass MIMG_Gather_WQM <bits<7> op, string asm> {
2634   defm _V1 : MIMG_Gather_Src_Helper<op, asm, VGPR_32, 1, 1>;
2635   defm _V2 : MIMG_Gather_Src_Helper<op, asm, VReg_64, 2, 1>;
2636   defm _V3 : MIMG_Gather_Src_Helper<op, asm, VReg_96, 3, 1>;
2637   defm _V4 : MIMG_Gather_Src_Helper<op, asm, VReg_128, 4, 1>;
2638 }
2639
2640 //===----------------------------------------------------------------------===//
2641 // Vector instruction mappings
2642 //===----------------------------------------------------------------------===//
2643
2644 // Maps an opcode in e32 form to its e64 equivalent
2645 def getVOPe64 : InstrMapping {
2646   let FilterClass = "VOP";
2647   let RowFields = ["OpName"];
2648   let ColFields = ["Size"];
2649   let KeyCol = ["4"];
2650   let ValueCols = [["8"]];
2651 }
2652
2653 // Maps an opcode in e64 form to its e32 equivalent
2654 def getVOPe32 : InstrMapping {
2655   let FilterClass = "VOP";
2656   let RowFields = ["OpName"];
2657   let ColFields = ["Size"];
2658   let KeyCol = ["8"];
2659   let ValueCols = [["4"]];
2660 }
2661
2662 def getMaskedMIMGOp : InstrMapping {
2663   let FilterClass = "MIMG_Mask";
2664   let RowFields = ["Op"];
2665   let ColFields = ["Channels"];
2666   let KeyCol = ["4"];
2667   let ValueCols = [["1"], ["2"], ["3"] ];
2668 }
2669
2670 // Maps an commuted opcode to its original version
2671 def getCommuteOrig : InstrMapping {
2672   let FilterClass = "VOP2_REV";
2673   let RowFields = ["RevOp"];
2674   let ColFields = ["IsOrig"];
2675   let KeyCol = ["0"];
2676   let ValueCols = [["1"]];
2677 }
2678
2679 // Maps an original opcode to its commuted version
2680 def getCommuteRev : InstrMapping {
2681   let FilterClass = "VOP2_REV";
2682   let RowFields = ["RevOp"];
2683   let ColFields = ["IsOrig"];
2684   let KeyCol = ["1"];
2685   let ValueCols = [["0"]];
2686 }
2687
2688 def getCommuteCmpOrig : InstrMapping {
2689   let FilterClass = "VOP2_REV";
2690   let RowFields = ["RevOp"];
2691   let ColFields = ["IsOrig"];
2692   let KeyCol = ["0"];
2693   let ValueCols = [["1"]];
2694 }
2695
2696 // Maps an original opcode to its commuted version
2697 def getCommuteCmpRev : InstrMapping {
2698   let FilterClass = "VOP2_REV";
2699   let RowFields = ["RevOp"];
2700   let ColFields = ["IsOrig"];
2701   let KeyCol = ["1"];
2702   let ValueCols = [["0"]];
2703 }
2704
2705
2706 def getMCOpcodeGen : InstrMapping {
2707   let FilterClass = "SIMCInstr";
2708   let RowFields = ["PseudoInstr"];
2709   let ColFields = ["Subtarget"];
2710   let KeyCol = [!cast<string>(SISubtarget.NONE)];
2711   let ValueCols = [[!cast<string>(SISubtarget.SI)],[!cast<string>(SISubtarget.VI)]];
2712 }
2713
2714 def getAddr64Inst : InstrMapping {
2715   let FilterClass = "MUBUFAddr64Table";
2716   let RowFields = ["OpName"];
2717   let ColFields = ["IsAddr64"];
2718   let KeyCol = ["0"];
2719   let ValueCols = [["1"]];
2720 }
2721
2722 // Maps an atomic opcode to its version with a return value.
2723 def getAtomicRetOp : InstrMapping {
2724   let FilterClass = "AtomicNoRet";
2725   let RowFields = ["NoRetOp"];
2726   let ColFields = ["IsRet"];
2727   let KeyCol = ["0"];
2728   let ValueCols = [["1"]];
2729 }
2730
2731 // Maps an atomic opcode to its returnless version.
2732 def getAtomicNoRetOp : InstrMapping {
2733   let FilterClass = "AtomicNoRet";
2734   let RowFields = ["NoRetOp"];
2735   let ColFields = ["IsRet"];
2736   let KeyCol = ["1"];
2737   let ValueCols = [["0"]];
2738 }
2739
2740 include "SIInstructions.td"
2741 include "CIInstructions.td"
2742 include "VIInstructions.td"