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//===----------------------------------------------------------------------===// 9def isCI : Predicate<"Subtarget->getGeneration() " 10 ">= AMDGPUSubtarget::SEA_ISLANDS">; 11def isCIOnly : Predicate<"Subtarget->getGeneration() ==" 12 "AMDGPUSubtarget::SEA_ISLANDS">, 13 AssemblerPredicate <"FeatureSeaIslands">; 14 15def DisableInst : Predicate <"false">, AssemblerPredicate<"FeatureDisable">; 16 17class vop { 18 field bits<9> SI3; 19 field bits<10> VI3; 20} 21 22class vopc <bits<8> si, bits<8> vi = !add(0x40, si)> : vop { 23 field bits<8> SI = si; 24 field bits<8> VI = vi; 25 26 field bits<9> SI3 = {0, si{7-0}}; 27 field bits<10> VI3 = {0, 0, vi{7-0}}; 28} 29 30class vop1 <bits<8> si, bits<8> vi = si> : vop { 31 field bits<8> SI = si; 32 field bits<8> VI = vi; 33 34 field bits<9> SI3 = {1, 1, si{6-0}}; 35 field bits<10> VI3 = !add(0x140, vi); 36} 37 38class vop2 <bits<6> si, bits<6> vi = si> : vop { 39 field bits<6> SI = si; 40 field bits<6> VI = vi; 41 42 field bits<9> SI3 = {1, 0, 0, si{5-0}}; 43 field bits<10> VI3 = {0, 1, 0, 0, vi{5-0}}; 44} 45 46// Specify a VOP2 opcode for SI and VOP3 opcode for VI 47// that doesn't have VOP2 encoding on VI 48class vop23 <bits<6> si, bits<10> vi> : vop2 <si> { 49 let VI3 = vi; 50} 51 52class vop3 <bits<9> si, bits<10> vi = {0, si}> : vop { 53 let SI3 = si; 54 let VI3 = vi; 55} 56 57class sop1 <bits<8> si, bits<8> vi = si> { 58 field bits<8> SI = si; 59 field bits<8> VI = vi; 60} 61 62class sop2 <bits<7> si, bits<7> vi = si> { 63 field bits<7> SI = si; 64 field bits<7> VI = vi; 65} 66 67class sopk <bits<5> si, bits<5> vi = si> { 68 field bits<5> SI = si; 69 field bits<5> VI = vi; 70} 71 72// Specify an SMRD opcode for SI and SMEM opcode for VI 73 74// FIXME: This should really be bits<5> si, Tablegen crashes if 75// parameter default value is other parameter with different bit size 76class smrd<bits<8> si, bits<8> vi = si> { 77 field bits<5> SI = si{4-0}; 78 field bits<8> VI = vi; 79} 80 81// Execpt for the NONE field, this must be kept in sync with the SISubtarget enum 82// in AMDGPUInstrInfo.cpp 83def SISubtarget { 84 int NONE = -1; 85 int SI = 0; 86 int VI = 1; 87} 88 89//===----------------------------------------------------------------------===// 90// SI DAG Nodes 91//===----------------------------------------------------------------------===// 92 93def SIload_constant : SDNode<"AMDGPUISD::LOAD_CONSTANT", 94 SDTypeProfile<1, 2, [SDTCisVT<0, f32>, SDTCisVT<1, v4i32>, SDTCisVT<2, i32>]>, 95 [SDNPMayLoad, SDNPMemOperand] 96>; 97 98def SItbuffer_store : SDNode<"AMDGPUISD::TBUFFER_STORE_FORMAT", 99 SDTypeProfile<0, 13, 100 [SDTCisVT<0, v4i32>, // rsrc(SGPR) 101 SDTCisVT<1, iAny>, // vdata(VGPR) 102 SDTCisVT<2, i32>, // num_channels(imm) 103 SDTCisVT<3, i32>, // vaddr(VGPR) 104 SDTCisVT<4, i32>, // soffset(SGPR) 105 SDTCisVT<5, i32>, // inst_offset(imm) 106 SDTCisVT<6, i32>, // dfmt(imm) 107 SDTCisVT<7, i32>, // nfmt(imm) 108 SDTCisVT<8, i32>, // offen(imm) 109 SDTCisVT<9, i32>, // idxen(imm) 110 SDTCisVT<10, i32>, // glc(imm) 111 SDTCisVT<11, i32>, // slc(imm) 112 SDTCisVT<12, i32> // tfe(imm) 113 ]>, 114 [SDNPMayStore, SDNPMemOperand, SDNPHasChain] 115>; 116 117def SIload_input : SDNode<"AMDGPUISD::LOAD_INPUT", 118 SDTypeProfile<1, 3, [SDTCisVT<0, v4f32>, SDTCisVT<1, v4i32>, SDTCisVT<2, i16>, 119 SDTCisVT<3, i32>]> 120>; 121 122class SDSample<string opcode> : SDNode <opcode, 123 SDTypeProfile<1, 4, [SDTCisVT<0, v4f32>, SDTCisVT<2, v8i32>, 124 SDTCisVT<3, v4i32>, SDTCisVT<4, i32>]> 125>; 126 127def SIsample : SDSample<"AMDGPUISD::SAMPLE">; 128def SIsampleb : SDSample<"AMDGPUISD::SAMPLEB">; 129def SIsampled : SDSample<"AMDGPUISD::SAMPLED">; 130def SIsamplel : SDSample<"AMDGPUISD::SAMPLEL">; 131 132def SIconstdata_ptr : SDNode< 133 "AMDGPUISD::CONST_DATA_PTR", SDTypeProfile <1, 1, [SDTCisVT<0, i64>, 134 SDTCisVT<0, i64>]> 135>; 136 137//===----------------------------------------------------------------------===// 138// PatFrags for FLAT instructions 139//===----------------------------------------------------------------------===// 140 141class flat_ld <SDPatternOperator ld> : PatFrag<(ops node:$ptr), 142 (ld node:$ptr), [{ 143 return isFlatLoad(dyn_cast<LoadSDNode>(N)) || 144 isGlobalLoad(dyn_cast<LoadSDNode>(N)) || 145 isConstantLoad(cast<LoadSDNode>(N), -1); 146}]>; 147 148def flat_load : flat_ld <load>; 149def flat_az_extloadi8 : flat_ld <az_extloadi8>; 150def flat_sextloadi8 : flat_ld <sextloadi8>; 151def flat_az_extloadi16 : flat_ld <az_extloadi16>; 152def flat_sextloadi16 : flat_ld <sextloadi16>; 153 154class flat_st <SDPatternOperator st> : PatFrag<(ops node:$val, node:$ptr), 155 (st node:$val, node:$ptr), [{ 156 return isFlatStore(dyn_cast<StoreSDNode>(N)) || 157 isGlobalStore(dyn_cast<StoreSDNode>(N)); 158}]>; 159 160def flat_store: flat_st <store>; 161def flat_truncstorei8 : flat_st <truncstorei8>; 162def flat_truncstorei16 : flat_st <truncstorei16>; 163 164 165def mubuf_load : PatFrag <(ops node:$ptr), (load node:$ptr), [{ 166 return isGlobalLoad(cast<LoadSDNode>(N)) || 167 isConstantLoad(cast<LoadSDNode>(N), -1); 168}]>; 169 170def smrd_load : PatFrag <(ops node:$ptr), (load node:$ptr), [{ 171 return isConstantLoad(cast<LoadSDNode>(N), -1) && 172 static_cast<const SITargetLowering *>(getTargetLowering())->isMemOpUniform(N); 173}]>; 174 175//===----------------------------------------------------------------------===// 176// SDNodes and PatFrag for local loads and stores to enable s_mov_b32 m0, -1 177// to be glued to the memory instructions. 178//===----------------------------------------------------------------------===// 179 180def SIld_local : SDNode <"ISD::LOAD", SDTLoad, 181 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand, SDNPInGlue] 182>; 183 184def si_ld_local : PatFrag <(ops node:$ptr), (SIld_local node:$ptr), [{ 185 return isLocalLoad(cast<LoadSDNode>(N)); 186}]>; 187 188def si_load_local : PatFrag <(ops node:$ptr), (si_ld_local node:$ptr), [{ 189 return cast<LoadSDNode>(N)->getAddressingMode() == ISD::UNINDEXED && 190 cast<LoadSDNode>(N)->getExtensionType() == ISD::NON_EXTLOAD; 191}]>; 192 193def si_load_local_align8 : Aligned8Bytes < 194 (ops node:$ptr), (si_load_local node:$ptr) 195>; 196 197def si_sextload_local : PatFrag <(ops node:$ptr), (si_ld_local node:$ptr), [{ 198 return cast<LoadSDNode>(N)->getExtensionType() == ISD::SEXTLOAD; 199}]>; 200def si_az_extload_local : AZExtLoadBase <si_ld_local>; 201 202multiclass SIExtLoadLocal <PatFrag ld_node> { 203 204 def _i8 : PatFrag <(ops node:$ptr), (ld_node node:$ptr), 205 [{return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i8;}] 206 >; 207 208 def _i16 : PatFrag <(ops node:$ptr), (ld_node node:$ptr), 209 [{return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i16;}] 210 >; 211} 212 213defm si_sextload_local : SIExtLoadLocal <si_sextload_local>; 214defm si_az_extload_local : SIExtLoadLocal <si_az_extload_local>; 215 216def SIst_local : SDNode <"ISD::STORE", SDTStore, 217 [SDNPHasChain, SDNPMayStore, SDNPMemOperand, SDNPInGlue] 218>; 219 220def si_st_local : PatFrag < 221 (ops node:$val, node:$ptr), (SIst_local node:$val, node:$ptr), [{ 222 return isLocalStore(cast<StoreSDNode>(N)); 223}]>; 224 225def si_store_local : PatFrag < 226 (ops node:$val, node:$ptr), (si_st_local node:$val, node:$ptr), [{ 227 return cast<StoreSDNode>(N)->getAddressingMode() == ISD::UNINDEXED && 228 !cast<StoreSDNode>(N)->isTruncatingStore(); 229}]>; 230 231def si_store_local_align8 : Aligned8Bytes < 232 (ops node:$val, node:$ptr), (si_store_local node:$val, node:$ptr) 233>; 234 235def si_truncstore_local : PatFrag < 236 (ops node:$val, node:$ptr), (si_st_local node:$val, node:$ptr), [{ 237 return cast<StoreSDNode>(N)->isTruncatingStore(); 238}]>; 239 240def si_truncstore_local_i8 : PatFrag < 241 (ops node:$val, node:$ptr), (si_truncstore_local node:$val, node:$ptr), [{ 242 return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i8; 243}]>; 244 245def si_truncstore_local_i16 : PatFrag < 246 (ops node:$val, node:$ptr), (si_truncstore_local node:$val, node:$ptr), [{ 247 return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i16; 248}]>; 249 250def si_setcc_uniform : PatFrag < 251 (ops node:$lhs, node:$rhs, node:$cond), 252 (setcc node:$lhs, node:$rhs, node:$cond), [{ 253 for (SDNode *Use : N->uses()) { 254 if (Use->isMachineOpcode() || Use->getOpcode() != ISD::CopyToReg) 255 return false; 256 257 unsigned Reg = cast<RegisterSDNode>(Use->getOperand(1))->getReg(); 258 if (Reg != AMDGPU::SCC) 259 return false; 260 } 261 return true; 262}]>; 263 264def si_uniform_br : PatFrag < 265 (ops node:$cond, node:$bb), (brcond node:$cond, node:$bb), [{ 266 return isUniformBr(N); 267}]>; 268 269def si_uniform_br_scc : PatFrag < 270 (ops node:$cond, node:$bb), (si_uniform_br node:$cond, node:$bb), [{ 271 return isCBranchSCC(N); 272}]>; 273 274multiclass SIAtomicM0Glue2 <string op_name> { 275 276 def _glue : SDNode <"ISD::ATOMIC_"#op_name, SDTAtomic2, 277 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand, SDNPInGlue] 278 >; 279 280 def _local : local_binary_atomic_op <!cast<SDNode>(NAME#"_glue")>; 281} 282 283defm si_atomic_load_add : SIAtomicM0Glue2 <"LOAD_ADD">; 284defm si_atomic_load_and : SIAtomicM0Glue2 <"LOAD_AND">; 285defm si_atomic_load_min : SIAtomicM0Glue2 <"LOAD_MIN">; 286defm si_atomic_load_max : SIAtomicM0Glue2 <"LOAD_MAX">; 287defm si_atomic_load_or : SIAtomicM0Glue2 <"LOAD_OR">; 288defm si_atomic_load_sub : SIAtomicM0Glue2 <"LOAD_SUB">; 289defm si_atomic_load_xor : SIAtomicM0Glue2 <"LOAD_XOR">; 290defm si_atomic_load_umin : SIAtomicM0Glue2 <"LOAD_UMIN">; 291defm si_atomic_load_umax : SIAtomicM0Glue2 <"LOAD_UMAX">; 292defm si_atomic_swap : SIAtomicM0Glue2 <"SWAP">; 293 294def si_atomic_cmp_swap_glue : SDNode <"ISD::ATOMIC_CMP_SWAP", SDTAtomic3, 295 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand, SDNPInGlue] 296>; 297 298defm si_atomic_cmp_swap : AtomicCmpSwapLocal <si_atomic_cmp_swap_glue>; 299 300// Transformation function, extract the lower 32bit of a 64bit immediate 301def LO32 : SDNodeXForm<imm, [{ 302 return CurDAG->getTargetConstant(N->getZExtValue() & 0xffffffff, SDLoc(N), 303 MVT::i32); 304}]>; 305 306def LO32f : SDNodeXForm<fpimm, [{ 307 APInt V = N->getValueAPF().bitcastToAPInt().trunc(32); 308 return CurDAG->getTargetConstantFP(APFloat(APFloat::IEEEsingle, V), MVT::f32); 309}]>; 310 311// Transformation function, extract the upper 32bit of a 64bit immediate 312def HI32 : SDNodeXForm<imm, [{ 313 return CurDAG->getTargetConstant(N->getZExtValue() >> 32, SDLoc(N), MVT::i32); 314}]>; 315 316def HI32f : SDNodeXForm<fpimm, [{ 317 APInt V = N->getValueAPF().bitcastToAPInt().lshr(32).trunc(32); 318 return CurDAG->getTargetConstantFP(APFloat(APFloat::IEEEsingle, V), SDLoc(N), 319 MVT::f32); 320}]>; 321 322def IMM8bitDWORD : PatLeaf <(imm), 323 [{return (N->getZExtValue() & ~0x3FC) == 0;}] 324>; 325 326def as_dword_i32imm : SDNodeXForm<imm, [{ 327 return CurDAG->getTargetConstant(N->getZExtValue() >> 2, SDLoc(N), MVT::i32); 328}]>; 329 330def as_i1imm : SDNodeXForm<imm, [{ 331 return CurDAG->getTargetConstant(N->getZExtValue(), SDLoc(N), MVT::i1); 332}]>; 333 334def as_i8imm : SDNodeXForm<imm, [{ 335 return CurDAG->getTargetConstant(N->getZExtValue(), SDLoc(N), MVT::i8); 336}]>; 337 338def as_i16imm : SDNodeXForm<imm, [{ 339 return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i16); 340}]>; 341 342def as_i32imm: SDNodeXForm<imm, [{ 343 return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i32); 344}]>; 345 346def as_i64imm: SDNodeXForm<imm, [{ 347 return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i64); 348}]>; 349 350// Copied from the AArch64 backend: 351def bitcast_fpimm_to_i32 : SDNodeXForm<fpimm, [{ 352return CurDAG->getTargetConstant( 353 N->getValueAPF().bitcastToAPInt().getZExtValue(), SDLoc(N), MVT::i32); 354}]>; 355 356// Copied from the AArch64 backend: 357def bitcast_fpimm_to_i64 : SDNodeXForm<fpimm, [{ 358return CurDAG->getTargetConstant( 359 N->getValueAPF().bitcastToAPInt().getZExtValue(), SDLoc(N), MVT::i64); 360}]>; 361 362def IMM8bit : PatLeaf <(imm), 363 [{return isUInt<8>(N->getZExtValue());}] 364>; 365 366def IMM12bit : PatLeaf <(imm), 367 [{return isUInt<12>(N->getZExtValue());}] 368>; 369 370def IMM16bit : PatLeaf <(imm), 371 [{return isUInt<16>(N->getZExtValue());}] 372>; 373 374def SIMM16bit : PatLeaf <(imm), 375 [{return isInt<16>(N->getSExtValue());}] 376>; 377 378def IMM20bit : PatLeaf <(imm), 379 [{return isUInt<20>(N->getZExtValue());}] 380>; 381 382def IMM32bit : PatLeaf <(imm), 383 [{return isUInt<32>(N->getZExtValue());}] 384>; 385 386def mubuf_vaddr_offset : PatFrag< 387 (ops node:$ptr, node:$offset, node:$imm_offset), 388 (add (add node:$ptr, node:$offset), node:$imm_offset) 389>; 390 391class InlineImm <ValueType vt> : PatLeaf <(vt imm), [{ 392 return isInlineImmediate(N); 393}]>; 394 395class InlineFPImm <ValueType vt> : PatLeaf <(vt fpimm), [{ 396 return isInlineImmediate(N); 397}]>; 398 399class SGPRImm <dag frag> : PatLeaf<frag, [{ 400 if (Subtarget->getGeneration() < AMDGPUSubtarget::SOUTHERN_ISLANDS) { 401 return false; 402 } 403 const SIRegisterInfo *SIRI = 404 static_cast<const SIRegisterInfo *>(Subtarget->getRegisterInfo()); 405 for (SDNode::use_iterator U = N->use_begin(), E = SDNode::use_end(); 406 U != E; ++U) { 407 const TargetRegisterClass *RC = getOperandRegClass(*U, U.getOperandNo()); 408 if (RC && SIRI->isSGPRClass(RC)) 409 return true; 410 } 411 return false; 412}]>; 413 414//===----------------------------------------------------------------------===// 415// Custom Operands 416//===----------------------------------------------------------------------===// 417 418def FRAMEri32 : Operand<iPTR> { 419 let MIOperandInfo = (ops i32:$ptr, i32imm:$index); 420} 421 422def SoppBrTarget : AsmOperandClass { 423 let Name = "SoppBrTarget"; 424 let ParserMethod = "parseSOppBrTarget"; 425} 426 427def sopp_brtarget : Operand<OtherVT> { 428 let EncoderMethod = "getSOPPBrEncoding"; 429 let OperandType = "OPERAND_PCREL"; 430 let ParserMatchClass = SoppBrTarget; 431} 432 433def const_ga : Operand<iPTR>; 434 435include "SIInstrFormats.td" 436include "VIInstrFormats.td" 437 438def MubufOffsetMatchClass : AsmOperandClass { 439 let Name = "MubufOffset"; 440 let ParserMethod = "parseMubufOptionalOps"; 441 let RenderMethod = "addImmOperands"; 442 let IsOptional = 1; 443} 444 445class DSOffsetBaseMatchClass <string parser> : AsmOperandClass { 446 let Name = "DSOffset"#parser; 447 let ParserMethod = parser; 448 let RenderMethod = "addImmOperands"; 449 let PredicateMethod = "isDSOffset"; 450 let IsOptional = 1; 451} 452 453def DSOffsetMatchClass : DSOffsetBaseMatchClass <"parseDSOptionalOps">; 454def DSOffsetGDSMatchClass : DSOffsetBaseMatchClass <"parseDSOffsetOptional">; 455 456def DSOffset01MatchClass : AsmOperandClass { 457 let Name = "DSOffset1"; 458 let ParserMethod = "parseDSOff01OptionalOps"; 459 let RenderMethod = "addImmOperands"; 460 let PredicateMethod = "isDSOffset01"; 461 let IsOptional = 1; 462} 463 464class GDSBaseMatchClass <string parser> : AsmOperandClass { 465 let Name = "GDS"#parser; 466 let PredicateMethod = "isImm"; 467 let ParserMethod = parser; 468 let RenderMethod = "addImmOperands"; 469 let IsOptional = 1; 470} 471 472def GDSMatchClass : GDSBaseMatchClass <"parseDSOptionalOps">; 473def GDS01MatchClass : GDSBaseMatchClass <"parseDSOff01OptionalOps">; 474 475class GLCBaseMatchClass <string parser> : AsmOperandClass { 476 let Name = "GLC"#parser; 477 let PredicateMethod = "isImm"; 478 let ParserMethod = parser; 479 let RenderMethod = "addImmOperands"; 480 let IsOptional = 1; 481} 482 483def GLCMubufMatchClass : GLCBaseMatchClass <"parseMubufOptionalOps">; 484def GLCFlatMatchClass : GLCBaseMatchClass <"parseFlatOptionalOps">; 485 486class SLCBaseMatchClass <string parser> : AsmOperandClass { 487 let Name = "SLC"#parser; 488 let PredicateMethod = "isImm"; 489 let ParserMethod = parser; 490 let RenderMethod = "addImmOperands"; 491 let IsOptional = 1; 492} 493 494def SLCMubufMatchClass : SLCBaseMatchClass <"parseMubufOptionalOps">; 495def SLCFlatMatchClass : SLCBaseMatchClass <"parseFlatOptionalOps">; 496def SLCFlatAtomicMatchClass : SLCBaseMatchClass <"parseFlatAtomicOptionalOps">; 497 498class TFEBaseMatchClass <string parser> : AsmOperandClass { 499 let Name = "TFE"#parser; 500 let PredicateMethod = "isImm"; 501 let ParserMethod = parser; 502 let RenderMethod = "addImmOperands"; 503 let IsOptional = 1; 504} 505 506def TFEMubufMatchClass : TFEBaseMatchClass <"parseMubufOptionalOps">; 507def TFEFlatMatchClass : TFEBaseMatchClass <"parseFlatOptionalOps">; 508def TFEFlatAtomicMatchClass : TFEBaseMatchClass <"parseFlatAtomicOptionalOps">; 509 510def OModMatchClass : AsmOperandClass { 511 let Name = "OMod"; 512 let PredicateMethod = "isImm"; 513 let ParserMethod = "parseVOP3OptionalOps"; 514 let RenderMethod = "addImmOperands"; 515 let IsOptional = 1; 516} 517 518def ClampMatchClass : AsmOperandClass { 519 let Name = "Clamp"; 520 let PredicateMethod = "isImm"; 521 let ParserMethod = "parseVOP3OptionalOps"; 522 let RenderMethod = "addImmOperands"; 523 let IsOptional = 1; 524} 525 526class SMRDOffsetBaseMatchClass <string predicate> : AsmOperandClass { 527 let Name = "SMRDOffset"#predicate; 528 let PredicateMethod = predicate; 529 let RenderMethod = "addImmOperands"; 530} 531 532def SMRDOffsetMatchClass : SMRDOffsetBaseMatchClass <"isSMRDOffset">; 533def SMRDLiteralOffsetMatchClass : SMRDOffsetBaseMatchClass < 534 "isSMRDLiteralOffset" 535>; 536 537class OptionalImmAsmOperand <string OpName> : AsmOperandClass { 538 let Name = "Imm"#OpName; 539 let PredicateMethod = "isImm"; 540 let RenderMethod = "addImmOperands"; 541 let IsOptional = 1; 542} 543 544def DMaskMatchClass : AsmOperandClass { 545 let Name = "DMask"; 546 let PredicateMethod = "isDMask"; 547 let ParserMethod = "parseDMask"; 548 let RenderMethod = "addImmOperands"; 549 let IsOptional = 1; 550} 551 552class NamedBitMatchClass<string BitName> : AsmOperandClass { 553 let Name = "Imm"#BitName; 554 let PredicateMethod = "is"#BitName; 555 let ParserMethod = "parse"#BitName; 556 let RenderMethod = "addImmOperands"; 557 let IsOptional = 1; 558} 559 560class NamedBitOperand<string BitName> : Operand<i1> { 561 let PrintMethod = "print"#BitName; 562} 563 564let OperandType = "OPERAND_IMMEDIATE" in { 565 566def offen : Operand<i1> { 567 let PrintMethod = "printOffen"; 568 let ParserMatchClass = OptionalImmAsmOperand<"offen">; 569} 570def idxen : Operand<i1> { 571 let PrintMethod = "printIdxen"; 572 let ParserMatchClass = OptionalImmAsmOperand<"idxen">; 573} 574def addr64 : Operand<i1> { 575 let PrintMethod = "printAddr64"; 576} 577def mbuf_offset : Operand<i16> { 578 let PrintMethod = "printMBUFOffset"; 579 let ParserMatchClass = MubufOffsetMatchClass; 580} 581class ds_offset_base <AsmOperandClass mc> : Operand<i16> { 582 let PrintMethod = "printDSOffset"; 583 let ParserMatchClass = mc; 584} 585def ds_offset : ds_offset_base <DSOffsetMatchClass>; 586def ds_offset_gds : ds_offset_base <DSOffsetGDSMatchClass>; 587 588def ds_offset0 : Operand<i8> { 589 let PrintMethod = "printDSOffset0"; 590 let ParserMatchClass = DSOffset01MatchClass; 591} 592def ds_offset1 : Operand<i8> { 593 let PrintMethod = "printDSOffset1"; 594 let ParserMatchClass = DSOffset01MatchClass; 595} 596class gds_base <AsmOperandClass mc> : Operand <i1> { 597 let PrintMethod = "printGDS"; 598 let ParserMatchClass = mc; 599} 600def gds : gds_base <GDSMatchClass>; 601 602def gds01 : gds_base <GDS01MatchClass>; 603 604class glc_base <AsmOperandClass mc> : Operand <i1> { 605 let PrintMethod = "printGLC"; 606 let ParserMatchClass = mc; 607} 608 609def glc : glc_base <GLCMubufMatchClass>; 610def glc_flat : glc_base <GLCFlatMatchClass>; 611 612class slc_base <AsmOperandClass mc> : Operand <i1> { 613 let PrintMethod = "printSLC"; 614 let ParserMatchClass = mc; 615} 616 617def slc : slc_base <SLCMubufMatchClass>; 618def slc_flat : slc_base <SLCFlatMatchClass>; 619def slc_flat_atomic : slc_base <SLCFlatAtomicMatchClass>; 620 621class tfe_base <AsmOperandClass mc> : Operand <i1> { 622 let PrintMethod = "printTFE"; 623 let ParserMatchClass = mc; 624} 625 626def tfe : tfe_base <TFEMubufMatchClass>; 627def tfe_flat : tfe_base <TFEFlatMatchClass>; 628def tfe_flat_atomic : tfe_base <TFEFlatAtomicMatchClass>; 629 630def omod : Operand <i32> { 631 let PrintMethod = "printOModSI"; 632 let ParserMatchClass = OModMatchClass; 633} 634 635def ClampMod : Operand <i1> { 636 let PrintMethod = "printClampSI"; 637 let ParserMatchClass = ClampMatchClass; 638} 639 640def smrd_offset : Operand <i32> { 641 let PrintMethod = "printU32ImmOperand"; 642 let ParserMatchClass = SMRDOffsetMatchClass; 643} 644 645def smrd_literal_offset : Operand <i32> { 646 let PrintMethod = "printU32ImmOperand"; 647 let ParserMatchClass = SMRDLiteralOffsetMatchClass; 648} 649 650def dmask : Operand <i32> { 651 let PrintMethod = "printDMask"; 652 let ParserMatchClass = DMaskMatchClass; 653} 654 655def unorm : NamedBitOperand<"UNorm"> { 656 let ParserMatchClass = NamedBitMatchClass<"UNorm">; 657} 658 659def da : NamedBitOperand<"DA"> { 660 let ParserMatchClass = NamedBitMatchClass<"DA">; 661} 662 663def r128 : NamedBitOperand<"R128"> { 664 let ParserMatchClass = NamedBitMatchClass<"R128">; 665} 666 667def lwe : NamedBitOperand<"LWE"> { 668 let ParserMatchClass = NamedBitMatchClass<"LWE">; 669} 670 671} // End OperandType = "OPERAND_IMMEDIATE" 672 673 674def VOPDstS64 : VOPDstOperand <SReg_64>; 675 676//===----------------------------------------------------------------------===// 677// Complex patterns 678//===----------------------------------------------------------------------===// 679 680def DS1Addr1Offset : ComplexPattern<i32, 2, "SelectDS1Addr1Offset">; 681def DS64Bit4ByteAligned : ComplexPattern<i32, 3, "SelectDS64Bit4ByteAligned">; 682 683def MUBUFAddr32 : ComplexPattern<i64, 9, "SelectMUBUFAddr32">; 684def MUBUFAddr64 : ComplexPattern<i64, 7, "SelectMUBUFAddr64">; 685def MUBUFAddr64Atomic : ComplexPattern<i64, 5, "SelectMUBUFAddr64">; 686def MUBUFScratch : ComplexPattern<i64, 4, "SelectMUBUFScratch">; 687def MUBUFOffset : ComplexPattern<i64, 6, "SelectMUBUFOffset">; 688def MUBUFOffsetAtomic : ComplexPattern<i64, 4, "SelectMUBUFOffset">; 689 690def SMRDImm : ComplexPattern<i64, 2, "SelectSMRDImm">; 691def SMRDImm32 : ComplexPattern<i64, 2, "SelectSMRDImm32">; 692def SMRDSgpr : ComplexPattern<i64, 2, "SelectSMRDSgpr">; 693def SMRDBufferImm : ComplexPattern<i32, 1, "SelectSMRDBufferImm">; 694def SMRDBufferImm32 : ComplexPattern<i32, 1, "SelectSMRDBufferImm32">; 695def SMRDBufferSgpr : ComplexPattern<i32, 1, "SelectSMRDBufferSgpr">; 696 697def VOP3Mods0 : ComplexPattern<untyped, 4, "SelectVOP3Mods0">; 698def VOP3NoMods0 : ComplexPattern<untyped, 4, "SelectVOP3NoMods0">; 699def VOP3Mods0Clamp : ComplexPattern<untyped, 3, "SelectVOP3Mods0Clamp">; 700def VOP3Mods0Clamp0OMod : ComplexPattern<untyped, 4, "SelectVOP3Mods0Clamp0OMod">; 701def VOP3Mods : ComplexPattern<untyped, 2, "SelectVOP3Mods">; 702def VOP3NoMods : ComplexPattern<untyped, 2, "SelectVOP3NoMods">; 703 704//===----------------------------------------------------------------------===// 705// SI assembler operands 706//===----------------------------------------------------------------------===// 707 708def SIOperand { 709 int ZERO = 0x80; 710 int VCC = 0x6A; 711 int FLAT_SCR = 0x68; 712} 713 714def SRCMODS { 715 int NONE = 0; 716 int NEG = 1; 717} 718 719def DSTCLAMP { 720 int NONE = 0; 721} 722 723def DSTOMOD { 724 int NONE = 0; 725} 726 727//===----------------------------------------------------------------------===// 728// 729// SI Instruction multiclass helpers. 730// 731// Instructions with _32 take 32-bit operands. 732// Instructions with _64 take 64-bit operands. 733// 734// VOP_* instructions can use either a 32-bit or 64-bit encoding. The 32-bit 735// encoding is the standard encoding, but instruction that make use of 736// any of the instruction modifiers must use the 64-bit encoding. 737// 738// Instructions with _e32 use the 32-bit encoding. 739// Instructions with _e64 use the 64-bit encoding. 740// 741//===----------------------------------------------------------------------===// 742 743class SIMCInstr <string pseudo, int subtarget> { 744 string PseudoInstr = pseudo; 745 int Subtarget = subtarget; 746} 747 748//===----------------------------------------------------------------------===// 749// EXP classes 750//===----------------------------------------------------------------------===// 751 752class EXPCommon : InstSI< 753 (outs), 754 (ins i32imm:$en, i32imm:$tgt, i32imm:$compr, i32imm:$done, i32imm:$vm, 755 VGPR_32:$src0, VGPR_32:$src1, VGPR_32:$src2, VGPR_32:$src3), 756 "exp $en, $tgt, $compr, $done, $vm, $src0, $src1, $src2, $src3", 757 [] > { 758 759 let EXP_CNT = 1; 760 let Uses = [EXEC]; 761} 762 763multiclass EXP_m { 764 765 let isPseudo = 1, isCodeGenOnly = 1 in { 766 def "" : EXPCommon, SIMCInstr <"exp", SISubtarget.NONE> ; 767 } 768 769 def _si : EXPCommon, SIMCInstr <"exp", SISubtarget.SI>, EXPe { 770 let DecoderNamespace="SICI"; 771 let DisableDecoder = DisableSIDecoder; 772 } 773 774 def _vi : EXPCommon, SIMCInstr <"exp", SISubtarget.VI>, EXPe_vi { 775 let DecoderNamespace="VI"; 776 let DisableDecoder = DisableVIDecoder; 777 } 778} 779 780//===----------------------------------------------------------------------===// 781// Scalar classes 782//===----------------------------------------------------------------------===// 783 784class SOP1_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> : 785 SOP1 <outs, ins, "", pattern>, 786 SIMCInstr<opName, SISubtarget.NONE> { 787 let isPseudo = 1; 788 let isCodeGenOnly = 1; 789} 790 791class SOP1_Real_si <sop1 op, string opName, dag outs, dag ins, string asm> : 792 SOP1 <outs, ins, asm, []>, 793 SOP1e <op.SI>, 794 SIMCInstr<opName, SISubtarget.SI> { 795 let isCodeGenOnly = 0; 796 let AssemblerPredicates = [isSICI]; 797 let DecoderNamespace = "SICI"; 798 let DisableDecoder = DisableSIDecoder; 799} 800 801class SOP1_Real_vi <sop1 op, string opName, dag outs, dag ins, string asm> : 802 SOP1 <outs, ins, asm, []>, 803 SOP1e <op.VI>, 804 SIMCInstr<opName, SISubtarget.VI> { 805 let isCodeGenOnly = 0; 806 let AssemblerPredicates = [isVI]; 807 let DecoderNamespace = "VI"; 808 let DisableDecoder = DisableVIDecoder; 809} 810 811multiclass SOP1_m <sop1 op, string opName, dag outs, dag ins, string asm, 812 list<dag> pattern> { 813 814 def "" : SOP1_Pseudo <opName, outs, ins, pattern>; 815 816 def _si : SOP1_Real_si <op, opName, outs, ins, asm>; 817 818 def _vi : SOP1_Real_vi <op, opName, outs, ins, asm>; 819 820} 821 822multiclass SOP1_32 <sop1 op, string opName, list<dag> pattern> : SOP1_m < 823 op, opName, (outs SReg_32:$dst), (ins SSrc_32:$src0), 824 opName#" $dst, $src0", pattern 825>; 826 827multiclass SOP1_64 <sop1 op, string opName, list<dag> pattern> : SOP1_m < 828 op, opName, (outs SReg_64:$dst), (ins SSrc_64:$src0), 829 opName#" $dst, $src0", pattern 830>; 831 832// no input, 64-bit output. 833multiclass SOP1_64_0 <sop1 op, string opName, list<dag> pattern> { 834 def "" : SOP1_Pseudo <opName, (outs SReg_64:$dst), (ins), pattern>; 835 836 def _si : SOP1_Real_si <op, opName, (outs SReg_64:$dst), (ins), 837 opName#" $dst"> { 838 let ssrc0 = 0; 839 } 840 841 def _vi : SOP1_Real_vi <op, opName, (outs SReg_64:$dst), (ins), 842 opName#" $dst"> { 843 let ssrc0 = 0; 844 } 845} 846 847// 64-bit input, no output 848multiclass SOP1_1 <sop1 op, string opName, list<dag> pattern> { 849 def "" : SOP1_Pseudo <opName, (outs), (ins SReg_64:$src0), pattern>; 850 851 def _si : SOP1_Real_si <op, opName, (outs), (ins SReg_64:$src0), 852 opName#" $src0"> { 853 let sdst = 0; 854 } 855 856 def _vi : SOP1_Real_vi <op, opName, (outs), (ins SReg_64:$src0), 857 opName#" $src0"> { 858 let sdst = 0; 859 } 860} 861 862// 64-bit input, 32-bit output. 863multiclass SOP1_32_64 <sop1 op, string opName, list<dag> pattern> : SOP1_m < 864 op, opName, (outs SReg_32:$dst), (ins SSrc_64:$src0), 865 opName#" $dst, $src0", pattern 866>; 867 868class SOP2_Pseudo<string opName, dag outs, dag ins, list<dag> pattern> : 869 SOP2<outs, ins, "", pattern>, 870 SIMCInstr<opName, SISubtarget.NONE> { 871 let isPseudo = 1; 872 let isCodeGenOnly = 1; 873 let Size = 4; 874 875 // Pseudo instructions have no encodings, but adding this field here allows 876 // us to do: 877 // let sdst = xxx in { 878 // for multiclasses that include both real and pseudo instructions. 879 field bits<7> sdst = 0; 880} 881 882class SOP2_Real_si<sop2 op, string opName, dag outs, dag ins, string asm> : 883 SOP2<outs, ins, asm, []>, 884 SOP2e<op.SI>, 885 SIMCInstr<opName, SISubtarget.SI> { 886 let AssemblerPredicates = [isSICI]; 887 let DecoderNamespace = "SICI"; 888 let DisableDecoder = DisableSIDecoder; 889} 890 891class SOP2_Real_vi<sop2 op, string opName, dag outs, dag ins, string asm> : 892 SOP2<outs, ins, asm, []>, 893 SOP2e<op.VI>, 894 SIMCInstr<opName, SISubtarget.VI> { 895 let AssemblerPredicates = [isVI]; 896 let DecoderNamespace = "VI"; 897 let DisableDecoder = DisableVIDecoder; 898} 899 900multiclass SOP2_m <sop2 op, string opName, dag outs, dag ins, string asm, 901 list<dag> pattern> { 902 903 def "" : SOP2_Pseudo <opName, outs, ins, pattern>; 904 905 def _si : SOP2_Real_si <op, opName, outs, ins, asm>; 906 907 def _vi : SOP2_Real_vi <op, opName, outs, ins, asm>; 908 909} 910 911multiclass SOP2_32 <sop2 op, string opName, list<dag> pattern> : SOP2_m < 912 op, opName, (outs SReg_32:$dst), (ins SSrc_32:$src0, SSrc_32:$src1), 913 opName#" $dst, $src0, $src1", pattern 914>; 915 916multiclass SOP2_64 <sop2 op, string opName, list<dag> pattern> : SOP2_m < 917 op, opName, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_64:$src1), 918 opName#" $dst, $src0, $src1", pattern 919>; 920 921multiclass SOP2_64_32 <sop2 op, string opName, list<dag> pattern> : SOP2_m < 922 op, opName, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_32:$src1), 923 opName#" $dst, $src0, $src1", pattern 924>; 925 926multiclass SOP2_64_32_32 <sop2 op, string opName, list<dag> pattern> : SOP2_m < 927 op, opName, (outs SReg_64:$dst), (ins SSrc_32:$src0, SSrc_32:$src1), 928 opName#" $dst, $src0, $src1", pattern 929>; 930 931class SOPC_Helper <bits<7> op, RegisterOperand rc, ValueType vt, 932 string opName, PatLeaf cond> : SOPC < 933 op, (outs), (ins rc:$src0, rc:$src1), 934 opName#" $src0, $src1", 935 [(set SCC, (si_setcc_uniform vt:$src0, vt:$src1, cond))] > { 936 let Defs = [SCC]; 937} 938 939class SOPC_32<bits<7> op, string opName, PatLeaf cond = COND_NULL> 940 : SOPC_Helper<op, SSrc_32, i32, opName, cond>; 941 942class SOPC_64<bits<7> op, string opName, PatLeaf cond = COND_NULL> 943 : SOPC_Helper<op, SSrc_64, i64, opName, cond>; 944 945class SOPK_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> : 946 SOPK <outs, ins, "", pattern>, 947 SIMCInstr<opName, SISubtarget.NONE> { 948 let isPseudo = 1; 949 let isCodeGenOnly = 1; 950} 951 952class SOPK_Real_si <sopk op, string opName, dag outs, dag ins, string asm> : 953 SOPK <outs, ins, asm, []>, 954 SOPKe <op.SI>, 955 SIMCInstr<opName, SISubtarget.SI> { 956 let AssemblerPredicates = [isSICI]; 957 let DecoderNamespace = "SICI"; 958 let DisableDecoder = DisableSIDecoder; 959 let isCodeGenOnly = 0; 960} 961 962class SOPK_Real_vi <sopk op, string opName, dag outs, dag ins, string asm> : 963 SOPK <outs, ins, asm, []>, 964 SOPKe <op.VI>, 965 SIMCInstr<opName, SISubtarget.VI> { 966 let AssemblerPredicates = [isVI]; 967 let DecoderNamespace = "VI"; 968 let DisableDecoder = DisableVIDecoder; 969 let isCodeGenOnly = 0; 970} 971 972multiclass SOPK_m <sopk op, string opName, dag outs, dag ins, string opAsm, 973 string asm = opName#opAsm> { 974 def "" : SOPK_Pseudo <opName, outs, ins, []>; 975 976 def _si : SOPK_Real_si <op, opName, outs, ins, asm>; 977 978 def _vi : SOPK_Real_vi <op, opName, outs, ins, asm>; 979 980} 981 982multiclass SOPK_32 <sopk op, string opName, list<dag> pattern> { 983 def "" : SOPK_Pseudo <opName, (outs SReg_32:$dst), (ins u16imm:$src0), 984 pattern>; 985 986 def _si : SOPK_Real_si <op, opName, (outs SReg_32:$dst), (ins u16imm:$src0), 987 opName#" $dst, $src0">; 988 989 def _vi : SOPK_Real_vi <op, opName, (outs SReg_32:$dst), (ins u16imm:$src0), 990 opName#" $dst, $src0">; 991} 992 993multiclass SOPK_SCC <sopk op, string opName, list<dag> pattern> { 994 def "" : SOPK_Pseudo <opName, (outs), 995 (ins SReg_32:$src0, u16imm:$src1), pattern> { 996 let Defs = [SCC]; 997 } 998 999 1000 def _si : SOPK_Real_si <op, opName, (outs), 1001 (ins SReg_32:$sdst, u16imm:$simm16), opName#" $sdst, $simm16"> { 1002 let Defs = [SCC]; 1003 } 1004 1005 def _vi : SOPK_Real_vi <op, opName, (outs), 1006 (ins SReg_32:$sdst, u16imm:$simm16), opName#" $sdst, $simm16"> { 1007 let Defs = [SCC]; 1008 } 1009} 1010 1011multiclass SOPK_32TIE <sopk op, string opName, list<dag> pattern> : SOPK_m < 1012 op, opName, (outs SReg_32:$sdst), (ins SReg_32:$src0, u16imm:$simm16), 1013 " $sdst, $simm16" 1014>; 1015 1016multiclass SOPK_IMM32 <sopk op, string opName, dag outs, dag ins, 1017 string argAsm, string asm = opName#argAsm> { 1018 1019 def "" : SOPK_Pseudo <opName, outs, ins, []>; 1020 1021 def _si : SOPK <outs, ins, asm, []>, 1022 SOPK64e <op.SI>, 1023 SIMCInstr<opName, SISubtarget.SI> { 1024 let AssemblerPredicates = [isSICI]; 1025 let DecoderNamespace = "SICI"; 1026 let DisableDecoder = DisableSIDecoder; 1027 let isCodeGenOnly = 0; 1028 } 1029 1030 def _vi : SOPK <outs, ins, asm, []>, 1031 SOPK64e <op.VI>, 1032 SIMCInstr<opName, SISubtarget.VI> { 1033 let AssemblerPredicates = [isVI]; 1034 let DecoderNamespace = "VI"; 1035 let DisableDecoder = DisableVIDecoder; 1036 let isCodeGenOnly = 0; 1037 } 1038} 1039//===----------------------------------------------------------------------===// 1040// SMRD classes 1041//===----------------------------------------------------------------------===// 1042 1043class SMRD_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> : 1044 SMRD <outs, ins, "", pattern>, 1045 SIMCInstr<opName, SISubtarget.NONE> { 1046 let isPseudo = 1; 1047 let isCodeGenOnly = 1; 1048} 1049 1050class SMRD_Real_si <bits<5> op, string opName, bit imm, dag outs, dag ins, 1051 string asm> : 1052 SMRD <outs, ins, asm, []>, 1053 SMRDe <op, imm>, 1054 SIMCInstr<opName, SISubtarget.SI> { 1055 let AssemblerPredicates = [isSICI]; 1056 let DecoderNamespace = "SICI"; 1057 let DisableDecoder = DisableSIDecoder; 1058} 1059 1060class SMRD_Real_vi <bits<8> op, string opName, bit imm, dag outs, dag ins, 1061 string asm, list<dag> pattern = []> : 1062 SMRD <outs, ins, asm, pattern>, 1063 SMEMe_vi <op, imm>, 1064 SIMCInstr<opName, SISubtarget.VI> { 1065 let AssemblerPredicates = [isVI]; 1066 let DecoderNamespace = "VI"; 1067 let DisableDecoder = DisableVIDecoder; 1068} 1069 1070multiclass SMRD_m <smrd op, string opName, bit imm, dag outs, dag ins, 1071 string asm, list<dag> pattern> { 1072 1073 def "" : SMRD_Pseudo <opName, outs, ins, pattern>; 1074 1075 def _si : SMRD_Real_si <op.SI, opName, imm, outs, ins, asm>; 1076 1077 // glc is only applicable to scalar stores, which are not yet 1078 // implemented. 1079 let glc = 0 in { 1080 def _vi : SMRD_Real_vi <op.VI, opName, imm, outs, ins, asm>; 1081 } 1082} 1083 1084multiclass SMRD_Special <smrd op, string opName, dag outs, 1085 string opStr = "", 1086 list<dag> pattern = []> { 1087 let hasSideEffects = 1 in { 1088 def "" : SMRD_Pseudo <opName, outs, (ins), pattern>; 1089 1090 let sbase = 0, offset = 0 in { 1091 let sdst = 0 in { 1092 def _si : SMRD_Real_si <op.SI, opName, 0, outs, (ins), opName#opStr>; 1093 } 1094 1095 let glc = 0, sdata = 0 in { 1096 def _vi : SMRD_Real_vi <op.VI, opName, 0, outs, (ins), opName#opStr>; 1097 } 1098 } 1099 } 1100} 1101 1102multiclass SMRD_Inval <smrd op, string opName, 1103 SDPatternOperator node> { 1104 let mayStore = 1 in { 1105 defm : SMRD_Special<op, opName, (outs), "", [(node)]>; 1106 } 1107} 1108 1109class SMEM_Inval <bits<8> op, string opName, SDPatternOperator node> : 1110 SMRD_Real_vi<op, opName, 0, (outs), (ins), opName, [(node)]> { 1111 let hasSideEffects = 1; 1112 let mayStore = 1; 1113 let sbase = 0; 1114 let sdata = 0; 1115 let glc = 0; 1116 let offset = 0; 1117} 1118 1119class SMEM_Ret <bits<8> op, string opName, SDPatternOperator node> : 1120 SMRD_Real_vi<op, opName, 0, (outs SReg_64:$dst), (ins), 1121 opName#" $dst", [(set i64:$dst, (node))]> { 1122 let hasSideEffects = 1; 1123 let mayStore = ?; 1124 let mayLoad = ?; 1125 let sbase = 0; 1126 let sdata = 0; 1127 let glc = 0; 1128 let offset = 0; 1129} 1130 1131multiclass SMRD_Helper <smrd op, string opName, RegisterClass baseClass, 1132 RegisterClass dstClass> { 1133 defm _IMM : SMRD_m < 1134 op, opName#"_IMM", 1, (outs dstClass:$dst), 1135 (ins baseClass:$sbase, smrd_offset:$offset), 1136 opName#" $dst, $sbase, $offset", [] 1137 >; 1138 1139 def _IMM_ci : SMRD < 1140 (outs dstClass:$dst), (ins baseClass:$sbase, smrd_literal_offset:$offset), 1141 opName#" $dst, $sbase, $offset", []>, SMRD_IMMe_ci <op.SI> { 1142 let AssemblerPredicates = [isCIOnly]; 1143 let DecoderNamespace = "CI"; 1144 } 1145 1146 defm _SGPR : SMRD_m < 1147 op, opName#"_SGPR", 0, (outs dstClass:$dst), 1148 (ins baseClass:$sbase, SReg_32:$soff), 1149 opName#" $dst, $sbase, $soff", [] 1150 >; 1151} 1152 1153//===----------------------------------------------------------------------===// 1154// Vector ALU classes 1155//===----------------------------------------------------------------------===// 1156 1157// This must always be right before the operand being input modified. 1158def InputMods : OperandWithDefaultOps <i32, (ops (i32 0))> { 1159 let PrintMethod = "printOperandAndMods"; 1160} 1161 1162def InputModsMatchClass : AsmOperandClass { 1163 let Name = "RegOrImmWithInputMods"; 1164} 1165 1166def InputModsNoDefault : Operand <i32> { 1167 let PrintMethod = "printOperandAndMods"; 1168 let ParserMatchClass = InputModsMatchClass; 1169} 1170 1171class getNumSrcArgs<ValueType Src0, ValueType Src1, ValueType Src2> { 1172 int ret = 1173 !if (!eq(Src0.Value, untyped.Value), 0, 1174 !if (!eq(Src1.Value, untyped.Value), 1, // VOP1 1175 !if (!eq(Src2.Value, untyped.Value), 2, // VOP2 1176 3))); // VOP3 1177} 1178 1179// Returns the register class to use for the destination of VOP[123C] 1180// instructions for the given VT. 1181class getVALUDstForVT<ValueType VT> { 1182 RegisterOperand ret = !if(!eq(VT.Size, 32), VOPDstOperand<VGPR_32>, 1183 !if(!eq(VT.Size, 64), VOPDstOperand<VReg_64>, 1184 !if(!eq(VT.Size, 16), VOPDstOperand<VGPR_32>, 1185 VOPDstOperand<SReg_64>))); // else VT == i1 1186} 1187 1188// Returns the register class to use for source 0 of VOP[12C] 1189// instructions for the given VT. 1190class getVOPSrc0ForVT<ValueType VT> { 1191 RegisterOperand ret = !if(!eq(VT.Size, 64), VSrc_64, VSrc_32); 1192} 1193 1194// Returns the register class to use for source 1 of VOP[12C] for the 1195// given VT. 1196class getVOPSrc1ForVT<ValueType VT> { 1197 RegisterClass ret = !if(!eq(VT.Size, 64), VReg_64, VGPR_32); 1198} 1199 1200// Returns the register class to use for DPP source operands. 1201class getDPPSrcForVT<ValueType VT> { 1202 RegisterClass ret = !if(!eq(VT.Size, 64), VReg_64, VGPR_32); 1203} 1204 1205// Returns the register class to use for sources of VOP3 instructions for the 1206// given VT. 1207class getVOP3SrcForVT<ValueType VT> { 1208 RegisterOperand ret = 1209 !if(!eq(VT.Size, 64), 1210 VCSrc_64, 1211 !if(!eq(VT.Value, i1.Value), 1212 SCSrc_64, 1213 VCSrc_32 1214 ) 1215 ); 1216} 1217 1218// Returns 1 if the source arguments have modifiers, 0 if they do not. 1219// XXX - do f16 instructions? 1220class hasModifiers<ValueType SrcVT> { 1221 bit ret = 1222 !if(!eq(SrcVT.Value, f32.Value), 1, 1223 !if(!eq(SrcVT.Value, f64.Value), 1, 1224 0)); 1225} 1226 1227// Returns the input arguments for VOP[12C] instructions for the given SrcVT. 1228class getIns32 <RegisterOperand Src0RC, RegisterClass Src1RC, int NumSrcArgs> { 1229 dag ret = !if(!eq(NumSrcArgs, 1), (ins Src0RC:$src0), // VOP1 1230 !if(!eq(NumSrcArgs, 2), (ins Src0RC:$src0, Src1RC:$src1), // VOP2 1231 (ins))); 1232} 1233 1234// Returns the input arguments for VOP3 instructions for the given SrcVT. 1235class getIns64 <RegisterOperand Src0RC, RegisterOperand Src1RC, 1236 RegisterOperand Src2RC, int NumSrcArgs, 1237 bit HasModifiers> { 1238 1239 dag ret = 1240 !if (!eq(NumSrcArgs, 0), 1241 // VOP1 without input operands (V_NOP, V_CLREXCP) 1242 (ins), 1243 /* else */ 1244 !if (!eq(NumSrcArgs, 1), 1245 !if (!eq(HasModifiers, 1), 1246 // VOP1 with modifiers 1247 (ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0, 1248 ClampMod:$clamp, omod:$omod) 1249 /* else */, 1250 // VOP1 without modifiers 1251 (ins Src0RC:$src0) 1252 /* endif */ ), 1253 !if (!eq(NumSrcArgs, 2), 1254 !if (!eq(HasModifiers, 1), 1255 // VOP 2 with modifiers 1256 (ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0, 1257 InputModsNoDefault:$src1_modifiers, Src1RC:$src1, 1258 ClampMod:$clamp, omod:$omod) 1259 /* else */, 1260 // VOP2 without modifiers 1261 (ins Src0RC:$src0, Src1RC:$src1) 1262 /* endif */ ) 1263 /* NumSrcArgs == 3 */, 1264 !if (!eq(HasModifiers, 1), 1265 // VOP3 with modifiers 1266 (ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0, 1267 InputModsNoDefault:$src1_modifiers, Src1RC:$src1, 1268 InputModsNoDefault:$src2_modifiers, Src2RC:$src2, 1269 ClampMod:$clamp, omod:$omod) 1270 /* else */, 1271 // VOP3 without modifiers 1272 (ins Src0RC:$src0, Src1RC:$src1, Src2RC:$src2) 1273 /* endif */ )))); 1274} 1275 1276class getInsDPP <RegisterClass Src0RC, RegisterClass Src1RC, int NumSrcArgs, 1277 bit HasModifiers> { 1278 1279 dag ret = !if (!eq(NumSrcArgs, 1), 1280 !if (!eq(HasModifiers, 1), 1281 // VOP1_DPP with modifiers 1282 (ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0, 1283 i32imm:$dpp_ctrl, i1imm:$bound_ctrl, 1284 i32imm:$bank_mask, i32imm:$row_mask) 1285 /* else */, 1286 // VOP1_DPP without modifiers 1287 (ins Src0RC:$src0, i32imm:$dpp_ctrl, i1imm:$bound_ctrl, 1288 i32imm:$bank_mask, i32imm:$row_mask) 1289 /* endif */) 1290 /* NumSrcArgs == 2 */, 1291 !if (!eq(HasModifiers, 1), 1292 // VOP2_DPP with modifiers 1293 (ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0, 1294 InputModsNoDefault:$src1_modifiers, Src1RC:$src1, 1295 i32imm:$dpp_ctrl, i1imm:$bound_ctrl, 1296 i32imm:$bank_mask, i32imm:$row_mask) 1297 /* else */, 1298 // VOP2_DPP without modifiers 1299 (ins Src0RC:$src0, Src1RC:$src1, i32imm:$dpp_ctrl, i1imm:$bound_ctrl, 1300 i32imm:$bank_mask, i32imm:$row_mask) 1301 /* endif */)); 1302} 1303 1304// Returns the assembly string for the inputs and outputs of a VOP[12C] 1305// instruction. This does not add the _e32 suffix, so it can be reused 1306// by getAsm64. 1307class getAsm32 <bit HasDst, int NumSrcArgs, ValueType DstVT = i32> { 1308 string dst = !if(!eq(DstVT.Size, 1), "$sdst", "$vdst"); // use $sdst for VOPC 1309 string src0 = ", $src0"; 1310 string src1 = ", $src1"; 1311 string src2 = ", $src2"; 1312 string ret = !if(HasDst, dst, "") # 1313 !if(!eq(NumSrcArgs, 1), src0, "") # 1314 !if(!eq(NumSrcArgs, 2), src0#src1, "") # 1315 !if(!eq(NumSrcArgs, 3), src0#src1#src2, ""); 1316} 1317 1318// Returns the assembly string for the inputs and outputs of a VOP3 1319// instruction. 1320class getAsm64 <bit HasDst, int NumSrcArgs, bit HasModifiers, ValueType DstVT = i32> { 1321 string dst = !if(!eq(DstVT.Size, 1), "$sdst", "$vdst"); // use $sdst for VOPC 1322 string src0 = !if(!eq(NumSrcArgs, 1), "$src0_modifiers", "$src0_modifiers,"); 1323 string src1 = !if(!eq(NumSrcArgs, 1), "", 1324 !if(!eq(NumSrcArgs, 2), " $src1_modifiers", 1325 " $src1_modifiers,")); 1326 string src2 = !if(!eq(NumSrcArgs, 3), " $src2_modifiers", ""); 1327 string ret = 1328 !if(!eq(HasModifiers, 0), 1329 getAsm32<HasDst, NumSrcArgs, DstVT>.ret, 1330 dst#", "#src0#src1#src2#"$clamp"#"$omod"); 1331} 1332 1333class getAsmDPP <bit HasDst, int NumSrcArgs, bit HasModifiers, ValueType DstVT = i32> { 1334 string dst = !if(!eq(DstVT.Size, 1), "$sdst", "$vdst"); // use $sdst for VOPC 1335 string src0 = !if(!eq(NumSrcArgs, 1), "$src0_modifiers", "$src0_modifiers,"); 1336 string src1 = !if(!eq(NumSrcArgs, 1), "", 1337 !if(!eq(NumSrcArgs, 2), " $src1_modifiers", 1338 " $src1_modifiers,")); 1339 string args = !if(!eq(HasModifiers, 0), 1340 getAsm32<0, NumSrcArgs, DstVT>.ret, 1341 src0#src1); 1342 string ret = " "#dst#args#", $dpp_ctrl, "#"$bound_ctrl, "#"$bank_mask, "#"$row_mask"; 1343} 1344 1345class VOPProfile <list<ValueType> _ArgVT> { 1346 1347 field list<ValueType> ArgVT = _ArgVT; 1348 1349 field ValueType DstVT = ArgVT[0]; 1350 field ValueType Src0VT = ArgVT[1]; 1351 field ValueType Src1VT = ArgVT[2]; 1352 field ValueType Src2VT = ArgVT[3]; 1353 field RegisterOperand DstRC = getVALUDstForVT<DstVT>.ret; 1354 field RegisterClass DstRCDPP = !if(!eq(DstVT.Size, 64), VReg_64, VGPR_32); 1355 field RegisterOperand Src0RC32 = getVOPSrc0ForVT<Src0VT>.ret; 1356 field RegisterClass Src1RC32 = getVOPSrc1ForVT<Src1VT>.ret; 1357 field RegisterOperand Src0RC64 = getVOP3SrcForVT<Src0VT>.ret; 1358 field RegisterOperand Src1RC64 = getVOP3SrcForVT<Src1VT>.ret; 1359 field RegisterOperand Src2RC64 = getVOP3SrcForVT<Src2VT>.ret; 1360 field RegisterClass Src0DPP = getDPPSrcForVT<Src0VT>.ret; 1361 field RegisterClass Src1DPP = getDPPSrcForVT<Src1VT>.ret; 1362 1363 field bit HasDst = !if(!eq(DstVT.Value, untyped.Value), 0, 1); 1364 field bit HasDst32 = HasDst; 1365 field int NumSrcArgs = getNumSrcArgs<Src0VT, Src1VT, Src2VT>.ret; 1366 field bit HasModifiers = hasModifiers<Src0VT>.ret; 1367 1368 field dag Outs = !if(HasDst,(outs DstRC:$vdst),(outs)); 1369 1370 // VOP3b instructions are a special case with a second explicit 1371 // output. This is manually overridden for them. 1372 field dag Outs32 = Outs; 1373 field dag Outs64 = Outs; 1374 field dag OutsDPP = !if(!eq(DstVT.Size, 1), (outs DstRCDPP:$sdst), // sdst for VOPC 1375 (outs DstRCDPP:$vdst)); 1376 1377 field dag Ins32 = getIns32<Src0RC32, Src1RC32, NumSrcArgs>.ret; 1378 field dag Ins64 = getIns64<Src0RC64, Src1RC64, Src2RC64, NumSrcArgs, 1379 HasModifiers>.ret; 1380 field dag InsDPP = getInsDPP<Src0DPP, Src1DPP, NumSrcArgs, HasModifiers>.ret; 1381 1382 field string Asm32 = getAsm32<HasDst, NumSrcArgs, DstVT>.ret; 1383 field string Asm64 = getAsm64<HasDst, NumSrcArgs, HasModifiers, DstVT>.ret; 1384 field string AsmDPP = getAsmDPP<HasDst, NumSrcArgs, HasModifiers, DstVT>.ret; 1385} 1386 1387// FIXME: I think these F16/I16 profiles will need to use f16/i16 types in order 1388// for the instruction patterns to work. 1389def VOP_F16_F16 : VOPProfile <[f16, f16, untyped, untyped]>; 1390def VOP_F16_I16 : VOPProfile <[f16, i32, untyped, untyped]>; 1391def VOP_I16_F16 : VOPProfile <[i32, f16, untyped, untyped]>; 1392 1393def VOP_F16_F16_F16 : VOPProfile <[f16, f16, f16, untyped]>; 1394def VOP_F16_F16_I16 : VOPProfile <[f16, f16, i32, untyped]>; 1395def VOP_I16_I16_I16 : VOPProfile <[i32, i32, i32, untyped]>; 1396 1397def VOP_NONE : VOPProfile <[untyped, untyped, untyped, untyped]>; 1398 1399def VOP_F32_F32 : VOPProfile <[f32, f32, untyped, untyped]>; 1400def VOP_F32_F64 : VOPProfile <[f32, f64, untyped, untyped]>; 1401def VOP_F32_I32 : VOPProfile <[f32, i32, untyped, untyped]>; 1402def VOP_F64_F32 : VOPProfile <[f64, f32, untyped, untyped]>; 1403def VOP_F64_F64 : VOPProfile <[f64, f64, untyped, untyped]>; 1404def VOP_F64_I32 : VOPProfile <[f64, i32, untyped, untyped]>; 1405def VOP_I32_F32 : VOPProfile <[i32, f32, untyped, untyped]>; 1406def VOP_I32_F64 : VOPProfile <[i32, f64, untyped, untyped]>; 1407def VOP_I32_I32 : VOPProfile <[i32, i32, untyped, untyped]>; 1408 1409def VOP_F32_F32_F32 : VOPProfile <[f32, f32, f32, untyped]>; 1410def VOP_F32_F32_I32 : VOPProfile <[f32, f32, i32, untyped]>; 1411def VOP_F64_F64_F64 : VOPProfile <[f64, f64, f64, untyped]>; 1412def VOP_F64_F64_I32 : VOPProfile <[f64, f64, i32, untyped]>; 1413def VOP_I32_F32_F32 : VOPProfile <[i32, f32, f32, untyped]>; 1414def VOP_I32_F32_I32 : VOPProfile <[i32, f32, i32, untyped]>; 1415def VOP_I32_I32_I32 : VOPProfile <[i32, i32, i32, untyped]>; 1416 1417// Write out to vcc or arbitrary SGPR. 1418def VOP2b_I32_I1_I32_I32 : VOPProfile<[i32, i32, i32, untyped]> { 1419 let Asm32 = "$vdst, vcc, $src0, $src1"; 1420 let Asm64 = "$vdst, $sdst, $src0, $src1"; 1421 let Outs32 = (outs DstRC:$vdst); 1422 let Outs64 = (outs DstRC:$vdst, SReg_64:$sdst); 1423} 1424 1425// Write out to vcc or arbitrary SGPR and read in from vcc or 1426// arbitrary SGPR. 1427def VOP2b_I32_I1_I32_I32_I1 : VOPProfile<[i32, i32, i32, i1]> { 1428 // We use VCSrc_32 to exclude literal constants, even though the 1429 // encoding normally allows them since the implicit VCC use means 1430 // using one would always violate the constant bus 1431 // restriction. SGPRs are still allowed because it should 1432 // technically be possible to use VCC again as src0. 1433 let Src0RC32 = VCSrc_32; 1434 let Asm32 = "$vdst, vcc, $src0, $src1, vcc"; 1435 let Asm64 = "$vdst, $sdst, $src0, $src1, $src2"; 1436 let Outs32 = (outs DstRC:$vdst); 1437 let Outs64 = (outs DstRC:$vdst, SReg_64:$sdst); 1438 1439 // Suppress src2 implied by type since the 32-bit encoding uses an 1440 // implicit VCC use. 1441 let Ins32 = (ins Src0RC32:$src0, Src1RC32:$src1); 1442} 1443 1444class VOP3b_Profile<ValueType vt> : VOPProfile<[vt, vt, vt, vt]> { 1445 let Outs64 = (outs DstRC:$vdst, SReg_64:$sdst); 1446 let Asm64 = "$vdst, $sdst, $src0_modifiers, $src1_modifiers, $src2_modifiers"#"$clamp"#"$omod"; 1447} 1448 1449def VOP3b_F32_I1_F32_F32_F32 : VOP3b_Profile<f32> { 1450 // FIXME: Hack to stop printing _e64 1451 let DstRC = RegisterOperand<VGPR_32>; 1452} 1453 1454def VOP3b_F64_I1_F64_F64_F64 : VOP3b_Profile<f64> { 1455 // FIXME: Hack to stop printing _e64 1456 let DstRC = RegisterOperand<VReg_64>; 1457} 1458 1459// VOPC instructions are a special case because for the 32-bit 1460// encoding, we want to display the implicit vcc write as if it were 1461// an explicit $dst. 1462class VOPC_Profile<ValueType vt0, ValueType vt1 = vt0> : VOPProfile <[i1, vt0, vt1, untyped]> { 1463 let Asm32 = "vcc, $src0, $src1"; 1464 // The destination for 32-bit encoding is implicit. 1465 let HasDst32 = 0; 1466 let Outs64 = (outs DstRC:$sdst); 1467} 1468 1469class VOPC_Class_Profile<ValueType vt> : VOPC_Profile<vt, i32> { 1470 let Ins64 = (ins InputModsNoDefault:$src0_modifiers, Src0RC64:$src0, Src1RC64:$src1); 1471 let Asm64 = "$sdst, $src0_modifiers, $src1"; 1472} 1473 1474def VOPC_I1_F32_F32 : VOPC_Profile<f32>; 1475def VOPC_I1_F64_F64 : VOPC_Profile<f64>; 1476def VOPC_I1_I32_I32 : VOPC_Profile<i32>; 1477def VOPC_I1_I64_I64 : VOPC_Profile<i64>; 1478 1479def VOPC_I1_F32_I32 : VOPC_Class_Profile<f32>; 1480def VOPC_I1_F64_I32 : VOPC_Class_Profile<f64>; 1481 1482def VOP_I64_I64_I32 : VOPProfile <[i64, i64, i32, untyped]>; 1483def VOP_I64_I32_I64 : VOPProfile <[i64, i32, i64, untyped]>; 1484def VOP_I64_I64_I64 : VOPProfile <[i64, i64, i64, untyped]>; 1485def VOP_CNDMASK : VOPProfile <[i32, i32, i32, untyped]> { 1486 let Ins32 = (ins Src0RC32:$src0, Src1RC32:$src1); 1487 let Ins64 = (ins Src0RC64:$src0, Src1RC64:$src1, SSrc_64:$src2); 1488 let Asm64 = "$vdst, $src0, $src1, $src2"; 1489} 1490 1491def VOP_F32_F32_F32_F32 : VOPProfile <[f32, f32, f32, f32]>; 1492def VOP_MADK : VOPProfile <[f32, f32, f32, f32]> { 1493 field dag Ins = (ins VCSrc_32:$src0, VGPR_32:$vsrc1, u32imm:$src2); 1494 field string Asm = "$vdst, $src0, $vsrc1, $src2"; 1495} 1496def VOP_MAC : VOPProfile <[f32, f32, f32, f32]> { 1497 let Ins32 = (ins Src0RC32:$src0, Src1RC32:$src1, VGPR_32:$src2); 1498 let Ins64 = getIns64<Src0RC64, Src1RC64, RegisterOperand<VGPR_32>, 3, 1499 HasModifiers>.ret; 1500 let Asm32 = getAsm32<1, 2, f32>.ret; 1501 let Asm64 = getAsm64<1, 2, HasModifiers, f32>.ret; 1502} 1503def VOP_F64_F64_F64_F64 : VOPProfile <[f64, f64, f64, f64]>; 1504def VOP_I32_I32_I32_I32 : VOPProfile <[i32, i32, i32, i32]>; 1505def VOP_I64_I32_I32_I64 : VOPProfile <[i64, i32, i32, i64]>; 1506 1507// This class is used only with VOPC instructions. Use $sdst for out operand 1508class SIInstAlias <string asm, Instruction inst, VOPProfile p> : 1509 InstAlias <asm, (inst)>, PredicateControl { 1510 1511 field bit isCompare; 1512 field bit isCommutable; 1513 1514 let ResultInst = 1515 !if (p.HasDst32, 1516 !if (!eq(p.NumSrcArgs, 0), 1517 // 1 dst, 0 src 1518 (inst p.DstRC:$sdst), 1519 !if (!eq(p.NumSrcArgs, 1), 1520 // 1 dst, 1 src 1521 (inst p.DstRC:$sdst, p.Src0RC32:$src0), 1522 !if (!eq(p.NumSrcArgs, 2), 1523 // 1 dst, 2 src 1524 (inst p.DstRC:$sdst, p.Src0RC32:$src0, p.Src1RC32:$src1), 1525 // else - unreachable 1526 (inst)))), 1527 // else 1528 !if (!eq(p.NumSrcArgs, 2), 1529 // 0 dst, 2 src 1530 (inst p.Src0RC32:$src0, p.Src1RC32:$src1), 1531 !if (!eq(p.NumSrcArgs, 1), 1532 // 0 dst, 1 src 1533 (inst p.Src0RC32:$src1), 1534 // else 1535 // 0 dst, 0 src 1536 (inst)))); 1537} 1538 1539class SIInstAliasSI <string asm, string op_name, VOPProfile p> : 1540 SIInstAlias <asm, !cast<Instruction>(op_name#"_e32_si"), p> { 1541 let AssemblerPredicate = SIAssemblerPredicate; 1542} 1543 1544class SIInstAliasVI <string asm, string op_name, VOPProfile p> : 1545 SIInstAlias <asm, !cast<Instruction>(op_name#"_e32_vi"), p> { 1546 let AssemblerPredicates = [isVI]; 1547} 1548 1549multiclass SIInstAliasBuilder <string asm, VOPProfile p> { 1550 1551 def : SIInstAliasSI <asm, NAME, p>; 1552 1553 def : SIInstAliasVI <asm, NAME, p>; 1554} 1555 1556class VOP <string opName> { 1557 string OpName = opName; 1558} 1559 1560class VOP2_REV <string revOp, bit isOrig> { 1561 string RevOp = revOp; 1562 bit IsOrig = isOrig; 1563} 1564 1565class AtomicNoRet <string noRetOp, bit isRet> { 1566 string NoRetOp = noRetOp; 1567 bit IsRet = isRet; 1568} 1569 1570class VOP1_Pseudo <dag outs, dag ins, list<dag> pattern, string opName> : 1571 VOP1Common <outs, ins, "", pattern>, 1572 VOP <opName>, 1573 SIMCInstr <opName#"_e32", SISubtarget.NONE>, 1574 MnemonicAlias<opName#"_e32", opName> { 1575 let isPseudo = 1; 1576 let isCodeGenOnly = 1; 1577 1578 field bits<8> vdst; 1579 field bits<9> src0; 1580} 1581 1582class VOP1_Real_si <string opName, vop1 op, dag outs, dag ins, string asm> : 1583 VOP1<op.SI, outs, ins, asm, []>, 1584 SIMCInstr <opName#"_e32", SISubtarget.SI> { 1585 let AssemblerPredicate = SIAssemblerPredicate; 1586 let DecoderNamespace = "SICI"; 1587 let DisableDecoder = DisableSIDecoder; 1588} 1589 1590class VOP1_Real_vi <string opName, vop1 op, dag outs, dag ins, string asm> : 1591 VOP1<op.VI, outs, ins, asm, []>, 1592 SIMCInstr <opName#"_e32", SISubtarget.VI> { 1593 let AssemblerPredicates = [isVI]; 1594 let DecoderNamespace = "VI"; 1595 let DisableDecoder = DisableVIDecoder; 1596} 1597 1598multiclass VOP1_m <vop1 op, string opName, VOPProfile p, list<dag> pattern, 1599 string asm = opName#p.Asm32> { 1600 def "" : VOP1_Pseudo <p.Outs, p.Ins32, pattern, opName>; 1601 1602 def _si : VOP1_Real_si <opName, op, p.Outs, p.Ins32, asm>; 1603 1604 def _vi : VOP1_Real_vi <opName, op, p.Outs, p.Ins32, asm>; 1605 1606} 1607 1608class VOP1_DPP <vop1 op, string opName, VOPProfile p> : 1609 VOP1_DPPe <op.VI>, 1610 VOP_DPP <p.OutsDPP, p.InsDPP, opName#p.AsmDPP, []> { 1611 let AssemblerPredicates = [isVI]; 1612 let src0_modifiers = !if(p.HasModifiers, ?, 0); 1613 let src1_modifiers = 0; 1614} 1615 1616multiclass VOP1SI_m <vop1 op, string opName, VOPProfile p, list<dag> pattern, 1617 string asm = opName#p.Asm32> { 1618 1619 def "" : VOP1_Pseudo <p.Outs, p.Ins32, pattern, opName>; 1620 1621 def _si : VOP1_Real_si <opName, op, p.Outs, p.Ins32, asm>; 1622} 1623 1624class VOP2_Pseudo <dag outs, dag ins, list<dag> pattern, string opName> : 1625 VOP2Common <outs, ins, "", pattern>, 1626 VOP <opName>, 1627 SIMCInstr<opName#"_e32", SISubtarget.NONE>, 1628 MnemonicAlias<opName#"_e32", opName> { 1629 let isPseudo = 1; 1630 let isCodeGenOnly = 1; 1631} 1632 1633class VOP2_Real_si <string opName, vop2 op, dag outs, dag ins, string asm> : 1634 VOP2 <op.SI, outs, ins, opName#asm, []>, 1635 SIMCInstr <opName#"_e32", SISubtarget.SI> { 1636 let AssemblerPredicates = [isSICI]; 1637 let DecoderNamespace = "SICI"; 1638 let DisableDecoder = DisableSIDecoder; 1639} 1640 1641class VOP2_Real_vi <string opName, vop2 op, dag outs, dag ins, string asm> : 1642 VOP2 <op.VI, outs, ins, opName#asm, []>, 1643 SIMCInstr <opName#"_e32", SISubtarget.VI> { 1644 let AssemblerPredicates = [isVI]; 1645 let DecoderNamespace = "VI"; 1646 let DisableDecoder = DisableVIDecoder; 1647} 1648 1649multiclass VOP2SI_m <vop2 op, string opName, VOPProfile p, list<dag> pattern, 1650 string revOp> { 1651 1652 def "" : VOP2_Pseudo <p.Outs32, p.Ins32, pattern, opName>, 1653 VOP2_REV<revOp#"_e32", !eq(revOp, opName)>; 1654 1655 def _si : VOP2_Real_si <opName, op, p.Outs32, p.Ins32, p.Asm32>; 1656} 1657 1658multiclass VOP2_m <vop2 op, string opName, VOPProfile p, list <dag> pattern, 1659 string revOp> { 1660 1661 def "" : VOP2_Pseudo <p.Outs32, p.Ins32, pattern, opName>, 1662 VOP2_REV<revOp#"_e32", !eq(revOp, opName)>; 1663 1664 def _si : VOP2_Real_si <opName, op, p.Outs32, p.Ins32, p.Asm32>; 1665 1666 def _vi : VOP2_Real_vi <opName, op, p.Outs32, p.Ins32, p.Asm32>; 1667 1668} 1669 1670class VOP3DisableFields <bit HasSrc1, bit HasSrc2, bit HasModifiers> { 1671 1672 bits<2> src0_modifiers = !if(HasModifiers, ?, 0); 1673 bits<2> src1_modifiers = !if(HasModifiers, !if(HasSrc1, ?, 0), 0); 1674 bits<2> src2_modifiers = !if(HasModifiers, !if(HasSrc2, ?, 0), 0); 1675 bits<2> omod = !if(HasModifiers, ?, 0); 1676 bits<1> clamp = !if(HasModifiers, ?, 0); 1677 bits<9> src1 = !if(HasSrc1, ?, 0); 1678 bits<9> src2 = !if(HasSrc2, ?, 0); 1679} 1680 1681class VOP3DisableModFields <bit HasSrc0Mods, 1682 bit HasSrc1Mods = 0, 1683 bit HasSrc2Mods = 0, 1684 bit HasOutputMods = 0> { 1685 bits<2> src0_modifiers = !if(HasSrc0Mods, ?, 0); 1686 bits<2> src1_modifiers = !if(HasSrc1Mods, ?, 0); 1687 bits<2> src2_modifiers = !if(HasSrc2Mods, ?, 0); 1688 bits<2> omod = !if(HasOutputMods, ?, 0); 1689 bits<1> clamp = !if(HasOutputMods, ?, 0); 1690} 1691 1692class VOP3_Pseudo <dag outs, dag ins, list<dag> pattern, string opName, 1693 bit HasMods = 0, bit VOP3Only = 0> : 1694 VOP3Common <outs, ins, "", pattern, HasMods, VOP3Only>, 1695 VOP <opName>, 1696 SIMCInstr<opName#"_e64", SISubtarget.NONE>, 1697 MnemonicAlias<opName#"_e64", opName> { 1698 let isPseudo = 1; 1699 let isCodeGenOnly = 1; 1700 1701 field bit vdst; 1702 field bit src0; 1703} 1704 1705class VOP3_Real_si <bits<9> op, dag outs, dag ins, string asm, string opName, 1706 bit HasMods = 0, bit VOP3Only = 0> : 1707 VOP3Common <outs, ins, asm, [], HasMods, VOP3Only>, 1708 VOP3e <op>, 1709 SIMCInstr<opName#"_e64", SISubtarget.SI> { 1710 let AssemblerPredicates = [isSICI]; 1711 let DecoderNamespace = "SICI"; 1712 let DisableDecoder = DisableSIDecoder; 1713} 1714 1715class VOP3_Real_vi <bits<10> op, dag outs, dag ins, string asm, string opName, 1716 bit HasMods = 0, bit VOP3Only = 0> : 1717 VOP3Common <outs, ins, asm, [], HasMods, VOP3Only>, 1718 VOP3e_vi <op>, 1719 SIMCInstr <opName#"_e64", SISubtarget.VI> { 1720 let AssemblerPredicates = [isVI]; 1721 let DecoderNamespace = "VI"; 1722 let DisableDecoder = DisableVIDecoder; 1723} 1724 1725class VOP3_C_Real_si <bits<9> op, dag outs, dag ins, string asm, string opName, 1726 bit HasMods = 0, bit VOP3Only = 0> : 1727 VOP3Common <outs, ins, asm, [], HasMods, VOP3Only>, 1728 VOP3ce <op>, 1729 SIMCInstr<opName#"_e64", SISubtarget.SI> { 1730 let AssemblerPredicates = [isSICI]; 1731 let DecoderNamespace = "SICI"; 1732 let DisableDecoder = DisableSIDecoder; 1733} 1734 1735class VOP3_C_Real_vi <bits<10> op, dag outs, dag ins, string asm, string opName, 1736 bit HasMods = 0, bit VOP3Only = 0> : 1737 VOP3Common <outs, ins, asm, [], HasMods, VOP3Only>, 1738 VOP3ce_vi <op>, 1739 SIMCInstr <opName#"_e64", SISubtarget.VI> { 1740 let AssemblerPredicates = [isVI]; 1741 let DecoderNamespace = "VI"; 1742 let DisableDecoder = DisableVIDecoder; 1743} 1744 1745class VOP3b_Real_si <bits<9> op, dag outs, dag ins, string asm, string opName, 1746 bit HasMods = 0, bit VOP3Only = 0> : 1747 VOP3Common <outs, ins, asm, [], HasMods, VOP3Only>, 1748 VOP3be <op>, 1749 SIMCInstr<opName#"_e64", SISubtarget.SI> { 1750 let AssemblerPredicates = [isSICI]; 1751 let DecoderNamespace = "SICI"; 1752 let DisableDecoder = DisableSIDecoder; 1753} 1754 1755class VOP3b_Real_vi <bits<10> op, dag outs, dag ins, string asm, string opName, 1756 bit HasMods = 0, bit VOP3Only = 0> : 1757 VOP3Common <outs, ins, asm, [], HasMods, VOP3Only>, 1758 VOP3be_vi <op>, 1759 SIMCInstr <opName#"_e64", SISubtarget.VI> { 1760 let AssemblerPredicates = [isVI]; 1761 let DecoderNamespace = "VI"; 1762 let DisableDecoder = DisableVIDecoder; 1763} 1764 1765multiclass VOP3_m <vop op, dag outs, dag ins, string asm, list<dag> pattern, 1766 string opName, int NumSrcArgs, bit HasMods = 1, bit VOP3Only = 0> { 1767 1768 def "" : VOP3_Pseudo <outs, ins, pattern, opName>; 1769 1770 def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName, HasMods, VOP3Only>, 1771 VOP3DisableFields<!if(!eq(NumSrcArgs, 1), 0, 1), 1772 !if(!eq(NumSrcArgs, 2), 0, 1), 1773 HasMods>; 1774 def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName, HasMods, VOP3Only>, 1775 VOP3DisableFields<!if(!eq(NumSrcArgs, 1), 0, 1), 1776 !if(!eq(NumSrcArgs, 2), 0, 1), 1777 HasMods>; 1778} 1779 1780multiclass VOP3_1_m <vop op, dag outs, dag ins, string asm, 1781 list<dag> pattern, string opName, bit HasMods = 1> { 1782 1783 def "" : VOP3_Pseudo <outs, ins, pattern, opName, HasMods>; 1784 1785 def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName, HasMods>, 1786 VOP3DisableFields<0, 0, HasMods>; 1787 1788 def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName, HasMods>, 1789 VOP3DisableFields<0, 0, HasMods>; 1790} 1791 1792multiclass VOP3SI_1_m <vop op, dag outs, dag ins, string asm, 1793 list<dag> pattern, string opName, bit HasMods = 1> { 1794 1795 def "" : VOP3_Pseudo <outs, ins, pattern, opName, HasMods>; 1796 1797 def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName, HasMods>, 1798 VOP3DisableFields<0, 0, HasMods>; 1799 // No VI instruction. This class is for SI only. 1800} 1801 1802multiclass VOP3_2_m <vop op, dag outs, dag ins, string asm, 1803 list<dag> pattern, string opName, string revOp, 1804 bit HasMods = 1> { 1805 1806 def "" : VOP3_Pseudo <outs, ins, pattern, opName, HasMods>, 1807 VOP2_REV<revOp#"_e64", !eq(revOp, opName)>; 1808 1809 def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName, HasMods>, 1810 VOP3DisableFields<1, 0, HasMods>; 1811 1812 def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName, HasMods>, 1813 VOP3DisableFields<1, 0, HasMods>; 1814} 1815 1816multiclass VOP3SI_2_m <vop op, dag outs, dag ins, string asm, 1817 list<dag> pattern, string opName, string revOp, 1818 bit HasMods = 1> { 1819 1820 def "" : VOP3_Pseudo <outs, ins, pattern, opName, HasMods>, 1821 VOP2_REV<revOp#"_e64", !eq(revOp, opName)>; 1822 1823 def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName, HasMods>, 1824 VOP3DisableFields<1, 0, HasMods>; 1825 1826 // No VI instruction. This class is for SI only. 1827} 1828 1829// Two operand VOP3b instruction that may have a 3rd SGPR bool operand 1830// instead of an implicit VCC as in the VOP2b format. 1831multiclass VOP3b_2_3_m <vop op, dag outs, dag ins, string asm, 1832 list<dag> pattern, string opName, string revOp, 1833 bit HasMods = 1, bit useSrc2Input = 0, bit VOP3Only = 0> { 1834 def "" : VOP3_Pseudo <outs, ins, pattern, opName, HasMods, VOP3Only>; 1835 1836 def _si : VOP3b_Real_si <op.SI3, outs, ins, asm, opName, HasMods, VOP3Only>, 1837 VOP3DisableFields<1, useSrc2Input, HasMods>; 1838 1839 def _vi : VOP3b_Real_vi <op.VI3, outs, ins, asm, opName, HasMods, VOP3Only>, 1840 VOP3DisableFields<1, useSrc2Input, HasMods>; 1841} 1842 1843multiclass VOP3_C_m <vop op, dag outs, dag ins, string asm, 1844 list<dag> pattern, string opName, 1845 bit HasMods, bit defExec, 1846 string revOp, list<SchedReadWrite> sched> { 1847 1848 def "" : VOP3_Pseudo <outs, ins, pattern, opName, HasMods>, 1849 VOP2_REV<revOp#"_e64", !eq(revOp, opName)> { 1850 let Defs = !if(defExec, [EXEC], []); 1851 let SchedRW = sched; 1852 } 1853 1854 def _si : VOP3_C_Real_si <op.SI3, outs, ins, asm, opName, HasMods>, 1855 VOP3DisableFields<1, 0, HasMods> { 1856 let Defs = !if(defExec, [EXEC], []); 1857 let SchedRW = sched; 1858 } 1859 1860 def _vi : VOP3_C_Real_vi <op.VI3, outs, ins, asm, opName, HasMods>, 1861 VOP3DisableFields<1, 0, HasMods> { 1862 let Defs = !if(defExec, [EXEC], []); 1863 let SchedRW = sched; 1864 } 1865} 1866 1867// An instruction that is VOP2 on SI and VOP3 on VI, no modifiers. 1868multiclass VOP2SI_3VI_m <vop3 op, string opName, dag outs, dag ins, 1869 string asm, list<dag> pattern = []> { 1870 let isPseudo = 1, isCodeGenOnly = 1 in { 1871 def "" : VOPAnyCommon <outs, ins, "", pattern>, 1872 SIMCInstr<opName, SISubtarget.NONE>; 1873 } 1874 1875 def _si : VOP2 <op.SI3{5-0}, outs, ins, asm, []>, 1876 SIMCInstr <opName, SISubtarget.SI> { 1877 let AssemblerPredicates = [isSICI]; 1878 let DecoderNamespace = "SICI"; 1879 let DisableDecoder = DisableSIDecoder; 1880 } 1881 1882 def _vi : VOP3Common <outs, ins, asm, []>, 1883 VOP3e_vi <op.VI3>, 1884 VOP3DisableFields <1, 0, 0>, 1885 SIMCInstr <opName, SISubtarget.VI> { 1886 let AssemblerPredicates = [isVI]; 1887 let DecoderNamespace = "VI"; 1888 let DisableDecoder = DisableVIDecoder; 1889 } 1890} 1891 1892multiclass VOP1_Helper <vop1 op, string opName, VOPProfile p, list<dag> pat32, 1893 list<dag> pat64> { 1894 1895 defm _e32 : VOP1_m <op, opName, p, pat32>; 1896 1897 defm _e64 : VOP3_1_m <op, p.Outs, p.Ins64, opName#p.Asm64, pat64, opName, 1898 p.HasModifiers>; 1899 1900 def _dpp : VOP1_DPP <op, opName, p>; 1901} 1902 1903multiclass VOP1Inst <vop1 op, string opName, VOPProfile P, 1904 SDPatternOperator node = null_frag> : VOP1_Helper < 1905 op, opName, P, [], 1906 !if(P.HasModifiers, 1907 [(set P.DstVT:$vdst, (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, 1908 i32:$src0_modifiers, i1:$clamp, i32:$omod))))], 1909 [(set P.DstVT:$vdst, (node P.Src0VT:$src0))]) 1910>; 1911 1912multiclass VOP1InstSI <vop1 op, string opName, VOPProfile P, 1913 SDPatternOperator node = null_frag> { 1914 1915 defm _e32 : VOP1SI_m <op, opName, P, []>; 1916 1917 defm _e64 : VOP3SI_1_m <op, P.Outs, P.Ins64, opName#P.Asm64, 1918 !if(P.HasModifiers, 1919 [(set P.DstVT:$vdst, (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, 1920 i32:$src0_modifiers, i1:$clamp, i32:$omod))))], 1921 [(set P.DstVT:$vdst, (node P.Src0VT:$src0))]), 1922 opName, P.HasModifiers>; 1923} 1924 1925multiclass VOP2_Helper <vop2 op, string opName, VOPProfile p, list<dag> pat32, 1926 list<dag> pat64, string revOp> { 1927 1928 defm _e32 : VOP2_m <op, opName, p, pat32, revOp>; 1929 1930 defm _e64 : VOP3_2_m <op, p.Outs, p.Ins64, opName#p.Asm64, pat64, opName, 1931 revOp, p.HasModifiers>; 1932} 1933 1934multiclass VOP2Inst <vop2 op, string opName, VOPProfile P, 1935 SDPatternOperator node = null_frag, 1936 string revOp = opName> : VOP2_Helper < 1937 op, opName, P, [], 1938 !if(P.HasModifiers, 1939 [(set P.DstVT:$vdst, 1940 (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, 1941 i1:$clamp, i32:$omod)), 1942 (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))], 1943 [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1))]), 1944 revOp 1945>; 1946 1947multiclass VOP2InstSI <vop2 op, string opName, VOPProfile P, 1948 SDPatternOperator node = null_frag, 1949 string revOp = opName> { 1950 1951 defm _e32 : VOP2SI_m <op, opName, P, [], revOp>; 1952 1953 defm _e64 : VOP3SI_2_m <op, P.Outs, P.Ins64, opName#P.Asm64, 1954 !if(P.HasModifiers, 1955 [(set P.DstVT:$vdst, 1956 (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, 1957 i1:$clamp, i32:$omod)), 1958 (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))], 1959 [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1))]), 1960 opName, revOp, P.HasModifiers>; 1961} 1962 1963multiclass VOP2b_Helper <vop2 op, string opName, VOPProfile p, 1964 list<dag> pat32, list<dag> pat64, 1965 string revOp, bit useSGPRInput> { 1966 1967 let SchedRW = [Write32Bit, WriteSALU] in { 1968 let Uses = !if(useSGPRInput, [VCC, EXEC], [EXEC]), Defs = [VCC] in { 1969 defm _e32 : VOP2_m <op, opName, p, pat32, revOp>; 1970 } 1971 1972 defm _e64 : VOP3b_2_3_m <op, p.Outs64, p.Ins64, opName#p.Asm64, pat64, 1973 opName, revOp, p.HasModifiers, useSGPRInput>; 1974 } 1975} 1976 1977multiclass VOP2bInst <vop2 op, string opName, VOPProfile P, 1978 SDPatternOperator node = null_frag, 1979 string revOp = opName> : VOP2b_Helper < 1980 op, opName, P, [], 1981 !if(P.HasModifiers, 1982 [(set P.DstVT:$vdst, 1983 (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, 1984 i1:$clamp, i32:$omod)), 1985 (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))], 1986 [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1))]), 1987 revOp, !eq(P.NumSrcArgs, 3) 1988>; 1989 1990// A VOP2 instruction that is VOP3-only on VI. 1991multiclass VOP2_VI3_Helper <vop23 op, string opName, VOPProfile p, 1992 list<dag> pat32, list<dag> pat64, string revOp> { 1993 1994 defm _e32 : VOP2SI_m <op, opName, p, pat32, revOp>; 1995 1996 defm _e64 : VOP3_2_m <op, p.Outs, p.Ins64, opName#p.Asm64, pat64, opName, 1997 revOp, p.HasModifiers>; 1998} 1999 2000multiclass VOP2_VI3_Inst <vop23 op, string opName, VOPProfile P, 2001 SDPatternOperator node = null_frag, 2002 string revOp = opName> 2003 : VOP2_VI3_Helper < 2004 op, opName, P, [], 2005 !if(P.HasModifiers, 2006 [(set P.DstVT:$vdst, 2007 (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, 2008 i1:$clamp, i32:$omod)), 2009 (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))], 2010 [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1))]), 2011 revOp 2012>; 2013 2014multiclass VOP2MADK <vop2 op, string opName, list<dag> pattern = []> { 2015 2016 def "" : VOP2_Pseudo <VOP_MADK.Outs, VOP_MADK.Ins, pattern, opName>; 2017 2018let isCodeGenOnly = 0 in { 2019 def _si : VOP2Common <VOP_MADK.Outs, VOP_MADK.Ins, 2020 !strconcat(opName, VOP_MADK.Asm), []>, 2021 SIMCInstr <opName#"_e32", SISubtarget.SI>, 2022 VOP2_MADKe <op.SI> { 2023 let AssemblerPredicates = [isSICI]; 2024 let DecoderNamespace = "SICI"; 2025 let DisableDecoder = DisableSIDecoder; 2026 } 2027 2028 def _vi : VOP2Common <VOP_MADK.Outs, VOP_MADK.Ins, 2029 !strconcat(opName, VOP_MADK.Asm), []>, 2030 SIMCInstr <opName#"_e32", SISubtarget.VI>, 2031 VOP2_MADKe <op.VI> { 2032 let AssemblerPredicates = [isVI]; 2033 let DecoderNamespace = "VI"; 2034 let DisableDecoder = DisableVIDecoder; 2035 } 2036} // End isCodeGenOnly = 0 2037} 2038 2039class VOPC_Pseudo <dag ins, list<dag> pattern, string opName> : 2040 VOPCCommon <ins, "", pattern>, 2041 VOP <opName>, 2042 SIMCInstr<opName#"_e32", SISubtarget.NONE> { 2043 let isPseudo = 1; 2044 let isCodeGenOnly = 1; 2045} 2046 2047multiclass VOPC_m <vopc op, dag ins, string op_asm, list<dag> pattern, 2048 string opName, bit DefExec, VOPProfile p, 2049 list<SchedReadWrite> sched, 2050 string revOpName = "", string asm = opName#"_e32 "#op_asm, 2051 string alias_asm = opName#" "#op_asm> { 2052 def "" : VOPC_Pseudo <ins, pattern, opName>, 2053 VOP2_REV<revOpName#"_e32", !eq(revOpName, opName)> { 2054 let Defs = !if(DefExec, [VCC, EXEC], [VCC]); 2055 let SchedRW = sched; 2056 } 2057 2058 let AssemblerPredicates = [isSICI] in { 2059 def _si : VOPC<op.SI, ins, asm, []>, 2060 SIMCInstr <opName#"_e32", SISubtarget.SI> { 2061 let Defs = !if(DefExec, [VCC, EXEC], [VCC]); 2062 let hasSideEffects = DefExec; 2063 let SchedRW = sched; 2064 let DecoderNamespace = "SICI"; 2065 let DisableDecoder = DisableSIDecoder; 2066 } 2067 2068 } // End AssemblerPredicates = [isSICI] 2069 2070 let AssemblerPredicates = [isVI] in { 2071 def _vi : VOPC<op.VI, ins, asm, []>, 2072 SIMCInstr <opName#"_e32", SISubtarget.VI> { 2073 let Defs = !if(DefExec, [VCC, EXEC], [VCC]); 2074 let hasSideEffects = DefExec; 2075 let SchedRW = sched; 2076 let DecoderNamespace = "VI"; 2077 let DisableDecoder = DisableVIDecoder; 2078 } 2079 2080 } // End AssemblerPredicates = [isVI] 2081 2082 defm : SIInstAliasBuilder<alias_asm, p>; 2083} 2084 2085multiclass VOPC_Helper <vopc op, string opName, list<dag> pat32, 2086 list<dag> pat64, bit DefExec, string revOp, 2087 VOPProfile p, list<SchedReadWrite> sched> { 2088 defm _e32 : VOPC_m <op, p.Ins32, p.Asm32, pat32, opName, DefExec, p, sched, 2089 revOp>; 2090 2091 defm _e64 : VOP3_C_m <op, (outs VOPDstS64:$sdst), p.Ins64, opName#p.Asm64, pat64, 2092 opName, p.HasModifiers, DefExec, revOp, sched>; 2093} 2094 2095// Special case for class instructions which only have modifiers on 2096// the 1st source operand. 2097multiclass VOPC_Class_Helper <vopc op, string opName, list<dag> pat32, 2098 list<dag> pat64, bit DefExec, string revOp, 2099 VOPProfile p, list<SchedReadWrite> sched> { 2100 defm _e32 : VOPC_m <op, p.Ins32, p.Asm32, pat32, opName, DefExec, p, sched>; 2101 2102 defm _e64 : VOP3_C_m <op, (outs VOPDstS64:$sdst), p.Ins64, opName#p.Asm64, pat64, 2103 opName, p.HasModifiers, DefExec, revOp, sched>, 2104 VOP3DisableModFields<1, 0, 0>; 2105} 2106 2107multiclass VOPCInst <vopc op, string opName, 2108 VOPProfile P, PatLeaf cond = COND_NULL, 2109 string revOp = opName, 2110 bit DefExec = 0, 2111 list<SchedReadWrite> sched = [Write32Bit]> : 2112 VOPC_Helper < 2113 op, opName, [], 2114 !if(P.HasModifiers, 2115 [(set i1:$sdst, 2116 (setcc (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, 2117 i1:$clamp, i32:$omod)), 2118 (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)), 2119 cond))], 2120 [(set i1:$sdst, (setcc P.Src0VT:$src0, P.Src1VT:$src1, cond))]), 2121 DefExec, revOp, P, sched 2122>; 2123 2124multiclass VOPCClassInst <vopc op, string opName, VOPProfile P, 2125 bit DefExec = 0, 2126 list<SchedReadWrite> sched> : VOPC_Class_Helper < 2127 op, opName, [], 2128 !if(P.HasModifiers, 2129 [(set i1:$sdst, 2130 (AMDGPUfp_class (P.Src0VT (VOP3Mods0Clamp0OMod P.Src0VT:$src0, i32:$src0_modifiers)), P.Src1VT:$src1))], 2131 [(set i1:$sdst, (AMDGPUfp_class P.Src0VT:$src0, P.Src1VT:$src1))]), 2132 DefExec, opName, P, sched 2133>; 2134 2135 2136multiclass VOPC_F32 <vopc op, string opName, PatLeaf cond = COND_NULL, string revOp = opName> : 2137 VOPCInst <op, opName, VOPC_I1_F32_F32, cond, revOp>; 2138 2139multiclass VOPC_F64 <vopc op, string opName, PatLeaf cond = COND_NULL, string revOp = opName> : 2140 VOPCInst <op, opName, VOPC_I1_F64_F64, cond, revOp, 0, [WriteDoubleAdd]>; 2141 2142multiclass VOPC_I32 <vopc op, string opName, PatLeaf cond = COND_NULL, string revOp = opName> : 2143 VOPCInst <op, opName, VOPC_I1_I32_I32, cond, revOp>; 2144 2145multiclass VOPC_I64 <vopc op, string opName, PatLeaf cond = COND_NULL, string revOp = opName> : 2146 VOPCInst <op, opName, VOPC_I1_I64_I64, cond, revOp, 0, [Write64Bit]>; 2147 2148 2149multiclass VOPCX <vopc op, string opName, VOPProfile P, 2150 PatLeaf cond = COND_NULL, 2151 list<SchedReadWrite> sched, 2152 string revOp = ""> 2153 : VOPCInst <op, opName, P, cond, revOp, 1, sched>; 2154 2155multiclass VOPCX_F32 <vopc op, string opName, string revOp = opName> : 2156 VOPCX <op, opName, VOPC_I1_F32_F32, COND_NULL, [Write32Bit], revOp>; 2157 2158multiclass VOPCX_F64 <vopc op, string opName, string revOp = opName> : 2159 VOPCX <op, opName, VOPC_I1_F64_F64, COND_NULL, [WriteDoubleAdd], revOp>; 2160 2161multiclass VOPCX_I32 <vopc op, string opName, string revOp = opName> : 2162 VOPCX <op, opName, VOPC_I1_I32_I32, COND_NULL, [Write32Bit], revOp>; 2163 2164multiclass VOPCX_I64 <vopc op, string opName, string revOp = opName> : 2165 VOPCX <op, opName, VOPC_I1_I64_I64, COND_NULL, [Write64Bit], revOp>; 2166 2167multiclass VOP3_Helper <vop3 op, string opName, dag outs, dag ins, string asm, 2168 list<dag> pat, int NumSrcArgs, bit HasMods, 2169 bit VOP3Only = 0> : VOP3_m < 2170 op, outs, ins, opName#" "#asm, pat, opName, NumSrcArgs, HasMods, VOP3Only 2171>; 2172 2173multiclass VOPC_CLASS_F32 <vopc op, string opName> : 2174 VOPCClassInst <op, opName, VOPC_I1_F32_I32, 0, [Write32Bit]>; 2175 2176multiclass VOPCX_CLASS_F32 <vopc op, string opName> : 2177 VOPCClassInst <op, opName, VOPC_I1_F32_I32, 1, [Write32Bit]>; 2178 2179multiclass VOPC_CLASS_F64 <vopc op, string opName> : 2180 VOPCClassInst <op, opName, VOPC_I1_F64_I32, 0, [WriteDoubleAdd]>; 2181 2182multiclass VOPCX_CLASS_F64 <vopc op, string opName> : 2183 VOPCClassInst <op, opName, VOPC_I1_F64_I32, 1, [WriteDoubleAdd]>; 2184 2185multiclass VOP3Inst <vop3 op, string opName, VOPProfile P, 2186 SDPatternOperator node = null_frag, bit VOP3Only = 0> : 2187 VOP3_Helper < 2188 op, opName, (outs P.DstRC.RegClass:$vdst), P.Ins64, P.Asm64, 2189 !if(!eq(P.NumSrcArgs, 3), 2190 !if(P.HasModifiers, 2191 [(set P.DstVT:$vdst, 2192 (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, 2193 i1:$clamp, i32:$omod)), 2194 (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)), 2195 (P.Src2VT (VOP3Mods P.Src2VT:$src2, i32:$src2_modifiers))))], 2196 [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1, 2197 P.Src2VT:$src2))]), 2198 !if(!eq(P.NumSrcArgs, 2), 2199 !if(P.HasModifiers, 2200 [(set P.DstVT:$vdst, 2201 (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, 2202 i1:$clamp, i32:$omod)), 2203 (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))], 2204 [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1))]) 2205 /* P.NumSrcArgs == 1 */, 2206 !if(P.HasModifiers, 2207 [(set P.DstVT:$vdst, 2208 (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, 2209 i1:$clamp, i32:$omod))))], 2210 [(set P.DstVT:$vdst, (node P.Src0VT:$src0))]))), 2211 P.NumSrcArgs, P.HasModifiers, VOP3Only 2212>; 2213 2214// Special case for v_div_fmas_{f32|f64}, since it seems to be the 2215// only VOP instruction that implicitly reads VCC. 2216multiclass VOP3_VCC_Inst <vop3 op, string opName, 2217 VOPProfile P, 2218 SDPatternOperator node = null_frag> : VOP3_Helper < 2219 op, opName, 2220 (outs P.DstRC.RegClass:$vdst), 2221 (ins InputModsNoDefault:$src0_modifiers, P.Src0RC64:$src0, 2222 InputModsNoDefault:$src1_modifiers, P.Src1RC64:$src1, 2223 InputModsNoDefault:$src2_modifiers, P.Src2RC64:$src2, 2224 ClampMod:$clamp, 2225 omod:$omod), 2226 "$vdst, $src0_modifiers, $src1_modifiers, $src2_modifiers"#"$clamp"#"$omod", 2227 [(set P.DstVT:$vdst, 2228 (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, 2229 i1:$clamp, i32:$omod)), 2230 (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)), 2231 (P.Src2VT (VOP3Mods P.Src2VT:$src2, i32:$src2_modifiers)), 2232 (i1 VCC)))], 2233 3, 1 2234>; 2235 2236multiclass VOP3bInst <vop op, string opName, VOPProfile P, list<dag> pattern = [], bit VOP3Only = 0> : 2237 VOP3b_2_3_m < 2238 op, P.Outs64, P.Ins64, 2239 opName#" "#P.Asm64, pattern, 2240 opName, "", 1, 1, VOP3Only 2241>; 2242 2243class Vop3ModPat<Instruction Inst, VOPProfile P, SDPatternOperator node> : Pat< 2244 (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i1:$clamp, i32:$omod)), 2245 (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)), 2246 (P.Src2VT (VOP3Mods P.Src2VT:$src2, i32:$src2_modifiers))), 2247 (Inst i32:$src0_modifiers, P.Src0VT:$src0, 2248 i32:$src1_modifiers, P.Src1VT:$src1, 2249 i32:$src2_modifiers, P.Src2VT:$src2, 2250 i1:$clamp, 2251 i32:$omod)>; 2252 2253//===----------------------------------------------------------------------===// 2254// Interpolation opcodes 2255//===----------------------------------------------------------------------===// 2256 2257class VINTRP_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> : 2258 VINTRPCommon <outs, ins, "", pattern>, 2259 SIMCInstr<opName, SISubtarget.NONE> { 2260 let isPseudo = 1; 2261 let isCodeGenOnly = 1; 2262} 2263 2264class VINTRP_Real_si <bits <2> op, string opName, dag outs, dag ins, 2265 string asm> : 2266 VINTRPCommon <outs, ins, asm, []>, 2267 VINTRPe <op>, 2268 SIMCInstr<opName, SISubtarget.SI> { 2269 let DecoderNamespace = "SICI"; 2270 let DisableDecoder = DisableSIDecoder; 2271} 2272 2273class VINTRP_Real_vi <bits <2> op, string opName, dag outs, dag ins, 2274 string asm> : 2275 VINTRPCommon <outs, ins, asm, []>, 2276 VINTRPe_vi <op>, 2277 SIMCInstr<opName, SISubtarget.VI> { 2278 let DecoderNamespace = "VI"; 2279 let DisableDecoder = DisableVIDecoder; 2280} 2281 2282multiclass VINTRP_m <bits <2> op, dag outs, dag ins, string asm, 2283 list<dag> pattern = []> { 2284 def "" : VINTRP_Pseudo <NAME, outs, ins, pattern>; 2285 2286 def _si : VINTRP_Real_si <op, NAME, outs, ins, asm>; 2287 2288 def _vi : VINTRP_Real_vi <op, NAME, outs, ins, asm>; 2289} 2290 2291//===----------------------------------------------------------------------===// 2292// Vector I/O classes 2293//===----------------------------------------------------------------------===// 2294 2295class DS_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> : 2296 DS <outs, ins, "", pattern>, 2297 SIMCInstr <opName, SISubtarget.NONE> { 2298 let isPseudo = 1; 2299 let isCodeGenOnly = 1; 2300} 2301 2302class DS_Real_si <bits<8> op, string opName, dag outs, dag ins, string asm> : 2303 DS <outs, ins, asm, []>, 2304 DSe <op>, 2305 SIMCInstr <opName, SISubtarget.SI> { 2306 let isCodeGenOnly = 0; 2307 let AssemblerPredicates = [isSICI]; 2308 let DecoderNamespace="SICI"; 2309 let DisableDecoder = DisableSIDecoder; 2310} 2311 2312class DS_Real_vi <bits<8> op, string opName, dag outs, dag ins, string asm> : 2313 DS <outs, ins, asm, []>, 2314 DSe_vi <op>, 2315 SIMCInstr <opName, SISubtarget.VI> { 2316 let isCodeGenOnly = 0; 2317 let AssemblerPredicates = [isVI]; 2318 let DecoderNamespace="VI"; 2319 let DisableDecoder = DisableVIDecoder; 2320} 2321 2322class DS_Off16_Real_si <bits<8> op, string opName, dag outs, dag ins, string asm> : 2323 DS_Real_si <op,opName, outs, ins, asm> { 2324 2325 // Single load interpret the 2 i8imm operands as a single i16 offset. 2326 bits<16> offset; 2327 let offset0 = offset{7-0}; 2328 let offset1 = offset{15-8}; 2329} 2330 2331class DS_Off16_Real_vi <bits<8> op, string opName, dag outs, dag ins, string asm> : 2332 DS_Real_vi <op, opName, outs, ins, asm> { 2333 2334 // Single load interpret the 2 i8imm operands as a single i16 offset. 2335 bits<16> offset; 2336 let offset0 = offset{7-0}; 2337 let offset1 = offset{15-8}; 2338} 2339 2340multiclass DS_1A_RET <bits<8> op, string opName, RegisterClass rc, 2341 dag outs = (outs rc:$vdst), 2342 dag ins = (ins VGPR_32:$addr, ds_offset:$offset, gds:$gds), 2343 string asm = opName#" $vdst, $addr"#"$offset$gds"> { 2344 2345 def "" : DS_Pseudo <opName, outs, ins, []>; 2346 2347 let data0 = 0, data1 = 0 in { 2348 def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>; 2349 def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>; 2350 } 2351} 2352 2353multiclass DS_1A_Off8_RET <bits<8> op, string opName, RegisterClass rc, 2354 dag outs = (outs rc:$vdst), 2355 dag ins = (ins VGPR_32:$addr, ds_offset0:$offset0, ds_offset1:$offset1, 2356 gds01:$gds), 2357 string asm = opName#" $vdst, $addr"#"$offset0"#"$offset1$gds"> { 2358 2359 def "" : DS_Pseudo <opName, outs, ins, []>; 2360 2361 let data0 = 0, data1 = 0, AsmMatchConverter = "cvtDSOffset01" in { 2362 def _si : DS_Real_si <op, opName, outs, ins, asm>; 2363 def _vi : DS_Real_vi <op, opName, outs, ins, asm>; 2364 } 2365} 2366 2367multiclass DS_1A1D_NORET <bits<8> op, string opName, RegisterClass rc, 2368 dag outs = (outs), 2369 dag ins = (ins VGPR_32:$addr, rc:$data0, ds_offset:$offset, gds:$gds), 2370 string asm = opName#" $addr, $data0"#"$offset$gds"> { 2371 2372 def "" : DS_Pseudo <opName, outs, ins, []>, 2373 AtomicNoRet<opName, 0>; 2374 2375 let data1 = 0, vdst = 0 in { 2376 def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>; 2377 def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>; 2378 } 2379} 2380 2381multiclass DS_1A1D_Off8_NORET <bits<8> op, string opName, RegisterClass rc, 2382 dag outs = (outs), 2383 dag ins = (ins VGPR_32:$addr, rc:$data0, rc:$data1, 2384 ds_offset0:$offset0, ds_offset1:$offset1, gds01:$gds), 2385 string asm = opName#" $addr, $data0, $data1"#"$offset0"#"$offset1"#"$gds"> { 2386 2387 def "" : DS_Pseudo <opName, outs, ins, []>; 2388 2389 let vdst = 0, AsmMatchConverter = "cvtDSOffset01" in { 2390 def _si : DS_Real_si <op, opName, outs, ins, asm>; 2391 def _vi : DS_Real_vi <op, opName, outs, ins, asm>; 2392 } 2393} 2394 2395multiclass DS_1A1D_RET <bits<8> op, string opName, RegisterClass rc, 2396 string noRetOp = "", 2397 dag outs = (outs rc:$vdst), 2398 dag ins = (ins VGPR_32:$addr, rc:$data0, ds_offset:$offset, gds:$gds), 2399 string asm = opName#" $vdst, $addr, $data0"#"$offset$gds"> { 2400 2401 let hasPostISelHook = 1 in { 2402 def "" : DS_Pseudo <opName, outs, ins, []>, 2403 AtomicNoRet<noRetOp, 1>; 2404 2405 let data1 = 0 in { 2406 def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>; 2407 def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>; 2408 } 2409 } 2410} 2411 2412multiclass DS_1A2D_RET_m <bits<8> op, string opName, RegisterClass rc, 2413 string noRetOp = "", dag ins, 2414 dag outs = (outs rc:$vdst), 2415 string asm = opName#" $vdst, $addr, $data0, $data1"#"$offset"#"$gds"> { 2416 2417 let hasPostISelHook = 1 in { 2418 def "" : DS_Pseudo <opName, outs, ins, []>, 2419 AtomicNoRet<noRetOp, 1>; 2420 2421 def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>; 2422 def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>; 2423 } 2424} 2425 2426multiclass DS_1A2D_RET <bits<8> op, string asm, RegisterClass rc, 2427 string noRetOp = "", RegisterClass src = rc> : 2428 DS_1A2D_RET_m <op, asm, rc, noRetOp, 2429 (ins VGPR_32:$addr, src:$data0, src:$data1, 2430 ds_offset:$offset, gds:$gds) 2431>; 2432 2433multiclass DS_1A2D_NORET <bits<8> op, string opName, RegisterClass rc, 2434 string noRetOp = opName, 2435 dag outs = (outs), 2436 dag ins = (ins VGPR_32:$addr, rc:$data0, rc:$data1, 2437 ds_offset:$offset, gds:$gds), 2438 string asm = opName#" $addr, $data0, $data1"#"$offset"#"$gds"> { 2439 2440 def "" : DS_Pseudo <opName, outs, ins, []>, 2441 AtomicNoRet<noRetOp, 0>; 2442 2443 let vdst = 0 in { 2444 def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>; 2445 def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>; 2446 } 2447} 2448 2449multiclass DS_0A_RET <bits<8> op, string opName, 2450 dag outs = (outs VGPR_32:$vdst), 2451 dag ins = (ins ds_offset:$offset, gds:$gds), 2452 string asm = opName#" $vdst"#"$offset"#"$gds"> { 2453 2454 let mayLoad = 1, mayStore = 1 in { 2455 def "" : DS_Pseudo <opName, outs, ins, []>; 2456 2457 let addr = 0, data0 = 0, data1 = 0 in { 2458 def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>; 2459 def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>; 2460 } // end addr = 0, data0 = 0, data1 = 0 2461 } // end mayLoad = 1, mayStore = 1 2462} 2463 2464multiclass DS_1A_RET_GDS <bits<8> op, string opName, 2465 dag outs = (outs VGPR_32:$vdst), 2466 dag ins = (ins VGPR_32:$addr, ds_offset_gds:$offset), 2467 string asm = opName#" $vdst, $addr"#"$offset gds"> { 2468 2469 def "" : DS_Pseudo <opName, outs, ins, []>; 2470 2471 let data0 = 0, data1 = 0, gds = 1 in { 2472 def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>; 2473 def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>; 2474 } // end data0 = 0, data1 = 0, gds = 1 2475} 2476 2477multiclass DS_1A_GDS <bits<8> op, string opName, 2478 dag outs = (outs), 2479 dag ins = (ins VGPR_32:$addr), 2480 string asm = opName#" $addr gds"> { 2481 2482 def "" : DS_Pseudo <opName, outs, ins, []>; 2483 2484 let vdst = 0, data0 = 0, data1 = 0, offset0 = 0, offset1 = 0, gds = 1 in { 2485 def _si : DS_Real_si <op, opName, outs, ins, asm>; 2486 def _vi : DS_Real_vi <op, opName, outs, ins, asm>; 2487 } // end vdst = 0, data = 0, data1 = 0, gds = 1 2488} 2489 2490multiclass DS_1A <bits<8> op, string opName, 2491 dag outs = (outs), 2492 dag ins = (ins VGPR_32:$addr, ds_offset:$offset, gds:$gds), 2493 string asm = opName#" $addr"#"$offset"#"$gds"> { 2494 2495 let mayLoad = 1, mayStore = 1 in { 2496 def "" : DS_Pseudo <opName, outs, ins, []>; 2497 2498 let vdst = 0, data0 = 0, data1 = 0 in { 2499 def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>; 2500 def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>; 2501 } // let vdst = 0, data0 = 0, data1 = 0 2502 } // end mayLoad = 1, mayStore = 1 2503} 2504 2505//===----------------------------------------------------------------------===// 2506// MTBUF classes 2507//===----------------------------------------------------------------------===// 2508 2509class MTBUF_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> : 2510 MTBUF <outs, ins, "", pattern>, 2511 SIMCInstr<opName, SISubtarget.NONE> { 2512 let isPseudo = 1; 2513 let isCodeGenOnly = 1; 2514} 2515 2516class MTBUF_Real_si <bits<3> op, string opName, dag outs, dag ins, 2517 string asm> : 2518 MTBUF <outs, ins, asm, []>, 2519 MTBUFe <op>, 2520 SIMCInstr<opName, SISubtarget.SI> { 2521 let DecoderNamespace="SICI"; 2522 let DisableDecoder = DisableSIDecoder; 2523} 2524 2525class MTBUF_Real_vi <bits<4> op, string opName, dag outs, dag ins, string asm> : 2526 MTBUF <outs, ins, asm, []>, 2527 MTBUFe_vi <op>, 2528 SIMCInstr <opName, SISubtarget.VI> { 2529 let DecoderNamespace="VI"; 2530 let DisableDecoder = DisableVIDecoder; 2531} 2532 2533multiclass MTBUF_m <bits<3> op, string opName, dag outs, dag ins, string asm, 2534 list<dag> pattern> { 2535 2536 def "" : MTBUF_Pseudo <opName, outs, ins, pattern>; 2537 2538 def _si : MTBUF_Real_si <op, opName, outs, ins, asm>; 2539 2540 def _vi : MTBUF_Real_vi <{0, op{2}, op{1}, op{0}}, opName, outs, ins, asm>; 2541 2542} 2543 2544let mayStore = 1, mayLoad = 0 in { 2545 2546multiclass MTBUF_Store_Helper <bits<3> op, string opName, 2547 RegisterClass regClass> : MTBUF_m < 2548 op, opName, (outs), 2549 (ins regClass:$vdata, u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, 2550 i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VGPR_32:$vaddr, 2551 SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SCSrc_32:$soffset), 2552 opName#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt," 2553 #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset", [] 2554>; 2555 2556} // mayStore = 1, mayLoad = 0 2557 2558let mayLoad = 1, mayStore = 0 in { 2559 2560multiclass MTBUF_Load_Helper <bits<3> op, string opName, 2561 RegisterClass regClass> : MTBUF_m < 2562 op, opName, (outs regClass:$dst), 2563 (ins u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64, 2564 i8imm:$dfmt, i8imm:$nfmt, VGPR_32:$vaddr, SReg_128:$srsrc, 2565 i1imm:$slc, i1imm:$tfe, SCSrc_32:$soffset), 2566 opName#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt," 2567 #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset", [] 2568>; 2569 2570} // mayLoad = 1, mayStore = 0 2571 2572//===----------------------------------------------------------------------===// 2573// MUBUF classes 2574//===----------------------------------------------------------------------===// 2575 2576class mubuf <bits<7> si, bits<7> vi = si> { 2577 field bits<7> SI = si; 2578 field bits<7> VI = vi; 2579} 2580 2581let isCodeGenOnly = 0 in { 2582 2583class MUBUF_si <bits<7> op, dag outs, dag ins, string asm, list<dag> pattern> : 2584 MUBUF <outs, ins, asm, pattern>, MUBUFe <op> { 2585 let lds = 0; 2586} 2587 2588} // End let isCodeGenOnly = 0 2589 2590class MUBUF_vi <bits<7> op, dag outs, dag ins, string asm, list<dag> pattern> : 2591 MUBUF <outs, ins, asm, pattern>, MUBUFe_vi <op> { 2592 let lds = 0; 2593} 2594 2595class MUBUFAddr64Table <bit is_addr64, string suffix = ""> { 2596 bit IsAddr64 = is_addr64; 2597 string OpName = NAME # suffix; 2598} 2599 2600class MUBUF_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> : 2601 MUBUF <outs, ins, "", pattern>, 2602 SIMCInstr<opName, SISubtarget.NONE> { 2603 let isPseudo = 1; 2604 let isCodeGenOnly = 1; 2605 2606 // dummy fields, so that we can use let statements around multiclasses 2607 bits<1> offen; 2608 bits<1> idxen; 2609 bits<8> vaddr; 2610 bits<1> glc; 2611 bits<1> slc; 2612 bits<1> tfe; 2613 bits<8> soffset; 2614} 2615 2616class MUBUF_Real_si <mubuf op, string opName, dag outs, dag ins, 2617 string asm> : 2618 MUBUF <outs, ins, asm, []>, 2619 MUBUFe <op.SI>, 2620 SIMCInstr<opName, SISubtarget.SI> { 2621 let lds = 0; 2622 let DecoderNamespace="SICI"; 2623 let DisableDecoder = DisableSIDecoder; 2624} 2625 2626class MUBUF_Real_vi <mubuf op, string opName, dag outs, dag ins, 2627 string asm> : 2628 MUBUF <outs, ins, asm, []>, 2629 MUBUFe_vi <op.VI>, 2630 SIMCInstr<opName, SISubtarget.VI> { 2631 let lds = 0; 2632 let DecoderNamespace="VI"; 2633 let DisableDecoder = DisableVIDecoder; 2634} 2635 2636multiclass MUBUF_m <mubuf op, string opName, dag outs, dag ins, string asm, 2637 list<dag> pattern> { 2638 2639 def "" : MUBUF_Pseudo <opName, outs, ins, pattern>, 2640 MUBUFAddr64Table <0>; 2641 2642 let addr64 = 0, isCodeGenOnly = 0 in { 2643 def _si : MUBUF_Real_si <op, opName, outs, ins, asm>; 2644 } 2645 2646 def _vi : MUBUF_Real_vi <op, opName, outs, ins, asm>; 2647} 2648 2649multiclass MUBUFAddr64_m <mubuf op, string opName, dag outs, 2650 dag ins, string asm, list<dag> pattern> { 2651 2652 def "" : MUBUF_Pseudo <opName, outs, ins, pattern>, 2653 MUBUFAddr64Table <1>; 2654 2655 let addr64 = 1, isCodeGenOnly = 0 in { 2656 def _si : MUBUF_Real_si <op, opName, outs, ins, asm>; 2657 } 2658 2659 // There is no VI version. If the pseudo is selected, it should be lowered 2660 // for VI appropriately. 2661} 2662 2663multiclass MUBUFAtomicOffset_m <mubuf op, string opName, dag outs, dag ins, 2664 string asm, list<dag> pattern, bit is_return> { 2665 2666 def "" : MUBUF_Pseudo <opName, outs, ins, pattern>, 2667 MUBUFAddr64Table <0, !if(is_return, "_RTN", "")>, 2668 AtomicNoRet<NAME#"_OFFSET", is_return>; 2669 2670 let offen = 0, idxen = 0, tfe = 0, vaddr = 0 in { 2671 let addr64 = 0 in { 2672 def _si : MUBUF_Real_si <op, opName, outs, ins, asm>; 2673 } 2674 2675 def _vi : MUBUF_Real_vi <op, opName, outs, ins, asm>; 2676 } 2677} 2678 2679multiclass MUBUFAtomicAddr64_m <mubuf op, string opName, dag outs, dag ins, 2680 string asm, list<dag> pattern, bit is_return> { 2681 2682 def "" : MUBUF_Pseudo <opName, outs, ins, pattern>, 2683 MUBUFAddr64Table <1, !if(is_return, "_RTN", "")>, 2684 AtomicNoRet<NAME#"_ADDR64", is_return>; 2685 2686 let offen = 0, idxen = 0, addr64 = 1, tfe = 0 in { 2687 def _si : MUBUF_Real_si <op, opName, outs, ins, asm>; 2688 } 2689 2690 // There is no VI version. If the pseudo is selected, it should be lowered 2691 // for VI appropriately. 2692} 2693 2694multiclass MUBUF_Atomic <mubuf op, string name, RegisterClass rc, 2695 ValueType vt, SDPatternOperator atomic> { 2696 2697 let mayStore = 1, mayLoad = 1, hasPostISelHook = 1 in { 2698 2699 // No return variants 2700 let glc = 0 in { 2701 2702 defm _ADDR64 : MUBUFAtomicAddr64_m < 2703 op, name#"_addr64", (outs), 2704 (ins rc:$vdata, VReg_64:$vaddr, SReg_128:$srsrc, 2705 SCSrc_32:$soffset, mbuf_offset:$offset, slc:$slc), 2706 name#" $vdata, $vaddr, $srsrc, $soffset addr64"#"$offset"#"$slc", [], 0 2707 >; 2708 2709 defm _OFFSET : MUBUFAtomicOffset_m < 2710 op, name#"_offset", (outs), 2711 (ins rc:$vdata, SReg_128:$srsrc, SCSrc_32:$soffset, mbuf_offset:$offset, 2712 slc:$slc), 2713 name#" $vdata, $srsrc, $soffset"#"$offset"#"$slc", [], 0 2714 >; 2715 } // glc = 0 2716 2717 // Variant that return values 2718 let glc = 1, Constraints = "$vdata = $vdata_in", 2719 DisableEncoding = "$vdata_in" in { 2720 2721 defm _RTN_ADDR64 : MUBUFAtomicAddr64_m < 2722 op, name#"_rtn_addr64", (outs rc:$vdata), 2723 (ins rc:$vdata_in, VReg_64:$vaddr, SReg_128:$srsrc, 2724 SCSrc_32:$soffset, mbuf_offset:$offset, slc:$slc), 2725 name#" $vdata, $vaddr, $srsrc, $soffset addr64"#"$offset"#" glc"#"$slc", 2726 [(set vt:$vdata, 2727 (atomic (MUBUFAddr64Atomic v4i32:$srsrc, i64:$vaddr, i32:$soffset, 2728 i16:$offset, i1:$slc), vt:$vdata_in))], 1 2729 >; 2730 2731 defm _RTN_OFFSET : MUBUFAtomicOffset_m < 2732 op, name#"_rtn_offset", (outs rc:$vdata), 2733 (ins rc:$vdata_in, SReg_128:$srsrc, SCSrc_32:$soffset, 2734 mbuf_offset:$offset, slc:$slc), 2735 name#" $vdata, $srsrc, $soffset"#"$offset"#" glc$slc", 2736 [(set vt:$vdata, 2737 (atomic (MUBUFOffsetAtomic v4i32:$srsrc, i32:$soffset, i16:$offset, 2738 i1:$slc), vt:$vdata_in))], 1 2739 >; 2740 2741 } // glc = 1 2742 2743 } // mayStore = 1, mayLoad = 1, hasPostISelHook = 1 2744} 2745 2746// FIXME: tfe can't be an operand because it requires a separate 2747// opcode because it needs an N+1 register class dest register. 2748multiclass MUBUF_Load_Helper <mubuf op, string name, RegisterClass regClass, 2749 ValueType load_vt = i32, 2750 SDPatternOperator ld = null_frag> { 2751 2752 let mayLoad = 1, mayStore = 0 in { 2753 let offen = 0, idxen = 0, vaddr = 0 in { 2754 defm _OFFSET : MUBUF_m <op, name#"_offset", (outs regClass:$vdata), 2755 (ins SReg_128:$srsrc, SCSrc_32:$soffset, 2756 mbuf_offset:$offset, glc:$glc, slc:$slc, tfe:$tfe), 2757 name#" $vdata, $srsrc, $soffset"#"$offset"#"$glc"#"$slc"#"$tfe", 2758 [(set load_vt:$vdata, (ld (MUBUFOffset v4i32:$srsrc, 2759 i32:$soffset, i16:$offset, 2760 i1:$glc, i1:$slc, i1:$tfe)))]>; 2761 } 2762 2763 let offen = 1, idxen = 0 in { 2764 defm _OFFEN : MUBUF_m <op, name#"_offen", (outs regClass:$vdata), 2765 (ins VGPR_32:$vaddr, SReg_128:$srsrc, 2766 SCSrc_32:$soffset, mbuf_offset:$offset, glc:$glc, slc:$slc, 2767 tfe:$tfe), 2768 name#" $vdata, $vaddr, $srsrc, $soffset offen"#"$offset"#"$glc"#"$slc"#"$tfe", []>; 2769 } 2770 2771 let offen = 0, idxen = 1 in { 2772 defm _IDXEN : MUBUF_m <op, name#"_idxen", (outs regClass:$vdata), 2773 (ins VGPR_32:$vaddr, SReg_128:$srsrc, 2774 SCSrc_32:$soffset, mbuf_offset:$offset, glc:$glc, 2775 slc:$slc, tfe:$tfe), 2776 name#" $vdata, $vaddr, $srsrc, $soffset idxen"#"$offset"#"$glc"#"$slc"#"$tfe", []>; 2777 } 2778 2779 let offen = 1, idxen = 1 in { 2780 defm _BOTHEN : MUBUF_m <op, name#"_bothen", (outs regClass:$vdata), 2781 (ins VReg_64:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset, 2782 mbuf_offset:$offset, glc:$glc, slc:$slc, tfe:$tfe), 2783 name#" $vdata, $vaddr, $srsrc, $soffset idxen offen"#"$offset"#"$glc"#"$slc"#"$tfe", []>; 2784 } 2785 2786 let offen = 0, idxen = 0 in { 2787 defm _ADDR64 : MUBUFAddr64_m <op, name#"_addr64", (outs regClass:$vdata), 2788 (ins VReg_64:$vaddr, SReg_128:$srsrc, 2789 SCSrc_32:$soffset, mbuf_offset:$offset, 2790 glc:$glc, slc:$slc, tfe:$tfe), 2791 name#" $vdata, $vaddr, $srsrc, $soffset addr64"#"$offset"# 2792 "$glc"#"$slc"#"$tfe", 2793 [(set load_vt:$vdata, (ld (MUBUFAddr64 v4i32:$srsrc, 2794 i64:$vaddr, i32:$soffset, 2795 i16:$offset, i1:$glc, i1:$slc, 2796 i1:$tfe)))]>; 2797 } 2798 } 2799} 2800 2801multiclass MUBUF_Store_Helper <mubuf op, string name, RegisterClass vdataClass, 2802 ValueType store_vt = i32, SDPatternOperator st = null_frag> { 2803 let mayLoad = 0, mayStore = 1 in { 2804 defm : MUBUF_m <op, name, (outs), 2805 (ins vdataClass:$vdata, VGPR_32:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset, 2806 mbuf_offset:$offset, offen:$offen, idxen:$idxen, glc:$glc, slc:$slc, 2807 tfe:$tfe), 2808 name#" $vdata, $vaddr, $srsrc, $soffset"#"$offen"#"$idxen"#"$offset"# 2809 "$glc"#"$slc"#"$tfe", []>; 2810 2811 let offen = 0, idxen = 0, vaddr = 0 in { 2812 defm _OFFSET : MUBUF_m <op, name#"_offset",(outs), 2813 (ins vdataClass:$vdata, SReg_128:$srsrc, SCSrc_32:$soffset, 2814 mbuf_offset:$offset, glc:$glc, slc:$slc, tfe:$tfe), 2815 name#" $vdata, $srsrc, $soffset"#"$offset"#"$glc"#"$slc"#"$tfe", 2816 [(st store_vt:$vdata, (MUBUFOffset v4i32:$srsrc, i32:$soffset, 2817 i16:$offset, i1:$glc, i1:$slc, i1:$tfe))]>; 2818 } // offen = 0, idxen = 0, vaddr = 0 2819 2820 let offen = 1, idxen = 0 in { 2821 defm _OFFEN : MUBUF_m <op, name#"_offen", (outs), 2822 (ins vdataClass:$vdata, VGPR_32:$vaddr, SReg_128:$srsrc, 2823 SCSrc_32:$soffset, mbuf_offset:$offset, glc:$glc, 2824 slc:$slc, tfe:$tfe), 2825 name#" $vdata, $vaddr, $srsrc, $soffset offen"#"$offset"# 2826 "$glc"#"$slc"#"$tfe", []>; 2827 } // end offen = 1, idxen = 0 2828 2829 let offen = 0, idxen = 1 in { 2830 defm _IDXEN : MUBUF_m <op, name#"_idxen", (outs), 2831 (ins vdataClass:$vdata, VGPR_32:$vaddr, SReg_128:$srsrc, 2832 SCSrc_32:$soffset, mbuf_offset:$offset, glc:$glc, 2833 slc:$slc, tfe:$tfe), 2834 name#" $vdata, $vaddr, $srsrc, $soffset idxen"#"$offset"#"$glc"#"$slc"#"$tfe", []>; 2835 } 2836 2837 let offen = 1, idxen = 1 in { 2838 defm _BOTHEN : MUBUF_m <op, name#"_bothen", (outs), 2839 (ins vdataClass:$vdata, VReg_64:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset, 2840 mbuf_offset:$offset, glc:$glc, slc:$slc, tfe:$tfe), 2841 name#" $vdata, $vaddr, $srsrc, $soffset idxen offen"#"$offset"#"$glc"#"$slc"#"$tfe", []>; 2842 } 2843 2844 let offen = 0, idxen = 0 in { 2845 defm _ADDR64 : MUBUFAddr64_m <op, name#"_addr64", (outs), 2846 (ins vdataClass:$vdata, VReg_64:$vaddr, SReg_128:$srsrc, 2847 SCSrc_32:$soffset, 2848 mbuf_offset:$offset, glc:$glc, slc:$slc, 2849 tfe:$tfe), 2850 name#" $vdata, $vaddr, $srsrc, $soffset addr64"# 2851 "$offset"#"$glc"#"$slc"#"$tfe", 2852 [(st store_vt:$vdata, 2853 (MUBUFAddr64 v4i32:$srsrc, i64:$vaddr, 2854 i32:$soffset, i16:$offset, 2855 i1:$glc, i1:$slc, i1:$tfe))]>; 2856 } 2857 } // End mayLoad = 0, mayStore = 1 2858} 2859 2860// For cache invalidation instructions. 2861multiclass MUBUF_Invalidate <mubuf op, string opName, SDPatternOperator node> { 2862 let hasSideEffects = 1, mayStore = 1, AsmMatchConverter = "" in { 2863 def "" : MUBUF_Pseudo <opName, (outs), (ins), [(node)]>; 2864 2865 // Set everything to 0. 2866 let offset = 0, offen = 0, idxen = 0, glc = 0, vaddr = 0, 2867 vdata = 0, srsrc = 0, slc = 0, tfe = 0, soffset = 0 in { 2868 let addr64 = 0 in { 2869 def _si : MUBUF_Real_si <op, opName, (outs), (ins), opName>; 2870 } 2871 2872 def _vi : MUBUF_Real_vi <op, opName, (outs), (ins), opName>; 2873 } 2874 } // End hasSideEffects = 1, mayStore = 1, AsmMatchConverter = "" 2875} 2876 2877//===----------------------------------------------------------------------===// 2878// FLAT classes 2879//===----------------------------------------------------------------------===// 2880 2881class flat <bits<7> ci, bits<7> vi = ci> { 2882 field bits<7> CI = ci; 2883 field bits<7> VI = vi; 2884} 2885 2886class FLAT_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> : 2887 FLAT <0, outs, ins, "", pattern>, 2888 SIMCInstr<opName, SISubtarget.NONE> { 2889 let isPseudo = 1; 2890 let isCodeGenOnly = 1; 2891} 2892 2893class FLAT_Real_ci <bits<7> op, string opName, dag outs, dag ins, string asm> : 2894 FLAT <op, outs, ins, asm, []>, 2895 SIMCInstr<opName, SISubtarget.SI> { 2896 let AssemblerPredicate = isCIOnly; 2897 let DecoderNamespace="CI"; 2898} 2899 2900class FLAT_Real_vi <bits<7> op, string opName, dag outs, dag ins, string asm> : 2901 FLAT <op, outs, ins, asm, []>, 2902 SIMCInstr<opName, SISubtarget.VI> { 2903 let AssemblerPredicate = VIAssemblerPredicate; 2904 let DecoderNamespace="VI"; 2905 let DisableDecoder = DisableVIDecoder; 2906} 2907 2908multiclass FLAT_AtomicRet_m <flat op, dag outs, dag ins, string asm, 2909 list<dag> pattern> { 2910 def "" : FLAT_Pseudo <NAME#"_RTN", outs, ins, pattern>, 2911 AtomicNoRet <NAME, 1>; 2912 2913 def _ci : FLAT_Real_ci <op.CI, NAME#"_RTN", outs, ins, asm>; 2914 2915 def _vi : FLAT_Real_vi <op.VI, NAME#"_RTN", outs, ins, asm>; 2916} 2917 2918multiclass FLAT_Load_Helper <flat op, string asm_name, 2919 RegisterClass regClass, 2920 dag outs = (outs regClass:$vdst), 2921 dag ins = (ins VReg_64:$addr, glc_flat:$glc, slc_flat:$slc, tfe_flat:$tfe), 2922 string asm = asm_name#" $vdst, $addr"#"$glc"#"$slc"#"$tfe"> { 2923 2924 let data = 0, mayLoad = 1 in { 2925 2926 def "" : FLAT_Pseudo <NAME, outs, ins, []>; 2927 2928 def _ci : FLAT_Real_ci <op.CI, NAME, outs, ins, asm>; 2929 2930 def _vi : FLAT_Real_vi <op.VI, NAME, outs, ins, asm>; 2931 } 2932} 2933 2934multiclass FLAT_Store_Helper <flat op, string asm_name, 2935 RegisterClass vdataClass, 2936 dag outs = (outs), 2937 dag ins = (ins VReg_64:$addr, vdataClass:$data, glc_flat:$glc, 2938 slc_flat:$slc, tfe_flat:$tfe), 2939 string asm = asm_name#" $addr, $data"#"$glc"#"$slc"#"$tfe"> { 2940 2941 let mayLoad = 0, mayStore = 1, vdst = 0 in { 2942 2943 def "" : FLAT_Pseudo <NAME, outs, ins, []>; 2944 2945 def _ci : FLAT_Real_ci <op.CI, NAME, outs, ins, asm>; 2946 2947 def _vi : FLAT_Real_vi <op.VI, NAME, outs, ins, asm>; 2948 } 2949} 2950 2951multiclass FLAT_ATOMIC <flat op, string asm_name, RegisterClass vdst_rc, 2952 RegisterClass data_rc = vdst_rc, 2953 dag outs_noret = (outs), 2954 string asm_noret = asm_name#" $addr, $data"#"$slc"#"$tfe"> { 2955 2956 let mayLoad = 1, mayStore = 1, glc = 0, vdst = 0, AsmMatchConverter = "cvtFlatAtomic" in { 2957 def "" : FLAT_Pseudo <NAME, outs_noret, 2958 (ins VReg_64:$addr, data_rc:$data, 2959 slc_flat_atomic:$slc, tfe_flat_atomic:$tfe), []>, 2960 AtomicNoRet <NAME, 0>; 2961 2962 def _ci : FLAT_Real_ci <op.CI, NAME, outs_noret, 2963 (ins VReg_64:$addr, data_rc:$data, 2964 slc_flat_atomic:$slc, tfe_flat_atomic:$tfe), 2965 asm_noret>; 2966 2967 def _vi : FLAT_Real_vi <op.VI, NAME, outs_noret, 2968 (ins VReg_64:$addr, data_rc:$data, 2969 slc_flat_atomic:$slc, tfe_flat_atomic:$tfe), 2970 asm_noret>; 2971 } 2972 2973 let glc = 1, hasPostISelHook = 1, AsmMatchConverter = "cvtFlatAtomic" in { 2974 defm _RTN : FLAT_AtomicRet_m <op, (outs vdst_rc:$vdst), 2975 (ins VReg_64:$addr, data_rc:$data, slc_flat_atomic:$slc, 2976 tfe_flat_atomic:$tfe), 2977 asm_name#" $vdst, $addr, $data glc"#"$slc"#"$tfe", []>; 2978 } 2979} 2980 2981class MIMG_Mask <string op, int channels> { 2982 string Op = op; 2983 int Channels = channels; 2984} 2985 2986class MIMG_Helper <bits<7> op, dag outs, dag ins, string asm, 2987 string dns=""> : MIMG<op, outs, ins, asm,[]> { 2988 let mayLoad = 1; 2989 let mayStore = 0; 2990 let hasPostISelHook = 1; 2991 let DecoderNamespace = dns; 2992 let isAsmParserOnly = !if(!eq(dns,""), 1, 0); 2993 let AsmMatchConverter = "cvtMIMG"; 2994} 2995 2996class MIMG_NoSampler_Helper <bits<7> op, string asm, 2997 RegisterClass dst_rc, 2998 RegisterClass addr_rc, 2999 string dns=""> : MIMG_Helper < 3000 op, 3001 (outs dst_rc:$vdata), 3002 (ins addr_rc:$vaddr, SReg_256:$srsrc, 3003 dmask:$dmask, unorm:$unorm, glc:$glc, slc:$slc, 3004 r128:$r128, tfe:$tfe, lwe:$lwe, da:$da), 3005 asm#" $vdata, $vaddr, $srsrc$dmask$unorm$glc$slc$r128$tfe$lwe$da", 3006 dns> { 3007 let ssamp = 0; 3008} 3009 3010multiclass MIMG_NoSampler_Src_Helper <bits<7> op, string asm, 3011 RegisterClass dst_rc, 3012 int channels> { 3013 def _V1 : MIMG_NoSampler_Helper <op, asm, dst_rc, VGPR_32, 3014 !if(!eq(channels, 1), "AMDGPU", "")>, 3015 MIMG_Mask<asm#"_V1", channels>; 3016 def _V2 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_64>, 3017 MIMG_Mask<asm#"_V2", channels>; 3018 def _V4 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_128>, 3019 MIMG_Mask<asm#"_V4", channels>; 3020} 3021 3022multiclass MIMG_NoSampler <bits<7> op, string asm> { 3023 defm _V1 : MIMG_NoSampler_Src_Helper <op, asm, VGPR_32, 1>; 3024 defm _V2 : MIMG_NoSampler_Src_Helper <op, asm, VReg_64, 2>; 3025 defm _V3 : MIMG_NoSampler_Src_Helper <op, asm, VReg_96, 3>; 3026 defm _V4 : MIMG_NoSampler_Src_Helper <op, asm, VReg_128, 4>; 3027} 3028 3029class MIMG_Store_Helper <bits<7> op, string asm, 3030 RegisterClass data_rc, 3031 RegisterClass addr_rc> : MIMG_Helper < 3032 op, 3033 (outs), 3034 (ins data_rc:$vdata, addr_rc:$vaddr, SReg_256:$srsrc, 3035 dmask:$dmask, unorm:$unorm, glc:$glc, slc:$slc, 3036 r128:$r128, tfe:$tfe, lwe:$lwe, da:$da), 3037 asm#" $vdata, $vaddr, $srsrc$dmask$unorm$glc$slc$r128$tfe$lwe$da" 3038 > { 3039 let ssamp = 0; 3040 let mayLoad = 1; // TableGen requires this for matching with the intrinsics 3041 let mayStore = 1; 3042 let hasSideEffects = 1; 3043 let hasPostISelHook = 0; 3044} 3045 3046multiclass MIMG_Store_Addr_Helper <bits<7> op, string asm, 3047 RegisterClass data_rc, 3048 int channels> { 3049 def _V1 : MIMG_Store_Helper <op, asm, data_rc, VGPR_32>, 3050 MIMG_Mask<asm#"_V1", channels>; 3051 def _V2 : MIMG_Store_Helper <op, asm, data_rc, VReg_64>, 3052 MIMG_Mask<asm#"_V2", channels>; 3053 def _V4 : MIMG_Store_Helper <op, asm, data_rc, VReg_128>, 3054 MIMG_Mask<asm#"_V4", channels>; 3055} 3056 3057multiclass MIMG_Store <bits<7> op, string asm> { 3058 defm _V1 : MIMG_Store_Addr_Helper <op, asm, VGPR_32, 1>; 3059 defm _V2 : MIMG_Store_Addr_Helper <op, asm, VReg_64, 2>; 3060 defm _V3 : MIMG_Store_Addr_Helper <op, asm, VReg_96, 3>; 3061 defm _V4 : MIMG_Store_Addr_Helper <op, asm, VReg_128, 4>; 3062} 3063 3064class MIMG_Sampler_Helper <bits<7> op, string asm, 3065 RegisterClass dst_rc, 3066 RegisterClass src_rc, 3067 int wqm, 3068 string dns=""> : MIMG_Helper < 3069 op, 3070 (outs dst_rc:$vdata), 3071 (ins src_rc:$vaddr, SReg_256:$srsrc, SReg_128:$ssamp, 3072 dmask:$dmask, unorm:$unorm, glc:$glc, slc:$slc, 3073 r128:$r128, tfe:$tfe, lwe:$lwe, da:$da), 3074 asm#" $vdata, $vaddr, $srsrc, $ssamp$dmask$unorm$glc$slc$r128$tfe$lwe$da", 3075 dns> { 3076 let WQM = wqm; 3077} 3078 3079multiclass MIMG_Sampler_Src_Helper <bits<7> op, string asm, 3080 RegisterClass dst_rc, 3081 int channels, int wqm> { 3082 def _V1 : MIMG_Sampler_Helper <op, asm, dst_rc, VGPR_32, wqm, 3083 !if(!eq(channels, 1), "AMDGPU", "")>, 3084 MIMG_Mask<asm#"_V1", channels>; 3085 def _V2 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_64, wqm>, 3086 MIMG_Mask<asm#"_V2", channels>; 3087 def _V4 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_128, wqm>, 3088 MIMG_Mask<asm#"_V4", channels>; 3089 def _V8 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_256, wqm>, 3090 MIMG_Mask<asm#"_V8", channels>; 3091 def _V16 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_512, wqm>, 3092 MIMG_Mask<asm#"_V16", channels>; 3093} 3094 3095multiclass MIMG_Sampler <bits<7> op, string asm, int wqm=0> { 3096 defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VGPR_32, 1, wqm>; 3097 defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2, wqm>; 3098 defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3, wqm>; 3099 defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4, wqm>; 3100} 3101 3102multiclass MIMG_Sampler_WQM <bits<7> op, string asm> : MIMG_Sampler<op, asm, 1>; 3103 3104class MIMG_Gather_Helper <bits<7> op, string asm, 3105 RegisterClass dst_rc, 3106 RegisterClass src_rc, int wqm> : MIMG < 3107 op, 3108 (outs dst_rc:$vdata), 3109 (ins src_rc:$vaddr, SReg_256:$srsrc, SReg_128:$ssamp, 3110 dmask:$dmask, unorm:$unorm, glc:$glc, slc:$slc, 3111 r128:$r128, tfe:$tfe, lwe:$lwe, da:$da), 3112 asm#" $vdata, $vaddr, $srsrc, $ssamp$dmask$unorm$glc$slc$r128$tfe$lwe$da", 3113 []> { 3114 let mayLoad = 1; 3115 let mayStore = 0; 3116 3117 // DMASK was repurposed for GATHER4. 4 components are always 3118 // returned and DMASK works like a swizzle - it selects 3119 // the component to fetch. The only useful DMASK values are 3120 // 1=red, 2=green, 4=blue, 8=alpha. (e.g. 1 returns 3121 // (red,red,red,red) etc.) The ISA document doesn't mention 3122 // this. 3123 // Therefore, disable all code which updates DMASK by setting these two: 3124 let MIMG = 0; 3125 let hasPostISelHook = 0; 3126 let WQM = wqm; 3127 3128 let isAsmParserOnly = 1; // TBD: fix it later 3129} 3130 3131multiclass MIMG_Gather_Src_Helper <bits<7> op, string asm, 3132 RegisterClass dst_rc, 3133 int channels, int wqm> { 3134 def _V1 : MIMG_Gather_Helper <op, asm, dst_rc, VGPR_32, wqm>, 3135 MIMG_Mask<asm#"_V1", channels>; 3136 def _V2 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_64, wqm>, 3137 MIMG_Mask<asm#"_V2", channels>; 3138 def _V4 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_128, wqm>, 3139 MIMG_Mask<asm#"_V4", channels>; 3140 def _V8 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_256, wqm>, 3141 MIMG_Mask<asm#"_V8", channels>; 3142 def _V16 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_512, wqm>, 3143 MIMG_Mask<asm#"_V16", channels>; 3144} 3145 3146multiclass MIMG_Gather <bits<7> op, string asm, int wqm=0> { 3147 defm _V1 : MIMG_Gather_Src_Helper<op, asm, VGPR_32, 1, wqm>; 3148 defm _V2 : MIMG_Gather_Src_Helper<op, asm, VReg_64, 2, wqm>; 3149 defm _V3 : MIMG_Gather_Src_Helper<op, asm, VReg_96, 3, wqm>; 3150 defm _V4 : MIMG_Gather_Src_Helper<op, asm, VReg_128, 4, wqm>; 3151} 3152 3153multiclass MIMG_Gather_WQM <bits<7> op, string asm> : MIMG_Gather<op, asm, 1>; 3154 3155//===----------------------------------------------------------------------===// 3156// Vector instruction mappings 3157//===----------------------------------------------------------------------===// 3158 3159// Maps an opcode in e32 form to its e64 equivalent 3160def getVOPe64 : InstrMapping { 3161 let FilterClass = "VOP"; 3162 let RowFields = ["OpName"]; 3163 let ColFields = ["Size"]; 3164 let KeyCol = ["4"]; 3165 let ValueCols = [["8"]]; 3166} 3167 3168// Maps an opcode in e64 form to its e32 equivalent 3169def getVOPe32 : InstrMapping { 3170 let FilterClass = "VOP"; 3171 let RowFields = ["OpName"]; 3172 let ColFields = ["Size"]; 3173 let KeyCol = ["8"]; 3174 let ValueCols = [["4"]]; 3175} 3176 3177def getMaskedMIMGOp : InstrMapping { 3178 let FilterClass = "MIMG_Mask"; 3179 let RowFields = ["Op"]; 3180 let ColFields = ["Channels"]; 3181 let KeyCol = ["4"]; 3182 let ValueCols = [["1"], ["2"], ["3"] ]; 3183} 3184 3185// Maps an commuted opcode to its original version 3186def getCommuteOrig : InstrMapping { 3187 let FilterClass = "VOP2_REV"; 3188 let RowFields = ["RevOp"]; 3189 let ColFields = ["IsOrig"]; 3190 let KeyCol = ["0"]; 3191 let ValueCols = [["1"]]; 3192} 3193 3194// Maps an original opcode to its commuted version 3195def getCommuteRev : InstrMapping { 3196 let FilterClass = "VOP2_REV"; 3197 let RowFields = ["RevOp"]; 3198 let ColFields = ["IsOrig"]; 3199 let KeyCol = ["1"]; 3200 let ValueCols = [["0"]]; 3201} 3202 3203def getCommuteCmpOrig : InstrMapping { 3204 let FilterClass = "VOP2_REV"; 3205 let RowFields = ["RevOp"]; 3206 let ColFields = ["IsOrig"]; 3207 let KeyCol = ["0"]; 3208 let ValueCols = [["1"]]; 3209} 3210 3211// Maps an original opcode to its commuted version 3212def getCommuteCmpRev : InstrMapping { 3213 let FilterClass = "VOP2_REV"; 3214 let RowFields = ["RevOp"]; 3215 let ColFields = ["IsOrig"]; 3216 let KeyCol = ["1"]; 3217 let ValueCols = [["0"]]; 3218} 3219 3220 3221def getMCOpcodeGen : InstrMapping { 3222 let FilterClass = "SIMCInstr"; 3223 let RowFields = ["PseudoInstr"]; 3224 let ColFields = ["Subtarget"]; 3225 let KeyCol = [!cast<string>(SISubtarget.NONE)]; 3226 let ValueCols = [[!cast<string>(SISubtarget.SI)],[!cast<string>(SISubtarget.VI)]]; 3227} 3228 3229def getAddr64Inst : InstrMapping { 3230 let FilterClass = "MUBUFAddr64Table"; 3231 let RowFields = ["OpName"]; 3232 let ColFields = ["IsAddr64"]; 3233 let KeyCol = ["0"]; 3234 let ValueCols = [["1"]]; 3235} 3236 3237// Maps an atomic opcode to its version with a return value. 3238def getAtomicRetOp : InstrMapping { 3239 let FilterClass = "AtomicNoRet"; 3240 let RowFields = ["NoRetOp"]; 3241 let ColFields = ["IsRet"]; 3242 let KeyCol = ["0"]; 3243 let ValueCols = [["1"]]; 3244} 3245 3246// Maps an atomic opcode to its returnless version. 3247def getAtomicNoRetOp : InstrMapping { 3248 let FilterClass = "AtomicNoRet"; 3249 let RowFields = ["NoRetOp"]; 3250 let ColFields = ["IsRet"]; 3251 let KeyCol = ["1"]; 3252 let ValueCols = [["0"]]; 3253} 3254 3255include "SIInstructions.td" 3256include "CIInstructions.td" 3257include "VIInstructions.td" 3258