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