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