SIInstrInfo.td revision dce4a407a24b04eebc6a376f8e62b41aaa7b071f
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 12def SISubtarget { 13 int NONE = -1; 14 int SI = 0; 15} 16 17//===----------------------------------------------------------------------===// 18// SI DAG Nodes 19//===----------------------------------------------------------------------===// 20 21def SIload_constant : SDNode<"AMDGPUISD::LOAD_CONSTANT", 22 SDTypeProfile<1, 2, [SDTCisVT<0, f32>, SDTCisVT<1, v4i32>, SDTCisVT<2, i32>]>, 23 [SDNPMayLoad, SDNPMemOperand] 24>; 25 26def 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 45def 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 50class SDSample<string opcode> : SDNode <opcode, 51 SDTypeProfile<1, 4, [SDTCisVT<0, v4f32>, SDTCisVT<2, v32i8>, 52 SDTCisVT<3, v4i32>, SDTCisVT<4, i32>]> 53>; 54 55def SIsample : SDSample<"AMDGPUISD::SAMPLE">; 56def SIsampleb : SDSample<"AMDGPUISD::SAMPLEB">; 57def SIsampled : SDSample<"AMDGPUISD::SAMPLED">; 58def SIsamplel : SDSample<"AMDGPUISD::SAMPLEL">; 59 60// Transformation function, extract the lower 32bit of a 64bit immediate 61def LO32 : SDNodeXForm<imm, [{ 62 return CurDAG->getTargetConstant(N->getZExtValue() & 0xffffffff, MVT::i32); 63}]>; 64 65def 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 71def HI32 : SDNodeXForm<imm, [{ 72 return CurDAG->getTargetConstant(N->getZExtValue() >> 32, MVT::i32); 73}]>; 74 75def 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 80def IMM8bitDWORD : PatLeaf <(imm), 81 [{return (N->getZExtValue() & ~0x3FC) == 0;}] 82>; 83 84def as_dword_i32imm : SDNodeXForm<imm, [{ 85 return CurDAG->getTargetConstant(N->getZExtValue() >> 2, MVT::i32); 86}]>; 87 88def as_i1imm : SDNodeXForm<imm, [{ 89 return CurDAG->getTargetConstant(N->getZExtValue(), MVT::i1); 90}]>; 91 92def as_i8imm : SDNodeXForm<imm, [{ 93 return CurDAG->getTargetConstant(N->getZExtValue(), MVT::i8); 94}]>; 95 96def as_i16imm : SDNodeXForm<imm, [{ 97 return CurDAG->getTargetConstant(N->getSExtValue(), MVT::i16); 98}]>; 99 100def as_i32imm: SDNodeXForm<imm, [{ 101 return CurDAG->getTargetConstant(N->getSExtValue(), MVT::i32); 102}]>; 103 104def IMM8bit : PatLeaf <(imm), 105 [{return isUInt<8>(N->getZExtValue());}] 106>; 107 108def IMM12bit : PatLeaf <(imm), 109 [{return isUInt<12>(N->getZExtValue());}] 110>; 111 112def IMM16bit : PatLeaf <(imm), 113 [{return isUInt<16>(N->getZExtValue());}] 114>; 115 116def IMM32bit : PatLeaf <(imm), 117 [{return isUInt<32>(N->getZExtValue());}] 118>; 119 120def 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 125class InlineImm <ValueType vt> : PatLeaf <(vt imm), [{ 126 return isInlineImmediate(N); 127}]>; 128 129class 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 145def FRAMEri32 : Operand<iPTR> { 146 let MIOperandInfo = (ops i32:$ptr, i32imm:$index); 147} 148 149//===----------------------------------------------------------------------===// 150// SI assembler operands 151//===----------------------------------------------------------------------===// 152 153def SIOperand { 154 int ZERO = 0x80; 155 int VCC = 0x6A; 156} 157 158include "SIInstrFormats.td" 159 160//===----------------------------------------------------------------------===// 161// 162// SI Instruction multiclass helpers. 163// 164// Instructions with _32 take 32-bit operands. 165// Instructions with _64 take 64-bit operands. 166// 167// VOP_* instructions can use either a 32-bit or 64-bit encoding. The 32-bit 168// encoding is the standard encoding, but instruction that make use of 169// any of the instruction modifiers must use the 64-bit encoding. 170// 171// Instructions with _e32 use the 32-bit encoding. 172// Instructions with _e64 use the 64-bit encoding. 173// 174//===----------------------------------------------------------------------===// 175 176//===----------------------------------------------------------------------===// 177// Scalar classes 178//===----------------------------------------------------------------------===// 179 180class SOP1_32 <bits<8> op, string opName, list<dag> pattern> : SOP1 < 181 op, (outs SReg_32:$dst), (ins SSrc_32:$src0), 182 opName#" $dst, $src0", pattern 183>; 184 185class SOP1_64 <bits<8> op, string opName, list<dag> pattern> : SOP1 < 186 op, (outs SReg_64:$dst), (ins SSrc_64:$src0), 187 opName#" $dst, $src0", pattern 188>; 189 190class SOP2_32 <bits<7> op, string opName, list<dag> pattern> : SOP2 < 191 op, (outs SReg_32:$dst), (ins SSrc_32:$src0, SSrc_32:$src1), 192 opName#" $dst, $src0, $src1", pattern 193>; 194 195class SOP2_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 < 196 op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_64:$src1), 197 opName#" $dst, $src0, $src1", pattern 198>; 199 200class SOP2_SHIFT_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 < 201 op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_32:$src1), 202 opName#" $dst, $src0, $src1", pattern 203>; 204 205 206class SOPC_Helper <bits<7> op, RegisterClass rc, ValueType vt, 207 string opName, PatLeaf cond> : SOPC < 208 op, (outs SCCReg:$dst), (ins rc:$src0, rc:$src1), 209 opName#" $dst, $src0, $src1", []>; 210 211class SOPC_32<bits<7> op, string opName, PatLeaf cond = COND_NULL> 212 : SOPC_Helper<op, SSrc_32, i32, opName, cond>; 213 214class SOPC_64<bits<7> op, string opName, PatLeaf cond = COND_NULL> 215 : SOPC_Helper<op, SSrc_64, i64, opName, cond>; 216 217class SOPK_32 <bits<5> op, string opName, list<dag> pattern> : SOPK < 218 op, (outs SReg_32:$dst), (ins i16imm:$src0), 219 opName#" $dst, $src0", pattern 220>; 221 222class SOPK_64 <bits<5> op, string opName, list<dag> pattern> : SOPK < 223 op, (outs SReg_64:$dst), (ins i16imm:$src0), 224 opName#" $dst, $src0", pattern 225>; 226 227multiclass SMRD_Helper <bits<5> op, string asm, RegisterClass baseClass, 228 RegisterClass dstClass> { 229 def _IMM : SMRD < 230 op, 1, (outs dstClass:$dst), 231 (ins baseClass:$sbase, u32imm:$offset), 232 asm#" $dst, $sbase, $offset", [] 233 >; 234 235 def _SGPR : SMRD < 236 op, 0, (outs dstClass:$dst), 237 (ins baseClass:$sbase, SReg_32:$soff), 238 asm#" $dst, $sbase, $soff", [] 239 >; 240} 241 242//===----------------------------------------------------------------------===// 243// Vector ALU classes 244//===----------------------------------------------------------------------===// 245 246class VOP <string opName> { 247 string OpName = opName; 248} 249 250class VOP2_REV <string revOp, bit isOrig> { 251 string RevOp = revOp; 252 bit IsOrig = isOrig; 253} 254 255class SIMCInstr <string pseudo, int subtarget> { 256 string PseudoInstr = pseudo; 257 int Subtarget = subtarget; 258} 259 260multiclass VOP3_m <bits<9> op, dag outs, dag ins, string asm, list<dag> pattern, 261 string opName> { 262 263 def "" : InstSI <outs, ins, "", pattern>, VOP <opName>, 264 SIMCInstr<OpName, SISubtarget.NONE> { 265 let isPseudo = 1; 266 } 267 268 def _si : VOP3 <op, outs, ins, asm, []>, SIMCInstr<opName, SISubtarget.SI>; 269 270} 271 272// This must always be right before the operand being input modified. 273def InputMods : OperandWithDefaultOps <i32, (ops (i32 0))> { 274 let PrintMethod = "printOperandAndMods"; 275} 276 277multiclass VOP1_Helper <bits<8> op, RegisterClass drc, RegisterClass src, 278 string opName, list<dag> pattern> { 279 280 def _e32 : VOP1 < 281 op, (outs drc:$dst), (ins src:$src0), 282 opName#"_e32 $dst, $src0", pattern 283 >, VOP <opName>; 284 285 def _e64 : VOP3 < 286 {1, 1, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}}, 287 (outs drc:$dst), 288 (ins InputMods:$src0_modifiers, src:$src0, i32imm:$clamp, i32imm:$omod), 289 opName#"_e64 $dst, $src0_modifiers, $clamp, $omod", [] 290 >, VOP <opName> { 291 let src1 = SIOperand.ZERO; 292 let src2 = SIOperand.ZERO; 293 } 294} 295 296multiclass VOP1_32 <bits<8> op, string opName, list<dag> pattern> 297 : VOP1_Helper <op, VReg_32, VSrc_32, opName, pattern>; 298 299multiclass VOP1_64 <bits<8> op, string opName, list<dag> pattern> 300 : VOP1_Helper <op, VReg_64, VSrc_64, opName, pattern>; 301 302multiclass VOP1_32_64 <bits<8> op, string opName, list<dag> pattern> 303 : VOP1_Helper <op, VReg_32, VSrc_64, opName, pattern>; 304 305multiclass VOP1_64_32 <bits<8> op, string opName, list<dag> pattern> 306 : VOP1_Helper <op, VReg_64, VSrc_32, opName, pattern>; 307 308multiclass VOP2_Helper <bits<6> op, RegisterClass vrc, RegisterClass arc, 309 string opName, list<dag> pattern, string revOp> { 310 def _e32 : VOP2 < 311 op, (outs vrc:$dst), (ins arc:$src0, vrc:$src1), 312 opName#"_e32 $dst, $src0, $src1", pattern 313 >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>; 314 315 def _e64 : VOP3 < 316 {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}}, 317 (outs vrc:$dst), 318 (ins InputMods:$src0_modifiers, arc:$src0, 319 InputMods:$src1_modifiers, arc:$src1, 320 i32imm:$clamp, i32imm:$omod), 321 opName#"_e64 $dst, $src0_modifiers, $src1_modifiers, $clamp, $omod", [] 322 >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> { 323 let src2 = SIOperand.ZERO; 324 } 325} 326 327multiclass VOP2_32 <bits<6> op, string opName, list<dag> pattern, 328 string revOp = opName> 329 : VOP2_Helper <op, VReg_32, VSrc_32, opName, pattern, revOp>; 330 331multiclass VOP2_64 <bits<6> op, string opName, list<dag> pattern, 332 string revOp = opName> 333 : VOP2_Helper <op, VReg_64, VSrc_64, opName, pattern, revOp>; 334 335multiclass VOP2b_32 <bits<6> op, string opName, list<dag> pattern, 336 RegisterClass src0_rc, string revOp = opName> { 337 338 def _e32 : VOP2 < 339 op, (outs VReg_32:$dst), (ins src0_rc:$src0, VReg_32:$src1), 340 opName#"_e32 $dst, $src0, $src1", pattern 341 >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>; 342 343 def _e64 : VOP3b < 344 {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}}, 345 (outs VReg_32:$dst), 346 (ins InputMods: $src0_modifiers, VSrc_32:$src0, 347 InputMods:$src1_modifiers, VSrc_32:$src1, 348 i32imm:$clamp, i32imm:$omod), 349 opName#"_e64 $dst, $src0_modifiers, $src1_modifiers, $clamp, $omod", [] 350 >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> { 351 let src2 = SIOperand.ZERO; 352 /* the VOP2 variant puts the carry out into VCC, the VOP3 variant 353 can write it into any SGPR. We currently don't use the carry out, 354 so for now hardcode it to VCC as well */ 355 let sdst = SIOperand.VCC; 356 } 357} 358 359multiclass VOPC_Helper <bits<8> op, RegisterClass vrc, RegisterClass arc, 360 string opName, ValueType vt, PatLeaf cond> { 361 362 def _e32 : VOPC < 363 op, (ins arc:$src0, vrc:$src1), 364 opName#"_e32 $dst, $src0, $src1", [] 365 >, VOP <opName>; 366 367 def _e64 : VOP3 < 368 {0, op{7}, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}}, 369 (outs SReg_64:$dst), 370 (ins InputMods:$src0_modifiers, arc:$src0, 371 InputMods:$src1_modifiers, arc:$src1, 372 InstFlag:$clamp, InstFlag:$omod), 373 opName#"_e64 $dst, $src0_modifiers, $src1_modifiers, $clamp, $omod", 374 !if(!eq(!cast<string>(cond), "COND_NULL"), []<dag>, 375 [(set SReg_64:$dst, (i1 (setcc (vt arc:$src0), arc:$src1, cond)))] 376 ) 377 >, VOP <opName> { 378 let src2 = SIOperand.ZERO; 379 let src2_modifiers = 0; 380 } 381} 382 383multiclass VOPC_32 <bits<8> op, string opName, 384 ValueType vt = untyped, PatLeaf cond = COND_NULL> 385 : VOPC_Helper <op, VReg_32, VSrc_32, opName, vt, cond>; 386 387multiclass VOPC_64 <bits<8> op, string opName, 388 ValueType vt = untyped, PatLeaf cond = COND_NULL> 389 : VOPC_Helper <op, VReg_64, VSrc_64, opName, vt, cond>; 390 391multiclass VOP3_32 <bits<9> op, string opName, list<dag> pattern> : VOP3_m < 392 op, (outs VReg_32:$dst), 393 (ins InputMods: $src0_modifiers, VSrc_32:$src0, InputMods:$src1_modifiers, 394 VSrc_32:$src1, InputMods:$src2_modifiers, VSrc_32:$src2, 395 InstFlag:$clamp, InstFlag:$omod), 396 opName#" $dst, $src0_modifiers, $src1, $src2, $clamp, $omod", pattern, opName 397>; 398 399class VOP3_64_Shift <bits <9> op, string opName, list<dag> pattern> : VOP3 < 400 op, (outs VReg_64:$dst), 401 (ins VSrc_64:$src0, VSrc_32:$src1), 402 opName#" $dst, $src0, $src1", pattern 403>, VOP <opName> { 404 405 let src2 = SIOperand.ZERO; 406 let src0_modifiers = 0; 407 let clamp = 0; 408 let omod = 0; 409} 410 411class VOP3_64 <bits<9> op, string opName, list<dag> pattern> : VOP3 < 412 op, (outs VReg_64:$dst), 413 (ins VSrc_64:$src0, VSrc_64:$src1, VSrc_64:$src2, 414 InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg), 415 opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern 416>, VOP <opName>; 417 418//===----------------------------------------------------------------------===// 419// Vector I/O classes 420//===----------------------------------------------------------------------===// 421 422class DS_1A <bits<8> op, dag outs, dag ins, string asm, list<dag> pat> : 423 DS <op, outs, ins, asm, pat> { 424 bits<16> offset; 425 426 // Single load interpret the 2 i8imm operands as a single i16 offset. 427 let offset0 = offset{7-0}; 428 let offset1 = offset{15-8}; 429} 430 431class DS_Load_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A < 432 op, 433 (outs regClass:$vdst), 434 (ins i1imm:$gds, VReg_32:$addr, u16imm:$offset), 435 asm#" $vdst, $addr, $offset, [M0]", 436 []> { 437 let data0 = 0; 438 let data1 = 0; 439 let mayLoad = 1; 440 let mayStore = 0; 441} 442 443class DS_Load2_Helper <bits<8> op, string asm, RegisterClass regClass> : DS < 444 op, 445 (outs regClass:$vdst), 446 (ins i1imm:$gds, VReg_32:$addr, u8imm:$offset0, u8imm:$offset1), 447 asm#" $gds, $vdst, $addr, $offset0, $offset1, [M0]", 448 []> { 449 let data0 = 0; 450 let data1 = 0; 451 let mayLoad = 1; 452 let mayStore = 0; 453} 454 455class DS_Store_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A < 456 op, 457 (outs), 458 (ins i1imm:$gds, VReg_32:$addr, regClass:$data0, u16imm:$offset), 459 asm#" $addr, $data0, $offset [M0]", 460 []> { 461 let data1 = 0; 462 let mayStore = 1; 463 let mayLoad = 0; 464 let vdst = 0; 465} 466 467class DS_Store2_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A < 468 op, 469 (outs), 470 (ins i1imm:$gds, VReg_32:$addr, regClass:$data0, u8imm:$offset0, u8imm:$offset1), 471 asm#" $addr, $data0, $data1, $offset0, $offset1 [M0]", 472 []> { 473 let mayStore = 1; 474 let mayLoad = 0; 475 let vdst = 0; 476} 477 478class DS_1A1D_RET <bits<8> op, string asm, RegisterClass rc> : DS_1A < 479 op, 480 (outs rc:$vdst), 481 (ins i1imm:$gds, VReg_32:$addr, VReg_32:$data0, u16imm:$offset), 482 asm#" $vdst, $addr, $data0, $offset, [M0]", 483 []> { 484 485 let data1 = 0; 486 let mayStore = 1; 487 let mayLoad = 1; 488} 489 490class MTBUF_Store_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF < 491 op, 492 (outs), 493 (ins regClass:$vdata, u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, 494 i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, 495 SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset), 496 asm#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt," 497 #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset", 498 []> { 499 let mayStore = 1; 500 let mayLoad = 0; 501} 502 503multiclass MUBUF_Load_Helper <bits<7> op, string asm, RegisterClass regClass> { 504 505 let lds = 0, mayLoad = 1 in { 506 507 let addr64 = 0 in { 508 509 let offen = 0, idxen = 0 in { 510 def _OFFSET : MUBUF <op, (outs regClass:$vdata), 511 (ins SReg_128:$srsrc, VReg_32:$vaddr, 512 u16imm:$offset, SSrc_32:$soffset, i1imm:$glc, 513 i1imm:$slc, i1imm:$tfe), 514 asm#" $vdata, $srsrc + $offset + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>; 515 } 516 517 let offen = 1, idxen = 0, offset = 0 in { 518 def _OFFEN : MUBUF <op, (outs regClass:$vdata), 519 (ins SReg_128:$srsrc, VReg_32:$vaddr, 520 SSrc_32:$soffset, i1imm:$glc, i1imm:$slc, 521 i1imm:$tfe), 522 asm#" $vdata, $srsrc + $vaddr + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>; 523 } 524 525 let offen = 0, idxen = 1 in { 526 def _IDXEN : MUBUF <op, (outs regClass:$vdata), 527 (ins SReg_128:$srsrc, VReg_32:$vaddr, 528 u16imm:$offset, SSrc_32:$soffset, i1imm:$glc, 529 i1imm:$slc, i1imm:$tfe), 530 asm#" $vdata, $srsrc[$vaddr] + $offset + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>; 531 } 532 533 let offen = 1, idxen = 1 in { 534 def _BOTHEN : MUBUF <op, (outs regClass:$vdata), 535 (ins SReg_128:$srsrc, VReg_64:$vaddr, 536 SSrc_32:$soffset, i1imm:$glc, 537 i1imm:$slc, i1imm:$tfe), 538 asm#" $vdata, $srsrc[$vaddr[0]] + $vaddr[1] + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>; 539 } 540 } 541 542 let offen = 0, idxen = 0, addr64 = 1, glc = 0, slc = 0, tfe = 0, soffset = 128 /* ZERO */ in { 543 def _ADDR64 : MUBUF <op, (outs regClass:$vdata), 544 (ins SReg_128:$srsrc, VReg_64:$vaddr, u16imm:$offset), 545 asm#" $vdata, $srsrc + $vaddr + $offset", []>; 546 } 547 } 548} 549 550class MUBUF_Store_Helper <bits<7> op, string name, RegisterClass vdataClass> : 551 MUBUF <op, (outs), (ins vdataClass:$vdata, SReg_128:$srsrc, VReg_64:$vaddr, 552 u16imm:$offset), 553 name#" $vdata, $srsrc + $vaddr + $offset", 554 []> { 555 556 let mayLoad = 0; 557 let mayStore = 1; 558 559 // Encoding 560 let offen = 0; 561 let idxen = 0; 562 let glc = 0; 563 let addr64 = 1; 564 let lds = 0; 565 let slc = 0; 566 let tfe = 0; 567 let soffset = 128; // ZERO 568} 569 570class MTBUF_Load_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF < 571 op, 572 (outs regClass:$dst), 573 (ins u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64, 574 i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, SReg_128:$srsrc, 575 i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset), 576 asm#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt," 577 #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset", 578 []> { 579 let mayLoad = 1; 580 let mayStore = 0; 581} 582 583class MIMG_Mask <string op, int channels> { 584 string Op = op; 585 int Channels = channels; 586} 587 588class MIMG_NoSampler_Helper <bits<7> op, string asm, 589 RegisterClass dst_rc, 590 RegisterClass src_rc> : MIMG < 591 op, 592 (outs dst_rc:$vdata), 593 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128, 594 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr, 595 SReg_256:$srsrc), 596 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128," 597 #" $tfe, $lwe, $slc, $vaddr, $srsrc", 598 []> { 599 let SSAMP = 0; 600 let mayLoad = 1; 601 let mayStore = 0; 602 let hasPostISelHook = 1; 603} 604 605multiclass MIMG_NoSampler_Src_Helper <bits<7> op, string asm, 606 RegisterClass dst_rc, 607 int channels> { 608 def _V1 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_32>, 609 MIMG_Mask<asm#"_V1", channels>; 610 def _V2 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_64>, 611 MIMG_Mask<asm#"_V2", channels>; 612 def _V4 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_128>, 613 MIMG_Mask<asm#"_V4", channels>; 614} 615 616multiclass MIMG_NoSampler <bits<7> op, string asm> { 617 defm _V1 : MIMG_NoSampler_Src_Helper <op, asm, VReg_32, 1>; 618 defm _V2 : MIMG_NoSampler_Src_Helper <op, asm, VReg_64, 2>; 619 defm _V3 : MIMG_NoSampler_Src_Helper <op, asm, VReg_96, 3>; 620 defm _V4 : MIMG_NoSampler_Src_Helper <op, asm, VReg_128, 4>; 621} 622 623class MIMG_Sampler_Helper <bits<7> op, string asm, 624 RegisterClass dst_rc, 625 RegisterClass src_rc> : MIMG < 626 op, 627 (outs dst_rc:$vdata), 628 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128, 629 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr, 630 SReg_256:$srsrc, SReg_128:$ssamp), 631 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128," 632 #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp", 633 []> { 634 let mayLoad = 1; 635 let mayStore = 0; 636 let hasPostISelHook = 1; 637} 638 639multiclass MIMG_Sampler_Src_Helper <bits<7> op, string asm, 640 RegisterClass dst_rc, 641 int channels> { 642 def _V1 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_32>, 643 MIMG_Mask<asm#"_V1", channels>; 644 def _V2 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_64>, 645 MIMG_Mask<asm#"_V2", channels>; 646 def _V4 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_128>, 647 MIMG_Mask<asm#"_V4", channels>; 648 def _V8 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_256>, 649 MIMG_Mask<asm#"_V8", channels>; 650 def _V16 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_512>, 651 MIMG_Mask<asm#"_V16", channels>; 652} 653 654multiclass MIMG_Sampler <bits<7> op, string asm> { 655 defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VReg_32, 1>; 656 defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2>; 657 defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3>; 658 defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4>; 659} 660 661//===----------------------------------------------------------------------===// 662// Vector instruction mappings 663//===----------------------------------------------------------------------===// 664 665// Maps an opcode in e32 form to its e64 equivalent 666def getVOPe64 : InstrMapping { 667 let FilterClass = "VOP"; 668 let RowFields = ["OpName"]; 669 let ColFields = ["Size"]; 670 let KeyCol = ["4"]; 671 let ValueCols = [["8"]]; 672} 673 674// Maps an original opcode to its commuted version 675def getCommuteRev : InstrMapping { 676 let FilterClass = "VOP2_REV"; 677 let RowFields = ["RevOp"]; 678 let ColFields = ["IsOrig"]; 679 let KeyCol = ["1"]; 680 let ValueCols = [["0"]]; 681} 682 683def getMaskedMIMGOp : InstrMapping { 684 let FilterClass = "MIMG_Mask"; 685 let RowFields = ["Op"]; 686 let ColFields = ["Channels"]; 687 let KeyCol = ["4"]; 688 let ValueCols = [["1"], ["2"], ["3"] ]; 689} 690 691// Maps an commuted opcode to its original version 692def getCommuteOrig : InstrMapping { 693 let FilterClass = "VOP2_REV"; 694 let RowFields = ["RevOp"]; 695 let ColFields = ["IsOrig"]; 696 let KeyCol = ["0"]; 697 let ValueCols = [["1"]]; 698} 699 700def isDS : InstrMapping { 701 let FilterClass = "DS"; 702 let RowFields = ["Inst"]; 703 let ColFields = ["Size"]; 704 let KeyCol = ["8"]; 705 let ValueCols = [["8"]]; 706} 707 708def getMCOpcode : InstrMapping { 709 let FilterClass = "SIMCInstr"; 710 let RowFields = ["PseudoInstr"]; 711 let ColFields = ["Subtarget"]; 712 let KeyCol = [!cast<string>(SISubtarget.NONE)]; 713 let ValueCols = [[!cast<string>(SISubtarget.SI)]]; 714} 715 716include "SIInstructions.td" 717