SIInstrInfo.td revision 285181
11592Srgrimes//===-- SIInstrInfo.td - SI Instruction Infos -------------*- tablegen -*--===// 21592Srgrimes// 31592Srgrimes// The LLVM Compiler Infrastructure 41592Srgrimes// 51592Srgrimes// This file is distributed under the University of Illinois Open Source 61592Srgrimes// License. See LICENSE.TXT for details. 71592Srgrimes// 81592Srgrimes//===----------------------------------------------------------------------===// 91592Srgrimesdef isCI : Predicate<"Subtarget->getGeneration() " 101592Srgrimes ">= AMDGPUSubtarget::SEA_ISLANDS">; 111592Srgrimesdef isVI : Predicate < 121592Srgrimes "Subtarget->getGeneration() >= AMDGPUSubtarget::VOLCANIC_ISLANDS">, 131592Srgrimes AssemblerPredicate<"FeatureGCN3Encoding">; 141592Srgrimes 151592Srgrimesdef DisableInst : Predicate <"false">, AssemblerPredicate<"FeatureDisable">; 161592Srgrimes 171592Srgrimesclass vop { 181592Srgrimes field bits<9> SI3; 191592Srgrimes field bits<10> VI3; 201592Srgrimes} 211592Srgrimes 221592Srgrimesclass vopc <bits<8> si, bits<8> vi = !add(0x40, si)> : vop { 231592Srgrimes field bits<8> SI = si; 241592Srgrimes field bits<8> VI = vi; 251592Srgrimes 261592Srgrimes field bits<9> SI3 = {0, si{7-0}}; 271592Srgrimes field bits<10> VI3 = {0, 0, vi{7-0}}; 281592Srgrimes} 291592Srgrimes 301592Srgrimesclass vop1 <bits<8> si, bits<8> vi = si> : vop { 311592Srgrimes field bits<8> SI = si; 321592Srgrimes field bits<8> VI = vi; 331592Srgrimes 341592Srgrimes field bits<9> SI3 = {1, 1, si{6-0}}; 3531491Scharnier field bits<10> VI3 = !add(0x140, vi); 3621838Spst} 3731491Scharnier 3831491Scharnierclass vop2 <bits<6> si, bits<6> vi = si> : vop { 3950476Speter field bits<6> SI = si; 401592Srgrimes field bits<6> VI = vi; 411592Srgrimes 421592Srgrimes field bits<9> SI3 = {1, 0, 0, si{5-0}}; 431592Srgrimes field bits<10> VI3 = {0, 1, 0, 0, vi{5-0}}; 441592Srgrimes} 451592Srgrimes 461592Srgrimes// Specify a VOP2 opcode for SI and VOP3 opcode for VI 471592Srgrimes// that doesn't have VOP2 encoding on VI 4821838Spstclass vop23 <bits<6> si, bits<10> vi> : vop2 <si> { 491592Srgrimes let VI3 = vi; 5021838Spst} 511592Srgrimes 5221838Spstclass vop3 <bits<9> si, bits<10> vi = {0, si}> : vop { 5321838Spst let SI3 = si; 5421838Spst let VI3 = vi; 5521838Spst} 561592Srgrimes 571592Srgrimesclass sop1 <bits<8> si, bits<8> vi = si> { 5821838Spst field bits<8> SI = si; 591592Srgrimes field bits<8> VI = vi; 601592Srgrimes} 611592Srgrimes 6231491Scharnierclass sop2 <bits<7> si, bits<7> vi = si> { 6331491Scharnier field bits<7> SI = si; 6431491Scharnier field bits<7> VI = vi; 651592Srgrimes} 661592Srgrimes 671592Srgrimesclass sopk <bits<5> si, bits<5> vi = si> { 688870Srgrimes field bits<5> SI = si; 691592Srgrimes field bits<5> VI = vi; 708870Srgrimes} 711592Srgrimes 721592Srgrimes// Execpt for the NONE field, this must be kept in sync with the SISubtarget enum 7331491Scharnier// in AMDGPUInstrInfo.cpp 741592Srgrimesdef SISubtarget { 751592Srgrimes int NONE = -1; 761592Srgrimes int SI = 0; 771592Srgrimes int VI = 1; 781592Srgrimes} 791592Srgrimes 801592Srgrimes//===----------------------------------------------------------------------===// 811592Srgrimes// SI DAG Nodes 821592Srgrimes//===----------------------------------------------------------------------===// 831592Srgrimes 841592Srgrimesdef SIload_constant : SDNode<"AMDGPUISD::LOAD_CONSTANT", 851592Srgrimes SDTypeProfile<1, 2, [SDTCisVT<0, f32>, SDTCisVT<1, v4i32>, SDTCisVT<2, i32>]>, 861592Srgrimes [SDNPMayLoad, SDNPMemOperand] 871592Srgrimes>; 881592Srgrimes 891592Srgrimesdef SItbuffer_store : SDNode<"AMDGPUISD::TBUFFER_STORE_FORMAT", 901592Srgrimes SDTypeProfile<0, 13, 9121838Spst [SDTCisVT<0, v4i32>, // rsrc(SGPR) 921592Srgrimes SDTCisVT<1, iAny>, // vdata(VGPR) 931592Srgrimes SDTCisVT<2, i32>, // num_channels(imm) 948870Srgrimes SDTCisVT<3, i32>, // vaddr(VGPR) 951592Srgrimes SDTCisVT<4, i32>, // soffset(SGPR) 961592Srgrimes SDTCisVT<5, i32>, // inst_offset(imm) 971592Srgrimes SDTCisVT<6, i32>, // dfmt(imm) 981592Srgrimes SDTCisVT<7, i32>, // nfmt(imm) 9931491Scharnier SDTCisVT<8, i32>, // offen(imm) 1001592Srgrimes SDTCisVT<9, i32>, // idxen(imm) 1011592Srgrimes SDTCisVT<10, i32>, // glc(imm) 1021592Srgrimes SDTCisVT<11, i32>, // slc(imm) 1031592Srgrimes SDTCisVT<12, i32> // tfe(imm) 1041592Srgrimes ]>, 1051592Srgrimes [SDNPMayStore, SDNPMemOperand, SDNPHasChain] 1061592Srgrimes>; 10737262Sbde 1081592Srgrimesdef SIload_input : SDNode<"AMDGPUISD::LOAD_INPUT", 1091592Srgrimes SDTypeProfile<1, 3, [SDTCisVT<0, v4f32>, SDTCisVT<1, v4i32>, SDTCisVT<2, i16>, 1101592Srgrimes SDTCisVT<3, i32>]> 1111592Srgrimes>; 1121592Srgrimes 1131592Srgrimesclass SDSample<string opcode> : SDNode <opcode, 1141592Srgrimes SDTypeProfile<1, 4, [SDTCisVT<0, v4f32>, SDTCisVT<2, v32i8>, 11521838Spst SDTCisVT<3, v4i32>, SDTCisVT<4, i32>]> 1161592Srgrimes>; 1171592Srgrimes 1181592Srgrimesdef SIsample : SDSample<"AMDGPUISD::SAMPLE">; 1191592Srgrimesdef SIsampleb : SDSample<"AMDGPUISD::SAMPLEB">; 1201592Srgrimesdef SIsampled : SDSample<"AMDGPUISD::SAMPLED">; 12137262Sbdedef SIsamplel : SDSample<"AMDGPUISD::SAMPLEL">; 12237262Sbde 12321838Spstdef SIconstdata_ptr : SDNode< 1241592Srgrimes "AMDGPUISD::CONST_DATA_PTR", SDTypeProfile <1, 0, [SDTCisVT<0, i64>]> 1251592Srgrimes>; 1261592Srgrimes 12721838Spst//===----------------------------------------------------------------------===// 12877862Sdd// SDNodes and PatFrag for local loads and stores to enable s_mov_b32 m0, -1 12977862Sdd// to be glued to the memory instructions. 13079674Sbrian//===----------------------------------------------------------------------===// 13177862Sdd 1321592Srgrimesdef SIld_local : SDNode <"ISD::LOAD", SDTLoad, 1331592Srgrimes [SDNPHasChain, SDNPMayLoad, SDNPMemOperand, SDNPInGlue] 1341592Srgrimes>; 13521838Spst 13621838Spstdef si_ld_local : PatFrag <(ops node:$ptr), (SIld_local node:$ptr), [{ 13721838Spst return isLocalLoad(cast<LoadSDNode>(N)); 13821838Spst}]>; 13921838Spst 1401592Srgrimesdef si_load_local : PatFrag <(ops node:$ptr), (si_ld_local node:$ptr), [{ 1411592Srgrimes return cast<LoadSDNode>(N)->getAddressingMode() == ISD::UNINDEXED && 1421592Srgrimes cast<LoadSDNode>(N)->getExtensionType() == ISD::NON_EXTLOAD; 14321838Spst}]>; 14421838Spst 1451592Srgrimesdef si_load_local_align8 : Aligned8Bytes < 1461592Srgrimes (ops node:$ptr), (si_load_local node:$ptr) 1471592Srgrimes>; 14821838Spst 1491592Srgrimesdef si_sextload_local : PatFrag <(ops node:$ptr), (si_ld_local node:$ptr), [{ 1501592Srgrimes return cast<LoadSDNode>(N)->getExtensionType() == ISD::SEXTLOAD; 1511592Srgrimes}]>; 1521592Srgrimesdef si_az_extload_local : AZExtLoadBase <si_ld_local>; 1531801Sphk 1541592Srgrimesmulticlass SIExtLoadLocal <PatFrag ld_node> { 1551592Srgrimes 1561592Srgrimes def _i8 : PatFrag <(ops node:$ptr), (ld_node node:$ptr), 1571592Srgrimes [{return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i8;}] 1581592Srgrimes >; 1591592Srgrimes 1601592Srgrimes def _i16 : PatFrag <(ops node:$ptr), (ld_node node:$ptr), 1611592Srgrimes [{return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i16;}] 1621592Srgrimes >; 1631592Srgrimes} 1641592Srgrimes 1651592Srgrimesdefm si_sextload_local : SIExtLoadLocal <si_sextload_local>; 1661592Srgrimesdefm si_az_extload_local : SIExtLoadLocal <si_az_extload_local>; 1671592Srgrimes 1681592Srgrimesdef SIst_local : SDNode <"ISD::STORE", SDTStore, 1691592Srgrimes [SDNPHasChain, SDNPMayStore, SDNPMemOperand, SDNPInGlue] 1701592Srgrimes>; 1711592Srgrimes 1721592Srgrimesdef si_st_local : PatFrag < 1731592Srgrimes (ops node:$val, node:$ptr), (SIst_local node:$val, node:$ptr), [{ 1741592Srgrimes return isLocalStore(cast<StoreSDNode>(N)); 1751592Srgrimes}]>; 1761592Srgrimes 1771592Srgrimesdef si_store_local : PatFrag < 1781592Srgrimes (ops node:$val, node:$ptr), (si_st_local node:$val, node:$ptr), [{ 1791592Srgrimes return cast<StoreSDNode>(N)->getAddressingMode() == ISD::UNINDEXED && 180 !cast<StoreSDNode>(N)->isTruncatingStore(); 181}]>; 182 183def si_store_local_align8 : Aligned8Bytes < 184 (ops node:$val, node:$ptr), (si_store_local node:$val, node:$ptr) 185>; 186 187def si_truncstore_local : PatFrag < 188 (ops node:$val, node:$ptr), (si_st_local node:$val, node:$ptr), [{ 189 return cast<StoreSDNode>(N)->isTruncatingStore(); 190}]>; 191 192def si_truncstore_local_i8 : PatFrag < 193 (ops node:$val, node:$ptr), (si_truncstore_local node:$val, node:$ptr), [{ 194 return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i8; 195}]>; 196 197def si_truncstore_local_i16 : PatFrag < 198 (ops node:$val, node:$ptr), (si_truncstore_local node:$val, node:$ptr), [{ 199 return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i16; 200}]>; 201 202multiclass SIAtomicM0Glue2 <string op_name> { 203 204 def _glue : SDNode <"ISD::ATOMIC_"#op_name, SDTAtomic2, 205 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand, SDNPInGlue] 206 >; 207 208 def _local : local_binary_atomic_op <!cast<SDNode>(NAME#"_glue")>; 209} 210 211defm si_atomic_load_add : SIAtomicM0Glue2 <"LOAD_ADD">; 212defm si_atomic_load_and : SIAtomicM0Glue2 <"LOAD_AND">; 213defm si_atomic_load_min : SIAtomicM0Glue2 <"LOAD_MIN">; 214defm si_atomic_load_max : SIAtomicM0Glue2 <"LOAD_MAX">; 215defm si_atomic_load_or : SIAtomicM0Glue2 <"LOAD_OR">; 216defm si_atomic_load_sub : SIAtomicM0Glue2 <"LOAD_SUB">; 217defm si_atomic_load_xor : SIAtomicM0Glue2 <"LOAD_XOR">; 218defm si_atomic_load_umin : SIAtomicM0Glue2 <"LOAD_UMIN">; 219defm si_atomic_load_umax : SIAtomicM0Glue2 <"LOAD_UMAX">; 220defm si_atomic_swap : SIAtomicM0Glue2 <"SWAP">; 221 222def si_atomic_cmp_swap_glue : SDNode <"ISD::ATOMIC_CMP_SWAP", SDTAtomic3, 223 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand, SDNPInGlue] 224>; 225 226defm si_atomic_cmp_swap : AtomicCmpSwapLocal <si_atomic_cmp_swap_glue>; 227 228// Transformation function, extract the lower 32bit of a 64bit immediate 229def LO32 : SDNodeXForm<imm, [{ 230 return CurDAG->getTargetConstant(N->getZExtValue() & 0xffffffff, SDLoc(N), 231 MVT::i32); 232}]>; 233 234def LO32f : SDNodeXForm<fpimm, [{ 235 APInt V = N->getValueAPF().bitcastToAPInt().trunc(32); 236 return CurDAG->getTargetConstantFP(APFloat(APFloat::IEEEsingle, V), MVT::f32); 237}]>; 238 239// Transformation function, extract the upper 32bit of a 64bit immediate 240def HI32 : SDNodeXForm<imm, [{ 241 return CurDAG->getTargetConstant(N->getZExtValue() >> 32, SDLoc(N), MVT::i32); 242}]>; 243 244def HI32f : SDNodeXForm<fpimm, [{ 245 APInt V = N->getValueAPF().bitcastToAPInt().lshr(32).trunc(32); 246 return CurDAG->getTargetConstantFP(APFloat(APFloat::IEEEsingle, V), SDLoc(N), 247 MVT::f32); 248}]>; 249 250def IMM8bitDWORD : PatLeaf <(imm), 251 [{return (N->getZExtValue() & ~0x3FC) == 0;}] 252>; 253 254def as_dword_i32imm : SDNodeXForm<imm, [{ 255 return CurDAG->getTargetConstant(N->getZExtValue() >> 2, SDLoc(N), MVT::i32); 256}]>; 257 258def as_i1imm : SDNodeXForm<imm, [{ 259 return CurDAG->getTargetConstant(N->getZExtValue(), SDLoc(N), MVT::i1); 260}]>; 261 262def as_i8imm : SDNodeXForm<imm, [{ 263 return CurDAG->getTargetConstant(N->getZExtValue(), SDLoc(N), MVT::i8); 264}]>; 265 266def as_i16imm : SDNodeXForm<imm, [{ 267 return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i16); 268}]>; 269 270def as_i32imm: SDNodeXForm<imm, [{ 271 return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i32); 272}]>; 273 274def as_i64imm: SDNodeXForm<imm, [{ 275 return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i64); 276}]>; 277 278// Copied from the AArch64 backend: 279def bitcast_fpimm_to_i32 : SDNodeXForm<fpimm, [{ 280return CurDAG->getTargetConstant( 281 N->getValueAPF().bitcastToAPInt().getZExtValue(), SDLoc(N), MVT::i32); 282}]>; 283 284// Copied from the AArch64 backend: 285def bitcast_fpimm_to_i64 : SDNodeXForm<fpimm, [{ 286return CurDAG->getTargetConstant( 287 N->getValueAPF().bitcastToAPInt().getZExtValue(), SDLoc(N), MVT::i64); 288}]>; 289 290def IMM8bit : PatLeaf <(imm), 291 [{return isUInt<8>(N->getZExtValue());}] 292>; 293 294def IMM12bit : PatLeaf <(imm), 295 [{return isUInt<12>(N->getZExtValue());}] 296>; 297 298def IMM16bit : PatLeaf <(imm), 299 [{return isUInt<16>(N->getZExtValue());}] 300>; 301 302def IMM20bit : PatLeaf <(imm), 303 [{return isUInt<20>(N->getZExtValue());}] 304>; 305 306def IMM32bit : PatLeaf <(imm), 307 [{return isUInt<32>(N->getZExtValue());}] 308>; 309 310def mubuf_vaddr_offset : PatFrag< 311 (ops node:$ptr, node:$offset, node:$imm_offset), 312 (add (add node:$ptr, node:$offset), node:$imm_offset) 313>; 314 315class InlineImm <ValueType vt> : PatLeaf <(vt imm), [{ 316 return isInlineImmediate(N); 317}]>; 318 319class InlineFPImm <ValueType vt> : PatLeaf <(vt fpimm), [{ 320 return isInlineImmediate(N); 321}]>; 322 323class SGPRImm <dag frag> : PatLeaf<frag, [{ 324 if (Subtarget->getGeneration() < AMDGPUSubtarget::SOUTHERN_ISLANDS) { 325 return false; 326 } 327 const SIRegisterInfo *SIRI = 328 static_cast<const SIRegisterInfo *>(Subtarget->getRegisterInfo()); 329 for (SDNode::use_iterator U = N->use_begin(), E = SDNode::use_end(); 330 U != E; ++U) { 331 if (SIRI->isSGPRClass(getOperandRegClass(*U, U.getOperandNo()))) { 332 return true; 333 } 334 } 335 return false; 336}]>; 337 338//===----------------------------------------------------------------------===// 339// Custom Operands 340//===----------------------------------------------------------------------===// 341 342def FRAMEri32 : Operand<iPTR> { 343 let MIOperandInfo = (ops i32:$ptr, i32imm:$index); 344} 345 346def SoppBrTarget : AsmOperandClass { 347 let Name = "SoppBrTarget"; 348 let ParserMethod = "parseSOppBrTarget"; 349} 350 351def sopp_brtarget : Operand<OtherVT> { 352 let EncoderMethod = "getSOPPBrEncoding"; 353 let OperandType = "OPERAND_PCREL"; 354 let ParserMatchClass = SoppBrTarget; 355} 356 357include "SIInstrFormats.td" 358include "VIInstrFormats.td" 359 360def MubufOffsetMatchClass : AsmOperandClass { 361 let Name = "MubufOffset"; 362 let ParserMethod = "parseMubufOptionalOps"; 363 let RenderMethod = "addImmOperands"; 364} 365 366class DSOffsetBaseMatchClass <string parser> : AsmOperandClass { 367 let Name = "DSOffset"#parser; 368 let ParserMethod = parser; 369 let RenderMethod = "addImmOperands"; 370 let PredicateMethod = "isDSOffset"; 371} 372 373def DSOffsetMatchClass : DSOffsetBaseMatchClass <"parseDSOptionalOps">; 374def DSOffsetGDSMatchClass : DSOffsetBaseMatchClass <"parseDSOffsetOptional">; 375 376def DSOffset01MatchClass : AsmOperandClass { 377 let Name = "DSOffset1"; 378 let ParserMethod = "parseDSOff01OptionalOps"; 379 let RenderMethod = "addImmOperands"; 380 let PredicateMethod = "isDSOffset01"; 381} 382 383class GDSBaseMatchClass <string parser> : AsmOperandClass { 384 let Name = "GDS"#parser; 385 let PredicateMethod = "isImm"; 386 let ParserMethod = parser; 387 let RenderMethod = "addImmOperands"; 388} 389 390def GDSMatchClass : GDSBaseMatchClass <"parseDSOptionalOps">; 391def GDS01MatchClass : GDSBaseMatchClass <"parseDSOff01OptionalOps">; 392 393class GLCBaseMatchClass <string parser> : AsmOperandClass { 394 let Name = "GLC"#parser; 395 let PredicateMethod = "isImm"; 396 let ParserMethod = parser; 397 let RenderMethod = "addImmOperands"; 398} 399 400def GLCMubufMatchClass : GLCBaseMatchClass <"parseMubufOptionalOps">; 401def GLCFlatMatchClass : GLCBaseMatchClass <"parseFlatOptionalOps">; 402 403class SLCBaseMatchClass <string parser> : AsmOperandClass { 404 let Name = "SLC"#parser; 405 let PredicateMethod = "isImm"; 406 let ParserMethod = parser; 407 let RenderMethod = "addImmOperands"; 408} 409 410def SLCMubufMatchClass : SLCBaseMatchClass <"parseMubufOptionalOps">; 411def SLCFlatMatchClass : SLCBaseMatchClass <"parseFlatOptionalOps">; 412def SLCFlatAtomicMatchClass : SLCBaseMatchClass <"parseFlatAtomicOptionalOps">; 413 414class TFEBaseMatchClass <string parser> : AsmOperandClass { 415 let Name = "TFE"#parser; 416 let PredicateMethod = "isImm"; 417 let ParserMethod = parser; 418 let RenderMethod = "addImmOperands"; 419} 420 421def TFEMubufMatchClass : TFEBaseMatchClass <"parseMubufOptionalOps">; 422def TFEFlatMatchClass : TFEBaseMatchClass <"parseFlatOptionalOps">; 423def TFEFlatAtomicMatchClass : TFEBaseMatchClass <"parseFlatAtomicOptionalOps">; 424 425def OModMatchClass : AsmOperandClass { 426 let Name = "OMod"; 427 let PredicateMethod = "isImm"; 428 let ParserMethod = "parseVOP3OptionalOps"; 429 let RenderMethod = "addImmOperands"; 430} 431 432def ClampMatchClass : AsmOperandClass { 433 let Name = "Clamp"; 434 let PredicateMethod = "isImm"; 435 let ParserMethod = "parseVOP3OptionalOps"; 436 let RenderMethod = "addImmOperands"; 437} 438 439let OperandType = "OPERAND_IMMEDIATE" in { 440 441def offen : Operand<i1> { 442 let PrintMethod = "printOffen"; 443} 444def idxen : Operand<i1> { 445 let PrintMethod = "printIdxen"; 446} 447def addr64 : Operand<i1> { 448 let PrintMethod = "printAddr64"; 449} 450def mbuf_offset : Operand<i16> { 451 let PrintMethod = "printMBUFOffset"; 452 let ParserMatchClass = MubufOffsetMatchClass; 453} 454class ds_offset_base <AsmOperandClass mc> : Operand<i16> { 455 let PrintMethod = "printDSOffset"; 456 let ParserMatchClass = mc; 457} 458def ds_offset : ds_offset_base <DSOffsetMatchClass>; 459def ds_offset_gds : ds_offset_base <DSOffsetGDSMatchClass>; 460 461def ds_offset0 : Operand<i8> { 462 let PrintMethod = "printDSOffset0"; 463 let ParserMatchClass = DSOffset01MatchClass; 464} 465def ds_offset1 : Operand<i8> { 466 let PrintMethod = "printDSOffset1"; 467 let ParserMatchClass = DSOffset01MatchClass; 468} 469class gds_base <AsmOperandClass mc> : Operand <i1> { 470 let PrintMethod = "printGDS"; 471 let ParserMatchClass = mc; 472} 473def gds : gds_base <GDSMatchClass>; 474 475def gds01 : gds_base <GDS01MatchClass>; 476 477class glc_base <AsmOperandClass mc> : Operand <i1> { 478 let PrintMethod = "printGLC"; 479 let ParserMatchClass = mc; 480} 481 482def glc : glc_base <GLCMubufMatchClass>; 483def glc_flat : glc_base <GLCFlatMatchClass>; 484 485class slc_base <AsmOperandClass mc> : Operand <i1> { 486 let PrintMethod = "printSLC"; 487 let ParserMatchClass = mc; 488} 489 490def slc : slc_base <SLCMubufMatchClass>; 491def slc_flat : slc_base <SLCFlatMatchClass>; 492def slc_flat_atomic : slc_base <SLCFlatAtomicMatchClass>; 493 494class tfe_base <AsmOperandClass mc> : Operand <i1> { 495 let PrintMethod = "printTFE"; 496 let ParserMatchClass = mc; 497} 498 499def tfe : tfe_base <TFEMubufMatchClass>; 500def tfe_flat : tfe_base <TFEFlatMatchClass>; 501def tfe_flat_atomic : tfe_base <TFEFlatAtomicMatchClass>; 502 503def omod : Operand <i32> { 504 let PrintMethod = "printOModSI"; 505 let ParserMatchClass = OModMatchClass; 506} 507 508def ClampMod : Operand <i1> { 509 let PrintMethod = "printClampSI"; 510 let ParserMatchClass = ClampMatchClass; 511} 512 513} // End OperandType = "OPERAND_IMMEDIATE" 514 515def VOPDstS64 : VOPDstOperand <SReg_64>; 516 517//===----------------------------------------------------------------------===// 518// Complex patterns 519//===----------------------------------------------------------------------===// 520 521def DS1Addr1Offset : ComplexPattern<i32, 2, "SelectDS1Addr1Offset">; 522def DS64Bit4ByteAligned : ComplexPattern<i32, 3, "SelectDS64Bit4ByteAligned">; 523 524def MUBUFAddr32 : ComplexPattern<i64, 9, "SelectMUBUFAddr32">; 525def MUBUFAddr64 : ComplexPattern<i64, 7, "SelectMUBUFAddr64">; 526def MUBUFAddr64Atomic : ComplexPattern<i64, 5, "SelectMUBUFAddr64">; 527def MUBUFScratch : ComplexPattern<i64, 4, "SelectMUBUFScratch">; 528def MUBUFOffset : ComplexPattern<i64, 6, "SelectMUBUFOffset">; 529def MUBUFOffsetAtomic : ComplexPattern<i64, 4, "SelectMUBUFOffset">; 530 531def VOP3Mods0 : ComplexPattern<untyped, 4, "SelectVOP3Mods0">; 532def VOP3Mods0Clamp : ComplexPattern<untyped, 3, "SelectVOP3Mods0Clamp">; 533def VOP3Mods0Clamp0OMod : ComplexPattern<untyped, 4, "SelectVOP3Mods0Clamp0OMod">; 534def VOP3Mods : ComplexPattern<untyped, 2, "SelectVOP3Mods">; 535 536//===----------------------------------------------------------------------===// 537// SI assembler operands 538//===----------------------------------------------------------------------===// 539 540def SIOperand { 541 int ZERO = 0x80; 542 int VCC = 0x6A; 543 int FLAT_SCR = 0x68; 544} 545 546def SRCMODS { 547 int NONE = 0; 548 int NEG = 1; 549} 550 551def DSTCLAMP { 552 int NONE = 0; 553} 554 555def DSTOMOD { 556 int NONE = 0; 557} 558 559//===----------------------------------------------------------------------===// 560// 561// SI Instruction multiclass helpers. 562// 563// Instructions with _32 take 32-bit operands. 564// Instructions with _64 take 64-bit operands. 565// 566// VOP_* instructions can use either a 32-bit or 64-bit encoding. The 32-bit 567// encoding is the standard encoding, but instruction that make use of 568// any of the instruction modifiers must use the 64-bit encoding. 569// 570// Instructions with _e32 use the 32-bit encoding. 571// Instructions with _e64 use the 64-bit encoding. 572// 573//===----------------------------------------------------------------------===// 574 575class SIMCInstr <string pseudo, int subtarget> { 576 string PseudoInstr = pseudo; 577 int Subtarget = subtarget; 578} 579 580//===----------------------------------------------------------------------===// 581// EXP classes 582//===----------------------------------------------------------------------===// 583 584class EXPCommon : InstSI< 585 (outs), 586 (ins i32imm:$en, i32imm:$tgt, i32imm:$compr, i32imm:$done, i32imm:$vm, 587 VGPR_32:$src0, VGPR_32:$src1, VGPR_32:$src2, VGPR_32:$src3), 588 "exp $en, $tgt, $compr, $done, $vm, $src0, $src1, $src2, $src3", 589 [] > { 590 591 let EXP_CNT = 1; 592 let Uses = [EXEC]; 593} 594 595multiclass EXP_m { 596 597 let isPseudo = 1, isCodeGenOnly = 1 in { 598 def "" : EXPCommon, SIMCInstr <"exp", SISubtarget.NONE> ; 599 } 600 601 def _si : EXPCommon, SIMCInstr <"exp", SISubtarget.SI>, EXPe; 602 603 def _vi : EXPCommon, SIMCInstr <"exp", SISubtarget.VI>, EXPe_vi; 604} 605 606//===----------------------------------------------------------------------===// 607// Scalar classes 608//===----------------------------------------------------------------------===// 609 610class SOP1_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> : 611 SOP1 <outs, ins, "", pattern>, 612 SIMCInstr<opName, SISubtarget.NONE> { 613 let isPseudo = 1; 614 let isCodeGenOnly = 1; 615} 616 617class SOP1_Real_si <sop1 op, string opName, dag outs, dag ins, string asm> : 618 SOP1 <outs, ins, asm, []>, 619 SOP1e <op.SI>, 620 SIMCInstr<opName, SISubtarget.SI> { 621 let isCodeGenOnly = 0; 622 let AssemblerPredicates = [isSICI]; 623} 624 625class SOP1_Real_vi <sop1 op, string opName, dag outs, dag ins, string asm> : 626 SOP1 <outs, ins, asm, []>, 627 SOP1e <op.VI>, 628 SIMCInstr<opName, SISubtarget.VI> { 629 let isCodeGenOnly = 0; 630 let AssemblerPredicates = [isVI]; 631} 632 633multiclass SOP1_m <sop1 op, string opName, dag outs, dag ins, string asm, 634 list<dag> pattern> { 635 636 def "" : SOP1_Pseudo <opName, outs, ins, pattern>; 637 638 def _si : SOP1_Real_si <op, opName, outs, ins, asm>; 639 640 def _vi : SOP1_Real_vi <op, opName, outs, ins, asm>; 641 642} 643 644multiclass SOP1_32 <sop1 op, string opName, list<dag> pattern> : SOP1_m < 645 op, opName, (outs SReg_32:$dst), (ins SSrc_32:$src0), 646 opName#" $dst, $src0", pattern 647>; 648 649multiclass SOP1_64 <sop1 op, string opName, list<dag> pattern> : SOP1_m < 650 op, opName, (outs SReg_64:$dst), (ins SSrc_64:$src0), 651 opName#" $dst, $src0", pattern 652>; 653 654// no input, 64-bit output. 655multiclass SOP1_64_0 <sop1 op, string opName, list<dag> pattern> { 656 def "" : SOP1_Pseudo <opName, (outs SReg_64:$dst), (ins), pattern>; 657 658 def _si : SOP1_Real_si <op, opName, (outs SReg_64:$dst), (ins), 659 opName#" $dst"> { 660 let ssrc0 = 0; 661 } 662 663 def _vi : SOP1_Real_vi <op, opName, (outs SReg_64:$dst), (ins), 664 opName#" $dst"> { 665 let ssrc0 = 0; 666 } 667} 668 669// 64-bit input, no output 670multiclass SOP1_1 <sop1 op, string opName, list<dag> pattern> { 671 def "" : SOP1_Pseudo <opName, (outs), (ins SReg_64:$src0), pattern>; 672 673 def _si : SOP1_Real_si <op, opName, (outs), (ins SReg_64:$src0), 674 opName#" $src0"> { 675 let sdst = 0; 676 } 677 678 def _vi : SOP1_Real_vi <op, opName, (outs), (ins SReg_64:$src0), 679 opName#" $src0"> { 680 let sdst = 0; 681 } 682} 683 684// 64-bit input, 32-bit output. 685multiclass SOP1_32_64 <sop1 op, string opName, list<dag> pattern> : SOP1_m < 686 op, opName, (outs SReg_32:$dst), (ins SSrc_64:$src0), 687 opName#" $dst, $src0", pattern 688>; 689 690class SOP2_Pseudo<string opName, dag outs, dag ins, list<dag> pattern> : 691 SOP2<outs, ins, "", pattern>, 692 SIMCInstr<opName, SISubtarget.NONE> { 693 let isPseudo = 1; 694 let isCodeGenOnly = 1; 695 let Size = 4; 696 697 // Pseudo instructions have no encodings, but adding this field here allows 698 // us to do: 699 // let sdst = xxx in { 700 // for multiclasses that include both real and pseudo instructions. 701 field bits<7> sdst = 0; 702} 703 704class SOP2_Real_si<sop2 op, string opName, dag outs, dag ins, string asm> : 705 SOP2<outs, ins, asm, []>, 706 SOP2e<op.SI>, 707 SIMCInstr<opName, SISubtarget.SI> { 708 let AssemblerPredicates = [isSICI]; 709} 710 711class SOP2_Real_vi<sop2 op, string opName, dag outs, dag ins, string asm> : 712 SOP2<outs, ins, asm, []>, 713 SOP2e<op.VI>, 714 SIMCInstr<opName, SISubtarget.VI> { 715 let AssemblerPredicates = [isVI]; 716} 717 718multiclass SOP2_SELECT_32 <sop2 op, string opName, list<dag> pattern> { 719 def "" : SOP2_Pseudo <opName, (outs SReg_32:$dst), 720 (ins SSrc_32:$src0, SSrc_32:$src1, SCCReg:$scc), pattern>; 721 722 def _si : SOP2_Real_si <op, opName, (outs SReg_32:$dst), 723 (ins SSrc_32:$src0, SSrc_32:$src1, SCCReg:$scc), 724 opName#" $dst, $src0, $src1 [$scc]">; 725 726 def _vi : SOP2_Real_vi <op, opName, (outs SReg_32:$dst), 727 (ins SSrc_32:$src0, SSrc_32:$src1, SCCReg:$scc), 728 opName#" $dst, $src0, $src1 [$scc]">; 729} 730 731multiclass SOP2_m <sop2 op, string opName, dag outs, dag ins, string asm, 732 list<dag> pattern> { 733 734 def "" : SOP2_Pseudo <opName, outs, ins, pattern>; 735 736 def _si : SOP2_Real_si <op, opName, outs, ins, asm>; 737 738 def _vi : SOP2_Real_vi <op, opName, outs, ins, asm>; 739 740} 741 742multiclass SOP2_32 <sop2 op, string opName, list<dag> pattern> : SOP2_m < 743 op, opName, (outs SReg_32:$dst), (ins SSrc_32:$src0, SSrc_32:$src1), 744 opName#" $dst, $src0, $src1", pattern 745>; 746 747multiclass SOP2_64 <sop2 op, string opName, list<dag> pattern> : SOP2_m < 748 op, opName, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_64:$src1), 749 opName#" $dst, $src0, $src1", pattern 750>; 751 752multiclass SOP2_64_32 <sop2 op, string opName, list<dag> pattern> : SOP2_m < 753 op, opName, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_32:$src1), 754 opName#" $dst, $src0, $src1", pattern 755>; 756 757class SOPC_Helper <bits<7> op, RegisterOperand rc, ValueType vt, 758 string opName, PatLeaf cond> : SOPC < 759 op, (outs SCCReg:$dst), (ins rc:$src0, rc:$src1), 760 opName#" $src0, $src1", []>; 761 762class SOPC_32<bits<7> op, string opName, PatLeaf cond = COND_NULL> 763 : SOPC_Helper<op, SSrc_32, i32, opName, cond>; 764 765class SOPC_64<bits<7> op, string opName, PatLeaf cond = COND_NULL> 766 : SOPC_Helper<op, SSrc_64, i64, opName, cond>; 767 768class SOPK_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> : 769 SOPK <outs, ins, "", pattern>, 770 SIMCInstr<opName, SISubtarget.NONE> { 771 let isPseudo = 1; 772 let isCodeGenOnly = 1; 773} 774 775class SOPK_Real_si <sopk op, string opName, dag outs, dag ins, string asm> : 776 SOPK <outs, ins, asm, []>, 777 SOPKe <op.SI>, 778 SIMCInstr<opName, SISubtarget.SI> { 779 let AssemblerPredicates = [isSICI]; 780 let isCodeGenOnly = 0; 781} 782 783class SOPK_Real_vi <sopk op, string opName, dag outs, dag ins, string asm> : 784 SOPK <outs, ins, asm, []>, 785 SOPKe <op.VI>, 786 SIMCInstr<opName, SISubtarget.VI> { 787 let AssemblerPredicates = [isVI]; 788 let isCodeGenOnly = 0; 789} 790 791multiclass SOPK_m <sopk op, string opName, dag outs, dag ins, string opAsm, 792 string asm = opName#opAsm> { 793 def "" : SOPK_Pseudo <opName, outs, ins, []>; 794 795 def _si : SOPK_Real_si <op, opName, outs, ins, asm>; 796 797 def _vi : SOPK_Real_vi <op, opName, outs, ins, asm>; 798 799} 800 801multiclass SOPK_32 <sopk op, string opName, list<dag> pattern> { 802 def "" : SOPK_Pseudo <opName, (outs SReg_32:$dst), (ins u16imm:$src0), 803 pattern>; 804 805 def _si : SOPK_Real_si <op, opName, (outs SReg_32:$dst), (ins u16imm:$src0), 806 opName#" $dst, $src0">; 807 808 def _vi : SOPK_Real_vi <op, opName, (outs SReg_32:$dst), (ins u16imm:$src0), 809 opName#" $dst, $src0">; 810} 811 812multiclass SOPK_SCC <sopk op, string opName, list<dag> pattern> { 813 def "" : SOPK_Pseudo <opName, (outs SCCReg:$dst), 814 (ins SReg_32:$src0, u16imm:$src1), pattern>; 815 816 let DisableEncoding = "$dst" in { 817 def _si : SOPK_Real_si <op, opName, (outs SCCReg:$dst), 818 (ins SReg_32:$sdst, u16imm:$simm16), opName#" $sdst, $simm16">; 819 820 def _vi : SOPK_Real_vi <op, opName, (outs SCCReg:$dst), 821 (ins SReg_32:$sdst, u16imm:$simm16), opName#" $sdst, $simm16">; 822 } 823} 824 825multiclass SOPK_32TIE <sopk op, string opName, list<dag> pattern> : SOPK_m < 826 op, opName, (outs SReg_32:$sdst), (ins SReg_32:$src0, u16imm:$simm16), 827 " $sdst, $simm16" 828>; 829 830multiclass SOPK_IMM32 <sopk op, string opName, dag outs, dag ins, 831 string argAsm, string asm = opName#argAsm> { 832 833 def "" : SOPK_Pseudo <opName, outs, ins, []>; 834 835 def _si : SOPK <outs, ins, asm, []>, 836 SOPK64e <op.SI>, 837 SIMCInstr<opName, SISubtarget.SI> { 838 let AssemblerPredicates = [isSICI]; 839 let isCodeGenOnly = 0; 840 } 841 842 def _vi : SOPK <outs, ins, asm, []>, 843 SOPK64e <op.VI>, 844 SIMCInstr<opName, SISubtarget.VI> { 845 let AssemblerPredicates = [isVI]; 846 let isCodeGenOnly = 0; 847 } 848} 849//===----------------------------------------------------------------------===// 850// SMRD classes 851//===----------------------------------------------------------------------===// 852 853class SMRD_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> : 854 SMRD <outs, ins, "", pattern>, 855 SIMCInstr<opName, SISubtarget.NONE> { 856 let isPseudo = 1; 857 let isCodeGenOnly = 1; 858} 859 860class SMRD_Real_si <bits<5> op, string opName, bit imm, dag outs, dag ins, 861 string asm> : 862 SMRD <outs, ins, asm, []>, 863 SMRDe <op, imm>, 864 SIMCInstr<opName, SISubtarget.SI> { 865 let AssemblerPredicates = [isSICI]; 866} 867 868class SMRD_Real_vi <bits<8> op, string opName, bit imm, dag outs, dag ins, 869 string asm> : 870 SMRD <outs, ins, asm, []>, 871 SMEMe_vi <op, imm>, 872 SIMCInstr<opName, SISubtarget.VI> { 873 let AssemblerPredicates = [isVI]; 874} 875 876multiclass SMRD_m <bits<5> op, string opName, bit imm, dag outs, dag ins, 877 string asm, list<dag> pattern> { 878 879 def "" : SMRD_Pseudo <opName, outs, ins, pattern>; 880 881 def _si : SMRD_Real_si <op, opName, imm, outs, ins, asm>; 882 883 // glc is only applicable to scalar stores, which are not yet 884 // implemented. 885 let glc = 0 in { 886 def _vi : SMRD_Real_vi <{0, 0, 0, op}, opName, imm, outs, ins, asm>; 887 } 888} 889 890multiclass SMRD_Helper <bits<5> op, string opName, RegisterClass baseClass, 891 RegisterClass dstClass> { 892 defm _IMM : SMRD_m < 893 op, opName#"_IMM", 1, (outs dstClass:$dst), 894 (ins baseClass:$sbase, u32imm:$offset), 895 opName#" $dst, $sbase, $offset", [] 896 >; 897 898 defm _SGPR : SMRD_m < 899 op, opName#"_SGPR", 0, (outs dstClass:$dst), 900 (ins baseClass:$sbase, SReg_32:$soff), 901 opName#" $dst, $sbase, $soff", [] 902 >; 903} 904 905//===----------------------------------------------------------------------===// 906// Vector ALU classes 907//===----------------------------------------------------------------------===// 908 909// This must always be right before the operand being input modified. 910def InputMods : OperandWithDefaultOps <i32, (ops (i32 0))> { 911 let PrintMethod = "printOperandAndMods"; 912} 913 914def InputModsMatchClass : AsmOperandClass { 915 let Name = "RegWithInputMods"; 916} 917 918def InputModsNoDefault : Operand <i32> { 919 let PrintMethod = "printOperandAndMods"; 920 let ParserMatchClass = InputModsMatchClass; 921} 922 923class getNumSrcArgs<ValueType Src1, ValueType Src2> { 924 int ret = 925 !if (!eq(Src1.Value, untyped.Value), 1, // VOP1 926 !if (!eq(Src2.Value, untyped.Value), 2, // VOP2 927 3)); // VOP3 928} 929 930// Returns the register class to use for the destination of VOP[123C] 931// instructions for the given VT. 932class getVALUDstForVT<ValueType VT> { 933 RegisterOperand ret = !if(!eq(VT.Size, 32), VOPDstOperand<VGPR_32>, 934 !if(!eq(VT.Size, 64), VOPDstOperand<VReg_64>, 935 VOPDstOperand<SReg_64>)); // else VT == i1 936} 937 938// Returns the register class to use for source 0 of VOP[12C] 939// instructions for the given VT. 940class getVOPSrc0ForVT<ValueType VT> { 941 RegisterOperand ret = !if(!eq(VT.Size, 32), VSrc_32, VSrc_64); 942} 943 944// Returns the register class to use for source 1 of VOP[12C] for the 945// given VT. 946class getVOPSrc1ForVT<ValueType VT> { 947 RegisterClass ret = !if(!eq(VT.Size, 32), VGPR_32, VReg_64); 948} 949 950// Returns the register class to use for sources of VOP3 instructions for the 951// given VT. 952class getVOP3SrcForVT<ValueType VT> { 953 RegisterOperand ret = !if(!eq(VT.Size, 32), VCSrc_32, VCSrc_64); 954} 955 956// Returns 1 if the source arguments have modifiers, 0 if they do not. 957class hasModifiers<ValueType SrcVT> { 958 bit ret = !if(!eq(SrcVT.Value, f32.Value), 1, 959 !if(!eq(SrcVT.Value, f64.Value), 1, 0)); 960} 961 962// Returns the input arguments for VOP[12C] instructions for the given SrcVT. 963class getIns32 <RegisterOperand Src0RC, RegisterClass Src1RC, int NumSrcArgs> { 964 dag ret = !if(!eq(NumSrcArgs, 1), (ins Src0RC:$src0), // VOP1 965 !if(!eq(NumSrcArgs, 2), (ins Src0RC:$src0, Src1RC:$src1), // VOP2 966 (ins))); 967} 968 969// Returns the input arguments for VOP3 instructions for the given SrcVT. 970class getIns64 <RegisterOperand Src0RC, RegisterOperand Src1RC, 971 RegisterOperand Src2RC, int NumSrcArgs, 972 bit HasModifiers> { 973 974 dag ret = 975 !if (!eq(NumSrcArgs, 1), 976 !if (!eq(HasModifiers, 1), 977 // VOP1 with modifiers 978 (ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0, 979 ClampMod:$clamp, omod:$omod) 980 /* else */, 981 // VOP1 without modifiers 982 (ins Src0RC:$src0) 983 /* endif */ ), 984 !if (!eq(NumSrcArgs, 2), 985 !if (!eq(HasModifiers, 1), 986 // VOP 2 with modifiers 987 (ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0, 988 InputModsNoDefault:$src1_modifiers, Src1RC:$src1, 989 ClampMod:$clamp, omod:$omod) 990 /* else */, 991 // VOP2 without modifiers 992 (ins Src0RC:$src0, Src1RC:$src1) 993 /* endif */ ) 994 /* NumSrcArgs == 3 */, 995 !if (!eq(HasModifiers, 1), 996 // VOP3 with modifiers 997 (ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0, 998 InputModsNoDefault:$src1_modifiers, Src1RC:$src1, 999 InputModsNoDefault:$src2_modifiers, Src2RC:$src2, 1000 ClampMod:$clamp, omod:$omod) 1001 /* else */, 1002 // VOP3 without modifiers 1003 (ins Src0RC:$src0, Src1RC:$src1, Src2RC:$src2) 1004 /* endif */ ))); 1005} 1006 1007// Returns the assembly string for the inputs and outputs of a VOP[12C] 1008// instruction. This does not add the _e32 suffix, so it can be reused 1009// by getAsm64. 1010class getAsm32 <int NumSrcArgs> { 1011 string src1 = ", $src1"; 1012 string src2 = ", $src2"; 1013 string ret = "$dst, $src0"# 1014 !if(!eq(NumSrcArgs, 1), "", src1)# 1015 !if(!eq(NumSrcArgs, 3), src2, ""); 1016} 1017 1018// Returns the assembly string for the inputs and outputs of a VOP3 1019// instruction. 1020class getAsm64 <int NumSrcArgs, bit HasModifiers> { 1021 string src0 = !if(!eq(NumSrcArgs, 1), "$src0_modifiers", "$src0_modifiers,"); 1022 string src1 = !if(!eq(NumSrcArgs, 1), "", 1023 !if(!eq(NumSrcArgs, 2), " $src1_modifiers", 1024 " $src1_modifiers,")); 1025 string src2 = !if(!eq(NumSrcArgs, 3), " $src2_modifiers", ""); 1026 string ret = 1027 !if(!eq(HasModifiers, 0), 1028 getAsm32<NumSrcArgs>.ret, 1029 "$dst, "#src0#src1#src2#"$clamp"#"$omod"); 1030} 1031 1032 1033class VOPProfile <list<ValueType> _ArgVT> { 1034 1035 field list<ValueType> ArgVT = _ArgVT; 1036 1037 field ValueType DstVT = ArgVT[0]; 1038 field ValueType Src0VT = ArgVT[1]; 1039 field ValueType Src1VT = ArgVT[2]; 1040 field ValueType Src2VT = ArgVT[3]; 1041 field RegisterOperand DstRC = getVALUDstForVT<DstVT>.ret; 1042 field RegisterOperand Src0RC32 = getVOPSrc0ForVT<Src0VT>.ret; 1043 field RegisterClass Src1RC32 = getVOPSrc1ForVT<Src1VT>.ret; 1044 field RegisterOperand Src0RC64 = getVOP3SrcForVT<Src0VT>.ret; 1045 field RegisterOperand Src1RC64 = getVOP3SrcForVT<Src1VT>.ret; 1046 field RegisterOperand Src2RC64 = getVOP3SrcForVT<Src2VT>.ret; 1047 1048 field int NumSrcArgs = getNumSrcArgs<Src1VT, Src2VT>.ret; 1049 field bit HasModifiers = hasModifiers<Src0VT>.ret; 1050 1051 field dag Outs = (outs DstRC:$dst); 1052 1053 field dag Ins32 = getIns32<Src0RC32, Src1RC32, NumSrcArgs>.ret; 1054 field dag Ins64 = getIns64<Src0RC64, Src1RC64, Src2RC64, NumSrcArgs, 1055 HasModifiers>.ret; 1056 1057 field string Asm32 = getAsm32<NumSrcArgs>.ret; 1058 field string Asm64 = getAsm64<NumSrcArgs, HasModifiers>.ret; 1059} 1060 1061// FIXME: I think these F16/I16 profiles will need to use f16/i16 types in order 1062// for the instruction patterns to work. 1063def VOP_F16_F16 : VOPProfile <[f32, f32, untyped, untyped]>; 1064def VOP_F16_I16 : VOPProfile <[f32, i32, untyped, untyped]>; 1065def VOP_I16_F16 : VOPProfile <[i32, f32, untyped, untyped]>; 1066 1067def VOP_F16_F16_F16 : VOPProfile <[f32, f32, f32, untyped]>; 1068def VOP_F16_F16_I16 : VOPProfile <[f32, f32, i32, untyped]>; 1069def VOP_I16_I16_I16 : VOPProfile <[i32, i32, i32, untyped]>; 1070 1071def VOP_F32_F32 : VOPProfile <[f32, f32, untyped, untyped]>; 1072def VOP_F32_F64 : VOPProfile <[f32, f64, untyped, untyped]>; 1073def VOP_F32_I32 : VOPProfile <[f32, i32, untyped, untyped]>; 1074def VOP_F64_F32 : VOPProfile <[f64, f32, untyped, untyped]>; 1075def VOP_F64_F64 : VOPProfile <[f64, f64, untyped, untyped]>; 1076def VOP_F64_I32 : VOPProfile <[f64, i32, untyped, untyped]>; 1077def VOP_I32_F32 : VOPProfile <[i32, f32, untyped, untyped]>; 1078def VOP_I32_F64 : VOPProfile <[i32, f64, untyped, untyped]>; 1079def VOP_I32_I32 : VOPProfile <[i32, i32, untyped, untyped]>; 1080 1081def VOP_F32_F32_F32 : VOPProfile <[f32, f32, f32, untyped]>; 1082def VOP_F32_F32_I32 : VOPProfile <[f32, f32, i32, untyped]>; 1083def VOP_F64_F64_F64 : VOPProfile <[f64, f64, f64, untyped]>; 1084def VOP_F64_F64_I32 : VOPProfile <[f64, f64, i32, untyped]>; 1085def VOP_I32_F32_F32 : VOPProfile <[i32, f32, f32, untyped]>; 1086def VOP_I32_F32_I32 : VOPProfile <[i32, f32, i32, untyped]>; 1087def VOP_I32_I32_I32 : VOPProfile <[i32, i32, i32, untyped]>; 1088def VOP_I32_I32_I32_VCC : VOPProfile <[i32, i32, i32, untyped]> { 1089 let Src0RC32 = VCSrc_32; 1090} 1091 1092def VOP_I1_F32_I32 : VOPProfile <[i1, f32, i32, untyped]> { 1093 let Ins64 = (ins InputModsNoDefault:$src0_modifiers, Src0RC64:$src0, Src1RC64:$src1); 1094 let Asm64 = "$dst, $src0_modifiers, $src1"; 1095} 1096 1097def VOP_I1_F64_I32 : VOPProfile <[i1, f64, i32, untyped]> { 1098 let Ins64 = (ins InputModsNoDefault:$src0_modifiers, Src0RC64:$src0, Src1RC64:$src1); 1099 let Asm64 = "$dst, $src0_modifiers, $src1"; 1100} 1101 1102def VOP_I64_I64_I32 : VOPProfile <[i64, i64, i32, untyped]>; 1103def VOP_I64_I32_I64 : VOPProfile <[i64, i32, i64, untyped]>; 1104def VOP_I64_I64_I64 : VOPProfile <[i64, i64, i64, untyped]>; 1105def VOP_CNDMASK : VOPProfile <[i32, i32, i32, untyped]> { 1106 let Ins32 = (ins Src0RC32:$src0, Src1RC32:$src1, VCCReg:$src2); 1107 let Ins64 = (ins Src0RC64:$src0, Src1RC64:$src1, SSrc_64:$src2); 1108 let Asm64 = "$dst, $src0, $src1, $src2"; 1109} 1110 1111def VOP_F32_F32_F32_F32 : VOPProfile <[f32, f32, f32, f32]>; 1112def VOP_MADK : VOPProfile <[f32, f32, f32, f32]> { 1113 field dag Ins = (ins VCSrc_32:$src0, VGPR_32:$vsrc1, u32imm:$src2); 1114 field string Asm = "$dst, $src0, $vsrc1, $src2"; 1115} 1116def VOP_F64_F64_F64_F64 : VOPProfile <[f64, f64, f64, f64]>; 1117def VOP_I32_I32_I32_I32 : VOPProfile <[i32, i32, i32, i32]>; 1118def VOP_I64_I32_I32_I64 : VOPProfile <[i64, i32, i32, i64]>; 1119 1120 1121class VOP <string opName> { 1122 string OpName = opName; 1123} 1124 1125class VOP2_REV <string revOp, bit isOrig> { 1126 string RevOp = revOp; 1127 bit IsOrig = isOrig; 1128} 1129 1130class AtomicNoRet <string noRetOp, bit isRet> { 1131 string NoRetOp = noRetOp; 1132 bit IsRet = isRet; 1133} 1134 1135class VOP1_Pseudo <dag outs, dag ins, list<dag> pattern, string opName> : 1136 VOP1Common <outs, ins, "", pattern>, 1137 VOP <opName>, 1138 SIMCInstr <opName#"_e32", SISubtarget.NONE>, 1139 MnemonicAlias<opName#"_e32", opName> { 1140 let isPseudo = 1; 1141 let isCodeGenOnly = 1; 1142 1143 field bits<8> vdst; 1144 field bits<9> src0; 1145} 1146 1147class VOP1_Real_si <string opName, vop1 op, dag outs, dag ins, string asm> : 1148 VOP1<op.SI, outs, ins, asm, []>, 1149 SIMCInstr <opName#"_e32", SISubtarget.SI> { 1150 let AssemblerPredicate = SIAssemblerPredicate; 1151} 1152 1153class VOP1_Real_vi <string opName, vop1 op, dag outs, dag ins, string asm> : 1154 VOP1<op.VI, outs, ins, asm, []>, 1155 SIMCInstr <opName#"_e32", SISubtarget.VI> { 1156 let AssemblerPredicates = [isVI]; 1157} 1158 1159multiclass VOP1_m <vop1 op, dag outs, dag ins, string asm, list<dag> pattern, 1160 string opName> { 1161 def "" : VOP1_Pseudo <outs, ins, pattern, opName>; 1162 1163 def _si : VOP1_Real_si <opName, op, outs, ins, asm>; 1164 1165 def _vi : VOP1_Real_vi <opName, op, outs, ins, asm>; 1166} 1167 1168multiclass VOP1SI_m <vop1 op, dag outs, dag ins, string asm, list<dag> pattern, 1169 string opName> { 1170 def "" : VOP1_Pseudo <outs, ins, pattern, opName>; 1171 1172 def _si : VOP1_Real_si <opName, op, outs, ins, asm>; 1173} 1174 1175class VOP2_Pseudo <dag outs, dag ins, list<dag> pattern, string opName> : 1176 VOP2Common <outs, ins, "", pattern>, 1177 VOP <opName>, 1178 SIMCInstr<opName#"_e32", SISubtarget.NONE>, 1179 MnemonicAlias<opName#"_e32", opName> { 1180 let isPseudo = 1; 1181 let isCodeGenOnly = 1; 1182} 1183 1184class VOP2_Real_si <string opName, vop2 op, dag outs, dag ins, string asm> : 1185 VOP2 <op.SI, outs, ins, opName#asm, []>, 1186 SIMCInstr <opName#"_e32", SISubtarget.SI> { 1187 let AssemblerPredicates = [isSICI]; 1188} 1189 1190class VOP2_Real_vi <string opName, vop2 op, dag outs, dag ins, string asm> : 1191 VOP2 <op.VI, outs, ins, opName#asm, []>, 1192 SIMCInstr <opName#"_e32", SISubtarget.VI> { 1193 let AssemblerPredicates = [isVI]; 1194} 1195 1196multiclass VOP2SI_m <vop2 op, dag outs, dag ins, string asm, list<dag> pattern, 1197 string opName, string revOp> { 1198 def "" : VOP2_Pseudo <outs, ins, pattern, opName>, 1199 VOP2_REV<revOp#"_e32", !eq(revOp, opName)>; 1200 1201 def _si : VOP2_Real_si <opName, op, outs, ins, asm>; 1202} 1203 1204multiclass VOP2_m <vop2 op, dag outs, dag ins, string asm, list<dag> pattern, 1205 string opName, string revOp> { 1206 def "" : VOP2_Pseudo <outs, ins, pattern, opName>, 1207 VOP2_REV<revOp#"_e32", !eq(revOp, opName)>; 1208 1209 def _si : VOP2_Real_si <opName, op, outs, ins, asm>; 1210 1211 def _vi : VOP2_Real_vi <opName, op, outs, ins, asm>; 1212 1213} 1214 1215class VOP3DisableFields <bit HasSrc1, bit HasSrc2, bit HasModifiers> { 1216 1217 bits<2> src0_modifiers = !if(HasModifiers, ?, 0); 1218 bits<2> src1_modifiers = !if(HasModifiers, !if(HasSrc1, ?, 0), 0); 1219 bits<2> src2_modifiers = !if(HasModifiers, !if(HasSrc2, ?, 0), 0); 1220 bits<2> omod = !if(HasModifiers, ?, 0); 1221 bits<1> clamp = !if(HasModifiers, ?, 0); 1222 bits<9> src1 = !if(HasSrc1, ?, 0); 1223 bits<9> src2 = !if(HasSrc2, ?, 0); 1224} 1225 1226class VOP3DisableModFields <bit HasSrc0Mods, 1227 bit HasSrc1Mods = 0, 1228 bit HasSrc2Mods = 0, 1229 bit HasOutputMods = 0> { 1230 bits<2> src0_modifiers = !if(HasSrc0Mods, ?, 0); 1231 bits<2> src1_modifiers = !if(HasSrc1Mods, ?, 0); 1232 bits<2> src2_modifiers = !if(HasSrc2Mods, ?, 0); 1233 bits<2> omod = !if(HasOutputMods, ?, 0); 1234 bits<1> clamp = !if(HasOutputMods, ?, 0); 1235} 1236 1237class VOP3_Pseudo <dag outs, dag ins, list<dag> pattern, string opName> : 1238 VOP3Common <outs, ins, "", pattern>, 1239 VOP <opName>, 1240 SIMCInstr<opName#"_e64", SISubtarget.NONE>, 1241 MnemonicAlias<opName#"_e64", opName> { 1242 let isPseudo = 1; 1243 let isCodeGenOnly = 1; 1244} 1245 1246class VOP3_Real_si <bits<9> op, dag outs, dag ins, string asm, string opName> : 1247 VOP3Common <outs, ins, asm, []>, 1248 VOP3e <op>, 1249 SIMCInstr<opName#"_e64", SISubtarget.SI> { 1250 let AssemblerPredicates = [isSICI]; 1251} 1252 1253class VOP3_Real_vi <bits<10> op, dag outs, dag ins, string asm, string opName> : 1254 VOP3Common <outs, ins, asm, []>, 1255 VOP3e_vi <op>, 1256 SIMCInstr <opName#"_e64", SISubtarget.VI> { 1257 let AssemblerPredicates = [isVI]; 1258} 1259 1260class VOP3b_Real_si <bits<9> op, dag outs, dag ins, string asm, string opName> : 1261 VOP3Common <outs, ins, asm, []>, 1262 VOP3be <op>, 1263 SIMCInstr<opName#"_e64", SISubtarget.SI> { 1264 let AssemblerPredicates = [isSICI]; 1265} 1266 1267class VOP3b_Real_vi <bits<10> op, dag outs, dag ins, string asm, string opName> : 1268 VOP3Common <outs, ins, asm, []>, 1269 VOP3be_vi <op>, 1270 SIMCInstr <opName#"_e64", SISubtarget.VI> { 1271 let AssemblerPredicates = [isVI]; 1272} 1273 1274multiclass VOP3_m <vop op, dag outs, dag ins, string asm, list<dag> pattern, 1275 string opName, int NumSrcArgs, bit HasMods = 1> { 1276 1277 def "" : VOP3_Pseudo <outs, ins, pattern, opName>; 1278 1279 def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>, 1280 VOP3DisableFields<!if(!eq(NumSrcArgs, 1), 0, 1), 1281 !if(!eq(NumSrcArgs, 2), 0, 1), 1282 HasMods>; 1283 def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName>, 1284 VOP3DisableFields<!if(!eq(NumSrcArgs, 1), 0, 1), 1285 !if(!eq(NumSrcArgs, 2), 0, 1), 1286 HasMods>; 1287} 1288 1289// VOP3_m without source modifiers 1290multiclass VOP3_m_nomods <vop op, dag outs, dag ins, string asm, list<dag> pattern, 1291 string opName, int NumSrcArgs, bit HasMods = 1> { 1292 1293 def "" : VOP3_Pseudo <outs, ins, pattern, opName>; 1294 1295 let src0_modifiers = 0, 1296 src1_modifiers = 0, 1297 src2_modifiers = 0, 1298 clamp = 0, 1299 omod = 0 in { 1300 def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>; 1301 def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName>; 1302 } 1303} 1304 1305multiclass VOP3_1_m <vop op, dag outs, dag ins, string asm, 1306 list<dag> pattern, string opName, bit HasMods = 1> { 1307 1308 def "" : VOP3_Pseudo <outs, ins, pattern, opName>; 1309 1310 def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>, 1311 VOP3DisableFields<0, 0, HasMods>; 1312 1313 def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName>, 1314 VOP3DisableFields<0, 0, HasMods>; 1315} 1316 1317multiclass VOP3SI_1_m <vop op, dag outs, dag ins, string asm, 1318 list<dag> pattern, string opName, bit HasMods = 1> { 1319 1320 def "" : VOP3_Pseudo <outs, ins, pattern, opName>; 1321 1322 def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>, 1323 VOP3DisableFields<0, 0, HasMods>; 1324 // No VI instruction. This class is for SI only. 1325} 1326 1327multiclass VOP3_2_m <vop op, dag outs, dag ins, string asm, 1328 list<dag> pattern, string opName, string revOp, 1329 bit HasMods = 1, bit UseFullOp = 0> { 1330 1331 def "" : VOP3_Pseudo <outs, ins, pattern, opName>, 1332 VOP2_REV<revOp#"_e64", !eq(revOp, opName)>; 1333 1334 def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>, 1335 VOP3DisableFields<1, 0, HasMods>; 1336 1337 def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName>, 1338 VOP3DisableFields<1, 0, HasMods>; 1339} 1340 1341multiclass VOP3SI_2_m <vop op, dag outs, dag ins, string asm, 1342 list<dag> pattern, string opName, string revOp, 1343 bit HasMods = 1, bit UseFullOp = 0> { 1344 1345 def "" : VOP3_Pseudo <outs, ins, pattern, opName>, 1346 VOP2_REV<revOp#"_e64", !eq(revOp, opName)>; 1347 1348 def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>, 1349 VOP3DisableFields<1, 0, HasMods>; 1350 1351 // No VI instruction. This class is for SI only. 1352} 1353 1354// XXX - Is v_div_scale_{f32|f64} only available in vop3b without 1355// option of implicit vcc use? 1356multiclass VOP3b_2_m <vop op, dag outs, dag ins, string asm, 1357 list<dag> pattern, string opName, string revOp, 1358 bit HasMods = 1, bit UseFullOp = 0> { 1359 def "" : VOP3_Pseudo <outs, ins, pattern, opName>, 1360 VOP2_REV<revOp#"_e64", !eq(revOp, opName)>; 1361 1362 // The VOP2 variant puts the carry out into VCC, the VOP3 variant 1363 // can write it into any SGPR. We currently don't use the carry out, 1364 // so for now hardcode it to VCC as well. 1365 let sdst = SIOperand.VCC, Defs = [VCC] in { 1366 def _si : VOP3b_Real_si <op.SI3, outs, ins, asm, opName>, 1367 VOP3DisableFields<1, 0, HasMods>; 1368 1369 def _vi : VOP3b_Real_vi <op.VI3, outs, ins, asm, opName>, 1370 VOP3DisableFields<1, 0, HasMods>; 1371 } // End sdst = SIOperand.VCC, Defs = [VCC] 1372} 1373 1374multiclass VOP3b_3_m <vop op, dag outs, dag ins, string asm, 1375 list<dag> pattern, string opName, string revOp, 1376 bit HasMods = 1, bit UseFullOp = 0> { 1377 def "" : VOP3_Pseudo <outs, ins, pattern, opName>; 1378 1379 1380 def _si : VOP3b_Real_si <op.SI3, outs, ins, asm, opName>, 1381 VOP3DisableFields<1, 1, HasMods>; 1382 1383 def _vi : VOP3b_Real_vi <op.VI3, outs, ins, asm, opName>, 1384 VOP3DisableFields<1, 1, HasMods>; 1385} 1386 1387multiclass VOP3_C_m <vop op, dag outs, dag ins, string asm, 1388 list<dag> pattern, string opName, 1389 bit HasMods, bit defExec, string revOp> { 1390 1391 def "" : VOP3_Pseudo <outs, ins, pattern, opName>, 1392 VOP2_REV<revOp#"_e64", !eq(revOp, opName)>; 1393 1394 def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>, 1395 VOP3DisableFields<1, 0, HasMods> { 1396 let Defs = !if(defExec, [EXEC], []); 1397 } 1398 1399 def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName>, 1400 VOP3DisableFields<1, 0, HasMods> { 1401 let Defs = !if(defExec, [EXEC], []); 1402 } 1403} 1404 1405// An instruction that is VOP2 on SI and VOP3 on VI, no modifiers. 1406multiclass VOP2SI_3VI_m <vop3 op, string opName, dag outs, dag ins, 1407 string asm, list<dag> pattern = []> { 1408 let isPseudo = 1, isCodeGenOnly = 1 in { 1409 def "" : VOPAnyCommon <outs, ins, "", pattern>, 1410 SIMCInstr<opName, SISubtarget.NONE>; 1411 } 1412 1413 def _si : VOP2 <op.SI3{5-0}, outs, ins, asm, []>, 1414 SIMCInstr <opName, SISubtarget.SI> { 1415 let AssemblerPredicates = [isSICI]; 1416 } 1417 1418 def _vi : VOP3Common <outs, ins, asm, []>, 1419 VOP3e_vi <op.VI3>, 1420 VOP3DisableFields <1, 0, 0>, 1421 SIMCInstr <opName, SISubtarget.VI> { 1422 let AssemblerPredicates = [isVI]; 1423 } 1424} 1425 1426multiclass VOP1_Helper <vop1 op, string opName, dag outs, 1427 dag ins32, string asm32, list<dag> pat32, 1428 dag ins64, string asm64, list<dag> pat64, 1429 bit HasMods> { 1430 1431 defm _e32 : VOP1_m <op, outs, ins32, opName#asm32, pat32, opName>; 1432 1433 defm _e64 : VOP3_1_m <op, outs, ins64, opName#asm64, pat64, opName, HasMods>; 1434} 1435 1436multiclass VOP1Inst <vop1 op, string opName, VOPProfile P, 1437 SDPatternOperator node = null_frag> : VOP1_Helper < 1438 op, opName, P.Outs, 1439 P.Ins32, P.Asm32, [], 1440 P.Ins64, P.Asm64, 1441 !if(P.HasModifiers, 1442 [(set P.DstVT:$dst, (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, 1443 i32:$src0_modifiers, i1:$clamp, i32:$omod))))], 1444 [(set P.DstVT:$dst, (node P.Src0VT:$src0))]), 1445 P.HasModifiers 1446>; 1447 1448multiclass VOP1InstSI <vop1 op, string opName, VOPProfile P, 1449 SDPatternOperator node = null_frag> { 1450 1451 defm _e32 : VOP1SI_m <op, P.Outs, P.Ins32, opName#P.Asm32, [], opName>; 1452 1453 defm _e64 : VOP3SI_1_m <op, P.Outs, P.Ins64, opName#P.Asm64, 1454 !if(P.HasModifiers, 1455 [(set P.DstVT:$dst, (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, 1456 i32:$src0_modifiers, i1:$clamp, i32:$omod))))], 1457 [(set P.DstVT:$dst, (node P.Src0VT:$src0))]), 1458 opName, P.HasModifiers>; 1459} 1460 1461multiclass VOP2_Helper <vop2 op, string opName, dag outs, 1462 dag ins32, string asm32, list<dag> pat32, 1463 dag ins64, string asm64, list<dag> pat64, 1464 string revOp, bit HasMods> { 1465 defm _e32 : VOP2_m <op, outs, ins32, asm32, pat32, opName, revOp>; 1466 1467 defm _e64 : VOP3_2_m <op, 1468 outs, ins64, opName#asm64, pat64, opName, revOp, HasMods 1469 >; 1470} 1471 1472multiclass VOP2Inst <vop2 op, string opName, VOPProfile P, 1473 SDPatternOperator node = null_frag, 1474 string revOp = opName> : VOP2_Helper < 1475 op, opName, P.Outs, 1476 P.Ins32, P.Asm32, [], 1477 P.Ins64, P.Asm64, 1478 !if(P.HasModifiers, 1479 [(set P.DstVT:$dst, 1480 (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, 1481 i1:$clamp, i32:$omod)), 1482 (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))], 1483 [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1))]), 1484 revOp, P.HasModifiers 1485>; 1486 1487multiclass VOP2InstSI <vop2 op, string opName, VOPProfile P, 1488 SDPatternOperator node = null_frag, 1489 string revOp = opName> { 1490 defm _e32 : VOP2SI_m <op, P.Outs, P.Ins32, P.Asm32, [], opName, revOp>; 1491 1492 defm _e64 : VOP3SI_2_m <op, P.Outs, P.Ins64, opName#P.Asm64, 1493 !if(P.HasModifiers, 1494 [(set P.DstVT:$dst, 1495 (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, 1496 i1:$clamp, i32:$omod)), 1497 (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))], 1498 [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1))]), 1499 opName, revOp, P.HasModifiers>; 1500} 1501 1502multiclass VOP2b_Helper <vop2 op, string opName, dag outs, 1503 dag ins32, string asm32, list<dag> pat32, 1504 dag ins64, string asm64, list<dag> pat64, 1505 string revOp, bit HasMods> { 1506 1507 defm _e32 : VOP2_m <op, outs, ins32, asm32, pat32, opName, revOp>; 1508 1509 defm _e64 : VOP3b_2_m <op, 1510 outs, ins64, opName#asm64, pat64, opName, revOp, HasMods 1511 >; 1512} 1513 1514multiclass VOP2bInst <vop2 op, string opName, VOPProfile P, 1515 SDPatternOperator node = null_frag, 1516 string revOp = opName> : VOP2b_Helper < 1517 op, opName, P.Outs, 1518 P.Ins32, P.Asm32, [], 1519 P.Ins64, P.Asm64, 1520 !if(P.HasModifiers, 1521 [(set P.DstVT:$dst, 1522 (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, 1523 i1:$clamp, i32:$omod)), 1524 (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))], 1525 [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1))]), 1526 revOp, P.HasModifiers 1527>; 1528 1529// A VOP2 instruction that is VOP3-only on VI. 1530multiclass VOP2_VI3_Helper <vop23 op, string opName, dag outs, 1531 dag ins32, string asm32, list<dag> pat32, 1532 dag ins64, string asm64, list<dag> pat64, 1533 string revOp, bit HasMods> { 1534 defm _e32 : VOP2SI_m <op, outs, ins32, asm32, pat32, opName, revOp>; 1535 1536 defm _e64 : VOP3_2_m <op, outs, ins64, opName#asm64, pat64, opName, 1537 revOp, HasMods>; 1538} 1539 1540multiclass VOP2_VI3_Inst <vop23 op, string opName, VOPProfile P, 1541 SDPatternOperator node = null_frag, 1542 string revOp = opName> 1543 : VOP2_VI3_Helper < 1544 op, opName, P.Outs, 1545 P.Ins32, P.Asm32, [], 1546 P.Ins64, P.Asm64, 1547 !if(P.HasModifiers, 1548 [(set P.DstVT:$dst, 1549 (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, 1550 i1:$clamp, i32:$omod)), 1551 (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))], 1552 [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1))]), 1553 revOp, P.HasModifiers 1554>; 1555 1556multiclass VOP2MADK <vop2 op, string opName, list<dag> pattern = []> { 1557 1558 def "" : VOP2_Pseudo <VOP_MADK.Outs, VOP_MADK.Ins, pattern, opName>; 1559 1560let isCodeGenOnly = 0 in { 1561 def _si : VOP2Common <VOP_MADK.Outs, VOP_MADK.Ins, 1562 !strconcat(opName, VOP_MADK.Asm), []>, 1563 SIMCInstr <opName#"_e32", SISubtarget.SI>, 1564 VOP2_MADKe <op.SI> { 1565 let AssemblerPredicates = [isSICI]; 1566 } 1567 1568 def _vi : VOP2Common <VOP_MADK.Outs, VOP_MADK.Ins, 1569 !strconcat(opName, VOP_MADK.Asm), []>, 1570 SIMCInstr <opName#"_e32", SISubtarget.VI>, 1571 VOP2_MADKe <op.VI> { 1572 let AssemblerPredicates = [isVI]; 1573 } 1574} // End isCodeGenOnly = 0 1575} 1576 1577class VOPC_Pseudo <dag outs, dag ins, list<dag> pattern, string opName> : 1578 VOPCCommon <ins, "", pattern>, 1579 VOP <opName>, 1580 SIMCInstr<opName#"_e32", SISubtarget.NONE>, 1581 MnemonicAlias<opName#"_e32", opName> { 1582 let isPseudo = 1; 1583 let isCodeGenOnly = 1; 1584} 1585 1586multiclass VOPC_m <vopc op, dag outs, dag ins, string asm, list<dag> pattern, 1587 string opName, bit DefExec, string revOpName = ""> { 1588 def "" : VOPC_Pseudo <outs, ins, pattern, opName>; 1589 1590 def _si : VOPC<op.SI, ins, asm, []>, 1591 SIMCInstr <opName#"_e32", SISubtarget.SI> { 1592 let Defs = !if(DefExec, [EXEC], []); 1593 let hasSideEffects = DefExec; 1594 } 1595 1596 def _vi : VOPC<op.VI, ins, asm, []>, 1597 SIMCInstr <opName#"_e32", SISubtarget.VI> { 1598 let Defs = !if(DefExec, [EXEC], []); 1599 let hasSideEffects = DefExec; 1600 } 1601} 1602 1603multiclass VOPC_Helper <vopc op, string opName, 1604 dag ins32, string asm32, list<dag> pat32, 1605 dag out64, dag ins64, string asm64, list<dag> pat64, 1606 bit HasMods, bit DefExec, string revOp> { 1607 defm _e32 : VOPC_m <op, (outs), ins32, opName#asm32, pat32, opName, DefExec>; 1608 1609 defm _e64 : VOP3_C_m <op, out64, ins64, opName#asm64, pat64, 1610 opName, HasMods, DefExec, revOp>; 1611} 1612 1613// Special case for class instructions which only have modifiers on 1614// the 1st source operand. 1615multiclass VOPC_Class_Helper <vopc op, string opName, 1616 dag ins32, string asm32, list<dag> pat32, 1617 dag out64, dag ins64, string asm64, list<dag> pat64, 1618 bit HasMods, bit DefExec, string revOp> { 1619 defm _e32 : VOPC_m <op, (outs), ins32, opName#asm32, pat32, opName, DefExec>; 1620 1621 defm _e64 : VOP3_C_m <op, out64, ins64, opName#asm64, pat64, 1622 opName, HasMods, DefExec, revOp>, 1623 VOP3DisableModFields<1, 0, 0>; 1624} 1625 1626multiclass VOPCInst <vopc op, string opName, 1627 VOPProfile P, PatLeaf cond = COND_NULL, 1628 string revOp = opName, 1629 bit DefExec = 0> : VOPC_Helper < 1630 op, opName, 1631 P.Ins32, P.Asm32, [], 1632 (outs VOPDstS64:$dst), P.Ins64, P.Asm64, 1633 !if(P.HasModifiers, 1634 [(set i1:$dst, 1635 (setcc (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, 1636 i1:$clamp, i32:$omod)), 1637 (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)), 1638 cond))], 1639 [(set i1:$dst, (setcc P.Src0VT:$src0, P.Src1VT:$src1, cond))]), 1640 P.HasModifiers, DefExec, revOp 1641>; 1642 1643multiclass VOPCClassInst <vopc op, string opName, VOPProfile P, 1644 bit DefExec = 0> : VOPC_Class_Helper < 1645 op, opName, 1646 P.Ins32, P.Asm32, [], 1647 (outs VOPDstS64:$dst), P.Ins64, P.Asm64, 1648 !if(P.HasModifiers, 1649 [(set i1:$dst, 1650 (AMDGPUfp_class (P.Src0VT (VOP3Mods0Clamp0OMod P.Src0VT:$src0, i32:$src0_modifiers)), P.Src1VT:$src1))], 1651 [(set i1:$dst, (AMDGPUfp_class P.Src0VT:$src0, P.Src1VT:$src1))]), 1652 P.HasModifiers, DefExec, opName 1653>; 1654 1655 1656multiclass VOPC_F32 <vopc op, string opName, PatLeaf cond = COND_NULL, string revOp = opName> : 1657 VOPCInst <op, opName, VOP_F32_F32_F32, cond, revOp>; 1658 1659multiclass VOPC_F64 <vopc op, string opName, PatLeaf cond = COND_NULL, string revOp = opName> : 1660 VOPCInst <op, opName, VOP_F64_F64_F64, cond, revOp>; 1661 1662multiclass VOPC_I32 <vopc op, string opName, PatLeaf cond = COND_NULL, string revOp = opName> : 1663 VOPCInst <op, opName, VOP_I32_I32_I32, cond, revOp>; 1664 1665multiclass VOPC_I64 <vopc op, string opName, PatLeaf cond = COND_NULL, string revOp = opName> : 1666 VOPCInst <op, opName, VOP_I64_I64_I64, cond, revOp>; 1667 1668 1669multiclass VOPCX <vopc op, string opName, VOPProfile P, 1670 PatLeaf cond = COND_NULL, 1671 string revOp = ""> 1672 : VOPCInst <op, opName, P, cond, revOp, 1>; 1673 1674multiclass VOPCX_F32 <vopc op, string opName, string revOp = opName> : 1675 VOPCX <op, opName, VOP_F32_F32_F32, COND_NULL, revOp>; 1676 1677multiclass VOPCX_F64 <vopc op, string opName, string revOp = opName> : 1678 VOPCX <op, opName, VOP_F64_F64_F64, COND_NULL, revOp>; 1679 1680multiclass VOPCX_I32 <vopc op, string opName, string revOp = opName> : 1681 VOPCX <op, opName, VOP_I32_I32_I32, COND_NULL, revOp>; 1682 1683multiclass VOPCX_I64 <vopc op, string opName, string revOp = opName> : 1684 VOPCX <op, opName, VOP_I64_I64_I64, COND_NULL, revOp>; 1685 1686multiclass VOP3_Helper <vop3 op, string opName, dag outs, dag ins, string asm, 1687 list<dag> pat, int NumSrcArgs, bit HasMods> : VOP3_m < 1688 op, outs, ins, opName#" "#asm, pat, opName, NumSrcArgs, HasMods 1689>; 1690 1691multiclass VOPC_CLASS_F32 <vopc op, string opName> : 1692 VOPCClassInst <op, opName, VOP_I1_F32_I32, 0>; 1693 1694multiclass VOPCX_CLASS_F32 <vopc op, string opName> : 1695 VOPCClassInst <op, opName, VOP_I1_F32_I32, 1>; 1696 1697multiclass VOPC_CLASS_F64 <vopc op, string opName> : 1698 VOPCClassInst <op, opName, VOP_I1_F64_I32, 0>; 1699 1700multiclass VOPCX_CLASS_F64 <vopc op, string opName> : 1701 VOPCClassInst <op, opName, VOP_I1_F64_I32, 1>; 1702 1703multiclass VOP3Inst <vop3 op, string opName, VOPProfile P, 1704 SDPatternOperator node = null_frag> : VOP3_Helper < 1705 op, opName, (outs P.DstRC.RegClass:$dst), P.Ins64, P.Asm64, 1706 !if(!eq(P.NumSrcArgs, 3), 1707 !if(P.HasModifiers, 1708 [(set P.DstVT:$dst, 1709 (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, 1710 i1:$clamp, i32:$omod)), 1711 (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)), 1712 (P.Src2VT (VOP3Mods P.Src2VT:$src2, i32:$src2_modifiers))))], 1713 [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1, 1714 P.Src2VT:$src2))]), 1715 !if(!eq(P.NumSrcArgs, 2), 1716 !if(P.HasModifiers, 1717 [(set P.DstVT:$dst, 1718 (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, 1719 i1:$clamp, i32:$omod)), 1720 (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))], 1721 [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1))]) 1722 /* P.NumSrcArgs == 1 */, 1723 !if(P.HasModifiers, 1724 [(set P.DstVT:$dst, 1725 (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, 1726 i1:$clamp, i32:$omod))))], 1727 [(set P.DstVT:$dst, (node P.Src0VT:$src0))]))), 1728 P.NumSrcArgs, P.HasModifiers 1729>; 1730 1731// Special case for v_div_fmas_{f32|f64}, since it seems to be the 1732// only VOP instruction that implicitly reads VCC. 1733multiclass VOP3_VCC_Inst <vop3 op, string opName, 1734 VOPProfile P, 1735 SDPatternOperator node = null_frag> : VOP3_Helper < 1736 op, opName, 1737 (outs P.DstRC.RegClass:$dst), 1738 (ins InputModsNoDefault:$src0_modifiers, P.Src0RC64:$src0, 1739 InputModsNoDefault:$src1_modifiers, P.Src1RC64:$src1, 1740 InputModsNoDefault:$src2_modifiers, P.Src2RC64:$src2, 1741 ClampMod:$clamp, 1742 omod:$omod), 1743 "$dst, $src0_modifiers, $src1_modifiers, $src2_modifiers"#"$clamp"#"$omod", 1744 [(set P.DstVT:$dst, 1745 (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, 1746 i1:$clamp, i32:$omod)), 1747 (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)), 1748 (P.Src2VT (VOP3Mods P.Src2VT:$src2, i32:$src2_modifiers)), 1749 (i1 VCC)))], 1750 3, 1 1751>; 1752 1753multiclass VOP3b_Helper <vop op, RegisterClass vrc, RegisterOperand arc, 1754 string opName, list<dag> pattern> : 1755 VOP3b_3_m < 1756 op, (outs vrc:$vdst, SReg_64:$sdst), 1757 (ins InputModsNoDefault:$src0_modifiers, arc:$src0, 1758 InputModsNoDefault:$src1_modifiers, arc:$src1, 1759 InputModsNoDefault:$src2_modifiers, arc:$src2, 1760 ClampMod:$clamp, omod:$omod), 1761 opName#" $vdst, $sdst, $src0_modifiers, $src1_modifiers, $src2_modifiers"#"$clamp"#"$omod", pattern, 1762 opName, opName, 1, 1 1763>; 1764 1765multiclass VOP3b_64 <vop3 op, string opName, list<dag> pattern> : 1766 VOP3b_Helper <op, VReg_64, VSrc_64, opName, pattern>; 1767 1768multiclass VOP3b_32 <vop3 op, string opName, list<dag> pattern> : 1769 VOP3b_Helper <op, VGPR_32, VSrc_32, opName, pattern>; 1770 1771 1772class Vop3ModPat<Instruction Inst, VOPProfile P, SDPatternOperator node> : Pat< 1773 (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i1:$clamp, i32:$omod)), 1774 (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)), 1775 (P.Src2VT (VOP3Mods P.Src2VT:$src2, i32:$src2_modifiers))), 1776 (Inst i32:$src0_modifiers, P.Src0VT:$src0, 1777 i32:$src1_modifiers, P.Src1VT:$src1, 1778 i32:$src2_modifiers, P.Src2VT:$src2, 1779 i1:$clamp, 1780 i32:$omod)>; 1781 1782//===----------------------------------------------------------------------===// 1783// Interpolation opcodes 1784//===----------------------------------------------------------------------===// 1785 1786class VINTRP_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> : 1787 VINTRPCommon <outs, ins, "", pattern>, 1788 SIMCInstr<opName, SISubtarget.NONE> { 1789 let isPseudo = 1; 1790 let isCodeGenOnly = 1; 1791} 1792 1793class VINTRP_Real_si <bits <2> op, string opName, dag outs, dag ins, 1794 string asm> : 1795 VINTRPCommon <outs, ins, asm, []>, 1796 VINTRPe <op>, 1797 SIMCInstr<opName, SISubtarget.SI>; 1798 1799class VINTRP_Real_vi <bits <2> op, string opName, dag outs, dag ins, 1800 string asm> : 1801 VINTRPCommon <outs, ins, asm, []>, 1802 VINTRPe_vi <op>, 1803 SIMCInstr<opName, SISubtarget.VI>; 1804 1805multiclass VINTRP_m <bits <2> op, dag outs, dag ins, string asm, 1806 list<dag> pattern = []> { 1807 def "" : VINTRP_Pseudo <NAME, outs, ins, pattern>; 1808 1809 def _si : VINTRP_Real_si <op, NAME, outs, ins, asm>; 1810 1811 def _vi : VINTRP_Real_vi <op, NAME, outs, ins, asm>; 1812} 1813 1814//===----------------------------------------------------------------------===// 1815// Vector I/O classes 1816//===----------------------------------------------------------------------===// 1817 1818class DS_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> : 1819 DS <outs, ins, "", pattern>, 1820 SIMCInstr <opName, SISubtarget.NONE> { 1821 let isPseudo = 1; 1822 let isCodeGenOnly = 1; 1823} 1824 1825class DS_Real_si <bits<8> op, string opName, dag outs, dag ins, string asm> : 1826 DS <outs, ins, asm, []>, 1827 DSe <op>, 1828 SIMCInstr <opName, SISubtarget.SI> { 1829 let isCodeGenOnly = 0; 1830} 1831 1832class DS_Real_vi <bits<8> op, string opName, dag outs, dag ins, string asm> : 1833 DS <outs, ins, asm, []>, 1834 DSe_vi <op>, 1835 SIMCInstr <opName, SISubtarget.VI>; 1836 1837class DS_Off16_Real_si <bits<8> op, string opName, dag outs, dag ins, string asm> : 1838 DS_Real_si <op,opName, outs, ins, asm> { 1839 1840 // Single load interpret the 2 i8imm operands as a single i16 offset. 1841 bits<16> offset; 1842 let offset0 = offset{7-0}; 1843 let offset1 = offset{15-8}; 1844 let isCodeGenOnly = 0; 1845} 1846 1847class DS_Off16_Real_vi <bits<8> op, string opName, dag outs, dag ins, string asm> : 1848 DS_Real_vi <op, opName, outs, ins, asm> { 1849 1850 // Single load interpret the 2 i8imm operands as a single i16 offset. 1851 bits<16> offset; 1852 let offset0 = offset{7-0}; 1853 let offset1 = offset{15-8}; 1854} 1855 1856multiclass DS_1A_RET <bits<8> op, string opName, RegisterClass rc, 1857 dag outs = (outs rc:$vdst), 1858 dag ins = (ins VGPR_32:$addr, ds_offset:$offset, gds:$gds), 1859 string asm = opName#" $vdst, $addr"#"$offset$gds"> { 1860 1861 def "" : DS_Pseudo <opName, outs, ins, []>; 1862 1863 let data0 = 0, data1 = 0 in { 1864 def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>; 1865 def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>; 1866 } 1867} 1868 1869multiclass DS_1A_Off8_RET <bits<8> op, string opName, RegisterClass rc, 1870 dag outs = (outs rc:$vdst), 1871 dag ins = (ins VGPR_32:$addr, ds_offset0:$offset0, ds_offset1:$offset1, 1872 gds01:$gds), 1873 string asm = opName#" $vdst, $addr"#"$offset0"#"$offset1$gds"> { 1874 1875 def "" : DS_Pseudo <opName, outs, ins, []>; 1876 1877 let data0 = 0, data1 = 0, AsmMatchConverter = "cvtDSOffset01" in { 1878 def _si : DS_Real_si <op, opName, outs, ins, asm>; 1879 def _vi : DS_Real_vi <op, opName, outs, ins, asm>; 1880 } 1881} 1882 1883multiclass DS_1A1D_NORET <bits<8> op, string opName, RegisterClass rc, 1884 dag outs = (outs), 1885 dag ins = (ins VGPR_32:$addr, rc:$data0, ds_offset:$offset, gds:$gds), 1886 string asm = opName#" $addr, $data0"#"$offset$gds"> { 1887 1888 def "" : DS_Pseudo <opName, outs, ins, []>, 1889 AtomicNoRet<opName, 0>; 1890 1891 let data1 = 0, vdst = 0 in { 1892 def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>; 1893 def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>; 1894 } 1895} 1896 1897multiclass DS_1A1D_Off8_NORET <bits<8> op, string opName, RegisterClass rc, 1898 dag outs = (outs), 1899 dag ins = (ins VGPR_32:$addr, rc:$data0, rc:$data1, 1900 ds_offset0:$offset0, ds_offset1:$offset1, gds01:$gds), 1901 string asm = opName#" $addr, $data0, $data1"#"$offset0"#"$offset1"#"$gds"> { 1902 1903 def "" : DS_Pseudo <opName, outs, ins, []>; 1904 1905 let vdst = 0, AsmMatchConverter = "cvtDSOffset01" in { 1906 def _si : DS_Real_si <op, opName, outs, ins, asm>; 1907 def _vi : DS_Real_vi <op, opName, outs, ins, asm>; 1908 } 1909} 1910 1911multiclass DS_1A1D_RET <bits<8> op, string opName, RegisterClass rc, 1912 string noRetOp = "", 1913 dag outs = (outs rc:$vdst), 1914 dag ins = (ins VGPR_32:$addr, rc:$data0, ds_offset:$offset, gds:$gds), 1915 string asm = opName#" $vdst, $addr, $data0"#"$offset$gds"> { 1916 1917 def "" : DS_Pseudo <opName, outs, ins, []>, 1918 AtomicNoRet<noRetOp, 1>; 1919 1920 let data1 = 0 in { 1921 def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>; 1922 def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>; 1923 } 1924} 1925 1926multiclass DS_1A2D_RET_m <bits<8> op, string opName, RegisterClass rc, 1927 string noRetOp = "", dag ins, 1928 dag outs = (outs rc:$vdst), 1929 string asm = opName#" $vdst, $addr, $data0, $data1"#"$offset"#"$gds"> { 1930 1931 def "" : DS_Pseudo <opName, outs, ins, []>, 1932 AtomicNoRet<noRetOp, 1>; 1933 1934 def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>; 1935 def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>; 1936} 1937 1938multiclass DS_1A2D_RET <bits<8> op, string asm, RegisterClass rc, 1939 string noRetOp = "", RegisterClass src = rc> : 1940 DS_1A2D_RET_m <op, asm, rc, noRetOp, 1941 (ins VGPR_32:$addr, src:$data0, src:$data1, 1942 ds_offset:$offset, gds:$gds) 1943>; 1944 1945multiclass DS_1A2D_NORET <bits<8> op, string opName, RegisterClass rc, 1946 string noRetOp = opName, 1947 dag outs = (outs), 1948 dag ins = (ins VGPR_32:$addr, rc:$data0, rc:$data1, 1949 ds_offset:$offset, gds:$gds), 1950 string asm = opName#" $addr, $data0, $data1"#"$offset"#"$gds"> { 1951 1952 def "" : DS_Pseudo <opName, outs, ins, []>, 1953 AtomicNoRet<noRetOp, 0>; 1954 1955 let vdst = 0 in { 1956 def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>; 1957 def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>; 1958 } 1959} 1960 1961multiclass DS_0A_RET <bits<8> op, string opName, 1962 dag outs = (outs VGPR_32:$vdst), 1963 dag ins = (ins ds_offset:$offset, gds:$gds), 1964 string asm = opName#" $vdst"#"$offset"#"$gds"> { 1965 1966 let mayLoad = 1, mayStore = 1 in { 1967 def "" : DS_Pseudo <opName, outs, ins, []>; 1968 1969 let addr = 0, data0 = 0, data1 = 0 in { 1970 def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>; 1971 def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>; 1972 } // end addr = 0, data0 = 0, data1 = 0 1973 } // end mayLoad = 1, mayStore = 1 1974} 1975 1976multiclass DS_1A_RET_GDS <bits<8> op, string opName, 1977 dag outs = (outs VGPR_32:$vdst), 1978 dag ins = (ins VGPR_32:$addr, ds_offset_gds:$offset), 1979 string asm = opName#" $vdst, $addr"#"$offset gds"> { 1980 1981 def "" : DS_Pseudo <opName, outs, ins, []>; 1982 1983 let data0 = 0, data1 = 0, gds = 1 in { 1984 def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>; 1985 def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>; 1986 } // end data0 = 0, data1 = 0, gds = 1 1987} 1988 1989multiclass DS_1A_GDS <bits<8> op, string opName, 1990 dag outs = (outs), 1991 dag ins = (ins VGPR_32:$addr), 1992 string asm = opName#" $addr gds"> { 1993 1994 def "" : DS_Pseudo <opName, outs, ins, []>; 1995 1996 let vdst = 0, data0 = 0, data1 = 0, offset0 = 0, offset1 = 0, gds = 1 in { 1997 def _si : DS_Real_si <op, opName, outs, ins, asm>; 1998 def _vi : DS_Real_vi <op, opName, outs, ins, asm>; 1999 } // end vdst = 0, data = 0, data1 = 0, gds = 1 2000} 2001 2002multiclass DS_1A <bits<8> op, string opName, 2003 dag outs = (outs), 2004 dag ins = (ins VGPR_32:$addr, ds_offset:$offset, gds:$gds), 2005 string asm = opName#" $addr"#"$offset"#"$gds"> { 2006 2007 let mayLoad = 1, mayStore = 1 in { 2008 def "" : DS_Pseudo <opName, outs, ins, []>; 2009 2010 let vdst = 0, data0 = 0, data1 = 0 in { 2011 def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>; 2012 def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>; 2013 } // let vdst = 0, data0 = 0, data1 = 0 2014 } // end mayLoad = 1, mayStore = 1 2015} 2016 2017//===----------------------------------------------------------------------===// 2018// MTBUF classes 2019//===----------------------------------------------------------------------===// 2020 2021class MTBUF_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> : 2022 MTBUF <outs, ins, "", pattern>, 2023 SIMCInstr<opName, SISubtarget.NONE> { 2024 let isPseudo = 1; 2025 let isCodeGenOnly = 1; 2026} 2027 2028class MTBUF_Real_si <bits<3> op, string opName, dag outs, dag ins, 2029 string asm> : 2030 MTBUF <outs, ins, asm, []>, 2031 MTBUFe <op>, 2032 SIMCInstr<opName, SISubtarget.SI>; 2033 2034class MTBUF_Real_vi <bits<4> op, string opName, dag outs, dag ins, string asm> : 2035 MTBUF <outs, ins, asm, []>, 2036 MTBUFe_vi <op>, 2037 SIMCInstr <opName, SISubtarget.VI>; 2038 2039multiclass MTBUF_m <bits<3> op, string opName, dag outs, dag ins, string asm, 2040 list<dag> pattern> { 2041 2042 def "" : MTBUF_Pseudo <opName, outs, ins, pattern>; 2043 2044 def _si : MTBUF_Real_si <op, opName, outs, ins, asm>; 2045 2046 def _vi : MTBUF_Real_vi <{0, op{2}, op{1}, op{0}}, opName, outs, ins, asm>; 2047 2048} 2049 2050let mayStore = 1, mayLoad = 0 in { 2051 2052multiclass MTBUF_Store_Helper <bits<3> op, string opName, 2053 RegisterClass regClass> : MTBUF_m < 2054 op, opName, (outs), 2055 (ins regClass:$vdata, u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, 2056 i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VGPR_32:$vaddr, 2057 SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SCSrc_32:$soffset), 2058 opName#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt," 2059 #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset", [] 2060>; 2061 2062} // mayStore = 1, mayLoad = 0 2063 2064let mayLoad = 1, mayStore = 0 in { 2065 2066multiclass MTBUF_Load_Helper <bits<3> op, string opName, 2067 RegisterClass regClass> : MTBUF_m < 2068 op, opName, (outs regClass:$dst), 2069 (ins u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64, 2070 i8imm:$dfmt, i8imm:$nfmt, VGPR_32:$vaddr, SReg_128:$srsrc, 2071 i1imm:$slc, i1imm:$tfe, SCSrc_32:$soffset), 2072 opName#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt," 2073 #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset", [] 2074>; 2075 2076} // mayLoad = 1, mayStore = 0 2077 2078//===----------------------------------------------------------------------===// 2079// MUBUF classes 2080//===----------------------------------------------------------------------===// 2081 2082class mubuf <bits<7> si, bits<7> vi = si> { 2083 field bits<7> SI = si; 2084 field bits<7> VI = vi; 2085} 2086 2087let isCodeGenOnly = 0 in { 2088 2089class MUBUF_si <bits<7> op, dag outs, dag ins, string asm, list<dag> pattern> : 2090 MUBUF <outs, ins, asm, pattern>, MUBUFe <op> { 2091 let lds = 0; 2092} 2093 2094} // End let isCodeGenOnly = 0 2095 2096class MUBUF_vi <bits<7> op, dag outs, dag ins, string asm, list<dag> pattern> : 2097 MUBUF <outs, ins, asm, pattern>, MUBUFe_vi <op> { 2098 let lds = 0; 2099} 2100 2101class MUBUFAddr64Table <bit is_addr64, string suffix = ""> { 2102 bit IsAddr64 = is_addr64; 2103 string OpName = NAME # suffix; 2104} 2105 2106class MUBUF_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> : 2107 MUBUF <outs, ins, "", pattern>, 2108 SIMCInstr<opName, SISubtarget.NONE> { 2109 let isPseudo = 1; 2110 let isCodeGenOnly = 1; 2111 2112 // dummy fields, so that we can use let statements around multiclasses 2113 bits<1> offen; 2114 bits<1> idxen; 2115 bits<8> vaddr; 2116 bits<1> glc; 2117 bits<1> slc; 2118 bits<1> tfe; 2119 bits<8> soffset; 2120} 2121 2122class MUBUF_Real_si <mubuf op, string opName, dag outs, dag ins, 2123 string asm> : 2124 MUBUF <outs, ins, asm, []>, 2125 MUBUFe <op.SI>, 2126 SIMCInstr<opName, SISubtarget.SI> { 2127 let lds = 0; 2128} 2129 2130class MUBUF_Real_vi <mubuf op, string opName, dag outs, dag ins, 2131 string asm> : 2132 MUBUF <outs, ins, asm, []>, 2133 MUBUFe_vi <op.VI>, 2134 SIMCInstr<opName, SISubtarget.VI> { 2135 let lds = 0; 2136} 2137 2138multiclass MUBUF_m <mubuf op, string opName, dag outs, dag ins, string asm, 2139 list<dag> pattern> { 2140 2141 def "" : MUBUF_Pseudo <opName, outs, ins, pattern>, 2142 MUBUFAddr64Table <0>; 2143 2144 let addr64 = 0, isCodeGenOnly = 0 in { 2145 def _si : MUBUF_Real_si <op, opName, outs, ins, asm>; 2146 } 2147 2148 def _vi : MUBUF_Real_vi <op, opName, outs, ins, asm>; 2149} 2150 2151multiclass MUBUFAddr64_m <mubuf op, string opName, dag outs, 2152 dag ins, string asm, list<dag> pattern> { 2153 2154 def "" : MUBUF_Pseudo <opName, outs, ins, pattern>, 2155 MUBUFAddr64Table <1>; 2156 2157 let addr64 = 1, isCodeGenOnly = 0 in { 2158 def _si : MUBUF_Real_si <op, opName, outs, ins, asm>; 2159 } 2160 2161 // There is no VI version. If the pseudo is selected, it should be lowered 2162 // for VI appropriately. 2163} 2164 2165multiclass MUBUFAtomicOffset_m <mubuf op, string opName, dag outs, dag ins, 2166 string asm, list<dag> pattern, bit is_return> { 2167 2168 def "" : MUBUF_Pseudo <opName, outs, ins, pattern>, 2169 MUBUFAddr64Table <0, !if(is_return, "_RTN", "")>, 2170 AtomicNoRet<NAME#"_OFFSET", is_return>; 2171 2172 let offen = 0, idxen = 0, tfe = 0, vaddr = 0 in { 2173 let addr64 = 0 in { 2174 def _si : MUBUF_Real_si <op, opName, outs, ins, asm>; 2175 } 2176 2177 def _vi : MUBUF_Real_vi <op, opName, outs, ins, asm>; 2178 } 2179} 2180 2181multiclass MUBUFAtomicAddr64_m <mubuf op, string opName, dag outs, dag ins, 2182 string asm, list<dag> pattern, bit is_return> { 2183 2184 def "" : MUBUF_Pseudo <opName, outs, ins, pattern>, 2185 MUBUFAddr64Table <1, !if(is_return, "_RTN", "")>, 2186 AtomicNoRet<NAME#"_ADDR64", is_return>; 2187 2188 let offen = 0, idxen = 0, addr64 = 1, tfe = 0 in { 2189 def _si : MUBUF_Real_si <op, opName, outs, ins, asm>; 2190 } 2191 2192 // There is no VI version. If the pseudo is selected, it should be lowered 2193 // for VI appropriately. 2194} 2195 2196multiclass MUBUF_Atomic <mubuf op, string name, RegisterClass rc, 2197 ValueType vt, SDPatternOperator atomic> { 2198 2199 let mayStore = 1, mayLoad = 1, hasPostISelHook = 1 in { 2200 2201 // No return variants 2202 let glc = 0 in { 2203 2204 defm _ADDR64 : MUBUFAtomicAddr64_m < 2205 op, name#"_addr64", (outs), 2206 (ins rc:$vdata, SReg_128:$srsrc, VReg_64:$vaddr, 2207 SCSrc_32:$soffset, mbuf_offset:$offset, slc:$slc), 2208 name#" $vdata, $vaddr, $srsrc, $soffset addr64"#"$offset"#"$slc", [], 0 2209 >; 2210 2211 defm _OFFSET : MUBUFAtomicOffset_m < 2212 op, name#"_offset", (outs), 2213 (ins rc:$vdata, SReg_128:$srsrc, SCSrc_32:$soffset, mbuf_offset:$offset, 2214 slc:$slc), 2215 name#" $vdata, $srsrc, $soffset"#"$offset"#"$slc", [], 0 2216 >; 2217 } // glc = 0 2218 2219 // Variant that return values 2220 let glc = 1, Constraints = "$vdata = $vdata_in", 2221 DisableEncoding = "$vdata_in" in { 2222 2223 defm _RTN_ADDR64 : MUBUFAtomicAddr64_m < 2224 op, name#"_rtn_addr64", (outs rc:$vdata), 2225 (ins rc:$vdata_in, SReg_128:$srsrc, VReg_64:$vaddr, 2226 SCSrc_32:$soffset, mbuf_offset:$offset, slc:$slc), 2227 name#" $vdata, $vaddr, $srsrc, $soffset addr64"#"$offset"#" glc"#"$slc", 2228 [(set vt:$vdata, 2229 (atomic (MUBUFAddr64Atomic v4i32:$srsrc, i64:$vaddr, i32:$soffset, 2230 i16:$offset, i1:$slc), vt:$vdata_in))], 1 2231 >; 2232 2233 defm _RTN_OFFSET : MUBUFAtomicOffset_m < 2234 op, name#"_rtn_offset", (outs rc:$vdata), 2235 (ins rc:$vdata_in, SReg_128:$srsrc, SCSrc_32:$soffset, 2236 mbuf_offset:$offset, slc:$slc), 2237 name#" $vdata, $srsrc, $soffset"#"$offset"#" glc $slc", 2238 [(set vt:$vdata, 2239 (atomic (MUBUFOffsetAtomic v4i32:$srsrc, i32:$soffset, i16:$offset, 2240 i1:$slc), vt:$vdata_in))], 1 2241 >; 2242 2243 } // glc = 1 2244 2245 } // mayStore = 1, mayLoad = 1, hasPostISelHook = 1 2246} 2247 2248multiclass MUBUF_Load_Helper <mubuf op, string name, RegisterClass regClass, 2249 ValueType load_vt = i32, 2250 SDPatternOperator ld = null_frag> { 2251 2252 let mayLoad = 1, mayStore = 0 in { 2253 let offen = 0, idxen = 0, vaddr = 0 in { 2254 defm _OFFSET : MUBUF_m <op, name#"_offset", (outs regClass:$vdata), 2255 (ins SReg_128:$srsrc, SCSrc_32:$soffset, 2256 mbuf_offset:$offset, glc:$glc, slc:$slc, tfe:$tfe), 2257 name#" $vdata, $srsrc, $soffset"#"$offset"#"$glc"#"$slc"#"$tfe", 2258 [(set load_vt:$vdata, (ld (MUBUFOffset v4i32:$srsrc, 2259 i32:$soffset, i16:$offset, 2260 i1:$glc, i1:$slc, i1:$tfe)))]>; 2261 } 2262 2263 let offen = 1, idxen = 0 in { 2264 defm _OFFEN : MUBUF_m <op, name#"_offen", (outs regClass:$vdata), 2265 (ins VGPR_32:$vaddr, SReg_128:$srsrc, 2266 SCSrc_32:$soffset, mbuf_offset:$offset, glc:$glc, slc:$slc, 2267 tfe:$tfe), 2268 name#" $vdata, $vaddr, $srsrc, $soffset offen"#"$offset"#"$glc"#"$slc"#"$tfe", []>; 2269 } 2270 2271 let offen = 0, idxen = 1 in { 2272 defm _IDXEN : MUBUF_m <op, name#"_idxen", (outs regClass:$vdata), 2273 (ins VGPR_32:$vaddr, SReg_128:$srsrc, 2274 SCSrc_32:$soffset, mbuf_offset:$offset, glc:$glc, 2275 slc:$slc, tfe:$tfe), 2276 name#" $vdata, $vaddr, $srsrc, $soffset idxen"#"$offset"#"$glc"#"$slc"#"$tfe", []>; 2277 } 2278 2279 let offen = 1, idxen = 1 in { 2280 defm _BOTHEN : MUBUF_m <op, name#"_bothen", (outs regClass:$vdata), 2281 (ins VReg_64:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset, 2282 mbuf_offset:$offset, glc:$glc, slc:$slc, tfe:$tfe), 2283 name#" $vdata, $vaddr, $srsrc, $soffset idxen offen"#"$offset"#"$glc"#"$slc"#"$tfe", []>; 2284 } 2285 2286 let offen = 0, idxen = 0 in { 2287 defm _ADDR64 : MUBUFAddr64_m <op, name#"_addr64", (outs regClass:$vdata), 2288 (ins VReg_64:$vaddr, SReg_128:$srsrc, 2289 SCSrc_32:$soffset, mbuf_offset:$offset, 2290 glc:$glc, slc:$slc, tfe:$tfe), 2291 name#" $vdata, $vaddr, $srsrc, $soffset addr64"#"$offset"# 2292 "$glc"#"$slc"#"$tfe", 2293 [(set load_vt:$vdata, (ld (MUBUFAddr64 v4i32:$srsrc, 2294 i64:$vaddr, i32:$soffset, 2295 i16:$offset, i1:$glc, i1:$slc, 2296 i1:$tfe)))]>; 2297 } 2298 } 2299} 2300 2301multiclass MUBUF_Store_Helper <mubuf op, string name, RegisterClass vdataClass, 2302 ValueType store_vt = i32, SDPatternOperator st = null_frag> { 2303 let mayLoad = 0, mayStore = 1 in { 2304 defm : MUBUF_m <op, name, (outs), 2305 (ins vdataClass:$vdata, VGPR_32:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset, 2306 mbuf_offset:$offset, offen:$offen, idxen:$idxen, glc:$glc, slc:$slc, 2307 tfe:$tfe), 2308 name#" $vdata, $vaddr, $srsrc, $soffset"#"$offen"#"$idxen"#"$offset"# 2309 "$glc"#"$slc"#"$tfe", []>; 2310 2311 let offen = 0, idxen = 0, vaddr = 0 in { 2312 defm _OFFSET : MUBUF_m <op, name#"_offset",(outs), 2313 (ins vdataClass:$vdata, SReg_128:$srsrc, SCSrc_32:$soffset, 2314 mbuf_offset:$offset, glc:$glc, slc:$slc, tfe:$tfe), 2315 name#" $vdata, $srsrc, $soffset"#"$offset"#"$glc"#"$slc"#"$tfe", 2316 [(st store_vt:$vdata, (MUBUFOffset v4i32:$srsrc, i32:$soffset, 2317 i16:$offset, i1:$glc, i1:$slc, i1:$tfe))]>; 2318 } // offen = 0, idxen = 0, vaddr = 0 2319 2320 let offen = 1, idxen = 0 in { 2321 defm _OFFEN : MUBUF_m <op, name#"_offen", (outs), 2322 (ins vdataClass:$vdata, VGPR_32:$vaddr, SReg_128:$srsrc, 2323 SCSrc_32:$soffset, mbuf_offset:$offset, glc:$glc, 2324 slc:$slc, tfe:$tfe), 2325 name#" $vdata, $vaddr, $srsrc, $soffset offen"#"$offset"# 2326 "$glc"#"$slc"#"$tfe", []>; 2327 } // end offen = 1, idxen = 0 2328 2329 let offen = 0, idxen = 1 in { 2330 defm _IDXEN : MUBUF_m <op, name#"_idxen", (outs), 2331 (ins vdataClass:$vdata, VGPR_32:$vaddr, SReg_128:$srsrc, 2332 SCSrc_32:$soffset, mbuf_offset:$offset, glc:$glc, 2333 slc:$slc, tfe:$tfe), 2334 name#" $vdata, $vaddr, $srsrc, $soffset idxen"#"$offset"#"$glc"#"$slc"#"$tfe", []>; 2335 } 2336 2337 let offen = 1, idxen = 1 in { 2338 defm _BOTHEN : MUBUF_m <op, name#"_bothen", (outs), 2339 (ins vdataClass:$vdata, VReg_64:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset, 2340 mbuf_offset:$offset, glc:$glc, slc:$slc, tfe:$tfe), 2341 name#" $vdata, $vaddr, $srsrc, $soffset idxen offen"#"$offset"#"$glc"#"$slc"#"$tfe", []>; 2342 } 2343 2344 let offen = 0, idxen = 0 in { 2345 defm _ADDR64 : MUBUFAddr64_m <op, name#"_addr64", (outs), 2346 (ins vdataClass:$vdata, VReg_64:$vaddr, SReg_128:$srsrc, 2347 SCSrc_32:$soffset, 2348 mbuf_offset:$offset, glc:$glc, slc:$slc, 2349 tfe:$tfe), 2350 name#" $vdata, $vaddr, $srsrc, $soffset addr64"# 2351 "$offset"#"$glc"#"$slc"#"$tfe", 2352 [(st store_vt:$vdata, 2353 (MUBUFAddr64 v4i32:$srsrc, i64:$vaddr, 2354 i32:$soffset, i16:$offset, 2355 i1:$glc, i1:$slc, i1:$tfe))]>; 2356 } 2357 } // End mayLoad = 0, mayStore = 1 2358} 2359 2360class FLAT_Load_Helper <bits<7> op, string asm, RegisterClass regClass> : 2361 FLAT <op, (outs regClass:$vdst), 2362 (ins VReg_64:$addr, glc_flat:$glc, slc_flat:$slc, tfe_flat:$tfe), 2363 asm#" $vdst, $addr"#"$glc"#"$slc"#"$tfe", []> { 2364 let data = 0; 2365 let mayLoad = 1; 2366} 2367 2368class FLAT_Store_Helper <bits<7> op, string name, RegisterClass vdataClass> : 2369 FLAT <op, (outs), (ins vdataClass:$data, VReg_64:$addr, 2370 glc_flat:$glc, slc_flat:$slc, tfe_flat:$tfe), 2371 name#" $data, $addr"#"$glc"#"$slc"#"$tfe", 2372 []> { 2373 2374 let mayLoad = 0; 2375 let mayStore = 1; 2376 2377 // Encoding 2378 let vdst = 0; 2379} 2380 2381multiclass FLAT_ATOMIC <bits<7> op, string name, RegisterClass vdst_rc, 2382 RegisterClass data_rc = vdst_rc> { 2383 2384 let mayLoad = 1, mayStore = 1 in { 2385 def "" : FLAT <op, (outs), 2386 (ins VReg_64:$addr, data_rc:$data, slc_flat_atomic:$slc, 2387 tfe_flat_atomic:$tfe), 2388 name#" $addr, $data"#"$slc"#"$tfe", []>, 2389 AtomicNoRet <NAME, 0> { 2390 let glc = 0; 2391 let vdst = 0; 2392 } 2393 2394 def _RTN : FLAT <op, (outs vdst_rc:$vdst), 2395 (ins VReg_64:$addr, data_rc:$data, slc_flat_atomic:$slc, 2396 tfe_flat_atomic:$tfe), 2397 name#" $vdst, $addr, $data glc"#"$slc"#"$tfe", []>, 2398 AtomicNoRet <NAME, 1> { 2399 let glc = 1; 2400 } 2401 } 2402} 2403 2404class MIMG_Mask <string op, int channels> { 2405 string Op = op; 2406 int Channels = channels; 2407} 2408 2409class MIMG_NoSampler_Helper <bits<7> op, string asm, 2410 RegisterClass dst_rc, 2411 RegisterClass src_rc> : MIMG < 2412 op, 2413 (outs dst_rc:$vdata), 2414 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128, 2415 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr, 2416 SReg_256:$srsrc), 2417 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128," 2418 #" $tfe, $lwe, $slc, $vaddr, $srsrc", 2419 []> { 2420 let ssamp = 0; 2421 let mayLoad = 1; 2422 let mayStore = 0; 2423 let hasPostISelHook = 1; 2424} 2425 2426multiclass MIMG_NoSampler_Src_Helper <bits<7> op, string asm, 2427 RegisterClass dst_rc, 2428 int channels> { 2429 def _V1 : MIMG_NoSampler_Helper <op, asm, dst_rc, VGPR_32>, 2430 MIMG_Mask<asm#"_V1", channels>; 2431 def _V2 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_64>, 2432 MIMG_Mask<asm#"_V2", channels>; 2433 def _V4 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_128>, 2434 MIMG_Mask<asm#"_V4", channels>; 2435} 2436 2437multiclass MIMG_NoSampler <bits<7> op, string asm> { 2438 defm _V1 : MIMG_NoSampler_Src_Helper <op, asm, VGPR_32, 1>; 2439 defm _V2 : MIMG_NoSampler_Src_Helper <op, asm, VReg_64, 2>; 2440 defm _V3 : MIMG_NoSampler_Src_Helper <op, asm, VReg_96, 3>; 2441 defm _V4 : MIMG_NoSampler_Src_Helper <op, asm, VReg_128, 4>; 2442} 2443 2444class MIMG_Sampler_Helper <bits<7> op, string asm, 2445 RegisterClass dst_rc, 2446 RegisterClass src_rc, int wqm> : MIMG < 2447 op, 2448 (outs dst_rc:$vdata), 2449 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128, 2450 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr, 2451 SReg_256:$srsrc, SReg_128:$ssamp), 2452 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128," 2453 #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp", 2454 []> { 2455 let mayLoad = 1; 2456 let mayStore = 0; 2457 let hasPostISelHook = 1; 2458 let WQM = wqm; 2459} 2460 2461multiclass MIMG_Sampler_Src_Helper <bits<7> op, string asm, 2462 RegisterClass dst_rc, 2463 int channels, int wqm> { 2464 def _V1 : MIMG_Sampler_Helper <op, asm, dst_rc, VGPR_32, wqm>, 2465 MIMG_Mask<asm#"_V1", channels>; 2466 def _V2 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_64, wqm>, 2467 MIMG_Mask<asm#"_V2", channels>; 2468 def _V4 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_128, wqm>, 2469 MIMG_Mask<asm#"_V4", channels>; 2470 def _V8 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_256, wqm>, 2471 MIMG_Mask<asm#"_V8", channels>; 2472 def _V16 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_512, wqm>, 2473 MIMG_Mask<asm#"_V16", channels>; 2474} 2475 2476multiclass MIMG_Sampler <bits<7> op, string asm> { 2477 defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VGPR_32, 1, 0>; 2478 defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2, 0>; 2479 defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3, 0>; 2480 defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4, 0>; 2481} 2482 2483multiclass MIMG_Sampler_WQM <bits<7> op, string asm> { 2484 defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VGPR_32, 1, 1>; 2485 defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2, 1>; 2486 defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3, 1>; 2487 defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4, 1>; 2488} 2489 2490class MIMG_Gather_Helper <bits<7> op, string asm, 2491 RegisterClass dst_rc, 2492 RegisterClass src_rc, int wqm> : MIMG < 2493 op, 2494 (outs dst_rc:$vdata), 2495 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128, 2496 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr, 2497 SReg_256:$srsrc, SReg_128:$ssamp), 2498 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128," 2499 #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp", 2500 []> { 2501 let mayLoad = 1; 2502 let mayStore = 0; 2503 2504 // DMASK was repurposed for GATHER4. 4 components are always 2505 // returned and DMASK works like a swizzle - it selects 2506 // the component to fetch. The only useful DMASK values are 2507 // 1=red, 2=green, 4=blue, 8=alpha. (e.g. 1 returns 2508 // (red,red,red,red) etc.) The ISA document doesn't mention 2509 // this. 2510 // Therefore, disable all code which updates DMASK by setting these two: 2511 let MIMG = 0; 2512 let hasPostISelHook = 0; 2513 let WQM = wqm; 2514} 2515 2516multiclass MIMG_Gather_Src_Helper <bits<7> op, string asm, 2517 RegisterClass dst_rc, 2518 int channels, int wqm> { 2519 def _V1 : MIMG_Gather_Helper <op, asm, dst_rc, VGPR_32, wqm>, 2520 MIMG_Mask<asm#"_V1", channels>; 2521 def _V2 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_64, wqm>, 2522 MIMG_Mask<asm#"_V2", channels>; 2523 def _V4 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_128, wqm>, 2524 MIMG_Mask<asm#"_V4", channels>; 2525 def _V8 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_256, wqm>, 2526 MIMG_Mask<asm#"_V8", channels>; 2527 def _V16 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_512, wqm>, 2528 MIMG_Mask<asm#"_V16", channels>; 2529} 2530 2531multiclass MIMG_Gather <bits<7> op, string asm> { 2532 defm _V1 : MIMG_Gather_Src_Helper<op, asm, VGPR_32, 1, 0>; 2533 defm _V2 : MIMG_Gather_Src_Helper<op, asm, VReg_64, 2, 0>; 2534 defm _V3 : MIMG_Gather_Src_Helper<op, asm, VReg_96, 3, 0>; 2535 defm _V4 : MIMG_Gather_Src_Helper<op, asm, VReg_128, 4, 0>; 2536} 2537 2538multiclass MIMG_Gather_WQM <bits<7> op, string asm> { 2539 defm _V1 : MIMG_Gather_Src_Helper<op, asm, VGPR_32, 1, 1>; 2540 defm _V2 : MIMG_Gather_Src_Helper<op, asm, VReg_64, 2, 1>; 2541 defm _V3 : MIMG_Gather_Src_Helper<op, asm, VReg_96, 3, 1>; 2542 defm _V4 : MIMG_Gather_Src_Helper<op, asm, VReg_128, 4, 1>; 2543} 2544 2545//===----------------------------------------------------------------------===// 2546// Vector instruction mappings 2547//===----------------------------------------------------------------------===// 2548 2549// Maps an opcode in e32 form to its e64 equivalent 2550def getVOPe64 : InstrMapping { 2551 let FilterClass = "VOP"; 2552 let RowFields = ["OpName"]; 2553 let ColFields = ["Size"]; 2554 let KeyCol = ["4"]; 2555 let ValueCols = [["8"]]; 2556} 2557 2558// Maps an opcode in e64 form to its e32 equivalent 2559def getVOPe32 : InstrMapping { 2560 let FilterClass = "VOP"; 2561 let RowFields = ["OpName"]; 2562 let ColFields = ["Size"]; 2563 let KeyCol = ["8"]; 2564 let ValueCols = [["4"]]; 2565} 2566 2567def getMaskedMIMGOp : InstrMapping { 2568 let FilterClass = "MIMG_Mask"; 2569 let RowFields = ["Op"]; 2570 let ColFields = ["Channels"]; 2571 let KeyCol = ["4"]; 2572 let ValueCols = [["1"], ["2"], ["3"] ]; 2573} 2574 2575// Maps an commuted opcode to its original version 2576def getCommuteOrig : InstrMapping { 2577 let FilterClass = "VOP2_REV"; 2578 let RowFields = ["RevOp"]; 2579 let ColFields = ["IsOrig"]; 2580 let KeyCol = ["0"]; 2581 let ValueCols = [["1"]]; 2582} 2583 2584// Maps an original opcode to its commuted version 2585def getCommuteRev : InstrMapping { 2586 let FilterClass = "VOP2_REV"; 2587 let RowFields = ["RevOp"]; 2588 let ColFields = ["IsOrig"]; 2589 let KeyCol = ["1"]; 2590 let ValueCols = [["0"]]; 2591} 2592 2593def getCommuteCmpOrig : InstrMapping { 2594 let FilterClass = "VOP2_REV"; 2595 let RowFields = ["RevOp"]; 2596 let ColFields = ["IsOrig"]; 2597 let KeyCol = ["0"]; 2598 let ValueCols = [["1"]]; 2599} 2600 2601// Maps an original opcode to its commuted version 2602def getCommuteCmpRev : InstrMapping { 2603 let FilterClass = "VOP2_REV"; 2604 let RowFields = ["RevOp"]; 2605 let ColFields = ["IsOrig"]; 2606 let KeyCol = ["1"]; 2607 let ValueCols = [["0"]]; 2608} 2609 2610 2611def getMCOpcodeGen : InstrMapping { 2612 let FilterClass = "SIMCInstr"; 2613 let RowFields = ["PseudoInstr"]; 2614 let ColFields = ["Subtarget"]; 2615 let KeyCol = [!cast<string>(SISubtarget.NONE)]; 2616 let ValueCols = [[!cast<string>(SISubtarget.SI)],[!cast<string>(SISubtarget.VI)]]; 2617} 2618 2619def getAddr64Inst : InstrMapping { 2620 let FilterClass = "MUBUFAddr64Table"; 2621 let RowFields = ["OpName"]; 2622 let ColFields = ["IsAddr64"]; 2623 let KeyCol = ["0"]; 2624 let ValueCols = [["1"]]; 2625} 2626 2627// Maps an atomic opcode to its version with a return value. 2628def getAtomicRetOp : InstrMapping { 2629 let FilterClass = "AtomicNoRet"; 2630 let RowFields = ["NoRetOp"]; 2631 let ColFields = ["IsRet"]; 2632 let KeyCol = ["0"]; 2633 let ValueCols = [["1"]]; 2634} 2635 2636// Maps an atomic opcode to its returnless version. 2637def getAtomicNoRetOp : InstrMapping { 2638 let FilterClass = "AtomicNoRet"; 2639 let RowFields = ["NoRetOp"]; 2640 let ColFields = ["IsRet"]; 2641 let KeyCol = ["1"]; 2642 let ValueCols = [["0"]]; 2643} 2644 2645include "SIInstructions.td" 2646include "CIInstructions.td" 2647include "VIInstructions.td" 2648