Home | History | Annotate | Download | only in R600
      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 
     10 // Execpt for the NONE field, this must be kept in sync with the SISubtarget enum
     11 // in AMDGPUMCInstLower.h
     12 def SISubtarget {
     13   int NONE = -1;
     14   int SI = 0;
     15 }
     16 
     17 //===----------------------------------------------------------------------===//
     18 // SI DAG Nodes
     19 //===----------------------------------------------------------------------===//
     20 
     21 def SIload_constant : SDNode<"AMDGPUISD::LOAD_CONSTANT",
     22   SDTypeProfile<1, 2, [SDTCisVT<0, f32>, SDTCisVT<1, v4i32>, SDTCisVT<2, i32>]>,
     23                       [SDNPMayLoad, SDNPMemOperand]
     24 >;
     25 
     26 def SItbuffer_store : SDNode<"AMDGPUISD::TBUFFER_STORE_FORMAT",
     27   SDTypeProfile<0, 13,
     28     [SDTCisVT<0, v4i32>,   // rsrc(SGPR)
     29      SDTCisVT<1, iAny>,   // vdata(VGPR)
     30      SDTCisVT<2, i32>,    // num_channels(imm)
     31      SDTCisVT<3, i32>,    // vaddr(VGPR)
     32      SDTCisVT<4, i32>,    // soffset(SGPR)
     33      SDTCisVT<5, i32>,    // inst_offset(imm)
     34      SDTCisVT<6, i32>,    // dfmt(imm)
     35      SDTCisVT<7, i32>,    // nfmt(imm)
     36      SDTCisVT<8, i32>,    // offen(imm)
     37      SDTCisVT<9, i32>,    // idxen(imm)
     38      SDTCisVT<10, i32>,   // glc(imm)
     39      SDTCisVT<11, i32>,   // slc(imm)
     40      SDTCisVT<12, i32>    // tfe(imm)
     41     ]>,
     42   [SDNPMayStore, SDNPMemOperand, SDNPHasChain]
     43 >;
     44 
     45 def SIload_input : SDNode<"AMDGPUISD::LOAD_INPUT",
     46   SDTypeProfile<1, 3, [SDTCisVT<0, v4f32>, SDTCisVT<1, v4i32>, SDTCisVT<2, i16>,
     47                        SDTCisVT<3, i32>]>
     48 >;
     49 
     50 class SDSample<string opcode> : SDNode <opcode,
     51   SDTypeProfile<1, 4, [SDTCisVT<0, v4f32>, SDTCisVT<2, v32i8>,
     52                        SDTCisVT<3, v4i32>, SDTCisVT<4, i32>]>
     53 >;
     54 
     55 def SIsample : SDSample<"AMDGPUISD::SAMPLE">;
     56 def SIsampleb : SDSample<"AMDGPUISD::SAMPLEB">;
     57 def SIsampled : SDSample<"AMDGPUISD::SAMPLED">;
     58 def SIsamplel : SDSample<"AMDGPUISD::SAMPLEL">;
     59 
     60 // Transformation function, extract the lower 32bit of a 64bit immediate
     61 def LO32 : SDNodeXForm<imm, [{
     62   return CurDAG->getTargetConstant(N->getZExtValue() & 0xffffffff, MVT::i32);
     63 }]>;
     64 
     65 def LO32f : SDNodeXForm<fpimm, [{
     66   APInt V = N->getValueAPF().bitcastToAPInt().trunc(32);
     67   return CurDAG->getTargetConstantFP(APFloat(APFloat::IEEEsingle, V), MVT::f32);
     68 }]>;
     69 
     70 // Transformation function, extract the upper 32bit of a 64bit immediate
     71 def HI32 : SDNodeXForm<imm, [{
     72   return CurDAG->getTargetConstant(N->getZExtValue() >> 32, MVT::i32);
     73 }]>;
     74 
     75 def HI32f : SDNodeXForm<fpimm, [{
     76   APInt V = N->getValueAPF().bitcastToAPInt().lshr(32).trunc(32);
     77   return CurDAG->getTargetConstantFP(APFloat(APFloat::IEEEsingle, V), MVT::f32);
     78 }]>;
     79 
     80 def IMM8bitDWORD : PatLeaf <(imm),
     81   [{return (N->getZExtValue() & ~0x3FC) == 0;}]
     82 >;
     83 
     84 def as_dword_i32imm : SDNodeXForm<imm, [{
     85   return CurDAG->getTargetConstant(N->getZExtValue() >> 2, MVT::i32);
     86 }]>;
     87 
     88 def as_i1imm : SDNodeXForm<imm, [{
     89   return CurDAG->getTargetConstant(N->getZExtValue(), MVT::i1);
     90 }]>;
     91 
     92 def as_i8imm : SDNodeXForm<imm, [{
     93   return CurDAG->getTargetConstant(N->getZExtValue(), MVT::i8);
     94 }]>;
     95 
     96 def as_i16imm : SDNodeXForm<imm, [{
     97   return CurDAG->getTargetConstant(N->getSExtValue(), MVT::i16);
     98 }]>;
     99 
    100 def as_i32imm: SDNodeXForm<imm, [{
    101   return CurDAG->getTargetConstant(N->getSExtValue(), MVT::i32);
    102 }]>;
    103 
    104 def IMM8bit : PatLeaf <(imm),
    105   [{return isUInt<8>(N->getZExtValue());}]
    106 >;
    107 
    108 def IMM12bit : PatLeaf <(imm),
    109   [{return isUInt<12>(N->getZExtValue());}]
    110 >;
    111 
    112 def IMM16bit : PatLeaf <(imm),
    113   [{return isUInt<16>(N->getZExtValue());}]
    114 >;
    115 
    116 def IMM32bit : PatLeaf <(imm),
    117   [{return isUInt<32>(N->getZExtValue());}]
    118 >;
    119 
    120 def mubuf_vaddr_offset : PatFrag<
    121   (ops node:$ptr, node:$offset, node:$imm_offset),
    122   (add (add node:$ptr, node:$offset), node:$imm_offset)
    123 >;
    124 
    125 class InlineImm <ValueType vt> : PatLeaf <(vt imm), [{
    126   return isInlineImmediate(N);
    127 }]>;
    128 
    129 class SGPRImm <dag frag> : PatLeaf<frag, [{
    130   if (TM.getSubtarget<AMDGPUSubtarget>().getGeneration() <
    131       AMDGPUSubtarget::SOUTHERN_ISLANDS) {
    132     return false;
    133   }
    134   const SIRegisterInfo *SIRI =
    135                        static_cast<const SIRegisterInfo*>(TM.getRegisterInfo());
    136   for (SDNode::use_iterator U = N->use_begin(), E = SDNode::use_end();
    137                                                 U != E; ++U) {
    138     if (SIRI->isSGPRClass(getOperandRegClass(*U, U.getOperandNo()))) {
    139       return true;
    140     }
    141   }
    142   return false;
    143 }]>;
    144 
    145 def FRAMEri32 : Operand<iPTR> {
    146   let MIOperandInfo = (ops i32:$ptr, i32imm:$index);
    147 }
    148 
    149 //===----------------------------------------------------------------------===//
    150 // Complex patterns
    151 //===----------------------------------------------------------------------===//
    152 
    153 def MUBUFAddr64 : ComplexPattern<i64, 3, "SelectMUBUFAddr64">;
    154 
    155 //===----------------------------------------------------------------------===//
    156 // SI assembler operands
    157 //===----------------------------------------------------------------------===//
    158 
    159 def SIOperand {
    160   int ZERO = 0x80;
    161   int VCC = 0x6A;
    162 }
    163 
    164 include "SIInstrFormats.td"
    165 
    166 //===----------------------------------------------------------------------===//
    167 //
    168 // SI Instruction multiclass helpers.
    169 //
    170 // Instructions with _32 take 32-bit operands.
    171 // Instructions with _64 take 64-bit operands.
    172 //
    173 // VOP_* instructions can use either a 32-bit or 64-bit encoding.  The 32-bit
    174 // encoding is the standard encoding, but instruction that make use of
    175 // any of the instruction modifiers must use the 64-bit encoding.
    176 //
    177 // Instructions with _e32 use the 32-bit encoding.
    178 // Instructions with _e64 use the 64-bit encoding.
    179 //
    180 //===----------------------------------------------------------------------===//
    181 
    182 //===----------------------------------------------------------------------===//
    183 // Scalar classes
    184 //===----------------------------------------------------------------------===//
    185 
    186 class SOP1_32 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
    187   op, (outs SReg_32:$dst), (ins SSrc_32:$src0),
    188   opName#" $dst, $src0", pattern
    189 >;
    190 
    191 class SOP1_64 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
    192   op, (outs SReg_64:$dst), (ins SSrc_64:$src0),
    193   opName#" $dst, $src0", pattern
    194 >;
    195 
    196 // 64-bit input, 32-bit output.
    197 class SOP1_32_64 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
    198   op, (outs SReg_32:$dst), (ins SSrc_64:$src0),
    199   opName#" $dst, $src0", pattern
    200 >;
    201 
    202 class SOP2_32 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
    203   op, (outs SReg_32:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
    204   opName#" $dst, $src0, $src1", pattern
    205 >;
    206 
    207 class SOP2_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
    208   op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
    209   opName#" $dst, $src0, $src1", pattern
    210 >;
    211 
    212 class SOP2_SHIFT_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
    213   op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_32:$src1),
    214   opName#" $dst, $src0, $src1", pattern
    215 >;
    216 
    217 
    218 class SOPC_Helper <bits<7> op, RegisterClass rc, ValueType vt,
    219                     string opName, PatLeaf cond> : SOPC <
    220   op, (outs SCCReg:$dst), (ins rc:$src0, rc:$src1),
    221   opName#" $dst, $src0, $src1", []>;
    222 
    223 class SOPC_32<bits<7> op, string opName, PatLeaf cond = COND_NULL>
    224   : SOPC_Helper<op, SSrc_32, i32, opName, cond>;
    225 
    226 class SOPC_64<bits<7> op, string opName, PatLeaf cond = COND_NULL>
    227   : SOPC_Helper<op, SSrc_64, i64, opName, cond>;
    228 
    229 class SOPK_32 <bits<5> op, string opName, list<dag> pattern> : SOPK <
    230   op, (outs SReg_32:$dst), (ins i16imm:$src0),
    231   opName#" $dst, $src0", pattern
    232 >;
    233 
    234 class SOPK_64 <bits<5> op, string opName, list<dag> pattern> : SOPK <
    235   op, (outs SReg_64:$dst), (ins i16imm:$src0),
    236   opName#" $dst, $src0", pattern
    237 >;
    238 
    239 multiclass SMRD_Helper <bits<5> op, string asm, RegisterClass baseClass,
    240                         RegisterClass dstClass> {
    241   def _IMM : SMRD <
    242     op, 1, (outs dstClass:$dst),
    243     (ins baseClass:$sbase, u32imm:$offset),
    244     asm#" $dst, $sbase, $offset", []
    245   >;
    246 
    247   def _SGPR : SMRD <
    248     op, 0, (outs dstClass:$dst),
    249     (ins baseClass:$sbase, SReg_32:$soff),
    250     asm#" $dst, $sbase, $soff", []
    251   >;
    252 }
    253 
    254 //===----------------------------------------------------------------------===//
    255 // Vector ALU classes
    256 //===----------------------------------------------------------------------===//
    257 
    258 class VOP <string opName> {
    259   string OpName = opName;
    260 }
    261 
    262 class VOP2_REV <string revOp, bit isOrig> {
    263   string RevOp = revOp;
    264   bit IsOrig = isOrig;
    265 }
    266 
    267 class SIMCInstr <string pseudo, int subtarget> {
    268   string PseudoInstr = pseudo;
    269   int Subtarget = subtarget;
    270 }
    271 
    272 multiclass VOP3_m <bits<9> op, dag outs, dag ins, string asm, list<dag> pattern,
    273                    string opName> {
    274 
    275   def "" : VOP3Common <outs, ins, "", pattern>, VOP <opName>,
    276            SIMCInstr<OpName, SISubtarget.NONE> {
    277     let isPseudo = 1;
    278   }
    279 
    280   def _si : VOP3 <op, outs, ins, asm, []>, SIMCInstr<opName, SISubtarget.SI>;
    281 
    282 }
    283 
    284 // This must always be right before the operand being input modified.
    285 def InputMods : OperandWithDefaultOps <i32, (ops (i32 0))> {
    286   let PrintMethod = "printOperandAndMods";
    287 }
    288 
    289 multiclass VOP1_Helper <bits<8> op, RegisterClass drc, RegisterClass src,
    290                         string opName, list<dag> pattern> {
    291 
    292   def _e32 : VOP1 <
    293     op, (outs drc:$dst), (ins src:$src0),
    294     opName#"_e32 $dst, $src0", pattern
    295   >, VOP <opName>;
    296 
    297   def _e64 : VOP3 <
    298     {1, 1, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
    299     (outs drc:$dst),
    300     (ins InputMods:$src0_modifiers, src:$src0, i32imm:$clamp, i32imm:$omod),
    301     opName#"_e64 $dst, $src0_modifiers, $clamp, $omod", []
    302   >, VOP <opName> {
    303     let src1 = SIOperand.ZERO;
    304     let src2 = SIOperand.ZERO;
    305   }
    306 }
    307 
    308 multiclass VOP1_32 <bits<8> op, string opName, list<dag> pattern>
    309   : VOP1_Helper <op, VReg_32, VSrc_32, opName, pattern>;
    310 
    311 multiclass VOP1_64 <bits<8> op, string opName, list<dag> pattern>
    312   : VOP1_Helper <op, VReg_64, VSrc_64, opName, pattern>;
    313 
    314 multiclass VOP1_32_64 <bits<8> op, string opName, list<dag> pattern>
    315   : VOP1_Helper <op, VReg_32, VSrc_64, opName, pattern>;
    316 
    317 multiclass VOP1_64_32 <bits<8> op, string opName, list<dag> pattern>
    318   : VOP1_Helper <op, VReg_64, VSrc_32, opName, pattern>;
    319 
    320 multiclass VOP2_Helper <bits<6> op, RegisterClass vrc, RegisterClass arc,
    321                         string opName, list<dag> pattern, string revOp> {
    322   def _e32 : VOP2 <
    323     op, (outs vrc:$dst), (ins arc:$src0, vrc:$src1),
    324     opName#"_e32 $dst, $src0, $src1", pattern
    325   >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
    326 
    327   def _e64 : VOP3 <
    328     {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
    329     (outs vrc:$dst),
    330     (ins InputMods:$src0_modifiers, arc:$src0,
    331          InputMods:$src1_modifiers, arc:$src1,
    332          i32imm:$clamp, i32imm:$omod),
    333     opName#"_e64 $dst, $src0_modifiers, $src1_modifiers, $clamp, $omod", []
    334   >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
    335     let src2 = SIOperand.ZERO;
    336   }
    337 }
    338 
    339 multiclass VOP2_32 <bits<6> op, string opName, list<dag> pattern,
    340                     string revOp = opName>
    341   : VOP2_Helper <op, VReg_32, VSrc_32, opName, pattern, revOp>;
    342 
    343 multiclass VOP2_64 <bits<6> op, string opName, list<dag> pattern,
    344                     string revOp = opName>
    345   : VOP2_Helper <op, VReg_64, VSrc_64, opName, pattern, revOp>;
    346 
    347 multiclass VOP2b_32 <bits<6> op, string opName, list<dag> pattern,
    348                      RegisterClass src0_rc, string revOp = opName> {
    349 
    350   def _e32 : VOP2 <
    351     op, (outs VReg_32:$dst), (ins src0_rc:$src0, VReg_32:$src1),
    352     opName#"_e32 $dst, $src0, $src1", pattern
    353   >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
    354 
    355   def _e64 : VOP3b <
    356     {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
    357     (outs VReg_32:$dst),
    358     (ins InputMods: $src0_modifiers, VSrc_32:$src0,
    359          InputMods:$src1_modifiers, VSrc_32:$src1,
    360          i32imm:$clamp, i32imm:$omod),
    361     opName#"_e64 $dst, $src0_modifiers, $src1_modifiers, $clamp, $omod", []
    362   >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
    363     let src2 = SIOperand.ZERO;
    364     /* the VOP2 variant puts the carry out into VCC, the VOP3 variant
    365        can write it into any SGPR. We currently don't use the carry out,
    366        so for now hardcode it to VCC as well */
    367     let sdst = SIOperand.VCC;
    368   }
    369 }
    370 
    371 multiclass VOPC_Helper <bits<8> op, RegisterClass vrc, RegisterClass arc,
    372                         string opName, ValueType vt, PatLeaf cond, bit defExec = 0> {
    373   def _e32 : VOPC <
    374     op, (ins arc:$src0, vrc:$src1),
    375     opName#"_e32 $dst, $src0, $src1", []
    376   >, VOP <opName> {
    377     let Defs = !if(defExec, [VCC, EXEC], [VCC]);
    378   }
    379 
    380   def _e64 : VOP3 <
    381     {0, op{7}, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
    382     (outs SReg_64:$dst),
    383     (ins InputMods:$src0_modifiers, arc:$src0,
    384          InputMods:$src1_modifiers, arc:$src1,
    385          InstFlag:$clamp, InstFlag:$omod),
    386     opName#"_e64 $dst, $src0_modifiers, $src1_modifiers, $clamp, $omod",
    387     !if(!eq(!cast<string>(cond), "COND_NULL"), []<dag>,
    388       [(set SReg_64:$dst, (i1 (setcc (vt arc:$src0), arc:$src1, cond)))]
    389     )
    390   >, VOP <opName> {
    391     let Defs = !if(defExec, [EXEC], []);
    392     let src2 = SIOperand.ZERO;
    393     let src2_modifiers = 0;
    394   }
    395 }
    396 
    397 multiclass VOPC_32 <bits<8> op, string opName,
    398   ValueType vt = untyped, PatLeaf cond = COND_NULL>
    399   : VOPC_Helper <op, VReg_32, VSrc_32, opName, vt, cond>;
    400 
    401 multiclass VOPC_64 <bits<8> op, string opName,
    402   ValueType vt = untyped, PatLeaf cond = COND_NULL>
    403   : VOPC_Helper <op, VReg_64, VSrc_64, opName, vt, cond>;
    404 
    405 multiclass VOPCX_32 <bits<8> op, string opName,
    406   ValueType vt = untyped, PatLeaf cond = COND_NULL>
    407   : VOPC_Helper <op, VReg_32, VSrc_32, opName, vt, cond, 1>;
    408 
    409 multiclass VOPCX_64 <bits<8> op, string opName,
    410   ValueType vt = untyped, PatLeaf cond = COND_NULL>
    411   : VOPC_Helper <op, VReg_64, VSrc_64, opName, vt, cond, 1>;
    412 
    413 multiclass VOP3_32 <bits<9> op, string opName, list<dag> pattern> : VOP3_m <
    414   op, (outs VReg_32:$dst),
    415   (ins InputMods: $src0_modifiers, VSrc_32:$src0, InputMods:$src1_modifiers,
    416    VSrc_32:$src1, InputMods:$src2_modifiers, VSrc_32:$src2,
    417    InstFlag:$clamp, InstFlag:$omod),
    418   opName#" $dst, $src0_modifiers, $src1, $src2, $clamp, $omod", pattern, opName
    419 >;
    420 
    421 class VOP3_64_32 <bits <9> op, string opName, list<dag> pattern> : VOP3 <
    422   op, (outs VReg_64:$dst),
    423   (ins VSrc_64:$src0, VSrc_32:$src1),
    424   opName#" $dst, $src0, $src1", pattern
    425 >, VOP <opName> {
    426 
    427   let src2 = SIOperand.ZERO;
    428   let src0_modifiers = 0;
    429   let clamp = 0;
    430   let omod = 0;
    431 }
    432 
    433 class VOP3_64 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
    434   op, (outs VReg_64:$dst),
    435   (ins InputMods:$src0_modifiers, VSrc_64:$src0,
    436        InputMods:$src1_modifiers, VSrc_64:$src1,
    437        InputMods:$src2_modifiers, VSrc_64:$src2,
    438        InstFlag:$clamp, InstFlag:$omod),
    439   opName#" $dst, $src0_modifiers, $src1_modifiers, $src2_modifiers, $clamp, $omod", pattern
    440 >, VOP <opName>;
    441 
    442 
    443 class VOP3b_Helper <bits<9> op, RegisterClass vrc, RegisterClass arc,
    444                     string opName, list<dag> pattern> : VOP3 <
    445   op, (outs vrc:$dst0, SReg_64:$dst1),
    446   (ins arc:$src0, arc:$src1, arc:$src2,
    447    InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg),
    448   opName#" $dst0, $dst1, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
    449 >, VOP <opName>;
    450 
    451 
    452 class VOP3b_64 <bits<9> op, string opName, list<dag> pattern> :
    453   VOP3b_Helper <op, VReg_64, VSrc_64, opName, pattern>;
    454 
    455 class VOP3b_32 <bits<9> op, string opName, list<dag> pattern> :
    456   VOP3b_Helper <op, VReg_32, VSrc_32, opName, pattern>;
    457 
    458 //===----------------------------------------------------------------------===//
    459 // Vector I/O classes
    460 //===----------------------------------------------------------------------===//
    461 
    462 class DS_1A <bits<8> op, dag outs, dag ins, string asm, list<dag> pat> :
    463     DS <op, outs, ins, asm, pat> {
    464   bits<16> offset;
    465 
    466   // Single load interpret the 2 i8imm operands as a single i16 offset.
    467   let offset0 = offset{7-0};
    468   let offset1 = offset{15-8};
    469 }
    470 
    471 class DS_Load_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
    472   op,
    473   (outs regClass:$vdst),
    474   (ins i1imm:$gds, VReg_32:$addr, u16imm:$offset),
    475   asm#" $vdst, $addr, $offset, [M0]",
    476   []> {
    477   let data0 = 0;
    478   let data1 = 0;
    479   let mayLoad = 1;
    480   let mayStore = 0;
    481 }
    482 
    483 class DS_Load2_Helper <bits<8> op, string asm, RegisterClass regClass> : DS <
    484   op,
    485   (outs regClass:$vdst),
    486   (ins i1imm:$gds, VReg_32:$addr, u8imm:$offset0, u8imm:$offset1),
    487   asm#" $gds, $vdst, $addr, $offset0, $offset1, [M0]",
    488   []> {
    489   let data0 = 0;
    490   let data1 = 0;
    491   let mayLoad = 1;
    492   let mayStore = 0;
    493 }
    494 
    495 class DS_Store_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
    496   op,
    497   (outs),
    498   (ins i1imm:$gds, VReg_32:$addr, regClass:$data0, u16imm:$offset),
    499   asm#" $addr, $data0, $offset [M0]",
    500   []> {
    501   let data1 = 0;
    502   let mayStore = 1;
    503   let mayLoad = 0;
    504   let vdst = 0;
    505 }
    506 
    507 class DS_Store2_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
    508   op,
    509   (outs),
    510   (ins i1imm:$gds, VReg_32:$addr, regClass:$data0, u8imm:$offset0, u8imm:$offset1),
    511   asm#" $addr, $data0, $data1, $offset0, $offset1 [M0]",
    512   []> {
    513   let mayStore = 1;
    514   let mayLoad = 0;
    515   let vdst = 0;
    516 }
    517 
    518 // 1 address, 1 data.
    519 class DS_1A1D_RET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
    520   op,
    521   (outs rc:$vdst),
    522   (ins i1imm:$gds, VReg_32:$addr, rc:$data0, u16imm:$offset),
    523   asm#" $vdst, $addr, $data0, $offset, [M0]",
    524   []> {
    525 
    526   let data1 = 0;
    527   let mayStore = 1;
    528   let mayLoad = 1;
    529 }
    530 
    531 // 1 address, 2 data.
    532 class DS_1A2D_RET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
    533   op,
    534   (outs rc:$vdst),
    535   (ins i1imm:$gds, VReg_32:$addr, rc:$data0, rc:$data1, u16imm:$offset),
    536   asm#" $vdst, $addr, $data0, $data1, $offset, [M0]",
    537   []> {
    538   let mayStore = 1;
    539   let mayLoad = 1;
    540 }
    541 
    542 // 1 address, 2 data.
    543 class DS_1A2D_NORET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
    544   op,
    545   (outs),
    546   (ins i1imm:$gds, VReg_32:$addr, rc:$data0, rc:$data1, u16imm:$offset),
    547   asm#" $addr, $data0, $data1, $offset, [M0]",
    548   []> {
    549   let mayStore = 1;
    550   let mayLoad = 1;
    551 }
    552 
    553 // 1 address, 1 data.
    554 class DS_1A1D_NORET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
    555   op,
    556   (outs),
    557   (ins i1imm:$gds, VReg_32:$addr, rc:$data0, u16imm:$offset),
    558   asm#" $addr, $data0, $offset, [M0]",
    559   []> {
    560 
    561   let data1 = 0;
    562   let mayStore = 1;
    563   let mayLoad = 1;
    564 }
    565 
    566 class MTBUF_Store_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
    567   op,
    568   (outs),
    569   (ins regClass:$vdata, u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
    570    i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr,
    571    SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
    572   asm#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
    573      #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
    574   []> {
    575   let mayStore = 1;
    576   let mayLoad = 0;
    577 }
    578 
    579 multiclass MUBUF_Load_Helper <bits<7> op, string asm, RegisterClass regClass,
    580                               ValueType load_vt = i32,
    581                               SDPatternOperator ld = null_frag> {
    582 
    583   let lds = 0, mayLoad = 1 in {
    584 
    585     let addr64 = 0 in {
    586 
    587       let offen = 0, idxen = 0 in {
    588         def _OFFSET : MUBUF <op, (outs regClass:$vdata),
    589                              (ins SReg_128:$srsrc, VReg_32:$vaddr,
    590                              u16imm:$offset, SSrc_32:$soffset, i1imm:$glc,
    591                              i1imm:$slc, i1imm:$tfe),
    592                              asm#" $vdata, $srsrc + $offset + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
    593       }
    594 
    595       let offen = 1, idxen = 0, offset = 0 in {
    596         def _OFFEN  : MUBUF <op, (outs regClass:$vdata),
    597                              (ins SReg_128:$srsrc, VReg_32:$vaddr,
    598                              SSrc_32:$soffset, i1imm:$glc, i1imm:$slc,
    599                              i1imm:$tfe),
    600                              asm#" $vdata, $srsrc + $vaddr + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
    601       }
    602 
    603       let offen = 0, idxen = 1 in {
    604         def _IDXEN  : MUBUF <op, (outs regClass:$vdata),
    605                              (ins SReg_128:$srsrc, VReg_32:$vaddr,
    606                              u16imm:$offset, SSrc_32:$soffset, i1imm:$glc,
    607                              i1imm:$slc, i1imm:$tfe),
    608                              asm#" $vdata, $srsrc[$vaddr] + $offset + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
    609       }
    610 
    611       let offen = 1, idxen = 1 in {
    612         def _BOTHEN : MUBUF <op, (outs regClass:$vdata),
    613                              (ins SReg_128:$srsrc, VReg_64:$vaddr,
    614                              SSrc_32:$soffset, i1imm:$glc,
    615                              i1imm:$slc, i1imm:$tfe),
    616                              asm#" $vdata, $srsrc[$vaddr[0]] + $vaddr[1] + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
    617       }
    618     }
    619 
    620     let offen = 0, idxen = 0, addr64 = 1, glc = 0, slc = 0, tfe = 0, soffset = 128 /* ZERO */ in {
    621       def _ADDR64 : MUBUF <op, (outs regClass:$vdata),
    622                            (ins SReg_128:$srsrc, VReg_64:$vaddr, u16imm:$offset),
    623                            asm#" $vdata, $srsrc + $vaddr + $offset",
    624                            [(set load_vt:$vdata, (ld (MUBUFAddr64 v4i32:$srsrc,
    625                                                   i64:$vaddr, u16imm:$offset)))]>;
    626     }
    627   }
    628 }
    629 
    630 class MUBUF_Store_Helper <bits<7> op, string name, RegisterClass vdataClass,
    631                           ValueType store_vt, SDPatternOperator st> :
    632     MUBUF <op, (outs), (ins vdataClass:$vdata, SReg_128:$srsrc, VReg_64:$vaddr,
    633                             u16imm:$offset),
    634           name#" $vdata, $srsrc + $vaddr + $offset",
    635           [(st store_vt:$vdata, (MUBUFAddr64 v4i32:$srsrc, i64:$vaddr, u16imm:$offset))]> {
    636 
    637   let mayLoad = 0;
    638   let mayStore = 1;
    639 
    640   // Encoding
    641   let offen = 0;
    642   let idxen = 0;
    643   let glc = 0;
    644   let addr64 = 1;
    645   let lds = 0;
    646   let slc = 0;
    647   let tfe = 0;
    648   let soffset = 128; // ZERO
    649 }
    650 
    651 class MTBUF_Load_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
    652   op,
    653   (outs regClass:$dst),
    654   (ins u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
    655        i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, SReg_128:$srsrc,
    656        i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
    657   asm#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
    658      #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
    659   []> {
    660   let mayLoad = 1;
    661   let mayStore = 0;
    662 }
    663 
    664 class MIMG_Mask <string op, int channels> {
    665   string Op = op;
    666   int Channels = channels;
    667 }
    668 
    669 class MIMG_NoSampler_Helper <bits<7> op, string asm,
    670                              RegisterClass dst_rc,
    671                              RegisterClass src_rc> : MIMG <
    672   op,
    673   (outs dst_rc:$vdata),
    674   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
    675        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
    676        SReg_256:$srsrc),
    677   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
    678      #" $tfe, $lwe, $slc, $vaddr, $srsrc",
    679   []> {
    680   let SSAMP = 0;
    681   let mayLoad = 1;
    682   let mayStore = 0;
    683   let hasPostISelHook = 1;
    684 }
    685 
    686 multiclass MIMG_NoSampler_Src_Helper <bits<7> op, string asm,
    687                                       RegisterClass dst_rc,
    688                                       int channels> {
    689   def _V1 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_32>,
    690             MIMG_Mask<asm#"_V1", channels>;
    691   def _V2 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_64>,
    692             MIMG_Mask<asm#"_V2", channels>;
    693   def _V4 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_128>,
    694             MIMG_Mask<asm#"_V4", channels>;
    695 }
    696 
    697 multiclass MIMG_NoSampler <bits<7> op, string asm> {
    698   defm _V1 : MIMG_NoSampler_Src_Helper <op, asm, VReg_32, 1>;
    699   defm _V2 : MIMG_NoSampler_Src_Helper <op, asm, VReg_64, 2>;
    700   defm _V3 : MIMG_NoSampler_Src_Helper <op, asm, VReg_96, 3>;
    701   defm _V4 : MIMG_NoSampler_Src_Helper <op, asm, VReg_128, 4>;
    702 }
    703 
    704 class MIMG_Sampler_Helper <bits<7> op, string asm,
    705                            RegisterClass dst_rc,
    706                            RegisterClass src_rc> : MIMG <
    707   op,
    708   (outs dst_rc:$vdata),
    709   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
    710        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
    711        SReg_256:$srsrc, SReg_128:$ssamp),
    712   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
    713      #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
    714   []> {
    715   let mayLoad = 1;
    716   let mayStore = 0;
    717   let hasPostISelHook = 1;
    718 }
    719 
    720 multiclass MIMG_Sampler_Src_Helper <bits<7> op, string asm,
    721                                     RegisterClass dst_rc,
    722                                     int channels> {
    723   def _V1 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_32>,
    724             MIMG_Mask<asm#"_V1", channels>;
    725   def _V2 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_64>,
    726             MIMG_Mask<asm#"_V2", channels>;
    727   def _V4 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_128>,
    728             MIMG_Mask<asm#"_V4", channels>;
    729   def _V8 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_256>,
    730             MIMG_Mask<asm#"_V8", channels>;
    731   def _V16 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_512>,
    732             MIMG_Mask<asm#"_V16", channels>;
    733 }
    734 
    735 multiclass MIMG_Sampler <bits<7> op, string asm> {
    736   defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VReg_32, 1>;
    737   defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2>;
    738   defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3>;
    739   defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4>;
    740 }
    741 
    742 class MIMG_Gather_Helper <bits<7> op, string asm,
    743                           RegisterClass dst_rc,
    744                           RegisterClass src_rc> : MIMG <
    745   op,
    746   (outs dst_rc:$vdata),
    747   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
    748        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
    749        SReg_256:$srsrc, SReg_128:$ssamp),
    750   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
    751      #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
    752   []> {
    753   let mayLoad = 1;
    754   let mayStore = 0;
    755 
    756   // DMASK was repurposed for GATHER4. 4 components are always
    757   // returned and DMASK works like a swizzle - it selects
    758   // the component to fetch. The only useful DMASK values are
    759   // 1=red, 2=green, 4=blue, 8=alpha. (e.g. 1 returns
    760   // (red,red,red,red) etc.) The ISA document doesn't mention
    761   // this.
    762   // Therefore, disable all code which updates DMASK by setting these two:
    763   let MIMG = 0;
    764   let hasPostISelHook = 0;
    765 }
    766 
    767 multiclass MIMG_Gather_Src_Helper <bits<7> op, string asm,
    768                                     RegisterClass dst_rc,
    769                                     int channels> {
    770   def _V1 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_32>,
    771             MIMG_Mask<asm#"_V1", channels>;
    772   def _V2 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_64>,
    773             MIMG_Mask<asm#"_V2", channels>;
    774   def _V4 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_128>,
    775             MIMG_Mask<asm#"_V4", channels>;
    776   def _V8 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_256>,
    777             MIMG_Mask<asm#"_V8", channels>;
    778   def _V16 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_512>,
    779             MIMG_Mask<asm#"_V16", channels>;
    780 }
    781 
    782 multiclass MIMG_Gather <bits<7> op, string asm> {
    783   defm _V1 : MIMG_Gather_Src_Helper<op, asm, VReg_32, 1>;
    784   defm _V2 : MIMG_Gather_Src_Helper<op, asm, VReg_64, 2>;
    785   defm _V3 : MIMG_Gather_Src_Helper<op, asm, VReg_96, 3>;
    786   defm _V4 : MIMG_Gather_Src_Helper<op, asm, VReg_128, 4>;
    787 }
    788 
    789 //===----------------------------------------------------------------------===//
    790 // Vector instruction mappings
    791 //===----------------------------------------------------------------------===//
    792 
    793 // Maps an opcode in e32 form to its e64 equivalent
    794 def getVOPe64 : InstrMapping {
    795   let FilterClass = "VOP";
    796   let RowFields = ["OpName"];
    797   let ColFields = ["Size"];
    798   let KeyCol = ["4"];
    799   let ValueCols = [["8"]];
    800 }
    801 
    802 // Maps an original opcode to its commuted version
    803 def getCommuteRev : InstrMapping {
    804   let FilterClass = "VOP2_REV";
    805   let RowFields = ["RevOp"];
    806   let ColFields = ["IsOrig"];
    807   let KeyCol = ["1"];
    808   let ValueCols = [["0"]];
    809 }
    810 
    811 def getMaskedMIMGOp : InstrMapping {
    812   let FilterClass = "MIMG_Mask";
    813   let RowFields = ["Op"];
    814   let ColFields = ["Channels"];
    815   let KeyCol = ["4"];
    816   let ValueCols = [["1"], ["2"], ["3"] ];
    817 }
    818 
    819 // Maps an commuted opcode to its original version
    820 def getCommuteOrig : InstrMapping {
    821   let FilterClass = "VOP2_REV";
    822   let RowFields = ["RevOp"];
    823   let ColFields = ["IsOrig"];
    824   let KeyCol = ["0"];
    825   let ValueCols = [["1"]];
    826 }
    827 
    828 def isDS : InstrMapping {
    829   let FilterClass = "DS";
    830   let RowFields = ["Inst"];
    831   let ColFields = ["Size"];
    832   let KeyCol = ["8"];
    833   let ValueCols = [["8"]];
    834 }
    835 
    836 def getMCOpcode : InstrMapping {
    837   let FilterClass = "SIMCInstr";
    838   let RowFields = ["PseudoInstr"];
    839   let ColFields = ["Subtarget"];
    840   let KeyCol = [!cast<string>(SISubtarget.NONE)];
    841   let ValueCols = [[!cast<string>(SISubtarget.SI)]];
    842 }
    843 
    844 include "SIInstructions.td"
    845