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