SIInstrInfo.td revision 249259
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 29249259Sdimdef IMM8bitDWORD : ImmLeaf < 30249259Sdim i32, [{ 31249259Sdim return (Imm & ~0x3FC) == 0; 32249259Sdim }], SDNodeXForm<imm, [{ 33249259Sdim return CurDAG->getTargetConstant( 34249259Sdim N->getZExtValue() >> 2, MVT::i32); 35249259Sdim }]> 36249259Sdim>; 37249259Sdim 38249259Sdimdef IMM12bit : ImmLeaf < 39249259Sdim i16, 40249259Sdim [{return isUInt<12>(Imm);}] 41249259Sdim>; 42249259Sdim 43249259Sdimclass InlineImm <ValueType vt> : PatLeaf <(vt imm), [{ 44249259Sdim return ((const SITargetLowering &)TLI).analyzeImmediate(N) == 0; 45249259Sdim}]>; 46249259Sdim 47249259Sdim//===----------------------------------------------------------------------===// 48249259Sdim// SI assembler operands 49249259Sdim//===----------------------------------------------------------------------===// 50249259Sdim 51249259Sdimdef SIOperand { 52249259Sdim int ZERO = 0x80; 53249259Sdim int VCC = 0x6A; 54249259Sdim} 55249259Sdim 56249259Sdiminclude "SIInstrFormats.td" 57249259Sdim 58249259Sdim//===----------------------------------------------------------------------===// 59249259Sdim// 60249259Sdim// SI Instruction multiclass helpers. 61249259Sdim// 62249259Sdim// Instructions with _32 take 32-bit operands. 63249259Sdim// Instructions with _64 take 64-bit operands. 64249259Sdim// 65249259Sdim// VOP_* instructions can use either a 32-bit or 64-bit encoding. The 32-bit 66249259Sdim// encoding is the standard encoding, but instruction that make use of 67249259Sdim// any of the instruction modifiers must use the 64-bit encoding. 68249259Sdim// 69249259Sdim// Instructions with _e32 use the 32-bit encoding. 70249259Sdim// Instructions with _e64 use the 64-bit encoding. 71249259Sdim// 72249259Sdim//===----------------------------------------------------------------------===// 73249259Sdim 74249259Sdim//===----------------------------------------------------------------------===// 75249259Sdim// Scalar classes 76249259Sdim//===----------------------------------------------------------------------===// 77249259Sdim 78249259Sdimclass SOP1_32 <bits<8> op, string opName, list<dag> pattern> : SOP1 < 79249259Sdim op, (outs SReg_32:$dst), (ins SSrc_32:$src0), 80249259Sdim opName#" $dst, $src0", pattern 81249259Sdim>; 82249259Sdim 83249259Sdimclass SOP1_64 <bits<8> op, string opName, list<dag> pattern> : SOP1 < 84249259Sdim op, (outs SReg_64:$dst), (ins SSrc_64:$src0), 85249259Sdim opName#" $dst, $src0", pattern 86249259Sdim>; 87249259Sdim 88249259Sdimclass SOP2_32 <bits<7> op, string opName, list<dag> pattern> : SOP2 < 89249259Sdim op, (outs SReg_32:$dst), (ins SSrc_32:$src0, SSrc_32:$src1), 90249259Sdim opName#" $dst, $src0, $src1", pattern 91249259Sdim>; 92249259Sdim 93249259Sdimclass SOP2_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 < 94249259Sdim op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_64:$src1), 95249259Sdim opName#" $dst, $src0, $src1", pattern 96249259Sdim>; 97249259Sdim 98249259Sdimclass SOPC_32 <bits<7> op, string opName, list<dag> pattern> : SOPC < 99249259Sdim op, (outs SCCReg:$dst), (ins SSrc_32:$src0, SSrc_32:$src1), 100249259Sdim opName#" $dst, $src0, $src1", pattern 101249259Sdim>; 102249259Sdim 103249259Sdimclass SOPC_64 <bits<7> op, string opName, list<dag> pattern> : SOPC < 104249259Sdim op, (outs SCCReg:$dst), (ins SSrc_64:$src0, SSrc_64:$src1), 105249259Sdim opName#" $dst, $src0, $src1", pattern 106249259Sdim>; 107249259Sdim 108249259Sdimclass SOPK_32 <bits<5> op, string opName, list<dag> pattern> : SOPK < 109249259Sdim op, (outs SReg_32:$dst), (ins i16imm:$src0), 110249259Sdim opName#" $dst, $src0", pattern 111249259Sdim>; 112249259Sdim 113249259Sdimclass SOPK_64 <bits<5> op, string opName, list<dag> pattern> : SOPK < 114249259Sdim op, (outs SReg_64:$dst), (ins i16imm:$src0), 115249259Sdim opName#" $dst, $src0", pattern 116249259Sdim>; 117249259Sdim 118249259Sdimmulticlass SMRD_Helper <bits<5> op, string asm, RegisterClass baseClass, 119249259Sdim RegisterClass dstClass> { 120249259Sdim def _IMM : SMRD < 121249259Sdim op, 1, (outs dstClass:$dst), 122249259Sdim (ins baseClass:$sbase, i32imm:$offset), 123249259Sdim asm#" $dst, $sbase, $offset", [] 124249259Sdim >; 125249259Sdim 126249259Sdim def _SGPR : SMRD < 127249259Sdim op, 0, (outs dstClass:$dst), 128249259Sdim (ins baseClass:$sbase, SReg_32:$soff), 129249259Sdim asm#" $dst, $sbase, $soff", [] 130249259Sdim >; 131249259Sdim} 132249259Sdim 133249259Sdim//===----------------------------------------------------------------------===// 134249259Sdim// Vector ALU classes 135249259Sdim//===----------------------------------------------------------------------===// 136249259Sdim 137249259Sdimclass VOP <string opName> { 138249259Sdim string OpName = opName; 139249259Sdim} 140249259Sdim 141249259Sdimclass VOP2_REV <string revOp, bit isOrig> { 142249259Sdim string RevOp = revOp; 143249259Sdim bit IsOrig = isOrig; 144249259Sdim} 145249259Sdim 146249259Sdimmulticlass VOP1_Helper <bits<8> op, RegisterClass drc, RegisterClass src, 147249259Sdim string opName, list<dag> pattern> { 148249259Sdim 149249259Sdim def _e32 : VOP1 < 150249259Sdim op, (outs drc:$dst), (ins src:$src0), 151249259Sdim opName#"_e32 $dst, $src0", pattern 152249259Sdim >, VOP <opName>; 153249259Sdim 154249259Sdim def _e64 : VOP3 < 155249259Sdim {1, 1, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}}, 156249259Sdim (outs drc:$dst), 157249259Sdim (ins src:$src0, 158249259Sdim i32imm:$abs, i32imm:$clamp, 159249259Sdim i32imm:$omod, i32imm:$neg), 160249259Sdim opName#"_e64 $dst, $src0, $abs, $clamp, $omod, $neg", [] 161249259Sdim >, VOP <opName> { 162249259Sdim let SRC1 = SIOperand.ZERO; 163249259Sdim let SRC2 = SIOperand.ZERO; 164249259Sdim } 165249259Sdim} 166249259Sdim 167249259Sdimmulticlass VOP1_32 <bits<8> op, string opName, list<dag> pattern> 168249259Sdim : VOP1_Helper <op, VReg_32, VSrc_32, opName, pattern>; 169249259Sdim 170249259Sdimmulticlass VOP1_64 <bits<8> op, string opName, list<dag> pattern> 171249259Sdim : VOP1_Helper <op, VReg_64, VSrc_64, opName, pattern>; 172249259Sdim 173249259Sdimmulticlass VOP2_Helper <bits<6> op, RegisterClass vrc, RegisterClass arc, 174249259Sdim string opName, list<dag> pattern, string revOp> { 175249259Sdim def _e32 : VOP2 < 176249259Sdim op, (outs vrc:$dst), (ins arc:$src0, vrc:$src1), 177249259Sdim opName#"_e32 $dst, $src0, $src1", pattern 178249259Sdim >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>; 179249259Sdim 180249259Sdim def _e64 : VOP3 < 181249259Sdim {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}}, 182249259Sdim (outs vrc:$dst), 183249259Sdim (ins arc:$src0, arc:$src1, 184249259Sdim i32imm:$abs, i32imm:$clamp, 185249259Sdim i32imm:$omod, i32imm:$neg), 186249259Sdim opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg", [] 187249259Sdim >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> { 188249259Sdim let SRC2 = SIOperand.ZERO; 189249259Sdim } 190249259Sdim} 191249259Sdim 192249259Sdimmulticlass VOP2_32 <bits<6> op, string opName, list<dag> pattern, 193249259Sdim string revOp = opName> 194249259Sdim : VOP2_Helper <op, VReg_32, VSrc_32, opName, pattern, revOp>; 195249259Sdim 196249259Sdimmulticlass VOP2_64 <bits<6> op, string opName, list<dag> pattern, 197249259Sdim string revOp = opName> 198249259Sdim : VOP2_Helper <op, VReg_64, VSrc_64, opName, pattern, revOp>; 199249259Sdim 200249259Sdimmulticlass VOP2b_32 <bits<6> op, string opName, list<dag> pattern, 201249259Sdim string revOp = opName> { 202249259Sdim 203249259Sdim def _e32 : VOP2 < 204249259Sdim op, (outs VReg_32:$dst), (ins VSrc_32:$src0, VReg_32:$src1), 205249259Sdim opName#"_e32 $dst, $src0, $src1", pattern 206249259Sdim >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>; 207249259Sdim 208249259Sdim def _e64 : VOP3b < 209249259Sdim {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}}, 210249259Sdim (outs VReg_32:$dst), 211249259Sdim (ins VSrc_32:$src0, VSrc_32:$src1, 212249259Sdim i32imm:$abs, i32imm:$clamp, 213249259Sdim i32imm:$omod, i32imm:$neg), 214249259Sdim opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg", [] 215249259Sdim >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> { 216249259Sdim let SRC2 = SIOperand.ZERO; 217249259Sdim /* the VOP2 variant puts the carry out into VCC, the VOP3 variant 218249259Sdim can write it into any SGPR. We currently don't use the carry out, 219249259Sdim so for now hardcode it to VCC as well */ 220249259Sdim let SDST = SIOperand.VCC; 221249259Sdim } 222249259Sdim} 223249259Sdim 224249259Sdimmulticlass VOPC_Helper <bits<8> op, RegisterClass vrc, RegisterClass arc, 225249259Sdim string opName, ValueType vt, PatLeaf cond> { 226249259Sdim 227249259Sdim def _e32 : VOPC < 228249259Sdim op, (ins arc:$src0, vrc:$src1), 229249259Sdim opName#"_e32 $dst, $src0, $src1", [] 230249259Sdim >, VOP <opName>; 231249259Sdim 232249259Sdim def _e64 : VOP3 < 233249259Sdim {0, op{7}, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}}, 234249259Sdim (outs SReg_64:$dst), 235249259Sdim (ins arc:$src0, arc:$src1, 236249259Sdim InstFlag:$abs, InstFlag:$clamp, 237249259Sdim InstFlag:$omod, InstFlag:$neg), 238249259Sdim opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg", 239249259Sdim !if(!eq(!cast<string>(cond), "COND_NULL"), []<dag>, 240249259Sdim [(set SReg_64:$dst, (i1 (setcc (vt arc:$src0), arc:$src1, cond)))] 241249259Sdim ) 242249259Sdim >, VOP <opName> { 243249259Sdim let SRC2 = SIOperand.ZERO; 244249259Sdim } 245249259Sdim} 246249259Sdim 247249259Sdimmulticlass VOPC_32 <bits<8> op, string opName, 248249259Sdim ValueType vt = untyped, PatLeaf cond = COND_NULL> 249249259Sdim : VOPC_Helper <op, VReg_32, VSrc_32, opName, vt, cond>; 250249259Sdim 251249259Sdimmulticlass VOPC_64 <bits<8> op, string opName, 252249259Sdim ValueType vt = untyped, PatLeaf cond = COND_NULL> 253249259Sdim : VOPC_Helper <op, VReg_64, VSrc_64, opName, vt, cond>; 254249259Sdim 255249259Sdimclass VOP3_32 <bits<9> op, string opName, list<dag> pattern> : VOP3 < 256249259Sdim op, (outs VReg_32:$dst), 257249259Sdim (ins VSrc_32:$src0, VSrc_32:$src1, VSrc_32:$src2, 258249259Sdim i32imm:$abs, i32imm:$clamp, i32imm:$omod, i32imm:$neg), 259249259Sdim opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern 260249259Sdim>, VOP <opName>; 261249259Sdim 262249259Sdimclass VOP3_64 <bits<9> op, string opName, list<dag> pattern> : VOP3 < 263249259Sdim op, (outs VReg_64:$dst), 264249259Sdim (ins VSrc_64:$src0, VSrc_64:$src1, VSrc_64:$src2, 265249259Sdim i32imm:$abs, i32imm:$clamp, i32imm:$omod, i32imm:$neg), 266249259Sdim opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern 267249259Sdim>, VOP <opName>; 268249259Sdim 269249259Sdim//===----------------------------------------------------------------------===// 270249259Sdim// Vector I/O classes 271249259Sdim//===----------------------------------------------------------------------===// 272249259Sdim 273249259Sdimclass MTBUF_Store_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF < 274249259Sdim op, 275249259Sdim (outs), 276249259Sdim (ins regClass:$vdata, i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, 277249259Sdim i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, 278249259Sdim SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset), 279249259Sdim asm#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt," 280249259Sdim #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset", 281249259Sdim []> { 282249259Sdim let mayStore = 1; 283249259Sdim let mayLoad = 0; 284249259Sdim} 285249259Sdim 286249259Sdimclass MUBUF_Load_Helper <bits<7> op, string asm, RegisterClass regClass> : MUBUF < 287249259Sdim op, 288249259Sdim (outs regClass:$dst), 289249259Sdim (ins i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64, 290249259Sdim i1imm:$lds, VReg_32:$vaddr, SReg_128:$srsrc, i1imm:$slc, 291249259Sdim i1imm:$tfe, SSrc_32:$soffset), 292249259Sdim asm#" $dst, $offset, $offen, $idxen, $glc, $addr64, " 293249259Sdim #"$lds, $vaddr, $srsrc, $slc, $tfe, $soffset", 294249259Sdim []> { 295249259Sdim let mayLoad = 1; 296249259Sdim let mayStore = 0; 297249259Sdim} 298249259Sdim 299249259Sdimclass MTBUF_Load_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF < 300249259Sdim op, 301249259Sdim (outs regClass:$dst), 302249259Sdim (ins i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64, 303249259Sdim i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, SReg_128:$srsrc, 304249259Sdim i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset), 305249259Sdim asm#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt," 306249259Sdim #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset", 307249259Sdim []> { 308249259Sdim let mayLoad = 1; 309249259Sdim let mayStore = 0; 310249259Sdim} 311249259Sdim 312249259Sdimclass MIMG_Load_Helper <bits<7> op, string asm> : MIMG < 313249259Sdim op, 314249259Sdim (outs VReg_128:$vdata), 315249259Sdim (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128, 316249259Sdim i1imm:$tfe, i1imm:$lwe, i1imm:$slc, unknown:$vaddr, 317249259Sdim SReg_256:$srsrc, SReg_128:$ssamp), 318249259Sdim asm#" $vdata, $dmask, $unorm, $glc, $da, $r128," 319249259Sdim #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp", 320249259Sdim []> { 321249259Sdim let mayLoad = 1; 322249259Sdim let mayStore = 0; 323249259Sdim} 324249259Sdim 325249259Sdim//===----------------------------------------------------------------------===// 326249259Sdim// Vector instruction mappings 327249259Sdim//===----------------------------------------------------------------------===// 328249259Sdim 329249259Sdim// Maps an opcode in e32 form to its e64 equivalent 330249259Sdimdef getVOPe64 : InstrMapping { 331249259Sdim let FilterClass = "VOP"; 332249259Sdim let RowFields = ["OpName"]; 333249259Sdim let ColFields = ["Size"]; 334249259Sdim let KeyCol = ["4"]; 335249259Sdim let ValueCols = [["8"]]; 336249259Sdim} 337249259Sdim 338249259Sdim// Maps an original opcode to its commuted version 339249259Sdimdef getCommuteRev : InstrMapping { 340249259Sdim let FilterClass = "VOP2_REV"; 341249259Sdim let RowFields = ["RevOp"]; 342249259Sdim let ColFields = ["IsOrig"]; 343249259Sdim let KeyCol = ["1"]; 344249259Sdim let ValueCols = [["0"]]; 345249259Sdim} 346249259Sdim 347249259Sdim// Maps an commuted opcode to its original version 348249259Sdimdef getCommuteOrig : InstrMapping { 349249259Sdim let FilterClass = "VOP2_REV"; 350249259Sdim let RowFields = ["RevOp"]; 351249259Sdim let ColFields = ["IsOrig"]; 352249259Sdim let KeyCol = ["0"]; 353249259Sdim let ValueCols = [["1"]]; 354249259Sdim} 355249259Sdim 356249259Sdiminclude "SIInstructions.td" 357