AMDGPU: Remove unused multiclass argument
[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 =
994   !if(!eq(VT.Size, 64),
995       VCSrc_64,
996       !if(!eq(VT.Value, i1.Value),
997           SCSrc_64,
998           VCSrc_32
999        )
1000     );
1001 }
1002
1003 // Returns 1 if the source arguments have modifiers, 0 if they do not.
1004 // XXX - do f16 instructions?
1005 class hasModifiers<ValueType SrcVT> {
1006   bit ret = !if(!eq(SrcVT.Value, f32.Value), 1,
1007             !if(!eq(SrcVT.Value, f64.Value), 1, 0));
1008 }
1009
1010 // Returns the input arguments for VOP[12C] instructions for the given SrcVT.
1011 class getIns32 <RegisterOperand Src0RC, RegisterClass Src1RC, int NumSrcArgs> {
1012   dag ret = !if(!eq(NumSrcArgs, 1), (ins Src0RC:$src0),               // VOP1
1013             !if(!eq(NumSrcArgs, 2), (ins Src0RC:$src0, Src1RC:$src1), // VOP2
1014                                     (ins)));
1015 }
1016
1017 // Returns the input arguments for VOP3 instructions for the given SrcVT.
1018 class getIns64 <RegisterOperand Src0RC, RegisterOperand Src1RC,
1019                 RegisterOperand Src2RC, int NumSrcArgs,
1020                 bit HasModifiers> {
1021
1022   dag ret =
1023     !if (!eq(NumSrcArgs, 1),
1024       !if (!eq(HasModifiers, 1),
1025         // VOP1 with modifiers
1026         (ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0,
1027              ClampMod:$clamp, omod:$omod)
1028       /* else */,
1029         // VOP1 without modifiers
1030         (ins Src0RC:$src0)
1031       /* endif */ ),
1032     !if (!eq(NumSrcArgs, 2),
1033       !if (!eq(HasModifiers, 1),
1034         // VOP 2 with modifiers
1035         (ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0,
1036              InputModsNoDefault:$src1_modifiers, Src1RC:$src1,
1037              ClampMod:$clamp, omod:$omod)
1038       /* else */,
1039         // VOP2 without modifiers
1040         (ins Src0RC:$src0, Src1RC:$src1)
1041       /* endif */ )
1042     /* NumSrcArgs == 3 */,
1043       !if (!eq(HasModifiers, 1),
1044         // VOP3 with modifiers
1045         (ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0,
1046              InputModsNoDefault:$src1_modifiers, Src1RC:$src1,
1047              InputModsNoDefault:$src2_modifiers, Src2RC:$src2,
1048              ClampMod:$clamp, omod:$omod)
1049       /* else */,
1050         // VOP3 without modifiers
1051         (ins Src0RC:$src0, Src1RC:$src1, Src2RC:$src2)
1052       /* endif */ )));
1053 }
1054
1055 // Returns the assembly string for the inputs and outputs of a VOP[12C]
1056 // instruction.  This does not add the _e32 suffix, so it can be reused
1057 // by getAsm64.
1058 class getAsm32 <int NumSrcArgs> {
1059   string src1 = ", $src1";
1060   string src2 = ", $src2";
1061   string ret = "$dst, $src0"#
1062                !if(!eq(NumSrcArgs, 1), "", src1)#
1063                !if(!eq(NumSrcArgs, 3), src2, "");
1064 }
1065
1066 // Returns the assembly string for the inputs and outputs of a VOP3
1067 // instruction.
1068 class getAsm64 <int NumSrcArgs, bit HasModifiers> {
1069   string src0 = !if(!eq(NumSrcArgs, 1), "$src0_modifiers", "$src0_modifiers,");
1070   string src1 = !if(!eq(NumSrcArgs, 1), "",
1071                    !if(!eq(NumSrcArgs, 2), " $src1_modifiers",
1072                                            " $src1_modifiers,"));
1073   string src2 = !if(!eq(NumSrcArgs, 3), " $src2_modifiers", "");
1074   string ret =
1075   !if(!eq(HasModifiers, 0),
1076       getAsm32<NumSrcArgs>.ret,
1077       "$dst, "#src0#src1#src2#"$clamp"#"$omod");
1078 }
1079
1080 class VOPProfile <list<ValueType> _ArgVT> {
1081
1082   field list<ValueType> ArgVT = _ArgVT;
1083
1084   field ValueType DstVT = ArgVT[0];
1085   field ValueType Src0VT = ArgVT[1];
1086   field ValueType Src1VT = ArgVT[2];
1087   field ValueType Src2VT = ArgVT[3];
1088   field RegisterOperand DstRC = getVALUDstForVT<DstVT>.ret;
1089   field RegisterOperand Src0RC32 = getVOPSrc0ForVT<Src0VT>.ret;
1090   field RegisterClass Src1RC32 = getVOPSrc1ForVT<Src1VT>.ret;
1091   field RegisterOperand Src0RC64 = getVOP3SrcForVT<Src0VT>.ret;
1092   field RegisterOperand Src1RC64 = getVOP3SrcForVT<Src1VT>.ret;
1093   field RegisterOperand Src2RC64 = getVOP3SrcForVT<Src2VT>.ret;
1094
1095   field int NumSrcArgs = getNumSrcArgs<Src1VT, Src2VT>.ret;
1096   field bit HasModifiers = hasModifiers<Src0VT>.ret;
1097
1098   field dag Outs = (outs DstRC:$dst);
1099
1100   // VOP3b instructions are a special case with a second explicit
1101   // output. This is manually overridden for them.
1102   field dag Outs32 = Outs;
1103   field dag Outs64 = Outs;
1104
1105   field dag Ins32 = getIns32<Src0RC32, Src1RC32, NumSrcArgs>.ret;
1106   field dag Ins64 = getIns64<Src0RC64, Src1RC64, Src2RC64, NumSrcArgs,
1107                              HasModifiers>.ret;
1108
1109   field string Asm32 = getAsm32<NumSrcArgs>.ret;
1110   field string Asm64 = getAsm64<NumSrcArgs, HasModifiers>.ret;
1111 }
1112
1113 // FIXME: I think these F16/I16 profiles will need to use f16/i16 types in order
1114 //        for the instruction patterns to work.
1115 def VOP_F16_F16 : VOPProfile <[f16, f16, untyped, untyped]>;
1116 def VOP_F16_I16 : VOPProfile <[f16, i32, untyped, untyped]>;
1117 def VOP_I16_F16 : VOPProfile <[i32, f16, untyped, untyped]>;
1118
1119 def VOP_F16_F16_F16 : VOPProfile <[f16, f16, f16, untyped]>;
1120 def VOP_F16_F16_I16 : VOPProfile <[f16, f16, i32, untyped]>;
1121 def VOP_I16_I16_I16 : VOPProfile <[i32, i32, i32, untyped]>;
1122
1123 def VOP_F32_F32 : VOPProfile <[f32, f32, untyped, untyped]>;
1124 def VOP_F32_F64 : VOPProfile <[f32, f64, untyped, untyped]>;
1125 def VOP_F32_I32 : VOPProfile <[f32, i32, untyped, untyped]>;
1126 def VOP_F64_F32 : VOPProfile <[f64, f32, untyped, untyped]>;
1127 def VOP_F64_F64 : VOPProfile <[f64, f64, untyped, untyped]>;
1128 def VOP_F64_I32 : VOPProfile <[f64, i32, untyped, untyped]>;
1129 def VOP_I32_F32 : VOPProfile <[i32, f32, untyped, untyped]>;
1130 def VOP_I32_F64 : VOPProfile <[i32, f64, untyped, untyped]>;
1131 def VOP_I32_I32 : VOPProfile <[i32, i32, untyped, untyped]>;
1132
1133 def VOP_F32_F32_F32 : VOPProfile <[f32, f32, f32, untyped]>;
1134 def VOP_F32_F32_I32 : VOPProfile <[f32, f32, i32, untyped]>;
1135 def VOP_F64_F64_F64 : VOPProfile <[f64, f64, f64, untyped]>;
1136 def VOP_F64_F64_I32 : VOPProfile <[f64, f64, i32, untyped]>;
1137 def VOP_I32_F32_F32 : VOPProfile <[i32, f32, f32, untyped]>;
1138 def VOP_I32_F32_I32 : VOPProfile <[i32, f32, i32, untyped]>;
1139 def VOP_I32_I32_I32 : VOPProfile <[i32, i32, i32, untyped]>;
1140
1141 // Write out to vcc or arbitrary SGPR.
1142 def VOP2b_I32_I1_I32_I32 : VOPProfile<[i32, i32, i32, untyped]> {
1143   let Asm32 = "$dst, vcc, $src0, $src1";
1144   let Asm64 = "$dst, $sdst, $src0, $src1";
1145   let Outs32 = (outs DstRC:$dst);
1146   let Outs64 = (outs DstRC:$dst, SReg_64:$sdst);
1147 }
1148
1149 // Write out to vcc or arbitrary SGPR and read in from vcc or
1150 // arbitrary SGPR.
1151 def VOP2b_I32_I1_I32_I32_I1 : VOPProfile<[i32, i32, i32, i1]> {
1152   let Src0RC32 = VCSrc_32;
1153   let Asm32 = "$dst, vcc, $src0, $src1, vcc";
1154   let Asm64 = "$dst, $sdst, $src0, $src1, $src2";
1155   let Outs32 = (outs DstRC:$dst);
1156   let Outs64 = (outs DstRC:$dst, SReg_64:$sdst);
1157
1158   // Suppress src2 implied by type since the 32-bit encoding uses an
1159   // implicit VCC use.
1160   let Ins32 = (ins Src0RC32:$src0, Src1RC32:$src1);
1161 }
1162
1163 // VOPC instructions are a special case because for the 32-bit
1164 // encoding, we want to display the implicit vcc write as if it were
1165 // an explicit $dst.
1166 class VOPC_Profile<ValueType vt0, ValueType vt1 = vt0> : VOPProfile <[i1, vt0, vt1, untyped]> {
1167   let Asm32 = "vcc, $src0, $src1";
1168 }
1169
1170 class VOPC_Class_Profile<ValueType vt> : VOPC_Profile<vt, i32> {
1171   let Ins64 = (ins InputModsNoDefault:$src0_modifiers, Src0RC64:$src0, Src1RC64:$src1);
1172   let Asm64 = "$dst, $src0_modifiers, $src1";
1173 }
1174
1175 def VOPC_I1_F32_F32 : VOPC_Profile<f32>;
1176 def VOPC_I1_F64_F64 : VOPC_Profile<f64>;
1177 def VOPC_I1_I32_I32 : VOPC_Profile<i32>;
1178 def VOPC_I1_I64_I64 : VOPC_Profile<i64>;
1179
1180 def VOPC_I1_F32_I32 : VOPC_Class_Profile<f32>;
1181 def VOPC_I1_F64_I32 : VOPC_Class_Profile<f64>;
1182
1183 def VOP_I64_I64_I32 : VOPProfile <[i64, i64, i32, untyped]>;
1184 def VOP_I64_I32_I64 : VOPProfile <[i64, i32, i64, untyped]>;
1185 def VOP_I64_I64_I64 : VOPProfile <[i64, i64, i64, untyped]>;
1186 def VOP_CNDMASK : VOPProfile <[i32, i32, i32, untyped]> {
1187   let Ins32 = (ins Src0RC32:$src0, Src1RC32:$src1);
1188   let Ins64 = (ins Src0RC64:$src0, Src1RC64:$src1, SSrc_64:$src2);
1189   let Asm64 = "$dst, $src0, $src1, $src2";
1190 }
1191
1192 def VOP_F32_F32_F32_F32 : VOPProfile <[f32, f32, f32, f32]>;
1193 def VOP_MADK : VOPProfile <[f32, f32, f32, f32]> {
1194   field dag Ins = (ins VCSrc_32:$src0, VGPR_32:$vsrc1, u32imm:$src2);
1195   field string Asm = "$dst, $src0, $vsrc1, $src2";
1196 }
1197 def VOP_MAC : VOPProfile <[f32, f32, f32, f32]> {
1198   let Ins32 = (ins Src0RC32:$src0, Src1RC32:$src1, VGPR_32:$src2);
1199   let Ins64 = getIns64<Src0RC64, Src1RC64, RegisterOperand<VGPR_32>, 3,
1200                              HasModifiers>.ret;
1201   let Asm32 = getAsm32<2>.ret;
1202   let Asm64 = getAsm64<2, HasModifiers>.ret;
1203 }
1204 def VOP_F64_F64_F64_F64 : VOPProfile <[f64, f64, f64, f64]>;
1205 def VOP_I32_I32_I32_I32 : VOPProfile <[i32, i32, i32, i32]>;
1206 def VOP_I64_I32_I32_I64 : VOPProfile <[i64, i32, i32, i64]>;
1207
1208 class SIInstAlias <string asm, dag result> : InstAlias <asm, result>,
1209                                              PredicateControl {
1210   field bit isCompare;
1211   field bit isCommutable;
1212 }
1213
1214 class VOP <string opName> {
1215   string OpName = opName;
1216 }
1217
1218 class VOP2_REV <string revOp, bit isOrig> {
1219   string RevOp = revOp;
1220   bit IsOrig = isOrig;
1221 }
1222
1223 class AtomicNoRet <string noRetOp, bit isRet> {
1224   string NoRetOp = noRetOp;
1225   bit IsRet = isRet;
1226 }
1227
1228 class VOP1_Pseudo <dag outs, dag ins, list<dag> pattern, string opName> :
1229   VOP1Common <outs, ins, "", pattern>,
1230   VOP <opName>,
1231   SIMCInstr <opName#"_e32", SISubtarget.NONE>,
1232   MnemonicAlias<opName#"_e32", opName> {
1233   let isPseudo = 1;
1234   let isCodeGenOnly = 1;
1235
1236   field bits<8> vdst;
1237   field bits<9> src0;
1238 }
1239
1240 class VOP1_Real_si <string opName, vop1 op, dag outs, dag ins, string asm> :
1241   VOP1<op.SI, outs, ins, asm, []>,
1242   SIMCInstr <opName#"_e32", SISubtarget.SI> {
1243   let AssemblerPredicate = SIAssemblerPredicate;
1244 }
1245
1246 class VOP1_Real_vi <string opName, vop1 op, dag outs, dag ins, string asm> :
1247   VOP1<op.VI, outs, ins, asm, []>,
1248   SIMCInstr <opName#"_e32", SISubtarget.VI> {
1249   let AssemblerPredicates = [isVI];
1250 }
1251
1252 multiclass VOP1_m <vop1 op, dag outs, dag ins, string asm, list<dag> pattern,
1253                    string opName> {
1254   def "" : VOP1_Pseudo <outs, ins, pattern, opName>;
1255
1256   def _si : VOP1_Real_si <opName, op, outs, ins, asm>;
1257
1258   def _vi : VOP1_Real_vi <opName, op, outs, ins, asm>;
1259 }
1260
1261 multiclass VOP1SI_m <vop1 op, dag outs, dag ins, string asm, list<dag> pattern,
1262                    string opName> {
1263   def "" : VOP1_Pseudo <outs, ins, pattern, opName>;
1264
1265   def _si : VOP1_Real_si <opName, op, outs, ins, asm>;
1266 }
1267
1268 class VOP2_Pseudo <dag outs, dag ins, list<dag> pattern, string opName> :
1269   VOP2Common <outs, ins, "", pattern>,
1270   VOP <opName>,
1271   SIMCInstr<opName#"_e32", SISubtarget.NONE>,
1272   MnemonicAlias<opName#"_e32", opName> {
1273   let isPseudo = 1;
1274   let isCodeGenOnly = 1;
1275 }
1276
1277 class VOP2_Real_si <string opName, vop2 op, dag outs, dag ins, string asm> :
1278   VOP2 <op.SI, outs, ins, opName#asm, []>,
1279   SIMCInstr <opName#"_e32", SISubtarget.SI> {
1280   let AssemblerPredicates = [isSICI];
1281 }
1282
1283 class VOP2_Real_vi <string opName, vop2 op, dag outs, dag ins, string asm> :
1284   VOP2 <op.VI, outs, ins, opName#asm, []>,
1285   SIMCInstr <opName#"_e32", SISubtarget.VI> {
1286   let AssemblerPredicates = [isVI];
1287 }
1288
1289 multiclass VOP2SI_m <vop2 op, dag outs, dag ins, string asm, list<dag> pattern,
1290                      string opName, string revOp> {
1291   def "" : VOP2_Pseudo <outs, ins, pattern, opName>,
1292            VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
1293
1294   def _si : VOP2_Real_si <opName, op, outs, ins, asm>;
1295 }
1296
1297 multiclass VOP2_m <vop2 op, dag outs, dag ins, string asm, list<dag> pattern,
1298                    string opName, string revOp> {
1299   def "" : VOP2_Pseudo <outs, ins, pattern, opName>,
1300            VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
1301
1302   def _si : VOP2_Real_si <opName, op, outs, ins, asm>;
1303
1304   def _vi : VOP2_Real_vi <opName, op, outs, ins, asm>;
1305
1306 }
1307
1308 class VOP3DisableFields <bit HasSrc1, bit HasSrc2, bit HasModifiers> {
1309
1310   bits<2> src0_modifiers = !if(HasModifiers, ?, 0);
1311   bits<2> src1_modifiers = !if(HasModifiers, !if(HasSrc1, ?, 0), 0);
1312   bits<2> src2_modifiers = !if(HasModifiers, !if(HasSrc2, ?, 0), 0);
1313   bits<2> omod = !if(HasModifiers, ?, 0);
1314   bits<1> clamp = !if(HasModifiers, ?, 0);
1315   bits<9> src1 = !if(HasSrc1, ?, 0);
1316   bits<9> src2 = !if(HasSrc2, ?, 0);
1317 }
1318
1319 class VOP3DisableModFields <bit HasSrc0Mods,
1320                             bit HasSrc1Mods = 0,
1321                             bit HasSrc2Mods = 0,
1322                             bit HasOutputMods = 0> {
1323   bits<2> src0_modifiers = !if(HasSrc0Mods, ?, 0);
1324   bits<2> src1_modifiers = !if(HasSrc1Mods, ?, 0);
1325   bits<2> src2_modifiers = !if(HasSrc2Mods, ?, 0);
1326   bits<2> omod = !if(HasOutputMods, ?, 0);
1327   bits<1> clamp = !if(HasOutputMods, ?, 0);
1328 }
1329
1330 class VOP3_Pseudo <dag outs, dag ins, list<dag> pattern, string opName> :
1331   VOP3Common <outs, ins, "", pattern>,
1332   VOP <opName>,
1333   SIMCInstr<opName#"_e64", SISubtarget.NONE>,
1334   MnemonicAlias<opName#"_e64", opName> {
1335   let isPseudo = 1;
1336   let isCodeGenOnly = 1;
1337 }
1338
1339 class VOP3_Real_si <bits<9> op, dag outs, dag ins, string asm, string opName> :
1340   VOP3Common <outs, ins, asm, []>,
1341   VOP3e <op>,
1342   SIMCInstr<opName#"_e64", SISubtarget.SI> {
1343   let AssemblerPredicates = [isSICI];
1344 }
1345
1346 class VOP3_Real_vi <bits<10> op, dag outs, dag ins, string asm, string opName> :
1347   VOP3Common <outs, ins, asm, []>,
1348   VOP3e_vi <op>,
1349   SIMCInstr <opName#"_e64", SISubtarget.VI> {
1350   let AssemblerPredicates = [isVI];
1351 }
1352
1353 class VOP3b_Real_si <bits<9> op, dag outs, dag ins, string asm, string opName> :
1354   VOP3Common <outs, ins, asm, []>,
1355   VOP3be <op>,
1356   SIMCInstr<opName#"_e64", SISubtarget.SI> {
1357   let AssemblerPredicates = [isSICI];
1358 }
1359
1360 class VOP3b_Real_vi <bits<10> op, dag outs, dag ins, string asm, string opName> :
1361   VOP3Common <outs, ins, asm, []>,
1362   VOP3be_vi <op>,
1363   SIMCInstr <opName#"_e64", SISubtarget.VI> {
1364   let AssemblerPredicates = [isVI];
1365 }
1366
1367 multiclass VOP3_m <vop op, dag outs, dag ins, string asm, list<dag> pattern,
1368                    string opName, int NumSrcArgs, bit HasMods = 1> {
1369
1370   def "" : VOP3_Pseudo <outs, ins, pattern, opName>;
1371
1372   def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>,
1373             VOP3DisableFields<!if(!eq(NumSrcArgs, 1), 0, 1),
1374                               !if(!eq(NumSrcArgs, 2), 0, 1),
1375                               HasMods>;
1376   def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName>,
1377             VOP3DisableFields<!if(!eq(NumSrcArgs, 1), 0, 1),
1378                               !if(!eq(NumSrcArgs, 2), 0, 1),
1379                               HasMods>;
1380 }
1381
1382 // VOP3_m without source modifiers
1383 multiclass VOP3_m_nomods <vop op, dag outs, dag ins, string asm, list<dag> pattern,
1384                    string opName, int NumSrcArgs, bit HasMods = 1> {
1385
1386   def "" : VOP3_Pseudo <outs, ins, pattern, opName>;
1387
1388   let src0_modifiers = 0,
1389       src1_modifiers = 0,
1390       src2_modifiers = 0,
1391       clamp = 0,
1392       omod = 0 in {
1393     def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>;
1394     def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName>;
1395   }
1396 }
1397
1398 multiclass VOP3_1_m <vop op, dag outs, dag ins, string asm,
1399                      list<dag> pattern, string opName, bit HasMods = 1> {
1400
1401   def "" : VOP3_Pseudo <outs, ins, pattern, opName>;
1402
1403   def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>,
1404             VOP3DisableFields<0, 0, HasMods>;
1405
1406   def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName>,
1407             VOP3DisableFields<0, 0, HasMods>;
1408 }
1409
1410 multiclass VOP3SI_1_m <vop op, dag outs, dag ins, string asm,
1411                      list<dag> pattern, string opName, bit HasMods = 1> {
1412
1413   def "" : VOP3_Pseudo <outs, ins, pattern, opName>;
1414
1415   def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>,
1416             VOP3DisableFields<0, 0, HasMods>;
1417   // No VI instruction. This class is for SI only.
1418 }
1419
1420 multiclass VOP3_2_m <vop op, dag outs, dag ins, string asm,
1421                      list<dag> pattern, string opName, string revOp,
1422                      bit HasMods = 1> {
1423
1424   def "" : VOP3_Pseudo <outs, ins, pattern, opName>,
1425            VOP2_REV<revOp#"_e64", !eq(revOp, opName)>;
1426
1427   def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>,
1428             VOP3DisableFields<1, 0, HasMods>;
1429
1430   def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName>,
1431             VOP3DisableFields<1, 0, HasMods>;
1432 }
1433
1434 multiclass VOP3SI_2_m <vop op, dag outs, dag ins, string asm,
1435                      list<dag> pattern, string opName, string revOp,
1436                      bit HasMods = 1> {
1437
1438   def "" : VOP3_Pseudo <outs, ins, pattern, opName>,
1439            VOP2_REV<revOp#"_e64", !eq(revOp, opName)>;
1440
1441   def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>,
1442             VOP3DisableFields<1, 0, HasMods>;
1443
1444   // No VI instruction. This class is for SI only.
1445 }
1446
1447 // Two operand VOP3b instruction that may have a 3rd SGPR bool operand
1448 // instead of an implicit VCC as in the VOP2b format.
1449 multiclass VOP3b_2_3_m <vop op, dag outs, dag ins, string asm,
1450                         list<dag> pattern, string opName, string revOp,
1451                         bit HasMods = 1, bit useSrc2Input = 0> {
1452   def "" : VOP3_Pseudo <outs, ins, pattern, opName>;
1453
1454   def _si : VOP3b_Real_si <op.SI3, outs, ins, asm, opName>,
1455             VOP3DisableFields<1, useSrc2Input, HasMods>;
1456
1457   def _vi : VOP3b_Real_vi <op.VI3, outs, ins, asm, opName>,
1458             VOP3DisableFields<1, useSrc2Input, HasMods>;
1459 }
1460
1461 multiclass VOP3_C_m <vop op, dag outs, dag ins, string asm,
1462                      list<dag> pattern, string opName,
1463                      bit HasMods, bit defExec, string revOp> {
1464
1465   def "" : VOP3_Pseudo <outs, ins, pattern, opName>,
1466            VOP2_REV<revOp#"_e64", !eq(revOp, opName)>;
1467
1468   def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>,
1469             VOP3DisableFields<1, 0, HasMods> {
1470     let Defs = !if(defExec, [EXEC], []);
1471   }
1472
1473   def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName>,
1474             VOP3DisableFields<1, 0, HasMods> {
1475     let Defs = !if(defExec, [EXEC], []);
1476   }
1477 }
1478
1479 // An instruction that is VOP2 on SI and VOP3 on VI, no modifiers.
1480 multiclass VOP2SI_3VI_m <vop3 op, string opName, dag outs, dag ins,
1481                          string asm, list<dag> pattern = []> {
1482   let isPseudo = 1, isCodeGenOnly = 1 in {
1483     def "" : VOPAnyCommon <outs, ins, "", pattern>,
1484              SIMCInstr<opName, SISubtarget.NONE>;
1485   }
1486
1487   def _si : VOP2 <op.SI3{5-0}, outs, ins, asm, []>,
1488             SIMCInstr <opName, SISubtarget.SI> {
1489             let AssemblerPredicates = [isSICI];
1490   }
1491
1492   def _vi : VOP3Common <outs, ins, asm, []>,
1493             VOP3e_vi <op.VI3>,
1494             VOP3DisableFields <1, 0, 0>,
1495             SIMCInstr <opName, SISubtarget.VI> {
1496             let AssemblerPredicates = [isVI];
1497   }
1498 }
1499
1500 multiclass VOP1_Helper <vop1 op, string opName, dag outs,
1501                         dag ins32, string asm32, list<dag> pat32,
1502                         dag ins64, string asm64, list<dag> pat64,
1503                         bit HasMods> {
1504
1505   defm _e32 : VOP1_m <op, outs, ins32, opName#asm32, pat32, opName>;
1506
1507   defm _e64 : VOP3_1_m <op, outs, ins64, opName#asm64, pat64, opName, HasMods>;
1508 }
1509
1510 multiclass VOP1Inst <vop1 op, string opName, VOPProfile P,
1511                      SDPatternOperator node = null_frag> : VOP1_Helper <
1512   op, opName, P.Outs,
1513   P.Ins32, P.Asm32, [],
1514   P.Ins64, P.Asm64,
1515   !if(P.HasModifiers,
1516       [(set P.DstVT:$dst, (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0,
1517                                 i32:$src0_modifiers, i1:$clamp, i32:$omod))))],
1518       [(set P.DstVT:$dst, (node P.Src0VT:$src0))]),
1519   P.HasModifiers
1520 >;
1521
1522 multiclass VOP1InstSI <vop1 op, string opName, VOPProfile P,
1523                        SDPatternOperator node = null_frag> {
1524
1525   defm _e32 : VOP1SI_m <op, P.Outs, P.Ins32, opName#P.Asm32, [], opName>;
1526
1527   defm _e64 : VOP3SI_1_m <op, P.Outs, P.Ins64, opName#P.Asm64,
1528     !if(P.HasModifiers,
1529       [(set P.DstVT:$dst, (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0,
1530                                 i32:$src0_modifiers, i1:$clamp, i32:$omod))))],
1531       [(set P.DstVT:$dst, (node P.Src0VT:$src0))]),
1532     opName, P.HasModifiers>;
1533 }
1534
1535 multiclass VOP2_Helper <vop2 op, string opName, dag outs,
1536                         dag ins32, string asm32, list<dag> pat32,
1537                         dag ins64, string asm64, list<dag> pat64,
1538                         string revOp, bit HasMods> {
1539   defm _e32 : VOP2_m <op, outs, ins32, asm32, pat32, opName, revOp>;
1540
1541   defm _e64 : VOP3_2_m <op,
1542     outs, ins64, opName#asm64, pat64, opName, revOp, HasMods
1543   >;
1544 }
1545
1546 multiclass VOP2Inst <vop2 op, string opName, VOPProfile P,
1547                      SDPatternOperator node = null_frag,
1548                      string revOp = opName> : VOP2_Helper <
1549   op, opName, P.Outs,
1550   P.Ins32, P.Asm32, [],
1551   P.Ins64, P.Asm64,
1552   !if(P.HasModifiers,
1553       [(set P.DstVT:$dst,
1554            (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1555                                       i1:$clamp, i32:$omod)),
1556                  (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
1557       [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1))]),
1558   revOp, P.HasModifiers
1559 >;
1560
1561 multiclass VOP2InstSI <vop2 op, string opName, VOPProfile P,
1562                        SDPatternOperator node = null_frag,
1563                        string revOp = opName> {
1564   defm _e32 : VOP2SI_m <op, P.Outs, P.Ins32, P.Asm32, [], opName, revOp>;
1565
1566   defm _e64 : VOP3SI_2_m <op, P.Outs, P.Ins64, opName#P.Asm64,
1567     !if(P.HasModifiers,
1568         [(set P.DstVT:$dst,
1569              (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1570                                         i1:$clamp, i32:$omod)),
1571                    (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
1572         [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1))]),
1573     opName, revOp, P.HasModifiers>;
1574 }
1575
1576 multiclass VOP2b_Helper <vop2 op, string opName, dag outs32, dag outs64,
1577                          dag ins32, string asm32, list<dag> pat32,
1578                          dag ins64, string asm64, list<dag> pat64,
1579                          string revOp, bit HasMods, bit useSGPRInput> {
1580
1581   let Uses = !if(useSGPRInput, [VCC, EXEC], [EXEC]), Defs = [VCC] in {
1582     defm _e32 : VOP2_m <op, outs32, ins32, asm32, pat32, opName, revOp>;
1583   }
1584
1585   defm _e64 : VOP3b_2_3_m <op,
1586     outs64, ins64, opName#asm64, pat64, opName, revOp, HasMods, useSGPRInput
1587   >;
1588 }
1589
1590 multiclass VOP2bInst <vop2 op, string opName, VOPProfile P,
1591                       SDPatternOperator node = null_frag,
1592                       string revOp = opName> : VOP2b_Helper <
1593   op, opName, P.Outs32, P.Outs64,
1594   P.Ins32, P.Asm32, [],
1595   P.Ins64, P.Asm64,
1596   !if(P.HasModifiers,
1597       [(set P.DstVT:$dst,
1598            (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1599                                       i1:$clamp, i32:$omod)),
1600                  (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
1601       [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1))]),
1602   revOp, P.HasModifiers, !eq(P.NumSrcArgs, 3)
1603 >;
1604
1605 // A VOP2 instruction that is VOP3-only on VI.
1606 multiclass VOP2_VI3_Helper <vop23 op, string opName, dag outs,
1607                             dag ins32, string asm32, list<dag> pat32,
1608                             dag ins64, string asm64, list<dag> pat64,
1609                             string revOp, bit HasMods> {
1610   defm _e32 : VOP2SI_m <op, outs, ins32, asm32, pat32, opName, revOp>;
1611
1612   defm _e64 : VOP3_2_m <op, outs, ins64, opName#asm64, pat64, opName,
1613                         revOp, HasMods>;
1614 }
1615
1616 multiclass VOP2_VI3_Inst <vop23 op, string opName, VOPProfile P,
1617                           SDPatternOperator node = null_frag,
1618                           string revOp = opName>
1619                           : VOP2_VI3_Helper <
1620   op, opName, P.Outs,
1621   P.Ins32, P.Asm32, [],
1622   P.Ins64, P.Asm64,
1623   !if(P.HasModifiers,
1624       [(set P.DstVT:$dst,
1625            (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1626                                       i1:$clamp, i32:$omod)),
1627                  (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
1628       [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1))]),
1629   revOp, P.HasModifiers
1630 >;
1631
1632 multiclass VOP2MADK <vop2 op, string opName, list<dag> pattern = []> {
1633
1634   def "" : VOP2_Pseudo <VOP_MADK.Outs, VOP_MADK.Ins, pattern, opName>;
1635
1636 let isCodeGenOnly = 0 in {
1637   def _si : VOP2Common <VOP_MADK.Outs, VOP_MADK.Ins,
1638                         !strconcat(opName, VOP_MADK.Asm), []>,
1639             SIMCInstr <opName#"_e32", SISubtarget.SI>,
1640             VOP2_MADKe <op.SI> {
1641             let AssemblerPredicates = [isSICI];
1642             }
1643
1644   def _vi : VOP2Common <VOP_MADK.Outs, VOP_MADK.Ins,
1645                         !strconcat(opName, VOP_MADK.Asm), []>,
1646             SIMCInstr <opName#"_e32", SISubtarget.VI>,
1647             VOP2_MADKe <op.VI> {
1648             let AssemblerPredicates = [isVI];
1649             }
1650 } // End isCodeGenOnly = 0
1651 }
1652
1653 class VOPC_Pseudo <dag ins, list<dag> pattern, string opName> :
1654   VOPCCommon <ins, "", pattern>,
1655   VOP <opName>,
1656   SIMCInstr<opName#"_e32", SISubtarget.NONE> {
1657   let isPseudo = 1;
1658   let isCodeGenOnly = 1;
1659 }
1660
1661 multiclass VOPC_m <vopc op, dag ins, string op_asm, list<dag> pattern,
1662                    string opName, bit DefExec, VOPProfile p,
1663                    string revOpName = "", string asm = opName#"_e32 "#op_asm,
1664                    string alias_asm = opName#" "#op_asm> {
1665   def "" : VOPC_Pseudo <ins, pattern, opName>;
1666
1667   let AssemblerPredicates = [isSICI] in {
1668
1669   def _si : VOPC<op.SI, ins, asm, []>,
1670             SIMCInstr <opName#"_e32", SISubtarget.SI> {
1671     let Defs = !if(DefExec, [VCC, EXEC], [VCC]);
1672     let hasSideEffects = DefExec;
1673   }
1674
1675   def : SIInstAlias <
1676     alias_asm,
1677     (!cast<Instruction>(NAME#"_e32_si") p.Src0RC32:$src0, p.Src1RC32:$src1)
1678   >;
1679
1680   } // End AssemblerPredicates = [isSICI]
1681
1682
1683   let AssemblerPredicates = [isVI] in {
1684
1685   def _vi : VOPC<op.VI, ins, asm, []>,
1686             SIMCInstr <opName#"_e32", SISubtarget.VI> {
1687     let Defs = !if(DefExec, [VCC, EXEC], [VCC]);
1688     let hasSideEffects = DefExec;
1689   }
1690
1691   def : SIInstAlias <
1692     alias_asm,
1693     (!cast<Instruction>(NAME#"_e32_vi") p.Src0RC32:$src0, p.Src1RC32:$src1)
1694   >;
1695
1696   } // End AssemblerPredicates = [isVI]
1697 }
1698
1699 multiclass VOPC_Helper <vopc op, string opName,
1700                         dag ins32, string asm32, list<dag> pat32,
1701                         dag out64, dag ins64, string asm64, list<dag> pat64,
1702                         bit HasMods, bit DefExec, string revOp,
1703                         VOPProfile p> {
1704   defm _e32 : VOPC_m <op, ins32, asm32, pat32, opName, DefExec, p>;
1705
1706   defm _e64 : VOP3_C_m <op, out64, ins64, opName#asm64, pat64,
1707                         opName, HasMods, DefExec, revOp>;
1708 }
1709
1710 // Special case for class instructions which only have modifiers on
1711 // the 1st source operand.
1712 multiclass VOPC_Class_Helper <vopc op, string opName,
1713                              dag ins32, string asm32, list<dag> pat32,
1714                              dag out64, dag ins64, string asm64, list<dag> pat64,
1715                              bit HasMods, bit DefExec, string revOp,
1716                              VOPProfile p> {
1717   defm _e32 : VOPC_m <op, ins32, asm32, pat32, opName, DefExec, p>;
1718
1719   defm _e64 : VOP3_C_m <op, out64, ins64, opName#asm64, pat64,
1720                         opName, HasMods, DefExec, revOp>,
1721                         VOP3DisableModFields<1, 0, 0>;
1722 }
1723
1724 multiclass VOPCInst <vopc op, string opName,
1725                      VOPProfile P, PatLeaf cond = COND_NULL,
1726                      string revOp = opName,
1727                      bit DefExec = 0> : VOPC_Helper <
1728   op, opName,
1729   P.Ins32, P.Asm32, [],
1730   (outs VOPDstS64:$dst), P.Ins64, P.Asm64,
1731   !if(P.HasModifiers,
1732       [(set i1:$dst,
1733           (setcc (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1734                                       i1:$clamp, i32:$omod)),
1735                  (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)),
1736                  cond))],
1737       [(set i1:$dst, (setcc P.Src0VT:$src0, P.Src1VT:$src1, cond))]),
1738   P.HasModifiers, DefExec, revOp, P
1739 >;
1740
1741 multiclass VOPCClassInst <vopc op, string opName, VOPProfile P,
1742                      bit DefExec = 0> : VOPC_Class_Helper <
1743   op, opName,
1744   P.Ins32, P.Asm32, [],
1745   (outs VOPDstS64:$dst), P.Ins64, P.Asm64,
1746   !if(P.HasModifiers,
1747       [(set i1:$dst,
1748           (AMDGPUfp_class (P.Src0VT (VOP3Mods0Clamp0OMod P.Src0VT:$src0, i32:$src0_modifiers)), P.Src1VT:$src1))],
1749       [(set i1:$dst, (AMDGPUfp_class P.Src0VT:$src0, P.Src1VT:$src1))]),
1750   P.HasModifiers, DefExec, opName, P
1751 >;
1752
1753
1754 multiclass VOPC_F32 <vopc op, string opName, PatLeaf cond = COND_NULL, string revOp = opName> :
1755   VOPCInst <op, opName, VOPC_I1_F32_F32, cond, revOp>;
1756
1757 multiclass VOPC_F64 <vopc op, string opName, PatLeaf cond = COND_NULL, string revOp = opName> :
1758   VOPCInst <op, opName, VOPC_I1_F64_F64, cond, revOp>;
1759
1760 multiclass VOPC_I32 <vopc op, string opName, PatLeaf cond = COND_NULL, string revOp = opName> :
1761   VOPCInst <op, opName, VOPC_I1_I32_I32, cond, revOp>;
1762
1763 multiclass VOPC_I64 <vopc op, string opName, PatLeaf cond = COND_NULL, string revOp = opName> :
1764   VOPCInst <op, opName, VOPC_I1_I64_I64, cond, revOp>;
1765
1766
1767 multiclass VOPCX <vopc op, string opName, VOPProfile P,
1768                   PatLeaf cond = COND_NULL,
1769                   string revOp = "">
1770   : VOPCInst <op, opName, P, cond, revOp, 1>;
1771
1772 multiclass VOPCX_F32 <vopc op, string opName, string revOp = opName> :
1773   VOPCX <op, opName, VOPC_I1_F32_F32, COND_NULL, revOp>;
1774
1775 multiclass VOPCX_F64 <vopc op, string opName, string revOp = opName> :
1776   VOPCX <op, opName, VOPC_I1_F64_F64, COND_NULL, revOp>;
1777
1778 multiclass VOPCX_I32 <vopc op, string opName, string revOp = opName> :
1779   VOPCX <op, opName, VOPC_I1_I32_I32, COND_NULL, revOp>;
1780
1781 multiclass VOPCX_I64 <vopc op, string opName, string revOp = opName> :
1782   VOPCX <op, opName, VOPC_I1_I64_I64, COND_NULL, revOp>;
1783
1784 multiclass VOP3_Helper <vop3 op, string opName, dag outs, dag ins, string asm,
1785                         list<dag> pat, int NumSrcArgs, bit HasMods> : VOP3_m <
1786     op, outs, ins, opName#" "#asm, pat, opName, NumSrcArgs, HasMods
1787 >;
1788
1789 multiclass VOPC_CLASS_F32 <vopc op, string opName> :
1790   VOPCClassInst <op, opName, VOPC_I1_F32_I32, 0>;
1791
1792 multiclass VOPCX_CLASS_F32 <vopc op, string opName> :
1793   VOPCClassInst <op, opName, VOPC_I1_F32_I32, 1>;
1794
1795 multiclass VOPC_CLASS_F64 <vopc op, string opName> :
1796   VOPCClassInst <op, opName, VOPC_I1_F64_I32, 0>;
1797
1798 multiclass VOPCX_CLASS_F64 <vopc op, string opName> :
1799   VOPCClassInst <op, opName, VOPC_I1_F64_I32, 1>;
1800
1801 multiclass VOP3Inst <vop3 op, string opName, VOPProfile P,
1802                      SDPatternOperator node = null_frag> : VOP3_Helper <
1803   op, opName, (outs P.DstRC.RegClass:$dst), P.Ins64, P.Asm64,
1804   !if(!eq(P.NumSrcArgs, 3),
1805     !if(P.HasModifiers,
1806         [(set P.DstVT:$dst,
1807             (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1808                                        i1:$clamp, i32:$omod)),
1809                   (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)),
1810                   (P.Src2VT (VOP3Mods P.Src2VT:$src2, i32:$src2_modifiers))))],
1811         [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1,
1812                                   P.Src2VT:$src2))]),
1813   !if(!eq(P.NumSrcArgs, 2),
1814     !if(P.HasModifiers,
1815         [(set P.DstVT:$dst,
1816             (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1817                                        i1:$clamp, i32:$omod)),
1818                   (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
1819         [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1))])
1820   /* P.NumSrcArgs == 1 */,
1821     !if(P.HasModifiers,
1822         [(set P.DstVT:$dst,
1823             (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1824                                        i1:$clamp, i32:$omod))))],
1825         [(set P.DstVT:$dst, (node P.Src0VT:$src0))]))),
1826   P.NumSrcArgs, P.HasModifiers
1827 >;
1828
1829 // Special case for v_div_fmas_{f32|f64}, since it seems to be the
1830 // only VOP instruction that implicitly reads VCC.
1831 multiclass VOP3_VCC_Inst <vop3 op, string opName,
1832                           VOPProfile P,
1833                           SDPatternOperator node = null_frag> : VOP3_Helper <
1834   op, opName,
1835   (outs P.DstRC.RegClass:$dst),
1836   (ins InputModsNoDefault:$src0_modifiers, P.Src0RC64:$src0,
1837        InputModsNoDefault:$src1_modifiers, P.Src1RC64:$src1,
1838        InputModsNoDefault:$src2_modifiers, P.Src2RC64:$src2,
1839        ClampMod:$clamp,
1840        omod:$omod),
1841   "$dst, $src0_modifiers, $src1_modifiers, $src2_modifiers"#"$clamp"#"$omod",
1842   [(set P.DstVT:$dst,
1843             (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1844                                        i1:$clamp, i32:$omod)),
1845                   (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)),
1846                   (P.Src2VT (VOP3Mods P.Src2VT:$src2, i32:$src2_modifiers)),
1847                   (i1 VCC)))],
1848   3, 1
1849 >;
1850
1851 multiclass VOP3b_Helper <vop op, RegisterClass vrc, RegisterOperand arc,
1852                     string opName, list<dag> pattern> :
1853   VOP3b_2_3_m <
1854   op, (outs vrc:$vdst, SReg_64:$sdst),
1855       (ins InputModsNoDefault:$src0_modifiers, arc:$src0,
1856            InputModsNoDefault:$src1_modifiers, arc:$src1,
1857            InputModsNoDefault:$src2_modifiers, arc:$src2,
1858            ClampMod:$clamp, omod:$omod),
1859   opName#" $vdst, $sdst, $src0_modifiers, $src1_modifiers, $src2_modifiers"#"$clamp"#"$omod", pattern,
1860   opName, opName, 1, 1
1861 >;
1862
1863 multiclass VOP3b_64 <vop3 op, string opName, list<dag> pattern> :
1864   VOP3b_Helper <op, VReg_64, VSrc_64, opName, pattern>;
1865
1866 multiclass VOP3b_32 <vop3 op, string opName, list<dag> pattern> :
1867   VOP3b_Helper <op, VGPR_32, VSrc_32, opName, pattern>;
1868
1869
1870 class Vop3ModPat<Instruction Inst, VOPProfile P, SDPatternOperator node> : Pat<
1871   (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i1:$clamp, i32:$omod)),
1872         (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)),
1873         (P.Src2VT (VOP3Mods P.Src2VT:$src2, i32:$src2_modifiers))),
1874   (Inst i32:$src0_modifiers, P.Src0VT:$src0,
1875         i32:$src1_modifiers, P.Src1VT:$src1,
1876         i32:$src2_modifiers, P.Src2VT:$src2,
1877         i1:$clamp,
1878         i32:$omod)>;
1879
1880 //===----------------------------------------------------------------------===//
1881 // Interpolation opcodes
1882 //===----------------------------------------------------------------------===//
1883
1884 class VINTRP_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
1885   VINTRPCommon <outs, ins, "", pattern>,
1886   SIMCInstr<opName, SISubtarget.NONE> {
1887   let isPseudo = 1;
1888   let isCodeGenOnly = 1;
1889 }
1890
1891 class VINTRP_Real_si <bits <2> op, string opName, dag outs, dag ins,
1892                       string asm> :
1893   VINTRPCommon <outs, ins, asm, []>,
1894   VINTRPe <op>,
1895   SIMCInstr<opName, SISubtarget.SI>;
1896
1897 class VINTRP_Real_vi <bits <2> op, string opName, dag outs, dag ins,
1898                       string asm> :
1899   VINTRPCommon <outs, ins, asm, []>,
1900   VINTRPe_vi <op>,
1901   SIMCInstr<opName, SISubtarget.VI>;
1902
1903 multiclass VINTRP_m <bits <2> op, dag outs, dag ins, string asm,
1904                      list<dag> pattern = []> {
1905   def "" : VINTRP_Pseudo <NAME, outs, ins, pattern>;
1906
1907   def _si : VINTRP_Real_si <op, NAME, outs, ins, asm>;
1908
1909   def _vi : VINTRP_Real_vi <op, NAME, outs, ins, asm>;
1910 }
1911
1912 //===----------------------------------------------------------------------===//
1913 // Vector I/O classes
1914 //===----------------------------------------------------------------------===//
1915
1916 class DS_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
1917   DS <outs, ins, "", pattern>,
1918   SIMCInstr <opName, SISubtarget.NONE> {
1919   let isPseudo = 1;
1920   let isCodeGenOnly = 1;
1921 }
1922
1923 class DS_Real_si <bits<8> op, string opName, dag outs, dag ins, string asm> :
1924   DS <outs, ins, asm, []>,
1925   DSe <op>,
1926   SIMCInstr <opName, SISubtarget.SI> {
1927   let isCodeGenOnly = 0;
1928 }
1929
1930 class DS_Real_vi <bits<8> op, string opName, dag outs, dag ins, string asm> :
1931   DS <outs, ins, asm, []>,
1932   DSe_vi <op>,
1933   SIMCInstr <opName, SISubtarget.VI>;
1934
1935 class DS_Off16_Real_si <bits<8> op, string opName, dag outs, dag ins, string asm> :
1936   DS_Real_si <op,opName, outs, ins, asm> {
1937
1938   // Single load interpret the 2 i8imm operands as a single i16 offset.
1939   bits<16> offset;
1940   let offset0 = offset{7-0};
1941   let offset1 = offset{15-8};
1942   let isCodeGenOnly = 0;
1943 }
1944
1945 class DS_Off16_Real_vi <bits<8> op, string opName, dag outs, dag ins, string asm> :
1946   DS_Real_vi <op, opName, outs, ins, asm> {
1947
1948   // Single load interpret the 2 i8imm operands as a single i16 offset.
1949   bits<16> offset;
1950   let offset0 = offset{7-0};
1951   let offset1 = offset{15-8};
1952 }
1953
1954 multiclass DS_1A_RET <bits<8> op, string opName, RegisterClass rc,
1955   dag outs = (outs rc:$vdst),
1956   dag ins = (ins VGPR_32:$addr, ds_offset:$offset, gds:$gds),
1957   string asm = opName#" $vdst, $addr"#"$offset$gds"> {
1958
1959   def "" : DS_Pseudo <opName, outs, ins, []>;
1960
1961   let data0 = 0, data1 = 0 in {
1962     def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
1963     def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
1964   }
1965 }
1966
1967 multiclass DS_1A_Off8_RET <bits<8> op, string opName, RegisterClass rc,
1968   dag outs = (outs rc:$vdst),
1969   dag ins = (ins VGPR_32:$addr, ds_offset0:$offset0, ds_offset1:$offset1,
1970                  gds01:$gds),
1971   string asm = opName#" $vdst, $addr"#"$offset0"#"$offset1$gds"> {
1972
1973   def "" : DS_Pseudo <opName, outs, ins, []>;
1974
1975   let data0 = 0, data1 = 0, AsmMatchConverter = "cvtDSOffset01" in {
1976     def _si : DS_Real_si <op, opName, outs, ins, asm>;
1977     def _vi : DS_Real_vi <op, opName, outs, ins, asm>;
1978   }
1979 }
1980
1981 multiclass DS_1A1D_NORET <bits<8> op, string opName, RegisterClass rc,
1982   dag outs = (outs),
1983   dag ins = (ins VGPR_32:$addr, rc:$data0, ds_offset:$offset, gds:$gds),
1984   string asm = opName#" $addr, $data0"#"$offset$gds"> {
1985
1986   def "" : DS_Pseudo <opName, outs, ins, []>,
1987            AtomicNoRet<opName, 0>;
1988
1989   let data1 = 0, vdst = 0 in {
1990     def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
1991     def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
1992   }
1993 }
1994
1995 multiclass DS_1A1D_Off8_NORET <bits<8> op, string opName, RegisterClass rc,
1996   dag outs = (outs),
1997   dag ins = (ins VGPR_32:$addr, rc:$data0, rc:$data1,
1998               ds_offset0:$offset0, ds_offset1:$offset1, gds01:$gds),
1999   string asm = opName#" $addr, $data0, $data1"#"$offset0"#"$offset1"#"$gds"> {
2000
2001   def "" : DS_Pseudo <opName, outs, ins, []>;
2002
2003   let vdst = 0, AsmMatchConverter = "cvtDSOffset01" in {
2004     def _si : DS_Real_si <op, opName, outs, ins, asm>;
2005     def _vi : DS_Real_vi <op, opName, outs, ins, asm>;
2006   }
2007 }
2008
2009 multiclass DS_1A1D_RET <bits<8> op, string opName, RegisterClass rc,
2010                         string noRetOp = "",
2011   dag outs = (outs rc:$vdst),
2012   dag ins = (ins VGPR_32:$addr, rc:$data0, ds_offset:$offset, gds:$gds),
2013   string asm = opName#" $vdst, $addr, $data0"#"$offset$gds"> {
2014
2015   def "" : DS_Pseudo <opName, outs, ins, []>,
2016            AtomicNoRet<noRetOp, 1>;
2017
2018   let data1 = 0 in {
2019     def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
2020     def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
2021   }
2022 }
2023
2024 multiclass DS_1A2D_RET_m <bits<8> op, string opName, RegisterClass rc,
2025                           string noRetOp = "", dag ins,
2026   dag outs = (outs rc:$vdst),
2027   string asm = opName#" $vdst, $addr, $data0, $data1"#"$offset"#"$gds"> {
2028
2029   def "" : DS_Pseudo <opName, outs, ins, []>,
2030            AtomicNoRet<noRetOp, 1>;
2031
2032   def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
2033   def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
2034 }
2035
2036 multiclass DS_1A2D_RET <bits<8> op, string asm, RegisterClass rc,
2037                         string noRetOp = "", RegisterClass src = rc> :
2038   DS_1A2D_RET_m <op, asm, rc, noRetOp,
2039                  (ins VGPR_32:$addr, src:$data0, src:$data1,
2040                       ds_offset:$offset, gds:$gds)
2041 >;
2042
2043 multiclass DS_1A2D_NORET <bits<8> op, string opName, RegisterClass rc,
2044                           string noRetOp = opName,
2045   dag outs = (outs),
2046   dag ins = (ins VGPR_32:$addr, rc:$data0, rc:$data1,
2047                  ds_offset:$offset, gds:$gds),
2048   string asm = opName#" $addr, $data0, $data1"#"$offset"#"$gds"> {
2049
2050   def "" : DS_Pseudo <opName, outs, ins, []>,
2051            AtomicNoRet<noRetOp, 0>;
2052
2053   let vdst = 0 in {
2054     def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
2055     def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
2056   }
2057 }
2058
2059 multiclass DS_0A_RET <bits<8> op, string opName,
2060   dag outs = (outs VGPR_32:$vdst),
2061   dag ins = (ins ds_offset:$offset, gds:$gds),
2062   string asm = opName#" $vdst"#"$offset"#"$gds"> {
2063
2064   let mayLoad = 1, mayStore = 1 in {
2065     def "" : DS_Pseudo <opName, outs, ins, []>;
2066
2067     let addr = 0, data0 = 0, data1 = 0 in {
2068       def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
2069       def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
2070     } // end addr = 0, data0 = 0, data1 = 0
2071   } // end mayLoad = 1, mayStore = 1
2072 }
2073
2074 multiclass DS_1A_RET_GDS <bits<8> op, string opName,
2075   dag outs = (outs VGPR_32:$vdst),
2076   dag ins = (ins VGPR_32:$addr, ds_offset_gds:$offset),
2077   string asm = opName#" $vdst, $addr"#"$offset gds"> {
2078
2079   def "" : DS_Pseudo <opName, outs, ins, []>;
2080
2081   let data0 = 0, data1 = 0, gds = 1 in {
2082     def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
2083     def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
2084   } // end data0 = 0, data1 = 0, gds = 1
2085 }
2086
2087 multiclass DS_1A_GDS <bits<8> op, string opName,
2088   dag outs = (outs),
2089   dag ins = (ins VGPR_32:$addr),
2090   string asm = opName#" $addr gds"> {
2091
2092   def "" : DS_Pseudo <opName, outs, ins, []>;
2093
2094   let vdst = 0, data0 = 0, data1 = 0, offset0 = 0, offset1 = 0, gds = 1 in {
2095     def _si : DS_Real_si <op, opName, outs, ins, asm>;
2096     def _vi : DS_Real_vi <op, opName, outs, ins, asm>;
2097   } // end vdst = 0, data = 0, data1 = 0, gds = 1
2098 }
2099
2100 multiclass DS_1A <bits<8> op, string opName,
2101   dag outs = (outs),
2102   dag ins = (ins VGPR_32:$addr, ds_offset:$offset, gds:$gds),
2103   string asm = opName#" $addr"#"$offset"#"$gds"> {
2104
2105   let mayLoad = 1, mayStore = 1 in {
2106     def "" : DS_Pseudo <opName, outs, ins, []>;
2107
2108     let vdst = 0, data0 = 0, data1 = 0 in {
2109       def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
2110       def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
2111     } // let vdst = 0, data0 = 0, data1 = 0
2112   } // end mayLoad = 1, mayStore = 1
2113 }
2114
2115 //===----------------------------------------------------------------------===//
2116 // MTBUF classes
2117 //===----------------------------------------------------------------------===//
2118
2119 class MTBUF_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
2120   MTBUF <outs, ins, "", pattern>,
2121   SIMCInstr<opName, SISubtarget.NONE> {
2122   let isPseudo = 1;
2123   let isCodeGenOnly = 1;
2124 }
2125
2126 class MTBUF_Real_si <bits<3> op, string opName, dag outs, dag ins,
2127                     string asm> :
2128   MTBUF <outs, ins, asm, []>,
2129   MTBUFe <op>,
2130   SIMCInstr<opName, SISubtarget.SI>;
2131
2132 class MTBUF_Real_vi <bits<4> op, string opName, dag outs, dag ins, string asm> :
2133   MTBUF <outs, ins, asm, []>,
2134   MTBUFe_vi <op>,
2135   SIMCInstr <opName, SISubtarget.VI>;
2136
2137 multiclass MTBUF_m <bits<3> op, string opName, dag outs, dag ins, string asm,
2138                     list<dag> pattern> {
2139
2140   def "" : MTBUF_Pseudo <opName, outs, ins, pattern>;
2141
2142   def _si : MTBUF_Real_si <op, opName, outs, ins, asm>;
2143
2144   def _vi : MTBUF_Real_vi <{0, op{2}, op{1}, op{0}}, opName, outs, ins, asm>;
2145
2146 }
2147
2148 let mayStore = 1, mayLoad = 0 in {
2149
2150 multiclass MTBUF_Store_Helper <bits<3> op, string opName,
2151                                RegisterClass regClass> : MTBUF_m <
2152   op, opName, (outs),
2153   (ins regClass:$vdata, u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
2154    i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VGPR_32:$vaddr,
2155    SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SCSrc_32:$soffset),
2156   opName#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
2157         #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset", []
2158 >;
2159
2160 } // mayStore = 1, mayLoad = 0
2161
2162 let mayLoad = 1, mayStore = 0 in {
2163
2164 multiclass MTBUF_Load_Helper <bits<3> op, string opName,
2165                               RegisterClass regClass> : MTBUF_m <
2166   op, opName, (outs regClass:$dst),
2167   (ins u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
2168        i8imm:$dfmt, i8imm:$nfmt, VGPR_32:$vaddr, SReg_128:$srsrc,
2169        i1imm:$slc, i1imm:$tfe, SCSrc_32:$soffset),
2170   opName#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
2171         #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset", []
2172 >;
2173
2174 } // mayLoad = 1, mayStore = 0
2175
2176 //===----------------------------------------------------------------------===//
2177 // MUBUF classes
2178 //===----------------------------------------------------------------------===//
2179
2180 class mubuf <bits<7> si, bits<7> vi = si> {
2181   field bits<7> SI = si;
2182   field bits<7> VI = vi;
2183 }
2184
2185 let isCodeGenOnly = 0 in {
2186
2187 class MUBUF_si <bits<7> op, dag outs, dag ins, string asm, list<dag> pattern> :
2188   MUBUF <outs, ins, asm, pattern>, MUBUFe <op> {
2189   let lds  = 0;
2190 }
2191
2192 } // End let isCodeGenOnly = 0
2193
2194 class MUBUF_vi <bits<7> op, dag outs, dag ins, string asm, list<dag> pattern> :
2195   MUBUF <outs, ins, asm, pattern>, MUBUFe_vi <op> {
2196   let lds = 0;
2197 }
2198
2199 class MUBUFAddr64Table <bit is_addr64, string suffix = ""> {
2200   bit IsAddr64 = is_addr64;
2201   string OpName = NAME # suffix;
2202 }
2203
2204 class MUBUF_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
2205   MUBUF <outs, ins, "", pattern>,
2206   SIMCInstr<opName, SISubtarget.NONE> {
2207   let isPseudo = 1;
2208   let isCodeGenOnly = 1;
2209
2210   // dummy fields, so that we can use let statements around multiclasses
2211   bits<1> offen;
2212   bits<1> idxen;
2213   bits<8> vaddr;
2214   bits<1> glc;
2215   bits<1> slc;
2216   bits<1> tfe;
2217   bits<8> soffset;
2218 }
2219
2220 class MUBUF_Real_si <mubuf op, string opName, dag outs, dag ins,
2221                      string asm> :
2222   MUBUF <outs, ins, asm, []>,
2223   MUBUFe <op.SI>,
2224   SIMCInstr<opName, SISubtarget.SI> {
2225   let lds = 0;
2226 }
2227
2228 class MUBUF_Real_vi <mubuf op, string opName, dag outs, dag ins,
2229                      string asm> :
2230   MUBUF <outs, ins, asm, []>,
2231   MUBUFe_vi <op.VI>,
2232   SIMCInstr<opName, SISubtarget.VI> {
2233   let lds = 0;
2234 }
2235
2236 multiclass MUBUF_m <mubuf op, string opName, dag outs, dag ins, string asm,
2237                     list<dag> pattern> {
2238
2239   def "" : MUBUF_Pseudo <opName, outs, ins, pattern>,
2240            MUBUFAddr64Table <0>;
2241
2242   let addr64 = 0, isCodeGenOnly = 0 in {
2243     def _si : MUBUF_Real_si <op, opName, outs, ins, asm>;
2244   }
2245
2246   def _vi : MUBUF_Real_vi <op, opName, outs, ins, asm>;
2247 }
2248
2249 multiclass MUBUFAddr64_m <mubuf op, string opName, dag outs,
2250                           dag ins, string asm, list<dag> pattern> {
2251
2252   def "" : MUBUF_Pseudo <opName, outs, ins, pattern>,
2253            MUBUFAddr64Table <1>;
2254
2255   let addr64 = 1, isCodeGenOnly = 0 in {
2256     def _si : MUBUF_Real_si <op, opName, outs, ins, asm>;
2257   }
2258
2259   // There is no VI version. If the pseudo is selected, it should be lowered
2260   // for VI appropriately.
2261 }
2262
2263 multiclass MUBUFAtomicOffset_m <mubuf op, string opName, dag outs, dag ins,
2264                                 string asm, list<dag> pattern, bit is_return> {
2265
2266   def "" : MUBUF_Pseudo <opName, outs, ins, pattern>,
2267            MUBUFAddr64Table <0, !if(is_return, "_RTN", "")>,
2268            AtomicNoRet<NAME#"_OFFSET", is_return>;
2269
2270   let offen = 0, idxen = 0, tfe = 0, vaddr = 0 in {
2271     let addr64 = 0 in {
2272       def _si : MUBUF_Real_si <op, opName, outs, ins, asm>;
2273     }
2274
2275     def _vi : MUBUF_Real_vi <op, opName, outs, ins, asm>;
2276   }
2277 }
2278
2279 multiclass MUBUFAtomicAddr64_m <mubuf op, string opName, dag outs, dag ins,
2280                                 string asm, list<dag> pattern, bit is_return> {
2281
2282   def "" : MUBUF_Pseudo <opName, outs, ins, pattern>,
2283            MUBUFAddr64Table <1, !if(is_return, "_RTN", "")>,
2284            AtomicNoRet<NAME#"_ADDR64", is_return>;
2285
2286   let offen = 0, idxen = 0, addr64 = 1, tfe = 0 in {
2287     def _si : MUBUF_Real_si <op, opName, outs, ins, asm>;
2288   }
2289
2290   // There is no VI version. If the pseudo is selected, it should be lowered
2291   // for VI appropriately.
2292 }
2293
2294 multiclass MUBUF_Atomic <mubuf op, string name, RegisterClass rc,
2295                          ValueType vt, SDPatternOperator atomic> {
2296
2297   let mayStore = 1, mayLoad = 1, hasPostISelHook = 1 in {
2298
2299     // No return variants
2300     let glc = 0 in {
2301
2302       defm _ADDR64 : MUBUFAtomicAddr64_m <
2303         op, name#"_addr64", (outs),
2304         (ins rc:$vdata, SReg_128:$srsrc, VReg_64:$vaddr,
2305              SCSrc_32:$soffset, mbuf_offset:$offset, slc:$slc),
2306         name#" $vdata, $vaddr, $srsrc, $soffset addr64"#"$offset"#"$slc", [], 0
2307       >;
2308
2309       defm _OFFSET : MUBUFAtomicOffset_m <
2310         op, name#"_offset", (outs),
2311         (ins rc:$vdata, SReg_128:$srsrc, SCSrc_32:$soffset, mbuf_offset:$offset,
2312              slc:$slc),
2313         name#" $vdata, $srsrc, $soffset"#"$offset"#"$slc", [], 0
2314       >;
2315     } // glc = 0
2316
2317     // Variant that return values
2318     let glc = 1, Constraints = "$vdata = $vdata_in",
2319         DisableEncoding = "$vdata_in"  in {
2320
2321       defm _RTN_ADDR64 : MUBUFAtomicAddr64_m <
2322         op, name#"_rtn_addr64", (outs rc:$vdata),
2323         (ins rc:$vdata_in, SReg_128:$srsrc, VReg_64:$vaddr,
2324              SCSrc_32:$soffset, mbuf_offset:$offset, slc:$slc),
2325         name#" $vdata, $vaddr, $srsrc, $soffset addr64"#"$offset"#" glc"#"$slc",
2326         [(set vt:$vdata,
2327          (atomic (MUBUFAddr64Atomic v4i32:$srsrc, i64:$vaddr, i32:$soffset,
2328                                     i16:$offset, i1:$slc), vt:$vdata_in))], 1
2329       >;
2330
2331       defm _RTN_OFFSET : MUBUFAtomicOffset_m <
2332         op, name#"_rtn_offset", (outs rc:$vdata),
2333         (ins rc:$vdata_in, SReg_128:$srsrc, SCSrc_32:$soffset,
2334              mbuf_offset:$offset, slc:$slc),
2335         name#" $vdata, $srsrc, $soffset"#"$offset"#" glc $slc",
2336         [(set vt:$vdata,
2337          (atomic (MUBUFOffsetAtomic v4i32:$srsrc, i32:$soffset, i16:$offset,
2338                                     i1:$slc), vt:$vdata_in))], 1
2339       >;
2340
2341     } // glc = 1
2342
2343   } // mayStore = 1, mayLoad = 1, hasPostISelHook = 1
2344 }
2345
2346 multiclass MUBUF_Load_Helper <mubuf op, string name, RegisterClass regClass,
2347                               ValueType load_vt = i32,
2348                               SDPatternOperator ld = null_frag> {
2349
2350   let mayLoad = 1, mayStore = 0 in {
2351     let offen = 0, idxen = 0, vaddr = 0 in {
2352       defm _OFFSET : MUBUF_m <op, name#"_offset", (outs regClass:$vdata),
2353                            (ins SReg_128:$srsrc, SCSrc_32:$soffset,
2354                            mbuf_offset:$offset, glc:$glc, slc:$slc, tfe:$tfe),
2355                            name#" $vdata, $srsrc, $soffset"#"$offset"#"$glc"#"$slc"#"$tfe",
2356                            [(set load_vt:$vdata, (ld (MUBUFOffset v4i32:$srsrc,
2357                                                      i32:$soffset, i16:$offset,
2358                                                      i1:$glc, i1:$slc, i1:$tfe)))]>;
2359     }
2360
2361     let offen = 1, idxen = 0  in {
2362       defm _OFFEN  : MUBUF_m <op, name#"_offen", (outs regClass:$vdata),
2363                            (ins VGPR_32:$vaddr, SReg_128:$srsrc,
2364                            SCSrc_32:$soffset, mbuf_offset:$offset, glc:$glc, slc:$slc,
2365                            tfe:$tfe),
2366                            name#" $vdata, $vaddr, $srsrc, $soffset offen"#"$offset"#"$glc"#"$slc"#"$tfe", []>;
2367     }
2368
2369     let offen = 0, idxen = 1 in {
2370       defm _IDXEN  : MUBUF_m <op, name#"_idxen", (outs regClass:$vdata),
2371                            (ins VGPR_32:$vaddr, SReg_128:$srsrc,
2372                            SCSrc_32:$soffset, mbuf_offset:$offset, glc:$glc,
2373                            slc:$slc, tfe:$tfe),
2374                            name#" $vdata, $vaddr, $srsrc, $soffset idxen"#"$offset"#"$glc"#"$slc"#"$tfe", []>;
2375     }
2376
2377     let offen = 1, idxen = 1 in {
2378       defm _BOTHEN : MUBUF_m <op, name#"_bothen", (outs regClass:$vdata),
2379                            (ins VReg_64:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset,
2380                            mbuf_offset:$offset, glc:$glc, slc:$slc, tfe:$tfe),
2381                            name#" $vdata, $vaddr, $srsrc, $soffset idxen offen"#"$offset"#"$glc"#"$slc"#"$tfe", []>;
2382     }
2383
2384     let offen = 0, idxen = 0 in {
2385       defm _ADDR64 : MUBUFAddr64_m <op, name#"_addr64", (outs regClass:$vdata),
2386                            (ins VReg_64:$vaddr, SReg_128:$srsrc,
2387                                 SCSrc_32:$soffset, mbuf_offset:$offset,
2388                                 glc:$glc, slc:$slc, tfe:$tfe),
2389                            name#" $vdata, $vaddr, $srsrc, $soffset addr64"#"$offset"#
2390                                 "$glc"#"$slc"#"$tfe",
2391                            [(set load_vt:$vdata, (ld (MUBUFAddr64 v4i32:$srsrc,
2392                                                   i64:$vaddr, i32:$soffset,
2393                                                   i16:$offset, i1:$glc, i1:$slc,
2394                                                   i1:$tfe)))]>;
2395     }
2396   }
2397 }
2398
2399 multiclass MUBUF_Store_Helper <mubuf op, string name, RegisterClass vdataClass,
2400                           ValueType store_vt = i32, SDPatternOperator st = null_frag> {
2401   let mayLoad = 0, mayStore = 1 in {
2402     defm : MUBUF_m <op, name, (outs),
2403                     (ins vdataClass:$vdata, VGPR_32:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset,
2404                     mbuf_offset:$offset, offen:$offen, idxen:$idxen, glc:$glc, slc:$slc,
2405                     tfe:$tfe),
2406                     name#" $vdata, $vaddr, $srsrc, $soffset"#"$offen"#"$idxen"#"$offset"#
2407                          "$glc"#"$slc"#"$tfe", []>;
2408
2409     let offen = 0, idxen = 0, vaddr = 0 in {
2410       defm _OFFSET : MUBUF_m <op, name#"_offset",(outs),
2411                               (ins vdataClass:$vdata, SReg_128:$srsrc, SCSrc_32:$soffset,
2412                               mbuf_offset:$offset, glc:$glc, slc:$slc, tfe:$tfe),
2413                               name#" $vdata, $srsrc, $soffset"#"$offset"#"$glc"#"$slc"#"$tfe",
2414                               [(st store_vt:$vdata, (MUBUFOffset v4i32:$srsrc, i32:$soffset,
2415                                    i16:$offset, i1:$glc, i1:$slc, i1:$tfe))]>;
2416     } // offen = 0, idxen = 0, vaddr = 0
2417
2418     let offen = 1, idxen = 0  in {
2419       defm _OFFEN : MUBUF_m <op, name#"_offen", (outs),
2420                              (ins vdataClass:$vdata, VGPR_32:$vaddr, SReg_128:$srsrc,
2421                               SCSrc_32:$soffset, mbuf_offset:$offset, glc:$glc,
2422                               slc:$slc, tfe:$tfe),
2423                              name#" $vdata, $vaddr, $srsrc, $soffset offen"#"$offset"#
2424                              "$glc"#"$slc"#"$tfe", []>;
2425     } // end offen = 1, idxen = 0
2426
2427     let offen = 0, idxen = 1 in {
2428       defm _IDXEN  : MUBUF_m <op, name#"_idxen", (outs),
2429                            (ins vdataClass:$vdata, VGPR_32:$vaddr, SReg_128:$srsrc,
2430                            SCSrc_32:$soffset, mbuf_offset:$offset, glc:$glc,
2431                            slc:$slc, tfe:$tfe),
2432                            name#" $vdata, $vaddr, $srsrc, $soffset idxen"#"$offset"#"$glc"#"$slc"#"$tfe", []>;
2433     }
2434
2435     let offen = 1, idxen = 1 in {
2436       defm _BOTHEN : MUBUF_m <op, name#"_bothen", (outs),
2437                            (ins vdataClass:$vdata, VReg_64:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset,
2438                            mbuf_offset:$offset, glc:$glc, slc:$slc, tfe:$tfe),
2439                            name#" $vdata, $vaddr, $srsrc, $soffset idxen offen"#"$offset"#"$glc"#"$slc"#"$tfe", []>;
2440     }
2441
2442     let offen = 0, idxen = 0 in {
2443       defm _ADDR64 : MUBUFAddr64_m <op, name#"_addr64", (outs),
2444                                     (ins vdataClass:$vdata, VReg_64:$vaddr, SReg_128:$srsrc,
2445                                          SCSrc_32:$soffset,
2446                                          mbuf_offset:$offset, glc:$glc, slc:$slc,
2447                                          tfe:$tfe),
2448                                     name#" $vdata, $vaddr, $srsrc, $soffset addr64"#
2449                                          "$offset"#"$glc"#"$slc"#"$tfe",
2450                                     [(st store_vt:$vdata,
2451                                       (MUBUFAddr64 v4i32:$srsrc, i64:$vaddr,
2452                                                    i32:$soffset, i16:$offset,
2453                                                    i1:$glc, i1:$slc, i1:$tfe))]>;
2454     }
2455   } // End mayLoad = 0, mayStore = 1
2456 }
2457
2458 class FLAT_Load_Helper <bits<7> op, string asm, RegisterClass regClass> :
2459       FLAT <op, (outs regClass:$vdst),
2460                 (ins VReg_64:$addr, glc_flat:$glc, slc_flat:$slc, tfe_flat:$tfe),
2461             asm#" $vdst, $addr"#"$glc"#"$slc"#"$tfe", []> {
2462   let data = 0;
2463   let mayLoad = 1;
2464 }
2465
2466 class FLAT_Store_Helper <bits<7> op, string name, RegisterClass vdataClass> :
2467       FLAT <op, (outs), (ins vdataClass:$data, VReg_64:$addr,
2468                              glc_flat:$glc, slc_flat:$slc, tfe_flat:$tfe),
2469           name#" $data, $addr"#"$glc"#"$slc"#"$tfe",
2470          []> {
2471
2472   let mayLoad = 0;
2473   let mayStore = 1;
2474
2475   // Encoding
2476   let vdst = 0;
2477 }
2478
2479 multiclass FLAT_ATOMIC <bits<7> op, string name, RegisterClass vdst_rc,
2480                         RegisterClass data_rc = vdst_rc> {
2481
2482   let mayLoad = 1, mayStore = 1 in {
2483     def "" : FLAT <op, (outs),
2484                   (ins VReg_64:$addr, data_rc:$data, slc_flat_atomic:$slc,
2485                        tfe_flat_atomic:$tfe),
2486                    name#" $addr, $data"#"$slc"#"$tfe", []>,
2487              AtomicNoRet <NAME, 0> {
2488       let glc = 0;
2489       let vdst = 0;
2490     }
2491
2492     def _RTN : FLAT <op, (outs vdst_rc:$vdst),
2493                      (ins VReg_64:$addr, data_rc:$data, slc_flat_atomic:$slc,
2494                           tfe_flat_atomic:$tfe),
2495                      name#" $vdst, $addr, $data glc"#"$slc"#"$tfe", []>,
2496                AtomicNoRet <NAME, 1> {
2497       let glc = 1;
2498     }
2499   }
2500 }
2501
2502 class MIMG_Mask <string op, int channels> {
2503   string Op = op;
2504   int Channels = channels;
2505 }
2506
2507 class MIMG_NoSampler_Helper <bits<7> op, string asm,
2508                              RegisterClass dst_rc,
2509                              RegisterClass src_rc> : MIMG <
2510   op,
2511   (outs dst_rc:$vdata),
2512   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
2513        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
2514        SReg_256:$srsrc),
2515   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
2516      #" $tfe, $lwe, $slc, $vaddr, $srsrc",
2517   []> {
2518   let ssamp = 0;
2519   let mayLoad = 1;
2520   let mayStore = 0;
2521   let hasPostISelHook = 1;
2522 }
2523
2524 multiclass MIMG_NoSampler_Src_Helper <bits<7> op, string asm,
2525                                       RegisterClass dst_rc,
2526                                       int channels> {
2527   def _V1 : MIMG_NoSampler_Helper <op, asm, dst_rc, VGPR_32>,
2528             MIMG_Mask<asm#"_V1", channels>;
2529   def _V2 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_64>,
2530             MIMG_Mask<asm#"_V2", channels>;
2531   def _V4 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_128>,
2532             MIMG_Mask<asm#"_V4", channels>;
2533 }
2534
2535 multiclass MIMG_NoSampler <bits<7> op, string asm> {
2536   defm _V1 : MIMG_NoSampler_Src_Helper <op, asm, VGPR_32, 1>;
2537   defm _V2 : MIMG_NoSampler_Src_Helper <op, asm, VReg_64, 2>;
2538   defm _V3 : MIMG_NoSampler_Src_Helper <op, asm, VReg_96, 3>;
2539   defm _V4 : MIMG_NoSampler_Src_Helper <op, asm, VReg_128, 4>;
2540 }
2541
2542 class MIMG_Sampler_Helper <bits<7> op, string asm,
2543                            RegisterClass dst_rc,
2544                            RegisterClass src_rc, int wqm> : MIMG <
2545   op,
2546   (outs dst_rc:$vdata),
2547   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
2548        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
2549        SReg_256:$srsrc, SReg_128:$ssamp),
2550   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
2551      #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
2552   []> {
2553   let mayLoad = 1;
2554   let mayStore = 0;
2555   let hasPostISelHook = 1;
2556   let WQM = wqm;
2557 }
2558
2559 multiclass MIMG_Sampler_Src_Helper <bits<7> op, string asm,
2560                                     RegisterClass dst_rc,
2561                                     int channels, int wqm> {
2562   def _V1 : MIMG_Sampler_Helper <op, asm, dst_rc, VGPR_32, wqm>,
2563             MIMG_Mask<asm#"_V1", channels>;
2564   def _V2 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_64, wqm>,
2565             MIMG_Mask<asm#"_V2", channels>;
2566   def _V4 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_128, wqm>,
2567             MIMG_Mask<asm#"_V4", channels>;
2568   def _V8 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_256, wqm>,
2569             MIMG_Mask<asm#"_V8", channels>;
2570   def _V16 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_512, wqm>,
2571             MIMG_Mask<asm#"_V16", channels>;
2572 }
2573
2574 multiclass MIMG_Sampler <bits<7> op, string asm> {
2575   defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VGPR_32, 1, 0>;
2576   defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2, 0>;
2577   defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3, 0>;
2578   defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4, 0>;
2579 }
2580
2581 multiclass MIMG_Sampler_WQM <bits<7> op, string asm> {
2582   defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VGPR_32, 1, 1>;
2583   defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2, 1>;
2584   defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3, 1>;
2585   defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4, 1>;
2586 }
2587
2588 class MIMG_Gather_Helper <bits<7> op, string asm,
2589                           RegisterClass dst_rc,
2590                           RegisterClass src_rc, int wqm> : MIMG <
2591   op,
2592   (outs dst_rc:$vdata),
2593   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
2594        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
2595        SReg_256:$srsrc, SReg_128:$ssamp),
2596   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
2597      #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
2598   []> {
2599   let mayLoad = 1;
2600   let mayStore = 0;
2601
2602   // DMASK was repurposed for GATHER4. 4 components are always
2603   // returned and DMASK works like a swizzle - it selects
2604   // the component to fetch. The only useful DMASK values are
2605   // 1=red, 2=green, 4=blue, 8=alpha. (e.g. 1 returns
2606   // (red,red,red,red) etc.) The ISA document doesn't mention
2607   // this.
2608   // Therefore, disable all code which updates DMASK by setting these two:
2609   let MIMG = 0;
2610   let hasPostISelHook = 0;
2611   let WQM = wqm;
2612 }
2613
2614 multiclass MIMG_Gather_Src_Helper <bits<7> op, string asm,
2615                                     RegisterClass dst_rc,
2616                                     int channels, int wqm> {
2617   def _V1 : MIMG_Gather_Helper <op, asm, dst_rc, VGPR_32, wqm>,
2618             MIMG_Mask<asm#"_V1", channels>;
2619   def _V2 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_64, wqm>,
2620             MIMG_Mask<asm#"_V2", channels>;
2621   def _V4 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_128, wqm>,
2622             MIMG_Mask<asm#"_V4", channels>;
2623   def _V8 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_256, wqm>,
2624             MIMG_Mask<asm#"_V8", channels>;
2625   def _V16 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_512, wqm>,
2626             MIMG_Mask<asm#"_V16", channels>;
2627 }
2628
2629 multiclass MIMG_Gather <bits<7> op, string asm> {
2630   defm _V1 : MIMG_Gather_Src_Helper<op, asm, VGPR_32, 1, 0>;
2631   defm _V2 : MIMG_Gather_Src_Helper<op, asm, VReg_64, 2, 0>;
2632   defm _V3 : MIMG_Gather_Src_Helper<op, asm, VReg_96, 3, 0>;
2633   defm _V4 : MIMG_Gather_Src_Helper<op, asm, VReg_128, 4, 0>;
2634 }
2635
2636 multiclass MIMG_Gather_WQM <bits<7> op, string asm> {
2637   defm _V1 : MIMG_Gather_Src_Helper<op, asm, VGPR_32, 1, 1>;
2638   defm _V2 : MIMG_Gather_Src_Helper<op, asm, VReg_64, 2, 1>;
2639   defm _V3 : MIMG_Gather_Src_Helper<op, asm, VReg_96, 3, 1>;
2640   defm _V4 : MIMG_Gather_Src_Helper<op, asm, VReg_128, 4, 1>;
2641 }
2642
2643 //===----------------------------------------------------------------------===//
2644 // Vector instruction mappings
2645 //===----------------------------------------------------------------------===//
2646
2647 // Maps an opcode in e32 form to its e64 equivalent
2648 def getVOPe64 : InstrMapping {
2649   let FilterClass = "VOP";
2650   let RowFields = ["OpName"];
2651   let ColFields = ["Size"];
2652   let KeyCol = ["4"];
2653   let ValueCols = [["8"]];
2654 }
2655
2656 // Maps an opcode in e64 form to its e32 equivalent
2657 def getVOPe32 : InstrMapping {
2658   let FilterClass = "VOP";
2659   let RowFields = ["OpName"];
2660   let ColFields = ["Size"];
2661   let KeyCol = ["8"];
2662   let ValueCols = [["4"]];
2663 }
2664
2665 def getMaskedMIMGOp : InstrMapping {
2666   let FilterClass = "MIMG_Mask";
2667   let RowFields = ["Op"];
2668   let ColFields = ["Channels"];
2669   let KeyCol = ["4"];
2670   let ValueCols = [["1"], ["2"], ["3"] ];
2671 }
2672
2673 // Maps an commuted opcode to its original version
2674 def getCommuteOrig : InstrMapping {
2675   let FilterClass = "VOP2_REV";
2676   let RowFields = ["RevOp"];
2677   let ColFields = ["IsOrig"];
2678   let KeyCol = ["0"];
2679   let ValueCols = [["1"]];
2680 }
2681
2682 // Maps an original opcode to its commuted version
2683 def getCommuteRev : InstrMapping {
2684   let FilterClass = "VOP2_REV";
2685   let RowFields = ["RevOp"];
2686   let ColFields = ["IsOrig"];
2687   let KeyCol = ["1"];
2688   let ValueCols = [["0"]];
2689 }
2690
2691 def getCommuteCmpOrig : InstrMapping {
2692   let FilterClass = "VOP2_REV";
2693   let RowFields = ["RevOp"];
2694   let ColFields = ["IsOrig"];
2695   let KeyCol = ["0"];
2696   let ValueCols = [["1"]];
2697 }
2698
2699 // Maps an original opcode to its commuted version
2700 def getCommuteCmpRev : InstrMapping {
2701   let FilterClass = "VOP2_REV";
2702   let RowFields = ["RevOp"];
2703   let ColFields = ["IsOrig"];
2704   let KeyCol = ["1"];
2705   let ValueCols = [["0"]];
2706 }
2707
2708
2709 def getMCOpcodeGen : InstrMapping {
2710   let FilterClass = "SIMCInstr";
2711   let RowFields = ["PseudoInstr"];
2712   let ColFields = ["Subtarget"];
2713   let KeyCol = [!cast<string>(SISubtarget.NONE)];
2714   let ValueCols = [[!cast<string>(SISubtarget.SI)],[!cast<string>(SISubtarget.VI)]];
2715 }
2716
2717 def getAddr64Inst : InstrMapping {
2718   let FilterClass = "MUBUFAddr64Table";
2719   let RowFields = ["OpName"];
2720   let ColFields = ["IsAddr64"];
2721   let KeyCol = ["0"];
2722   let ValueCols = [["1"]];
2723 }
2724
2725 // Maps an atomic opcode to its version with a return value.
2726 def getAtomicRetOp : InstrMapping {
2727   let FilterClass = "AtomicNoRet";
2728   let RowFields = ["NoRetOp"];
2729   let ColFields = ["IsRet"];
2730   let KeyCol = ["0"];
2731   let ValueCols = [["1"]];
2732 }
2733
2734 // Maps an atomic opcode to its returnless version.
2735 def getAtomicNoRetOp : InstrMapping {
2736   let FilterClass = "AtomicNoRet";
2737   let RowFields = ["NoRetOp"];
2738   let ColFields = ["IsRet"];
2739   let KeyCol = ["1"];
2740   let ValueCols = [["0"]];
2741 }
2742
2743 include "SIInstructions.td"
2744 include "CIInstructions.td"
2745 include "VIInstructions.td"