SIInstrInfo.td revision 251662
1249259Sdim//===-- SIInstrInfo.td - SI Instruction Infos -------------*- tablegen -*--===// 2249259Sdim// 3249259Sdim// The LLVM Compiler Infrastructure 4249259Sdim// 5249259Sdim// This file is distributed under the University of Illinois Open Source 6249259Sdim// License. See LICENSE.TXT for details. 7249259Sdim// 8249259Sdim//===----------------------------------------------------------------------===// 9249259Sdim 10249259Sdim//===----------------------------------------------------------------------===// 11249259Sdim// SI DAG Nodes 12249259Sdim//===----------------------------------------------------------------------===// 13249259Sdim 14249259Sdim// SMRD takes a 64bit memory address and can only add an 32bit offset 15249259Sdimdef SIadd64bit32bit : SDNode<"ISD::ADD", 16249259Sdim SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>, SDTCisVT<0, i64>, SDTCisVT<2, i32>]> 17249259Sdim>; 18249259Sdim 19249259Sdim// Transformation function, extract the lower 32bit of a 64bit immediate 20249259Sdimdef LO32 : SDNodeXForm<imm, [{ 21249259Sdim return CurDAG->getTargetConstant(N->getZExtValue() & 0xffffffff, MVT::i32); 22249259Sdim}]>; 23249259Sdim 24249259Sdim// Transformation function, extract the upper 32bit of a 64bit immediate 25249259Sdimdef HI32 : SDNodeXForm<imm, [{ 26249259Sdim return CurDAG->getTargetConstant(N->getZExtValue() >> 32, MVT::i32); 27249259Sdim}]>; 28249259Sdim 29251662Sdimdef SIbuffer_store : SDNode<"AMDGPUISD::BUFFER_STORE", 30251662Sdim SDTypeProfile<0, 3, [SDTCisPtrTy<1>, SDTCisInt<2>]>, 31251662Sdim [SDNPHasChain, SDNPMayStore]>; 32251662Sdim 33249259Sdimdef IMM8bitDWORD : ImmLeaf < 34249259Sdim i32, [{ 35249259Sdim return (Imm & ~0x3FC) == 0; 36249259Sdim }], SDNodeXForm<imm, [{ 37249259Sdim return CurDAG->getTargetConstant( 38249259Sdim N->getZExtValue() >> 2, MVT::i32); 39249259Sdim }]> 40249259Sdim>; 41249259Sdim 42249259Sdimdef IMM12bit : ImmLeaf < 43249259Sdim i16, 44249259Sdim [{return isUInt<12>(Imm);}] 45249259Sdim>; 46249259Sdim 47249259Sdimclass InlineImm <ValueType vt> : PatLeaf <(vt imm), [{ 48249259Sdim return ((const SITargetLowering &)TLI).analyzeImmediate(N) == 0; 49249259Sdim}]>; 50249259Sdim 51249259Sdim//===----------------------------------------------------------------------===// 52249259Sdim// SI assembler operands 53249259Sdim//===----------------------------------------------------------------------===// 54249259Sdim 55249259Sdimdef SIOperand { 56249259Sdim int ZERO = 0x80; 57249259Sdim int VCC = 0x6A; 58249259Sdim} 59249259Sdim 60249259Sdiminclude "SIInstrFormats.td" 61249259Sdim 62249259Sdim//===----------------------------------------------------------------------===// 63249259Sdim// 64249259Sdim// SI Instruction multiclass helpers. 65249259Sdim// 66249259Sdim// Instructions with _32 take 32-bit operands. 67249259Sdim// Instructions with _64 take 64-bit operands. 68249259Sdim// 69249259Sdim// VOP_* instructions can use either a 32-bit or 64-bit encoding. The 32-bit 70249259Sdim// encoding is the standard encoding, but instruction that make use of 71249259Sdim// any of the instruction modifiers must use the 64-bit encoding. 72249259Sdim// 73249259Sdim// Instructions with _e32 use the 32-bit encoding. 74249259Sdim// Instructions with _e64 use the 64-bit encoding. 75249259Sdim// 76249259Sdim//===----------------------------------------------------------------------===// 77249259Sdim 78249259Sdim//===----------------------------------------------------------------------===// 79249259Sdim// Scalar classes 80249259Sdim//===----------------------------------------------------------------------===// 81249259Sdim 82249259Sdimclass SOP1_32 <bits<8> op, string opName, list<dag> pattern> : SOP1 < 83249259Sdim op, (outs SReg_32:$dst), (ins SSrc_32:$src0), 84249259Sdim opName#" $dst, $src0", pattern 85249259Sdim>; 86249259Sdim 87249259Sdimclass SOP1_64 <bits<8> op, string opName, list<dag> pattern> : SOP1 < 88249259Sdim op, (outs SReg_64:$dst), (ins SSrc_64:$src0), 89249259Sdim opName#" $dst, $src0", pattern 90249259Sdim>; 91249259Sdim 92249259Sdimclass SOP2_32 <bits<7> op, string opName, list<dag> pattern> : SOP2 < 93249259Sdim op, (outs SReg_32:$dst), (ins SSrc_32:$src0, SSrc_32:$src1), 94249259Sdim opName#" $dst, $src0, $src1", pattern 95249259Sdim>; 96249259Sdim 97249259Sdimclass SOP2_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 < 98249259Sdim op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_64:$src1), 99249259Sdim opName#" $dst, $src0, $src1", pattern 100249259Sdim>; 101249259Sdim 102249259Sdimclass SOPC_32 <bits<7> op, string opName, list<dag> pattern> : SOPC < 103249259Sdim op, (outs SCCReg:$dst), (ins SSrc_32:$src0, SSrc_32:$src1), 104249259Sdim opName#" $dst, $src0, $src1", pattern 105249259Sdim>; 106249259Sdim 107249259Sdimclass SOPC_64 <bits<7> op, string opName, list<dag> pattern> : SOPC < 108249259Sdim op, (outs SCCReg:$dst), (ins SSrc_64:$src0, SSrc_64:$src1), 109249259Sdim opName#" $dst, $src0, $src1", pattern 110249259Sdim>; 111249259Sdim 112249259Sdimclass SOPK_32 <bits<5> op, string opName, list<dag> pattern> : SOPK < 113249259Sdim op, (outs SReg_32:$dst), (ins i16imm:$src0), 114249259Sdim opName#" $dst, $src0", pattern 115249259Sdim>; 116249259Sdim 117249259Sdimclass SOPK_64 <bits<5> op, string opName, list<dag> pattern> : SOPK < 118249259Sdim op, (outs SReg_64:$dst), (ins i16imm:$src0), 119249259Sdim opName#" $dst, $src0", pattern 120249259Sdim>; 121249259Sdim 122249259Sdimmulticlass SMRD_Helper <bits<5> op, string asm, RegisterClass baseClass, 123249259Sdim RegisterClass dstClass> { 124249259Sdim def _IMM : SMRD < 125249259Sdim op, 1, (outs dstClass:$dst), 126249259Sdim (ins baseClass:$sbase, i32imm:$offset), 127249259Sdim asm#" $dst, $sbase, $offset", [] 128249259Sdim >; 129249259Sdim 130249259Sdim def _SGPR : SMRD < 131249259Sdim op, 0, (outs dstClass:$dst), 132249259Sdim (ins baseClass:$sbase, SReg_32:$soff), 133249259Sdim asm#" $dst, $sbase, $soff", [] 134249259Sdim >; 135249259Sdim} 136249259Sdim 137249259Sdim//===----------------------------------------------------------------------===// 138249259Sdim// Vector ALU classes 139249259Sdim//===----------------------------------------------------------------------===// 140249259Sdim 141249259Sdimclass VOP <string opName> { 142249259Sdim string OpName = opName; 143249259Sdim} 144249259Sdim 145249259Sdimclass VOP2_REV <string revOp, bit isOrig> { 146249259Sdim string RevOp = revOp; 147249259Sdim bit IsOrig = isOrig; 148249259Sdim} 149249259Sdim 150249259Sdimmulticlass VOP1_Helper <bits<8> op, RegisterClass drc, RegisterClass src, 151249259Sdim string opName, list<dag> pattern> { 152249259Sdim 153249259Sdim def _e32 : VOP1 < 154249259Sdim op, (outs drc:$dst), (ins src:$src0), 155249259Sdim opName#"_e32 $dst, $src0", pattern 156249259Sdim >, VOP <opName>; 157249259Sdim 158249259Sdim def _e64 : VOP3 < 159249259Sdim {1, 1, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}}, 160249259Sdim (outs drc:$dst), 161249259Sdim (ins src:$src0, 162249259Sdim i32imm:$abs, i32imm:$clamp, 163249259Sdim i32imm:$omod, i32imm:$neg), 164249259Sdim opName#"_e64 $dst, $src0, $abs, $clamp, $omod, $neg", [] 165249259Sdim >, VOP <opName> { 166249259Sdim let SRC1 = SIOperand.ZERO; 167249259Sdim let SRC2 = SIOperand.ZERO; 168249259Sdim } 169249259Sdim} 170249259Sdim 171249259Sdimmulticlass VOP1_32 <bits<8> op, string opName, list<dag> pattern> 172249259Sdim : VOP1_Helper <op, VReg_32, VSrc_32, opName, pattern>; 173249259Sdim 174249259Sdimmulticlass VOP1_64 <bits<8> op, string opName, list<dag> pattern> 175249259Sdim : VOP1_Helper <op, VReg_64, VSrc_64, opName, pattern>; 176249259Sdim 177249259Sdimmulticlass VOP2_Helper <bits<6> op, RegisterClass vrc, RegisterClass arc, 178249259Sdim string opName, list<dag> pattern, string revOp> { 179249259Sdim def _e32 : VOP2 < 180249259Sdim op, (outs vrc:$dst), (ins arc:$src0, vrc:$src1), 181249259Sdim opName#"_e32 $dst, $src0, $src1", pattern 182249259Sdim >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>; 183249259Sdim 184249259Sdim def _e64 : VOP3 < 185249259Sdim {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}}, 186249259Sdim (outs vrc:$dst), 187249259Sdim (ins arc:$src0, arc:$src1, 188249259Sdim i32imm:$abs, i32imm:$clamp, 189249259Sdim i32imm:$omod, i32imm:$neg), 190249259Sdim opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg", [] 191249259Sdim >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> { 192249259Sdim let SRC2 = SIOperand.ZERO; 193249259Sdim } 194249259Sdim} 195249259Sdim 196249259Sdimmulticlass VOP2_32 <bits<6> op, string opName, list<dag> pattern, 197249259Sdim string revOp = opName> 198249259Sdim : VOP2_Helper <op, VReg_32, VSrc_32, opName, pattern, revOp>; 199249259Sdim 200249259Sdimmulticlass VOP2_64 <bits<6> op, string opName, list<dag> pattern, 201249259Sdim string revOp = opName> 202249259Sdim : VOP2_Helper <op, VReg_64, VSrc_64, opName, pattern, revOp>; 203249259Sdim 204249259Sdimmulticlass VOP2b_32 <bits<6> op, string opName, list<dag> pattern, 205249259Sdim string revOp = opName> { 206249259Sdim 207249259Sdim def _e32 : VOP2 < 208249259Sdim op, (outs VReg_32:$dst), (ins VSrc_32:$src0, VReg_32:$src1), 209249259Sdim opName#"_e32 $dst, $src0, $src1", pattern 210249259Sdim >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>; 211249259Sdim 212249259Sdim def _e64 : VOP3b < 213249259Sdim {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}}, 214249259Sdim (outs VReg_32:$dst), 215249259Sdim (ins VSrc_32:$src0, VSrc_32:$src1, 216249259Sdim i32imm:$abs, i32imm:$clamp, 217249259Sdim i32imm:$omod, i32imm:$neg), 218249259Sdim opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg", [] 219249259Sdim >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> { 220249259Sdim let SRC2 = SIOperand.ZERO; 221249259Sdim /* the VOP2 variant puts the carry out into VCC, the VOP3 variant 222249259Sdim can write it into any SGPR. We currently don't use the carry out, 223249259Sdim so for now hardcode it to VCC as well */ 224249259Sdim let SDST = SIOperand.VCC; 225249259Sdim } 226249259Sdim} 227249259Sdim 228249259Sdimmulticlass VOPC_Helper <bits<8> op, RegisterClass vrc, RegisterClass arc, 229249259Sdim string opName, ValueType vt, PatLeaf cond> { 230249259Sdim 231249259Sdim def _e32 : VOPC < 232249259Sdim op, (ins arc:$src0, vrc:$src1), 233249259Sdim opName#"_e32 $dst, $src0, $src1", [] 234249259Sdim >, VOP <opName>; 235249259Sdim 236249259Sdim def _e64 : VOP3 < 237249259Sdim {0, op{7}, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}}, 238249259Sdim (outs SReg_64:$dst), 239249259Sdim (ins arc:$src0, arc:$src1, 240249259Sdim InstFlag:$abs, InstFlag:$clamp, 241249259Sdim InstFlag:$omod, InstFlag:$neg), 242249259Sdim opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg", 243249259Sdim !if(!eq(!cast<string>(cond), "COND_NULL"), []<dag>, 244249259Sdim [(set SReg_64:$dst, (i1 (setcc (vt arc:$src0), arc:$src1, cond)))] 245249259Sdim ) 246249259Sdim >, VOP <opName> { 247249259Sdim let SRC2 = SIOperand.ZERO; 248249259Sdim } 249249259Sdim} 250249259Sdim 251249259Sdimmulticlass VOPC_32 <bits<8> op, string opName, 252249259Sdim ValueType vt = untyped, PatLeaf cond = COND_NULL> 253249259Sdim : VOPC_Helper <op, VReg_32, VSrc_32, opName, vt, cond>; 254249259Sdim 255249259Sdimmulticlass VOPC_64 <bits<8> op, string opName, 256249259Sdim ValueType vt = untyped, PatLeaf cond = COND_NULL> 257249259Sdim : VOPC_Helper <op, VReg_64, VSrc_64, opName, vt, cond>; 258249259Sdim 259249259Sdimclass VOP3_32 <bits<9> op, string opName, list<dag> pattern> : VOP3 < 260249259Sdim op, (outs VReg_32:$dst), 261249259Sdim (ins VSrc_32:$src0, VSrc_32:$src1, VSrc_32:$src2, 262251662Sdim InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg), 263249259Sdim opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern 264249259Sdim>, VOP <opName>; 265249259Sdim 266249259Sdimclass VOP3_64 <bits<9> op, string opName, list<dag> pattern> : VOP3 < 267249259Sdim op, (outs VReg_64:$dst), 268249259Sdim (ins VSrc_64:$src0, VSrc_64:$src1, VSrc_64:$src2, 269251662Sdim InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg), 270249259Sdim opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern 271249259Sdim>, VOP <opName>; 272249259Sdim 273249259Sdim//===----------------------------------------------------------------------===// 274249259Sdim// Vector I/O classes 275249259Sdim//===----------------------------------------------------------------------===// 276249259Sdim 277249259Sdimclass MTBUF_Store_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF < 278249259Sdim op, 279249259Sdim (outs), 280249259Sdim (ins regClass:$vdata, i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, 281249259Sdim i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, 282249259Sdim SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset), 283249259Sdim asm#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt," 284249259Sdim #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset", 285249259Sdim []> { 286249259Sdim let mayStore = 1; 287249259Sdim let mayLoad = 0; 288249259Sdim} 289249259Sdim 290249259Sdimclass MUBUF_Load_Helper <bits<7> op, string asm, RegisterClass regClass> : MUBUF < 291249259Sdim op, 292251662Sdim (outs regClass:$vdata), 293249259Sdim (ins i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64, 294249259Sdim i1imm:$lds, VReg_32:$vaddr, SReg_128:$srsrc, i1imm:$slc, 295249259Sdim i1imm:$tfe, SSrc_32:$soffset), 296251662Sdim asm#" $vdata, $offset, $offen, $idxen, $glc, $addr64, " 297249259Sdim #"$lds, $vaddr, $srsrc, $slc, $tfe, $soffset", 298249259Sdim []> { 299249259Sdim let mayLoad = 1; 300249259Sdim let mayStore = 0; 301249259Sdim} 302249259Sdim 303251662Sdimclass MUBUF_Store_Helper <bits<7> op, string name, RegisterClass vdataClass, 304251662Sdim ValueType VT> : 305251662Sdim MUBUF <op, (outs), (ins vdataClass:$vdata, SReg_128:$srsrc, VReg_64:$vaddr), 306251662Sdim name#" $vdata, $srsrc + $vaddr", 307251662Sdim [(SIbuffer_store (VT vdataClass:$vdata), (i128 SReg_128:$srsrc), 308251662Sdim (i64 VReg_64:$vaddr))]> { 309251662Sdim 310251662Sdim let mayLoad = 0; 311251662Sdim let mayStore = 1; 312251662Sdim 313251662Sdim // Encoding 314251662Sdim let offset = 0; 315251662Sdim let offen = 0; 316251662Sdim let idxen = 0; 317251662Sdim let glc = 0; 318251662Sdim let addr64 = 1; 319251662Sdim let lds = 0; 320251662Sdim let slc = 0; 321251662Sdim let tfe = 0; 322251662Sdim let soffset = 128; // ZERO 323251662Sdim} 324251662Sdim 325249259Sdimclass MTBUF_Load_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF < 326249259Sdim op, 327249259Sdim (outs regClass:$dst), 328249259Sdim (ins i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64, 329249259Sdim i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, SReg_128:$srsrc, 330249259Sdim i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset), 331249259Sdim asm#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt," 332249259Sdim #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset", 333249259Sdim []> { 334249259Sdim let mayLoad = 1; 335249259Sdim let mayStore = 0; 336249259Sdim} 337249259Sdim 338251662Sdimclass MIMG_NoSampler_Helper <bits<7> op, string asm> : MIMG < 339249259Sdim op, 340249259Sdim (outs VReg_128:$vdata), 341249259Sdim (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128, 342249259Sdim i1imm:$tfe, i1imm:$lwe, i1imm:$slc, unknown:$vaddr, 343251662Sdim SReg_256:$srsrc), 344251662Sdim asm#" $vdata, $dmask, $unorm, $glc, $da, $r128," 345251662Sdim #" $tfe, $lwe, $slc, $vaddr, $srsrc", 346251662Sdim []> { 347251662Sdim let SSAMP = 0; 348251662Sdim let mayLoad = 1; 349251662Sdim let mayStore = 0; 350251662Sdim let hasPostISelHook = 1; 351251662Sdim} 352251662Sdim 353251662Sdimclass MIMG_Sampler_Helper <bits<7> op, string asm> : MIMG < 354251662Sdim op, 355251662Sdim (outs VReg_128:$vdata), 356251662Sdim (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128, 357251662Sdim i1imm:$tfe, i1imm:$lwe, i1imm:$slc, unknown:$vaddr, 358249259Sdim SReg_256:$srsrc, SReg_128:$ssamp), 359249259Sdim asm#" $vdata, $dmask, $unorm, $glc, $da, $r128," 360249259Sdim #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp", 361249259Sdim []> { 362249259Sdim let mayLoad = 1; 363249259Sdim let mayStore = 0; 364251662Sdim let hasPostISelHook = 1; 365249259Sdim} 366249259Sdim 367249259Sdim//===----------------------------------------------------------------------===// 368249259Sdim// Vector instruction mappings 369249259Sdim//===----------------------------------------------------------------------===// 370249259Sdim 371249259Sdim// Maps an opcode in e32 form to its e64 equivalent 372249259Sdimdef getVOPe64 : InstrMapping { 373249259Sdim let FilterClass = "VOP"; 374249259Sdim let RowFields = ["OpName"]; 375249259Sdim let ColFields = ["Size"]; 376249259Sdim let KeyCol = ["4"]; 377249259Sdim let ValueCols = [["8"]]; 378249259Sdim} 379249259Sdim 380249259Sdim// Maps an original opcode to its commuted version 381249259Sdimdef getCommuteRev : InstrMapping { 382249259Sdim let FilterClass = "VOP2_REV"; 383249259Sdim let RowFields = ["RevOp"]; 384249259Sdim let ColFields = ["IsOrig"]; 385249259Sdim let KeyCol = ["1"]; 386249259Sdim let ValueCols = [["0"]]; 387249259Sdim} 388249259Sdim 389249259Sdim// Maps an commuted opcode to its original version 390249259Sdimdef getCommuteOrig : InstrMapping { 391249259Sdim let FilterClass = "VOP2_REV"; 392249259Sdim let RowFields = ["RevOp"]; 393249259Sdim let ColFields = ["IsOrig"]; 394249259Sdim let KeyCol = ["0"]; 395249259Sdim let ValueCols = [["1"]]; 396249259Sdim} 397249259Sdim 398251662Sdim// Test if the supplied opcode is an MIMG instruction 399251662Sdimdef isMIMG : InstrMapping { 400251662Sdim let FilterClass = "MIMG"; 401251662Sdim let RowFields = ["Inst"]; 402251662Sdim let ColFields = ["Size"]; 403251662Sdim let KeyCol = ["8"]; 404251662Sdim let ValueCols = [["8"]]; 405251662Sdim} 406251662Sdim 407249259Sdiminclude "SIInstructions.td" 408