AMDGPU/SI: Fix input vcc operand for VOP2b instructions
[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, bit UseFullOp = 0> {
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, bit UseFullOp = 0> {
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 useSGPRInput = 0,
1452                         bit UseFullOp = 0> {
1453   def "" : VOP3_Pseudo <outs, ins, pattern, opName>;
1454
1455   def _si : VOP3b_Real_si <op.SI3, outs, ins, asm, opName>,
1456             VOP3DisableFields<1, useSGPRInput, HasMods>;
1457
1458   def _vi : VOP3b_Real_vi <op.VI3, outs, ins, asm, opName>,
1459             VOP3DisableFields<1, useSGPRInput, HasMods>;
1460 }
1461
1462 multiclass VOP3_C_m <vop op, dag outs, dag ins, string asm,
1463                      list<dag> pattern, string opName,
1464                      bit HasMods, bit defExec, string revOp> {
1465
1466   def "" : VOP3_Pseudo <outs, ins, pattern, opName>,
1467            VOP2_REV<revOp#"_e64", !eq(revOp, opName)>;
1468
1469   def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>,
1470             VOP3DisableFields<1, 0, HasMods> {
1471     let Defs = !if(defExec, [EXEC], []);
1472   }
1473
1474   def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName>,
1475             VOP3DisableFields<1, 0, HasMods> {
1476     let Defs = !if(defExec, [EXEC], []);
1477   }
1478 }
1479
1480 // An instruction that is VOP2 on SI and VOP3 on VI, no modifiers.
1481 multiclass VOP2SI_3VI_m <vop3 op, string opName, dag outs, dag ins,
1482                          string asm, list<dag> pattern = []> {
1483   let isPseudo = 1, isCodeGenOnly = 1 in {
1484     def "" : VOPAnyCommon <outs, ins, "", pattern>,
1485              SIMCInstr<opName, SISubtarget.NONE>;
1486   }
1487
1488   def _si : VOP2 <op.SI3{5-0}, outs, ins, asm, []>,
1489             SIMCInstr <opName, SISubtarget.SI> {
1490             let AssemblerPredicates = [isSICI];
1491   }
1492
1493   def _vi : VOP3Common <outs, ins, asm, []>,
1494             VOP3e_vi <op.VI3>,
1495             VOP3DisableFields <1, 0, 0>,
1496             SIMCInstr <opName, SISubtarget.VI> {
1497             let AssemblerPredicates = [isVI];
1498   }
1499 }
1500
1501 multiclass VOP1_Helper <vop1 op, string opName, dag outs,
1502                         dag ins32, string asm32, list<dag> pat32,
1503                         dag ins64, string asm64, list<dag> pat64,
1504                         bit HasMods> {
1505
1506   defm _e32 : VOP1_m <op, outs, ins32, opName#asm32, pat32, opName>;
1507
1508   defm _e64 : VOP3_1_m <op, outs, ins64, opName#asm64, pat64, opName, HasMods>;
1509 }
1510
1511 multiclass VOP1Inst <vop1 op, string opName, VOPProfile P,
1512                      SDPatternOperator node = null_frag> : VOP1_Helper <
1513   op, opName, P.Outs,
1514   P.Ins32, P.Asm32, [],
1515   P.Ins64, P.Asm64,
1516   !if(P.HasModifiers,
1517       [(set P.DstVT:$dst, (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0,
1518                                 i32:$src0_modifiers, i1:$clamp, i32:$omod))))],
1519       [(set P.DstVT:$dst, (node P.Src0VT:$src0))]),
1520   P.HasModifiers
1521 >;
1522
1523 multiclass VOP1InstSI <vop1 op, string opName, VOPProfile P,
1524                        SDPatternOperator node = null_frag> {
1525
1526   defm _e32 : VOP1SI_m <op, P.Outs, P.Ins32, opName#P.Asm32, [], opName>;
1527
1528   defm _e64 : VOP3SI_1_m <op, P.Outs, P.Ins64, opName#P.Asm64,
1529     !if(P.HasModifiers,
1530       [(set P.DstVT:$dst, (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0,
1531                                 i32:$src0_modifiers, i1:$clamp, i32:$omod))))],
1532       [(set P.DstVT:$dst, (node P.Src0VT:$src0))]),
1533     opName, P.HasModifiers>;
1534 }
1535
1536 multiclass VOP2_Helper <vop2 op, string opName, dag outs,
1537                         dag ins32, string asm32, list<dag> pat32,
1538                         dag ins64, string asm64, list<dag> pat64,
1539                         string revOp, bit HasMods> {
1540   defm _e32 : VOP2_m <op, outs, ins32, asm32, pat32, opName, revOp>;
1541
1542   defm _e64 : VOP3_2_m <op,
1543     outs, ins64, opName#asm64, pat64, opName, revOp, HasMods
1544   >;
1545 }
1546
1547 multiclass VOP2Inst <vop2 op, string opName, VOPProfile P,
1548                      SDPatternOperator node = null_frag,
1549                      string revOp = opName> : VOP2_Helper <
1550   op, opName, P.Outs,
1551   P.Ins32, P.Asm32, [],
1552   P.Ins64, P.Asm64,
1553   !if(P.HasModifiers,
1554       [(set P.DstVT:$dst,
1555            (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1556                                       i1:$clamp, i32:$omod)),
1557                  (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
1558       [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1))]),
1559   revOp, P.HasModifiers
1560 >;
1561
1562 multiclass VOP2InstSI <vop2 op, string opName, VOPProfile P,
1563                        SDPatternOperator node = null_frag,
1564                        string revOp = opName> {
1565   defm _e32 : VOP2SI_m <op, P.Outs, P.Ins32, P.Asm32, [], opName, revOp>;
1566
1567   defm _e64 : VOP3SI_2_m <op, P.Outs, P.Ins64, opName#P.Asm64,
1568     !if(P.HasModifiers,
1569         [(set P.DstVT:$dst,
1570              (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1571                                         i1:$clamp, i32:$omod)),
1572                    (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
1573         [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1))]),
1574     opName, revOp, P.HasModifiers>;
1575 }
1576
1577 multiclass VOP2b_Helper <vop2 op, string opName, dag outs32, dag outs64,
1578                          dag ins32, string asm32, list<dag> pat32,
1579                          dag ins64, string asm64, list<dag> pat64,
1580                          string revOp, bit HasMods, bit useSGPRInput> {
1581
1582   let Uses = !if(useSGPRInput, [VCC, EXEC], [EXEC]), Defs = [VCC] in {
1583     defm _e32 : VOP2_m <op, outs32, ins32, asm32, pat32, opName, revOp>;
1584   }
1585
1586   defm _e64 : VOP3b_2_3_m <op,
1587     outs64, ins64, opName#asm64, pat64, opName, revOp, HasMods, useSGPRInput
1588   >;
1589 }
1590
1591 multiclass VOP2bInst <vop2 op, string opName, VOPProfile P,
1592                       SDPatternOperator node = null_frag,
1593                       string revOp = opName> : VOP2b_Helper <
1594   op, opName, P.Outs32, P.Outs64,
1595   P.Ins32, P.Asm32, [],
1596   P.Ins64, P.Asm64,
1597   !if(P.HasModifiers,
1598       [(set P.DstVT:$dst,
1599            (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1600                                       i1:$clamp, i32:$omod)),
1601                  (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
1602       [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1))]),
1603   revOp, P.HasModifiers, !eq(P.NumSrcArgs, 3)
1604 >;
1605
1606 // A VOP2 instruction that is VOP3-only on VI.
1607 multiclass VOP2_VI3_Helper <vop23 op, string opName, dag outs,
1608                             dag ins32, string asm32, list<dag> pat32,
1609                             dag ins64, string asm64, list<dag> pat64,
1610                             string revOp, bit HasMods> {
1611   defm _e32 : VOP2SI_m <op, outs, ins32, asm32, pat32, opName, revOp>;
1612
1613   defm _e64 : VOP3_2_m <op, outs, ins64, opName#asm64, pat64, opName,
1614                         revOp, HasMods>;
1615 }
1616
1617 multiclass VOP2_VI3_Inst <vop23 op, string opName, VOPProfile P,
1618                           SDPatternOperator node = null_frag,
1619                           string revOp = opName>
1620                           : VOP2_VI3_Helper <
1621   op, opName, P.Outs,
1622   P.Ins32, P.Asm32, [],
1623   P.Ins64, P.Asm64,
1624   !if(P.HasModifiers,
1625       [(set P.DstVT:$dst,
1626            (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1627                                       i1:$clamp, i32:$omod)),
1628                  (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
1629       [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1))]),
1630   revOp, P.HasModifiers
1631 >;
1632
1633 multiclass VOP2MADK <vop2 op, string opName, list<dag> pattern = []> {
1634
1635   def "" : VOP2_Pseudo <VOP_MADK.Outs, VOP_MADK.Ins, pattern, opName>;
1636
1637 let isCodeGenOnly = 0 in {
1638   def _si : VOP2Common <VOP_MADK.Outs, VOP_MADK.Ins,
1639                         !strconcat(opName, VOP_MADK.Asm), []>,
1640             SIMCInstr <opName#"_e32", SISubtarget.SI>,
1641             VOP2_MADKe <op.SI> {
1642             let AssemblerPredicates = [isSICI];
1643             }
1644
1645   def _vi : VOP2Common <VOP_MADK.Outs, VOP_MADK.Ins,
1646                         !strconcat(opName, VOP_MADK.Asm), []>,
1647             SIMCInstr <opName#"_e32", SISubtarget.VI>,
1648             VOP2_MADKe <op.VI> {
1649             let AssemblerPredicates = [isVI];
1650             }
1651 } // End isCodeGenOnly = 0
1652 }
1653
1654 class VOPC_Pseudo <dag ins, list<dag> pattern, string opName> :
1655   VOPCCommon <ins, "", pattern>,
1656   VOP <opName>,
1657   SIMCInstr<opName#"_e32", SISubtarget.NONE> {
1658   let isPseudo = 1;
1659   let isCodeGenOnly = 1;
1660 }
1661
1662 multiclass VOPC_m <vopc op, dag ins, string op_asm, list<dag> pattern,
1663                    string opName, bit DefExec, VOPProfile p,
1664                    string revOpName = "", string asm = opName#"_e32 "#op_asm,
1665                    string alias_asm = opName#" "#op_asm> {
1666   def "" : VOPC_Pseudo <ins, pattern, opName>;
1667
1668   let AssemblerPredicates = [isSICI] in {
1669
1670   def _si : VOPC<op.SI, ins, asm, []>,
1671             SIMCInstr <opName#"_e32", SISubtarget.SI> {
1672     let Defs = !if(DefExec, [VCC, EXEC], [VCC]);
1673     let hasSideEffects = DefExec;
1674   }
1675
1676   def : SIInstAlias <
1677     alias_asm,
1678     (!cast<Instruction>(NAME#"_e32_si") p.Src0RC32:$src0, p.Src1RC32:$src1)
1679   >;
1680
1681   } // End AssemblerPredicates = [isSICI]
1682
1683
1684   let AssemblerPredicates = [isVI] in {
1685
1686   def _vi : VOPC<op.VI, ins, asm, []>,
1687             SIMCInstr <opName#"_e32", SISubtarget.VI> {
1688     let Defs = !if(DefExec, [VCC, EXEC], [VCC]);
1689     let hasSideEffects = DefExec;
1690   }
1691
1692   def : SIInstAlias <
1693     alias_asm,
1694     (!cast<Instruction>(NAME#"_e32_vi") p.Src0RC32:$src0, p.Src1RC32:$src1)
1695   >;
1696
1697   } // End AssemblerPredicates = [isVI]
1698 }
1699
1700 multiclass VOPC_Helper <vopc op, string opName,
1701                         dag ins32, string asm32, list<dag> pat32,
1702                         dag out64, dag ins64, string asm64, list<dag> pat64,
1703                         bit HasMods, bit DefExec, string revOp,
1704                         VOPProfile p> {
1705   defm _e32 : VOPC_m <op, ins32, asm32, pat32, opName, DefExec, p>;
1706
1707   defm _e64 : VOP3_C_m <op, out64, ins64, opName#asm64, pat64,
1708                         opName, HasMods, DefExec, revOp>;
1709 }
1710
1711 // Special case for class instructions which only have modifiers on
1712 // the 1st source operand.
1713 multiclass VOPC_Class_Helper <vopc op, string opName,
1714                              dag ins32, string asm32, list<dag> pat32,
1715                              dag out64, dag ins64, string asm64, list<dag> pat64,
1716                              bit HasMods, bit DefExec, string revOp,
1717                              VOPProfile p> {
1718   defm _e32 : VOPC_m <op, ins32, asm32, pat32, opName, DefExec, p>;
1719
1720   defm _e64 : VOP3_C_m <op, out64, ins64, opName#asm64, pat64,
1721                         opName, HasMods, DefExec, revOp>,
1722                         VOP3DisableModFields<1, 0, 0>;
1723 }
1724
1725 multiclass VOPCInst <vopc op, string opName,
1726                      VOPProfile P, PatLeaf cond = COND_NULL,
1727                      string revOp = opName,
1728                      bit DefExec = 0> : VOPC_Helper <
1729   op, opName,
1730   P.Ins32, P.Asm32, [],
1731   (outs VOPDstS64:$dst), P.Ins64, P.Asm64,
1732   !if(P.HasModifiers,
1733       [(set i1:$dst,
1734           (setcc (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1735                                       i1:$clamp, i32:$omod)),
1736                  (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)),
1737                  cond))],
1738       [(set i1:$dst, (setcc P.Src0VT:$src0, P.Src1VT:$src1, cond))]),
1739   P.HasModifiers, DefExec, revOp, P
1740 >;
1741
1742 multiclass VOPCClassInst <vopc op, string opName, VOPProfile P,
1743                      bit DefExec = 0> : VOPC_Class_Helper <
1744   op, opName,
1745   P.Ins32, P.Asm32, [],
1746   (outs VOPDstS64:$dst), P.Ins64, P.Asm64,
1747   !if(P.HasModifiers,
1748       [(set i1:$dst,
1749           (AMDGPUfp_class (P.Src0VT (VOP3Mods0Clamp0OMod P.Src0VT:$src0, i32:$src0_modifiers)), P.Src1VT:$src1))],
1750       [(set i1:$dst, (AMDGPUfp_class P.Src0VT:$src0, P.Src1VT:$src1))]),
1751   P.HasModifiers, DefExec, opName, P
1752 >;
1753
1754
1755 multiclass VOPC_F32 <vopc op, string opName, PatLeaf cond = COND_NULL, string revOp = opName> :
1756   VOPCInst <op, opName, VOPC_I1_F32_F32, cond, revOp>;
1757
1758 multiclass VOPC_F64 <vopc op, string opName, PatLeaf cond = COND_NULL, string revOp = opName> :
1759   VOPCInst <op, opName, VOPC_I1_F64_F64, cond, revOp>;
1760
1761 multiclass VOPC_I32 <vopc op, string opName, PatLeaf cond = COND_NULL, string revOp = opName> :
1762   VOPCInst <op, opName, VOPC_I1_I32_I32, cond, revOp>;
1763
1764 multiclass VOPC_I64 <vopc op, string opName, PatLeaf cond = COND_NULL, string revOp = opName> :
1765   VOPCInst <op, opName, VOPC_I1_I64_I64, cond, revOp>;
1766
1767
1768 multiclass VOPCX <vopc op, string opName, VOPProfile P,
1769                   PatLeaf cond = COND_NULL,
1770                   string revOp = "">
1771   : VOPCInst <op, opName, P, cond, revOp, 1>;
1772
1773 multiclass VOPCX_F32 <vopc op, string opName, string revOp = opName> :
1774   VOPCX <op, opName, VOPC_I1_F32_F32, COND_NULL, revOp>;
1775
1776 multiclass VOPCX_F64 <vopc op, string opName, string revOp = opName> :
1777   VOPCX <op, opName, VOPC_I1_F64_F64, COND_NULL, revOp>;
1778
1779 multiclass VOPCX_I32 <vopc op, string opName, string revOp = opName> :
1780   VOPCX <op, opName, VOPC_I1_I32_I32, COND_NULL, revOp>;
1781
1782 multiclass VOPCX_I64 <vopc op, string opName, string revOp = opName> :
1783   VOPCX <op, opName, VOPC_I1_I64_I64, COND_NULL, revOp>;
1784
1785 multiclass VOP3_Helper <vop3 op, string opName, dag outs, dag ins, string asm,
1786                         list<dag> pat, int NumSrcArgs, bit HasMods> : VOP3_m <
1787     op, outs, ins, opName#" "#asm, pat, opName, NumSrcArgs, HasMods
1788 >;
1789
1790 multiclass VOPC_CLASS_F32 <vopc op, string opName> :
1791   VOPCClassInst <op, opName, VOPC_I1_F32_I32, 0>;
1792
1793 multiclass VOPCX_CLASS_F32 <vopc op, string opName> :
1794   VOPCClassInst <op, opName, VOPC_I1_F32_I32, 1>;
1795
1796 multiclass VOPC_CLASS_F64 <vopc op, string opName> :
1797   VOPCClassInst <op, opName, VOPC_I1_F64_I32, 0>;
1798
1799 multiclass VOPCX_CLASS_F64 <vopc op, string opName> :
1800   VOPCClassInst <op, opName, VOPC_I1_F64_I32, 1>;
1801
1802 multiclass VOP3Inst <vop3 op, string opName, VOPProfile P,
1803                      SDPatternOperator node = null_frag> : VOP3_Helper <
1804   op, opName, (outs P.DstRC.RegClass:$dst), P.Ins64, P.Asm64,
1805   !if(!eq(P.NumSrcArgs, 3),
1806     !if(P.HasModifiers,
1807         [(set P.DstVT:$dst,
1808             (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1809                                        i1:$clamp, i32:$omod)),
1810                   (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)),
1811                   (P.Src2VT (VOP3Mods P.Src2VT:$src2, i32:$src2_modifiers))))],
1812         [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1,
1813                                   P.Src2VT:$src2))]),
1814   !if(!eq(P.NumSrcArgs, 2),
1815     !if(P.HasModifiers,
1816         [(set P.DstVT:$dst,
1817             (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1818                                        i1:$clamp, i32:$omod)),
1819                   (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
1820         [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1))])
1821   /* P.NumSrcArgs == 1 */,
1822     !if(P.HasModifiers,
1823         [(set P.DstVT:$dst,
1824             (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1825                                        i1:$clamp, i32:$omod))))],
1826         [(set P.DstVT:$dst, (node P.Src0VT:$src0))]))),
1827   P.NumSrcArgs, P.HasModifiers
1828 >;
1829
1830 // Special case for v_div_fmas_{f32|f64}, since it seems to be the
1831 // only VOP instruction that implicitly reads VCC.
1832 multiclass VOP3_VCC_Inst <vop3 op, string opName,
1833                           VOPProfile P,
1834                           SDPatternOperator node = null_frag> : VOP3_Helper <
1835   op, opName,
1836   (outs P.DstRC.RegClass:$dst),
1837   (ins InputModsNoDefault:$src0_modifiers, P.Src0RC64:$src0,
1838        InputModsNoDefault:$src1_modifiers, P.Src1RC64:$src1,
1839        InputModsNoDefault:$src2_modifiers, P.Src2RC64:$src2,
1840        ClampMod:$clamp,
1841        omod:$omod),
1842   "$dst, $src0_modifiers, $src1_modifiers, $src2_modifiers"#"$clamp"#"$omod",
1843   [(set P.DstVT:$dst,
1844             (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1845                                        i1:$clamp, i32:$omod)),
1846                   (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)),
1847                   (P.Src2VT (VOP3Mods P.Src2VT:$src2, i32:$src2_modifiers)),
1848                   (i1 VCC)))],
1849   3, 1
1850 >;
1851
1852 multiclass VOP3b_Helper <vop op, RegisterClass vrc, RegisterOperand arc,
1853                     string opName, list<dag> pattern> :
1854   VOP3b_2_3_m <
1855   op, (outs vrc:$vdst, SReg_64:$sdst),
1856       (ins InputModsNoDefault:$src0_modifiers, arc:$src0,
1857            InputModsNoDefault:$src1_modifiers, arc:$src1,
1858            InputModsNoDefault:$src2_modifiers, arc:$src2,
1859            ClampMod:$clamp, omod:$omod),
1860   opName#" $vdst, $sdst, $src0_modifiers, $src1_modifiers, $src2_modifiers"#"$clamp"#"$omod", pattern,
1861   opName, opName, 1, 0, 1
1862 >;
1863
1864 multiclass VOP3b_64 <vop3 op, string opName, list<dag> pattern> :
1865   VOP3b_Helper <op, VReg_64, VSrc_64, opName, pattern>;
1866
1867 multiclass VOP3b_32 <vop3 op, string opName, list<dag> pattern> :
1868   VOP3b_Helper <op, VGPR_32, VSrc_32, opName, pattern>;
1869
1870
1871 class Vop3ModPat<Instruction Inst, VOPProfile P, SDPatternOperator node> : Pat<
1872   (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i1:$clamp, i32:$omod)),
1873         (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)),
1874         (P.Src2VT (VOP3Mods P.Src2VT:$src2, i32:$src2_modifiers))),
1875   (Inst i32:$src0_modifiers, P.Src0VT:$src0,
1876         i32:$src1_modifiers, P.Src1VT:$src1,
1877         i32:$src2_modifiers, P.Src2VT:$src2,
1878         i1:$clamp,
1879         i32:$omod)>;
1880
1881 //===----------------------------------------------------------------------===//
1882 // Interpolation opcodes
1883 //===----------------------------------------------------------------------===//
1884
1885 class VINTRP_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
1886   VINTRPCommon <outs, ins, "", pattern>,
1887   SIMCInstr<opName, SISubtarget.NONE> {
1888   let isPseudo = 1;
1889   let isCodeGenOnly = 1;
1890 }
1891
1892 class VINTRP_Real_si <bits <2> op, string opName, dag outs, dag ins,
1893                       string asm> :
1894   VINTRPCommon <outs, ins, asm, []>,
1895   VINTRPe <op>,
1896   SIMCInstr<opName, SISubtarget.SI>;
1897
1898 class VINTRP_Real_vi <bits <2> op, string opName, dag outs, dag ins,
1899                       string asm> :
1900   VINTRPCommon <outs, ins, asm, []>,
1901   VINTRPe_vi <op>,
1902   SIMCInstr<opName, SISubtarget.VI>;
1903
1904 multiclass VINTRP_m <bits <2> op, dag outs, dag ins, string asm,
1905                      list<dag> pattern = []> {
1906   def "" : VINTRP_Pseudo <NAME, outs, ins, pattern>;
1907
1908   def _si : VINTRP_Real_si <op, NAME, outs, ins, asm>;
1909
1910   def _vi : VINTRP_Real_vi <op, NAME, outs, ins, asm>;
1911 }
1912
1913 //===----------------------------------------------------------------------===//
1914 // Vector I/O classes
1915 //===----------------------------------------------------------------------===//
1916
1917 class DS_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
1918   DS <outs, ins, "", pattern>,
1919   SIMCInstr <opName, SISubtarget.NONE> {
1920   let isPseudo = 1;
1921   let isCodeGenOnly = 1;
1922 }
1923
1924 class DS_Real_si <bits<8> op, string opName, dag outs, dag ins, string asm> :
1925   DS <outs, ins, asm, []>,
1926   DSe <op>,
1927   SIMCInstr <opName, SISubtarget.SI> {
1928   let isCodeGenOnly = 0;
1929 }
1930
1931 class DS_Real_vi <bits<8> op, string opName, dag outs, dag ins, string asm> :
1932   DS <outs, ins, asm, []>,
1933   DSe_vi <op>,
1934   SIMCInstr <opName, SISubtarget.VI>;
1935
1936 class DS_Off16_Real_si <bits<8> op, string opName, dag outs, dag ins, string asm> :
1937   DS_Real_si <op,opName, outs, ins, asm> {
1938
1939   // Single load interpret the 2 i8imm operands as a single i16 offset.
1940   bits<16> offset;
1941   let offset0 = offset{7-0};
1942   let offset1 = offset{15-8};
1943   let isCodeGenOnly = 0;
1944 }
1945
1946 class DS_Off16_Real_vi <bits<8> op, string opName, dag outs, dag ins, string asm> :
1947   DS_Real_vi <op, opName, outs, ins, asm> {
1948
1949   // Single load interpret the 2 i8imm operands as a single i16 offset.
1950   bits<16> offset;
1951   let offset0 = offset{7-0};
1952   let offset1 = offset{15-8};
1953 }
1954
1955 multiclass DS_1A_RET <bits<8> op, string opName, RegisterClass rc,
1956   dag outs = (outs rc:$vdst),
1957   dag ins = (ins VGPR_32:$addr, ds_offset:$offset, gds:$gds),
1958   string asm = opName#" $vdst, $addr"#"$offset$gds"> {
1959
1960   def "" : DS_Pseudo <opName, outs, ins, []>;
1961
1962   let data0 = 0, data1 = 0 in {
1963     def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
1964     def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
1965   }
1966 }
1967
1968 multiclass DS_1A_Off8_RET <bits<8> op, string opName, RegisterClass rc,
1969   dag outs = (outs rc:$vdst),
1970   dag ins = (ins VGPR_32:$addr, ds_offset0:$offset0, ds_offset1:$offset1,
1971                  gds01:$gds),
1972   string asm = opName#" $vdst, $addr"#"$offset0"#"$offset1$gds"> {
1973
1974   def "" : DS_Pseudo <opName, outs, ins, []>;
1975
1976   let data0 = 0, data1 = 0, AsmMatchConverter = "cvtDSOffset01" in {
1977     def _si : DS_Real_si <op, opName, outs, ins, asm>;
1978     def _vi : DS_Real_vi <op, opName, outs, ins, asm>;
1979   }
1980 }
1981
1982 multiclass DS_1A1D_NORET <bits<8> op, string opName, RegisterClass rc,
1983   dag outs = (outs),
1984   dag ins = (ins VGPR_32:$addr, rc:$data0, ds_offset:$offset, gds:$gds),
1985   string asm = opName#" $addr, $data0"#"$offset$gds"> {
1986
1987   def "" : DS_Pseudo <opName, outs, ins, []>,
1988            AtomicNoRet<opName, 0>;
1989
1990   let data1 = 0, vdst = 0 in {
1991     def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
1992     def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
1993   }
1994 }
1995
1996 multiclass DS_1A1D_Off8_NORET <bits<8> op, string opName, RegisterClass rc,
1997   dag outs = (outs),
1998   dag ins = (ins VGPR_32:$addr, rc:$data0, rc:$data1,
1999               ds_offset0:$offset0, ds_offset1:$offset1, gds01:$gds),
2000   string asm = opName#" $addr, $data0, $data1"#"$offset0"#"$offset1"#"$gds"> {
2001
2002   def "" : DS_Pseudo <opName, outs, ins, []>;
2003
2004   let vdst = 0, AsmMatchConverter = "cvtDSOffset01" in {
2005     def _si : DS_Real_si <op, opName, outs, ins, asm>;
2006     def _vi : DS_Real_vi <op, opName, outs, ins, asm>;
2007   }
2008 }
2009
2010 multiclass DS_1A1D_RET <bits<8> op, string opName, RegisterClass rc,
2011                         string noRetOp = "",
2012   dag outs = (outs rc:$vdst),
2013   dag ins = (ins VGPR_32:$addr, rc:$data0, ds_offset:$offset, gds:$gds),
2014   string asm = opName#" $vdst, $addr, $data0"#"$offset$gds"> {
2015
2016   def "" : DS_Pseudo <opName, outs, ins, []>,
2017            AtomicNoRet<noRetOp, 1>;
2018
2019   let data1 = 0 in {
2020     def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
2021     def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
2022   }
2023 }
2024
2025 multiclass DS_1A2D_RET_m <bits<8> op, string opName, RegisterClass rc,
2026                           string noRetOp = "", dag ins,
2027   dag outs = (outs rc:$vdst),
2028   string asm = opName#" $vdst, $addr, $data0, $data1"#"$offset"#"$gds"> {
2029
2030   def "" : DS_Pseudo <opName, outs, ins, []>,
2031            AtomicNoRet<noRetOp, 1>;
2032
2033   def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
2034   def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
2035 }
2036
2037 multiclass DS_1A2D_RET <bits<8> op, string asm, RegisterClass rc,
2038                         string noRetOp = "", RegisterClass src = rc> :
2039   DS_1A2D_RET_m <op, asm, rc, noRetOp,
2040                  (ins VGPR_32:$addr, src:$data0, src:$data1,
2041                       ds_offset:$offset, gds:$gds)
2042 >;
2043
2044 multiclass DS_1A2D_NORET <bits<8> op, string opName, RegisterClass rc,
2045                           string noRetOp = opName,
2046   dag outs = (outs),
2047   dag ins = (ins VGPR_32:$addr, rc:$data0, rc:$data1,
2048                  ds_offset:$offset, gds:$gds),
2049   string asm = opName#" $addr, $data0, $data1"#"$offset"#"$gds"> {
2050
2051   def "" : DS_Pseudo <opName, outs, ins, []>,
2052            AtomicNoRet<noRetOp, 0>;
2053
2054   let vdst = 0 in {
2055     def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
2056     def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
2057   }
2058 }
2059
2060 multiclass DS_0A_RET <bits<8> op, string opName,
2061   dag outs = (outs VGPR_32:$vdst),
2062   dag ins = (ins ds_offset:$offset, gds:$gds),
2063   string asm = opName#" $vdst"#"$offset"#"$gds"> {
2064
2065   let mayLoad = 1, mayStore = 1 in {
2066     def "" : DS_Pseudo <opName, outs, ins, []>;
2067
2068     let addr = 0, data0 = 0, data1 = 0 in {
2069       def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
2070       def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
2071     } // end addr = 0, data0 = 0, data1 = 0
2072   } // end mayLoad = 1, mayStore = 1
2073 }
2074
2075 multiclass DS_1A_RET_GDS <bits<8> op, string opName,
2076   dag outs = (outs VGPR_32:$vdst),
2077   dag ins = (ins VGPR_32:$addr, ds_offset_gds:$offset),
2078   string asm = opName#" $vdst, $addr"#"$offset gds"> {
2079
2080   def "" : DS_Pseudo <opName, outs, ins, []>;
2081
2082   let data0 = 0, data1 = 0, gds = 1 in {
2083     def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
2084     def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
2085   } // end data0 = 0, data1 = 0, gds = 1
2086 }
2087
2088 multiclass DS_1A_GDS <bits<8> op, string opName,
2089   dag outs = (outs),
2090   dag ins = (ins VGPR_32:$addr),
2091   string asm = opName#" $addr gds"> {
2092
2093   def "" : DS_Pseudo <opName, outs, ins, []>;
2094
2095   let vdst = 0, data0 = 0, data1 = 0, offset0 = 0, offset1 = 0, gds = 1 in {
2096     def _si : DS_Real_si <op, opName, outs, ins, asm>;
2097     def _vi : DS_Real_vi <op, opName, outs, ins, asm>;
2098   } // end vdst = 0, data = 0, data1 = 0, gds = 1
2099 }
2100
2101 multiclass DS_1A <bits<8> op, string opName,
2102   dag outs = (outs),
2103   dag ins = (ins VGPR_32:$addr, ds_offset:$offset, gds:$gds),
2104   string asm = opName#" $addr"#"$offset"#"$gds"> {
2105
2106   let mayLoad = 1, mayStore = 1 in {
2107     def "" : DS_Pseudo <opName, outs, ins, []>;
2108
2109     let vdst = 0, data0 = 0, data1 = 0 in {
2110       def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
2111       def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
2112     } // let vdst = 0, data0 = 0, data1 = 0
2113   } // end mayLoad = 1, mayStore = 1
2114 }
2115
2116 //===----------------------------------------------------------------------===//
2117 // MTBUF classes
2118 //===----------------------------------------------------------------------===//
2119
2120 class MTBUF_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
2121   MTBUF <outs, ins, "", pattern>,
2122   SIMCInstr<opName, SISubtarget.NONE> {
2123   let isPseudo = 1;
2124   let isCodeGenOnly = 1;
2125 }
2126
2127 class MTBUF_Real_si <bits<3> op, string opName, dag outs, dag ins,
2128                     string asm> :
2129   MTBUF <outs, ins, asm, []>,
2130   MTBUFe <op>,
2131   SIMCInstr<opName, SISubtarget.SI>;
2132
2133 class MTBUF_Real_vi <bits<4> op, string opName, dag outs, dag ins, string asm> :
2134   MTBUF <outs, ins, asm, []>,
2135   MTBUFe_vi <op>,
2136   SIMCInstr <opName, SISubtarget.VI>;
2137
2138 multiclass MTBUF_m <bits<3> op, string opName, dag outs, dag ins, string asm,
2139                     list<dag> pattern> {
2140
2141   def "" : MTBUF_Pseudo <opName, outs, ins, pattern>;
2142
2143   def _si : MTBUF_Real_si <op, opName, outs, ins, asm>;
2144
2145   def _vi : MTBUF_Real_vi <{0, op{2}, op{1}, op{0}}, opName, outs, ins, asm>;
2146
2147 }
2148
2149 let mayStore = 1, mayLoad = 0 in {
2150
2151 multiclass MTBUF_Store_Helper <bits<3> op, string opName,
2152                                RegisterClass regClass> : MTBUF_m <
2153   op, opName, (outs),
2154   (ins regClass:$vdata, u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
2155    i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VGPR_32:$vaddr,
2156    SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SCSrc_32:$soffset),
2157   opName#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
2158         #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset", []
2159 >;
2160
2161 } // mayStore = 1, mayLoad = 0
2162
2163 let mayLoad = 1, mayStore = 0 in {
2164
2165 multiclass MTBUF_Load_Helper <bits<3> op, string opName,
2166                               RegisterClass regClass> : MTBUF_m <
2167   op, opName, (outs regClass:$dst),
2168   (ins u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
2169        i8imm:$dfmt, i8imm:$nfmt, VGPR_32:$vaddr, SReg_128:$srsrc,
2170        i1imm:$slc, i1imm:$tfe, SCSrc_32:$soffset),
2171   opName#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
2172         #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset", []
2173 >;
2174
2175 } // mayLoad = 1, mayStore = 0
2176
2177 //===----------------------------------------------------------------------===//
2178 // MUBUF classes
2179 //===----------------------------------------------------------------------===//
2180
2181 class mubuf <bits<7> si, bits<7> vi = si> {
2182   field bits<7> SI = si;
2183   field bits<7> VI = vi;
2184 }
2185
2186 let isCodeGenOnly = 0 in {
2187
2188 class MUBUF_si <bits<7> op, dag outs, dag ins, string asm, list<dag> pattern> :
2189   MUBUF <outs, ins, asm, pattern>, MUBUFe <op> {
2190   let lds  = 0;
2191 }
2192
2193 } // End let isCodeGenOnly = 0
2194
2195 class MUBUF_vi <bits<7> op, dag outs, dag ins, string asm, list<dag> pattern> :
2196   MUBUF <outs, ins, asm, pattern>, MUBUFe_vi <op> {
2197   let lds = 0;
2198 }
2199
2200 class MUBUFAddr64Table <bit is_addr64, string suffix = ""> {
2201   bit IsAddr64 = is_addr64;
2202   string OpName = NAME # suffix;
2203 }
2204
2205 class MUBUF_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
2206   MUBUF <outs, ins, "", pattern>,
2207   SIMCInstr<opName, SISubtarget.NONE> {
2208   let isPseudo = 1;
2209   let isCodeGenOnly = 1;
2210
2211   // dummy fields, so that we can use let statements around multiclasses
2212   bits<1> offen;
2213   bits<1> idxen;
2214   bits<8> vaddr;
2215   bits<1> glc;
2216   bits<1> slc;
2217   bits<1> tfe;
2218   bits<8> soffset;
2219 }
2220
2221 class MUBUF_Real_si <mubuf op, string opName, dag outs, dag ins,
2222                      string asm> :
2223   MUBUF <outs, ins, asm, []>,
2224   MUBUFe <op.SI>,
2225   SIMCInstr<opName, SISubtarget.SI> {
2226   let lds = 0;
2227 }
2228
2229 class MUBUF_Real_vi <mubuf op, string opName, dag outs, dag ins,
2230                      string asm> :
2231   MUBUF <outs, ins, asm, []>,
2232   MUBUFe_vi <op.VI>,
2233   SIMCInstr<opName, SISubtarget.VI> {
2234   let lds = 0;
2235 }
2236
2237 multiclass MUBUF_m <mubuf op, string opName, dag outs, dag ins, string asm,
2238                     list<dag> pattern> {
2239
2240   def "" : MUBUF_Pseudo <opName, outs, ins, pattern>,
2241            MUBUFAddr64Table <0>;
2242
2243   let addr64 = 0, isCodeGenOnly = 0 in {
2244     def _si : MUBUF_Real_si <op, opName, outs, ins, asm>;
2245   }
2246
2247   def _vi : MUBUF_Real_vi <op, opName, outs, ins, asm>;
2248 }
2249
2250 multiclass MUBUFAddr64_m <mubuf op, string opName, dag outs,
2251                           dag ins, string asm, list<dag> pattern> {
2252
2253   def "" : MUBUF_Pseudo <opName, outs, ins, pattern>,
2254            MUBUFAddr64Table <1>;
2255
2256   let addr64 = 1, isCodeGenOnly = 0 in {
2257     def _si : MUBUF_Real_si <op, opName, outs, ins, asm>;
2258   }
2259
2260   // There is no VI version. If the pseudo is selected, it should be lowered
2261   // for VI appropriately.
2262 }
2263
2264 multiclass MUBUFAtomicOffset_m <mubuf op, string opName, dag outs, dag ins,
2265                                 string asm, list<dag> pattern, bit is_return> {
2266
2267   def "" : MUBUF_Pseudo <opName, outs, ins, pattern>,
2268            MUBUFAddr64Table <0, !if(is_return, "_RTN", "")>,
2269            AtomicNoRet<NAME#"_OFFSET", is_return>;
2270
2271   let offen = 0, idxen = 0, tfe = 0, vaddr = 0 in {
2272     let addr64 = 0 in {
2273       def _si : MUBUF_Real_si <op, opName, outs, ins, asm>;
2274     }
2275
2276     def _vi : MUBUF_Real_vi <op, opName, outs, ins, asm>;
2277   }
2278 }
2279
2280 multiclass MUBUFAtomicAddr64_m <mubuf op, string opName, dag outs, dag ins,
2281                                 string asm, list<dag> pattern, bit is_return> {
2282
2283   def "" : MUBUF_Pseudo <opName, outs, ins, pattern>,
2284            MUBUFAddr64Table <1, !if(is_return, "_RTN", "")>,
2285            AtomicNoRet<NAME#"_ADDR64", is_return>;
2286
2287   let offen = 0, idxen = 0, addr64 = 1, tfe = 0 in {
2288     def _si : MUBUF_Real_si <op, opName, outs, ins, asm>;
2289   }
2290
2291   // There is no VI version. If the pseudo is selected, it should be lowered
2292   // for VI appropriately.
2293 }
2294
2295 multiclass MUBUF_Atomic <mubuf op, string name, RegisterClass rc,
2296                          ValueType vt, SDPatternOperator atomic> {
2297
2298   let mayStore = 1, mayLoad = 1, hasPostISelHook = 1 in {
2299
2300     // No return variants
2301     let glc = 0 in {
2302
2303       defm _ADDR64 : MUBUFAtomicAddr64_m <
2304         op, name#"_addr64", (outs),
2305         (ins rc:$vdata, SReg_128:$srsrc, VReg_64:$vaddr,
2306              SCSrc_32:$soffset, mbuf_offset:$offset, slc:$slc),
2307         name#" $vdata, $vaddr, $srsrc, $soffset addr64"#"$offset"#"$slc", [], 0
2308       >;
2309
2310       defm _OFFSET : MUBUFAtomicOffset_m <
2311         op, name#"_offset", (outs),
2312         (ins rc:$vdata, SReg_128:$srsrc, SCSrc_32:$soffset, mbuf_offset:$offset,
2313              slc:$slc),
2314         name#" $vdata, $srsrc, $soffset"#"$offset"#"$slc", [], 0
2315       >;
2316     } // glc = 0
2317
2318     // Variant that return values
2319     let glc = 1, Constraints = "$vdata = $vdata_in",
2320         DisableEncoding = "$vdata_in"  in {
2321
2322       defm _RTN_ADDR64 : MUBUFAtomicAddr64_m <
2323         op, name#"_rtn_addr64", (outs rc:$vdata),
2324         (ins rc:$vdata_in, SReg_128:$srsrc, VReg_64:$vaddr,
2325              SCSrc_32:$soffset, mbuf_offset:$offset, slc:$slc),
2326         name#" $vdata, $vaddr, $srsrc, $soffset addr64"#"$offset"#" glc"#"$slc",
2327         [(set vt:$vdata,
2328          (atomic (MUBUFAddr64Atomic v4i32:$srsrc, i64:$vaddr, i32:$soffset,
2329                                     i16:$offset, i1:$slc), vt:$vdata_in))], 1
2330       >;
2331
2332       defm _RTN_OFFSET : MUBUFAtomicOffset_m <
2333         op, name#"_rtn_offset", (outs rc:$vdata),
2334         (ins rc:$vdata_in, SReg_128:$srsrc, SCSrc_32:$soffset,
2335              mbuf_offset:$offset, slc:$slc),
2336         name#" $vdata, $srsrc, $soffset"#"$offset"#" glc $slc",
2337         [(set vt:$vdata,
2338          (atomic (MUBUFOffsetAtomic v4i32:$srsrc, i32:$soffset, i16:$offset,
2339                                     i1:$slc), vt:$vdata_in))], 1
2340       >;
2341
2342     } // glc = 1
2343
2344   } // mayStore = 1, mayLoad = 1, hasPostISelHook = 1
2345 }
2346
2347 multiclass MUBUF_Load_Helper <mubuf op, string name, RegisterClass regClass,
2348                               ValueType load_vt = i32,
2349                               SDPatternOperator ld = null_frag> {
2350
2351   let mayLoad = 1, mayStore = 0 in {
2352     let offen = 0, idxen = 0, vaddr = 0 in {
2353       defm _OFFSET : MUBUF_m <op, name#"_offset", (outs regClass:$vdata),
2354                            (ins SReg_128:$srsrc, SCSrc_32:$soffset,
2355                            mbuf_offset:$offset, glc:$glc, slc:$slc, tfe:$tfe),
2356                            name#" $vdata, $srsrc, $soffset"#"$offset"#"$glc"#"$slc"#"$tfe",
2357                            [(set load_vt:$vdata, (ld (MUBUFOffset v4i32:$srsrc,
2358                                                      i32:$soffset, i16:$offset,
2359                                                      i1:$glc, i1:$slc, i1:$tfe)))]>;
2360     }
2361
2362     let offen = 1, idxen = 0  in {
2363       defm _OFFEN  : MUBUF_m <op, name#"_offen", (outs regClass:$vdata),
2364                            (ins VGPR_32:$vaddr, SReg_128:$srsrc,
2365                            SCSrc_32:$soffset, mbuf_offset:$offset, glc:$glc, slc:$slc,
2366                            tfe:$tfe),
2367                            name#" $vdata, $vaddr, $srsrc, $soffset offen"#"$offset"#"$glc"#"$slc"#"$tfe", []>;
2368     }
2369
2370     let offen = 0, idxen = 1 in {
2371       defm _IDXEN  : MUBUF_m <op, name#"_idxen", (outs regClass:$vdata),
2372                            (ins VGPR_32:$vaddr, SReg_128:$srsrc,
2373                            SCSrc_32:$soffset, mbuf_offset:$offset, glc:$glc,
2374                            slc:$slc, tfe:$tfe),
2375                            name#" $vdata, $vaddr, $srsrc, $soffset idxen"#"$offset"#"$glc"#"$slc"#"$tfe", []>;
2376     }
2377
2378     let offen = 1, idxen = 1 in {
2379       defm _BOTHEN : MUBUF_m <op, name#"_bothen", (outs regClass:$vdata),
2380                            (ins VReg_64:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset,
2381                            mbuf_offset:$offset, glc:$glc, slc:$slc, tfe:$tfe),
2382                            name#" $vdata, $vaddr, $srsrc, $soffset idxen offen"#"$offset"#"$glc"#"$slc"#"$tfe", []>;
2383     }
2384
2385     let offen = 0, idxen = 0 in {
2386       defm _ADDR64 : MUBUFAddr64_m <op, name#"_addr64", (outs regClass:$vdata),
2387                            (ins VReg_64:$vaddr, SReg_128:$srsrc,
2388                                 SCSrc_32:$soffset, mbuf_offset:$offset,
2389                                 glc:$glc, slc:$slc, tfe:$tfe),
2390                            name#" $vdata, $vaddr, $srsrc, $soffset addr64"#"$offset"#
2391                                 "$glc"#"$slc"#"$tfe",
2392                            [(set load_vt:$vdata, (ld (MUBUFAddr64 v4i32:$srsrc,
2393                                                   i64:$vaddr, i32:$soffset,
2394                                                   i16:$offset, i1:$glc, i1:$slc,
2395                                                   i1:$tfe)))]>;
2396     }
2397   }
2398 }
2399
2400 multiclass MUBUF_Store_Helper <mubuf op, string name, RegisterClass vdataClass,
2401                           ValueType store_vt = i32, SDPatternOperator st = null_frag> {
2402   let mayLoad = 0, mayStore = 1 in {
2403     defm : MUBUF_m <op, name, (outs),
2404                     (ins vdataClass:$vdata, VGPR_32:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset,
2405                     mbuf_offset:$offset, offen:$offen, idxen:$idxen, glc:$glc, slc:$slc,
2406                     tfe:$tfe),
2407                     name#" $vdata, $vaddr, $srsrc, $soffset"#"$offen"#"$idxen"#"$offset"#
2408                          "$glc"#"$slc"#"$tfe", []>;
2409
2410     let offen = 0, idxen = 0, vaddr = 0 in {
2411       defm _OFFSET : MUBUF_m <op, name#"_offset",(outs),
2412                               (ins vdataClass:$vdata, SReg_128:$srsrc, SCSrc_32:$soffset,
2413                               mbuf_offset:$offset, glc:$glc, slc:$slc, tfe:$tfe),
2414                               name#" $vdata, $srsrc, $soffset"#"$offset"#"$glc"#"$slc"#"$tfe",
2415                               [(st store_vt:$vdata, (MUBUFOffset v4i32:$srsrc, i32:$soffset,
2416                                    i16:$offset, i1:$glc, i1:$slc, i1:$tfe))]>;
2417     } // offen = 0, idxen = 0, vaddr = 0
2418
2419     let offen = 1, idxen = 0  in {
2420       defm _OFFEN : MUBUF_m <op, name#"_offen", (outs),
2421                              (ins vdataClass:$vdata, VGPR_32:$vaddr, SReg_128:$srsrc,
2422                               SCSrc_32:$soffset, mbuf_offset:$offset, glc:$glc,
2423                               slc:$slc, tfe:$tfe),
2424                              name#" $vdata, $vaddr, $srsrc, $soffset offen"#"$offset"#
2425                              "$glc"#"$slc"#"$tfe", []>;
2426     } // end offen = 1, idxen = 0
2427
2428     let offen = 0, idxen = 1 in {
2429       defm _IDXEN  : MUBUF_m <op, name#"_idxen", (outs),
2430                            (ins vdataClass:$vdata, VGPR_32:$vaddr, SReg_128:$srsrc,
2431                            SCSrc_32:$soffset, mbuf_offset:$offset, glc:$glc,
2432                            slc:$slc, tfe:$tfe),
2433                            name#" $vdata, $vaddr, $srsrc, $soffset idxen"#"$offset"#"$glc"#"$slc"#"$tfe", []>;
2434     }
2435
2436     let offen = 1, idxen = 1 in {
2437       defm _BOTHEN : MUBUF_m <op, name#"_bothen", (outs),
2438                            (ins vdataClass:$vdata, VReg_64:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset,
2439                            mbuf_offset:$offset, glc:$glc, slc:$slc, tfe:$tfe),
2440                            name#" $vdata, $vaddr, $srsrc, $soffset idxen offen"#"$offset"#"$glc"#"$slc"#"$tfe", []>;
2441     }
2442
2443     let offen = 0, idxen = 0 in {
2444       defm _ADDR64 : MUBUFAddr64_m <op, name#"_addr64", (outs),
2445                                     (ins vdataClass:$vdata, VReg_64:$vaddr, SReg_128:$srsrc,
2446                                          SCSrc_32:$soffset,
2447                                          mbuf_offset:$offset, glc:$glc, slc:$slc,
2448                                          tfe:$tfe),
2449                                     name#" $vdata, $vaddr, $srsrc, $soffset addr64"#
2450                                          "$offset"#"$glc"#"$slc"#"$tfe",
2451                                     [(st store_vt:$vdata,
2452                                       (MUBUFAddr64 v4i32:$srsrc, i64:$vaddr,
2453                                                    i32:$soffset, i16:$offset,
2454                                                    i1:$glc, i1:$slc, i1:$tfe))]>;
2455     }
2456   } // End mayLoad = 0, mayStore = 1
2457 }
2458
2459 class FLAT_Load_Helper <bits<7> op, string asm, RegisterClass regClass> :
2460       FLAT <op, (outs regClass:$vdst),
2461                 (ins VReg_64:$addr, glc_flat:$glc, slc_flat:$slc, tfe_flat:$tfe),
2462             asm#" $vdst, $addr"#"$glc"#"$slc"#"$tfe", []> {
2463   let data = 0;
2464   let mayLoad = 1;
2465 }
2466
2467 class FLAT_Store_Helper <bits<7> op, string name, RegisterClass vdataClass> :
2468       FLAT <op, (outs), (ins vdataClass:$data, VReg_64:$addr,
2469                              glc_flat:$glc, slc_flat:$slc, tfe_flat:$tfe),
2470           name#" $data, $addr"#"$glc"#"$slc"#"$tfe",
2471          []> {
2472
2473   let mayLoad = 0;
2474   let mayStore = 1;
2475
2476   // Encoding
2477   let vdst = 0;
2478 }
2479
2480 multiclass FLAT_ATOMIC <bits<7> op, string name, RegisterClass vdst_rc,
2481                         RegisterClass data_rc = vdst_rc> {
2482
2483   let mayLoad = 1, mayStore = 1 in {
2484     def "" : FLAT <op, (outs),
2485                   (ins VReg_64:$addr, data_rc:$data, slc_flat_atomic:$slc,
2486                        tfe_flat_atomic:$tfe),
2487                    name#" $addr, $data"#"$slc"#"$tfe", []>,
2488              AtomicNoRet <NAME, 0> {
2489       let glc = 0;
2490       let vdst = 0;
2491     }
2492
2493     def _RTN : FLAT <op, (outs vdst_rc:$vdst),
2494                      (ins VReg_64:$addr, data_rc:$data, slc_flat_atomic:$slc,
2495                           tfe_flat_atomic:$tfe),
2496                      name#" $vdst, $addr, $data glc"#"$slc"#"$tfe", []>,
2497                AtomicNoRet <NAME, 1> {
2498       let glc = 1;
2499     }
2500   }
2501 }
2502
2503 class MIMG_Mask <string op, int channels> {
2504   string Op = op;
2505   int Channels = channels;
2506 }
2507
2508 class MIMG_NoSampler_Helper <bits<7> op, string asm,
2509                              RegisterClass dst_rc,
2510                              RegisterClass src_rc> : MIMG <
2511   op,
2512   (outs dst_rc:$vdata),
2513   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
2514        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
2515        SReg_256:$srsrc),
2516   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
2517      #" $tfe, $lwe, $slc, $vaddr, $srsrc",
2518   []> {
2519   let ssamp = 0;
2520   let mayLoad = 1;
2521   let mayStore = 0;
2522   let hasPostISelHook = 1;
2523 }
2524
2525 multiclass MIMG_NoSampler_Src_Helper <bits<7> op, string asm,
2526                                       RegisterClass dst_rc,
2527                                       int channels> {
2528   def _V1 : MIMG_NoSampler_Helper <op, asm, dst_rc, VGPR_32>,
2529             MIMG_Mask<asm#"_V1", channels>;
2530   def _V2 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_64>,
2531             MIMG_Mask<asm#"_V2", channels>;
2532   def _V4 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_128>,
2533             MIMG_Mask<asm#"_V4", channels>;
2534 }
2535
2536 multiclass MIMG_NoSampler <bits<7> op, string asm> {
2537   defm _V1 : MIMG_NoSampler_Src_Helper <op, asm, VGPR_32, 1>;
2538   defm _V2 : MIMG_NoSampler_Src_Helper <op, asm, VReg_64, 2>;
2539   defm _V3 : MIMG_NoSampler_Src_Helper <op, asm, VReg_96, 3>;
2540   defm _V4 : MIMG_NoSampler_Src_Helper <op, asm, VReg_128, 4>;
2541 }
2542
2543 class MIMG_Sampler_Helper <bits<7> op, string asm,
2544                            RegisterClass dst_rc,
2545                            RegisterClass src_rc, int wqm> : MIMG <
2546   op,
2547   (outs dst_rc:$vdata),
2548   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
2549        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
2550        SReg_256:$srsrc, SReg_128:$ssamp),
2551   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
2552      #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
2553   []> {
2554   let mayLoad = 1;
2555   let mayStore = 0;
2556   let hasPostISelHook = 1;
2557   let WQM = wqm;
2558 }
2559
2560 multiclass MIMG_Sampler_Src_Helper <bits<7> op, string asm,
2561                                     RegisterClass dst_rc,
2562                                     int channels, int wqm> {
2563   def _V1 : MIMG_Sampler_Helper <op, asm, dst_rc, VGPR_32, wqm>,
2564             MIMG_Mask<asm#"_V1", channels>;
2565   def _V2 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_64, wqm>,
2566             MIMG_Mask<asm#"_V2", channels>;
2567   def _V4 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_128, wqm>,
2568             MIMG_Mask<asm#"_V4", channels>;
2569   def _V8 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_256, wqm>,
2570             MIMG_Mask<asm#"_V8", channels>;
2571   def _V16 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_512, wqm>,
2572             MIMG_Mask<asm#"_V16", channels>;
2573 }
2574
2575 multiclass MIMG_Sampler <bits<7> op, string asm> {
2576   defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VGPR_32, 1, 0>;
2577   defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2, 0>;
2578   defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3, 0>;
2579   defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4, 0>;
2580 }
2581
2582 multiclass MIMG_Sampler_WQM <bits<7> op, string asm> {
2583   defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VGPR_32, 1, 1>;
2584   defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2, 1>;
2585   defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3, 1>;
2586   defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4, 1>;
2587 }
2588
2589 class MIMG_Gather_Helper <bits<7> op, string asm,
2590                           RegisterClass dst_rc,
2591                           RegisterClass src_rc, int wqm> : MIMG <
2592   op,
2593   (outs dst_rc:$vdata),
2594   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
2595        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
2596        SReg_256:$srsrc, SReg_128:$ssamp),
2597   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
2598      #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
2599   []> {
2600   let mayLoad = 1;
2601   let mayStore = 0;
2602
2603   // DMASK was repurposed for GATHER4. 4 components are always
2604   // returned and DMASK works like a swizzle - it selects
2605   // the component to fetch. The only useful DMASK values are
2606   // 1=red, 2=green, 4=blue, 8=alpha. (e.g. 1 returns
2607   // (red,red,red,red) etc.) The ISA document doesn't mention
2608   // this.
2609   // Therefore, disable all code which updates DMASK by setting these two:
2610   let MIMG = 0;
2611   let hasPostISelHook = 0;
2612   let WQM = wqm;
2613 }
2614
2615 multiclass MIMG_Gather_Src_Helper <bits<7> op, string asm,
2616                                     RegisterClass dst_rc,
2617                                     int channels, int wqm> {
2618   def _V1 : MIMG_Gather_Helper <op, asm, dst_rc, VGPR_32, wqm>,
2619             MIMG_Mask<asm#"_V1", channels>;
2620   def _V2 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_64, wqm>,
2621             MIMG_Mask<asm#"_V2", channels>;
2622   def _V4 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_128, wqm>,
2623             MIMG_Mask<asm#"_V4", channels>;
2624   def _V8 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_256, wqm>,
2625             MIMG_Mask<asm#"_V8", channels>;
2626   def _V16 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_512, wqm>,
2627             MIMG_Mask<asm#"_V16", channels>;
2628 }
2629
2630 multiclass MIMG_Gather <bits<7> op, string asm> {
2631   defm _V1 : MIMG_Gather_Src_Helper<op, asm, VGPR_32, 1, 0>;
2632   defm _V2 : MIMG_Gather_Src_Helper<op, asm, VReg_64, 2, 0>;
2633   defm _V3 : MIMG_Gather_Src_Helper<op, asm, VReg_96, 3, 0>;
2634   defm _V4 : MIMG_Gather_Src_Helper<op, asm, VReg_128, 4, 0>;
2635 }
2636
2637 multiclass MIMG_Gather_WQM <bits<7> op, string asm> {
2638   defm _V1 : MIMG_Gather_Src_Helper<op, asm, VGPR_32, 1, 1>;
2639   defm _V2 : MIMG_Gather_Src_Helper<op, asm, VReg_64, 2, 1>;
2640   defm _V3 : MIMG_Gather_Src_Helper<op, asm, VReg_96, 3, 1>;
2641   defm _V4 : MIMG_Gather_Src_Helper<op, asm, VReg_128, 4, 1>;
2642 }
2643
2644 //===----------------------------------------------------------------------===//
2645 // Vector instruction mappings
2646 //===----------------------------------------------------------------------===//
2647
2648 // Maps an opcode in e32 form to its e64 equivalent
2649 def getVOPe64 : InstrMapping {
2650   let FilterClass = "VOP";
2651   let RowFields = ["OpName"];
2652   let ColFields = ["Size"];
2653   let KeyCol = ["4"];
2654   let ValueCols = [["8"]];
2655 }
2656
2657 // Maps an opcode in e64 form to its e32 equivalent
2658 def getVOPe32 : InstrMapping {
2659   let FilterClass = "VOP";
2660   let RowFields = ["OpName"];
2661   let ColFields = ["Size"];
2662   let KeyCol = ["8"];
2663   let ValueCols = [["4"]];
2664 }
2665
2666 def getMaskedMIMGOp : InstrMapping {
2667   let FilterClass = "MIMG_Mask";
2668   let RowFields = ["Op"];
2669   let ColFields = ["Channels"];
2670   let KeyCol = ["4"];
2671   let ValueCols = [["1"], ["2"], ["3"] ];
2672 }
2673
2674 // Maps an commuted opcode to its original version
2675 def getCommuteOrig : InstrMapping {
2676   let FilterClass = "VOP2_REV";
2677   let RowFields = ["RevOp"];
2678   let ColFields = ["IsOrig"];
2679   let KeyCol = ["0"];
2680   let ValueCols = [["1"]];
2681 }
2682
2683 // Maps an original opcode to its commuted version
2684 def getCommuteRev : InstrMapping {
2685   let FilterClass = "VOP2_REV";
2686   let RowFields = ["RevOp"];
2687   let ColFields = ["IsOrig"];
2688   let KeyCol = ["1"];
2689   let ValueCols = [["0"]];
2690 }
2691
2692 def getCommuteCmpOrig : InstrMapping {
2693   let FilterClass = "VOP2_REV";
2694   let RowFields = ["RevOp"];
2695   let ColFields = ["IsOrig"];
2696   let KeyCol = ["0"];
2697   let ValueCols = [["1"]];
2698 }
2699
2700 // Maps an original opcode to its commuted version
2701 def getCommuteCmpRev : InstrMapping {
2702   let FilterClass = "VOP2_REV";
2703   let RowFields = ["RevOp"];
2704   let ColFields = ["IsOrig"];
2705   let KeyCol = ["1"];
2706   let ValueCols = [["0"]];
2707 }
2708
2709
2710 def getMCOpcodeGen : InstrMapping {
2711   let FilterClass = "SIMCInstr";
2712   let RowFields = ["PseudoInstr"];
2713   let ColFields = ["Subtarget"];
2714   let KeyCol = [!cast<string>(SISubtarget.NONE)];
2715   let ValueCols = [[!cast<string>(SISubtarget.SI)],[!cast<string>(SISubtarget.VI)]];
2716 }
2717
2718 def getAddr64Inst : InstrMapping {
2719   let FilterClass = "MUBUFAddr64Table";
2720   let RowFields = ["OpName"];
2721   let ColFields = ["IsAddr64"];
2722   let KeyCol = ["0"];
2723   let ValueCols = [["1"]];
2724 }
2725
2726 // Maps an atomic opcode to its version with a return value.
2727 def getAtomicRetOp : InstrMapping {
2728   let FilterClass = "AtomicNoRet";
2729   let RowFields = ["NoRetOp"];
2730   let ColFields = ["IsRet"];
2731   let KeyCol = ["0"];
2732   let ValueCols = [["1"]];
2733 }
2734
2735 // Maps an atomic opcode to its returnless version.
2736 def getAtomicNoRetOp : InstrMapping {
2737   let FilterClass = "AtomicNoRet";
2738   let RowFields = ["NoRetOp"];
2739   let ColFields = ["IsRet"];
2740   let KeyCol = ["1"];
2741   let ValueCols = [["0"]];
2742 }
2743
2744 include "SIInstructions.td"
2745 include "CIInstructions.td"
2746 include "VIInstructions.td"