]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/AMDGPU/SIInstrInfo.td
Copy ^/vendor/NetBSD/tests/dist to contrib/netbsd-tests
[FreeBSD/FreeBSD.git] / contrib / llvm / 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                       ">= SISubtarget::SEA_ISLANDS">;
11 def isCIOnly : Predicate<"Subtarget->getGeneration() =="
12                          "SISubtarget::SEA_ISLANDS">,
13   AssemblerPredicate <"FeatureSeaIslands">;
14
15 def DisableInst : Predicate <"false">, AssemblerPredicate<"FeatureDisable">;
16
17 class vop {
18   field bits<9> SI3;
19   field bits<10> VI3;
20 }
21
22 class vopc <bits<8> si, bits<8> vi = !add(0x40, si)> : vop {
23   field bits<8> SI = si;
24   field bits<8> VI = vi;
25
26   field bits<9>  SI3 = {0, si{7-0}};
27   field bits<10> VI3 = {0, 0, vi{7-0}};
28 }
29
30 class vop1 <bits<8> si, bits<8> vi = si> : vop {
31   field bits<8> SI = si;
32   field bits<8> VI = vi;
33
34   field bits<9>  SI3 = {1, 1, si{6-0}};
35   field bits<10> VI3 = !add(0x140, vi);
36 }
37
38 class vop2 <bits<6> si, bits<6> vi = si> : vop {
39   field bits<6> SI = si;
40   field bits<6> VI = vi;
41
42   field bits<9>  SI3 = {1, 0, 0, si{5-0}};
43   field bits<10> VI3 = {0, 1, 0, 0, vi{5-0}};
44 }
45
46 // Specify a VOP2 opcode for SI and VOP3 opcode for VI
47 // that doesn't have VOP2 encoding on VI
48 class vop23 <bits<6> si, bits<10> vi> : vop2 <si> {
49   let VI3 = vi;
50 }
51
52 class vop3 <bits<9> si, bits<10> vi = {0, si}> : vop {
53   let SI3 = si;
54   let VI3 = vi;
55 }
56
57 class sop1 <bits<8> si, bits<8> vi = si> {
58   field bits<8> SI = si;
59   field bits<8> VI = vi;
60 }
61
62 class sop2 <bits<7> si, bits<7> vi = si> {
63   field bits<7> SI = si;
64   field bits<7> VI = vi;
65 }
66
67 class sopk <bits<5> si, bits<5> vi = si> {
68   field bits<5> SI = si;
69   field bits<5> VI = vi;
70 }
71
72 class dsop <bits<8> si, bits<8> vi = si> {
73   field bits<8> SI = si;
74   field bits<8> VI = vi;
75 }
76
77 // Specify an SMRD opcode for SI and SMEM opcode for VI
78
79 // FIXME: This should really be bits<5> si, Tablegen crashes if
80 // parameter default value is other parameter with different bit size
81 class smrd<bits<8> si, bits<8> vi = si> {
82   field bits<5> SI = si{4-0};
83   field bits<8> VI = vi;
84 }
85
86 // Execpt for the NONE field, this must be kept in sync with the
87 // SIEncodingFamily enum in AMDGPUInstrInfo.cpp
88 def SIEncodingFamily {
89   int NONE = -1;
90   int SI = 0;
91   int VI = 1;
92 }
93
94 //===----------------------------------------------------------------------===//
95 // SI DAG Nodes
96 //===----------------------------------------------------------------------===//
97
98 def SIload_constant : SDNode<"AMDGPUISD::LOAD_CONSTANT",
99   SDTypeProfile<1, 2, [SDTCisVT<0, f32>, SDTCisVT<1, v4i32>, SDTCisVT<2, i32>]>,
100                       [SDNPMayLoad, SDNPMemOperand]
101 >;
102
103 def SIatomic_inc : SDNode<"AMDGPUISD::ATOMIC_INC", SDTAtomic2,
104   [SDNPMayLoad, SDNPMayStore, SDNPMemOperand, SDNPHasChain]
105 >;
106
107 def SIatomic_dec : SDNode<"AMDGPUISD::ATOMIC_DEC", SDTAtomic2,
108   [SDNPMayLoad, SDNPMayStore, SDNPMemOperand, SDNPHasChain]
109 >;
110
111 def SItbuffer_store : SDNode<"AMDGPUISD::TBUFFER_STORE_FORMAT",
112   SDTypeProfile<0, 13,
113     [SDTCisVT<0, v4i32>,   // rsrc(SGPR)
114      SDTCisVT<1, iAny>,   // vdata(VGPR)
115      SDTCisVT<2, i32>,    // num_channels(imm)
116      SDTCisVT<3, i32>,    // vaddr(VGPR)
117      SDTCisVT<4, i32>,    // soffset(SGPR)
118      SDTCisVT<5, i32>,    // inst_offset(imm)
119      SDTCisVT<6, i32>,    // dfmt(imm)
120      SDTCisVT<7, i32>,    // nfmt(imm)
121      SDTCisVT<8, i32>,    // offen(imm)
122      SDTCisVT<9, i32>,    // idxen(imm)
123      SDTCisVT<10, i32>,   // glc(imm)
124      SDTCisVT<11, i32>,   // slc(imm)
125      SDTCisVT<12, i32>    // tfe(imm)
126     ]>,
127   [SDNPMayStore, SDNPMemOperand, SDNPHasChain]
128 >;
129
130 def SIload_input : SDNode<"AMDGPUISD::LOAD_INPUT",
131   SDTypeProfile<1, 3, [SDTCisVT<0, v4f32>, SDTCisVT<1, v4i32>, SDTCisVT<2, i16>,
132                        SDTCisVT<3, i32>]>
133 >;
134
135 class SDSample<string opcode> : SDNode <opcode,
136   SDTypeProfile<1, 4, [SDTCisVT<0, v4f32>, SDTCisVT<2, v8i32>,
137                        SDTCisVT<3, v4i32>, SDTCisVT<4, i32>]>
138 >;
139
140 def SIsample : SDSample<"AMDGPUISD::SAMPLE">;
141 def SIsampleb : SDSample<"AMDGPUISD::SAMPLEB">;
142 def SIsampled : SDSample<"AMDGPUISD::SAMPLED">;
143 def SIsamplel : SDSample<"AMDGPUISD::SAMPLEL">;
144
145 def SIpc_add_rel_offset : SDNode<"AMDGPUISD::PC_ADD_REL_OFFSET",
146   SDTypeProfile<1, 1, [SDTCisVT<0, iPTR>, SDTCisSameAs<0,1>]>
147 >;
148
149 //===----------------------------------------------------------------------===//
150 // PatFrags for FLAT instructions
151 //===----------------------------------------------------------------------===//
152
153 class flat_ld <SDPatternOperator ld> : PatFrag<(ops node:$ptr),
154                                                (ld node:$ptr), [{
155   const MemSDNode *LD = cast<MemSDNode>(N);
156   return LD->getAddressSpace() == AMDGPUAS::FLAT_ADDRESS ||
157          LD->getAddressSpace() == AMDGPUAS::GLOBAL_ADDRESS ||
158          LD->getAddressSpace() == AMDGPUAS::CONSTANT_ADDRESS;
159 }]>;
160
161 def flat_load : flat_ld <load>;
162 def atomic_flat_load : flat_ld<atomic_load>;
163 def flat_az_extloadi8 : flat_ld <az_extloadi8>;
164 def flat_sextloadi8 : flat_ld <sextloadi8>;
165 def flat_az_extloadi16 : flat_ld <az_extloadi16>;
166 def flat_sextloadi16 : flat_ld <sextloadi16>;
167
168 class flat_st <SDPatternOperator st> : PatFrag<(ops node:$val, node:$ptr),
169                                                (st node:$val, node:$ptr), [{
170   const MemSDNode *ST = cast<MemSDNode>(N);
171   return ST->getAddressSpace() == AMDGPUAS::FLAT_ADDRESS ||
172          ST->getAddressSpace() == AMDGPUAS::GLOBAL_ADDRESS;
173 }]>;
174
175 def flat_store: flat_st <store>;
176 def atomic_flat_store: flat_st <atomic_store>;
177 def flat_truncstorei8 : flat_st <truncstorei8>;
178 def flat_truncstorei16 : flat_st <truncstorei16>;
179
180 class MubufLoad <SDPatternOperator op> : PatFrag <
181   (ops node:$ptr), (op node:$ptr), [{
182
183   const MemSDNode *LD = cast<MemSDNode>(N);
184   return LD->getAddressSpace() == AMDGPUAS::GLOBAL_ADDRESS ||
185          LD->getAddressSpace() == AMDGPUAS::CONSTANT_ADDRESS;
186 }]>;
187
188 def mubuf_load : MubufLoad <load>;
189 def mubuf_az_extloadi8 : MubufLoad <az_extloadi8>;
190 def mubuf_sextloadi8 : MubufLoad <sextloadi8>;
191 def mubuf_az_extloadi16 : MubufLoad <az_extloadi16>;
192 def mubuf_sextloadi16 : MubufLoad <sextloadi16>;
193
194 def mubuf_load_atomic : MubufLoad <atomic_load>;
195
196 def smrd_load : PatFrag <(ops node:$ptr), (load node:$ptr), [{
197   auto Ld = cast<LoadSDNode>(N);
198   return Ld->getAlignment() >= 4  &&
199     Ld->getAddressSpace() == AMDGPUAS::CONSTANT_ADDRESS &&
200     static_cast<const SITargetLowering *>(getTargetLowering())->isMemOpUniform(N);
201 }]>;
202
203 //===----------------------------------------------------------------------===//
204 // PatFrags for global memory operations
205 //===----------------------------------------------------------------------===//
206
207 def atomic_inc_global : global_binary_atomic_op<SIatomic_inc>;
208 def atomic_dec_global : global_binary_atomic_op<SIatomic_dec>;
209
210 def atomic_inc_flat : flat_binary_atomic_op<SIatomic_inc>;
211 def atomic_dec_flat : flat_binary_atomic_op<SIatomic_dec>;
212
213 //===----------------------------------------------------------------------===//
214 // SDNodes and PatFrag for local loads and stores to enable s_mov_b32 m0, -1
215 // to be glued to the memory instructions.
216 //===----------------------------------------------------------------------===//
217
218 def SIld_local : SDNode <"ISD::LOAD", SDTLoad,
219   [SDNPHasChain, SDNPMayLoad, SDNPMemOperand, SDNPInGlue]
220 >;
221
222 def si_ld_local : PatFrag <(ops node:$ptr), (SIld_local node:$ptr), [{
223   return cast<LoadSDNode>(N)->getAddressSpace() == AMDGPUAS::LOCAL_ADDRESS;
224 }]>;
225
226 def si_load_local : PatFrag <(ops node:$ptr), (si_ld_local node:$ptr), [{
227   return cast<LoadSDNode>(N)->getAddressingMode() == ISD::UNINDEXED &&
228          cast<LoadSDNode>(N)->getExtensionType() == ISD::NON_EXTLOAD;
229 }]>;
230
231 def si_load_local_align8 : Aligned8Bytes <
232   (ops node:$ptr), (si_load_local node:$ptr)
233 >;
234
235 def si_sextload_local : PatFrag <(ops node:$ptr), (si_ld_local node:$ptr), [{
236   return cast<LoadSDNode>(N)->getExtensionType() == ISD::SEXTLOAD;
237 }]>;
238 def si_az_extload_local : AZExtLoadBase <si_ld_local>;
239
240 multiclass SIExtLoadLocal <PatFrag ld_node> {
241
242   def _i8 : PatFrag <(ops node:$ptr), (ld_node node:$ptr),
243                      [{return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i8;}]
244   >;
245
246   def _i16 : PatFrag <(ops node:$ptr), (ld_node node:$ptr),
247                      [{return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i16;}]
248   >;
249 }
250
251 defm si_sextload_local : SIExtLoadLocal <si_sextload_local>;
252 defm si_az_extload_local : SIExtLoadLocal <si_az_extload_local>;
253
254 def SIst_local : SDNode <"ISD::STORE", SDTStore,
255   [SDNPHasChain, SDNPMayStore, SDNPMemOperand, SDNPInGlue]
256 >;
257
258 def si_st_local : PatFrag <
259   (ops node:$val, node:$ptr), (SIst_local node:$val, node:$ptr), [{
260   return cast<StoreSDNode>(N)->getAddressSpace() == AMDGPUAS::LOCAL_ADDRESS;
261 }]>;
262
263 def si_store_local : PatFrag <
264   (ops node:$val, node:$ptr), (si_st_local node:$val, node:$ptr), [{
265   return cast<StoreSDNode>(N)->getAddressingMode() == ISD::UNINDEXED &&
266          !cast<StoreSDNode>(N)->isTruncatingStore();
267 }]>;
268
269 def si_store_local_align8 : Aligned8Bytes <
270   (ops node:$val, node:$ptr), (si_store_local node:$val, node:$ptr)
271 >;
272
273 def si_truncstore_local : PatFrag <
274   (ops node:$val, node:$ptr), (si_st_local node:$val, node:$ptr), [{
275   return cast<StoreSDNode>(N)->isTruncatingStore();
276 }]>;
277
278 def si_truncstore_local_i8 : PatFrag <
279   (ops node:$val, node:$ptr), (si_truncstore_local node:$val, node:$ptr), [{
280   return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i8;
281 }]>;
282
283 def si_truncstore_local_i16 : PatFrag <
284   (ops node:$val, node:$ptr), (si_truncstore_local node:$val, node:$ptr), [{
285   return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i16;
286 }]>;
287
288 def si_setcc_uniform : PatFrag <
289   (ops node:$lhs, node:$rhs, node:$cond),
290   (setcc node:$lhs, node:$rhs, node:$cond), [{
291   for (SDNode *Use : N->uses()) {
292     if (Use->isMachineOpcode() || Use->getOpcode() != ISD::CopyToReg)
293       return false;
294
295     unsigned Reg = cast<RegisterSDNode>(Use->getOperand(1))->getReg();
296     if (Reg != AMDGPU::SCC)
297       return false;
298   }
299   return true;
300 }]>;
301
302 def si_uniform_br : PatFrag <
303   (ops node:$cond, node:$bb), (brcond node:$cond, node:$bb), [{
304   return isUniformBr(N);
305 }]>;
306
307 def si_uniform_br_scc : PatFrag <
308   (ops node:$cond, node:$bb), (si_uniform_br node:$cond, node:$bb), [{
309   return isCBranchSCC(N);
310 }]>;
311
312 multiclass SIAtomicM0Glue2 <string op_name, bit is_amdgpu = 0> {
313
314   def _glue : SDNode <
315     !if(is_amdgpu, "AMDGPUISD", "ISD")#"::ATOMIC_"#op_name, SDTAtomic2,
316     [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand, SDNPInGlue]
317   >;
318
319   def _local : local_binary_atomic_op <!cast<SDNode>(NAME#"_glue")>;
320 }
321
322 defm si_atomic_load_add : SIAtomicM0Glue2 <"LOAD_ADD">;
323 defm si_atomic_load_sub : SIAtomicM0Glue2 <"LOAD_SUB">;
324 defm si_atomic_inc : SIAtomicM0Glue2 <"INC", 1>;
325 defm si_atomic_dec : SIAtomicM0Glue2 <"DEC", 1>;
326 defm si_atomic_load_and : SIAtomicM0Glue2 <"LOAD_AND">;
327 defm si_atomic_load_min : SIAtomicM0Glue2 <"LOAD_MIN">;
328 defm si_atomic_load_max : SIAtomicM0Glue2 <"LOAD_MAX">;
329 defm si_atomic_load_or : SIAtomicM0Glue2 <"LOAD_OR">;
330 defm si_atomic_load_xor : SIAtomicM0Glue2 <"LOAD_XOR">;
331 defm si_atomic_load_umin : SIAtomicM0Glue2 <"LOAD_UMIN">;
332 defm si_atomic_load_umax : SIAtomicM0Glue2 <"LOAD_UMAX">;
333 defm si_atomic_swap : SIAtomicM0Glue2 <"SWAP">;
334
335 def si_atomic_cmp_swap_glue : SDNode <"ISD::ATOMIC_CMP_SWAP", SDTAtomic3,
336   [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand, SDNPInGlue]
337 >;
338
339 defm si_atomic_cmp_swap : AtomicCmpSwapLocal <si_atomic_cmp_swap_glue>;
340
341 // Transformation function, extract the lower 32bit of a 64bit immediate
342 def LO32 : SDNodeXForm<imm, [{
343   return CurDAG->getTargetConstant(N->getZExtValue() & 0xffffffff, SDLoc(N),
344                                    MVT::i32);
345 }]>;
346
347 def LO32f : SDNodeXForm<fpimm, [{
348   APInt V = N->getValueAPF().bitcastToAPInt().trunc(32);
349   return CurDAG->getTargetConstantFP(APFloat(APFloat::IEEEsingle, V), MVT::f32);
350 }]>;
351
352 // Transformation function, extract the upper 32bit of a 64bit immediate
353 def HI32 : SDNodeXForm<imm, [{
354   return CurDAG->getTargetConstant(N->getZExtValue() >> 32, SDLoc(N), MVT::i32);
355 }]>;
356
357 def HI32f : SDNodeXForm<fpimm, [{
358   APInt V = N->getValueAPF().bitcastToAPInt().lshr(32).trunc(32);
359   return CurDAG->getTargetConstantFP(APFloat(APFloat::IEEEsingle, V), SDLoc(N),
360                                      MVT::f32);
361 }]>;
362
363 def IMM8bitDWORD : PatLeaf <(imm),
364   [{return (N->getZExtValue() & ~0x3FC) == 0;}]
365 >;
366
367 def as_dword_i32imm : SDNodeXForm<imm, [{
368   return CurDAG->getTargetConstant(N->getZExtValue() >> 2, SDLoc(N), MVT::i32);
369 }]>;
370
371 def as_i1imm : SDNodeXForm<imm, [{
372   return CurDAG->getTargetConstant(N->getZExtValue(), SDLoc(N), MVT::i1);
373 }]>;
374
375 def as_i8imm : SDNodeXForm<imm, [{
376   return CurDAG->getTargetConstant(N->getZExtValue(), SDLoc(N), MVT::i8);
377 }]>;
378
379 def as_i16imm : SDNodeXForm<imm, [{
380   return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i16);
381 }]>;
382
383 def as_i32imm: SDNodeXForm<imm, [{
384   return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i32);
385 }]>;
386
387 def as_i64imm: SDNodeXForm<imm, [{
388   return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i64);
389 }]>;
390
391 // Copied from the AArch64 backend:
392 def bitcast_fpimm_to_i32 : SDNodeXForm<fpimm, [{
393 return CurDAG->getTargetConstant(
394   N->getValueAPF().bitcastToAPInt().getZExtValue(), SDLoc(N), MVT::i32);
395 }]>;
396
397 // Copied from the AArch64 backend:
398 def bitcast_fpimm_to_i64 : SDNodeXForm<fpimm, [{
399 return CurDAG->getTargetConstant(
400   N->getValueAPF().bitcastToAPInt().getZExtValue(), SDLoc(N), MVT::i64);
401 }]>;
402
403 def IMM8bit : PatLeaf <(imm),
404   [{return isUInt<8>(N->getZExtValue());}]
405 >;
406
407 def IMM12bit : PatLeaf <(imm),
408   [{return isUInt<12>(N->getZExtValue());}]
409 >;
410
411 def IMM16bit : PatLeaf <(imm),
412   [{return isUInt<16>(N->getZExtValue());}]
413 >;
414
415 def SIMM16bit : PatLeaf <(imm),
416   [{return isInt<16>(N->getSExtValue());}]
417 >;
418
419 def IMM20bit : PatLeaf <(imm),
420   [{return isUInt<20>(N->getZExtValue());}]
421 >;
422
423 def IMM32bit : PatLeaf <(imm),
424   [{return isUInt<32>(N->getZExtValue());}]
425 >;
426
427 def mubuf_vaddr_offset : PatFrag<
428   (ops node:$ptr, node:$offset, node:$imm_offset),
429   (add (add node:$ptr, node:$offset), node:$imm_offset)
430 >;
431
432 class InlineImm <ValueType vt> : PatLeaf <(vt imm), [{
433   return isInlineImmediate(N);
434 }]>;
435
436 class InlineFPImm <ValueType vt> : PatLeaf <(vt fpimm), [{
437   return isInlineImmediate(N);
438 }]>;
439
440 class SGPRImm <dag frag> : PatLeaf<frag, [{
441   if (Subtarget->getGeneration() < SISubtarget::SOUTHERN_ISLANDS) {
442     return false;
443   }
444   const SIRegisterInfo *SIRI =
445       static_cast<const SIRegisterInfo *>(Subtarget->getRegisterInfo());
446   for (SDNode::use_iterator U = N->use_begin(), E = SDNode::use_end();
447                                                 U != E; ++U) {
448     const TargetRegisterClass *RC = getOperandRegClass(*U, U.getOperandNo());
449     if (RC && SIRI->isSGPRClass(RC))
450       return true;
451   }
452   return false;
453 }]>;
454
455 //===----------------------------------------------------------------------===//
456 // Custom Operands
457 //===----------------------------------------------------------------------===//
458
459 def FRAMEri32 : Operand<iPTR> {
460   let MIOperandInfo = (ops i32:$ptr, i32imm:$index);
461 }
462
463 def SoppBrTarget : AsmOperandClass {
464   let Name = "SoppBrTarget";
465   let ParserMethod = "parseSOppBrTarget";
466 }
467
468 def sopp_brtarget : Operand<OtherVT> {
469   let EncoderMethod = "getSOPPBrEncoding";
470   let OperandType = "OPERAND_PCREL";
471   let ParserMatchClass = SoppBrTarget;
472 }
473
474 def si_ga : Operand<iPTR>;
475
476 def InterpSlot : Operand<i32> {
477   let PrintMethod = "printInterpSlot";
478 }
479
480 def SendMsgMatchClass : AsmOperandClass {
481   let Name = "SendMsg";
482   let PredicateMethod = "isSendMsg";
483   let ParserMethod = "parseSendMsgOp";
484   let RenderMethod = "addImmOperands";
485 }
486
487 def SendMsgImm : Operand<i32> {
488   let PrintMethod = "printSendMsg";
489   let ParserMatchClass = SendMsgMatchClass;
490 }
491
492 def SWaitMatchClass : AsmOperandClass {
493   let Name = "SWaitCnt";
494   let RenderMethod = "addImmOperands";
495   let ParserMethod = "parseSWaitCntOps";
496 }
497
498 def WAIT_FLAG : Operand <i32> {
499   let ParserMatchClass = SWaitMatchClass;
500   let PrintMethod = "printWaitFlag";
501 }
502
503 include "SIInstrFormats.td"
504 include "VIInstrFormats.td"
505
506 class NamedMatchClass<string CName, bit Optional = 1> : AsmOperandClass {
507   let Name = "Imm"#CName;
508   let PredicateMethod = "is"#CName;
509   let ParserMethod = !if(Optional, "parseOptionalOperand", "parse"#CName);
510   let RenderMethod = "addImmOperands";
511   let IsOptional = Optional;
512   let DefaultMethod = !if(Optional, "default"#CName, ?);
513 }
514
515 class NamedOperandBit<string Name, AsmOperandClass MatchClass> : Operand<i1> {
516   let PrintMethod = "print"#Name;
517   let ParserMatchClass = MatchClass;
518 }
519
520 class NamedOperandU8<string Name, AsmOperandClass MatchClass> : Operand<i8> {
521   let PrintMethod = "print"#Name;
522   let ParserMatchClass = MatchClass;
523 }
524
525 class NamedOperandU16<string Name, AsmOperandClass MatchClass> : Operand<i16> {
526   let PrintMethod = "print"#Name;
527   let ParserMatchClass = MatchClass;
528 }
529
530 class NamedOperandU32<string Name, AsmOperandClass MatchClass> : Operand<i32> {
531   let PrintMethod = "print"#Name;
532   let ParserMatchClass = MatchClass;
533 }
534
535 let OperandType = "OPERAND_IMMEDIATE" in {
536
537 def offen : NamedOperandBit<"Offen", NamedMatchClass<"Offen">>;
538 def idxen : NamedOperandBit<"Idxen", NamedMatchClass<"Idxen">>;
539 def addr64 : NamedOperandBit<"Addr64", NamedMatchClass<"Addr64">>;
540
541 def offset : NamedOperandU16<"Offset", NamedMatchClass<"Offset">>;
542 def offset0 : NamedOperandU8<"Offset0", NamedMatchClass<"Offset0">>;
543 def offset1 : NamedOperandU8<"Offset1", NamedMatchClass<"Offset1">>;
544
545 def gds : NamedOperandBit<"GDS", NamedMatchClass<"GDS">>;
546
547 def omod : NamedOperandU32<"OModSI", NamedMatchClass<"OModSI">>;
548 def clampmod : NamedOperandBit<"ClampSI", NamedMatchClass<"ClampSI">>;
549
550 def smrd_offset : NamedOperandU32<"SMRDOffset", NamedMatchClass<"SMRDOffset">>;
551 def smrd_literal_offset : NamedOperandU32<"SMRDLiteralOffset", NamedMatchClass<"SMRDLiteralOffset">>;
552
553 def glc : NamedOperandBit<"GLC", NamedMatchClass<"GLC">>;
554 def slc : NamedOperandBit<"SLC", NamedMatchClass<"SLC">>;
555 def tfe : NamedOperandBit<"TFE", NamedMatchClass<"TFE">>;
556 def unorm : NamedOperandBit<"UNorm", NamedMatchClass<"UNorm">>;
557 def da : NamedOperandBit<"DA", NamedMatchClass<"DA">>;
558 def r128 : NamedOperandBit<"R128", NamedMatchClass<"R128">>;
559 def lwe : NamedOperandBit<"LWE", NamedMatchClass<"LWE">>;
560
561 def dmask : NamedOperandU16<"DMask", NamedMatchClass<"DMask">>;
562
563 def dpp_ctrl : NamedOperandU32<"DPPCtrl", NamedMatchClass<"DPPCtrl", 0>>;
564 def row_mask : NamedOperandU32<"RowMask", NamedMatchClass<"RowMask">>;
565 def bank_mask : NamedOperandU32<"BankMask", NamedMatchClass<"BankMask">>;
566 def bound_ctrl : NamedOperandBit<"BoundCtrl", NamedMatchClass<"BoundCtrl">>;
567
568 def dst_sel : NamedOperandU32<"SDWADstSel", NamedMatchClass<"SDWADstSel">>;
569 def src0_sel : NamedOperandU32<"SDWASrc0Sel", NamedMatchClass<"SDWASrc0Sel">>;
570 def src1_sel : NamedOperandU32<"SDWASrc1Sel", NamedMatchClass<"SDWASrc1Sel">>;
571 def dst_unused : NamedOperandU32<"SDWADstUnused", NamedMatchClass<"SDWADstUnused">>;
572
573 def hwreg : NamedOperandU16<"Hwreg", NamedMatchClass<"Hwreg", 0>>;
574
575 } // End OperandType = "OPERAND_IMMEDIATE"
576
577
578 def VOPDstS64 : VOPDstOperand <SReg_64>;
579
580 def FPInputModsMatchClass : AsmOperandClass {
581   let Name = "RegOrImmWithFPInputMods";
582   let ParserMethod = "parseRegOrImmWithFPInputMods";
583   let PredicateMethod = "isRegOrImmWithInputMods";
584 }
585
586 def FPInputMods : Operand <i32> {
587   let PrintMethod = "printOperandAndFPInputMods";
588   let ParserMatchClass = FPInputModsMatchClass;
589 }
590
591 def IntInputModsMatchClass : AsmOperandClass {
592   let Name = "RegOrImmWithIntInputMods";
593   let ParserMethod = "parseRegOrImmWithIntInputMods";
594   let PredicateMethod = "isRegOrImmWithInputMods";
595 }
596
597 def IntInputMods: Operand <i32> {
598   let PrintMethod = "printOperandAndIntInputMods";
599   let ParserMatchClass = IntInputModsMatchClass;
600 }
601
602 //===----------------------------------------------------------------------===//
603 // Complex patterns
604 //===----------------------------------------------------------------------===//
605
606 def DS1Addr1Offset : ComplexPattern<i32, 2, "SelectDS1Addr1Offset">;
607 def DS64Bit4ByteAligned : ComplexPattern<i32, 3, "SelectDS64Bit4ByteAligned">;
608
609 def MUBUFAddr32 : ComplexPattern<i64, 9, "SelectMUBUFAddr32">;
610 def MUBUFAddr64 : ComplexPattern<i64, 7, "SelectMUBUFAddr64">;
611 def MUBUFAddr64Atomic : ComplexPattern<i64, 5, "SelectMUBUFAddr64">;
612 def FLATAtomic : ComplexPattern<i64, 3, "SelectFlat">;
613 def MUBUFScratch : ComplexPattern<i64, 4, "SelectMUBUFScratch">;
614 def MUBUFOffset : ComplexPattern<i64, 6, "SelectMUBUFOffset">;
615 def MUBUFOffsetNoGLC : ComplexPattern<i64, 3, "SelectMUBUFOffset">;
616 def MUBUFOffsetAtomic : ComplexPattern<i64, 4, "SelectMUBUFOffset">;
617 def MUBUFIntrinsicOffset : ComplexPattern<i32, 2, "SelectMUBUFIntrinsicOffset">;
618 def MUBUFIntrinsicVOffset : ComplexPattern<i32, 3, "SelectMUBUFIntrinsicVOffset">;
619
620 def SMRDImm   : ComplexPattern<i64, 2, "SelectSMRDImm">;
621 def SMRDImm32 : ComplexPattern<i64, 2, "SelectSMRDImm32">;
622 def SMRDSgpr  : ComplexPattern<i64, 2, "SelectSMRDSgpr">;
623 def SMRDBufferImm   : ComplexPattern<i32, 1, "SelectSMRDBufferImm">;
624 def SMRDBufferImm32 : ComplexPattern<i32, 1, "SelectSMRDBufferImm32">;
625 def SMRDBufferSgpr  : ComplexPattern<i32, 1, "SelectSMRDBufferSgpr">;
626
627 def MOVRELOffset : ComplexPattern<i32, 2, "SelectMOVRELOffset">;
628
629 def VOP3Mods0 : ComplexPattern<untyped, 4, "SelectVOP3Mods0">;
630 def VOP3NoMods0 : ComplexPattern<untyped, 4, "SelectVOP3NoMods0">;
631 def VOP3Mods0Clamp : ComplexPattern<untyped, 3, "SelectVOP3Mods0Clamp">;
632 def VOP3Mods0Clamp0OMod : ComplexPattern<untyped, 4, "SelectVOP3Mods0Clamp0OMod">;
633 def VOP3Mods  : ComplexPattern<untyped, 2, "SelectVOP3Mods">;
634 def VOP3NoMods : ComplexPattern<untyped, 2, "SelectVOP3NoMods">;
635
636 //===----------------------------------------------------------------------===//
637 // SI assembler operands
638 //===----------------------------------------------------------------------===//
639
640 def SIOperand {
641   int ZERO = 0x80;
642   int VCC = 0x6A;
643   int FLAT_SCR = 0x68;
644 }
645
646 def SRCMODS {
647   int NONE = 0;
648   int NEG = 1;
649 }
650
651 def DSTCLAMP {
652   int NONE = 0;
653 }
654
655 def DSTOMOD {
656   int NONE = 0;
657 }
658
659 //===----------------------------------------------------------------------===//
660 //
661 // SI Instruction multiclass helpers.
662 //
663 // Instructions with _32 take 32-bit operands.
664 // Instructions with _64 take 64-bit operands.
665 //
666 // VOP_* instructions can use either a 32-bit or 64-bit encoding.  The 32-bit
667 // encoding is the standard encoding, but instruction that make use of
668 // any of the instruction modifiers must use the 64-bit encoding.
669 //
670 // Instructions with _e32 use the 32-bit encoding.
671 // Instructions with _e64 use the 64-bit encoding.
672 //
673 //===----------------------------------------------------------------------===//
674
675 class SIMCInstr <string pseudo, int subtarget> {
676   string PseudoInstr = pseudo;
677   int Subtarget = subtarget;
678 }
679
680 //===----------------------------------------------------------------------===//
681 // EXP classes
682 //===----------------------------------------------------------------------===//
683
684 class EXPCommon : InstSI<
685   (outs),
686   (ins i32imm:$en, i32imm:$tgt, i32imm:$compr, i32imm:$done, i32imm:$vm,
687        VGPR_32:$src0, VGPR_32:$src1, VGPR_32:$src2, VGPR_32:$src3),
688   "exp $en, $tgt, $compr, $done, $vm, $src0, $src1, $src2, $src3",
689   [] > {
690
691   let EXP_CNT = 1;
692   let Uses = [EXEC];
693   let SchedRW = [WriteExport];
694 }
695
696 multiclass EXP_m {
697
698   let isPseudo = 1, isCodeGenOnly = 1 in {
699     def "" : EXPCommon, SIMCInstr <"exp", SIEncodingFamily.NONE> ;
700   }
701
702   def _si : EXPCommon, SIMCInstr <"exp", SIEncodingFamily.SI>, EXPe {
703     let DecoderNamespace="SICI";
704     let DisableDecoder = DisableSIDecoder;
705   }
706
707   def _vi : EXPCommon, SIMCInstr <"exp", SIEncodingFamily.VI>, EXPe_vi {
708     let DecoderNamespace="VI";
709     let DisableDecoder = DisableVIDecoder;
710   }
711 }
712
713 //===----------------------------------------------------------------------===//
714 // Scalar classes
715 //===----------------------------------------------------------------------===//
716
717 class SOP1_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
718   SOP1 <outs, ins, "", pattern>,
719   SIMCInstr<opName, SIEncodingFamily.NONE> {
720   let isPseudo = 1;
721   let isCodeGenOnly = 1;
722 }
723
724 class SOP1_Real_si <sop1 op, string opName, dag outs, dag ins, string asm> :
725   SOP1 <outs, ins, asm, []>,
726   SOP1e <op.SI>,
727   SIMCInstr<opName, SIEncodingFamily.SI> {
728   let isCodeGenOnly = 0;
729   let AssemblerPredicates = [isSICI];
730   let DecoderNamespace = "SICI";
731   let DisableDecoder = DisableSIDecoder;
732 }
733
734 class SOP1_Real_vi <sop1 op, string opName, dag outs, dag ins, string asm> :
735   SOP1 <outs, ins, asm, []>,
736   SOP1e <op.VI>,
737   SIMCInstr<opName, SIEncodingFamily.VI> {
738   let isCodeGenOnly = 0;
739   let AssemblerPredicates = [isVI];
740   let DecoderNamespace = "VI";
741   let DisableDecoder = DisableVIDecoder;
742 }
743
744 multiclass SOP1_m <sop1 op, string opName, dag outs, dag ins, string asm,
745                    list<dag> pattern> {
746
747   def "" : SOP1_Pseudo <opName, outs, ins, pattern>;
748
749   def _si : SOP1_Real_si <op, opName, outs, ins, asm>;
750
751   def _vi : SOP1_Real_vi <op, opName, outs, ins, asm>;
752
753 }
754
755 multiclass SOP1_32 <sop1 op, string opName, list<dag> pattern> : SOP1_m <
756     op, opName, (outs SReg_32:$sdst), (ins SSrc_32:$src0),
757     opName#" $sdst, $src0", pattern
758 >;
759
760 multiclass SOP1_64 <sop1 op, string opName, list<dag> pattern> : SOP1_m <
761     op, opName, (outs SReg_64:$sdst), (ins SSrc_64:$src0),
762     opName#" $sdst, $src0", pattern
763 >;
764
765 // no input, 64-bit output.
766 multiclass SOP1_64_0 <sop1 op, string opName, list<dag> pattern> {
767   def "" : SOP1_Pseudo <opName, (outs SReg_64:$sdst), (ins), pattern>;
768
769   def _si : SOP1_Real_si <op, opName, (outs SReg_64:$sdst), (ins),
770     opName#" $sdst"> {
771     let src0 = 0;
772   }
773
774   def _vi : SOP1_Real_vi <op, opName, (outs SReg_64:$sdst), (ins),
775     opName#" $sdst"> {
776     let src0 = 0;
777   }
778 }
779
780 // 64-bit input, no output
781 multiclass SOP1_1 <sop1 op, string opName, list<dag> pattern> {
782   def "" : SOP1_Pseudo <opName, (outs), (ins SReg_64:$src0), pattern>;
783
784   def _si : SOP1_Real_si <op, opName, (outs), (ins SReg_64:$src0),
785     opName#" $src0"> {
786     let sdst = 0;
787   }
788
789   def _vi : SOP1_Real_vi <op, opName, (outs), (ins SReg_64:$src0),
790     opName#" $src0"> {
791     let sdst = 0;
792   }
793 }
794
795 // 64-bit input, 32-bit output.
796 multiclass SOP1_32_64 <sop1 op, string opName, list<dag> pattern> : SOP1_m <
797     op, opName, (outs SReg_32:$sdst), (ins SSrc_64:$src0),
798     opName#" $sdst, $src0", pattern
799 >;
800
801 // 32-bit input, 64-bit output.
802 multiclass SOP1_64_32 <sop1 op, string opName, list<dag> pattern> : SOP1_m <
803     op, opName, (outs SReg_64:$sdst), (ins SSrc_32:$src0),
804     opName#" $sdst, $src0", pattern
805 >;
806
807 class SOP2_Pseudo<string opName, dag outs, dag ins, list<dag> pattern> :
808   SOP2<outs, ins, "", pattern>,
809   SIMCInstr<opName, SIEncodingFamily.NONE> {
810   let isPseudo = 1;
811   let isCodeGenOnly = 1;
812   let Size = 4;
813
814   // Pseudo instructions have no encodings, but adding this field here allows
815   // us to do:
816   // let sdst = xxx in {
817   // for multiclasses that include both real and pseudo instructions.
818   field bits<7> sdst = 0;
819 }
820
821 class SOP2_Real_si<sop2 op, string opName, dag outs, dag ins, string asm> :
822   SOP2<outs, ins, asm, []>,
823   SOP2e<op.SI>,
824   SIMCInstr<opName, SIEncodingFamily.SI> {
825   let AssemblerPredicates = [isSICI];
826   let DecoderNamespace = "SICI";
827   let DisableDecoder = DisableSIDecoder;
828 }
829
830 class SOP2_Real_vi<sop2 op, string opName, dag outs, dag ins, string asm> :
831   SOP2<outs, ins, asm, []>,
832   SOP2e<op.VI>,
833   SIMCInstr<opName, SIEncodingFamily.VI> {
834   let AssemblerPredicates = [isVI];
835   let DecoderNamespace = "VI";
836   let DisableDecoder = DisableVIDecoder;
837 }
838
839 multiclass SOP2_m <sop2 op, string opName, dag outs, dag ins, string asm,
840                    list<dag> pattern> {
841
842   def "" : SOP2_Pseudo <opName, outs, ins, pattern>;
843
844   def _si : SOP2_Real_si <op, opName, outs, ins, asm>;
845
846   def _vi : SOP2_Real_vi <op, opName, outs, ins, asm>;
847
848 }
849
850 multiclass SOP2_32 <sop2 op, string opName, list<dag> pattern> : SOP2_m <
851     op, opName, (outs SReg_32:$sdst), (ins SSrc_32:$src0, SSrc_32:$src1),
852     opName#" $sdst, $src0, $src1", pattern
853 >;
854
855 multiclass SOP2_64 <sop2 op, string opName, list<dag> pattern> : SOP2_m <
856     op, opName, (outs SReg_64:$sdst), (ins SSrc_64:$src0, SSrc_64:$src1),
857     opName#" $sdst, $src0, $src1", pattern
858 >;
859
860 multiclass SOP2_64_32 <sop2 op, string opName, list<dag> pattern> : SOP2_m <
861     op, opName, (outs SReg_64:$sdst), (ins SSrc_64:$src0, SSrc_32:$src1),
862     opName#" $sdst, $src0, $src1", pattern
863 >;
864
865 multiclass SOP2_64_32_32 <sop2 op, string opName, list<dag> pattern> : SOP2_m <
866     op, opName, (outs SReg_64:$sdst), (ins SSrc_32:$src0, SSrc_32:$src1),
867     opName#" $sdst, $src0, $src1", pattern
868 >;
869
870 class SOPC_Base <bits<7> op, RegisterOperand rc0, RegisterOperand rc1,
871                  string opName, list<dag> pattern = []> : SOPC <
872   op, (outs), (ins rc0:$src0, rc1:$src1),
873   opName#" $src0, $src1", pattern > {
874   let Defs = [SCC];
875 }
876 class SOPC_Helper <bits<7> op, RegisterOperand rc, ValueType vt,
877                     string opName, PatLeaf cond> : SOPC_Base <
878   op, rc, rc, opName,
879   [(set SCC, (si_setcc_uniform vt:$src0, vt:$src1, cond))] > {
880 }
881
882 class SOPC_CMP_32<bits<7> op, string opName, PatLeaf cond = COND_NULL>
883   : SOPC_Helper<op, SSrc_32, i32, opName, cond>;
884
885 class SOPC_32<bits<7> op, string opName, list<dag> pattern = []>
886   : SOPC_Base<op, SSrc_32, SSrc_32, opName, pattern>;
887
888 class SOPC_64_32<bits<7> op, string opName, list<dag> pattern = []>
889   : SOPC_Base<op, SSrc_64, SSrc_32, opName, pattern>;
890
891 class SOPK_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
892   SOPK <outs, ins, "", pattern>,
893   SIMCInstr<opName, SIEncodingFamily.NONE> {
894   let isPseudo = 1;
895   let isCodeGenOnly = 1;
896 }
897
898 class SOPK_Real_si <sopk op, string opName, dag outs, dag ins, string asm> :
899   SOPK <outs, ins, asm, []>,
900   SOPKe <op.SI>,
901   SIMCInstr<opName, SIEncodingFamily.SI> {
902   let AssemblerPredicates = [isSICI];
903   let DecoderNamespace = "SICI";
904   let DisableDecoder = DisableSIDecoder;
905   let isCodeGenOnly = 0;
906 }
907
908 class SOPK_Real_vi <sopk op, string opName, dag outs, dag ins, string asm> :
909   SOPK <outs, ins, asm, []>,
910   SOPKe <op.VI>,
911   SIMCInstr<opName, SIEncodingFamily.VI> {
912   let AssemblerPredicates = [isVI];
913   let DecoderNamespace = "VI";
914   let DisableDecoder = DisableVIDecoder;
915   let isCodeGenOnly = 0;
916 }
917
918 multiclass SOPK_m <sopk op, string opName, dag outs, dag ins, string opAsm,
919                    string asm = opName#opAsm> {
920   def "" : SOPK_Pseudo <opName, outs, ins, []>;
921
922   def _si : SOPK_Real_si <op, opName, outs, ins, asm>;
923
924   def _vi : SOPK_Real_vi <op, opName, outs, ins, asm>;
925
926 }
927
928 multiclass SOPK_32 <sopk op, string opName, list<dag> pattern> {
929   def "" : SOPK_Pseudo <opName, (outs SReg_32:$sdst), (ins u16imm:$simm16),
930     pattern>;
931
932   def _si : SOPK_Real_si <op, opName, (outs SReg_32:$sdst), (ins u16imm:$simm16),
933     opName#" $sdst, $simm16">;
934
935   def _vi : SOPK_Real_vi <op, opName, (outs SReg_32:$sdst), (ins u16imm:$simm16),
936     opName#" $sdst, $simm16">;
937 }
938
939 multiclass SOPK_SCC <sopk op, string opName, list<dag> pattern> {
940   def "" : SOPK_Pseudo <opName, (outs),
941     (ins SReg_32:$src0, u16imm:$src1), pattern> {
942     let Defs = [SCC];
943   }
944
945
946   def _si : SOPK_Real_si <op, opName, (outs),
947     (ins SReg_32:$sdst, u16imm:$simm16), opName#" $sdst, $simm16"> {
948     let Defs = [SCC];
949   }
950
951   def _vi : SOPK_Real_vi <op, opName, (outs),
952     (ins SReg_32:$sdst, u16imm:$simm16), opName#" $sdst, $simm16"> {
953     let Defs = [SCC];
954   }
955 }
956
957 multiclass SOPK_32TIE <sopk op, string opName, list<dag> pattern> : SOPK_m <
958   op, opName, (outs SReg_32:$sdst), (ins SReg_32:$src0, u16imm:$simm16),
959   " $sdst, $simm16"
960 >;
961
962 multiclass SOPK_IMM32 <sopk op, string opName, dag outs, dag ins,
963                        string argAsm, string asm = opName#argAsm> {
964
965   def "" : SOPK_Pseudo <opName, outs, ins, []>;
966
967   def _si : SOPK <outs, ins, asm, []>,
968             SOPK64e <op.SI>,
969             SIMCInstr<opName, SIEncodingFamily.SI> {
970               let AssemblerPredicates = [isSICI];
971               let DecoderNamespace = "SICI";
972               let DisableDecoder = DisableSIDecoder;
973               let isCodeGenOnly = 0;
974             }
975
976   def _vi : SOPK <outs, ins, asm, []>,
977             SOPK64e <op.VI>,
978             SIMCInstr<opName, SIEncodingFamily.VI> {
979               let AssemblerPredicates = [isVI];
980               let DecoderNamespace = "VI";
981               let DisableDecoder = DisableVIDecoder;
982               let isCodeGenOnly = 0;
983             }
984 }
985 //===----------------------------------------------------------------------===//
986 // SMRD classes
987 //===----------------------------------------------------------------------===//
988
989 class SMRD_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
990   SMRD <outs, ins, "", pattern>,
991   SIMCInstr<opName, SIEncodingFamily.NONE> {
992   let isPseudo = 1;
993   let isCodeGenOnly = 1;
994 }
995
996 class SMRD_IMM_Real_si <bits<5> op, string opName, dag outs, dag ins,
997                         string asm> :
998   SMRD <outs, ins, asm, []>,
999   SMRD_IMMe <op>,
1000   SIMCInstr<opName, SIEncodingFamily.SI> {
1001   let AssemblerPredicates = [isSICI];
1002   let DecoderNamespace = "SICI";
1003   let DisableDecoder = DisableSIDecoder;
1004 }
1005
1006 class SMRD_SOFF_Real_si <bits<5> op, string opName, dag outs, dag ins,
1007                          string asm> :
1008   SMRD <outs, ins, asm, []>,
1009   SMRD_SOFFe <op>,
1010   SIMCInstr<opName, SIEncodingFamily.SI> {
1011   let AssemblerPredicates = [isSICI];
1012   let DecoderNamespace = "SICI";
1013   let DisableDecoder = DisableSIDecoder;
1014 }
1015
1016
1017 class SMRD_IMM_Real_vi <bits<8> op, string opName, dag outs, dag ins,
1018                         string asm, list<dag> pattern = []> :
1019   SMRD <outs, ins, asm, pattern>,
1020   SMEM_IMMe_vi <op>,
1021   SIMCInstr<opName, SIEncodingFamily.VI> {
1022   let AssemblerPredicates = [isVI];
1023   let DecoderNamespace = "VI";
1024   let DisableDecoder = DisableVIDecoder;
1025 }
1026
1027 class SMRD_SOFF_Real_vi <bits<8> op, string opName, dag outs, dag ins,
1028                          string asm, list<dag> pattern = []> :
1029   SMRD <outs, ins, asm, pattern>,
1030   SMEM_SOFFe_vi <op>,
1031   SIMCInstr<opName, SIEncodingFamily.VI> {
1032   let AssemblerPredicates = [isVI];
1033   let DecoderNamespace = "VI";
1034   let DisableDecoder = DisableVIDecoder;
1035 }
1036
1037
1038 multiclass SMRD_IMM_m <smrd op, string opName, dag outs, dag ins,
1039                    string asm, list<dag> pattern> {
1040
1041   def "" : SMRD_Pseudo <opName, outs, ins, pattern>;
1042
1043   def _si : SMRD_IMM_Real_si <op.SI, opName, outs, ins, asm>;
1044
1045   // glc is only applicable to scalar stores, which are not yet
1046   // implemented.
1047   let glc = 0 in {
1048     def _vi : SMRD_IMM_Real_vi <op.VI, opName, outs, ins, asm>;
1049   }
1050 }
1051
1052 multiclass SMRD_SOFF_m <smrd op, string opName, dag outs, dag ins,
1053                         string asm, list<dag> pattern> {
1054
1055   def "" : SMRD_Pseudo <opName, outs, ins, pattern>;
1056
1057   def _si : SMRD_SOFF_Real_si <op.SI, opName, outs, ins, asm>;
1058
1059   // glc is only applicable to scalar stores, which are not yet
1060   // implemented.
1061   let glc = 0 in {
1062     def _vi : SMRD_SOFF_Real_vi <op.VI, opName, outs, ins, asm>;
1063   }
1064 }
1065
1066 multiclass SMRD_Special <smrd op, string opName, dag outs,
1067                        int sdst_ = ?,
1068                        string opStr = "",
1069                        list<dag> pattern = []> {
1070   let hasSideEffects = 1 in {
1071     def "" : SMRD_Pseudo <opName, outs, (ins), pattern>;
1072
1073     let sbase = 0, soff = 0, sdst = sdst_ in {
1074       def _si : SMRD_SOFF_Real_si <op.SI, opName, outs, (ins), opName#opStr>;
1075
1076       let glc = 0 in {
1077         def _vi : SMRD_SOFF_Real_vi <op.VI, opName, outs, (ins), opName#opStr>;
1078       }
1079     }
1080   }
1081 }
1082
1083 multiclass SMRD_Inval <smrd op, string opName,
1084                      SDPatternOperator node> {
1085   let mayStore = 1 in {
1086     defm : SMRD_Special<op, opName, (outs), 0, "", [(node)]>;
1087   }
1088 }
1089
1090 class SMEM_Inval <bits<8> op, string opName, SDPatternOperator node> :
1091   SMRD_SOFF_Real_vi<op, opName, (outs), (ins), opName, [(node)]> {
1092   let hasSideEffects = 1;
1093   let mayStore = 1;
1094   let sbase = 0;
1095   let sdst = 0;
1096   let glc = 0;
1097   let soff = 0;
1098 }
1099
1100 class SMEM_Ret <bits<8> op, string opName, SDPatternOperator node> :
1101   SMRD_SOFF_Real_vi<op, opName, (outs SReg_64:$sdst), (ins),
1102   opName#" $sdst", [(set i64:$sdst, (node))]> {
1103   let hasSideEffects = 1;
1104   let mayStore = ?;
1105   let mayLoad = ?;
1106   let sbase = 0;
1107   let glc = 0;
1108   let soff = 0;
1109 }
1110
1111 multiclass SMRD_Helper <smrd op, string opName, RegisterClass baseClass,
1112                         RegisterClass dstClass> {
1113   defm _IMM : SMRD_IMM_m <
1114     op, opName#"_IMM", (outs dstClass:$sdst),
1115     (ins baseClass:$sbase, smrd_offset:$offset),
1116     opName#" $sdst, $sbase, $offset", []
1117   >;
1118
1119   def _IMM_ci : SMRD <
1120     (outs dstClass:$sdst), (ins baseClass:$sbase, smrd_literal_offset:$offset),
1121     opName#" $sdst, $sbase, $offset", []>, SMRD_IMMe_ci <op.SI> {
1122     let AssemblerPredicates = [isCIOnly];
1123     let DecoderNamespace = "CI";
1124   }
1125
1126   defm _SGPR : SMRD_SOFF_m <
1127     op, opName#"_SGPR", (outs dstClass:$sdst),
1128     (ins baseClass:$sbase, SReg_32:$soff),
1129     opName#" $sdst, $sbase, $soff", []
1130   >;
1131 }
1132
1133 //===----------------------------------------------------------------------===//
1134 // Vector ALU classes
1135 //===----------------------------------------------------------------------===//
1136
1137 class getNumSrcArgs<ValueType Src0, ValueType Src1, ValueType Src2> {
1138   int ret =
1139     !if (!eq(Src0.Value, untyped.Value),      0,
1140       !if (!eq(Src1.Value, untyped.Value),    1,   // VOP1
1141          !if (!eq(Src2.Value, untyped.Value), 2,   // VOP2
1142                                               3))); // VOP3
1143 }
1144
1145 // Returns the register class to use for the destination of VOP[123C]
1146 // instructions for the given VT.
1147 class getVALUDstForVT<ValueType VT> {
1148   RegisterOperand ret = !if(!eq(VT.Size, 32), VOPDstOperand<VGPR_32>,
1149                           !if(!eq(VT.Size, 64), VOPDstOperand<VReg_64>,
1150                             !if(!eq(VT.Size, 16), VOPDstOperand<VGPR_32>,
1151                             VOPDstOperand<SReg_64>))); // else VT == i1
1152 }
1153
1154 // Returns the register class to use for source 0 of VOP[12C]
1155 // instructions for the given VT.
1156 class getVOPSrc0ForVT<ValueType VT> {
1157   RegisterOperand ret = !if(!eq(VT.Size, 64), VSrc_64, VSrc_32);
1158 }
1159
1160 // Returns the vreg register class to use for source operand given VT
1161 class getVregSrcForVT<ValueType VT> {
1162   RegisterClass ret = !if(!eq(VT.Size, 64), VReg_64, VGPR_32);
1163 }
1164
1165
1166 // Returns the register class to use for sources of VOP3 instructions for the
1167 // given VT.
1168 class getVOP3SrcForVT<ValueType VT> {
1169   RegisterOperand ret =
1170   !if(!eq(VT.Size, 64),
1171       VCSrc_64,
1172       !if(!eq(VT.Value, i1.Value),
1173           SCSrc_64,
1174           VCSrc_32
1175        )
1176     );
1177 }
1178
1179 // Returns 1 if the source arguments have modifiers, 0 if they do not.
1180 // XXX - do f16 instructions?
1181 class hasModifiers<ValueType SrcVT> {
1182   bit ret =
1183     !if(!eq(SrcVT.Value, f32.Value), 1,
1184     !if(!eq(SrcVT.Value, f64.Value), 1,
1185     0));
1186 }
1187
1188 // Returns the input arguments for VOP[12C] instructions for the given SrcVT.
1189 class getIns32 <RegisterOperand Src0RC, RegisterClass Src1RC, int NumSrcArgs> {
1190   dag ret = !if(!eq(NumSrcArgs, 1), (ins Src0RC:$src0),               // VOP1
1191             !if(!eq(NumSrcArgs, 2), (ins Src0RC:$src0, Src1RC:$src1), // VOP2
1192                                     (ins)));
1193 }
1194
1195 // Returns the input arguments for VOP3 instructions for the given SrcVT.
1196 class getIns64 <RegisterOperand Src0RC, RegisterOperand Src1RC,
1197                 RegisterOperand Src2RC, int NumSrcArgs,
1198                 bit HasModifiers> {
1199
1200   dag ret =
1201     !if (!eq(NumSrcArgs, 0),
1202       // VOP1 without input operands (V_NOP, V_CLREXCP)
1203       (ins),
1204       /* else */
1205     !if (!eq(NumSrcArgs, 1),
1206       !if (!eq(HasModifiers, 1),
1207         // VOP1 with modifiers
1208         (ins FPInputMods:$src0_modifiers, Src0RC:$src0,
1209              clampmod:$clamp, omod:$omod)
1210       /* else */,
1211         // VOP1 without modifiers
1212         (ins Src0RC:$src0)
1213       /* endif */ ),
1214     !if (!eq(NumSrcArgs, 2),
1215       !if (!eq(HasModifiers, 1),
1216         // VOP 2 with modifiers
1217         (ins FPInputMods:$src0_modifiers, Src0RC:$src0,
1218              FPInputMods:$src1_modifiers, Src1RC:$src1,
1219              clampmod:$clamp, omod:$omod)
1220       /* else */,
1221         // VOP2 without modifiers
1222         (ins Src0RC:$src0, Src1RC:$src1)
1223       /* endif */ )
1224     /* NumSrcArgs == 3 */,
1225       !if (!eq(HasModifiers, 1),
1226         // VOP3 with modifiers
1227         (ins FPInputMods:$src0_modifiers, Src0RC:$src0,
1228              FPInputMods:$src1_modifiers, Src1RC:$src1,
1229              FPInputMods:$src2_modifiers, Src2RC:$src2,
1230              clampmod:$clamp, omod:$omod)
1231       /* else */,
1232         // VOP3 without modifiers
1233         (ins Src0RC:$src0, Src1RC:$src1, Src2RC:$src2)
1234       /* endif */ ))));
1235 }
1236
1237 class getInsDPP <RegisterClass Src0RC, RegisterClass Src1RC, int NumSrcArgs,
1238                                                              bit HasModifiers> {
1239
1240   dag ret = !if (!eq(NumSrcArgs, 0),
1241                 // VOP1 without input operands (V_NOP)
1242                 (ins dpp_ctrl:$dpp_ctrl, row_mask:$row_mask,
1243                      bank_mask:$bank_mask, bound_ctrl:$bound_ctrl),
1244             !if (!eq(NumSrcArgs, 1),
1245               !if (!eq(HasModifiers, 1),
1246                 // VOP1_DPP with modifiers
1247                 (ins FPInputMods:$src0_modifiers, Src0RC:$src0,
1248                      dpp_ctrl:$dpp_ctrl, row_mask:$row_mask,
1249                      bank_mask:$bank_mask, bound_ctrl:$bound_ctrl)
1250               /* else */,
1251                 // VOP1_DPP without modifiers
1252                 (ins Src0RC:$src0, dpp_ctrl:$dpp_ctrl, row_mask:$row_mask,
1253                 bank_mask:$bank_mask, bound_ctrl:$bound_ctrl)
1254               /* endif */)
1255               /* NumSrcArgs == 2 */,
1256               !if (!eq(HasModifiers, 1),
1257                 // VOP2_DPP with modifiers
1258                 (ins FPInputMods:$src0_modifiers, Src0RC:$src0,
1259                      FPInputMods:$src1_modifiers, Src1RC:$src1,
1260                      dpp_ctrl:$dpp_ctrl, row_mask:$row_mask,
1261                      bank_mask:$bank_mask, bound_ctrl:$bound_ctrl)
1262               /* else */,
1263                 // VOP2_DPP without modifiers
1264                 (ins Src0RC:$src0, Src1RC:$src1, dpp_ctrl:$dpp_ctrl,
1265                 row_mask:$row_mask, bank_mask:$bank_mask,
1266                 bound_ctrl:$bound_ctrl)
1267              /* endif */)));
1268 }
1269
1270 class getInsSDWA <RegisterClass Src0RC, RegisterClass Src1RC, int NumSrcArgs,
1271                   bit HasFloatModifiers, ValueType DstVT> {
1272
1273   dag ret = !if(!eq(NumSrcArgs, 0),
1274                // VOP1 without input operands (V_NOP)
1275                (ins),
1276             !if(!eq(NumSrcArgs, 1),
1277                 !if(HasFloatModifiers,
1278                     // VOP1_SDWA with float modifiers
1279                     (ins FPInputMods:$src0_fmodifiers, Src0RC:$src0,
1280                          clampmod:$clamp, dst_sel:$dst_sel, dst_unused:$dst_unused,
1281                          src0_sel:$src0_sel)
1282                 /* else */,
1283                     // VOP1_SDWA with sext modifier
1284                     (ins IntInputMods:$src0_imodifiers, Src0RC:$src0,
1285                          clampmod:$clamp, dst_sel:$dst_sel, dst_unused:$dst_unused,
1286                          src0_sel:$src0_sel)
1287                 /* endif */)
1288               /* NumSrcArgs == 2 */,
1289               !if(HasFloatModifiers,
1290                   !if(!eq(DstVT.Size, 1),
1291                       // VOPC_SDWA with float modifiers
1292                       (ins FPInputMods:$src0_fmodifiers, Src0RC:$src0,
1293                            FPInputMods:$src1_fmodifiers, Src1RC:$src1,
1294                            clampmod:$clamp, src0_sel:$src0_sel, src1_sel:$src1_sel),
1295                       // VOP2_SDWA or VOPC_SDWA with float modifiers
1296                       (ins FPInputMods:$src0_fmodifiers, Src0RC:$src0,
1297                            FPInputMods:$src1_fmodifiers, Src1RC:$src1,
1298                            clampmod:$clamp, dst_sel:$dst_sel, dst_unused:$dst_unused,
1299                            src0_sel:$src0_sel, src1_sel:$src1_sel)
1300                   ),
1301               /* else */
1302                 !if(!eq(DstVT.Size, 1),
1303                     // VOPC_SDWA with sext modifiers
1304                     (ins IntInputMods:$src0_imodifiers, Src0RC:$src0,
1305                          IntInputMods:$src1_imodifiers, Src1RC:$src1,
1306                          clampmod:$clamp, src0_sel:$src0_sel, src1_sel:$src1_sel),
1307                     // VOP2_SDWA or VOPC_SDWA with sext modifier
1308                     (ins IntInputMods:$src0_imodifiers, Src0RC:$src0,
1309                          IntInputMods:$src1_imodifiers, Src1RC:$src1,
1310                          clampmod:$clamp, dst_sel:$dst_sel, dst_unused:$dst_unused,
1311                          src0_sel:$src0_sel, src1_sel:$src1_sel)
1312                 )
1313              /* endif */)));
1314 }
1315
1316 // Outs for DPP and SDWA
1317 class getOutsExt <bit HasDst, ValueType DstVT, RegisterOperand DstRCDPP> {
1318   dag ret = !if(HasDst,
1319                 !if(!eq(DstVT.Size, 1),
1320                     (outs), // no dst for VOPC, we use "vcc"-token as dst in SDWA VOPC instructions
1321                     (outs DstRCDPP:$vdst)),
1322                 (outs)); // V_NOP
1323 }
1324
1325 // Returns the assembly string for the inputs and outputs of a VOP[12C]
1326 // instruction.  This does not add the _e32 suffix, so it can be reused
1327 // by getAsm64.
1328 class getAsm32 <bit HasDst, int NumSrcArgs, ValueType DstVT = i32> {
1329   string dst = !if(!eq(DstVT.Size, 1), "$sdst", "$vdst"); // use $sdst for VOPC
1330   string src0 = ", $src0";
1331   string src1 = ", $src1";
1332   string src2 = ", $src2";
1333   string ret = !if(HasDst, dst, "") #
1334                !if(!eq(NumSrcArgs, 1), src0, "") #
1335                !if(!eq(NumSrcArgs, 2), src0#src1, "") #
1336                !if(!eq(NumSrcArgs, 3), src0#src1#src2, "");
1337 }
1338
1339 // Returns the assembly string for the inputs and outputs of a VOP3
1340 // instruction.
1341 class getAsm64 <bit HasDst, int NumSrcArgs, bit HasModifiers, ValueType DstVT = i32> {
1342   string dst = !if(!eq(DstVT.Size, 1), "$sdst", "$vdst"); // use $sdst for VOPC
1343   string src0 = !if(!eq(NumSrcArgs, 1), "$src0_modifiers", "$src0_modifiers,");
1344   string src1 = !if(!eq(NumSrcArgs, 1), "",
1345                    !if(!eq(NumSrcArgs, 2), " $src1_modifiers",
1346                                            " $src1_modifiers,"));
1347   string src2 = !if(!eq(NumSrcArgs, 3), " $src2_modifiers", "");
1348   string ret =
1349   !if(!eq(HasModifiers, 0),
1350       getAsm32<HasDst, NumSrcArgs, DstVT>.ret,
1351       dst#", "#src0#src1#src2#"$clamp"#"$omod");
1352 }
1353
1354 class getAsmDPP <bit HasDst, int NumSrcArgs, bit HasModifiers, ValueType DstVT = i32> {
1355   string dst = !if(HasDst,
1356                    !if(!eq(DstVT.Size, 1),
1357                        "$sdst",
1358                        "$vdst"),
1359                     ""); // use $sdst for VOPC
1360   string src0 = !if(!eq(NumSrcArgs, 1), "$src0_modifiers", "$src0_modifiers,");
1361   string src1 = !if(!eq(NumSrcArgs, 1), "",
1362                    !if(!eq(NumSrcArgs, 2), " $src1_modifiers",
1363                                            " $src1_modifiers,"));
1364   string args = !if(!eq(HasModifiers, 0),
1365                      getAsm32<0, NumSrcArgs, DstVT>.ret,
1366                      ", "#src0#src1);
1367   string ret = dst#args#" $dpp_ctrl$row_mask$bank_mask$bound_ctrl";
1368 }
1369
1370 class getAsmSDWA <bit HasDst, int NumSrcArgs, bit HasFloatModifiers,
1371                   ValueType DstVT = i32> {
1372   string dst = !if(HasDst,
1373                    !if(!eq(DstVT.Size, 1),
1374                        " vcc", // use vcc token as dst for VOPC instructioins
1375                        "$vdst"),
1376                     "");
1377   string src0 = !if(HasFloatModifiers, "$src0_fmodifiers", "$src0_imodifiers");
1378   string src1 = !if(HasFloatModifiers, "$src1_fmodifiers", "$src1_imodifiers");
1379   string args = !if(!eq(NumSrcArgs, 0),
1380                     "",
1381                     !if(!eq(NumSrcArgs, 1),
1382                         ", "#src0#"$clamp",
1383                         ", "#src0#", "#src1#"$clamp"
1384                      )
1385                 );
1386   string sdwa = !if(!eq(NumSrcArgs, 0),
1387                     "",
1388                     !if(!eq(NumSrcArgs, 1),
1389                         " $dst_sel $dst_unused $src0_sel",
1390                         !if(!eq(DstVT.Size, 1),
1391                             " $src0_sel $src1_sel", // No dst_sel and dst_unused for VOPC
1392                             " $dst_sel $dst_unused $src0_sel $src1_sel"
1393                         )
1394                     )
1395                 );
1396   string ret = dst#args#sdwa;
1397 }
1398
1399 // Function that checks if instruction supports DPP and SDWA
1400 class getHasExt <int NumSrcArgs, ValueType DstVT = i32, ValueType Src0VT = i32,
1401                  ValueType Src1VT = i32> {
1402   bit ret = !if(!eq(NumSrcArgs, 3),
1403                 0, // NumSrcArgs == 3 - No DPP or SDWA for VOP3
1404                 !if(!eq(DstVT.Size, 64),
1405                     0, // 64-bit dst - No DPP or SDWA for 64-bit operands
1406                     !if(!eq(Src0VT.Size, 64),
1407                         0, // 64-bit src0
1408                         !if(!eq(Src0VT.Size, 64),
1409                             0, // 64-bit src2
1410                             1
1411                         )
1412                     )
1413                 )
1414             );
1415 }
1416
1417 class VOPProfile <list<ValueType> _ArgVT> {
1418
1419   field list<ValueType> ArgVT = _ArgVT;
1420
1421   field ValueType DstVT = ArgVT[0];
1422   field ValueType Src0VT = ArgVT[1];
1423   field ValueType Src1VT = ArgVT[2];
1424   field ValueType Src2VT = ArgVT[3];
1425   field RegisterOperand DstRC = getVALUDstForVT<DstVT>.ret;
1426   field RegisterOperand DstRCDPP = getVALUDstForVT<DstVT>.ret;
1427   field RegisterOperand DstRCSDWA = getVALUDstForVT<DstVT>.ret;
1428   field RegisterOperand Src0RC32 = getVOPSrc0ForVT<Src0VT>.ret;
1429   field RegisterClass Src1RC32 = getVregSrcForVT<Src1VT>.ret;
1430   field RegisterOperand Src0RC64 = getVOP3SrcForVT<Src0VT>.ret;
1431   field RegisterOperand Src1RC64 = getVOP3SrcForVT<Src1VT>.ret;
1432   field RegisterOperand Src2RC64 = getVOP3SrcForVT<Src2VT>.ret;
1433   field RegisterClass Src0DPP = getVregSrcForVT<Src0VT>.ret;
1434   field RegisterClass Src1DPP = getVregSrcForVT<Src1VT>.ret;
1435   field RegisterClass Src0SDWA = getVregSrcForVT<Src0VT>.ret;
1436   field RegisterClass Src1SDWA = getVregSrcForVT<Src1VT>.ret;
1437
1438   field bit HasDst = !if(!eq(DstVT.Value, untyped.Value), 0, 1);
1439   field bit HasDst32 = HasDst;
1440   field int NumSrcArgs = getNumSrcArgs<Src0VT, Src1VT, Src2VT>.ret;
1441   field bit HasModifiers = hasModifiers<Src0VT>.ret;
1442
1443   field bit HasExt = getHasExt<NumSrcArgs, DstVT, Src0VT, Src1VT>.ret;
1444
1445   field dag Outs = !if(HasDst,(outs DstRC:$vdst),(outs));
1446
1447   // VOP3b instructions are a special case with a second explicit
1448   // output. This is manually overridden for them.
1449   field dag Outs32 = Outs;
1450   field dag Outs64 = Outs;
1451   field dag OutsDPP = getOutsExt<HasDst, DstVT, DstRCDPP>.ret;
1452   field dag OutsSDWA = getOutsExt<HasDst, DstVT, DstRCDPP>.ret;
1453
1454   field dag Ins32 = getIns32<Src0RC32, Src1RC32, NumSrcArgs>.ret;
1455   field dag Ins64 = getIns64<Src0RC64, Src1RC64, Src2RC64, NumSrcArgs,
1456                              HasModifiers>.ret;
1457   field dag InsDPP = getInsDPP<Src0DPP, Src1DPP, NumSrcArgs, HasModifiers>.ret;
1458   field dag InsSDWA = getInsSDWA<Src0SDWA, Src1SDWA, NumSrcArgs, HasModifiers, DstVT>.ret;
1459
1460   field string Asm32 = getAsm32<HasDst, NumSrcArgs, DstVT>.ret;
1461   field string Asm64 = getAsm64<HasDst, NumSrcArgs, HasModifiers, DstVT>.ret;
1462   field string AsmDPP = getAsmDPP<HasDst, NumSrcArgs, HasModifiers, DstVT>.ret;
1463   field string AsmSDWA = getAsmSDWA<HasDst, NumSrcArgs, HasModifiers, DstVT>.ret;
1464 }
1465
1466 class VOP_NO_EXT <VOPProfile p> : VOPProfile <p.ArgVT> {
1467   let HasExt = 0;
1468 }
1469
1470 // FIXME: I think these F16/I16 profiles will need to use f16/i16 types in order
1471 //        for the instruction patterns to work.
1472 def VOP_F16_F16 : VOPProfile <[f16, f16, untyped, untyped]>;
1473 def VOP_F16_I16 : VOPProfile <[f16, i32, untyped, untyped]>;
1474 def VOP_I16_F16 : VOPProfile <[i32, f16, untyped, untyped]>;
1475
1476 def VOP_F16_F16_F16 : VOPProfile <[f16, f16, f16, untyped]>;
1477 def VOP_F16_F16_I16 : VOPProfile <[f16, f16, i32, untyped]>;
1478 def VOP_I16_I16_I16 : VOPProfile <[i32, i32, i32, untyped]>;
1479
1480 def VOP_I16_I16_I16_I16 : VOPProfile <[i32, i32, i32, i32, untyped]>;
1481 def VOP_F16_F16_F16_F16 : VOPProfile <[f16, f16, f16, f16, untyped]>;
1482
1483 def VOP_NONE : VOPProfile <[untyped, untyped, untyped, untyped]>;
1484
1485 def VOP_F32_F32 : VOPProfile <[f32, f32, untyped, untyped]>;
1486 def VOP_F32_F64 : VOPProfile <[f32, f64, untyped, untyped]>;
1487 def VOP_F32_I32 : VOPProfile <[f32, i32, untyped, untyped]>;
1488 def VOP_F64_F32 : VOPProfile <[f64, f32, untyped, untyped]>;
1489 def VOP_F64_F64 : VOPProfile <[f64, f64, untyped, untyped]>;
1490 def VOP_F64_I32 : VOPProfile <[f64, i32, untyped, untyped]>;
1491 def VOP_I32_F32 : VOPProfile <[i32, f32, untyped, untyped]>;
1492 def VOP_I32_F64 : VOPProfile <[i32, f64, untyped, untyped]>;
1493 def VOP_I32_I32 : VOPProfile <[i32, i32, untyped, untyped]>;
1494
1495 def VOP_F32_F32_F32 : VOPProfile <[f32, f32, f32, untyped]>;
1496 def VOP_F32_F32_I32 : VOPProfile <[f32, f32, i32, untyped]>;
1497 def VOP_F64_F64_F64 : VOPProfile <[f64, f64, f64, untyped]>;
1498 def VOP_F64_F64_I32 : VOPProfile <[f64, f64, i32, untyped]>;
1499 def VOP_I32_F32_F32 : VOPProfile <[i32, f32, f32, untyped]>;
1500 def VOP_I32_F32_I32 : VOPProfile <[i32, f32, i32, untyped]>;
1501 def VOP_I32_I32_I32 : VOPProfile <[i32, i32, i32, untyped]>;
1502
1503 // Write out to vcc or arbitrary SGPR.
1504 def VOP2b_I32_I1_I32_I32 : VOPProfile<[i32, i32, i32, untyped]> {
1505   let Asm32 = "$vdst, vcc, $src0, $src1";
1506   let Asm64 = "$vdst, $sdst, $src0, $src1";
1507   let Outs32 = (outs DstRC:$vdst);
1508   let Outs64 = (outs DstRC:$vdst, SReg_64:$sdst);
1509 }
1510
1511 // Write out to vcc or arbitrary SGPR and read in from vcc or
1512 // arbitrary SGPR.
1513 def VOP2b_I32_I1_I32_I32_I1 : VOPProfile<[i32, i32, i32, i1]> {
1514   // We use VCSrc_32 to exclude literal constants, even though the
1515   // encoding normally allows them since the implicit VCC use means
1516   // using one would always violate the constant bus
1517   // restriction. SGPRs are still allowed because it should
1518   // technically be possible to use VCC again as src0.
1519   let Src0RC32 = VCSrc_32;
1520   let Asm32 = "$vdst, vcc, $src0, $src1, vcc";
1521   let Asm64 = "$vdst, $sdst, $src0, $src1, $src2";
1522   let Outs32 = (outs DstRC:$vdst);
1523   let Outs64 = (outs DstRC:$vdst, SReg_64:$sdst);
1524
1525   // Suppress src2 implied by type since the 32-bit encoding uses an
1526   // implicit VCC use.
1527   let Ins32 = (ins Src0RC32:$src0, Src1RC32:$src1);
1528 }
1529
1530 // Read in from vcc or arbitrary SGPR
1531 def VOP2e_I32_I32_I32_I1 : VOPProfile<[i32, i32, i32, i1]> {
1532   let Src0RC32 = VCSrc_32; // See comment in def VOP2b_I32_I1_I32_I32_I1 above.
1533   let Asm32 = "$vdst, $src0, $src1, vcc";
1534   let Asm64 = "$vdst, $src0, $src1, $src2";
1535   let Outs32 = (outs DstRC:$vdst);
1536   let Outs64 = (outs DstRC:$vdst);
1537
1538   // Suppress src2 implied by type since the 32-bit encoding uses an
1539   // implicit VCC use.
1540   let Ins32 = (ins Src0RC32:$src0, Src1RC32:$src1);
1541 }
1542
1543 class VOP3b_Profile<ValueType vt> : VOPProfile<[vt, vt, vt, vt]> {
1544   let Outs64 = (outs DstRC:$vdst, SReg_64:$sdst);
1545   let Asm64 = "$vdst, $sdst, $src0_modifiers, $src1_modifiers, $src2_modifiers"#"$clamp"#"$omod";
1546 }
1547
1548 def VOP3b_F32_I1_F32_F32_F32 : VOP3b_Profile<f32> {
1549   // FIXME: Hack to stop printing _e64
1550   let DstRC = RegisterOperand<VGPR_32>;
1551 }
1552
1553 def VOP3b_F64_I1_F64_F64_F64 : VOP3b_Profile<f64> {
1554   // FIXME: Hack to stop printing _e64
1555   let DstRC = RegisterOperand<VReg_64>;
1556 }
1557
1558 // VOPC instructions are a special case because for the 32-bit
1559 // encoding, we want to display the implicit vcc write as if it were
1560 // an explicit $dst.
1561 class VOPC_Profile<ValueType vt0, ValueType vt1 = vt0> : VOPProfile <[i1, vt0, vt1, untyped]> {
1562   let Asm32 = "vcc, $src0, $src1";
1563   // The destination for 32-bit encoding is implicit.
1564   let HasDst32 = 0;
1565   let Outs64 = (outs DstRC:$sdst);
1566 }
1567
1568 class VOPC_Class_Profile<ValueType vt> : VOPC_Profile<vt, i32> {
1569   let Ins64 = (ins FPInputMods:$src0_modifiers, Src0RC64:$src0, Src1RC64:$src1);
1570   let Asm64 = "$sdst, $src0_modifiers, $src1";
1571   let InsSDWA = (ins FPInputMods:$src0_fmodifiers, Src0RC64:$src0,
1572                      IntInputMods:$src1_imodifiers, Src1RC64:$src1,
1573                      clampmod:$clamp, src0_sel:$src0_sel, src1_sel:$src1_sel);
1574   let AsmSDWA = " vcc, $src0_fmodifiers, $src1_imodifiers$clamp $src0_sel $src1_sel";
1575
1576 }
1577
1578 def VOPC_I1_F32_F32 : VOPC_Profile<f32>;
1579 def VOPC_I1_F64_F64 : VOPC_Profile<f64>;
1580 def VOPC_I1_I32_I32 : VOPC_Profile<i32>;
1581 def VOPC_I1_I64_I64 : VOPC_Profile<i64>;
1582
1583 def VOPC_I1_F32_I32 : VOPC_Class_Profile<f32>;
1584 def VOPC_I1_F64_I32 : VOPC_Class_Profile<f64>;
1585
1586 def VOP_I64_I64_I32 : VOPProfile <[i64, i64, i32, untyped]>;
1587 def VOP_I64_I32_I64 : VOPProfile <[i64, i32, i64, untyped]>;
1588 def VOP_I64_I64_I64 : VOPProfile <[i64, i64, i64, untyped]>;
1589
1590 def VOP_F32_F32_F32_F32 : VOPProfile <[f32, f32, f32, f32]>;
1591 def VOP_MADAK : VOPProfile <[f32, f32, f32, f32]> {
1592   field dag Ins32 = (ins VCSrc_32:$src0, VGPR_32:$src1, u32kimm:$imm);
1593   field string Asm32 = "$vdst, $src0, $src1, $imm";
1594   field bit HasExt = 0;
1595 }
1596 def VOP_MADMK : VOPProfile <[f32, f32, f32, f32]> {
1597   field dag Ins32 = (ins VCSrc_32:$src0, u32kimm:$imm, VGPR_32:$src1);
1598   field string Asm32 = "$vdst, $src0, $imm, $src1";
1599   field bit HasExt = 0;
1600 }
1601 def VOP_MAC : VOPProfile <[f32, f32, f32, f32]> {
1602   let Ins32 = (ins Src0RC32:$src0, Src1RC32:$src1, VGPR_32:$src2);
1603   let Ins64 = getIns64<Src0RC64, Src1RC64, RegisterOperand<VGPR_32>, 3,
1604                              HasModifiers>.ret;
1605   let InsDPP = (ins FPInputMods:$src0_modifiers, Src0RC32:$src0,
1606                     FPInputMods:$src1_modifiers, Src1RC32:$src1,
1607                     VGPR_32:$src2, // stub argument
1608                     dpp_ctrl:$dpp_ctrl, row_mask:$row_mask,
1609                     bank_mask:$bank_mask, bound_ctrl:$bound_ctrl);
1610   let InsSDWA = (ins FPInputMods:$src0_fmodifiers, Src0RC32:$src0,
1611                      FPInputMods:$src1_fmodifiers, Src1RC32:$src1,
1612                      VGPR_32:$src2, // stub argument
1613                      clampmod:$clamp, dst_sel:$dst_sel, dst_unused:$dst_unused,
1614                      src0_sel:$src0_sel, src1_sel:$src1_sel);
1615   let Asm32 = getAsm32<1, 2, f32>.ret;
1616   let Asm64 = getAsm64<1, 2, HasModifiers, f32>.ret;
1617   let AsmDPP = getAsmDPP<1, 2, HasModifiers, f32>.ret;
1618   let AsmSDWA = getAsmSDWA<1, 2, HasModifiers, f32>.ret;
1619 }
1620 def VOP_F64_F64_F64_F64 : VOPProfile <[f64, f64, f64, f64]>;
1621 def VOP_I32_I32_I32_I32 : VOPProfile <[i32, i32, i32, i32]>;
1622 def VOP_I64_I32_I32_I64 : VOPProfile <[i64, i32, i32, i64]>;
1623
1624 // This class is used only with VOPC instructions. Use $sdst for out operand
1625 class SIInstAlias <string asm, Instruction inst, VOPProfile p> :
1626     InstAlias <asm, (inst)>, PredicateControl {
1627
1628   field bit isCompare;
1629   field bit isCommutable;
1630
1631   let ResultInst =
1632     !if (p.HasDst32,
1633       !if (!eq(p.NumSrcArgs, 0),
1634         // 1 dst, 0 src
1635         (inst p.DstRC:$sdst),
1636       !if (!eq(p.NumSrcArgs, 1),
1637         // 1 dst, 1 src
1638         (inst p.DstRC:$sdst, p.Src0RC32:$src0),
1639       !if (!eq(p.NumSrcArgs, 2),
1640         // 1 dst, 2 src
1641         (inst p.DstRC:$sdst, p.Src0RC32:$src0, p.Src1RC32:$src1),
1642       // else - unreachable
1643         (inst)))),
1644     // else
1645       !if (!eq(p.NumSrcArgs, 2),
1646         // 0 dst, 2 src
1647         (inst p.Src0RC32:$src0, p.Src1RC32:$src1),
1648       !if (!eq(p.NumSrcArgs, 1),
1649         // 0 dst, 1 src
1650         (inst p.Src0RC32:$src1),
1651       // else
1652         // 0 dst, 0 src
1653         (inst))));
1654 }
1655
1656 class SIInstAliasSI <string asm, string op_name, VOPProfile p> :
1657   SIInstAlias <asm, !cast<Instruction>(op_name#"_e32_si"), p> {
1658   let AssemblerPredicate = SIAssemblerPredicate;
1659 }
1660
1661 class SIInstAliasVI <string asm, string op_name, VOPProfile p> :
1662   SIInstAlias <asm, !cast<Instruction>(op_name#"_e32_vi"), p> {
1663   let AssemblerPredicates = [isVI];
1664 }
1665
1666 multiclass SIInstAliasBuilder <string asm, VOPProfile p> {
1667
1668   def : SIInstAliasSI <asm, NAME, p>;
1669
1670   def : SIInstAliasVI <asm, NAME, p>;
1671 }
1672
1673 class VOP <string opName> {
1674   string OpName = opName;
1675 }
1676
1677 class VOP2_REV <string revOp, bit isOrig> {
1678   string RevOp = revOp;
1679   bit IsOrig = isOrig;
1680 }
1681
1682 class AtomicNoRet <string noRetOp, bit isRet> {
1683   string NoRetOp = noRetOp;
1684   bit IsRet = isRet;
1685 }
1686
1687 class VOP1_Pseudo <dag outs, dag ins, list<dag> pattern, string opName> :
1688   VOP1Common <outs, ins, "", pattern>,
1689   VOP <opName>,
1690   SIMCInstr <opName#"_e32", SIEncodingFamily.NONE>,
1691   MnemonicAlias<opName#"_e32", opName> {
1692   let isPseudo = 1;
1693   let isCodeGenOnly = 1;
1694
1695   field bits<8> vdst;
1696   field bits<9> src0;
1697 }
1698
1699 class VOP1_Real_si <string opName, vop1 op, dag outs, dag ins, string asm> :
1700   VOP1<op.SI, outs, ins, asm, []>,
1701   SIMCInstr <opName#"_e32", SIEncodingFamily.SI> {
1702   let AssemblerPredicate = SIAssemblerPredicate;
1703   let DecoderNamespace = "SICI";
1704   let DisableDecoder = DisableSIDecoder;
1705 }
1706
1707 class VOP1_Real_vi <string opName, vop1 op, dag outs, dag ins, string asm> :
1708   VOP1<op.VI, outs, ins, asm, []>,
1709   SIMCInstr <opName#"_e32", SIEncodingFamily.VI> {
1710   let AssemblerPredicates = [isVI];
1711   let DecoderNamespace = "VI";
1712   let DisableDecoder = DisableVIDecoder;
1713 }
1714
1715 multiclass VOP1_m <vop1 op, string opName, VOPProfile p, list<dag> pattern,
1716                    string asm = opName#p.Asm32> {
1717   def "" : VOP1_Pseudo <p.Outs, p.Ins32, pattern, opName>;
1718
1719   def _si : VOP1_Real_si <opName, op, p.Outs, p.Ins32, asm>;
1720
1721   def _vi : VOP1_Real_vi <opName, op, p.Outs, p.Ins32, asm>;
1722
1723 }
1724
1725 class VOP1_DPP <vop1 op, string opName, VOPProfile p> :
1726   VOP1_DPPe <op.VI>,
1727   VOP_DPP <p.OutsDPP, p.InsDPP, opName#p.AsmDPP, [], p.HasModifiers> {
1728   let AssemblerPredicates = !if(p.HasExt, [isVI], [DisableInst]);
1729   let DecoderNamespace = "DPP";
1730   let DisableDecoder = DisableVIDecoder;
1731   let src0_modifiers = !if(p.HasModifiers, ?, 0);
1732   let src1_modifiers = 0;
1733 }
1734
1735 class SDWADisableFields <VOPProfile p> {
1736   bits<8> src0 = !if(!eq(p.NumSrcArgs, 0), 0, ?);
1737   bits<3> src0_sel = !if(!eq(p.NumSrcArgs, 0), 6, ?);
1738   bits<2> src0_fmodifiers = !if(!eq(p.NumSrcArgs, 0),
1739                                 0,
1740                                 !if(p.HasModifiers, ?, 0));
1741   bits<1> src0_imodifiers = !if(!eq(p.NumSrcArgs, 0),
1742                                 0,
1743                                 !if(p.HasModifiers, 0, ?));
1744   bits<3> src1_sel = !if(!eq(p.NumSrcArgs, 0), 6,
1745                          !if(!eq(p.NumSrcArgs, 1), 6,
1746                              ?));
1747   bits<2> src1_fmodifiers = !if(!eq(p.NumSrcArgs, 0), 0,
1748                                 !if(!eq(p.NumSrcArgs, 1), 0,
1749                                     !if(p.HasModifiers, ?, 0)));
1750   bits<1> src1_imodifiers = !if(!eq(p.NumSrcArgs, 0), 0,
1751                                 !if(!eq(p.NumSrcArgs, 1), 0,
1752                                     !if(p.HasModifiers, 0, ?)));
1753   bits<3> dst_sel = !if(p.HasDst, ?, 6);
1754   bits<2> dst_unused = !if(p.HasDst, ?, 2);
1755   bits<1> clamp = !if(!eq(p.NumSrcArgs, 0), 0, ?);
1756 }
1757
1758 class VOP1_SDWA <vop1 op, string opName, VOPProfile p> :
1759   VOP1_SDWAe <op.VI>,
1760   VOP_SDWA <p.OutsSDWA, p.InsSDWA, opName#p.AsmSDWA, [], p.HasModifiers>,
1761   SDWADisableFields <p> {
1762   let AsmMatchConverter = "cvtSdwaVOP1";
1763   let AssemblerPredicates = !if(p.HasExt, [isVI], [DisableInst]);
1764   let DecoderNamespace = "SDWA";
1765   let DisableDecoder = DisableVIDecoder;
1766 }
1767
1768 multiclass VOP1SI_m <vop1 op, string opName, VOPProfile p, list<dag> pattern,
1769                      string asm = opName#p.Asm32> {
1770
1771   def "" : VOP1_Pseudo <p.Outs, p.Ins32, pattern, opName>;
1772
1773   def _si : VOP1_Real_si <opName, op, p.Outs, p.Ins32, asm>;
1774 }
1775
1776 class VOP2_Pseudo <dag outs, dag ins, list<dag> pattern, string opName> :
1777   VOP2Common <outs, ins, "", pattern>,
1778   VOP <opName>,
1779   SIMCInstr<opName#"_e32", SIEncodingFamily.NONE>,
1780   MnemonicAlias<opName#"_e32", opName> {
1781   let isPseudo = 1;
1782   let isCodeGenOnly = 1;
1783 }
1784
1785 class VOP2_Real_si <string opName, vop2 op, dag outs, dag ins, string asm> :
1786   VOP2 <op.SI, outs, ins, opName#asm, []>,
1787   SIMCInstr <opName#"_e32", SIEncodingFamily.SI> {
1788   let AssemblerPredicates = [isSICI];
1789   let DecoderNamespace = "SICI";
1790   let DisableDecoder = DisableSIDecoder;
1791 }
1792
1793 class VOP2_Real_vi <string opName, vop2 op, dag outs, dag ins, string asm> :
1794   VOP2 <op.VI, outs, ins, opName#asm, []>,
1795   SIMCInstr <opName#"_e32", SIEncodingFamily.VI> {
1796   let AssemblerPredicates = [isVI];
1797   let DecoderNamespace = "VI";
1798   let DisableDecoder = DisableVIDecoder;
1799 }
1800
1801 multiclass VOP2SI_m <vop2 op, string opName, VOPProfile p, list<dag> pattern,
1802                      string revOp> {
1803
1804   def "" : VOP2_Pseudo <p.Outs32, p.Ins32, pattern, opName>,
1805            VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
1806
1807   def _si : VOP2_Real_si <opName, op, p.Outs32, p.Ins32, p.Asm32>;
1808 }
1809
1810 multiclass VOP2_m <vop2 op, string opName, VOPProfile p, list <dag> pattern,
1811                    string revOp> {
1812
1813   def "" : VOP2_Pseudo <p.Outs32, p.Ins32, pattern, opName>,
1814            VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
1815
1816   def _si : VOP2_Real_si <opName, op, p.Outs32, p.Ins32, p.Asm32>;
1817
1818   def _vi : VOP2_Real_vi <opName, op, p.Outs32, p.Ins32, p.Asm32>;
1819
1820 }
1821
1822 class VOP2_DPP <vop2 op, string opName, VOPProfile p> :
1823   VOP2_DPPe <op.VI>,
1824   VOP_DPP <p.OutsDPP, p.InsDPP, opName#p.AsmDPP, [], p.HasModifiers> {
1825   let AssemblerPredicates = !if(p.HasExt, [isVI], [DisableInst]);
1826   let DecoderNamespace = "DPP";
1827   let DisableDecoder = DisableVIDecoder;
1828   let src0_modifiers = !if(p.HasModifiers, ?, 0);
1829   let src1_modifiers = !if(p.HasModifiers, ?, 0);
1830 }
1831
1832 class VOP2_SDWA <vop2 op, string opName, VOPProfile p> :
1833   VOP2_SDWAe <op.VI>,
1834   VOP_SDWA <p.OutsSDWA, p.InsSDWA, opName#p.AsmSDWA, [], p.HasModifiers>,
1835   SDWADisableFields <p> {
1836   let AsmMatchConverter = "cvtSdwaVOP2";
1837   let AssemblerPredicates = !if(p.HasExt, [isVI], [DisableInst]);
1838   let DecoderNamespace = "SDWA";
1839   let DisableDecoder = DisableVIDecoder;
1840 }
1841
1842 class VOP3DisableFields <bit HasSrc1, bit HasSrc2, bit HasModifiers> {
1843
1844   bits<2> src0_modifiers = !if(HasModifiers, ?, 0);
1845   bits<2> src1_modifiers = !if(HasModifiers, !if(HasSrc1, ?, 0), 0);
1846   bits<2> src2_modifiers = !if(HasModifiers, !if(HasSrc2, ?, 0), 0);
1847   bits<2> omod = !if(HasModifiers, ?, 0);
1848   bits<1> clamp = !if(HasModifiers, ?, 0);
1849   bits<9> src1 = !if(HasSrc1, ?, 0);
1850   bits<9> src2 = !if(HasSrc2, ?, 0);
1851 }
1852
1853 class VOP3DisableModFields <bit HasSrc0Mods,
1854                             bit HasSrc1Mods = 0,
1855                             bit HasSrc2Mods = 0,
1856                             bit HasOutputMods = 0> {
1857   bits<2> src0_modifiers = !if(HasSrc0Mods, ?, 0);
1858   bits<2> src1_modifiers = !if(HasSrc1Mods, ?, 0);
1859   bits<2> src2_modifiers = !if(HasSrc2Mods, ?, 0);
1860   bits<2> omod = !if(HasOutputMods, ?, 0);
1861   bits<1> clamp = !if(HasOutputMods, ?, 0);
1862 }
1863
1864 class VOP3_Pseudo <dag outs, dag ins, list<dag> pattern, string opName,
1865                    bit HasMods = 0, bit VOP3Only = 0> :
1866   VOP3Common <outs, ins, "", pattern, HasMods, VOP3Only>,
1867   VOP <opName>,
1868   SIMCInstr<opName#"_e64", SIEncodingFamily.NONE>,
1869   MnemonicAlias<opName#"_e64", opName> {
1870   let isPseudo = 1;
1871   let isCodeGenOnly = 1;
1872
1873   field bit vdst;
1874   field bit src0;
1875 }
1876
1877 class VOP3_Real_si <bits<9> op, dag outs, dag ins, string asm, string opName,
1878                     bit HasMods = 0, bit VOP3Only = 0> :
1879   VOP3Common <outs, ins, asm, [], HasMods, VOP3Only>,
1880   VOP3e <op>,
1881   SIMCInstr<opName#"_e64", SIEncodingFamily.SI> {
1882   let AssemblerPredicates = [isSICI];
1883   let DecoderNamespace = "SICI";
1884   let DisableDecoder = DisableSIDecoder;
1885 }
1886
1887 class VOP3_Real_vi <bits<10> op, dag outs, dag ins, string asm, string opName,
1888                     bit HasMods = 0, bit VOP3Only = 0> :
1889   VOP3Common <outs, ins, asm, [], HasMods, VOP3Only>,
1890   VOP3e_vi <op>,
1891   SIMCInstr <opName#"_e64", SIEncodingFamily.VI> {
1892   let AssemblerPredicates = [isVI];
1893   let DecoderNamespace = "VI";
1894   let DisableDecoder = DisableVIDecoder;
1895 }
1896
1897 class VOP3_C_Real_si <bits<9> op, dag outs, dag ins, string asm, string opName,
1898                      bit HasMods = 0, bit VOP3Only = 0> :
1899   VOP3Common <outs, ins, asm, [], HasMods, VOP3Only>,
1900   VOP3ce <op>,
1901   SIMCInstr<opName#"_e64", SIEncodingFamily.SI> {
1902   let AssemblerPredicates = [isSICI];
1903   let DecoderNamespace = "SICI";
1904   let DisableDecoder = DisableSIDecoder;
1905 }
1906
1907 class VOP3_C_Real_vi <bits<10> op, dag outs, dag ins, string asm, string opName,
1908                       bit HasMods = 0, bit VOP3Only = 0> :
1909   VOP3Common <outs, ins, asm, [], HasMods, VOP3Only>,
1910   VOP3ce_vi <op>,
1911   SIMCInstr <opName#"_e64", SIEncodingFamily.VI> {
1912   let AssemblerPredicates = [isVI];
1913   let DecoderNamespace = "VI";
1914   let DisableDecoder = DisableVIDecoder;
1915 }
1916
1917 class VOP3b_Real_si <bits<9> op, dag outs, dag ins, string asm, string opName,
1918                      bit HasMods = 0, bit VOP3Only = 0> :
1919   VOP3Common <outs, ins, asm, [], HasMods, VOP3Only>,
1920   VOP3be <op>,
1921   SIMCInstr<opName#"_e64", SIEncodingFamily.SI> {
1922   let AssemblerPredicates = [isSICI];
1923   let DecoderNamespace = "SICI";
1924   let DisableDecoder = DisableSIDecoder;
1925 }
1926
1927 class VOP3b_Real_vi <bits<10> op, dag outs, dag ins, string asm, string opName,
1928                      bit HasMods = 0, bit VOP3Only = 0> :
1929   VOP3Common <outs, ins, asm, [], HasMods, VOP3Only>,
1930   VOP3be_vi <op>,
1931   SIMCInstr <opName#"_e64", SIEncodingFamily.VI> {
1932   let AssemblerPredicates = [isVI];
1933   let DecoderNamespace = "VI";
1934   let DisableDecoder = DisableVIDecoder;
1935 }
1936
1937 class VOP3e_Real_si <bits<9> op, dag outs, dag ins, string asm, string opName,
1938                      bit HasMods = 0, bit VOP3Only = 0> :
1939   VOP3Common <outs, ins, asm, [], HasMods, VOP3Only>,
1940   VOP3e <op>,
1941   SIMCInstr<opName#"_e64", SIEncodingFamily.SI> {
1942   let AssemblerPredicates = [isSICI];
1943   let DecoderNamespace = "SICI";
1944   let DisableDecoder = DisableSIDecoder;
1945 }
1946
1947 class VOP3e_Real_vi <bits<10> op, dag outs, dag ins, string asm, string opName,
1948                      bit HasMods = 0, bit VOP3Only = 0> :
1949   VOP3Common <outs, ins, asm, [], HasMods, VOP3Only>,
1950   VOP3e_vi <op>,
1951   SIMCInstr <opName#"_e64", SIEncodingFamily.VI> {
1952   let AssemblerPredicates = [isVI];
1953   let DecoderNamespace = "VI";
1954   let DisableDecoder = DisableVIDecoder;
1955 }
1956
1957 multiclass VOP3_m <vop op, dag outs, dag ins, string asm, list<dag> pattern,
1958                    string opName, int NumSrcArgs, bit HasMods = 1, bit VOP3Only = 0> {
1959
1960   def "" : VOP3_Pseudo <outs, ins, pattern, opName>;
1961
1962   def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName, HasMods, VOP3Only>,
1963             VOP3DisableFields<!if(!eq(NumSrcArgs, 1), 0, 1),
1964                               !if(!eq(NumSrcArgs, 2), 0, 1),
1965                               HasMods>;
1966   def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName, HasMods, VOP3Only>,
1967             VOP3DisableFields<!if(!eq(NumSrcArgs, 1), 0, 1),
1968                               !if(!eq(NumSrcArgs, 2), 0, 1),
1969                               HasMods>;
1970 }
1971
1972 multiclass VOP3_1_m <vop op, dag outs, dag ins, string asm,
1973                      list<dag> pattern, string opName, bit HasMods = 1> {
1974
1975   def "" : VOP3_Pseudo <outs, ins, pattern, opName, HasMods>;
1976
1977   def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName, HasMods>,
1978             VOP3DisableFields<0, 0, HasMods>;
1979
1980   def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName, HasMods>,
1981             VOP3DisableFields<0, 0, HasMods>;
1982 }
1983
1984 multiclass VOP3SI_1_m <vop op, dag outs, dag ins, string asm,
1985                      list<dag> pattern, string opName, bit HasMods = 1> {
1986
1987   def "" : VOP3_Pseudo <outs, ins, pattern, opName, HasMods>;
1988
1989   def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName, HasMods>,
1990             VOP3DisableFields<0, 0, HasMods>;
1991   // No VI instruction. This class is for SI only.
1992 }
1993
1994 multiclass VOP3_2_m <vop op, dag outs, dag ins, string asm,
1995                      list<dag> pattern, string opName, string revOp,
1996                      bit HasMods = 1> {
1997
1998   def "" : VOP3_Pseudo <outs, ins, pattern, opName, HasMods>,
1999            VOP2_REV<revOp#"_e64", !eq(revOp, opName)>;
2000
2001   def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName, HasMods>,
2002             VOP3DisableFields<1, 0, HasMods>;
2003
2004   def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName, HasMods>,
2005             VOP3DisableFields<1, 0, HasMods>;
2006 }
2007
2008 multiclass VOP3SI_2_m <vop op, dag outs, dag ins, string asm,
2009                      list<dag> pattern, string opName, string revOp,
2010                      bit HasMods = 1> {
2011
2012   def "" : VOP3_Pseudo <outs, ins, pattern, opName, HasMods>,
2013            VOP2_REV<revOp#"_e64", !eq(revOp, opName)>;
2014
2015   def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName, HasMods>,
2016             VOP3DisableFields<1, 0, HasMods>;
2017
2018   // No VI instruction. This class is for SI only.
2019 }
2020
2021 // Two operand VOP3b instruction that may have a 3rd SGPR bool operand
2022 // instead of an implicit VCC as in the VOP2b format.
2023 multiclass VOP3b_2_3_m <vop op, dag outs, dag ins, string asm,
2024                         list<dag> pattern, string opName, string revOp,
2025                         bit HasMods = 1, bit useSrc2Input = 0, bit VOP3Only = 0> {
2026   def "" : VOP3_Pseudo <outs, ins, pattern, opName, HasMods, VOP3Only>;
2027
2028   def _si : VOP3b_Real_si <op.SI3, outs, ins, asm, opName, HasMods, VOP3Only>,
2029             VOP3DisableFields<1, useSrc2Input, HasMods>;
2030
2031   def _vi : VOP3b_Real_vi <op.VI3, outs, ins, asm, opName, HasMods, VOP3Only>,
2032             VOP3DisableFields<1, useSrc2Input, HasMods>;
2033 }
2034
2035 // Same as VOP3b_2_3_m but no 2nd destination (sdst), e.g. v_cndmask_b32.
2036 multiclass VOP3e_2_3_m <vop op, dag outs, dag ins, string asm,
2037                         list<dag> pattern, string opName, string revOp,
2038                         bit HasMods = 1, bit useSrc2Input = 0, bit VOP3Only = 0> {
2039   def "" : VOP3_Pseudo <outs, ins, pattern, opName, HasMods, VOP3Only>;
2040
2041   def _si : VOP3e_Real_si <op.SI3, outs, ins, asm, opName, HasMods, VOP3Only>,
2042             VOP3DisableFields<1, useSrc2Input, HasMods>;
2043
2044   def _vi : VOP3e_Real_vi <op.VI3, outs, ins, asm, opName, HasMods, VOP3Only>,
2045             VOP3DisableFields<1, useSrc2Input, HasMods>;
2046 }
2047
2048 multiclass VOP3_C_m <vop op, dag outs, dag ins, string asm,
2049                      list<dag> pattern, string opName,
2050                      bit HasMods, bit defExec,
2051                      string revOp, list<SchedReadWrite> sched> {
2052
2053   def "" : VOP3_Pseudo <outs, ins, pattern, opName, HasMods>,
2054            VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
2055     let Defs = !if(defExec, [EXEC], []);
2056     let SchedRW = sched;
2057   }
2058
2059   def _si : VOP3_C_Real_si <op.SI3, outs, ins, asm, opName, HasMods>,
2060             VOP3DisableFields<1, 0, HasMods> {
2061     let Defs = !if(defExec, [EXEC], []);
2062     let SchedRW = sched;
2063   }
2064
2065   def _vi : VOP3_C_Real_vi <op.VI3, outs, ins, asm, opName, HasMods>,
2066             VOP3DisableFields<1, 0, HasMods> {
2067     let Defs = !if(defExec, [EXEC], []);
2068     let SchedRW = sched;
2069   }
2070 }
2071
2072 // An instruction that is VOP2 on SI and VOP3 on VI, no modifiers.
2073 multiclass VOP2SI_3VI_m <vop3 op, string opName, dag outs, dag ins,
2074                          string asm, list<dag> pattern = []> {
2075   let isPseudo = 1, isCodeGenOnly = 1 in {
2076     def "" : VOPAnyCommon <outs, ins, "", pattern>,
2077              SIMCInstr<opName, SIEncodingFamily.NONE>;
2078   }
2079
2080   def _si : VOP2 <op.SI3{5-0}, outs, ins, asm, []>,
2081             SIMCInstr <opName, SIEncodingFamily.SI> {
2082             let AssemblerPredicates = [isSICI];
2083             let DecoderNamespace = "SICI";
2084             let DisableDecoder = DisableSIDecoder;
2085   }
2086
2087   def _vi : VOP3Common <outs, ins, asm, []>,
2088             VOP3e_vi <op.VI3>,
2089             VOP3DisableFields <1, 0, 0>,
2090             SIMCInstr <opName, SIEncodingFamily.VI> {
2091             let AssemblerPredicates = [isVI];
2092             let DecoderNamespace = "VI";
2093             let DisableDecoder = DisableVIDecoder;
2094   }
2095 }
2096
2097 multiclass VOP1_Helper <vop1 op, string opName, VOPProfile p, list<dag> pat32,
2098                         list<dag> pat64> {
2099
2100   defm _e32 : VOP1_m <op, opName, p, pat32>;
2101
2102   defm _e64 : VOP3_1_m <op, p.Outs, p.Ins64, opName#p.Asm64, pat64, opName,
2103                         p.HasModifiers>;
2104
2105   def _dpp : VOP1_DPP <op, opName, p>;
2106
2107   def _sdwa : VOP1_SDWA <op, opName, p>;
2108 }
2109
2110 multiclass VOP1Inst <vop1 op, string opName, VOPProfile P,
2111                      SDPatternOperator node = null_frag> : VOP1_Helper <
2112   op, opName, P, [],
2113   !if(P.HasModifiers,
2114       [(set P.DstVT:$vdst, (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0,
2115                                 i32:$src0_modifiers, i1:$clamp, i32:$omod))))],
2116       [(set P.DstVT:$vdst, (node P.Src0VT:$src0))])
2117 >;
2118
2119 multiclass VOP1InstSI <vop1 op, string opName, VOPProfile P,
2120                        SDPatternOperator node = null_frag> {
2121
2122   defm _e32 : VOP1SI_m <op, opName, P, []>;
2123
2124   defm _e64 : VOP3SI_1_m <op, P.Outs, P.Ins64, opName#P.Asm64,
2125     !if(P.HasModifiers,
2126       [(set P.DstVT:$vdst, (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0,
2127                                 i32:$src0_modifiers, i1:$clamp, i32:$omod))))],
2128       [(set P.DstVT:$vdst, (node P.Src0VT:$src0))]),
2129     opName, P.HasModifiers>;
2130 }
2131
2132 multiclass VOP2_Helper <vop2 op, string opName, VOPProfile p, list<dag> pat32,
2133                         list<dag> pat64, string revOp> {
2134
2135   defm _e32 : VOP2_m <op, opName, p, pat32, revOp>;
2136
2137   defm _e64 : VOP3_2_m <op, p.Outs, p.Ins64, opName#p.Asm64, pat64, opName,
2138                         revOp, p.HasModifiers>;
2139
2140   def _dpp : VOP2_DPP <op, opName, p>;
2141
2142   def _sdwa : VOP2_SDWA <op, opName, p>;
2143 }
2144
2145 multiclass VOP2Inst <vop2 op, string opName, VOPProfile P,
2146                      SDPatternOperator node = null_frag,
2147                      string revOp = opName> : VOP2_Helper <
2148   op, opName, P, [],
2149   !if(P.HasModifiers,
2150       [(set P.DstVT:$vdst,
2151            (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
2152                                       i1:$clamp, i32:$omod)),
2153                  (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
2154       [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1))]),
2155   revOp
2156 >;
2157
2158 multiclass VOP2InstSI <vop2 op, string opName, VOPProfile P,
2159                        SDPatternOperator node = null_frag,
2160                        string revOp = opName> {
2161
2162   defm _e32 : VOP2SI_m <op, opName, P, [], revOp>;
2163
2164   defm _e64 : VOP3SI_2_m <op, P.Outs, P.Ins64, opName#P.Asm64,
2165     !if(P.HasModifiers,
2166         [(set P.DstVT:$vdst,
2167              (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
2168                                         i1:$clamp, i32:$omod)),
2169                    (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
2170         [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1))]),
2171     opName, revOp, P.HasModifiers>;
2172 }
2173
2174 multiclass VOP2e_Helper <vop2 op, string opName, VOPProfile p,
2175                          list<dag> pat32, list<dag> pat64,
2176                          string revOp, bit useSGPRInput> {
2177
2178   let SchedRW = [Write32Bit] in {
2179     let Uses = !if(useSGPRInput, [VCC, EXEC], [EXEC]) in {
2180       defm _e32 : VOP2_m <op, opName, p, pat32, revOp>;
2181     }
2182
2183     defm _e64 : VOP3e_2_3_m <op, p.Outs64, p.Ins64, opName#p.Asm64, pat64,
2184                              opName, revOp, p.HasModifiers, useSGPRInput>;
2185   }
2186 }
2187
2188 multiclass VOP2eInst <vop2 op, string opName, VOPProfile P,
2189                       SDPatternOperator node = null_frag,
2190                       string revOp = opName> : VOP2e_Helper <
2191   op, opName, P, [],
2192   !if(P.HasModifiers,
2193       [(set P.DstVT:$vdst,
2194            (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
2195                                       i1:$clamp, i32:$omod)),
2196                  (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
2197       [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1))]),
2198   revOp, !eq(P.NumSrcArgs, 3)
2199 >;
2200
2201 multiclass VOP2b_Helper <vop2 op, string opName, VOPProfile p,
2202                          list<dag> pat32, list<dag> pat64,
2203                          string revOp, bit useSGPRInput> {
2204
2205   let SchedRW = [Write32Bit, WriteSALU] in {
2206     let Uses = !if(useSGPRInput, [VCC, EXEC], [EXEC]), Defs = [VCC] in {
2207       defm _e32 : VOP2_m <op, opName, p, pat32, revOp>;
2208     }
2209
2210     defm _e64 : VOP3b_2_3_m <op, p.Outs64, p.Ins64, opName#p.Asm64, pat64,
2211                              opName, revOp, p.HasModifiers, useSGPRInput>;
2212   }
2213 }
2214
2215 multiclass VOP2bInst <vop2 op, string opName, VOPProfile P,
2216                       SDPatternOperator node = null_frag,
2217                       string revOp = opName> : VOP2b_Helper <
2218   op, opName, P, [],
2219   !if(P.HasModifiers,
2220       [(set P.DstVT:$vdst,
2221            (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
2222                                       i1:$clamp, i32:$omod)),
2223                  (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
2224       [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1))]),
2225   revOp, !eq(P.NumSrcArgs, 3)
2226 >;
2227
2228 // A VOP2 instruction that is VOP3-only on VI.
2229 multiclass VOP2_VI3_Helper <vop23 op, string opName, VOPProfile p,
2230                             list<dag> pat32, list<dag> pat64, string revOp> {
2231
2232   defm _e32 : VOP2SI_m <op, opName, p, pat32, revOp>;
2233
2234   defm _e64 : VOP3_2_m <op, p.Outs, p.Ins64, opName#p.Asm64, pat64, opName,
2235                         revOp, p.HasModifiers>;
2236 }
2237
2238 multiclass VOP2_VI3_Inst <vop23 op, string opName, VOPProfile P,
2239                           SDPatternOperator node = null_frag,
2240                           string revOp = opName>
2241                           : VOP2_VI3_Helper <
2242   op, opName, P, [],
2243   !if(P.HasModifiers,
2244       [(set P.DstVT:$vdst,
2245            (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
2246                                       i1:$clamp, i32:$omod)),
2247                  (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
2248       [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1))]),
2249   revOp
2250 >;
2251
2252 multiclass VOP2MADK <vop2 op, string opName, VOPProfile P, list<dag> pattern = []> {
2253
2254   def "" : VOP2_Pseudo <P.Outs, P.Ins32, pattern, opName>;
2255
2256 let isCodeGenOnly = 0 in {
2257   def _si : VOP2Common <P.Outs, P.Ins32,
2258                         !strconcat(opName, P.Asm32), []>,
2259             SIMCInstr <opName#"_e32", SIEncodingFamily.SI>,
2260             VOP2_MADKe <op.SI> {
2261             let AssemblerPredicates = [isSICI];
2262             let DecoderNamespace = "SICI";
2263             let DisableDecoder = DisableSIDecoder;
2264             }
2265
2266   def _vi : VOP2Common <P.Outs, P.Ins32,
2267                         !strconcat(opName, P.Asm32), []>,
2268             SIMCInstr <opName#"_e32", SIEncodingFamily.VI>,
2269             VOP2_MADKe <op.VI> {
2270             let AssemblerPredicates = [isVI];
2271             let DecoderNamespace = "VI";
2272             let DisableDecoder = DisableVIDecoder;
2273             }
2274 } // End isCodeGenOnly = 0
2275 }
2276
2277 class VOPC_Pseudo <dag ins, list<dag> pattern, string opName> :
2278   VOPCCommon <ins, "", pattern>,
2279   VOP <opName>,
2280   SIMCInstr<opName#"_e32", SIEncodingFamily.NONE> {
2281   let isPseudo = 1;
2282   let isCodeGenOnly = 1;
2283 }
2284
2285 class VOPC_SDWA <vopc op, string opName, bit DefExec, VOPProfile p> :
2286     VOPC_SDWAe <op.VI>,
2287     VOP_SDWA <p.OutsSDWA, p.InsSDWA, opName#p.AsmSDWA, [], p.HasModifiers>,
2288     SDWADisableFields <p> {
2289   let Defs = !if(DefExec, [VCC, EXEC], [VCC]);
2290   let hasSideEffects = DefExec;
2291   let AsmMatchConverter = "cvtSdwaVOPC";
2292   let AssemblerPredicates = !if(p.HasExt, [isVI], [DisableInst]);
2293   let DecoderNamespace = "SDWA";
2294   let DisableDecoder = DisableVIDecoder;
2295 }
2296
2297 multiclass VOPC_m <vopc op, dag ins, string op_asm, list<dag> pattern,
2298                    string opName, bit DefExec, VOPProfile p,
2299                    list<SchedReadWrite> sched,
2300                    string revOpName = "", string asm = opName#"_e32 "#op_asm,
2301                    string alias_asm = opName#" "#op_asm> {
2302   def "" : VOPC_Pseudo <ins, pattern, opName>,
2303            VOP2_REV<revOpName#"_e32", !eq(revOpName, opName)> {
2304     let Defs = !if(DefExec, [VCC, EXEC], [VCC]);
2305     let SchedRW = sched;
2306     let isConvergent = DefExec;
2307   }
2308
2309   let AssemblerPredicates = [isSICI] in {
2310     def _si : VOPC<op.SI, ins, asm, []>,
2311               SIMCInstr <opName#"_e32", SIEncodingFamily.SI> {
2312       let Defs = !if(DefExec, [VCC, EXEC], [VCC]);
2313       let isConvergent = DefExec;
2314       let SchedRW = sched;
2315       let DecoderNamespace = "SICI";
2316       let DisableDecoder = DisableSIDecoder;
2317     }
2318
2319   } // End AssemblerPredicates = [isSICI]
2320
2321   let AssemblerPredicates = [isVI] in {
2322     def _vi : VOPC<op.VI, ins, asm, []>,
2323               SIMCInstr <opName#"_e32", SIEncodingFamily.VI> {
2324       let Defs = !if(DefExec, [VCC, EXEC], [VCC]);
2325       let isConvergent = DefExec;
2326       let SchedRW = sched;
2327       let DecoderNamespace = "VI";
2328       let DisableDecoder = DisableVIDecoder;
2329     }
2330
2331   } // End AssemblerPredicates = [isVI]
2332
2333   defm : SIInstAliasBuilder<alias_asm, p>;
2334 }
2335
2336 multiclass VOPC_Helper <vopc op, string opName, list<dag> pat32,
2337                         list<dag> pat64, bit DefExec, string revOp,
2338                         VOPProfile p, list<SchedReadWrite> sched> {
2339   defm _e32 : VOPC_m <op, p.Ins32, p.Asm32, pat32, opName, DefExec, p, sched,
2340                       revOp>;
2341
2342   defm _e64 : VOP3_C_m <op, (outs VOPDstS64:$sdst), p.Ins64, opName#p.Asm64, pat64,
2343                         opName, p.HasModifiers, DefExec, revOp, sched>;
2344
2345   def _sdwa : VOPC_SDWA <op, opName, DefExec, p>;
2346 }
2347
2348 // Special case for class instructions which only have modifiers on
2349 // the 1st source operand.
2350 multiclass VOPC_Class_Helper <vopc op, string opName, list<dag> pat32,
2351                               list<dag> pat64, bit DefExec, string revOp,
2352                               VOPProfile p, list<SchedReadWrite> sched> {
2353   defm _e32 : VOPC_m <op, p.Ins32, p.Asm32, pat32, opName, DefExec, p, sched>;
2354
2355   defm _e64 : VOP3_C_m <op, (outs VOPDstS64:$sdst), p.Ins64, opName#p.Asm64, pat64,
2356                         opName, p.HasModifiers, DefExec, revOp, sched>,
2357                         VOP3DisableModFields<1, 0, 0>;
2358
2359   def _sdwa : VOPC_SDWA <op, opName, DefExec, p> {
2360     let src1_fmodifiers = 0;
2361     let src1_imodifiers = ?;
2362   }
2363 }
2364
2365 multiclass VOPCInst <vopc op, string opName,
2366                      VOPProfile P, PatLeaf cond = COND_NULL,
2367                      string revOp = opName,
2368                      bit DefExec = 0,
2369                      list<SchedReadWrite> sched = [Write32Bit]> :
2370                      VOPC_Helper <
2371   op, opName, [],
2372   !if(P.HasModifiers,
2373       [(set i1:$sdst,
2374           (setcc (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
2375                                       i1:$clamp, i32:$omod)),
2376                  (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)),
2377                  cond))],
2378       [(set i1:$sdst, (setcc P.Src0VT:$src0, P.Src1VT:$src1, cond))]),
2379   DefExec, revOp, P, sched
2380 >;
2381
2382 multiclass VOPCClassInst <vopc op, string opName, VOPProfile P,
2383                      bit DefExec = 0,
2384                      list<SchedReadWrite> sched> : VOPC_Class_Helper <
2385   op, opName, [],
2386   !if(P.HasModifiers,
2387       [(set i1:$sdst,
2388           (AMDGPUfp_class (P.Src0VT (VOP3Mods0Clamp0OMod P.Src0VT:$src0, i32:$src0_modifiers)), P.Src1VT:$src1))],
2389       [(set i1:$sdst, (AMDGPUfp_class P.Src0VT:$src0, P.Src1VT:$src1))]),
2390   DefExec, opName, P, sched
2391 >;
2392
2393
2394 multiclass VOPC_F32 <vopc op, string opName, PatLeaf cond = COND_NULL, string revOp = opName> :
2395   VOPCInst <op, opName, VOPC_I1_F32_F32, cond, revOp>;
2396
2397 multiclass VOPC_F64 <vopc op, string opName, PatLeaf cond = COND_NULL, string revOp = opName> :
2398   VOPCInst <op, opName, VOPC_I1_F64_F64, cond, revOp, 0, [WriteDoubleAdd]>;
2399
2400 multiclass VOPC_I32 <vopc op, string opName, PatLeaf cond = COND_NULL, string revOp = opName> :
2401   VOPCInst <op, opName, VOPC_I1_I32_I32, cond, revOp>;
2402
2403 multiclass VOPC_I64 <vopc op, string opName, PatLeaf cond = COND_NULL, string revOp = opName> :
2404   VOPCInst <op, opName, VOPC_I1_I64_I64, cond, revOp, 0, [Write64Bit]>;
2405
2406
2407 multiclass VOPCX <vopc op, string opName, VOPProfile P,
2408                   PatLeaf cond = COND_NULL,
2409                   list<SchedReadWrite> sched,
2410                   string revOp = "">
2411   : VOPCInst <op, opName, P, cond, revOp, 1, sched>;
2412
2413 multiclass VOPCX_F32 <vopc op, string opName, string revOp = opName> :
2414   VOPCX <op, opName, VOPC_I1_F32_F32, COND_NULL, [Write32Bit], revOp>;
2415
2416 multiclass VOPCX_F64 <vopc op, string opName, string revOp = opName> :
2417   VOPCX <op, opName, VOPC_I1_F64_F64, COND_NULL, [WriteDoubleAdd], revOp>;
2418
2419 multiclass VOPCX_I32 <vopc op, string opName, string revOp = opName> :
2420   VOPCX <op, opName, VOPC_I1_I32_I32, COND_NULL, [Write32Bit], revOp>;
2421
2422 multiclass VOPCX_I64 <vopc op, string opName, string revOp = opName> :
2423   VOPCX <op, opName, VOPC_I1_I64_I64, COND_NULL, [Write64Bit], revOp>;
2424
2425
2426 multiclass VOPC_CLASS_F32 <vopc op, string opName> :
2427   VOPCClassInst <op, opName, VOPC_I1_F32_I32, 0, [Write32Bit]>;
2428
2429 multiclass VOPCX_CLASS_F32 <vopc op, string opName> :
2430   VOPCClassInst <op, opName, VOPC_I1_F32_I32, 1, [Write32Bit]>;
2431
2432 multiclass VOPC_CLASS_F64 <vopc op, string opName> :
2433   VOPCClassInst <op, opName, VOPC_I1_F64_I32, 0, [WriteDoubleAdd]>;
2434
2435 multiclass VOPCX_CLASS_F64 <vopc op, string opName> :
2436   VOPCClassInst <op, opName, VOPC_I1_F64_I32, 1, [WriteDoubleAdd]>;
2437
2438
2439 multiclass VOP3_Helper <vop3 op, string opName, dag outs, dag ins, string asm,
2440                         list<dag> pat, int NumSrcArgs, bit HasMods,
2441                         bit VOP3Only = 0> : VOP3_m <
2442     op, outs, ins, opName#" "#asm, pat, opName, NumSrcArgs, HasMods, VOP3Only
2443 >;
2444
2445 multiclass VOP3Inst <vop3 op, string opName, VOPProfile P,
2446                      SDPatternOperator node = null_frag, bit VOP3Only = 0> :
2447   VOP3_Helper <
2448   op, opName, (outs P.DstRC.RegClass:$vdst), P.Ins64, P.Asm64,
2449   !if(!eq(P.NumSrcArgs, 3),
2450     !if(P.HasModifiers,
2451         [(set P.DstVT:$vdst,
2452             (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
2453                                        i1:$clamp, i32:$omod)),
2454                   (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)),
2455                   (P.Src2VT (VOP3Mods P.Src2VT:$src2, i32:$src2_modifiers))))],
2456         [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1,
2457                                   P.Src2VT:$src2))]),
2458   !if(!eq(P.NumSrcArgs, 2),
2459     !if(P.HasModifiers,
2460         [(set P.DstVT:$vdst,
2461             (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
2462                                        i1:$clamp, i32:$omod)),
2463                   (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
2464         [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1))])
2465   /* P.NumSrcArgs == 1 */,
2466     !if(P.HasModifiers,
2467         [(set P.DstVT:$vdst,
2468             (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
2469                                        i1:$clamp, i32:$omod))))],
2470         [(set P.DstVT:$vdst, (node P.Src0VT:$src0))]))),
2471   P.NumSrcArgs, P.HasModifiers, VOP3Only
2472 >;
2473
2474 // Special case for v_div_fmas_{f32|f64}, since it seems to be the
2475 // only VOP instruction that implicitly reads VCC.
2476 multiclass VOP3_VCC_Inst <vop3 op, string opName,
2477                           VOPProfile P,
2478                           SDPatternOperator node = null_frag> : VOP3_Helper <
2479   op, opName,
2480   (outs P.DstRC.RegClass:$vdst),
2481   (ins FPInputMods:$src0_modifiers, P.Src0RC64:$src0,
2482        FPInputMods:$src1_modifiers, P.Src1RC64:$src1,
2483        FPInputMods:$src2_modifiers, P.Src2RC64:$src2,
2484        clampmod:$clamp,
2485        omod:$omod),
2486   "$vdst, $src0_modifiers, $src1_modifiers, $src2_modifiers"#"$clamp"#"$omod",
2487   [(set P.DstVT:$vdst,
2488             (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
2489                                        i1:$clamp, i32:$omod)),
2490                   (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)),
2491                   (P.Src2VT (VOP3Mods P.Src2VT:$src2, i32:$src2_modifiers)),
2492                   (i1 VCC)))],
2493   3, 1
2494 >;
2495
2496 multiclass VOP3bInst <vop op, string opName, VOPProfile P, list<dag> pattern = [], bit VOP3Only = 0> :
2497   VOP3b_2_3_m <
2498   op, P.Outs64, P.Ins64,
2499   opName#" "#P.Asm64, pattern,
2500   opName, "", 1, 1, VOP3Only
2501 >;
2502
2503 class Vop3ModPat<Instruction Inst, VOPProfile P, SDPatternOperator node> : Pat<
2504   (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i1:$clamp, i32:$omod)),
2505         (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)),
2506         (P.Src2VT (VOP3Mods P.Src2VT:$src2, i32:$src2_modifiers))),
2507   (Inst i32:$src0_modifiers, P.Src0VT:$src0,
2508         i32:$src1_modifiers, P.Src1VT:$src1,
2509         i32:$src2_modifiers, P.Src2VT:$src2,
2510         i1:$clamp,
2511         i32:$omod)>;
2512
2513 //===----------------------------------------------------------------------===//
2514 // Interpolation opcodes
2515 //===----------------------------------------------------------------------===//
2516
2517 class VINTRP_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
2518   VINTRPCommon <outs, ins, "", pattern>,
2519   SIMCInstr<opName, SIEncodingFamily.NONE> {
2520   let isPseudo = 1;
2521   let isCodeGenOnly = 1;
2522 }
2523
2524 class VINTRP_Real_si <bits <2> op, string opName, dag outs, dag ins,
2525                       string asm> :
2526   VINTRPCommon <outs, ins, asm, []>,
2527   VINTRPe <op>,
2528   SIMCInstr<opName, SIEncodingFamily.SI> {
2529   let AssemblerPredicate = SIAssemblerPredicate;
2530   let DecoderNamespace = "SICI";
2531   let DisableDecoder = DisableSIDecoder;
2532 }
2533
2534 class VINTRP_Real_vi <bits <2> op, string opName, dag outs, dag ins,
2535                       string asm> :
2536   VINTRPCommon <outs, ins, asm, []>,
2537   VINTRPe_vi <op>,
2538   SIMCInstr<opName, SIEncodingFamily.VI> {
2539   let AssemblerPredicate = VIAssemblerPredicate;
2540   let DecoderNamespace = "VI";
2541   let DisableDecoder = DisableVIDecoder;
2542 }
2543
2544 multiclass VINTRP_m <bits <2> op, dag outs, dag ins, string asm,
2545                      list<dag> pattern = []> {
2546   def "" : VINTRP_Pseudo <NAME, outs, ins, pattern>;
2547
2548   def _si : VINTRP_Real_si <op, NAME, outs, ins, asm>;
2549
2550   def _vi : VINTRP_Real_vi <op, NAME, outs, ins, asm>;
2551 }
2552
2553 //===----------------------------------------------------------------------===//
2554 // Vector I/O classes
2555 //===----------------------------------------------------------------------===//
2556
2557 class DS_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
2558   DS <outs, ins, "", pattern>,
2559   SIMCInstr <opName, SIEncodingFamily.NONE> {
2560   let isPseudo = 1;
2561   let isCodeGenOnly = 1;
2562 }
2563
2564 class DS_Real_si <bits<8> op, string opName, dag outs, dag ins, string asm> :
2565   DS <outs, ins, asm, []>,
2566   DSe <op>,
2567   SIMCInstr <opName, SIEncodingFamily.SI> {
2568   let isCodeGenOnly = 0;
2569   let AssemblerPredicates = [isSICI];
2570   let DecoderNamespace="SICI";
2571   let DisableDecoder = DisableSIDecoder;
2572 }
2573
2574 class DS_Real_vi <bits<8> op, string opName, dag outs, dag ins, string asm> :
2575   DS <outs, ins, asm, []>,
2576   DSe_vi <op>,
2577   SIMCInstr <opName, SIEncodingFamily.VI> {
2578   let isCodeGenOnly = 0;
2579   let AssemblerPredicates = [isVI];
2580   let DecoderNamespace="VI";
2581   let DisableDecoder = DisableVIDecoder;
2582 }
2583
2584 class DS_Off16_Real_si <bits<8> op, string opName, dag outs, dag ins, string asm> :
2585   DS_Real_si <op,opName, outs, ins, asm> {
2586
2587   // Single load interpret the 2 i8imm operands as a single i16 offset.
2588   bits<16> offset;
2589   let offset0 = offset{7-0};
2590   let offset1 = offset{15-8};
2591 }
2592
2593 class DS_Off16_Real_vi <bits<8> op, string opName, dag outs, dag ins, string asm> :
2594   DS_Real_vi <op, opName, outs, ins, asm> {
2595
2596   // Single load interpret the 2 i8imm operands as a single i16 offset.
2597   bits<16> offset;
2598   let offset0 = offset{7-0};
2599   let offset1 = offset{15-8};
2600 }
2601
2602 multiclass DS_1A_RET_ <dsop op, string opName, RegisterClass rc,
2603   dag outs = (outs rc:$vdst),
2604   dag ins = (ins VGPR_32:$addr, offset:$offset, gds:$gds),
2605   string asm = opName#" $vdst, $addr"#"$offset$gds"> {
2606
2607   def "" : DS_Pseudo <opName, outs, ins, []>;
2608
2609   let data0 = 0, data1 = 0 in {
2610     def _si : DS_Off16_Real_si <op.SI, opName, outs, ins, asm>;
2611     def _vi : DS_Off16_Real_vi <op.VI, opName, outs, ins, asm>;
2612   }
2613 }
2614
2615 // TODO: DS_1A_RET can be inherited from DS_1A_RET_ but its not working
2616 // for some reason. In fact we can remove this class if use dsop everywhere
2617 multiclass DS_1A_RET <bits<8> op, string opName, RegisterClass rc,
2618   dag outs = (outs rc:$vdst),
2619   dag ins = (ins VGPR_32:$addr, offset:$offset, gds:$gds),
2620   string asm = opName#" $vdst, $addr"#"$offset$gds"> {
2621
2622   def "" : DS_Pseudo <opName, outs, ins, []>;
2623
2624   let data0 = 0, data1 = 0 in {
2625     def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
2626     def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
2627   }
2628 }
2629
2630 multiclass DS_1A_Off8_RET <bits<8> op, string opName, RegisterClass rc,
2631   dag outs = (outs rc:$vdst),
2632   dag ins = (ins VGPR_32:$addr, offset0:$offset0, offset1:$offset1,
2633                  gds:$gds),
2634   string asm = opName#" $vdst, $addr"#"$offset0"#"$offset1$gds"> {
2635
2636   def "" : DS_Pseudo <opName, outs, ins, []>;
2637
2638   let data0 = 0, data1 = 0, AsmMatchConverter = "cvtDSOffset01" in {
2639     def _si : DS_Real_si <op, opName, outs, ins, asm>;
2640     def _vi : DS_Real_vi <op, opName, outs, ins, asm>;
2641   }
2642 }
2643
2644 multiclass DS_1A1D_NORET <bits<8> op, string opName, RegisterClass rc,
2645   dag outs = (outs),
2646   dag ins = (ins VGPR_32:$addr, rc:$data0, offset:$offset, gds:$gds),
2647   string asm = opName#" $addr, $data0"#"$offset$gds"> {
2648
2649   def "" : DS_Pseudo <opName, outs, ins, []>,
2650            AtomicNoRet<opName, 0>;
2651
2652   let data1 = 0, vdst = 0 in {
2653     def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
2654     def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
2655   }
2656 }
2657
2658 multiclass DS_1A_Off8_NORET <bits<8> op, string opName,
2659   dag outs = (outs),
2660   dag ins = (ins VGPR_32:$addr,
2661               offset0:$offset0, offset1:$offset1, gds:$gds),
2662   string asm = opName#" $addr $offset0"#"$offset1$gds"> {
2663
2664   def "" : DS_Pseudo <opName, outs, ins, []>;
2665
2666   let data0 = 0, data1 = 0, vdst = 0, AsmMatchConverter = "cvtDSOffset01" in {
2667     def _si : DS_Real_si <op, opName, outs, ins, asm>;
2668     def _vi : DS_Real_vi <op, opName, outs, ins, asm>;
2669   }
2670 }
2671
2672 multiclass DS_1A2D_Off8_NORET <bits<8> op, string opName, RegisterClass rc,
2673   dag outs = (outs),
2674   dag ins = (ins VGPR_32:$addr, rc:$data0, rc:$data1,
2675               offset0:$offset0, offset1:$offset1, gds:$gds),
2676   string asm = opName#" $addr, $data0, $data1$offset0$offset1$gds"> {
2677
2678   def "" : DS_Pseudo <opName, outs, ins, []>;
2679
2680   let vdst = 0, AsmMatchConverter = "cvtDSOffset01" in {
2681     def _si : DS_Real_si <op, opName, outs, ins, asm>;
2682     def _vi : DS_Real_vi <op, opName, outs, ins, asm>;
2683   }
2684 }
2685
2686 multiclass DS_1A1D_RET <bits<8> op, string opName, RegisterClass rc,
2687                         string noRetOp = "",
2688   dag outs = (outs rc:$vdst),
2689   dag ins = (ins VGPR_32:$addr, rc:$data0, offset:$offset, gds:$gds),
2690   string asm = opName#" $vdst, $addr, $data0"#"$offset$gds"> {
2691
2692   let hasPostISelHook = 1 in {
2693     def "" : DS_Pseudo <opName, outs, ins, []>,
2694              AtomicNoRet<noRetOp, 1>;
2695
2696     let data1 = 0 in {
2697       def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
2698       def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
2699     }
2700   }
2701 }
2702
2703 multiclass DS_1A1D_PERMUTE <bits<8> op, string opName, RegisterClass rc,
2704                             SDPatternOperator node = null_frag,
2705   dag outs = (outs rc:$vdst),
2706   dag ins = (ins VGPR_32:$addr, rc:$data0, offset:$offset),
2707   string asm = opName#" $vdst, $addr, $data0"#"$offset"> {
2708
2709   let mayLoad = 0, mayStore = 0, isConvergent = 1 in {
2710     def "" : DS_Pseudo <opName, outs, ins,
2711      [(set i32:$vdst,
2712          (node (DS1Addr1Offset i32:$addr, i16:$offset), i32:$data0))]>;
2713
2714     let data1 = 0, gds = 0  in {
2715       def "_vi" : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
2716     }
2717   }
2718 }
2719
2720 multiclass DS_1A2D_RET_m <bits<8> op, string opName, RegisterClass rc,
2721                           string noRetOp = "", dag ins,
2722   dag outs = (outs rc:$vdst),
2723   string asm = opName#" $vdst, $addr, $data0, $data1"#"$offset"#"$gds"> {
2724
2725   let hasPostISelHook = 1 in {
2726     def "" : DS_Pseudo <opName, outs, ins, []>,
2727              AtomicNoRet<noRetOp, 1>;
2728
2729     def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
2730     def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
2731   }
2732 }
2733
2734 multiclass DS_1A2D_RET <bits<8> op, string asm, RegisterClass rc,
2735                         string noRetOp = "", RegisterClass src = rc> :
2736   DS_1A2D_RET_m <op, asm, rc, noRetOp,
2737                  (ins VGPR_32:$addr, src:$data0, src:$data1,
2738                       offset:$offset, gds:$gds)
2739 >;
2740
2741 multiclass DS_1A2D_NORET <bits<8> op, string opName, RegisterClass rc,
2742                           string noRetOp = opName,
2743   dag outs = (outs),
2744   dag ins = (ins VGPR_32:$addr, rc:$data0, rc:$data1,
2745                  offset:$offset, gds:$gds),
2746   string asm = opName#" $addr, $data0, $data1"#"$offset"#"$gds"> {
2747
2748   def "" : DS_Pseudo <opName, outs, ins, []>,
2749            AtomicNoRet<noRetOp, 0>;
2750
2751   let vdst = 0 in {
2752     def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
2753     def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
2754   }
2755 }
2756
2757 multiclass DS_0A_RET <bits<8> op, string opName,
2758   dag outs = (outs VGPR_32:$vdst),
2759   dag ins = (ins offset:$offset, gds:$gds),
2760   string asm = opName#" $vdst"#"$offset"#"$gds"> {
2761
2762   let mayLoad = 1, mayStore = 1 in {
2763     def "" : DS_Pseudo <opName, outs, ins, []>;
2764
2765     let addr = 0, data0 = 0, data1 = 0 in {
2766       def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
2767       def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
2768     } // end addr = 0, data0 = 0, data1 = 0
2769   } // end mayLoad = 1, mayStore = 1
2770 }
2771
2772 multiclass DS_1A_RET_GDS <bits<8> op, string opName,
2773   dag outs = (outs VGPR_32:$vdst),
2774   dag ins = (ins VGPR_32:$addr, offset:$offset),
2775   string asm = opName#" $vdst, $addr"#"$offset gds"> {
2776
2777   def "" : DS_Pseudo <opName, outs, ins, []>;
2778
2779   let data0 = 0, data1 = 0, gds = 1 in {
2780     def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
2781     def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
2782   } // end data0 = 0, data1 = 0, gds = 1
2783 }
2784
2785 multiclass DS_1A_GDS <bits<8> op, string opName,
2786   dag outs = (outs),
2787   dag ins = (ins VGPR_32:$addr),
2788   string asm = opName#" $addr gds"> {
2789
2790   def "" : DS_Pseudo <opName, outs, ins, []>;
2791
2792   let vdst = 0, data0 = 0, data1 = 0, offset0 = 0, offset1 = 0, gds = 1 in {
2793     def _si : DS_Real_si <op, opName, outs, ins, asm>;
2794     def _vi : DS_Real_vi <op, opName, outs, ins, asm>;
2795   } // end vdst = 0, data = 0, data1 = 0, gds = 1
2796 }
2797
2798 multiclass DS_1A <bits<8> op, string opName,
2799   dag outs = (outs),
2800   dag ins = (ins VGPR_32:$addr, offset:$offset, gds:$gds),
2801   string asm = opName#" $addr"#"$offset"#"$gds"> {
2802
2803   let mayLoad = 1, mayStore = 1 in {
2804     def "" : DS_Pseudo <opName, outs, ins, []>;
2805
2806     let vdst = 0, data0 = 0, data1 = 0 in {
2807       def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
2808       def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
2809     } // let vdst = 0, data0 = 0, data1 = 0
2810   } // end mayLoad = 1, mayStore = 1
2811 }
2812
2813 //===----------------------------------------------------------------------===//
2814 // MTBUF classes
2815 //===----------------------------------------------------------------------===//
2816
2817 class MTBUF_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
2818   MTBUF <outs, ins, "", pattern>,
2819   SIMCInstr<opName, SIEncodingFamily.NONE> {
2820   let isPseudo = 1;
2821   let isCodeGenOnly = 1;
2822 }
2823
2824 class MTBUF_Real_si <bits<3> op, string opName, dag outs, dag ins,
2825                     string asm> :
2826   MTBUF <outs, ins, asm, []>,
2827   MTBUFe <op>,
2828   SIMCInstr<opName, SIEncodingFamily.SI> {
2829   let DecoderNamespace="SICI";
2830   let DisableDecoder = DisableSIDecoder;
2831 }
2832
2833 class MTBUF_Real_vi <bits<4> op, string opName, dag outs, dag ins, string asm> :
2834   MTBUF <outs, ins, asm, []>,
2835   MTBUFe_vi <op>,
2836   SIMCInstr <opName, SIEncodingFamily.VI> {
2837   let DecoderNamespace="VI";
2838   let DisableDecoder = DisableVIDecoder;
2839 }
2840
2841 multiclass MTBUF_m <bits<3> op, string opName, dag outs, dag ins, string asm,
2842                     list<dag> pattern> {
2843
2844   def "" : MTBUF_Pseudo <opName, outs, ins, pattern>;
2845
2846   def _si : MTBUF_Real_si <op, opName, outs, ins, asm>;
2847
2848   def _vi : MTBUF_Real_vi <{0, op{2}, op{1}, op{0}}, opName, outs, ins, asm>;
2849
2850 }
2851
2852 let mayStore = 1, mayLoad = 0 in {
2853
2854 multiclass MTBUF_Store_Helper <bits<3> op, string opName,
2855                                RegisterClass regClass> : MTBUF_m <
2856   op, opName, (outs),
2857   (ins regClass:$vdata, u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
2858    i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VGPR_32:$vaddr,
2859    SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SCSrc_32:$soffset),
2860   opName#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
2861         #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset", []
2862 >;
2863
2864 } // mayStore = 1, mayLoad = 0
2865
2866 let mayLoad = 1, mayStore = 0 in {
2867
2868 multiclass MTBUF_Load_Helper <bits<3> op, string opName,
2869                               RegisterClass regClass> : MTBUF_m <
2870   op, opName, (outs regClass:$dst),
2871   (ins u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
2872        i8imm:$dfmt, i8imm:$nfmt, VGPR_32:$vaddr, SReg_128:$srsrc,
2873        i1imm:$slc, i1imm:$tfe, SCSrc_32:$soffset),
2874   opName#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
2875         #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset", []
2876 >;
2877
2878 } // mayLoad = 1, mayStore = 0
2879
2880 //===----------------------------------------------------------------------===//
2881 // MUBUF classes
2882 //===----------------------------------------------------------------------===//
2883
2884 class mubuf <bits<7> si, bits<7> vi = si> {
2885   field bits<7> SI = si;
2886   field bits<7> VI = vi;
2887 }
2888
2889 let isCodeGenOnly = 0 in {
2890
2891 class MUBUF_si <bits<7> op, dag outs, dag ins, string asm, list<dag> pattern> :
2892   MUBUF <outs, ins, asm, pattern>, MUBUFe <op> {
2893   let lds  = 0;
2894 }
2895
2896 } // End let isCodeGenOnly = 0
2897
2898 class MUBUF_vi <bits<7> op, dag outs, dag ins, string asm, list<dag> pattern> :
2899   MUBUF <outs, ins, asm, pattern>, MUBUFe_vi <op> {
2900   let lds = 0;
2901 }
2902
2903 class MUBUFAddr64Table <bit is_addr64, string suffix = ""> {
2904   bit IsAddr64 = is_addr64;
2905   string OpName = NAME # suffix;
2906 }
2907
2908 class MUBUF_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
2909   MUBUF <outs, ins, "", pattern>,
2910   SIMCInstr<opName, SIEncodingFamily.NONE> {
2911   let isPseudo = 1;
2912   let isCodeGenOnly = 1;
2913
2914   // dummy fields, so that we can use let statements around multiclasses
2915   bits<1> offen;
2916   bits<1> idxen;
2917   bits<8> vaddr;
2918   bits<1> glc;
2919   bits<1> slc;
2920   bits<1> tfe;
2921   bits<8> soffset;
2922 }
2923
2924 class MUBUF_Real_si <mubuf op, string opName, dag outs, dag ins,
2925                      string asm> :
2926   MUBUF <outs, ins, asm, []>,
2927   MUBUFe <op.SI>,
2928   SIMCInstr<opName, SIEncodingFamily.SI> {
2929   let lds = 0;
2930   let AssemblerPredicate = SIAssemblerPredicate;
2931   let DecoderNamespace="SICI";
2932   let DisableDecoder = DisableSIDecoder;
2933 }
2934
2935 class MUBUF_Real_vi <mubuf op, string opName, dag outs, dag ins,
2936                      string asm> :
2937   MUBUF <outs, ins, asm, []>,
2938   MUBUFe_vi <op.VI>,
2939   SIMCInstr<opName, SIEncodingFamily.VI> {
2940   let lds = 0;
2941   let AssemblerPredicate = VIAssemblerPredicate;
2942   let DecoderNamespace="VI";
2943   let DisableDecoder = DisableVIDecoder;
2944 }
2945
2946 multiclass MUBUF_m <mubuf op, string opName, dag outs, dag ins, string asm,
2947                     list<dag> pattern> {
2948
2949   def "" : MUBUF_Pseudo <opName, outs, ins, pattern>,
2950            MUBUFAddr64Table <0>;
2951
2952   let DisableWQM = 1 in {
2953     def "_exact" : MUBUF_Pseudo <opName, outs, ins, []>;
2954   }
2955
2956   let addr64 = 0, isCodeGenOnly = 0 in {
2957     def _si : MUBUF_Real_si <op, opName, outs, ins, asm>;
2958   }
2959
2960   def _vi : MUBUF_Real_vi <op, opName, outs, ins, asm>;
2961 }
2962
2963 multiclass MUBUFAddr64_m <mubuf op, string opName, dag outs,
2964                           dag ins, string asm, list<dag> pattern> {
2965
2966   def "" : MUBUF_Pseudo <opName, outs, ins, pattern>,
2967            MUBUFAddr64Table <1>;
2968
2969   let addr64 = 1, isCodeGenOnly = 0 in {
2970     def _si : MUBUF_Real_si <op, opName, outs, ins, asm>;
2971   }
2972
2973   // There is no VI version. If the pseudo is selected, it should be lowered
2974   // for VI appropriately.
2975 }
2976
2977 multiclass MUBUFAtomicOffset_m <mubuf op, string opName, dag outs, dag ins,
2978                                 string asm, list<dag> pattern, bit is_return> {
2979
2980   def "" : MUBUF_Pseudo <opName, outs, ins, pattern>,
2981            MUBUFAddr64Table <0, !if(is_return, "_RTN", "")>,
2982            AtomicNoRet<NAME#"_OFFSET", is_return>;
2983
2984   let offen = 0, idxen = 0, tfe = 0, vaddr = 0 in {
2985     let addr64 = 0 in {
2986       def _si : MUBUF_Real_si <op, opName, outs, ins, asm>;
2987     }
2988
2989     def _vi : MUBUF_Real_vi <op, opName, outs, ins, asm>;
2990   }
2991 }
2992
2993 multiclass MUBUFAtomicAddr64_m <mubuf op, string opName, dag outs, dag ins,
2994                                 string asm, list<dag> pattern, bit is_return> {
2995
2996   def "" : MUBUF_Pseudo <opName, outs, ins, pattern>,
2997            MUBUFAddr64Table <1, !if(is_return, "_RTN", "")>,
2998            AtomicNoRet<NAME#"_ADDR64", is_return>;
2999
3000   let offen = 0, idxen = 0, addr64 = 1, tfe = 0 in {
3001     def _si : MUBUF_Real_si <op, opName, outs, ins, asm>;
3002   }
3003
3004   // There is no VI version. If the pseudo is selected, it should be lowered
3005   // for VI appropriately.
3006 }
3007
3008 multiclass MUBUFAtomicOther_m <mubuf op, string opName, dag outs, dag ins,
3009                                string asm, list<dag> pattern, bit is_return> {
3010
3011   def "" : MUBUF_Pseudo <opName, outs, ins, pattern>,
3012            AtomicNoRet<opName, is_return>;
3013
3014   let tfe = 0 in {
3015     let addr64 = 0 in {
3016       def _si : MUBUF_Real_si <op, opName, outs, ins, asm>;
3017     }
3018
3019     def _vi : MUBUF_Real_vi <op, opName, outs, ins, asm>;
3020   }
3021 }
3022
3023 multiclass MUBUF_Atomic <mubuf op, string name, RegisterClass rc,
3024                          ValueType vt, SDPatternOperator atomic> {
3025
3026   let mayStore = 1, mayLoad = 1, hasPostISelHook = 1, hasSideEffects = 1,
3027       DisableWQM = 1 in {
3028
3029     // No return variants
3030     let glc = 0, AsmMatchConverter = "cvtMubufAtomic" in {
3031
3032       defm _ADDR64 : MUBUFAtomicAddr64_m <
3033         op, name#"_addr64", (outs),
3034         (ins rc:$vdata, VReg_64:$vaddr, SReg_128:$srsrc,
3035              SCSrc_32:$soffset, offset:$offset, slc:$slc),
3036         name#" $vdata, $vaddr, $srsrc, $soffset addr64$offset$slc", [], 0
3037       >;
3038
3039       defm _OFFSET : MUBUFAtomicOffset_m <
3040         op, name#"_offset", (outs),
3041         (ins rc:$vdata, SReg_128:$srsrc, SCSrc_32:$soffset, offset:$offset,
3042              slc:$slc),
3043         name#" $vdata, off, $srsrc, $soffset$offset$slc", [], 0
3044       >;
3045
3046       let offen = 1, idxen = 0 in {
3047         defm _OFFEN : MUBUFAtomicOther_m <
3048           op, name#"_offen", (outs),
3049           (ins rc:$vdata, VGPR_32:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset,
3050                 offset:$offset, slc:$slc),
3051           name#" $vdata, $vaddr, $srsrc, $soffset offen$offset$slc", [], 0
3052         >;
3053       }
3054
3055       let offen = 0, idxen = 1 in {
3056         defm _IDXEN : MUBUFAtomicOther_m <
3057           op, name#"_idxen", (outs),
3058           (ins rc:$vdata, VGPR_32:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset,
3059                 offset:$offset, slc:$slc),
3060           name#" $vdata, $vaddr, $srsrc, $soffset idxen$offset$slc", [], 0
3061         >;
3062       }
3063
3064       let offen = 1, idxen = 1 in {
3065         defm _BOTHEN : MUBUFAtomicOther_m <
3066           op, name#"_bothen", (outs),
3067           (ins rc:$vdata, VReg_64:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset,
3068                 offset:$offset, slc:$slc),
3069           name#" $vdata, $vaddr, $srsrc, $soffset idxen offen$offset$slc",
3070           [], 0
3071         >;
3072       }
3073     } // glc = 0
3074
3075     // Variant that return values
3076     let glc = 1, Constraints = "$vdata = $vdata_in",
3077         AsmMatchConverter = "cvtMubufAtomicReturn",
3078         DisableEncoding = "$vdata_in"  in {
3079
3080       defm _RTN_ADDR64 : MUBUFAtomicAddr64_m <
3081         op, name#"_rtn_addr64", (outs rc:$vdata),
3082         (ins rc:$vdata_in, VReg_64:$vaddr, SReg_128:$srsrc,
3083              SCSrc_32:$soffset, offset:$offset, slc:$slc),
3084         name#" $vdata, $vaddr, $srsrc, $soffset addr64$offset glc$slc",
3085         [(set vt:$vdata,
3086          (atomic (MUBUFAddr64Atomic v4i32:$srsrc, i64:$vaddr, i32:$soffset,
3087                                     i16:$offset, i1:$slc), vt:$vdata_in))], 1
3088       >;
3089
3090       defm _RTN_OFFSET : MUBUFAtomicOffset_m <
3091         op, name#"_rtn_offset", (outs rc:$vdata),
3092         (ins rc:$vdata_in, SReg_128:$srsrc, SCSrc_32:$soffset,
3093              offset:$offset, slc:$slc),
3094         name#" $vdata, off, $srsrc, $soffset$offset glc$slc",
3095         [(set vt:$vdata,
3096          (atomic (MUBUFOffsetAtomic v4i32:$srsrc, i32:$soffset, i16:$offset,
3097                                     i1:$slc), vt:$vdata_in))], 1
3098       >;
3099
3100       let offen = 1, idxen = 0 in {
3101         defm _RTN_OFFEN : MUBUFAtomicOther_m <
3102           op, name#"_rtn_offen", (outs rc:$vdata),
3103           (ins rc:$vdata_in, VGPR_32:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset,
3104                 offset:$offset, slc:$slc),
3105           name#" $vdata, $vaddr, $srsrc, $soffset offen$offset glc$slc",
3106           [], 1
3107         >;
3108       }
3109
3110       let offen = 0, idxen = 1 in {
3111         defm _RTN_IDXEN : MUBUFAtomicOther_m <
3112           op, name#"_rtn_idxen", (outs rc:$vdata),
3113           (ins rc:$vdata_in, VGPR_32:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset,
3114                 offset:$offset, slc:$slc),
3115           name#" $vdata, $vaddr, $srsrc, $soffset idxen$offset glc$slc",
3116           [], 1
3117         >;
3118       }
3119
3120       let offen = 1, idxen = 1 in {
3121         defm _RTN_BOTHEN : MUBUFAtomicOther_m <
3122           op, name#"_rtn_bothen", (outs rc:$vdata),
3123           (ins rc:$vdata_in, VReg_64:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset,
3124                 offset:$offset, slc:$slc),
3125           name#" $vdata, $vaddr, $srsrc, $soffset idxen offen$offset glc$slc",
3126           [], 1
3127         >;
3128       }
3129     } // glc = 1
3130
3131   } // mayStore = 1, mayLoad = 1, hasPostISelHook = 1
3132 }
3133
3134 // FIXME: tfe can't be an operand because it requires a separate
3135 // opcode because it needs an N+1 register class dest register.
3136 multiclass MUBUF_Load_Helper <mubuf op, string name, RegisterClass regClass,
3137                               ValueType load_vt = i32,
3138                               SDPatternOperator ld = null_frag> {
3139
3140   let mayLoad = 1, mayStore = 0 in {
3141     let offen = 0, idxen = 0, vaddr = 0 in {
3142       defm _OFFSET : MUBUF_m <op, name#"_offset", (outs regClass:$vdata),
3143                            (ins SReg_128:$srsrc, SCSrc_32:$soffset,
3144                            offset:$offset, glc:$glc, slc:$slc, tfe:$tfe),
3145                            name#" $vdata, off, $srsrc, $soffset$offset$glc$slc$tfe",
3146                            [(set load_vt:$vdata, (ld (MUBUFOffset v4i32:$srsrc,
3147                                                      i32:$soffset, i16:$offset,
3148                                                      i1:$glc, i1:$slc, i1:$tfe)))]>;
3149     }
3150
3151     let offen = 1, idxen = 0  in {
3152       defm _OFFEN  : MUBUF_m <op, name#"_offen", (outs regClass:$vdata),
3153                            (ins VGPR_32:$vaddr, SReg_128:$srsrc,
3154                            SCSrc_32:$soffset, offset:$offset, glc:$glc, slc:$slc,
3155                            tfe:$tfe),
3156                            name#" $vdata, $vaddr, $srsrc, $soffset offen$offset$glc$slc$tfe", []>;
3157     }
3158
3159     let offen = 0, idxen = 1 in {
3160       defm _IDXEN  : MUBUF_m <op, name#"_idxen", (outs regClass:$vdata),
3161                            (ins VGPR_32:$vaddr, SReg_128:$srsrc,
3162                            SCSrc_32:$soffset, offset:$offset, glc:$glc,
3163                            slc:$slc, tfe:$tfe),
3164                            name#" $vdata, $vaddr, $srsrc, $soffset idxen$offset$glc$slc$tfe", []>;
3165     }
3166
3167     let offen = 1, idxen = 1 in {
3168       defm _BOTHEN : MUBUF_m <op, name#"_bothen", (outs regClass:$vdata),
3169                            (ins VReg_64:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset,
3170                            offset:$offset, glc:$glc, slc:$slc, tfe:$tfe),
3171                            name#" $vdata, $vaddr, $srsrc, $soffset idxen offen$offset$glc$slc$tfe", []>;
3172     }
3173
3174     let offen = 0, idxen = 0 in {
3175       defm _ADDR64 : MUBUFAddr64_m <op, name#"_addr64", (outs regClass:$vdata),
3176                            (ins VReg_64:$vaddr, SReg_128:$srsrc,
3177                                 SCSrc_32:$soffset, offset:$offset,
3178                                 glc:$glc, slc:$slc, tfe:$tfe),
3179                            name#" $vdata, $vaddr, $srsrc, $soffset addr64$offset$glc$slc$tfe",
3180                            [(set load_vt:$vdata, (ld (MUBUFAddr64 v4i32:$srsrc,
3181                                                   i64:$vaddr, i32:$soffset,
3182                                                   i16:$offset, i1:$glc, i1:$slc,
3183                                                   i1:$tfe)))]>;
3184     }
3185   }
3186 }
3187
3188 multiclass MUBUF_Store_Helper <mubuf op, string name, RegisterClass vdataClass,
3189                           ValueType store_vt = i32, SDPatternOperator st = null_frag> {
3190   let mayLoad = 0, mayStore = 1 in {
3191     let offen = 0, idxen = 0, vaddr = 0 in {
3192       defm _OFFSET : MUBUF_m <op, name#"_offset",(outs),
3193                               (ins vdataClass:$vdata, SReg_128:$srsrc, SCSrc_32:$soffset,
3194                               offset:$offset, glc:$glc, slc:$slc, tfe:$tfe),
3195                               name#" $vdata, off, $srsrc, $soffset$offset$glc$slc$tfe",
3196                               [(st store_vt:$vdata, (MUBUFOffset v4i32:$srsrc, i32:$soffset,
3197                                    i16:$offset, i1:$glc, i1:$slc, i1:$tfe))]>;
3198     } // offen = 0, idxen = 0, vaddr = 0
3199
3200     let offen = 1, idxen = 0  in {
3201       defm _OFFEN : MUBUF_m <op, name#"_offen", (outs),
3202                              (ins vdataClass:$vdata, VGPR_32:$vaddr, SReg_128:$srsrc,
3203                               SCSrc_32:$soffset, offset:$offset, glc:$glc,
3204                               slc:$slc, tfe:$tfe),
3205                              name#" $vdata, $vaddr, $srsrc, $soffset offen"#
3206                              "$offset$glc$slc$tfe", []>;
3207     } // end offen = 1, idxen = 0
3208
3209     let offen = 0, idxen = 1 in {
3210       defm _IDXEN  : MUBUF_m <op, name#"_idxen", (outs),
3211                            (ins vdataClass:$vdata, VGPR_32:$vaddr, SReg_128:$srsrc,
3212                            SCSrc_32:$soffset, offset:$offset, glc:$glc,
3213                            slc:$slc, tfe:$tfe),
3214                            name#" $vdata, $vaddr, $srsrc, $soffset idxen$offset$glc$slc$tfe", []>;
3215     }
3216
3217     let offen = 1, idxen = 1 in {
3218       defm _BOTHEN : MUBUF_m <op, name#"_bothen", (outs),
3219                            (ins vdataClass:$vdata, VReg_64:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset,
3220                            offset:$offset, glc:$glc, slc:$slc, tfe:$tfe),
3221                            name#" $vdata, $vaddr, $srsrc, $soffset idxen offen$offset$glc$slc$tfe", []>;
3222     }
3223
3224     let offen = 0, idxen = 0 in {
3225       defm _ADDR64 : MUBUFAddr64_m <op, name#"_addr64", (outs),
3226                                     (ins vdataClass:$vdata, VReg_64:$vaddr, SReg_128:$srsrc,
3227                                          SCSrc_32:$soffset,
3228                                          offset:$offset, glc:$glc, slc:$slc,
3229                                          tfe:$tfe),
3230                                     name#" $vdata, $vaddr, $srsrc, $soffset addr64"#
3231                                          "$offset$glc$slc$tfe",
3232                                     [(st store_vt:$vdata,
3233                                       (MUBUFAddr64 v4i32:$srsrc, i64:$vaddr,
3234                                                    i32:$soffset, i16:$offset,
3235                                                    i1:$glc, i1:$slc, i1:$tfe))]>;
3236     }
3237   } // End mayLoad = 0, mayStore = 1
3238 }
3239
3240 // For cache invalidation instructions.
3241 multiclass MUBUF_Invalidate <mubuf op, string opName, SDPatternOperator node> {
3242   let hasSideEffects = 1, mayStore = 1, AsmMatchConverter = "" in {
3243     def "" : MUBUF_Pseudo <opName, (outs), (ins), [(node)]>;
3244
3245     // Set everything to 0.
3246     let offset = 0, offen = 0, idxen = 0, glc = 0, vaddr = 0,
3247         vdata = 0, srsrc = 0, slc = 0, tfe = 0, soffset = 0 in {
3248       let addr64 = 0 in {
3249         def _si : MUBUF_Real_si <op, opName, (outs), (ins), opName>;
3250       }
3251
3252       def _vi : MUBUF_Real_vi <op, opName, (outs), (ins), opName>;
3253     }
3254   } // End hasSideEffects = 1, mayStore = 1, AsmMatchConverter = ""
3255 }
3256
3257 //===----------------------------------------------------------------------===//
3258 // FLAT classes
3259 //===----------------------------------------------------------------------===//
3260
3261 class flat <bits<7> ci, bits<7> vi = ci> {
3262   field bits<7> CI = ci;
3263   field bits<7> VI = vi;
3264 }
3265
3266 class FLAT_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
3267      FLAT <0, outs, ins, "", pattern>,
3268       SIMCInstr<opName, SIEncodingFamily.NONE> {
3269   let isPseudo = 1;
3270   let isCodeGenOnly = 1;
3271 }
3272
3273 class FLAT_Real_ci <bits<7> op, string opName, dag outs, dag ins, string asm> :
3274     FLAT <op, outs, ins, asm, []>,
3275     SIMCInstr<opName, SIEncodingFamily.SI> {
3276   let AssemblerPredicate = isCIOnly;
3277   let DecoderNamespace="CI";
3278 }
3279
3280 class FLAT_Real_vi <bits<7> op, string opName, dag outs, dag ins, string asm> :
3281     FLAT <op, outs, ins, asm, []>,
3282     SIMCInstr<opName, SIEncodingFamily.VI> {
3283   let AssemblerPredicate = VIAssemblerPredicate;
3284   let DecoderNamespace="VI";
3285   let DisableDecoder = DisableVIDecoder;
3286 }
3287
3288 multiclass FLAT_AtomicRet_m <flat op, dag outs, dag ins, string asm,
3289                    list<dag> pattern> {
3290   def "" : FLAT_Pseudo <NAME#"_RTN", outs, ins, pattern>,
3291                AtomicNoRet <NAME, 1>;
3292
3293   def _ci : FLAT_Real_ci <op.CI, NAME#"_RTN", outs, ins, asm>;
3294
3295   def _vi : FLAT_Real_vi <op.VI, NAME#"_RTN", outs, ins, asm>;
3296 }
3297
3298 multiclass FLAT_Load_Helper <flat op, string asm_name,
3299     RegisterClass regClass,
3300     dag outs = (outs regClass:$vdst),
3301     dag ins = (ins VReg_64:$addr, glc:$glc, slc:$slc, tfe:$tfe),
3302     string asm = asm_name#" $vdst, $addr$glc$slc$tfe"> {
3303
3304   let data = 0, mayLoad = 1 in {
3305
3306     def "" : FLAT_Pseudo <NAME, outs, ins, []>;
3307
3308     def _ci : FLAT_Real_ci <op.CI, NAME, outs, ins, asm>;
3309
3310     def _vi : FLAT_Real_vi <op.VI, NAME, outs, ins, asm>;
3311   }
3312 }
3313
3314 multiclass FLAT_Store_Helper <flat op, string asm_name,
3315     RegisterClass vdataClass,
3316     dag outs = (outs),
3317     dag ins = (ins VReg_64:$addr, vdataClass:$data, glc:$glc,
3318                    slc:$slc, tfe:$tfe),
3319     string asm = asm_name#" $addr, $data$glc$slc$tfe"> {
3320
3321   let mayLoad = 0, mayStore = 1, vdst = 0 in {
3322
3323     def "" : FLAT_Pseudo <NAME, outs, ins, []>;
3324
3325     def _ci : FLAT_Real_ci <op.CI, NAME, outs, ins, asm>;
3326
3327     def _vi : FLAT_Real_vi <op.VI, NAME, outs, ins, asm>;
3328   }
3329 }
3330
3331 multiclass FLAT_ATOMIC <flat op, string asm_name, RegisterClass vdst_rc,
3332     ValueType vt, SDPatternOperator atomic = null_frag,
3333     ValueType data_vt = vt,
3334     RegisterClass data_rc = vdst_rc,
3335     string asm_noret = asm_name#" $addr, $data"#"$slc"#"$tfe"> {
3336
3337   let mayLoad = 1, mayStore = 1, glc = 0, vdst = 0 in {
3338     def "" : FLAT_Pseudo <NAME, (outs),
3339                           (ins VReg_64:$addr, data_rc:$data,
3340                                slc:$slc, tfe:$tfe), []>,
3341              AtomicNoRet <NAME, 0>;
3342
3343     def _ci : FLAT_Real_ci <op.CI, NAME, (outs),
3344                             (ins VReg_64:$addr, data_rc:$data,
3345                                  slc:$slc, tfe:$tfe),
3346                             asm_noret>;
3347
3348     def _vi : FLAT_Real_vi <op.VI, NAME, (outs),
3349                             (ins VReg_64:$addr, data_rc:$data,
3350                                  slc:$slc, tfe:$tfe),
3351                             asm_noret>;
3352   }
3353
3354   let glc = 1, hasPostISelHook = 1 in {
3355     defm _RTN : FLAT_AtomicRet_m <
3356       op, (outs vdst_rc:$vdst),
3357       (ins VReg_64:$addr, data_rc:$data, slc:$slc, tfe:$tfe),
3358       asm_name#" $vdst, $addr, $data glc$slc$tfe",
3359       [(set vt:$vdst,
3360          (atomic (FLATAtomic i64:$addr, i1:$slc, i1:$tfe), data_vt:$data))]
3361     >;
3362   }
3363 }
3364
3365 class MIMG_Mask <string op, int channels> {
3366   string Op = op;
3367   int Channels = channels;
3368 }
3369
3370 class mimg <bits<7> si, bits<7> vi = si> {
3371   field bits<7> SI = si;
3372   field bits<7> VI = vi;
3373 }
3374
3375 class MIMG_Helper <dag outs, dag ins, string asm,
3376                    string dns=""> : MIMG<outs, ins, asm,[]> {
3377   let mayLoad = 1;
3378   let mayStore = 0;
3379   let hasPostISelHook = 1;
3380   let DecoderNamespace = dns;
3381   let isAsmParserOnly = !if(!eq(dns,""), 1, 0);
3382   let AsmMatchConverter = "cvtMIMG";
3383 }
3384
3385 class MIMG_NoSampler_Helper <bits<7> op, string asm,
3386                              RegisterClass dst_rc,
3387                              RegisterClass addr_rc,
3388                              string dns=""> : MIMG_Helper <
3389   (outs dst_rc:$vdata),
3390   (ins addr_rc:$vaddr, SReg_256:$srsrc,
3391        dmask:$dmask, unorm:$unorm, glc:$glc, slc:$slc,
3392        r128:$r128, tfe:$tfe, lwe:$lwe, da:$da),
3393   asm#" $vdata, $vaddr, $srsrc$dmask$unorm$glc$slc$r128$tfe$lwe$da",
3394   dns>, MIMGe<op> {
3395   let ssamp = 0;
3396 }
3397
3398 multiclass MIMG_NoSampler_Src_Helper <bits<7> op, string asm,
3399                                       RegisterClass dst_rc,
3400                                       int channels> {
3401   def _V1 : MIMG_NoSampler_Helper <op, asm, dst_rc, VGPR_32,
3402                                    !if(!eq(channels, 1), "AMDGPU", "")>,
3403             MIMG_Mask<asm#"_V1", channels>;
3404   def _V2 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_64>,
3405             MIMG_Mask<asm#"_V2", channels>;
3406   def _V4 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_128>,
3407             MIMG_Mask<asm#"_V4", channels>;
3408 }
3409
3410 multiclass MIMG_NoSampler <bits<7> op, string asm> {
3411   defm _V1 : MIMG_NoSampler_Src_Helper <op, asm, VGPR_32, 1>;
3412   defm _V2 : MIMG_NoSampler_Src_Helper <op, asm, VReg_64, 2>;
3413   defm _V3 : MIMG_NoSampler_Src_Helper <op, asm, VReg_96, 3>;
3414   defm _V4 : MIMG_NoSampler_Src_Helper <op, asm, VReg_128, 4>;
3415 }
3416
3417 class MIMG_Store_Helper <bits<7> op, string asm,
3418                          RegisterClass data_rc,
3419                          RegisterClass addr_rc> : MIMG_Helper <
3420   (outs),
3421   (ins data_rc:$vdata, addr_rc:$vaddr, SReg_256:$srsrc,
3422        dmask:$dmask, unorm:$unorm, glc:$glc, slc:$slc,
3423        r128:$r128, tfe:$tfe, lwe:$lwe, da:$da),
3424   asm#" $vdata, $vaddr, $srsrc$dmask$unorm$glc$slc$r128$tfe$lwe$da"
3425      >, MIMGe<op> {
3426   let ssamp = 0;
3427   let mayLoad = 1; // TableGen requires this for matching with the intrinsics
3428   let mayStore = 1;
3429   let hasSideEffects = 1;
3430   let hasPostISelHook = 0;
3431   let DisableWQM = 1;
3432 }
3433
3434 multiclass MIMG_Store_Addr_Helper <bits<7> op, string asm,
3435                                   RegisterClass data_rc,
3436                                   int channels> {
3437   def _V1 : MIMG_Store_Helper <op, asm, data_rc, VGPR_32>,
3438             MIMG_Mask<asm#"_V1", channels>;
3439   def _V2 : MIMG_Store_Helper <op, asm, data_rc, VReg_64>,
3440             MIMG_Mask<asm#"_V2", channels>;
3441   def _V4 : MIMG_Store_Helper <op, asm, data_rc, VReg_128>,
3442             MIMG_Mask<asm#"_V4", channels>;
3443 }
3444
3445 multiclass MIMG_Store <bits<7> op, string asm> {
3446   defm _V1 : MIMG_Store_Addr_Helper <op, asm, VGPR_32, 1>;
3447   defm _V2 : MIMG_Store_Addr_Helper <op, asm, VReg_64, 2>;
3448   defm _V3 : MIMG_Store_Addr_Helper <op, asm, VReg_96, 3>;
3449   defm _V4 : MIMG_Store_Addr_Helper <op, asm, VReg_128, 4>;
3450 }
3451
3452 class MIMG_Atomic_Helper <string asm, RegisterClass data_rc,
3453                           RegisterClass addr_rc> : MIMG_Helper <
3454     (outs data_rc:$vdst),
3455     (ins data_rc:$vdata, addr_rc:$vaddr, SReg_256:$srsrc,
3456          dmask:$dmask, unorm:$unorm, glc:$glc, slc:$slc,
3457          r128:$r128, tfe:$tfe, lwe:$lwe, da:$da),
3458     asm#" $vdst, $vaddr, $srsrc$dmask$unorm$glc$slc$r128$tfe$lwe$da"
3459   > {
3460   let mayStore = 1;
3461   let hasSideEffects = 1;
3462   let hasPostISelHook = 0;
3463   let DisableWQM = 1;
3464   let Constraints = "$vdst = $vdata";
3465   let AsmMatchConverter = "cvtMIMGAtomic";
3466 }
3467
3468 class MIMG_Atomic_Real_si<mimg op, string name, string asm,
3469   RegisterClass data_rc, RegisterClass addr_rc> :
3470   MIMG_Atomic_Helper<asm, data_rc, addr_rc>,
3471   SIMCInstr<name, SIEncodingFamily.SI>,
3472   MIMGe<op.SI> {
3473   let isCodeGenOnly = 0;
3474   let AssemblerPredicates = [isSICI];
3475   let DecoderNamespace = "SICI";
3476   let DisableDecoder = DisableSIDecoder;
3477 }
3478
3479 class MIMG_Atomic_Real_vi<mimg op, string name, string asm,
3480   RegisterClass data_rc, RegisterClass addr_rc> :
3481   MIMG_Atomic_Helper<asm, data_rc, addr_rc>,
3482   SIMCInstr<name, SIEncodingFamily.VI>,
3483   MIMGe<op.VI> {
3484   let isCodeGenOnly = 0;
3485   let AssemblerPredicates = [isVI];
3486   let DecoderNamespace = "VI";
3487   let DisableDecoder = DisableVIDecoder;
3488 }
3489
3490 multiclass MIMG_Atomic_Helper_m <mimg op, string name, string asm,
3491                                  RegisterClass data_rc, RegisterClass addr_rc> {
3492   let isPseudo = 1, isCodeGenOnly = 1 in {
3493     def "" : MIMG_Atomic_Helper<asm, data_rc, addr_rc>,
3494              SIMCInstr<name, SIEncodingFamily.NONE>;
3495   }
3496
3497   let ssamp = 0 in {
3498     def _si : MIMG_Atomic_Real_si<op, name, asm, data_rc, addr_rc>;
3499
3500     def _vi : MIMG_Atomic_Real_vi<op, name, asm, data_rc, addr_rc>;
3501   }
3502 }
3503
3504 multiclass MIMG_Atomic <mimg op, string asm, RegisterClass data_rc = VGPR_32> {
3505   defm _V1 : MIMG_Atomic_Helper_m <op, asm # "_V1", asm, data_rc, VGPR_32>;
3506   defm _V2 : MIMG_Atomic_Helper_m <op, asm # "_V2", asm, data_rc, VReg_64>;
3507   defm _V4 : MIMG_Atomic_Helper_m <op, asm # "_V3", asm, data_rc, VReg_128>;
3508 }
3509
3510 class MIMG_Sampler_Helper <bits<7> op, string asm,
3511                            RegisterClass dst_rc,
3512                            RegisterClass src_rc,
3513                            int wqm,
3514                            string dns=""> : MIMG_Helper <
3515   (outs dst_rc:$vdata),
3516   (ins src_rc:$vaddr, SReg_256:$srsrc, SReg_128:$ssamp,
3517        dmask:$dmask, unorm:$unorm, glc:$glc, slc:$slc,
3518        r128:$r128, tfe:$tfe, lwe:$lwe, da:$da),
3519   asm#" $vdata, $vaddr, $srsrc, $ssamp$dmask$unorm$glc$slc$r128$tfe$lwe$da",
3520   dns>, MIMGe<op> {
3521   let WQM = wqm;
3522 }
3523
3524 multiclass MIMG_Sampler_Src_Helper <bits<7> op, string asm,
3525                                     RegisterClass dst_rc,
3526                                     int channels, int wqm> {
3527   def _V1 : MIMG_Sampler_Helper <op, asm, dst_rc, VGPR_32, wqm,
3528                                  !if(!eq(channels, 1), "AMDGPU", "")>,
3529             MIMG_Mask<asm#"_V1", channels>;
3530   def _V2 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_64, wqm>,
3531             MIMG_Mask<asm#"_V2", channels>;
3532   def _V4 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_128, wqm>,
3533             MIMG_Mask<asm#"_V4", channels>;
3534   def _V8 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_256, wqm>,
3535             MIMG_Mask<asm#"_V8", channels>;
3536   def _V16 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_512, wqm>,
3537             MIMG_Mask<asm#"_V16", channels>;
3538 }
3539
3540 multiclass MIMG_Sampler <bits<7> op, string asm, int wqm=0> {
3541   defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VGPR_32, 1, wqm>;
3542   defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2, wqm>;
3543   defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3, wqm>;
3544   defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4, wqm>;
3545 }
3546
3547 multiclass MIMG_Sampler_WQM <bits<7> op, string asm> : MIMG_Sampler<op, asm, 1>;
3548
3549 class MIMG_Gather_Helper <bits<7> op, string asm,
3550                           RegisterClass dst_rc,
3551                           RegisterClass src_rc, int wqm> : MIMG <
3552   (outs dst_rc:$vdata),
3553   (ins src_rc:$vaddr, SReg_256:$srsrc, SReg_128:$ssamp,
3554        dmask:$dmask, unorm:$unorm, glc:$glc, slc:$slc,
3555        r128:$r128, tfe:$tfe, lwe:$lwe, da:$da),
3556   asm#" $vdata, $vaddr, $srsrc, $ssamp$dmask$unorm$glc$slc$r128$tfe$lwe$da",
3557   []>, MIMGe<op> {
3558   let mayLoad = 1;
3559   let mayStore = 0;
3560
3561   // DMASK was repurposed for GATHER4. 4 components are always
3562   // returned and DMASK works like a swizzle - it selects
3563   // the component to fetch. The only useful DMASK values are
3564   // 1=red, 2=green, 4=blue, 8=alpha. (e.g. 1 returns
3565   // (red,red,red,red) etc.) The ISA document doesn't mention
3566   // this.
3567   // Therefore, disable all code which updates DMASK by setting this:
3568   let Gather4 = 1;
3569   let hasPostISelHook = 0;
3570   let WQM = wqm;
3571
3572   let isAsmParserOnly = 1; // TBD: fix it later
3573 }
3574
3575 multiclass MIMG_Gather_Src_Helper <bits<7> op, string asm,
3576                                     RegisterClass dst_rc,
3577                                     int channels, int wqm> {
3578   def _V1 : MIMG_Gather_Helper <op, asm, dst_rc, VGPR_32, wqm>,
3579             MIMG_Mask<asm#"_V1", channels>;
3580   def _V2 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_64, wqm>,
3581             MIMG_Mask<asm#"_V2", channels>;
3582   def _V4 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_128, wqm>,
3583             MIMG_Mask<asm#"_V4", channels>;
3584   def _V8 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_256, wqm>,
3585             MIMG_Mask<asm#"_V8", channels>;
3586   def _V16 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_512, wqm>,
3587             MIMG_Mask<asm#"_V16", channels>;
3588 }
3589
3590 multiclass MIMG_Gather <bits<7> op, string asm, int wqm=0> {
3591   defm _V1 : MIMG_Gather_Src_Helper<op, asm, VGPR_32, 1, wqm>;
3592   defm _V2 : MIMG_Gather_Src_Helper<op, asm, VReg_64, 2, wqm>;
3593   defm _V3 : MIMG_Gather_Src_Helper<op, asm, VReg_96, 3, wqm>;
3594   defm _V4 : MIMG_Gather_Src_Helper<op, asm, VReg_128, 4, wqm>;
3595 }
3596
3597 multiclass MIMG_Gather_WQM <bits<7> op, string asm> : MIMG_Gather<op, asm, 1>;
3598
3599 //===----------------------------------------------------------------------===//
3600 // Vector instruction mappings
3601 //===----------------------------------------------------------------------===//
3602
3603 // Maps an opcode in e32 form to its e64 equivalent
3604 def getVOPe64 : InstrMapping {
3605   let FilterClass = "VOP";
3606   let RowFields = ["OpName"];
3607   let ColFields = ["Size"];
3608   let KeyCol = ["4"];
3609   let ValueCols = [["8"]];
3610 }
3611
3612 // Maps an opcode in e64 form to its e32 equivalent
3613 def getVOPe32 : InstrMapping {
3614   let FilterClass = "VOP";
3615   let RowFields = ["OpName"];
3616   let ColFields = ["Size"];
3617   let KeyCol = ["8"];
3618   let ValueCols = [["4"]];
3619 }
3620
3621 def getMaskedMIMGOp : InstrMapping {
3622   let FilterClass = "MIMG_Mask";
3623   let RowFields = ["Op"];
3624   let ColFields = ["Channels"];
3625   let KeyCol = ["4"];
3626   let ValueCols = [["1"], ["2"], ["3"] ];
3627 }
3628
3629 // Maps an commuted opcode to its original version
3630 def getCommuteOrig : InstrMapping {
3631   let FilterClass = "VOP2_REV";
3632   let RowFields = ["RevOp"];
3633   let ColFields = ["IsOrig"];
3634   let KeyCol = ["0"];
3635   let ValueCols = [["1"]];
3636 }
3637
3638 // Maps an original opcode to its commuted version
3639 def getCommuteRev : InstrMapping {
3640   let FilterClass = "VOP2_REV";
3641   let RowFields = ["RevOp"];
3642   let ColFields = ["IsOrig"];
3643   let KeyCol = ["1"];
3644   let ValueCols = [["0"]];
3645 }
3646
3647 def getCommuteCmpOrig : InstrMapping {
3648   let FilterClass = "VOP2_REV";
3649   let RowFields = ["RevOp"];
3650   let ColFields = ["IsOrig"];
3651   let KeyCol = ["0"];
3652   let ValueCols = [["1"]];
3653 }
3654
3655 // Maps an original opcode to its commuted version
3656 def getCommuteCmpRev : InstrMapping {
3657   let FilterClass = "VOP2_REV";
3658   let RowFields = ["RevOp"];
3659   let ColFields = ["IsOrig"];
3660   let KeyCol = ["1"];
3661   let ValueCols = [["0"]];
3662 }
3663
3664
3665 def getMCOpcodeGen : InstrMapping {
3666   let FilterClass = "SIMCInstr";
3667   let RowFields = ["PseudoInstr"];
3668   let ColFields = ["Subtarget"];
3669   let KeyCol = [!cast<string>(SIEncodingFamily.NONE)];
3670   let ValueCols = [[!cast<string>(SIEncodingFamily.SI)],
3671                    [!cast<string>(SIEncodingFamily.VI)]];
3672 }
3673
3674 def getAddr64Inst : InstrMapping {
3675   let FilterClass = "MUBUFAddr64Table";
3676   let RowFields = ["OpName"];
3677   let ColFields = ["IsAddr64"];
3678   let KeyCol = ["0"];
3679   let ValueCols = [["1"]];
3680 }
3681
3682 // Maps an atomic opcode to its version with a return value.
3683 def getAtomicRetOp : InstrMapping {
3684   let FilterClass = "AtomicNoRet";
3685   let RowFields = ["NoRetOp"];
3686   let ColFields = ["IsRet"];
3687   let KeyCol = ["0"];
3688   let ValueCols = [["1"]];
3689 }
3690
3691 // Maps an atomic opcode to its returnless version.
3692 def getAtomicNoRetOp : InstrMapping {
3693   let FilterClass = "AtomicNoRet";
3694   let RowFields = ["NoRetOp"];
3695   let ColFields = ["IsRet"];
3696   let KeyCol = ["1"];
3697   let ValueCols = [["0"]];
3698 }
3699
3700 include "SIInstructions.td"
3701 include "CIInstructions.td"
3702 include "VIInstructions.td"