• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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//===----------------------------------------------------------------------===//
9def isCI : Predicate<"Subtarget->getGeneration() "
10                      ">= SISubtarget::SEA_ISLANDS">;
11def isCIOnly : Predicate<"Subtarget->getGeneration() =="
12                         "SISubtarget::SEA_ISLANDS">,
13  AssemblerPredicate <"FeatureSeaIslands">;
14
15def DisableInst : Predicate <"false">, AssemblerPredicate<"FeatureDisable">;
16
17class vop {
18  field bits<9> SI3;
19  field bits<10> VI3;
20}
21
22class 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
30class 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
38class 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
48class vop23 <bits<6> si, bits<10> vi> : vop2 <si> {
49  let VI3 = vi;
50}
51
52class vop3 <bits<9> si, bits<10> vi = {0, si}> : vop {
53  let SI3 = si;
54  let VI3 = vi;
55}
56
57class sop1 <bits<8> si, bits<8> vi = si> {
58  field bits<8> SI = si;
59  field bits<8> VI = vi;
60}
61
62class sop2 <bits<7> si, bits<7> vi = si> {
63  field bits<7> SI = si;
64  field bits<7> VI = vi;
65}
66
67class sopk <bits<5> si, bits<5> vi = si> {
68  field bits<5> SI = si;
69  field bits<5> VI = vi;
70}
71
72class 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
81class 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
88def SIEncodingFamily {
89  int NONE = -1;
90  int SI = 0;
91  int VI = 1;
92}
93
94//===----------------------------------------------------------------------===//
95// SI DAG Nodes
96//===----------------------------------------------------------------------===//
97
98def SIload_constant : SDNode<"AMDGPUISD::LOAD_CONSTANT",
99  SDTypeProfile<1, 2, [SDTCisVT<0, f32>, SDTCisVT<1, v4i32>, SDTCisVT<2, i32>]>,
100                      [SDNPMayLoad, SDNPMemOperand]
101>;
102
103def SIatomic_inc : SDNode<"AMDGPUISD::ATOMIC_INC", SDTAtomic2,
104  [SDNPMayLoad, SDNPMayStore, SDNPMemOperand, SDNPHasChain]
105>;
106
107def SIatomic_dec : SDNode<"AMDGPUISD::ATOMIC_DEC", SDTAtomic2,
108  [SDNPMayLoad, SDNPMayStore, SDNPMemOperand, SDNPHasChain]
109>;
110
111def 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
130def 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
135class SDSample<string opcode> : SDNode <opcode,
136  SDTypeProfile<1, 4, [SDTCisVT<0, v4f32>, SDTCisVT<2, v8i32>,
137                       SDTCisVT<3, v4i32>, SDTCisVT<4, i32>]>
138>;
139
140def SIsample : SDSample<"AMDGPUISD::SAMPLE">;
141def SIsampleb : SDSample<"AMDGPUISD::SAMPLEB">;
142def SIsampled : SDSample<"AMDGPUISD::SAMPLED">;
143def SIsamplel : SDSample<"AMDGPUISD::SAMPLEL">;
144
145def 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
153class 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
161def flat_load : flat_ld <load>;
162def atomic_flat_load : flat_ld<atomic_load>;
163def flat_az_extloadi8 : flat_ld <az_extloadi8>;
164def flat_sextloadi8 : flat_ld <sextloadi8>;
165def flat_az_extloadi16 : flat_ld <az_extloadi16>;
166def flat_sextloadi16 : flat_ld <sextloadi16>;
167
168class 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
175def flat_store: flat_st <store>;
176def atomic_flat_store: flat_st <atomic_store>;
177def flat_truncstorei8 : flat_st <truncstorei8>;
178def flat_truncstorei16 : flat_st <truncstorei16>;
179
180class 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
188def mubuf_load : MubufLoad <load>;
189def mubuf_az_extloadi8 : MubufLoad <az_extloadi8>;
190def mubuf_sextloadi8 : MubufLoad <sextloadi8>;
191def mubuf_az_extloadi16 : MubufLoad <az_extloadi16>;
192def mubuf_sextloadi16 : MubufLoad <sextloadi16>;
193
194def mubuf_load_atomic : MubufLoad <atomic_load>;
195
196def 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
207def atomic_inc_global : global_binary_atomic_op<SIatomic_inc>;
208def atomic_dec_global : global_binary_atomic_op<SIatomic_dec>;
209
210def atomic_inc_flat : flat_binary_atomic_op<SIatomic_inc>;
211def 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
218def SIld_local : SDNode <"ISD::LOAD", SDTLoad,
219  [SDNPHasChain, SDNPMayLoad, SDNPMemOperand, SDNPInGlue]
220>;
221
222def si_ld_local : PatFrag <(ops node:$ptr), (SIld_local node:$ptr), [{
223  return cast<LoadSDNode>(N)->getAddressSpace() == AMDGPUAS::LOCAL_ADDRESS;
224}]>;
225
226def 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
231def si_load_local_align8 : Aligned8Bytes <
232  (ops node:$ptr), (si_load_local node:$ptr)
233>;
234
235def si_sextload_local : PatFrag <(ops node:$ptr), (si_ld_local node:$ptr), [{
236  return cast<LoadSDNode>(N)->getExtensionType() == ISD::SEXTLOAD;
237}]>;
238def si_az_extload_local : AZExtLoadBase <si_ld_local>;
239
240multiclass 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
251defm si_sextload_local : SIExtLoadLocal <si_sextload_local>;
252defm si_az_extload_local : SIExtLoadLocal <si_az_extload_local>;
253
254def SIst_local : SDNode <"ISD::STORE", SDTStore,
255  [SDNPHasChain, SDNPMayStore, SDNPMemOperand, SDNPInGlue]
256>;
257
258def 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
263def 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
269def si_store_local_align8 : Aligned8Bytes <
270  (ops node:$val, node:$ptr), (si_store_local node:$val, node:$ptr)
271>;
272
273def 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
278def 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
283def 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
288def 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
302def si_uniform_br : PatFrag <
303  (ops node:$cond, node:$bb), (brcond node:$cond, node:$bb), [{
304  return isUniformBr(N);
305}]>;
306
307def si_uniform_br_scc : PatFrag <
308  (ops node:$cond, node:$bb), (si_uniform_br node:$cond, node:$bb), [{
309  return isCBranchSCC(N);
310}]>;
311
312multiclass 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
322defm si_atomic_load_add : SIAtomicM0Glue2 <"LOAD_ADD">;
323defm si_atomic_load_sub : SIAtomicM0Glue2 <"LOAD_SUB">;
324defm si_atomic_inc : SIAtomicM0Glue2 <"INC", 1>;
325defm si_atomic_dec : SIAtomicM0Glue2 <"DEC", 1>;
326defm si_atomic_load_and : SIAtomicM0Glue2 <"LOAD_AND">;
327defm si_atomic_load_min : SIAtomicM0Glue2 <"LOAD_MIN">;
328defm si_atomic_load_max : SIAtomicM0Glue2 <"LOAD_MAX">;
329defm si_atomic_load_or : SIAtomicM0Glue2 <"LOAD_OR">;
330defm si_atomic_load_xor : SIAtomicM0Glue2 <"LOAD_XOR">;
331defm si_atomic_load_umin : SIAtomicM0Glue2 <"LOAD_UMIN">;
332defm si_atomic_load_umax : SIAtomicM0Glue2 <"LOAD_UMAX">;
333defm si_atomic_swap : SIAtomicM0Glue2 <"SWAP">;
334
335def si_atomic_cmp_swap_glue : SDNode <"ISD::ATOMIC_CMP_SWAP", SDTAtomic3,
336  [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand, SDNPInGlue]
337>;
338
339defm si_atomic_cmp_swap : AtomicCmpSwapLocal <si_atomic_cmp_swap_glue>;
340
341// Transformation function, extract the lower 32bit of a 64bit immediate
342def LO32 : SDNodeXForm<imm, [{
343  return CurDAG->getTargetConstant(N->getZExtValue() & 0xffffffff, SDLoc(N),
344                                   MVT::i32);
345}]>;
346
347def 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
353def HI32 : SDNodeXForm<imm, [{
354  return CurDAG->getTargetConstant(N->getZExtValue() >> 32, SDLoc(N), MVT::i32);
355}]>;
356
357def 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
363def IMM8bitDWORD : PatLeaf <(imm),
364  [{return (N->getZExtValue() & ~0x3FC) == 0;}]
365>;
366
367def as_dword_i32imm : SDNodeXForm<imm, [{
368  return CurDAG->getTargetConstant(N->getZExtValue() >> 2, SDLoc(N), MVT::i32);
369}]>;
370
371def as_i1imm : SDNodeXForm<imm, [{
372  return CurDAG->getTargetConstant(N->getZExtValue(), SDLoc(N), MVT::i1);
373}]>;
374
375def as_i8imm : SDNodeXForm<imm, [{
376  return CurDAG->getTargetConstant(N->getZExtValue(), SDLoc(N), MVT::i8);
377}]>;
378
379def as_i16imm : SDNodeXForm<imm, [{
380  return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i16);
381}]>;
382
383def as_i32imm: SDNodeXForm<imm, [{
384  return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i32);
385}]>;
386
387def as_i64imm: SDNodeXForm<imm, [{
388  return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i64);
389}]>;
390
391// Copied from the AArch64 backend:
392def bitcast_fpimm_to_i32 : SDNodeXForm<fpimm, [{
393return CurDAG->getTargetConstant(
394  N->getValueAPF().bitcastToAPInt().getZExtValue(), SDLoc(N), MVT::i32);
395}]>;
396
397// Copied from the AArch64 backend:
398def bitcast_fpimm_to_i64 : SDNodeXForm<fpimm, [{
399return CurDAG->getTargetConstant(
400  N->getValueAPF().bitcastToAPInt().getZExtValue(), SDLoc(N), MVT::i64);
401}]>;
402
403def IMM8bit : PatLeaf <(imm),
404  [{return isUInt<8>(N->getZExtValue());}]
405>;
406
407def IMM12bit : PatLeaf <(imm),
408  [{return isUInt<12>(N->getZExtValue());}]
409>;
410
411def IMM16bit : PatLeaf <(imm),
412  [{return isUInt<16>(N->getZExtValue());}]
413>;
414
415def SIMM16bit : PatLeaf <(imm),
416  [{return isInt<16>(N->getSExtValue());}]
417>;
418
419def IMM20bit : PatLeaf <(imm),
420  [{return isUInt<20>(N->getZExtValue());}]
421>;
422
423def IMM32bit : PatLeaf <(imm),
424  [{return isUInt<32>(N->getZExtValue());}]
425>;
426
427def 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
432class InlineImm <ValueType vt> : PatLeaf <(vt imm), [{
433  return isInlineImmediate(N);
434}]>;
435
436class InlineFPImm <ValueType vt> : PatLeaf <(vt fpimm), [{
437  return isInlineImmediate(N);
438}]>;
439
440class 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
459def FRAMEri32 : Operand<iPTR> {
460  let MIOperandInfo = (ops i32:$ptr, i32imm:$index);
461}
462
463def SoppBrTarget : AsmOperandClass {
464  let Name = "SoppBrTarget";
465  let ParserMethod = "parseSOppBrTarget";
466}
467
468def sopp_brtarget : Operand<OtherVT> {
469  let EncoderMethod = "getSOPPBrEncoding";
470  let OperandType = "OPERAND_PCREL";
471  let ParserMatchClass = SoppBrTarget;
472}
473
474def si_ga : Operand<iPTR>;
475
476def InterpSlot : Operand<i32> {
477  let PrintMethod = "printInterpSlot";
478}
479
480def SendMsgMatchClass : AsmOperandClass {
481  let Name = "SendMsg";
482  let PredicateMethod = "isSendMsg";
483  let ParserMethod = "parseSendMsgOp";
484  let RenderMethod = "addImmOperands";
485}
486
487def SendMsgImm : Operand<i32> {
488  let PrintMethod = "printSendMsg";
489  let ParserMatchClass = SendMsgMatchClass;
490}
491
492def SWaitMatchClass : AsmOperandClass {
493  let Name = "SWaitCnt";
494  let RenderMethod = "addImmOperands";
495  let ParserMethod = "parseSWaitCntOps";
496}
497
498def WAIT_FLAG : Operand <i32> {
499  let ParserMatchClass = SWaitMatchClass;
500  let PrintMethod = "printWaitFlag";
501}
502
503include "SIInstrFormats.td"
504include "VIInstrFormats.td"
505
506class 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
515class NamedOperandBit<string Name, AsmOperandClass MatchClass> : Operand<i1> {
516  let PrintMethod = "print"#Name;
517  let ParserMatchClass = MatchClass;
518}
519
520class NamedOperandU8<string Name, AsmOperandClass MatchClass> : Operand<i8> {
521  let PrintMethod = "print"#Name;
522  let ParserMatchClass = MatchClass;
523}
524
525class NamedOperandU16<string Name, AsmOperandClass MatchClass> : Operand<i16> {
526  let PrintMethod = "print"#Name;
527  let ParserMatchClass = MatchClass;
528}
529
530class NamedOperandU32<string Name, AsmOperandClass MatchClass> : Operand<i32> {
531  let PrintMethod = "print"#Name;
532  let ParserMatchClass = MatchClass;
533}
534
535let OperandType = "OPERAND_IMMEDIATE" in {
536
537def offen : NamedOperandBit<"Offen", NamedMatchClass<"Offen">>;
538def idxen : NamedOperandBit<"Idxen", NamedMatchClass<"Idxen">>;
539def addr64 : NamedOperandBit<"Addr64", NamedMatchClass<"Addr64">>;
540
541def offset : NamedOperandU16<"Offset", NamedMatchClass<"Offset">>;
542def offset0 : NamedOperandU8<"Offset0", NamedMatchClass<"Offset0">>;
543def offset1 : NamedOperandU8<"Offset1", NamedMatchClass<"Offset1">>;
544
545def gds : NamedOperandBit<"GDS", NamedMatchClass<"GDS">>;
546
547def omod : NamedOperandU32<"OModSI", NamedMatchClass<"OModSI">>;
548def clampmod : NamedOperandBit<"ClampSI", NamedMatchClass<"ClampSI">>;
549
550def smrd_offset : NamedOperandU32<"SMRDOffset", NamedMatchClass<"SMRDOffset">>;
551def smrd_literal_offset : NamedOperandU32<"SMRDLiteralOffset", NamedMatchClass<"SMRDLiteralOffset">>;
552
553def glc : NamedOperandBit<"GLC", NamedMatchClass<"GLC">>;
554def slc : NamedOperandBit<"SLC", NamedMatchClass<"SLC">>;
555def tfe : NamedOperandBit<"TFE", NamedMatchClass<"TFE">>;
556def unorm : NamedOperandBit<"UNorm", NamedMatchClass<"UNorm">>;
557def da : NamedOperandBit<"DA", NamedMatchClass<"DA">>;
558def r128 : NamedOperandBit<"R128", NamedMatchClass<"R128">>;
559def lwe : NamedOperandBit<"LWE", NamedMatchClass<"LWE">>;
560
561def dmask : NamedOperandU16<"DMask", NamedMatchClass<"DMask">>;
562
563def dpp_ctrl : NamedOperandU32<"DPPCtrl", NamedMatchClass<"DPPCtrl", 0>>;
564def row_mask : NamedOperandU32<"RowMask", NamedMatchClass<"RowMask">>;
565def bank_mask : NamedOperandU32<"BankMask", NamedMatchClass<"BankMask">>;
566def bound_ctrl : NamedOperandBit<"BoundCtrl", NamedMatchClass<"BoundCtrl">>;
567
568def dst_sel : NamedOperandU32<"SDWADstSel", NamedMatchClass<"SDWADstSel">>;
569def src0_sel : NamedOperandU32<"SDWASrc0Sel", NamedMatchClass<"SDWASrc0Sel">>;
570def src1_sel : NamedOperandU32<"SDWASrc1Sel", NamedMatchClass<"SDWASrc1Sel">>;
571def dst_unused : NamedOperandU32<"SDWADstUnused", NamedMatchClass<"SDWADstUnused">>;
572
573def hwreg : NamedOperandU16<"Hwreg", NamedMatchClass<"Hwreg", 0>>;
574
575} // End OperandType = "OPERAND_IMMEDIATE"
576
577
578def VOPDstS64 : VOPDstOperand <SReg_64>;
579
580def FPInputModsMatchClass : AsmOperandClass {
581  let Name = "RegOrImmWithFPInputMods";
582  let ParserMethod = "parseRegOrImmWithFPInputMods";
583  let PredicateMethod = "isRegOrImmWithInputMods";
584}
585
586def FPInputMods : Operand <i32> {
587  let PrintMethod = "printOperandAndFPInputMods";
588  let ParserMatchClass = FPInputModsMatchClass;
589}
590
591def IntInputModsMatchClass : AsmOperandClass {
592  let Name = "RegOrImmWithIntInputMods";
593  let ParserMethod = "parseRegOrImmWithIntInputMods";
594  let PredicateMethod = "isRegOrImmWithInputMods";
595}
596
597def IntInputMods: Operand <i32> {
598  let PrintMethod = "printOperandAndIntInputMods";
599  let ParserMatchClass = IntInputModsMatchClass;
600}
601
602//===----------------------------------------------------------------------===//
603// Complex patterns
604//===----------------------------------------------------------------------===//
605
606def DS1Addr1Offset : ComplexPattern<i32, 2, "SelectDS1Addr1Offset">;
607def DS64Bit4ByteAligned : ComplexPattern<i32, 3, "SelectDS64Bit4ByteAligned">;
608
609def MUBUFAddr32 : ComplexPattern<i64, 9, "SelectMUBUFAddr32">;
610def MUBUFAddr64 : ComplexPattern<i64, 7, "SelectMUBUFAddr64">;
611def MUBUFAddr64Atomic : ComplexPattern<i64, 5, "SelectMUBUFAddr64">;
612def FLATAtomic : ComplexPattern<i64, 3, "SelectFlat">;
613def MUBUFScratch : ComplexPattern<i64, 4, "SelectMUBUFScratch">;
614def MUBUFOffset : ComplexPattern<i64, 6, "SelectMUBUFOffset">;
615def MUBUFOffsetNoGLC : ComplexPattern<i64, 3, "SelectMUBUFOffset">;
616def MUBUFOffsetAtomic : ComplexPattern<i64, 4, "SelectMUBUFOffset">;
617def MUBUFIntrinsicOffset : ComplexPattern<i32, 2, "SelectMUBUFIntrinsicOffset">;
618def MUBUFIntrinsicVOffset : ComplexPattern<i32, 3, "SelectMUBUFIntrinsicVOffset">;
619
620def SMRDImm   : ComplexPattern<i64, 2, "SelectSMRDImm">;
621def SMRDImm32 : ComplexPattern<i64, 2, "SelectSMRDImm32">;
622def SMRDSgpr  : ComplexPattern<i64, 2, "SelectSMRDSgpr">;
623def SMRDBufferImm   : ComplexPattern<i32, 1, "SelectSMRDBufferImm">;
624def SMRDBufferImm32 : ComplexPattern<i32, 1, "SelectSMRDBufferImm32">;
625def SMRDBufferSgpr  : ComplexPattern<i32, 1, "SelectSMRDBufferSgpr">;
626
627def MOVRELOffset : ComplexPattern<i32, 2, "SelectMOVRELOffset">;
628
629def VOP3Mods0 : ComplexPattern<untyped, 4, "SelectVOP3Mods0">;
630def VOP3NoMods0 : ComplexPattern<untyped, 4, "SelectVOP3NoMods0">;
631def VOP3Mods0Clamp : ComplexPattern<untyped, 3, "SelectVOP3Mods0Clamp">;
632def VOP3Mods0Clamp0OMod : ComplexPattern<untyped, 4, "SelectVOP3Mods0Clamp0OMod">;
633def VOP3Mods  : ComplexPattern<untyped, 2, "SelectVOP3Mods">;
634def VOP3NoMods : ComplexPattern<untyped, 2, "SelectVOP3NoMods">;
635
636//===----------------------------------------------------------------------===//
637// SI assembler operands
638//===----------------------------------------------------------------------===//
639
640def SIOperand {
641  int ZERO = 0x80;
642  int VCC = 0x6A;
643  int FLAT_SCR = 0x68;
644}
645
646def SRCMODS {
647  int NONE = 0;
648  int NEG = 1;
649}
650
651def DSTCLAMP {
652  int NONE = 0;
653}
654
655def 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
675class SIMCInstr <string pseudo, int subtarget> {
676  string PseudoInstr = pseudo;
677  int Subtarget = subtarget;
678}
679
680//===----------------------------------------------------------------------===//
681// EXP classes
682//===----------------------------------------------------------------------===//
683
684class 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
696multiclass 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
717class 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
724class 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
734class 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
744multiclass 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
755multiclass 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
760multiclass 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.
766multiclass 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
781multiclass 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.
796multiclass 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.
802multiclass 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
807class 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
821class 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
830class 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
839multiclass 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
850multiclass 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
855multiclass 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
860multiclass 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
865multiclass 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
870class 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}
876class 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
882class SOPC_CMP_32<bits<7> op, string opName, PatLeaf cond = COND_NULL>
883  : SOPC_Helper<op, SSrc_32, i32, opName, cond>;
884
885class SOPC_32<bits<7> op, string opName, list<dag> pattern = []>
886  : SOPC_Base<op, SSrc_32, SSrc_32, opName, pattern>;
887
888class SOPC_64_32<bits<7> op, string opName, list<dag> pattern = []>
889  : SOPC_Base<op, SSrc_64, SSrc_32, opName, pattern>;
890
891class 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
898class 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
908class 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
918multiclass 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
928multiclass 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
939multiclass 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
957multiclass 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
962multiclass 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
989class 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
996class 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
1006class 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
1017class 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
1027class 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
1038multiclass 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
1052multiclass 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
1066multiclass 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
1083multiclass 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
1090class 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
1100class 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
1111multiclass 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
1137class 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.
1147class 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.
1156class 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
1161class 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.
1168class 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?
1181class 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.
1189class 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.
1196class 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
1237class 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
1270class 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
1317class 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.
1328class 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.
1341class 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
1354class 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
1370class 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
1400class 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
1417class 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
1466class 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.
1472def VOP_F16_F16 : VOPProfile <[f16, f16, untyped, untyped]>;
1473def VOP_F16_I16 : VOPProfile <[f16, i32, untyped, untyped]>;
1474def VOP_I16_F16 : VOPProfile <[i32, f16, untyped, untyped]>;
1475
1476def VOP_F16_F16_F16 : VOPProfile <[f16, f16, f16, untyped]>;
1477def VOP_F16_F16_I16 : VOPProfile <[f16, f16, i32, untyped]>;
1478def VOP_I16_I16_I16 : VOPProfile <[i32, i32, i32, untyped]>;
1479
1480def VOP_I16_I16_I16_I16 : VOPProfile <[i32, i32, i32, i32, untyped]>;
1481def VOP_F16_F16_F16_F16 : VOPProfile <[f16, f16, f16, f16, untyped]>;
1482
1483def VOP_NONE : VOPProfile <[untyped, untyped, untyped, untyped]>;
1484
1485def VOP_F32_F32 : VOPProfile <[f32, f32, untyped, untyped]>;
1486def VOP_F32_F64 : VOPProfile <[f32, f64, untyped, untyped]>;
1487def VOP_F32_I32 : VOPProfile <[f32, i32, untyped, untyped]>;
1488def VOP_F64_F32 : VOPProfile <[f64, f32, untyped, untyped]>;
1489def VOP_F64_F64 : VOPProfile <[f64, f64, untyped, untyped]>;
1490def VOP_F64_I32 : VOPProfile <[f64, i32, untyped, untyped]>;
1491def VOP_I32_F32 : VOPProfile <[i32, f32, untyped, untyped]>;
1492def VOP_I32_F64 : VOPProfile <[i32, f64, untyped, untyped]>;
1493def VOP_I32_I32 : VOPProfile <[i32, i32, untyped, untyped]>;
1494
1495def VOP_F32_F32_F32 : VOPProfile <[f32, f32, f32, untyped]>;
1496def VOP_F32_F32_I32 : VOPProfile <[f32, f32, i32, untyped]>;
1497def VOP_F64_F64_F64 : VOPProfile <[f64, f64, f64, untyped]>;
1498def VOP_F64_F64_I32 : VOPProfile <[f64, f64, i32, untyped]>;
1499def VOP_I32_F32_F32 : VOPProfile <[i32, f32, f32, untyped]>;
1500def VOP_I32_F32_I32 : VOPProfile <[i32, f32, i32, untyped]>;
1501def VOP_I32_I32_I32 : VOPProfile <[i32, i32, i32, untyped]>;
1502
1503// Write out to vcc or arbitrary SGPR.
1504def 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.
1513def 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
1531def 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
1543class 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
1548def VOP3b_F32_I1_F32_F32_F32 : VOP3b_Profile<f32> {
1549  // FIXME: Hack to stop printing _e64
1550  let DstRC = RegisterOperand<VGPR_32>;
1551}
1552
1553def 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.
1561class 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
1568class 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
1578def VOPC_I1_F32_F32 : VOPC_Profile<f32>;
1579def VOPC_I1_F64_F64 : VOPC_Profile<f64>;
1580def VOPC_I1_I32_I32 : VOPC_Profile<i32>;
1581def VOPC_I1_I64_I64 : VOPC_Profile<i64>;
1582
1583def VOPC_I1_F32_I32 : VOPC_Class_Profile<f32>;
1584def VOPC_I1_F64_I32 : VOPC_Class_Profile<f64>;
1585
1586def VOP_I64_I64_I32 : VOPProfile <[i64, i64, i32, untyped]>;
1587def VOP_I64_I32_I64 : VOPProfile <[i64, i32, i64, untyped]>;
1588def VOP_I64_I64_I64 : VOPProfile <[i64, i64, i64, untyped]>;
1589
1590def VOP_F32_F32_F32_F32 : VOPProfile <[f32, f32, f32, f32]>;
1591def 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}
1596def 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}
1601def 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}
1620def VOP_F64_F64_F64_F64 : VOPProfile <[f64, f64, f64, f64]>;
1621def VOP_I32_I32_I32_I32 : VOPProfile <[i32, i32, i32, i32]>;
1622def 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
1625class 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
1656class SIInstAliasSI <string asm, string op_name, VOPProfile p> :
1657  SIInstAlias <asm, !cast<Instruction>(op_name#"_e32_si"), p> {
1658  let AssemblerPredicate = SIAssemblerPredicate;
1659}
1660
1661class SIInstAliasVI <string asm, string op_name, VOPProfile p> :
1662  SIInstAlias <asm, !cast<Instruction>(op_name#"_e32_vi"), p> {
1663  let AssemblerPredicates = [isVI];
1664}
1665
1666multiclass SIInstAliasBuilder <string asm, VOPProfile p> {
1667
1668  def : SIInstAliasSI <asm, NAME, p>;
1669
1670  def : SIInstAliasVI <asm, NAME, p>;
1671}
1672
1673class VOP <string opName> {
1674  string OpName = opName;
1675}
1676
1677class VOP2_REV <string revOp, bit isOrig> {
1678  string RevOp = revOp;
1679  bit IsOrig = isOrig;
1680}
1681
1682class AtomicNoRet <string noRetOp, bit isRet> {
1683  string NoRetOp = noRetOp;
1684  bit IsRet = isRet;
1685}
1686
1687class 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
1699class 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
1707class 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
1715multiclass 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
1725class 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
1735class 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
1758class 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
1768multiclass 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
1776class 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
1785class 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
1793class 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
1801multiclass 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
1810multiclass 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
1822class 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
1832class 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
1842class 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
1853class 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
1864class 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
1877class 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
1887class 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
1897class 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
1907class 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
1917class 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
1927class 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
1937class 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
1947class 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
1957multiclass 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
1972multiclass 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
1984multiclass 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
1994multiclass 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
2008multiclass 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.
2023multiclass 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.
2036multiclass 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
2048multiclass 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.
2073multiclass 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
2097multiclass 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
2110multiclass 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
2119multiclass 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
2132multiclass 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
2145multiclass 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
2158multiclass 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
2174multiclass 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
2188multiclass 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
2201multiclass 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
2215multiclass 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.
2229multiclass 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
2238multiclass 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
2252multiclass VOP2MADK <vop2 op, string opName, VOPProfile P, list<dag> pattern = []> {
2253
2254  def "" : VOP2_Pseudo <P.Outs, P.Ins32, pattern, opName>;
2255
2256let 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
2277class 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
2285class 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
2297multiclass 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
2336multiclass 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.
2350multiclass 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
2365multiclass 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
2382multiclass 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
2394multiclass VOPC_F32 <vopc op, string opName, PatLeaf cond = COND_NULL, string revOp = opName> :
2395  VOPCInst <op, opName, VOPC_I1_F32_F32, cond, revOp>;
2396
2397multiclass 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
2400multiclass VOPC_I32 <vopc op, string opName, PatLeaf cond = COND_NULL, string revOp = opName> :
2401  VOPCInst <op, opName, VOPC_I1_I32_I32, cond, revOp>;
2402
2403multiclass 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
2407multiclass 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
2413multiclass VOPCX_F32 <vopc op, string opName, string revOp = opName> :
2414  VOPCX <op, opName, VOPC_I1_F32_F32, COND_NULL, [Write32Bit], revOp>;
2415
2416multiclass VOPCX_F64 <vopc op, string opName, string revOp = opName> :
2417  VOPCX <op, opName, VOPC_I1_F64_F64, COND_NULL, [WriteDoubleAdd], revOp>;
2418
2419multiclass VOPCX_I32 <vopc op, string opName, string revOp = opName> :
2420  VOPCX <op, opName, VOPC_I1_I32_I32, COND_NULL, [Write32Bit], revOp>;
2421
2422multiclass VOPCX_I64 <vopc op, string opName, string revOp = opName> :
2423  VOPCX <op, opName, VOPC_I1_I64_I64, COND_NULL, [Write64Bit], revOp>;
2424
2425
2426multiclass VOPC_CLASS_F32 <vopc op, string opName> :
2427  VOPCClassInst <op, opName, VOPC_I1_F32_I32, 0, [Write32Bit]>;
2428
2429multiclass VOPCX_CLASS_F32 <vopc op, string opName> :
2430  VOPCClassInst <op, opName, VOPC_I1_F32_I32, 1, [Write32Bit]>;
2431
2432multiclass VOPC_CLASS_F64 <vopc op, string opName> :
2433  VOPCClassInst <op, opName, VOPC_I1_F64_I32, 0, [WriteDoubleAdd]>;
2434
2435multiclass VOPCX_CLASS_F64 <vopc op, string opName> :
2436  VOPCClassInst <op, opName, VOPC_I1_F64_I32, 1, [WriteDoubleAdd]>;
2437
2438
2439multiclass 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
2445multiclass 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.
2476multiclass 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
2496multiclass 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
2503class 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
2517class 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
2524class 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
2534class 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
2544multiclass 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
2557class 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
2564class 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
2574class 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
2584class 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
2593class 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
2602multiclass 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
2617multiclass 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
2630multiclass 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
2644multiclass 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
2658multiclass 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
2672multiclass 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
2686multiclass 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
2703multiclass 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
2720multiclass 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
2734multiclass 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
2741multiclass 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
2757multiclass 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
2772multiclass 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
2785multiclass 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
2798multiclass 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
2817class 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
2824class 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
2833class 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
2841multiclass 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
2852let mayStore = 1, mayLoad = 0 in {
2853
2854multiclass 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
2866let mayLoad = 1, mayStore = 0 in {
2867
2868multiclass 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
2884class mubuf <bits<7> si, bits<7> vi = si> {
2885  field bits<7> SI = si;
2886  field bits<7> VI = vi;
2887}
2888
2889let isCodeGenOnly = 0 in {
2890
2891class 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
2898class 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
2903class MUBUFAddr64Table <bit is_addr64, string suffix = ""> {
2904  bit IsAddr64 = is_addr64;
2905  string OpName = NAME # suffix;
2906}
2907
2908class 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
2924class 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
2935class 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
2946multiclass 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 addr64 = 0, isCodeGenOnly = 0 in {
2953    def _si : MUBUF_Real_si <op, opName, outs, ins, asm>;
2954  }
2955
2956  def _vi : MUBUF_Real_vi <op, opName, outs, ins, asm>;
2957}
2958
2959multiclass MUBUFAddr64_m <mubuf op, string opName, dag outs,
2960                          dag ins, string asm, list<dag> pattern> {
2961
2962  def "" : MUBUF_Pseudo <opName, outs, ins, pattern>,
2963           MUBUFAddr64Table <1>;
2964
2965  let addr64 = 1, isCodeGenOnly = 0 in {
2966    def _si : MUBUF_Real_si <op, opName, outs, ins, asm>;
2967  }
2968
2969  // There is no VI version. If the pseudo is selected, it should be lowered
2970  // for VI appropriately.
2971}
2972
2973multiclass MUBUFAtomicOffset_m <mubuf op, string opName, dag outs, dag ins,
2974                                string asm, list<dag> pattern, bit is_return> {
2975
2976  def "" : MUBUF_Pseudo <opName, outs, ins, pattern>,
2977           MUBUFAddr64Table <0, !if(is_return, "_RTN", "")>,
2978           AtomicNoRet<NAME#"_OFFSET", is_return>;
2979
2980  let offen = 0, idxen = 0, tfe = 0, vaddr = 0 in {
2981    let addr64 = 0 in {
2982      def _si : MUBUF_Real_si <op, opName, outs, ins, asm>;
2983    }
2984
2985    def _vi : MUBUF_Real_vi <op, opName, outs, ins, asm>;
2986  }
2987}
2988
2989multiclass MUBUFAtomicAddr64_m <mubuf op, string opName, dag outs, dag ins,
2990                                string asm, list<dag> pattern, bit is_return> {
2991
2992  def "" : MUBUF_Pseudo <opName, outs, ins, pattern>,
2993           MUBUFAddr64Table <1, !if(is_return, "_RTN", "")>,
2994           AtomicNoRet<NAME#"_ADDR64", is_return>;
2995
2996  let offen = 0, idxen = 0, addr64 = 1, tfe = 0 in {
2997    def _si : MUBUF_Real_si <op, opName, outs, ins, asm>;
2998  }
2999
3000  // There is no VI version. If the pseudo is selected, it should be lowered
3001  // for VI appropriately.
3002}
3003
3004multiclass MUBUFAtomicOther_m <mubuf op, string opName, dag outs, dag ins,
3005                               string asm, list<dag> pattern, bit is_return> {
3006
3007  def "" : MUBUF_Pseudo <opName, outs, ins, pattern>,
3008           AtomicNoRet<opName, is_return>;
3009
3010  let tfe = 0 in {
3011    let addr64 = 0 in {
3012      def _si : MUBUF_Real_si <op, opName, outs, ins, asm>;
3013    }
3014
3015    def _vi : MUBUF_Real_vi <op, opName, outs, ins, asm>;
3016  }
3017}
3018
3019multiclass MUBUF_Atomic <mubuf op, string name, RegisterClass rc,
3020                         ValueType vt, SDPatternOperator atomic> {
3021
3022  let mayStore = 1, mayLoad = 1, hasPostISelHook = 1, hasSideEffects = 1 in {
3023
3024    // No return variants
3025    let glc = 0, AsmMatchConverter = "cvtMubufAtomic" in {
3026
3027      defm _ADDR64 : MUBUFAtomicAddr64_m <
3028        op, name#"_addr64", (outs),
3029        (ins rc:$vdata, VReg_64:$vaddr, SReg_128:$srsrc,
3030             SCSrc_32:$soffset, offset:$offset, slc:$slc),
3031        name#" $vdata, $vaddr, $srsrc, $soffset addr64$offset$slc", [], 0
3032      >;
3033
3034      defm _OFFSET : MUBUFAtomicOffset_m <
3035        op, name#"_offset", (outs),
3036        (ins rc:$vdata, SReg_128:$srsrc, SCSrc_32:$soffset, offset:$offset,
3037             slc:$slc),
3038        name#" $vdata, off, $srsrc, $soffset$offset$slc", [], 0
3039      >;
3040
3041      let offen = 1, idxen = 0 in {
3042        defm _OFFEN : MUBUFAtomicOther_m <
3043          op, name#"_offen", (outs),
3044          (ins rc:$vdata, VGPR_32:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset,
3045                offset:$offset, slc:$slc),
3046          name#" $vdata, $vaddr, $srsrc, $soffset offen$offset$slc", [], 0
3047        >;
3048      }
3049
3050      let offen = 0, idxen = 1 in {
3051        defm _IDXEN : MUBUFAtomicOther_m <
3052          op, name#"_idxen", (outs),
3053          (ins rc:$vdata, VGPR_32:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset,
3054                offset:$offset, slc:$slc),
3055          name#" $vdata, $vaddr, $srsrc, $soffset idxen$offset$slc", [], 0
3056        >;
3057      }
3058
3059      let offen = 1, idxen = 1 in {
3060        defm _BOTHEN : MUBUFAtomicOther_m <
3061          op, name#"_bothen", (outs),
3062          (ins rc:$vdata, VReg_64:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset,
3063                offset:$offset, slc:$slc),
3064          name#" $vdata, $vaddr, $srsrc, $soffset idxen offen$offset$slc",
3065          [], 0
3066        >;
3067      }
3068    } // glc = 0
3069
3070    // Variant that return values
3071    let glc = 1, Constraints = "$vdata = $vdata_in",
3072        AsmMatchConverter = "cvtMubufAtomicReturn",
3073        DisableEncoding = "$vdata_in"  in {
3074
3075      defm _RTN_ADDR64 : MUBUFAtomicAddr64_m <
3076        op, name#"_rtn_addr64", (outs rc:$vdata),
3077        (ins rc:$vdata_in, VReg_64:$vaddr, SReg_128:$srsrc,
3078             SCSrc_32:$soffset, offset:$offset, slc:$slc),
3079        name#" $vdata, $vaddr, $srsrc, $soffset addr64$offset glc$slc",
3080        [(set vt:$vdata,
3081         (atomic (MUBUFAddr64Atomic v4i32:$srsrc, i64:$vaddr, i32:$soffset,
3082	                            i16:$offset, i1:$slc), vt:$vdata_in))], 1
3083      >;
3084
3085      defm _RTN_OFFSET : MUBUFAtomicOffset_m <
3086        op, name#"_rtn_offset", (outs rc:$vdata),
3087        (ins rc:$vdata_in, SReg_128:$srsrc, SCSrc_32:$soffset,
3088             offset:$offset, slc:$slc),
3089        name#" $vdata, off, $srsrc, $soffset$offset glc$slc",
3090        [(set vt:$vdata,
3091         (atomic (MUBUFOffsetAtomic v4i32:$srsrc, i32:$soffset, i16:$offset,
3092                                    i1:$slc), vt:$vdata_in))], 1
3093      >;
3094
3095      let offen = 1, idxen = 0 in {
3096        defm _RTN_OFFEN : MUBUFAtomicOther_m <
3097          op, name#"_rtn_offen", (outs rc:$vdata),
3098          (ins rc:$vdata_in, VGPR_32:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset,
3099                offset:$offset, slc:$slc),
3100          name#" $vdata, $vaddr, $srsrc, $soffset offen$offset glc$slc",
3101          [], 1
3102        >;
3103      }
3104
3105      let offen = 0, idxen = 1 in {
3106        defm _RTN_IDXEN : MUBUFAtomicOther_m <
3107          op, name#"_rtn_idxen", (outs rc:$vdata),
3108          (ins rc:$vdata_in, VGPR_32:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset,
3109                offset:$offset, slc:$slc),
3110          name#" $vdata, $vaddr, $srsrc, $soffset idxen$offset glc$slc",
3111          [], 1
3112        >;
3113      }
3114
3115      let offen = 1, idxen = 1 in {
3116        defm _RTN_BOTHEN : MUBUFAtomicOther_m <
3117          op, name#"_rtn_bothen", (outs rc:$vdata),
3118          (ins rc:$vdata_in, VReg_64:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset,
3119                offset:$offset, slc:$slc),
3120          name#" $vdata, $vaddr, $srsrc, $soffset idxen offen$offset glc$slc",
3121          [], 1
3122        >;
3123      }
3124    } // glc = 1
3125
3126  } // mayStore = 1, mayLoad = 1, hasPostISelHook = 1
3127}
3128
3129// FIXME: tfe can't be an operand because it requires a separate
3130// opcode because it needs an N+1 register class dest register.
3131multiclass MUBUF_Load_Helper <mubuf op, string name, RegisterClass regClass,
3132                              ValueType load_vt = i32,
3133                              SDPatternOperator ld = null_frag> {
3134
3135  let mayLoad = 1, mayStore = 0 in {
3136    let offen = 0, idxen = 0, vaddr = 0 in {
3137      defm _OFFSET : MUBUF_m <op, name#"_offset", (outs regClass:$vdata),
3138                           (ins SReg_128:$srsrc, SCSrc_32:$soffset,
3139                           offset:$offset, glc:$glc, slc:$slc, tfe:$tfe),
3140                           name#" $vdata, off, $srsrc, $soffset$offset$glc$slc$tfe",
3141                           [(set load_vt:$vdata, (ld (MUBUFOffset v4i32:$srsrc,
3142                                                     i32:$soffset, i16:$offset,
3143                                                     i1:$glc, i1:$slc, i1:$tfe)))]>;
3144    }
3145
3146    let offen = 1, idxen = 0  in {
3147      defm _OFFEN  : MUBUF_m <op, name#"_offen", (outs regClass:$vdata),
3148                           (ins VGPR_32:$vaddr, SReg_128:$srsrc,
3149                           SCSrc_32:$soffset, offset:$offset, glc:$glc, slc:$slc,
3150                           tfe:$tfe),
3151                           name#" $vdata, $vaddr, $srsrc, $soffset offen$offset$glc$slc$tfe", []>;
3152    }
3153
3154    let offen = 0, idxen = 1 in {
3155      defm _IDXEN  : MUBUF_m <op, name#"_idxen", (outs regClass:$vdata),
3156                           (ins VGPR_32:$vaddr, SReg_128:$srsrc,
3157                           SCSrc_32:$soffset, offset:$offset, glc:$glc,
3158                           slc:$slc, tfe:$tfe),
3159                           name#" $vdata, $vaddr, $srsrc, $soffset idxen$offset$glc$slc$tfe", []>;
3160    }
3161
3162    let offen = 1, idxen = 1 in {
3163      defm _BOTHEN : MUBUF_m <op, name#"_bothen", (outs regClass:$vdata),
3164                           (ins VReg_64:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset,
3165                           offset:$offset, glc:$glc, slc:$slc, tfe:$tfe),
3166                           name#" $vdata, $vaddr, $srsrc, $soffset idxen offen$offset$glc$slc$tfe", []>;
3167    }
3168
3169    let offen = 0, idxen = 0 in {
3170      defm _ADDR64 : MUBUFAddr64_m <op, name#"_addr64", (outs regClass:$vdata),
3171                           (ins VReg_64:$vaddr, SReg_128:$srsrc,
3172                                SCSrc_32:$soffset, offset:$offset,
3173				glc:$glc, slc:$slc, tfe:$tfe),
3174                           name#" $vdata, $vaddr, $srsrc, $soffset addr64$offset$glc$slc$tfe",
3175                           [(set load_vt:$vdata, (ld (MUBUFAddr64 v4i32:$srsrc,
3176                                                  i64:$vaddr, i32:$soffset,
3177                                                  i16:$offset, i1:$glc, i1:$slc,
3178						  i1:$tfe)))]>;
3179    }
3180  }
3181}
3182
3183multiclass MUBUF_Store_Helper <mubuf op, string name, RegisterClass vdataClass,
3184                          ValueType store_vt = i32, SDPatternOperator st = null_frag> {
3185  let mayLoad = 0, mayStore = 1 in {
3186    let offen = 0, idxen = 0, vaddr = 0 in {
3187      defm _OFFSET : MUBUF_m <op, name#"_offset",(outs),
3188                              (ins vdataClass:$vdata, SReg_128:$srsrc, SCSrc_32:$soffset,
3189                              offset:$offset, glc:$glc, slc:$slc, tfe:$tfe),
3190                              name#" $vdata, off, $srsrc, $soffset$offset$glc$slc$tfe",
3191                              [(st store_vt:$vdata, (MUBUFOffset v4i32:$srsrc, i32:$soffset,
3192                                   i16:$offset, i1:$glc, i1:$slc, i1:$tfe))]>;
3193    } // offen = 0, idxen = 0, vaddr = 0
3194
3195    let offen = 1, idxen = 0  in {
3196      defm _OFFEN : MUBUF_m <op, name#"_offen", (outs),
3197                             (ins vdataClass:$vdata, VGPR_32:$vaddr, SReg_128:$srsrc,
3198                              SCSrc_32:$soffset, offset:$offset, glc:$glc,
3199                              slc:$slc, tfe:$tfe),
3200                             name#" $vdata, $vaddr, $srsrc, $soffset offen"#
3201                             "$offset$glc$slc$tfe", []>;
3202    } // end offen = 1, idxen = 0
3203
3204    let offen = 0, idxen = 1 in {
3205      defm _IDXEN  : MUBUF_m <op, name#"_idxen", (outs),
3206                           (ins vdataClass:$vdata, VGPR_32:$vaddr, SReg_128:$srsrc,
3207                           SCSrc_32:$soffset, offset:$offset, glc:$glc,
3208                           slc:$slc, tfe:$tfe),
3209                           name#" $vdata, $vaddr, $srsrc, $soffset idxen$offset$glc$slc$tfe", []>;
3210    }
3211
3212    let offen = 1, idxen = 1 in {
3213      defm _BOTHEN : MUBUF_m <op, name#"_bothen", (outs),
3214                           (ins vdataClass:$vdata, VReg_64:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset,
3215                           offset:$offset, glc:$glc, slc:$slc, tfe:$tfe),
3216                           name#" $vdata, $vaddr, $srsrc, $soffset idxen offen$offset$glc$slc$tfe", []>;
3217    }
3218
3219    let offen = 0, idxen = 0 in {
3220      defm _ADDR64 : MUBUFAddr64_m <op, name#"_addr64", (outs),
3221                                    (ins vdataClass:$vdata, VReg_64:$vaddr, SReg_128:$srsrc,
3222                                         SCSrc_32:$soffset,
3223                                         offset:$offset, glc:$glc, slc:$slc,
3224                                         tfe:$tfe),
3225                                    name#" $vdata, $vaddr, $srsrc, $soffset addr64"#
3226                                         "$offset$glc$slc$tfe",
3227                                    [(st store_vt:$vdata,
3228                                      (MUBUFAddr64 v4i32:$srsrc, i64:$vaddr,
3229                                                   i32:$soffset, i16:$offset,
3230                                                   i1:$glc, i1:$slc, i1:$tfe))]>;
3231    }
3232  } // End mayLoad = 0, mayStore = 1
3233}
3234
3235// For cache invalidation instructions.
3236multiclass MUBUF_Invalidate <mubuf op, string opName, SDPatternOperator node> {
3237  let hasSideEffects = 1, mayStore = 1, AsmMatchConverter = "" in {
3238    def "" : MUBUF_Pseudo <opName, (outs), (ins), [(node)]>;
3239
3240    // Set everything to 0.
3241    let offset = 0, offen = 0, idxen = 0, glc = 0, vaddr = 0,
3242        vdata = 0, srsrc = 0, slc = 0, tfe = 0, soffset = 0 in {
3243      let addr64 = 0 in {
3244        def _si : MUBUF_Real_si <op, opName, (outs), (ins), opName>;
3245      }
3246
3247      def _vi : MUBUF_Real_vi <op, opName, (outs), (ins), opName>;
3248    }
3249  } // End hasSideEffects = 1, mayStore = 1, AsmMatchConverter = ""
3250}
3251
3252//===----------------------------------------------------------------------===//
3253// FLAT classes
3254//===----------------------------------------------------------------------===//
3255
3256class flat <bits<7> ci, bits<7> vi = ci> {
3257  field bits<7> CI = ci;
3258  field bits<7> VI = vi;
3259}
3260
3261class FLAT_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
3262     FLAT <0, outs, ins, "", pattern>,
3263      SIMCInstr<opName, SIEncodingFamily.NONE> {
3264  let isPseudo = 1;
3265  let isCodeGenOnly = 1;
3266}
3267
3268class FLAT_Real_ci <bits<7> op, string opName, dag outs, dag ins, string asm> :
3269    FLAT <op, outs, ins, asm, []>,
3270    SIMCInstr<opName, SIEncodingFamily.SI> {
3271  let AssemblerPredicate = isCIOnly;
3272  let DecoderNamespace="CI";
3273}
3274
3275class FLAT_Real_vi <bits<7> op, string opName, dag outs, dag ins, string asm> :
3276    FLAT <op, outs, ins, asm, []>,
3277    SIMCInstr<opName, SIEncodingFamily.VI> {
3278  let AssemblerPredicate = VIAssemblerPredicate;
3279  let DecoderNamespace="VI";
3280  let DisableDecoder = DisableVIDecoder;
3281}
3282
3283multiclass FLAT_AtomicRet_m <flat op, dag outs, dag ins, string asm,
3284                   list<dag> pattern> {
3285  def "" : FLAT_Pseudo <NAME#"_RTN", outs, ins, pattern>,
3286               AtomicNoRet <NAME, 1>;
3287
3288  def _ci : FLAT_Real_ci <op.CI, NAME#"_RTN", outs, ins, asm>;
3289
3290  def _vi : FLAT_Real_vi <op.VI, NAME#"_RTN", outs, ins, asm>;
3291}
3292
3293multiclass FLAT_Load_Helper <flat op, string asm_name,
3294    RegisterClass regClass,
3295    dag outs = (outs regClass:$vdst),
3296    dag ins = (ins VReg_64:$addr, glc:$glc, slc:$slc, tfe:$tfe),
3297    string asm = asm_name#" $vdst, $addr$glc$slc$tfe"> {
3298
3299  let data = 0, mayLoad = 1 in {
3300
3301    def "" : FLAT_Pseudo <NAME, outs, ins, []>;
3302
3303    def _ci : FLAT_Real_ci <op.CI, NAME, outs, ins, asm>;
3304
3305    def _vi : FLAT_Real_vi <op.VI, NAME, outs, ins, asm>;
3306  }
3307}
3308
3309multiclass FLAT_Store_Helper <flat op, string asm_name,
3310    RegisterClass vdataClass,
3311    dag outs = (outs),
3312    dag ins = (ins VReg_64:$addr, vdataClass:$data, glc:$glc,
3313                   slc:$slc, tfe:$tfe),
3314    string asm = asm_name#" $addr, $data$glc$slc$tfe"> {
3315
3316  let mayLoad = 0, mayStore = 1, vdst = 0 in {
3317
3318    def "" : FLAT_Pseudo <NAME, outs, ins, []>;
3319
3320    def _ci : FLAT_Real_ci <op.CI, NAME, outs, ins, asm>;
3321
3322    def _vi : FLAT_Real_vi <op.VI, NAME, outs, ins, asm>;
3323  }
3324}
3325
3326multiclass FLAT_ATOMIC <flat op, string asm_name, RegisterClass vdst_rc,
3327    ValueType vt, SDPatternOperator atomic = null_frag,
3328    ValueType data_vt = vt,
3329    RegisterClass data_rc = vdst_rc,
3330    string asm_noret = asm_name#" $addr, $data"#"$slc"#"$tfe"> {
3331
3332  let mayLoad = 1, mayStore = 1, glc = 0, vdst = 0 in {
3333    def "" : FLAT_Pseudo <NAME, (outs),
3334                          (ins VReg_64:$addr, data_rc:$data,
3335                               slc:$slc, tfe:$tfe), []>,
3336             AtomicNoRet <NAME, 0>;
3337
3338    def _ci : FLAT_Real_ci <op.CI, NAME, (outs),
3339                            (ins VReg_64:$addr, data_rc:$data,
3340                                 slc:$slc, tfe:$tfe),
3341                            asm_noret>;
3342
3343    def _vi : FLAT_Real_vi <op.VI, NAME, (outs),
3344                            (ins VReg_64:$addr, data_rc:$data,
3345                                 slc:$slc, tfe:$tfe),
3346                            asm_noret>;
3347  }
3348
3349  let glc = 1, hasPostISelHook = 1 in {
3350    defm _RTN : FLAT_AtomicRet_m <
3351      op, (outs vdst_rc:$vdst),
3352      (ins VReg_64:$addr, data_rc:$data, slc:$slc, tfe:$tfe),
3353      asm_name#" $vdst, $addr, $data glc$slc$tfe",
3354      [(set vt:$vdst,
3355         (atomic (FLATAtomic i64:$addr, i1:$slc, i1:$tfe), data_vt:$data))]
3356    >;
3357  }
3358}
3359
3360class MIMG_Mask <string op, int channels> {
3361  string Op = op;
3362  int Channels = channels;
3363}
3364
3365class mimg <bits<7> si, bits<7> vi = si> {
3366  field bits<7> SI = si;
3367  field bits<7> VI = vi;
3368}
3369
3370class MIMG_Helper <dag outs, dag ins, string asm,
3371                   string dns=""> : MIMG<outs, ins, asm,[]> {
3372  let mayLoad = 1;
3373  let mayStore = 0;
3374  let hasPostISelHook = 1;
3375  let DecoderNamespace = dns;
3376  let isAsmParserOnly = !if(!eq(dns,""), 1, 0);
3377  let AsmMatchConverter = "cvtMIMG";
3378}
3379
3380class MIMG_NoSampler_Helper <bits<7> op, string asm,
3381                             RegisterClass dst_rc,
3382                             RegisterClass addr_rc,
3383                             string dns=""> : MIMG_Helper <
3384  (outs dst_rc:$vdata),
3385  (ins addr_rc:$vaddr, SReg_256:$srsrc,
3386       dmask:$dmask, unorm:$unorm, glc:$glc, slc:$slc,
3387       r128:$r128, tfe:$tfe, lwe:$lwe, da:$da),
3388  asm#" $vdata, $vaddr, $srsrc$dmask$unorm$glc$slc$r128$tfe$lwe$da",
3389  dns>, MIMGe<op> {
3390  let ssamp = 0;
3391}
3392
3393multiclass MIMG_NoSampler_Src_Helper <bits<7> op, string asm,
3394                                      RegisterClass dst_rc,
3395                                      int channels> {
3396  def _V1 : MIMG_NoSampler_Helper <op, asm, dst_rc, VGPR_32,
3397                                   !if(!eq(channels, 1), "AMDGPU", "")>,
3398            MIMG_Mask<asm#"_V1", channels>;
3399  def _V2 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_64>,
3400            MIMG_Mask<asm#"_V2", channels>;
3401  def _V4 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_128>,
3402            MIMG_Mask<asm#"_V4", channels>;
3403}
3404
3405multiclass MIMG_NoSampler <bits<7> op, string asm> {
3406  defm _V1 : MIMG_NoSampler_Src_Helper <op, asm, VGPR_32, 1>;
3407  defm _V2 : MIMG_NoSampler_Src_Helper <op, asm, VReg_64, 2>;
3408  defm _V3 : MIMG_NoSampler_Src_Helper <op, asm, VReg_96, 3>;
3409  defm _V4 : MIMG_NoSampler_Src_Helper <op, asm, VReg_128, 4>;
3410}
3411
3412class MIMG_Store_Helper <bits<7> op, string asm,
3413                         RegisterClass data_rc,
3414                         RegisterClass addr_rc> : MIMG_Helper <
3415  (outs),
3416  (ins data_rc:$vdata, addr_rc:$vaddr, SReg_256:$srsrc,
3417       dmask:$dmask, unorm:$unorm, glc:$glc, slc:$slc,
3418       r128:$r128, tfe:$tfe, lwe:$lwe, da:$da),
3419  asm#" $vdata, $vaddr, $srsrc$dmask$unorm$glc$slc$r128$tfe$lwe$da"
3420     >, MIMGe<op> {
3421  let ssamp = 0;
3422  let mayLoad = 1; // TableGen requires this for matching with the intrinsics
3423  let mayStore = 1;
3424  let hasSideEffects = 1;
3425  let hasPostISelHook = 0;
3426}
3427
3428multiclass MIMG_Store_Addr_Helper <bits<7> op, string asm,
3429                                  RegisterClass data_rc,
3430                                  int channels> {
3431  def _V1 : MIMG_Store_Helper <op, asm, data_rc, VGPR_32>,
3432            MIMG_Mask<asm#"_V1", channels>;
3433  def _V2 : MIMG_Store_Helper <op, asm, data_rc, VReg_64>,
3434            MIMG_Mask<asm#"_V2", channels>;
3435  def _V4 : MIMG_Store_Helper <op, asm, data_rc, VReg_128>,
3436            MIMG_Mask<asm#"_V4", channels>;
3437}
3438
3439multiclass MIMG_Store <bits<7> op, string asm> {
3440  defm _V1 : MIMG_Store_Addr_Helper <op, asm, VGPR_32, 1>;
3441  defm _V2 : MIMG_Store_Addr_Helper <op, asm, VReg_64, 2>;
3442  defm _V3 : MIMG_Store_Addr_Helper <op, asm, VReg_96, 3>;
3443  defm _V4 : MIMG_Store_Addr_Helper <op, asm, VReg_128, 4>;
3444}
3445
3446class MIMG_Atomic_Helper <string asm, RegisterClass data_rc,
3447                          RegisterClass addr_rc> : MIMG_Helper <
3448    (outs data_rc:$vdst),
3449    (ins data_rc:$vdata, addr_rc:$vaddr, SReg_256:$srsrc,
3450         dmask:$dmask, unorm:$unorm, glc:$glc, slc:$slc,
3451         r128:$r128, tfe:$tfe, lwe:$lwe, da:$da),
3452    asm#" $vdst, $vaddr, $srsrc$dmask$unorm$glc$slc$r128$tfe$lwe$da"
3453  > {
3454  let mayStore = 1;
3455  let hasSideEffects = 1;
3456  let hasPostISelHook = 0;
3457  let Constraints = "$vdst = $vdata";
3458  let AsmMatchConverter = "cvtMIMGAtomic";
3459}
3460
3461class MIMG_Atomic_Real_si<mimg op, string name, string asm,
3462  RegisterClass data_rc, RegisterClass addr_rc> :
3463  MIMG_Atomic_Helper<asm, data_rc, addr_rc>,
3464  SIMCInstr<name, SIEncodingFamily.SI>,
3465  MIMGe<op.SI> {
3466  let isCodeGenOnly = 0;
3467  let AssemblerPredicates = [isSICI];
3468  let DecoderNamespace = "SICI";
3469  let DisableDecoder = DisableSIDecoder;
3470}
3471
3472class MIMG_Atomic_Real_vi<mimg op, string name, string asm,
3473  RegisterClass data_rc, RegisterClass addr_rc> :
3474  MIMG_Atomic_Helper<asm, data_rc, addr_rc>,
3475  SIMCInstr<name, SIEncodingFamily.VI>,
3476  MIMGe<op.VI> {
3477  let isCodeGenOnly = 0;
3478  let AssemblerPredicates = [isVI];
3479  let DecoderNamespace = "VI";
3480  let DisableDecoder = DisableVIDecoder;
3481}
3482
3483multiclass MIMG_Atomic_Helper_m <mimg op, string name, string asm,
3484                                 RegisterClass data_rc, RegisterClass addr_rc> {
3485  let isPseudo = 1, isCodeGenOnly = 1 in {
3486    def "" : MIMG_Atomic_Helper<asm, data_rc, addr_rc>,
3487             SIMCInstr<name, SIEncodingFamily.NONE>;
3488  }
3489
3490  let ssamp = 0 in {
3491    def _si : MIMG_Atomic_Real_si<op, name, asm, data_rc, addr_rc>;
3492
3493    def _vi : MIMG_Atomic_Real_vi<op, name, asm, data_rc, addr_rc>;
3494  }
3495}
3496
3497multiclass MIMG_Atomic <mimg op, string asm, RegisterClass data_rc = VGPR_32> {
3498  defm _V1 : MIMG_Atomic_Helper_m <op, asm # "_V1", asm, data_rc, VGPR_32>;
3499  defm _V2 : MIMG_Atomic_Helper_m <op, asm # "_V2", asm, data_rc, VReg_64>;
3500  defm _V4 : MIMG_Atomic_Helper_m <op, asm # "_V3", asm, data_rc, VReg_128>;
3501}
3502
3503class MIMG_Sampler_Helper <bits<7> op, string asm,
3504                           RegisterClass dst_rc,
3505                           RegisterClass src_rc,
3506                           int wqm,
3507                           string dns=""> : MIMG_Helper <
3508  (outs dst_rc:$vdata),
3509  (ins src_rc:$vaddr, SReg_256:$srsrc, SReg_128:$ssamp,
3510       dmask:$dmask, unorm:$unorm, glc:$glc, slc:$slc,
3511       r128:$r128, tfe:$tfe, lwe:$lwe, da:$da),
3512  asm#" $vdata, $vaddr, $srsrc, $ssamp$dmask$unorm$glc$slc$r128$tfe$lwe$da",
3513  dns>, MIMGe<op> {
3514  let WQM = wqm;
3515}
3516
3517multiclass MIMG_Sampler_Src_Helper <bits<7> op, string asm,
3518                                    RegisterClass dst_rc,
3519                                    int channels, int wqm> {
3520  def _V1 : MIMG_Sampler_Helper <op, asm, dst_rc, VGPR_32, wqm,
3521                                 !if(!eq(channels, 1), "AMDGPU", "")>,
3522            MIMG_Mask<asm#"_V1", channels>;
3523  def _V2 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_64, wqm>,
3524            MIMG_Mask<asm#"_V2", channels>;
3525  def _V4 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_128, wqm>,
3526            MIMG_Mask<asm#"_V4", channels>;
3527  def _V8 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_256, wqm>,
3528            MIMG_Mask<asm#"_V8", channels>;
3529  def _V16 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_512, wqm>,
3530            MIMG_Mask<asm#"_V16", channels>;
3531}
3532
3533multiclass MIMG_Sampler <bits<7> op, string asm, int wqm=0> {
3534  defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VGPR_32, 1, wqm>;
3535  defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2, wqm>;
3536  defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3, wqm>;
3537  defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4, wqm>;
3538}
3539
3540multiclass MIMG_Sampler_WQM <bits<7> op, string asm> : MIMG_Sampler<op, asm, 1>;
3541
3542class MIMG_Gather_Helper <bits<7> op, string asm,
3543                          RegisterClass dst_rc,
3544                          RegisterClass src_rc, int wqm> : MIMG <
3545  (outs dst_rc:$vdata),
3546  (ins src_rc:$vaddr, SReg_256:$srsrc, SReg_128:$ssamp,
3547       dmask:$dmask, unorm:$unorm, glc:$glc, slc:$slc,
3548       r128:$r128, tfe:$tfe, lwe:$lwe, da:$da),
3549  asm#" $vdata, $vaddr, $srsrc, $ssamp$dmask$unorm$glc$slc$r128$tfe$lwe$da",
3550  []>, MIMGe<op> {
3551  let mayLoad = 1;
3552  let mayStore = 0;
3553
3554  // DMASK was repurposed for GATHER4. 4 components are always
3555  // returned and DMASK works like a swizzle - it selects
3556  // the component to fetch. The only useful DMASK values are
3557  // 1=red, 2=green, 4=blue, 8=alpha. (e.g. 1 returns
3558  // (red,red,red,red) etc.) The ISA document doesn't mention
3559  // this.
3560  // Therefore, disable all code which updates DMASK by setting this:
3561  let Gather4 = 1;
3562  let hasPostISelHook = 0;
3563  let WQM = wqm;
3564
3565  let isAsmParserOnly = 1; // TBD: fix it later
3566}
3567
3568multiclass MIMG_Gather_Src_Helper <bits<7> op, string asm,
3569                                    RegisterClass dst_rc,
3570                                    int channels, int wqm> {
3571  def _V1 : MIMG_Gather_Helper <op, asm, dst_rc, VGPR_32, wqm>,
3572            MIMG_Mask<asm#"_V1", channels>;
3573  def _V2 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_64, wqm>,
3574            MIMG_Mask<asm#"_V2", channels>;
3575  def _V4 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_128, wqm>,
3576            MIMG_Mask<asm#"_V4", channels>;
3577  def _V8 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_256, wqm>,
3578            MIMG_Mask<asm#"_V8", channels>;
3579  def _V16 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_512, wqm>,
3580            MIMG_Mask<asm#"_V16", channels>;
3581}
3582
3583multiclass MIMG_Gather <bits<7> op, string asm, int wqm=0> {
3584  defm _V1 : MIMG_Gather_Src_Helper<op, asm, VGPR_32, 1, wqm>;
3585  defm _V2 : MIMG_Gather_Src_Helper<op, asm, VReg_64, 2, wqm>;
3586  defm _V3 : MIMG_Gather_Src_Helper<op, asm, VReg_96, 3, wqm>;
3587  defm _V4 : MIMG_Gather_Src_Helper<op, asm, VReg_128, 4, wqm>;
3588}
3589
3590multiclass MIMG_Gather_WQM <bits<7> op, string asm> : MIMG_Gather<op, asm, 1>;
3591
3592//===----------------------------------------------------------------------===//
3593// Vector instruction mappings
3594//===----------------------------------------------------------------------===//
3595
3596// Maps an opcode in e32 form to its e64 equivalent
3597def getVOPe64 : InstrMapping {
3598  let FilterClass = "VOP";
3599  let RowFields = ["OpName"];
3600  let ColFields = ["Size"];
3601  let KeyCol = ["4"];
3602  let ValueCols = [["8"]];
3603}
3604
3605// Maps an opcode in e64 form to its e32 equivalent
3606def getVOPe32 : InstrMapping {
3607  let FilterClass = "VOP";
3608  let RowFields = ["OpName"];
3609  let ColFields = ["Size"];
3610  let KeyCol = ["8"];
3611  let ValueCols = [["4"]];
3612}
3613
3614def getMaskedMIMGOp : InstrMapping {
3615  let FilterClass = "MIMG_Mask";
3616  let RowFields = ["Op"];
3617  let ColFields = ["Channels"];
3618  let KeyCol = ["4"];
3619  let ValueCols = [["1"], ["2"], ["3"] ];
3620}
3621
3622// Maps an commuted opcode to its original version
3623def getCommuteOrig : InstrMapping {
3624  let FilterClass = "VOP2_REV";
3625  let RowFields = ["RevOp"];
3626  let ColFields = ["IsOrig"];
3627  let KeyCol = ["0"];
3628  let ValueCols = [["1"]];
3629}
3630
3631// Maps an original opcode to its commuted version
3632def getCommuteRev : InstrMapping {
3633  let FilterClass = "VOP2_REV";
3634  let RowFields = ["RevOp"];
3635  let ColFields = ["IsOrig"];
3636  let KeyCol = ["1"];
3637  let ValueCols = [["0"]];
3638}
3639
3640def getCommuteCmpOrig : InstrMapping {
3641  let FilterClass = "VOP2_REV";
3642  let RowFields = ["RevOp"];
3643  let ColFields = ["IsOrig"];
3644  let KeyCol = ["0"];
3645  let ValueCols = [["1"]];
3646}
3647
3648// Maps an original opcode to its commuted version
3649def getCommuteCmpRev : InstrMapping {
3650  let FilterClass = "VOP2_REV";
3651  let RowFields = ["RevOp"];
3652  let ColFields = ["IsOrig"];
3653  let KeyCol = ["1"];
3654  let ValueCols = [["0"]];
3655}
3656
3657
3658def getMCOpcodeGen : InstrMapping {
3659  let FilterClass = "SIMCInstr";
3660  let RowFields = ["PseudoInstr"];
3661  let ColFields = ["Subtarget"];
3662  let KeyCol = [!cast<string>(SIEncodingFamily.NONE)];
3663  let ValueCols = [[!cast<string>(SIEncodingFamily.SI)],
3664                   [!cast<string>(SIEncodingFamily.VI)]];
3665}
3666
3667def getAddr64Inst : InstrMapping {
3668  let FilterClass = "MUBUFAddr64Table";
3669  let RowFields = ["OpName"];
3670  let ColFields = ["IsAddr64"];
3671  let KeyCol = ["0"];
3672  let ValueCols = [["1"]];
3673}
3674
3675// Maps an atomic opcode to its version with a return value.
3676def getAtomicRetOp : InstrMapping {
3677  let FilterClass = "AtomicNoRet";
3678  let RowFields = ["NoRetOp"];
3679  let ColFields = ["IsRet"];
3680  let KeyCol = ["0"];
3681  let ValueCols = [["1"]];
3682}
3683
3684// Maps an atomic opcode to its returnless version.
3685def getAtomicNoRetOp : InstrMapping {
3686  let FilterClass = "AtomicNoRet";
3687  let RowFields = ["NoRetOp"];
3688  let ColFields = ["IsRet"];
3689  let KeyCol = ["1"];
3690  let ValueCols = [["0"]];
3691}
3692
3693include "SIInstructions.td"
3694include "CIInstructions.td"
3695include "VIInstructions.td"
3696