1//===-- SIInstrInfo.td - SI Instruction Infos -------------*- tablegen -*--===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9def isCI : Predicate<"Subtarget->getGeneration() " 10 ">= SISubtarget::SEA_ISLANDS">; 11def isCIOnly : Predicate<"Subtarget->getGeneration() ==" 12 "SISubtarget::SEA_ISLANDS">, 13 AssemblerPredicate <"FeatureSeaIslands">; 14 15def DisableInst : Predicate <"false">, AssemblerPredicate<"FeatureDisable">; 16 17// Execpt for the NONE field, this must be kept in sync with the 18// SIEncodingFamily enum in AMDGPUInstrInfo.cpp 19def SIEncodingFamily { 20 int NONE = -1; 21 int SI = 0; 22 int VI = 1; 23} 24 25//===----------------------------------------------------------------------===// 26// SI DAG Nodes 27//===----------------------------------------------------------------------===// 28 29def SIload_constant : SDNode<"AMDGPUISD::LOAD_CONSTANT", 30 SDTypeProfile<1, 2, [SDTCisVT<0, f32>, SDTCisVT<1, v4i32>, SDTCisVT<2, i32>]>, 31 [SDNPMayLoad, SDNPMemOperand] 32>; 33 34def SIatomic_inc : SDNode<"AMDGPUISD::ATOMIC_INC", SDTAtomic2, 35 [SDNPMayLoad, SDNPMayStore, SDNPMemOperand, SDNPHasChain] 36>; 37 38def SIatomic_dec : SDNode<"AMDGPUISD::ATOMIC_DEC", SDTAtomic2, 39 [SDNPMayLoad, SDNPMayStore, SDNPMemOperand, SDNPHasChain] 40>; 41 42def SItbuffer_store : SDNode<"AMDGPUISD::TBUFFER_STORE_FORMAT", 43 SDTypeProfile<0, 13, 44 [SDTCisVT<0, v4i32>, // rsrc(SGPR) 45 SDTCisVT<1, iAny>, // vdata(VGPR) 46 SDTCisVT<2, i32>, // num_channels(imm) 47 SDTCisVT<3, i32>, // vaddr(VGPR) 48 SDTCisVT<4, i32>, // soffset(SGPR) 49 SDTCisVT<5, i32>, // inst_offset(imm) 50 SDTCisVT<6, i32>, // dfmt(imm) 51 SDTCisVT<7, i32>, // nfmt(imm) 52 SDTCisVT<8, i32>, // offen(imm) 53 SDTCisVT<9, i32>, // idxen(imm) 54 SDTCisVT<10, i32>, // glc(imm) 55 SDTCisVT<11, i32>, // slc(imm) 56 SDTCisVT<12, i32> // tfe(imm) 57 ]>, 58 [SDNPMayStore, SDNPMemOperand, SDNPHasChain] 59>; 60 61def SDTBufferLoad : SDTypeProfile<1, 5, 62 [ // vdata 63 SDTCisVT<1, v4i32>, // rsrc 64 SDTCisVT<2, i32>, // vindex 65 SDTCisVT<3, i32>, // offset 66 SDTCisVT<4, i1>, // glc 67 SDTCisVT<5, i1>]>; // slc 68 69def SIbuffer_load : SDNode <"AMDGPUISD::BUFFER_LOAD", SDTBufferLoad, 70 [SDNPMemOperand, SDNPHasChain, SDNPMayLoad]>; 71def SIbuffer_load_format : SDNode <"AMDGPUISD::BUFFER_LOAD_FORMAT", SDTBufferLoad, 72 [SDNPMemOperand, SDNPHasChain, SDNPMayLoad]>; 73 74def SIload_input : SDNode<"AMDGPUISD::LOAD_INPUT", 75 SDTypeProfile<1, 3, [SDTCisVT<0, v4f32>, SDTCisVT<1, v4i32>, SDTCisVT<2, i16>, 76 SDTCisVT<3, i32>]> 77>; 78 79class SDSample<string opcode> : SDNode <opcode, 80 SDTypeProfile<1, 4, [SDTCisVT<0, v4f32>, SDTCisVT<2, v8i32>, 81 SDTCisVT<3, v4i32>, SDTCisVT<4, i32>]> 82>; 83 84def SIsample : SDSample<"AMDGPUISD::SAMPLE">; 85def SIsampleb : SDSample<"AMDGPUISD::SAMPLEB">; 86def SIsampled : SDSample<"AMDGPUISD::SAMPLED">; 87def SIsamplel : SDSample<"AMDGPUISD::SAMPLEL">; 88 89def SIpc_add_rel_offset : SDNode<"AMDGPUISD::PC_ADD_REL_OFFSET", 90 SDTypeProfile<1, 2, [SDTCisVT<0, iPTR>, SDTCisSameAs<0,1>, SDTCisSameAs<0,2>]> 91>; 92 93//===----------------------------------------------------------------------===// 94// PatFrags for global memory operations 95//===----------------------------------------------------------------------===// 96 97defm atomic_inc_global : global_binary_atomic_op<SIatomic_inc>; 98defm atomic_dec_global : global_binary_atomic_op<SIatomic_dec>; 99 100//===----------------------------------------------------------------------===// 101// SDNodes and PatFrag for local loads and stores to enable s_mov_b32 m0, -1 102// to be glued to the memory instructions. 103//===----------------------------------------------------------------------===// 104 105def SIld_local : SDNode <"ISD::LOAD", SDTLoad, 106 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand, SDNPInGlue] 107>; 108 109def si_ld_local : PatFrag <(ops node:$ptr), (SIld_local node:$ptr), [{ 110 return cast<LoadSDNode>(N)->getAddressSpace() == AMDGPUAS::LOCAL_ADDRESS; 111}]>; 112 113def si_load_local : PatFrag <(ops node:$ptr), (si_ld_local node:$ptr), [{ 114 return cast<LoadSDNode>(N)->getAddressingMode() == ISD::UNINDEXED && 115 cast<LoadSDNode>(N)->getExtensionType() == ISD::NON_EXTLOAD; 116}]>; 117 118def si_load_local_align8 : Aligned8Bytes < 119 (ops node:$ptr), (si_load_local node:$ptr) 120>; 121 122def si_sextload_local : PatFrag <(ops node:$ptr), (si_ld_local node:$ptr), [{ 123 return cast<LoadSDNode>(N)->getExtensionType() == ISD::SEXTLOAD; 124}]>; 125def si_az_extload_local : AZExtLoadBase <si_ld_local>; 126 127multiclass SIExtLoadLocal <PatFrag ld_node> { 128 129 def _i8 : PatFrag <(ops node:$ptr), (ld_node node:$ptr), 130 [{return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i8;}] 131 >; 132 133 def _i16 : PatFrag <(ops node:$ptr), (ld_node node:$ptr), 134 [{return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i16;}] 135 >; 136} 137 138defm si_sextload_local : SIExtLoadLocal <si_sextload_local>; 139defm si_az_extload_local : SIExtLoadLocal <si_az_extload_local>; 140 141def SIst_local : SDNode <"ISD::STORE", SDTStore, 142 [SDNPHasChain, SDNPMayStore, SDNPMemOperand, SDNPInGlue] 143>; 144 145def si_st_local : PatFrag < 146 (ops node:$val, node:$ptr), (SIst_local node:$val, node:$ptr), [{ 147 return cast<StoreSDNode>(N)->getAddressSpace() == AMDGPUAS::LOCAL_ADDRESS; 148}]>; 149 150def si_store_local : PatFrag < 151 (ops node:$val, node:$ptr), (si_st_local node:$val, node:$ptr), [{ 152 return cast<StoreSDNode>(N)->getAddressingMode() == ISD::UNINDEXED && 153 !cast<StoreSDNode>(N)->isTruncatingStore(); 154}]>; 155 156def si_store_local_align8 : Aligned8Bytes < 157 (ops node:$val, node:$ptr), (si_store_local node:$val, node:$ptr) 158>; 159 160def si_truncstore_local : PatFrag < 161 (ops node:$val, node:$ptr), (si_st_local node:$val, node:$ptr), [{ 162 return cast<StoreSDNode>(N)->isTruncatingStore(); 163}]>; 164 165def si_truncstore_local_i8 : PatFrag < 166 (ops node:$val, node:$ptr), (si_truncstore_local node:$val, node:$ptr), [{ 167 return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i8; 168}]>; 169 170def si_truncstore_local_i16 : PatFrag < 171 (ops node:$val, node:$ptr), (si_truncstore_local node:$val, node:$ptr), [{ 172 return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i16; 173}]>; 174 175def si_setcc_uniform : PatFrag < 176 (ops node:$lhs, node:$rhs, node:$cond), 177 (setcc node:$lhs, node:$rhs, node:$cond), [{ 178 for (SDNode *Use : N->uses()) { 179 if (Use->isMachineOpcode() || Use->getOpcode() != ISD::CopyToReg) 180 return false; 181 182 unsigned Reg = cast<RegisterSDNode>(Use->getOperand(1))->getReg(); 183 if (Reg != AMDGPU::SCC) 184 return false; 185 } 186 return true; 187}]>; 188 189def si_uniform_br : PatFrag < 190 (ops node:$cond, node:$bb), (brcond node:$cond, node:$bb), [{ 191 return isUniformBr(N); 192}]>; 193 194def si_uniform_br_scc : PatFrag < 195 (ops node:$cond, node:$bb), (si_uniform_br node:$cond, node:$bb), [{ 196 return isCBranchSCC(N); 197}]>; 198 199def lshr_rev : PatFrag < 200 (ops node:$src1, node:$src0), 201 (srl $src0, $src1) 202>; 203 204def ashr_rev : PatFrag < 205 (ops node:$src1, node:$src0), 206 (sra $src0, $src1) 207>; 208 209def lshl_rev : PatFrag < 210 (ops node:$src1, node:$src0), 211 (shl $src0, $src1) 212>; 213 214multiclass SIAtomicM0Glue2 <string op_name, bit is_amdgpu = 0> { 215 216 def _glue : SDNode < 217 !if(is_amdgpu, "AMDGPUISD", "ISD")#"::ATOMIC_"#op_name, SDTAtomic2, 218 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand, SDNPInGlue] 219 >; 220 221 def _local : local_binary_atomic_op <!cast<SDNode>(NAME#"_glue")>; 222} 223 224defm si_atomic_load_add : SIAtomicM0Glue2 <"LOAD_ADD">; 225defm si_atomic_load_sub : SIAtomicM0Glue2 <"LOAD_SUB">; 226defm si_atomic_inc : SIAtomicM0Glue2 <"INC", 1>; 227defm si_atomic_dec : SIAtomicM0Glue2 <"DEC", 1>; 228defm si_atomic_load_and : SIAtomicM0Glue2 <"LOAD_AND">; 229defm si_atomic_load_min : SIAtomicM0Glue2 <"LOAD_MIN">; 230defm si_atomic_load_max : SIAtomicM0Glue2 <"LOAD_MAX">; 231defm si_atomic_load_or : SIAtomicM0Glue2 <"LOAD_OR">; 232defm si_atomic_load_xor : SIAtomicM0Glue2 <"LOAD_XOR">; 233defm si_atomic_load_umin : SIAtomicM0Glue2 <"LOAD_UMIN">; 234defm si_atomic_load_umax : SIAtomicM0Glue2 <"LOAD_UMAX">; 235defm si_atomic_swap : SIAtomicM0Glue2 <"SWAP">; 236 237def si_atomic_cmp_swap_glue : SDNode <"ISD::ATOMIC_CMP_SWAP", SDTAtomic3, 238 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand, SDNPInGlue] 239>; 240 241defm si_atomic_cmp_swap : AtomicCmpSwapLocal <si_atomic_cmp_swap_glue>; 242 243def as_i1imm : SDNodeXForm<imm, [{ 244 return CurDAG->getTargetConstant(N->getZExtValue(), SDLoc(N), MVT::i1); 245}]>; 246 247def as_i8imm : SDNodeXForm<imm, [{ 248 return CurDAG->getTargetConstant(N->getZExtValue(), SDLoc(N), MVT::i8); 249}]>; 250 251def as_i16imm : SDNodeXForm<imm, [{ 252 return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i16); 253}]>; 254 255def as_i32imm: SDNodeXForm<imm, [{ 256 return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i32); 257}]>; 258 259def as_i64imm: SDNodeXForm<imm, [{ 260 return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i64); 261}]>; 262 263// Copied from the AArch64 backend: 264def bitcast_fpimm_to_i32 : SDNodeXForm<fpimm, [{ 265return CurDAG->getTargetConstant( 266 N->getValueAPF().bitcastToAPInt().getZExtValue(), SDLoc(N), MVT::i32); 267}]>; 268 269def frameindex_to_targetframeindex : SDNodeXForm<frameindex, [{ 270 auto FI = cast<FrameIndexSDNode>(N); 271 return CurDAG->getTargetFrameIndex(FI->getIndex(), MVT::i32); 272}]>; 273 274// Copied from the AArch64 backend: 275def bitcast_fpimm_to_i64 : SDNodeXForm<fpimm, [{ 276return CurDAG->getTargetConstant( 277 N->getValueAPF().bitcastToAPInt().getZExtValue(), SDLoc(N), MVT::i64); 278}]>; 279 280def SIMM16bit : PatLeaf <(imm), 281 [{return isInt<16>(N->getSExtValue());}] 282>; 283 284class InlineImm <ValueType vt> : PatLeaf <(vt imm), [{ 285 return isInlineImmediate(N); 286}]>; 287 288class InlineFPImm <ValueType vt> : PatLeaf <(vt fpimm), [{ 289 return isInlineImmediate(N); 290}]>; 291 292class VGPRImm <dag frag> : PatLeaf<frag, [{ 293 if (Subtarget->getGeneration() < SISubtarget::SOUTHERN_ISLANDS) { 294 return false; 295 } 296 const SIRegisterInfo *SIRI = 297 static_cast<const SIRegisterInfo *>(Subtarget->getRegisterInfo()); 298 unsigned Limit = 0; 299 for (SDNode::use_iterator U = N->use_begin(), E = SDNode::use_end(); 300 Limit < 10 && U != E; ++U, ++Limit) { 301 const TargetRegisterClass *RC = getOperandRegClass(*U, U.getOperandNo()); 302 303 // If the register class is unknown, it could be an unknown 304 // register class that needs to be an SGPR, e.g. an inline asm 305 // constraint 306 if (!RC || SIRI->isSGPRClass(RC)) 307 return false; 308 } 309 310 return Limit < 10; 311}]>; 312 313def NegateImm : SDNodeXForm<imm, [{ 314 return CurDAG->getConstant(-N->getSExtValue(), SDLoc(N), MVT::i32); 315}]>; 316 317// TODO: When FP inline imm values work? 318def NegSubInlineConst32 : ImmLeaf<i32, [{ 319 return Imm < -16 && Imm >= -64; 320}], NegateImm>; 321 322def NegSubInlineConst16 : ImmLeaf<i16, [{ 323 return Imm < -16 && Imm >= -64; 324}], NegateImm>; 325 326//===----------------------------------------------------------------------===// 327// Custom Operands 328//===----------------------------------------------------------------------===// 329 330def SoppBrTarget : AsmOperandClass { 331 let Name = "SoppBrTarget"; 332 let ParserMethod = "parseSOppBrTarget"; 333} 334 335def sopp_brtarget : Operand<OtherVT> { 336 let EncoderMethod = "getSOPPBrEncoding"; 337 let DecoderMethod = "decodeSoppBrTarget"; 338 let OperandType = "OPERAND_PCREL"; 339 let ParserMatchClass = SoppBrTarget; 340} 341 342def si_ga : Operand<iPTR>; 343 344def InterpSlotMatchClass : AsmOperandClass { 345 let Name = "InterpSlot"; 346 let PredicateMethod = "isInterpSlot"; 347 let ParserMethod = "parseInterpSlot"; 348 let RenderMethod = "addImmOperands"; 349} 350 351def InterpSlot : Operand<i32> { 352 let PrintMethod = "printInterpSlot"; 353 let ParserMatchClass = InterpSlotMatchClass; 354 let OperandType = "OPERAND_IMMEDIATE"; 355} 356 357def AttrMatchClass : AsmOperandClass { 358 let Name = "Attr"; 359 let PredicateMethod = "isInterpAttr"; 360 let ParserMethod = "parseInterpAttr"; 361 let RenderMethod = "addImmOperands"; 362} 363 364// It appears to be necessary to create a separate operand for this to 365// be able to parse attr<num> with no space. 366def Attr : Operand<i32> { 367 let PrintMethod = "printInterpAttr"; 368 let ParserMatchClass = AttrMatchClass; 369 let OperandType = "OPERAND_IMMEDIATE"; 370} 371 372def AttrChanMatchClass : AsmOperandClass { 373 let Name = "AttrChan"; 374 let PredicateMethod = "isAttrChan"; 375 let RenderMethod = "addImmOperands"; 376} 377 378def AttrChan : Operand<i32> { 379 let PrintMethod = "printInterpAttrChan"; 380 let ParserMatchClass = AttrChanMatchClass; 381 let OperandType = "OPERAND_IMMEDIATE"; 382} 383 384def SendMsgMatchClass : AsmOperandClass { 385 let Name = "SendMsg"; 386 let PredicateMethod = "isSendMsg"; 387 let ParserMethod = "parseSendMsgOp"; 388 let RenderMethod = "addImmOperands"; 389} 390 391def ExpTgtMatchClass : AsmOperandClass { 392 let Name = "ExpTgt"; 393 let PredicateMethod = "isExpTgt"; 394 let ParserMethod = "parseExpTgt"; 395 let RenderMethod = "printExpTgt"; 396} 397 398def SendMsgImm : Operand<i32> { 399 let PrintMethod = "printSendMsg"; 400 let ParserMatchClass = SendMsgMatchClass; 401} 402 403def SWaitMatchClass : AsmOperandClass { 404 let Name = "SWaitCnt"; 405 let RenderMethod = "addImmOperands"; 406 let ParserMethod = "parseSWaitCntOps"; 407} 408 409def VReg32OrOffClass : AsmOperandClass { 410 let Name = "VReg32OrOff"; 411 let ParserMethod = "parseVReg32OrOff"; 412} 413 414def WAIT_FLAG : Operand <i32> { 415 let ParserMatchClass = SWaitMatchClass; 416 let PrintMethod = "printWaitFlag"; 417} 418 419include "SIInstrFormats.td" 420include "VIInstrFormats.td" 421 422// ===----------------------------------------------------------------------===// 423// ExpSrc* Special cases for exp src operands which are printed as 424// "off" depending on en operand. 425// ===----------------------------------------------------------------------===// 426 427def ExpSrc0 : RegisterOperand<VGPR_32> { 428 let PrintMethod = "printExpSrc0"; 429 let ParserMatchClass = VReg32OrOffClass; 430} 431 432def ExpSrc1 : RegisterOperand<VGPR_32> { 433 let PrintMethod = "printExpSrc1"; 434 let ParserMatchClass = VReg32OrOffClass; 435} 436 437def ExpSrc2 : RegisterOperand<VGPR_32> { 438 let PrintMethod = "printExpSrc2"; 439 let ParserMatchClass = VReg32OrOffClass; 440} 441 442def ExpSrc3 : RegisterOperand<VGPR_32> { 443 let PrintMethod = "printExpSrc3"; 444 let ParserMatchClass = VReg32OrOffClass; 445} 446 447class NamedMatchClass<string CName, bit Optional = 1> : AsmOperandClass { 448 let Name = "Imm"#CName; 449 let PredicateMethod = "is"#CName; 450 let ParserMethod = !if(Optional, "parseOptionalOperand", "parse"#CName); 451 let RenderMethod = "addImmOperands"; 452 let IsOptional = Optional; 453 let DefaultMethod = !if(Optional, "default"#CName, ?); 454} 455 456class NamedOperandBit<string Name, AsmOperandClass MatchClass> : Operand<i1> { 457 let PrintMethod = "print"#Name; 458 let ParserMatchClass = MatchClass; 459} 460 461class NamedOperandU8<string Name, AsmOperandClass MatchClass> : Operand<i8> { 462 let PrintMethod = "print"#Name; 463 let ParserMatchClass = MatchClass; 464} 465 466class NamedOperandU16<string Name, AsmOperandClass MatchClass> : Operand<i16> { 467 let PrintMethod = "print"#Name; 468 let ParserMatchClass = MatchClass; 469} 470 471class NamedOperandU32<string Name, AsmOperandClass MatchClass> : Operand<i32> { 472 let PrintMethod = "print"#Name; 473 let ParserMatchClass = MatchClass; 474} 475 476class NamedOperandU32Default0<string Name, AsmOperandClass MatchClass> : 477 OperandWithDefaultOps<i32, (ops (i32 0))> { 478 let PrintMethod = "print"#Name; 479 let ParserMatchClass = MatchClass; 480} 481 482let OperandType = "OPERAND_IMMEDIATE" in { 483 484def offen : NamedOperandBit<"Offen", NamedMatchClass<"Offen">>; 485def idxen : NamedOperandBit<"Idxen", NamedMatchClass<"Idxen">>; 486def addr64 : NamedOperandBit<"Addr64", NamedMatchClass<"Addr64">>; 487 488def offset : NamedOperandU16<"Offset", NamedMatchClass<"Offset">>; 489def offset0 : NamedOperandU8<"Offset0", NamedMatchClass<"Offset0">>; 490def offset1 : NamedOperandU8<"Offset1", NamedMatchClass<"Offset1">>; 491 492def gds : NamedOperandBit<"GDS", NamedMatchClass<"GDS">>; 493 494def omod : NamedOperandU32<"OModSI", NamedMatchClass<"OModSI">>; 495def clampmod : NamedOperandBit<"ClampSI", NamedMatchClass<"ClampSI">>; 496 497def GLC : NamedOperandBit<"GLC", NamedMatchClass<"GLC">>; 498def slc : NamedOperandBit<"SLC", NamedMatchClass<"SLC">>; 499def tfe : NamedOperandBit<"TFE", NamedMatchClass<"TFE">>; 500def unorm : NamedOperandBit<"UNorm", NamedMatchClass<"UNorm">>; 501def da : NamedOperandBit<"DA", NamedMatchClass<"DA">>; 502def r128 : NamedOperandBit<"R128", NamedMatchClass<"R128">>; 503def lwe : NamedOperandBit<"LWE", NamedMatchClass<"LWE">>; 504def exp_compr : NamedOperandBit<"ExpCompr", NamedMatchClass<"ExpCompr">>; 505def exp_vm : NamedOperandBit<"ExpVM", NamedMatchClass<"ExpVM">>; 506 507def dmask : NamedOperandU16<"DMask", NamedMatchClass<"DMask">>; 508 509def dpp_ctrl : NamedOperandU32<"DPPCtrl", NamedMatchClass<"DPPCtrl", 0>>; 510def row_mask : NamedOperandU32<"RowMask", NamedMatchClass<"RowMask">>; 511def bank_mask : NamedOperandU32<"BankMask", NamedMatchClass<"BankMask">>; 512def bound_ctrl : NamedOperandBit<"BoundCtrl", NamedMatchClass<"BoundCtrl">>; 513 514def dst_sel : NamedOperandU32<"SDWADstSel", NamedMatchClass<"SDWADstSel">>; 515def src0_sel : NamedOperandU32<"SDWASrc0Sel", NamedMatchClass<"SDWASrc0Sel">>; 516def src1_sel : NamedOperandU32<"SDWASrc1Sel", NamedMatchClass<"SDWASrc1Sel">>; 517def dst_unused : NamedOperandU32<"SDWADstUnused", NamedMatchClass<"SDWADstUnused">>; 518 519def op_sel : NamedOperandU32Default0<"OpSel", NamedMatchClass<"OpSel">>; 520def op_sel_hi : NamedOperandU32Default0<"OpSelHi", NamedMatchClass<"OpSelHi">>; 521def neg_lo : NamedOperandU32Default0<"NegLo", NamedMatchClass<"NegLo">>; 522def neg_hi : NamedOperandU32Default0<"NegHi", NamedMatchClass<"NegHi">>; 523 524def hwreg : NamedOperandU16<"Hwreg", NamedMatchClass<"Hwreg", 0>>; 525 526def exp_tgt : NamedOperandU8<"ExpTgt", NamedMatchClass<"ExpTgt", 0>> { 527 528} 529 530} // End OperandType = "OPERAND_IMMEDIATE" 531 532class KImmMatchClass<int size> : AsmOperandClass { 533 let Name = "KImmFP"#size; 534 let PredicateMethod = "isKImmFP"#size; 535 let ParserMethod = "parseImm"; 536 let RenderMethod = "addKImmFP"#size#"Operands"; 537} 538 539class kimmOperand<ValueType vt> : Operand<vt> { 540 let OperandNamespace = "AMDGPU"; 541 let OperandType = "OPERAND_KIMM"#vt.Size; 542 let PrintMethod = "printU"#vt.Size#"ImmOperand"; 543 let ParserMatchClass = !cast<AsmOperandClass>("KImmFP"#vt.Size#"MatchClass"); 544} 545 546// 32-bit VALU immediate operand that uses the constant bus. 547def KImmFP32MatchClass : KImmMatchClass<32>; 548def f32kimm : kimmOperand<i32>; 549 550// 32-bit VALU immediate operand with a 16-bit value that uses the 551// constant bus. 552def KImmFP16MatchClass : KImmMatchClass<16>; 553def f16kimm : kimmOperand<i16>; 554 555 556def VOPDstS64 : VOPDstOperand <SReg_64>; 557 558class FPInputModsMatchClass <int opSize> : AsmOperandClass { 559 let Name = "RegOrImmWithFP"#opSize#"InputMods"; 560 let ParserMethod = "parseRegOrImmWithFPInputMods"; 561 let PredicateMethod = "isRegOrImmWithFP"#opSize#"InputMods"; 562} 563 564def FP16InputModsMatchClass : FPInputModsMatchClass<16>; 565def FP32InputModsMatchClass : FPInputModsMatchClass<32>; 566def FP64InputModsMatchClass : FPInputModsMatchClass<64>; 567 568class InputMods <AsmOperandClass matchClass> : Operand <i32> { 569 let OperandNamespace = "AMDGPU"; 570 let OperandType = "OPERAND_INPUT_MODS"; 571 let ParserMatchClass = matchClass; 572} 573 574class FPInputMods <FPInputModsMatchClass matchClass> : InputMods <matchClass> { 575 let PrintMethod = "printOperandAndFPInputMods"; 576} 577 578def FP16InputMods : FPInputMods<FP16InputModsMatchClass>; 579def FP32InputMods : FPInputMods<FP32InputModsMatchClass>; 580def FP64InputMods : FPInputMods<FP64InputModsMatchClass>; 581 582class IntInputModsMatchClass <int opSize> : AsmOperandClass { 583 let Name = "RegOrImmWithInt"#opSize#"InputMods"; 584 let ParserMethod = "parseRegOrImmWithIntInputMods"; 585 let PredicateMethod = "isRegOrImmWithInt"#opSize#"InputMods"; 586} 587def Int32InputModsMatchClass : IntInputModsMatchClass<32>; 588def Int64InputModsMatchClass : IntInputModsMatchClass<64>; 589 590class IntInputMods <IntInputModsMatchClass matchClass> : InputMods <matchClass> { 591 let PrintMethod = "printOperandAndIntInputMods"; 592} 593def Int32InputMods : IntInputMods<Int32InputModsMatchClass>; 594def Int64InputMods : IntInputMods<Int64InputModsMatchClass>; 595 596def FPVRegInputModsMatchClass : AsmOperandClass { 597 let Name = "VRegWithFPInputMods"; 598 let ParserMethod = "parseRegWithFPInputMods"; 599 let PredicateMethod = "isVReg"; 600} 601 602def FPVRegInputMods : InputMods <FPVRegInputModsMatchClass> { 603 let PrintMethod = "printOperandAndFPInputMods"; 604} 605 606def IntVRegInputModsMatchClass : AsmOperandClass { 607 let Name = "VRegWithIntInputMods"; 608 let ParserMethod = "parseRegWithIntInputMods"; 609 let PredicateMethod = "isVReg"; 610} 611 612def IntVRegInputMods : InputMods <IntVRegInputModsMatchClass> { 613 let PrintMethod = "printOperandAndIntInputMods"; 614} 615 616class PackedFPInputModsMatchClass <int opSize> : AsmOperandClass { 617 let Name = "PackedFP"#opSize#"InputMods"; 618 let ParserMethod = "parseRegOrImm"; 619 let PredicateMethod = "isRegOrImm"; 620// let PredicateMethod = "isPackedFP"#opSize#"InputMods"; 621} 622 623class PackedIntInputModsMatchClass <int opSize> : AsmOperandClass { 624 let Name = "PackedInt"#opSize#"InputMods"; 625 let ParserMethod = "parseRegOrImm"; 626 let PredicateMethod = "isRegOrImm"; 627// let PredicateMethod = "isPackedInt"#opSize#"InputMods"; 628} 629 630def PackedF16InputModsMatchClass : PackedFPInputModsMatchClass<16>; 631def PackedI16InputModsMatchClass : PackedIntInputModsMatchClass<16>; 632 633class PackedFPInputMods <PackedFPInputModsMatchClass matchClass> : InputMods <matchClass> { 634// let PrintMethod = "printPackedFPInputMods"; 635} 636 637class PackedIntInputMods <PackedIntInputModsMatchClass matchClass> : InputMods <matchClass> { 638 //let PrintMethod = "printPackedIntInputMods"; 639} 640 641def PackedF16InputMods : PackedFPInputMods<PackedF16InputModsMatchClass>; 642def PackedI16InputMods : PackedIntInputMods<PackedI16InputModsMatchClass>; 643 644//===----------------------------------------------------------------------===// 645// Complex patterns 646//===----------------------------------------------------------------------===// 647 648def DS1Addr1Offset : ComplexPattern<i32, 2, "SelectDS1Addr1Offset">; 649def DS64Bit4ByteAligned : ComplexPattern<i32, 3, "SelectDS64Bit4ByteAligned">; 650 651def MOVRELOffset : ComplexPattern<i32, 2, "SelectMOVRELOffset">; 652 653def VOP3Mods0 : ComplexPattern<untyped, 4, "SelectVOP3Mods0">; 654def VOP3NoMods0 : ComplexPattern<untyped, 4, "SelectVOP3NoMods0">; 655def VOP3Mods0Clamp : ComplexPattern<untyped, 3, "SelectVOP3Mods0Clamp">; 656def VOP3Mods0Clamp0OMod : ComplexPattern<untyped, 4, "SelectVOP3Mods0Clamp0OMod">; 657def VOP3Mods : ComplexPattern<untyped, 2, "SelectVOP3Mods">; 658def VOP3NoMods : ComplexPattern<untyped, 2, "SelectVOP3NoMods">; 659// VOP3Mods, but the input source is known to never be NaN. 660def VOP3Mods_nnan : ComplexPattern<fAny, 2, "SelectVOP3Mods_NNaN">; 661 662def VOP3PMods : ComplexPattern<untyped, 2, "SelectVOP3PMods">; 663def VOP3PMods0 : ComplexPattern<untyped, 3, "SelectVOP3PMods0">; 664 665 666//===----------------------------------------------------------------------===// 667// SI assembler operands 668//===----------------------------------------------------------------------===// 669 670def SIOperand { 671 int ZERO = 0x80; 672 int VCC = 0x6A; 673 int FLAT_SCR = 0x68; 674} 675 676// This should be kept in sync with SISrcMods enum 677def SRCMODS { 678 int NONE = 0; 679 int NEG = 1; 680 int ABS = 2; 681 int NEG_ABS = 3; 682 683 int NEG_HI = ABS; 684 int OP_SEL_0 = 4; 685 int OP_SEL_1 = 8; 686} 687 688def DSTCLAMP { 689 int NONE = 0; 690 int ENABLE = 1; 691} 692 693def DSTOMOD { 694 int NONE = 0; 695} 696 697def TRAPID{ 698 int LLVM_TRAP = 2; 699 int LLVM_DEBUG_TRAP = 3; 700} 701 702//===----------------------------------------------------------------------===// 703// 704// SI Instruction multiclass helpers. 705// 706// Instructions with _32 take 32-bit operands. 707// Instructions with _64 take 64-bit operands. 708// 709// VOP_* instructions can use either a 32-bit or 64-bit encoding. The 32-bit 710// encoding is the standard encoding, but instruction that make use of 711// any of the instruction modifiers must use the 64-bit encoding. 712// 713// Instructions with _e32 use the 32-bit encoding. 714// Instructions with _e64 use the 64-bit encoding. 715// 716//===----------------------------------------------------------------------===// 717 718class SIMCInstr <string pseudo, int subtarget> { 719 string PseudoInstr = pseudo; 720 int Subtarget = subtarget; 721} 722 723//===----------------------------------------------------------------------===// 724// EXP classes 725//===----------------------------------------------------------------------===// 726 727class EXP_Helper<bit done, SDPatternOperator node = null_frag> : EXPCommon< 728 (outs), 729 (ins exp_tgt:$tgt, 730 ExpSrc0:$src0, ExpSrc1:$src1, ExpSrc2:$src2, ExpSrc3:$src3, 731 exp_vm:$vm, exp_compr:$compr, i8imm:$en), 732 "exp$tgt $src0, $src1, $src2, $src3"#!if(done, " done", "")#"$compr$vm", 733 [(node (i8 timm:$tgt), (i8 timm:$en), 734 f32:$src0, f32:$src1, f32:$src2, f32:$src3, 735 (i1 timm:$compr), (i1 timm:$vm))]> { 736 let AsmMatchConverter = "cvtExp"; 737} 738 739// Split EXP instruction into EXP and EXP_DONE so we can set 740// mayLoad for done=1. 741multiclass EXP_m<bit done, SDPatternOperator node> { 742 let mayLoad = done in { 743 let isPseudo = 1, isCodeGenOnly = 1 in { 744 def "" : EXP_Helper<done, node>, 745 SIMCInstr <"exp"#!if(done, "_done", ""), SIEncodingFamily.NONE>; 746 } 747 748 let done = done in { 749 def _si : EXP_Helper<done>, 750 SIMCInstr <"exp"#!if(done, "_done", ""), SIEncodingFamily.SI>, 751 EXPe { 752 let AssemblerPredicates = [isSICI]; 753 let DecoderNamespace = "SICI"; 754 let DisableDecoder = DisableSIDecoder; 755 } 756 757 def _vi : EXP_Helper<done>, 758 SIMCInstr <"exp"#!if(done, "_done", ""), SIEncodingFamily.VI>, 759 EXPe_vi { 760 let AssemblerPredicates = [isVI]; 761 let DecoderNamespace = "VI"; 762 let DisableDecoder = DisableVIDecoder; 763 } 764 } 765 } 766} 767 768//===----------------------------------------------------------------------===// 769// Vector ALU classes 770//===----------------------------------------------------------------------===// 771 772class getNumSrcArgs<ValueType Src0, ValueType Src1, ValueType Src2> { 773 int ret = 774 !if (!eq(Src0.Value, untyped.Value), 0, 775 !if (!eq(Src1.Value, untyped.Value), 1, // VOP1 776 !if (!eq(Src2.Value, untyped.Value), 2, // VOP2 777 3))); // VOP3 778} 779 780// Returns the register class to use for the destination of VOP[123C] 781// instructions for the given VT. 782class getVALUDstForVT<ValueType VT> { 783 RegisterOperand ret = !if(!eq(VT.Size, 32), VOPDstOperand<VGPR_32>, 784 !if(!eq(VT.Size, 128), VOPDstOperand<VReg_128>, 785 !if(!eq(VT.Size, 64), VOPDstOperand<VReg_64>, 786 !if(!eq(VT.Size, 16), VOPDstOperand<VGPR_32>, 787 VOPDstOperand<SReg_64>)))); // else VT == i1 788} 789 790// Returns the register class to use for source 0 of VOP[12C] 791// instructions for the given VT. 792class getVOPSrc0ForVT<ValueType VT> { 793 bit isFP = !if(!eq(VT.Value, f16.Value), 1, 794 !if(!eq(VT.Value, v2f16.Value), 1, 795 !if(!eq(VT.Value, f32.Value), 1, 796 !if(!eq(VT.Value, f64.Value), 1, 797 0)))); 798 799 RegisterOperand ret = 800 !if(isFP, 801 !if(!eq(VT.Size, 64), 802 VSrc_f64, 803 !if(!eq(VT.Value, f16.Value), 804 VSrc_f16, 805 !if(!eq(VT.Value, v2f16.Value), 806 VCSrc_v2f16, 807 VSrc_f32 808 ) 809 ) 810 ), 811 !if(!eq(VT.Size, 64), 812 VSrc_b64, 813 !if(!eq(VT.Value, i16.Value), 814 VSrc_b16, 815 !if(!eq(VT.Value, v2i16.Value), 816 VCSrc_v2b16, 817 VSrc_b32 818 ) 819 ) 820 ) 821 ); 822} 823 824// Returns the vreg register class to use for source operand given VT 825class getVregSrcForVT<ValueType VT> { 826 RegisterClass ret = !if(!eq(VT.Size, 128), VReg_128, 827 !if(!eq(VT.Size, 64), VReg_64, VGPR_32)); 828} 829 830 831// Returns the register class to use for sources of VOP3 instructions for the 832// given VT. 833class getVOP3SrcForVT<ValueType VT> { 834 bit isFP = !if(!eq(VT.Value, f16.Value), 1, 835 !if(!eq(VT.Value, v2f16.Value), 1, 836 !if(!eq(VT.Value, f32.Value), 1, 837 !if(!eq(VT.Value, f64.Value), 1, 838 0)))); 839 RegisterOperand ret = 840 !if(!eq(VT.Size, 128), 841 VSrc_128, 842 !if(!eq(VT.Size, 64), 843 !if(isFP, 844 VCSrc_f64, 845 VCSrc_b64), 846 !if(!eq(VT.Value, i1.Value), 847 SCSrc_b64, 848 !if(isFP, 849 !if(!eq(VT.Value, f16.Value), 850 VCSrc_f16, 851 !if(!eq(VT.Value, v2f16.Value), 852 VCSrc_v2f16, 853 VCSrc_f32 854 ) 855 ), 856 !if(!eq(VT.Value, i16.Value), 857 VCSrc_b16, 858 !if(!eq(VT.Value, v2i16.Value), 859 VCSrc_v2b16, 860 VCSrc_b32 861 ) 862 ) 863 ) 864 ) 865 ) 866 ); 867} 868 869// Returns 1 if the source arguments have modifiers, 0 if they do not. 870// XXX - do f16 instructions? 871class isFloatType<ValueType SrcVT> { 872 bit ret = 873 !if(!eq(SrcVT.Value, f16.Value), 1, 874 !if(!eq(SrcVT.Value, f32.Value), 1, 875 !if(!eq(SrcVT.Value, f64.Value), 1, 876 !if(!eq(SrcVT.Value, v2f16.Value), 1, 877 0)))); 878} 879 880class isIntType<ValueType SrcVT> { 881 bit ret = 882 !if(!eq(SrcVT.Value, i16.Value), 1, 883 !if(!eq(SrcVT.Value, i32.Value), 1, 884 !if(!eq(SrcVT.Value, i64.Value), 1, 885 0))); 886} 887 888class isPackedType<ValueType SrcVT> { 889 bit ret = 890 !if(!eq(SrcVT.Value, v2i16.Value), 1, 891 !if(!eq(SrcVT.Value, v2f16.Value), 1, 0) 892 ); 893} 894 895// Float or packed int 896class isModifierType<ValueType SrcVT> { 897 bit ret = 898 !if(!eq(SrcVT.Value, f16.Value), 1, 899 !if(!eq(SrcVT.Value, f32.Value), 1, 900 !if(!eq(SrcVT.Value, f64.Value), 1, 901 !if(!eq(SrcVT.Value, v2f16.Value), 1, 902 !if(!eq(SrcVT.Value, v2i16.Value), 1, 903 0))))); 904} 905 906// Return type of input modifiers operand for specified input operand 907class getSrcMod <ValueType VT> { 908 bit isFP = !if(!eq(VT.Value, f16.Value), 1, 909 !if(!eq(VT.Value, f32.Value), 1, 910 !if(!eq(VT.Value, f64.Value), 1, 911 0))); 912 bit isPacked = isPackedType<VT>.ret; 913 Operand ret = !if(!eq(VT.Size, 64), 914 !if(isFP, FP64InputMods, Int64InputMods), 915 !if(isFP, 916 !if(!eq(VT.Value, f16.Value), 917 FP16InputMods, 918 FP32InputMods 919 ), 920 Int32InputMods) 921 ); 922} 923 924// Return type of input modifiers operand specified input operand for SDWA/DPP 925class getSrcModExt <ValueType VT> { 926 bit isFP = !if(!eq(VT.Value, f16.Value), 1, 927 !if(!eq(VT.Value, f32.Value), 1, 928 !if(!eq(VT.Value, f64.Value), 1, 929 0))); 930 Operand ret = !if(isFP, FPVRegInputMods, IntVRegInputMods); 931} 932 933// Returns the input arguments for VOP[12C] instructions for the given SrcVT. 934class getIns32 <RegisterOperand Src0RC, RegisterClass Src1RC, int NumSrcArgs> { 935 dag ret = !if(!eq(NumSrcArgs, 1), (ins Src0RC:$src0), // VOP1 936 !if(!eq(NumSrcArgs, 2), (ins Src0RC:$src0, Src1RC:$src1), // VOP2 937 (ins))); 938} 939 940// Returns the input arguments for VOP3 instructions for the given SrcVT. 941class getIns64 <RegisterOperand Src0RC, RegisterOperand Src1RC, 942 RegisterOperand Src2RC, int NumSrcArgs, 943 bit HasModifiers, bit HasOMod, 944 Operand Src0Mod, Operand Src1Mod, Operand Src2Mod> { 945 946 dag ret = 947 !if (!eq(NumSrcArgs, 0), 948 // VOP1 without input operands (V_NOP, V_CLREXCP) 949 (ins), 950 /* else */ 951 !if (!eq(NumSrcArgs, 1), 952 !if (!eq(HasModifiers, 1), 953 // VOP1 with modifiers 954 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 955 clampmod:$clamp, omod:$omod) 956 /* else */, 957 // VOP1 without modifiers 958 (ins Src0RC:$src0) 959 /* endif */ ), 960 !if (!eq(NumSrcArgs, 2), 961 !if (!eq(HasModifiers, 1), 962 // VOP 2 with modifiers 963 !if( !eq(HasOMod, 1), 964 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 965 Src1Mod:$src1_modifiers, Src1RC:$src1, 966 clampmod:$clamp, omod:$omod), 967 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 968 Src1Mod:$src1_modifiers, Src1RC:$src1, 969 clampmod:$clamp)) 970 /* else */, 971 // VOP2 without modifiers 972 (ins Src0RC:$src0, Src1RC:$src1) 973 /* endif */ ) 974 /* NumSrcArgs == 3 */, 975 !if (!eq(HasModifiers, 1), 976 // VOP3 with modifiers 977 !if (!eq(HasOMod, 1), 978 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 979 Src1Mod:$src1_modifiers, Src1RC:$src1, 980 Src2Mod:$src2_modifiers, Src2RC:$src2, 981 clampmod:$clamp, omod:$omod), 982 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 983 Src1Mod:$src1_modifiers, Src1RC:$src1, 984 Src2Mod:$src2_modifiers, Src2RC:$src2, 985 clampmod:$clamp)) 986 /* else */, 987 // VOP3 without modifiers 988 (ins Src0RC:$src0, Src1RC:$src1, Src2RC:$src2) 989 /* endif */ )))); 990} 991 992/// XXX - src1 may only allow VGPRs? 993 994// The modifiers (except clamp) are dummy operands for the benefit of 995// printing and parsing. They defer their values to looking at the 996// srcN_modifiers for what to print. 997class getInsVOP3P <RegisterOperand Src0RC, RegisterOperand Src1RC, 998 RegisterOperand Src2RC, int NumSrcArgs, 999 bit HasClamp, 1000 Operand Src0Mod, Operand Src1Mod, Operand Src2Mod> { 1001 dag ret = !if (!eq(NumSrcArgs, 2), 1002 !if (HasClamp, 1003 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 1004 Src1Mod:$src1_modifiers, Src1RC:$src1, 1005 clampmod:$clamp, 1006 op_sel:$op_sel, op_sel_hi:$op_sel_hi, 1007 neg_lo:$neg_lo, neg_hi:$neg_hi), 1008 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 1009 Src1Mod:$src1_modifiers, Src1RC:$src1, 1010 op_sel:$op_sel, op_sel_hi:$op_sel_hi, 1011 neg_lo:$neg_lo, neg_hi:$neg_hi)), 1012 // else NumSrcArgs == 3 1013 !if (HasClamp, 1014 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 1015 Src1Mod:$src1_modifiers, Src1RC:$src1, 1016 Src2Mod:$src2_modifiers, Src2RC:$src2, 1017 clampmod:$clamp, 1018 op_sel:$op_sel, op_sel_hi:$op_sel_hi, 1019 neg_lo:$neg_lo, neg_hi:$neg_hi), 1020 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 1021 Src1Mod:$src1_modifiers, Src1RC:$src1, 1022 Src2Mod:$src2_modifiers, Src2RC:$src2, 1023 op_sel:$op_sel, op_sel_hi:$op_sel_hi, 1024 neg_lo:$neg_lo, neg_hi:$neg_hi)) 1025 ); 1026} 1027 1028class getInsDPP <RegisterClass Src0RC, RegisterClass Src1RC, int NumSrcArgs, 1029 bit HasModifiers, Operand Src0Mod, Operand Src1Mod> { 1030 1031 dag ret = !if (!eq(NumSrcArgs, 0), 1032 // VOP1 without input operands (V_NOP) 1033 (ins dpp_ctrl:$dpp_ctrl, row_mask:$row_mask, 1034 bank_mask:$bank_mask, bound_ctrl:$bound_ctrl), 1035 !if (!eq(NumSrcArgs, 1), 1036 !if (!eq(HasModifiers, 1), 1037 // VOP1_DPP with modifiers 1038 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 1039 dpp_ctrl:$dpp_ctrl, row_mask:$row_mask, 1040 bank_mask:$bank_mask, bound_ctrl:$bound_ctrl) 1041 /* else */, 1042 // VOP1_DPP without modifiers 1043 (ins Src0RC:$src0, dpp_ctrl:$dpp_ctrl, row_mask:$row_mask, 1044 bank_mask:$bank_mask, bound_ctrl:$bound_ctrl) 1045 /* endif */) 1046 /* NumSrcArgs == 2 */, 1047 !if (!eq(HasModifiers, 1), 1048 // VOP2_DPP with modifiers 1049 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 1050 Src1Mod:$src1_modifiers, Src1RC:$src1, 1051 dpp_ctrl:$dpp_ctrl, row_mask:$row_mask, 1052 bank_mask:$bank_mask, bound_ctrl:$bound_ctrl) 1053 /* else */, 1054 // VOP2_DPP without modifiers 1055 (ins Src0RC:$src0, Src1RC:$src1, dpp_ctrl:$dpp_ctrl, 1056 row_mask:$row_mask, bank_mask:$bank_mask, 1057 bound_ctrl:$bound_ctrl) 1058 /* endif */))); 1059} 1060 1061class getInsSDWA <RegisterClass Src0RC, RegisterClass Src1RC, int NumSrcArgs, 1062 bit HasFloatModifiers, Operand Src0Mod, Operand Src1Mod, 1063 ValueType DstVT> { 1064 1065 dag ret = !if(!eq(NumSrcArgs, 0), 1066 // VOP1 without input operands (V_NOP) 1067 (ins), 1068 !if(!eq(NumSrcArgs, 1), 1069 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 1070 clampmod:$clamp, dst_sel:$dst_sel, dst_unused:$dst_unused, 1071 src0_sel:$src0_sel), 1072 !if(!eq(NumSrcArgs, 2), 1073 !if(!eq(DstVT.Size, 1), 1074 // VOPC_SDWA with modifiers 1075 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 1076 Src1Mod:$src1_modifiers, Src1RC:$src1, 1077 clampmod:$clamp, src0_sel:$src0_sel, src1_sel:$src1_sel), 1078 // VOP2_SDWA or VOPC_SDWA with modifiers 1079 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 1080 Src1Mod:$src1_modifiers, Src1RC:$src1, 1081 clampmod:$clamp, dst_sel:$dst_sel, dst_unused:$dst_unused, 1082 src0_sel:$src0_sel, src1_sel:$src1_sel)), 1083 (ins)/* endif */))); 1084} 1085 1086// Outs for DPP and SDWA 1087class getOutsExt <bit HasDst, ValueType DstVT, RegisterOperand DstRCDPP> { 1088 dag ret = !if(HasDst, 1089 !if(!eq(DstVT.Size, 1), 1090 (outs), // no dst for VOPC, we use "vcc"-token as dst in SDWA VOPC instructions 1091 (outs DstRCDPP:$vdst)), 1092 (outs)); // V_NOP 1093} 1094 1095// Returns the assembly string for the inputs and outputs of a VOP[12C] 1096// instruction. This does not add the _e32 suffix, so it can be reused 1097// by getAsm64. 1098class getAsm32 <bit HasDst, int NumSrcArgs, ValueType DstVT = i32> { 1099 string dst = !if(!eq(DstVT.Size, 1), "$sdst", "$vdst"); // use $sdst for VOPC 1100 string src0 = ", $src0"; 1101 string src1 = ", $src1"; 1102 string src2 = ", $src2"; 1103 string ret = !if(HasDst, dst, "") # 1104 !if(!eq(NumSrcArgs, 1), src0, "") # 1105 !if(!eq(NumSrcArgs, 2), src0#src1, "") # 1106 !if(!eq(NumSrcArgs, 3), src0#src1#src2, ""); 1107} 1108 1109// Returns the assembly string for the inputs and outputs of a VOP3 1110// instruction. 1111class getAsm64 <bit HasDst, int NumSrcArgs, bit HasModifiers, 1112 bit HasOMod, ValueType DstVT = i32> { 1113 string dst = !if(!eq(DstVT.Size, 1), "$sdst", "$vdst"); // use $sdst for VOPC 1114 string src0 = !if(!eq(NumSrcArgs, 1), "$src0_modifiers", "$src0_modifiers,"); 1115 string src1 = !if(!eq(NumSrcArgs, 1), "", 1116 !if(!eq(NumSrcArgs, 2), " $src1_modifiers", 1117 " $src1_modifiers,")); 1118 string src2 = !if(!eq(NumSrcArgs, 3), " $src2_modifiers", ""); 1119 string ret = 1120 !if(!eq(HasModifiers, 0), 1121 getAsm32<HasDst, NumSrcArgs, DstVT>.ret, 1122 dst#", "#src0#src1#src2#"$clamp"#!if(HasOMod, "$omod", "")); 1123} 1124 1125// Returns the assembly string for the inputs and outputs of a VOP3P 1126// instruction. 1127class getAsmVOP3P <bit HasDst, int NumSrcArgs, bit HasModifiers, 1128 bit HasClamp, ValueType DstVT = i32> { 1129 string dst = " $vdst"; 1130 string src0 = !if(!eq(NumSrcArgs, 1), "$src0", "$src0,"); 1131 string src1 = !if(!eq(NumSrcArgs, 1), "", 1132 !if(!eq(NumSrcArgs, 2), " $src1", 1133 " $src1,")); 1134 string src2 = !if(!eq(NumSrcArgs, 3), " $src2", ""); 1135 1136 string mods = !if(HasModifiers, "$neg_lo$neg_hi", ""); 1137 string clamp = !if(HasClamp, "$clamp", ""); 1138 1139 // Each modifier is printed as an array of bits for each operand, so 1140 // all operands are printed as part of src0_modifiers. 1141 string ret = dst#", "#src0#src1#src2#"$op_sel$op_sel_hi"#mods#clamp; 1142} 1143 1144class getAsmDPP <bit HasDst, int NumSrcArgs, bit HasModifiers, ValueType DstVT = i32> { 1145 string dst = !if(HasDst, 1146 !if(!eq(DstVT.Size, 1), 1147 "$sdst", 1148 "$vdst"), 1149 ""); // use $sdst for VOPC 1150 string src0 = !if(!eq(NumSrcArgs, 1), "$src0_modifiers", "$src0_modifiers,"); 1151 string src1 = !if(!eq(NumSrcArgs, 1), "", 1152 !if(!eq(NumSrcArgs, 2), " $src1_modifiers", 1153 " $src1_modifiers,")); 1154 string args = !if(!eq(HasModifiers, 0), 1155 getAsm32<0, NumSrcArgs, DstVT>.ret, 1156 ", "#src0#src1); 1157 string ret = dst#args#" $dpp_ctrl$row_mask$bank_mask$bound_ctrl"; 1158} 1159 1160class getAsmSDWA <bit HasDst, int NumSrcArgs, bit HasFloatModifiers, 1161 ValueType DstVT = i32> { 1162 string dst = !if(HasDst, 1163 !if(!eq(DstVT.Size, 1), 1164 " vcc", // use vcc token as dst for VOPC instructioins 1165 "$vdst"), 1166 ""); 1167 string src0 = "$src0_modifiers"; 1168 string src1 = "$src1_modifiers"; 1169 string args = !if(!eq(NumSrcArgs, 0), 1170 "", 1171 !if(!eq(NumSrcArgs, 1), 1172 ", "#src0#"$clamp", 1173 ", "#src0#", "#src1#"$clamp" 1174 ) 1175 ); 1176 string sdwa = !if(!eq(NumSrcArgs, 0), 1177 "", 1178 !if(!eq(NumSrcArgs, 1), 1179 " $dst_sel $dst_unused $src0_sel", 1180 !if(!eq(DstVT.Size, 1), 1181 " $src0_sel $src1_sel", // No dst_sel and dst_unused for VOPC 1182 " $dst_sel $dst_unused $src0_sel $src1_sel" 1183 ) 1184 ) 1185 ); 1186 string ret = dst#args#sdwa; 1187} 1188 1189// Function that checks if instruction supports DPP and SDWA 1190class getHasExt <int NumSrcArgs, ValueType DstVT = i32, ValueType Src0VT = i32, 1191 ValueType Src1VT = i32> { 1192 bit ret = !if(!eq(NumSrcArgs, 3), 1193 0, // NumSrcArgs == 3 - No DPP or SDWA for VOP3 1194 !if(!eq(DstVT.Size, 64), 1195 0, // 64-bit dst - No DPP or SDWA for 64-bit operands 1196 !if(!eq(Src0VT.Size, 64), 1197 0, // 64-bit src0 1198 !if(!eq(Src0VT.Size, 64), 1199 0, // 64-bit src2 1200 1 1201 ) 1202 ) 1203 ) 1204 ); 1205} 1206 1207class BitOr<bit a, bit b> { 1208 bit ret = !if(a, 1, !if(b, 1, 0)); 1209} 1210 1211class BitAnd<bit a, bit b> { 1212 bit ret = !if(a, !if(b, 1, 0), 0); 1213} 1214 1215class VOPProfile <list<ValueType> _ArgVT> { 1216 1217 field list<ValueType> ArgVT = _ArgVT; 1218 1219 field ValueType DstVT = ArgVT[0]; 1220 field ValueType Src0VT = ArgVT[1]; 1221 field ValueType Src1VT = ArgVT[2]; 1222 field ValueType Src2VT = ArgVT[3]; 1223 field RegisterOperand DstRC = getVALUDstForVT<DstVT>.ret; 1224 field RegisterOperand DstRCDPP = getVALUDstForVT<DstVT>.ret; 1225 field RegisterOperand DstRCSDWA = getVALUDstForVT<DstVT>.ret; 1226 field RegisterOperand Src0RC32 = getVOPSrc0ForVT<Src0VT>.ret; 1227 field RegisterClass Src1RC32 = getVregSrcForVT<Src1VT>.ret; 1228 field RegisterOperand Src0RC64 = getVOP3SrcForVT<Src0VT>.ret; 1229 field RegisterOperand Src1RC64 = getVOP3SrcForVT<Src1VT>.ret; 1230 field RegisterOperand Src2RC64 = getVOP3SrcForVT<Src2VT>.ret; 1231 field RegisterClass Src0DPP = getVregSrcForVT<Src0VT>.ret; 1232 field RegisterClass Src1DPP = getVregSrcForVT<Src1VT>.ret; 1233 field RegisterClass Src0SDWA = getVregSrcForVT<Src0VT>.ret; 1234 field RegisterClass Src1SDWA = getVregSrcForVT<Src1VT>.ret; 1235 field Operand Src0Mod = getSrcMod<Src0VT>.ret; 1236 field Operand Src1Mod = getSrcMod<Src1VT>.ret; 1237 field Operand Src2Mod = getSrcMod<Src2VT>.ret; 1238 field Operand Src0ModDPP = getSrcModExt<Src0VT>.ret; 1239 field Operand Src1ModDPP = getSrcModExt<Src1VT>.ret; 1240 field Operand Src0ModSDWA = getSrcModExt<Src0VT>.ret; 1241 field Operand Src1ModSDWA = getSrcModExt<Src1VT>.ret; 1242 1243 1244 field bit HasDst = !if(!eq(DstVT.Value, untyped.Value), 0, 1); 1245 field bit HasDst32 = HasDst; 1246 field bit EmitDst = HasDst; // force dst encoding, see v_movreld_b32 special case 1247 field int NumSrcArgs = getNumSrcArgs<Src0VT, Src1VT, Src2VT>.ret; 1248 field bit HasSrc0 = !if(!eq(Src0VT.Value, untyped.Value), 0, 1); 1249 field bit HasSrc1 = !if(!eq(Src1VT.Value, untyped.Value), 0, 1); 1250 field bit HasSrc2 = !if(!eq(Src2VT.Value, untyped.Value), 0, 1); 1251 1252 // TODO: Modifiers logic is somewhat adhoc here, to be refined later 1253 field bit HasModifiers = isModifierType<Src0VT>.ret; 1254 1255 field bit HasSrc0FloatMods = isFloatType<Src0VT>.ret; 1256 field bit HasSrc1FloatMods = isFloatType<Src1VT>.ret; 1257 field bit HasSrc2FloatMods = isFloatType<Src2VT>.ret; 1258 1259 field bit HasSrc0IntMods = isIntType<Src0VT>.ret; 1260 field bit HasSrc1IntMods = isIntType<Src1VT>.ret; 1261 field bit HasSrc2IntMods = isIntType<Src2VT>.ret; 1262 1263 field bit HasSrc0Mods = HasModifiers; 1264 field bit HasSrc1Mods = !if(HasModifiers, BitOr<HasSrc1FloatMods, HasSrc1IntMods>.ret, 0); 1265 field bit HasSrc2Mods = !if(HasModifiers, BitOr<HasSrc2FloatMods, HasSrc2IntMods>.ret, 0); 1266 1267 field bit HasClamp = HasModifiers; 1268 field bit HasSDWAClamp = HasSrc0; 1269 field bit HasFPClamp = BitAnd<isFloatType<DstVT>.ret, HasClamp>.ret; 1270 1271 field bit IsPacked = isPackedType<Src0VT>.ret; 1272 field bit HasOpSel = IsPacked; 1273 field bit HasOMod = !if(HasOpSel, 0, HasModifiers); 1274 1275 field bit HasExt = getHasExt<NumSrcArgs, DstVT, Src0VT, Src1VT>.ret; 1276 1277 field Operand Src0PackedMod = !if(HasSrc0FloatMods, PackedF16InputMods, PackedI16InputMods); 1278 field Operand Src1PackedMod = !if(HasSrc1FloatMods, PackedF16InputMods, PackedI16InputMods); 1279 field Operand Src2PackedMod = !if(HasSrc2FloatMods, PackedF16InputMods, PackedI16InputMods); 1280 1281 field dag Outs = !if(HasDst,(outs DstRC:$vdst),(outs)); 1282 1283 // VOP3b instructions are a special case with a second explicit 1284 // output. This is manually overridden for them. 1285 field dag Outs32 = Outs; 1286 field dag Outs64 = Outs; 1287 field dag OutsDPP = getOutsExt<HasDst, DstVT, DstRCDPP>.ret; 1288 field dag OutsSDWA = getOutsExt<HasDst, DstVT, DstRCSDWA>.ret; 1289 1290 field dag Ins32 = getIns32<Src0RC32, Src1RC32, NumSrcArgs>.ret; 1291 field dag Ins64 = getIns64<Src0RC64, Src1RC64, Src2RC64, NumSrcArgs, 1292 HasModifiers, HasOMod, Src0Mod, Src1Mod, 1293 Src2Mod>.ret; 1294 field dag InsVOP3P = getInsVOP3P<Src0RC64, Src1RC64, Src2RC64, 1295 NumSrcArgs, HasClamp, 1296 Src0PackedMod, Src1PackedMod, Src2PackedMod>.ret; 1297 1298 field dag InsDPP = getInsDPP<Src0DPP, Src1DPP, NumSrcArgs, 1299 HasModifiers, Src0ModDPP, Src1ModDPP>.ret; 1300 field dag InsSDWA = getInsSDWA<Src0SDWA, Src1SDWA, NumSrcArgs, 1301 HasModifiers, Src0ModSDWA, Src1ModSDWA, 1302 DstVT>.ret; 1303 1304 field string Asm32 = getAsm32<HasDst, NumSrcArgs, DstVT>.ret; 1305 field string Asm64 = getAsm64<HasDst, NumSrcArgs, HasModifiers, HasOMod, DstVT>.ret; 1306 field string AsmVOP3P = getAsmVOP3P<HasDst, NumSrcArgs, HasModifiers, HasClamp, DstVT>.ret; 1307 field string AsmDPP = getAsmDPP<HasDst, NumSrcArgs, HasModifiers, DstVT>.ret; 1308 field string AsmSDWA = getAsmSDWA<HasDst, NumSrcArgs, HasModifiers, DstVT>.ret; 1309} 1310 1311class VOP_NO_EXT <VOPProfile p> : VOPProfile <p.ArgVT> { 1312 let HasExt = 0; 1313} 1314 1315def VOP_F16_F16 : VOPProfile <[f16, f16, untyped, untyped]>; 1316def VOP_F16_I16 : VOPProfile <[f16, i16, untyped, untyped]>; 1317def VOP_I16_F16 : VOPProfile <[i16, f16, untyped, untyped]>; 1318 1319def VOP_F16_F16_F16 : VOPProfile <[f16, f16, f16, untyped]>; 1320def VOP_F16_F16_I16 : VOPProfile <[f16, f16, i16, untyped]>; 1321def VOP_F16_F16_I32 : VOPProfile <[f16, f16, i32, untyped]>; 1322def VOP_I16_I16_I16 : VOPProfile <[i32, i32, i32, untyped]>; 1323 1324def VOP_I16_I16_I16_I16 : VOPProfile <[i16, i16, i16, i16, untyped]>; 1325def VOP_F16_F16_F16_F16 : VOPProfile <[f16, f16, f16, f16, untyped]>; 1326 1327def VOP_V2F16_V2F16_V2F16 : VOPProfile <[v2f16, v2f16, v2f16, untyped]>; 1328def VOP_V2I16_V2I16_V2I16 : VOPProfile <[v2i16, v2i16, v2i16, untyped]>; 1329def VOP_B32_F16_F16 : VOPProfile <[i32, f16, f16, untyped]>; 1330 1331def VOP_V2F16_V2F16_V2F16_V2F16 : VOPProfile <[v2f16, v2f16, v2f16, v2f16]>; 1332def VOP_V2I16_V2I16_V2I16_V2I16 : VOPProfile <[v2i16, v2i16, v2i16, v2i16]>; 1333 1334def VOP_NONE : VOPProfile <[untyped, untyped, untyped, untyped]>; 1335 1336def VOP_F32_F32 : VOPProfile <[f32, f32, untyped, untyped]>; 1337def VOP_F32_F64 : VOPProfile <[f32, f64, untyped, untyped]>; 1338def VOP_F32_I32 : VOPProfile <[f32, i32, untyped, untyped]>; 1339def VOP_F64_F32 : VOPProfile <[f64, f32, untyped, untyped]>; 1340def VOP_F64_F64 : VOPProfile <[f64, f64, untyped, untyped]>; 1341def VOP_F64_I32 : VOPProfile <[f64, i32, untyped, untyped]>; 1342def VOP_I32_F32 : VOPProfile <[i32, f32, untyped, untyped]>; 1343def VOP_I32_F64 : VOPProfile <[i32, f64, untyped, untyped]>; 1344def VOP_I32_I32 : VOPProfile <[i32, i32, untyped, untyped]>; 1345def VOP_F16_F32 : VOPProfile <[f16, f32, untyped, untyped]>; 1346def VOP_F32_F16 : VOPProfile <[f32, f16, untyped, untyped]>; 1347 1348def VOP_F32_F32_F16 : VOPProfile <[f32, f32, f16, untyped]>; 1349def VOP_F32_F32_F32 : VOPProfile <[f32, f32, f32, untyped]>; 1350def VOP_F32_F32_I32 : VOPProfile <[f32, f32, i32, untyped]>; 1351def VOP_F64_F64_F64 : VOPProfile <[f64, f64, f64, untyped]>; 1352def VOP_F64_F64_I32 : VOPProfile <[f64, f64, i32, untyped]>; 1353def VOP_I32_F32_F32 : VOPProfile <[i32, f32, f32, untyped]>; 1354def VOP_I32_F32_I32 : VOPProfile <[i32, f32, i32, untyped]>; 1355def VOP_I32_I32_I32 : VOPProfile <[i32, i32, i32, untyped]>; 1356def VOP_V2F16_F32_F32 : VOPProfile <[v2f16, f32, f32, untyped]>; 1357 1358def VOP_I64_I64_I32 : VOPProfile <[i64, i64, i32, untyped]>; 1359def VOP_I64_I32_I64 : VOPProfile <[i64, i32, i64, untyped]>; 1360def VOP_I64_I64_I64 : VOPProfile <[i64, i64, i64, untyped]>; 1361 1362def VOP_F16_F32_F16_F32 : VOPProfile <[f16, f32, f16, f32]>; 1363def VOP_F32_F32_F16_F16 : VOPProfile <[f32, f32, f16, f16]>; 1364def VOP_F32_F32_F32_F32 : VOPProfile <[f32, f32, f32, f32]>; 1365def VOP_F64_F64_F64_F64 : VOPProfile <[f64, f64, f64, f64]>; 1366def VOP_I32_I32_I32_I32 : VOPProfile <[i32, i32, i32, i32]>; 1367def VOP_I64_I32_I32_I64 : VOPProfile <[i64, i32, i32, i64]>; 1368def VOP_I32_F32_I32_I32 : VOPProfile <[i32, f32, i32, i32]>; 1369def VOP_I64_I64_I32_I64 : VOPProfile <[i64, i64, i32, i64]>; 1370def VOP_V4I32_I64_I32_V4I32 : VOPProfile <[v4i32, i64, i32, v4i32]>; 1371 1372class Commutable_REV <string revOp, bit isOrig> { 1373 string RevOp = revOp; 1374 bit IsOrig = isOrig; 1375} 1376 1377class AtomicNoRet <string noRetOp, bit isRet> { 1378 string NoRetOp = noRetOp; 1379 bit IsRet = isRet; 1380} 1381 1382//===----------------------------------------------------------------------===// 1383// Interpolation opcodes 1384//===----------------------------------------------------------------------===// 1385 1386class VINTRP_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> : 1387 VINTRPCommon <outs, ins, "", pattern>, 1388 SIMCInstr<opName, SIEncodingFamily.NONE> { 1389 let isPseudo = 1; 1390 let isCodeGenOnly = 1; 1391} 1392 1393class VINTRP_Real_si <bits <2> op, string opName, dag outs, dag ins, 1394 string asm> : 1395 VINTRPCommon <outs, ins, asm, []>, 1396 VINTRPe <op>, 1397 SIMCInstr<opName, SIEncodingFamily.SI> { 1398 let AssemblerPredicate = SIAssemblerPredicate; 1399 let DecoderNamespace = "SICI"; 1400 let DisableDecoder = DisableSIDecoder; 1401} 1402 1403class VINTRP_Real_vi <bits <2> op, string opName, dag outs, dag ins, 1404 string asm> : 1405 VINTRPCommon <outs, ins, asm, []>, 1406 VINTRPe_vi <op>, 1407 SIMCInstr<opName, SIEncodingFamily.VI> { 1408 let AssemblerPredicate = VIAssemblerPredicate; 1409 let DecoderNamespace = "VI"; 1410 let DisableDecoder = DisableVIDecoder; 1411} 1412 1413multiclass VINTRP_m <bits <2> op, dag outs, dag ins, string asm, 1414 list<dag> pattern = []> { 1415 def "" : VINTRP_Pseudo <NAME, outs, ins, pattern>; 1416 1417 def _si : VINTRP_Real_si <op, NAME, outs, ins, asm>; 1418 1419 def _vi : VINTRP_Real_vi <op, NAME, outs, ins, asm>; 1420} 1421 1422//===----------------------------------------------------------------------===// 1423// Vector instruction mappings 1424//===----------------------------------------------------------------------===// 1425 1426// Maps an opcode in e32 form to its e64 equivalent 1427def getVOPe64 : InstrMapping { 1428 let FilterClass = "VOP"; 1429 let RowFields = ["OpName"]; 1430 let ColFields = ["Size", "VOP3"]; 1431 let KeyCol = ["4", "0"]; 1432 let ValueCols = [["8", "1"]]; 1433} 1434 1435// Maps an opcode in e64 form to its e32 equivalent 1436def getVOPe32 : InstrMapping { 1437 let FilterClass = "VOP"; 1438 let RowFields = ["OpName"]; 1439 let ColFields = ["Size", "VOP3"]; 1440 let KeyCol = ["8", "1"]; 1441 let ValueCols = [["4", "0"]]; 1442} 1443 1444def getMaskedMIMGOp : InstrMapping { 1445 let FilterClass = "MIMG_Mask"; 1446 let RowFields = ["Op"]; 1447 let ColFields = ["Channels"]; 1448 let KeyCol = ["4"]; 1449 let ValueCols = [["1"], ["2"], ["3"] ]; 1450} 1451 1452// Maps an commuted opcode to its original version 1453def getCommuteOrig : InstrMapping { 1454 let FilterClass = "Commutable_REV"; 1455 let RowFields = ["RevOp"]; 1456 let ColFields = ["IsOrig"]; 1457 let KeyCol = ["0"]; 1458 let ValueCols = [["1"]]; 1459} 1460 1461// Maps an original opcode to its commuted version 1462def getCommuteRev : InstrMapping { 1463 let FilterClass = "Commutable_REV"; 1464 let RowFields = ["RevOp"]; 1465 let ColFields = ["IsOrig"]; 1466 let KeyCol = ["1"]; 1467 let ValueCols = [["0"]]; 1468} 1469 1470def getMCOpcodeGen : InstrMapping { 1471 let FilterClass = "SIMCInstr"; 1472 let RowFields = ["PseudoInstr"]; 1473 let ColFields = ["Subtarget"]; 1474 let KeyCol = [!cast<string>(SIEncodingFamily.NONE)]; 1475 let ValueCols = [[!cast<string>(SIEncodingFamily.SI)], 1476 [!cast<string>(SIEncodingFamily.VI)]]; 1477} 1478 1479// Get equivalent SOPK instruction. 1480def getSOPKOp : InstrMapping { 1481 let FilterClass = "SOPKInstTable"; 1482 let RowFields = ["BaseCmpOp"]; 1483 let ColFields = ["IsSOPK"]; 1484 let KeyCol = ["0"]; 1485 let ValueCols = [["1"]]; 1486} 1487 1488def getAddr64Inst : InstrMapping { 1489 let FilterClass = "MUBUFAddr64Table"; 1490 let RowFields = ["OpName"]; 1491 let ColFields = ["IsAddr64"]; 1492 let KeyCol = ["0"]; 1493 let ValueCols = [["1"]]; 1494} 1495 1496// Maps an atomic opcode to its version with a return value. 1497def getAtomicRetOp : InstrMapping { 1498 let FilterClass = "AtomicNoRet"; 1499 let RowFields = ["NoRetOp"]; 1500 let ColFields = ["IsRet"]; 1501 let KeyCol = ["0"]; 1502 let ValueCols = [["1"]]; 1503} 1504 1505// Maps an atomic opcode to its returnless version. 1506def getAtomicNoRetOp : InstrMapping { 1507 let FilterClass = "AtomicNoRet"; 1508 let RowFields = ["NoRetOp"]; 1509 let ColFields = ["IsRet"]; 1510 let KeyCol = ["1"]; 1511 let ValueCols = [["0"]]; 1512} 1513 1514include "SIInstructions.td" 1515include "CIInstructions.td" 1516 1517include "DSInstructions.td" 1518include "MIMGInstructions.td" 1519