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