1//===-- SIInstrInfo.td - SI Instruction Infos -------------*- tablegen -*--===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8def isCI : Predicate<"Subtarget->getGeneration() " 9 ">= AMDGPUSubtarget::SEA_ISLANDS">; 10def isCIOnly : Predicate<"Subtarget->getGeneration() ==" 11 "AMDGPUSubtarget::SEA_ISLANDS">, 12 AssemblerPredicate <"FeatureSeaIslands">; 13def isVIOnly : Predicate<"Subtarget->getGeneration() ==" 14 "AMDGPUSubtarget::VOLCANIC_ISLANDS">, 15 AssemblerPredicate <"FeatureVolcanicIslands">; 16 17def DisableInst : Predicate <"false">, AssemblerPredicate<"FeatureDisable">; 18 19class GCNPredicateControl : PredicateControl { 20 Predicate SIAssemblerPredicate = isSICI; 21 Predicate VIAssemblerPredicate = isVI; 22} 23 24// Execpt for the NONE field, this must be kept in sync with the 25// SIEncodingFamily enum in AMDGPUInstrInfo.cpp 26def SIEncodingFamily { 27 int NONE = -1; 28 int SI = 0; 29 int VI = 1; 30 int SDWA = 2; 31 int SDWA9 = 3; 32 int GFX80 = 4; 33 int GFX9 = 5; 34} 35 36//===----------------------------------------------------------------------===// 37// SI DAG Nodes 38//===----------------------------------------------------------------------===// 39 40def AMDGPUclamp : SDNode<"AMDGPUISD::CLAMP", SDTFPUnaryOp>; 41 42def SIsbuffer_load : SDNode<"AMDGPUISD::SBUFFER_LOAD", 43 SDTypeProfile<1, 3, [SDTCisVT<1, v4i32>, SDTCisVT<2, i32>, SDTCisVT<3, i1>]>, 44 [SDNPMayLoad, SDNPMemOperand] 45>; 46 47def SIds_ordered_count : SDNode<"AMDGPUISD::DS_ORDERED_COUNT", 48 SDTypeProfile<1, 2, [SDTCisVT<0, i32>, SDTCisVT<1, i32>, SDTCisVT<2, i16>]>, 49 [SDNPMayLoad, SDNPMayStore, SDNPMemOperand, SDNPHasChain, SDNPInGlue] 50>; 51 52def SIatomic_inc : SDNode<"AMDGPUISD::ATOMIC_INC", SDTAtomic2, 53 [SDNPMayLoad, SDNPMayStore, SDNPMemOperand, SDNPHasChain] 54>; 55 56def SIatomic_dec : SDNode<"AMDGPUISD::ATOMIC_DEC", SDTAtomic2, 57 [SDNPMayLoad, SDNPMayStore, SDNPMemOperand, SDNPHasChain] 58>; 59 60def SDTAtomic2_f32 : SDTypeProfile<1, 2, [ 61 SDTCisSameAs<0,2>, SDTCisFP<0>, SDTCisPtrTy<1> 62]>; 63 64def SIatomic_fmin : SDNode<"AMDGPUISD::ATOMIC_LOAD_FMIN", SDTAtomic2_f32, 65 [SDNPMayLoad, SDNPMayStore, SDNPMemOperand, SDNPHasChain] 66>; 67 68def SIatomic_fmax : SDNode<"AMDGPUISD::ATOMIC_LOAD_FMAX", SDTAtomic2_f32, 69 [SDNPMayLoad, SDNPMayStore, SDNPMemOperand, SDNPHasChain] 70>; 71 72// load_d16_{lo|hi} ptr, tied_input 73def SIload_d16 : SDTypeProfile<1, 2, [ 74 SDTCisPtrTy<1>, 75 SDTCisSameAs<0, 2> 76]>; 77 78 79def SDTtbuffer_load : SDTypeProfile<1, 8, 80 [ // vdata 81 SDTCisVT<1, v4i32>, // rsrc 82 SDTCisVT<2, i32>, // vindex(VGPR) 83 SDTCisVT<3, i32>, // voffset(VGPR) 84 SDTCisVT<4, i32>, // soffset(SGPR) 85 SDTCisVT<5, i32>, // offset(imm) 86 SDTCisVT<6, i32>, // format(imm) 87 SDTCisVT<7, i32>, // cachecontrol(imm) 88 SDTCisVT<8, i1> // idxen(imm) 89 ]>; 90 91def SItbuffer_load : SDNode<"AMDGPUISD::TBUFFER_LOAD_FORMAT", SDTtbuffer_load, 92 [SDNPMayLoad, SDNPMemOperand, SDNPHasChain]>; 93def SItbuffer_load_d16 : SDNode<"AMDGPUISD::TBUFFER_LOAD_FORMAT_D16", 94 SDTtbuffer_load, 95 [SDNPMayLoad, SDNPMemOperand, SDNPHasChain]>; 96 97def SDTtbuffer_store : SDTypeProfile<0, 9, 98 [ // vdata 99 SDTCisVT<1, v4i32>, // rsrc 100 SDTCisVT<2, i32>, // vindex(VGPR) 101 SDTCisVT<3, i32>, // voffset(VGPR) 102 SDTCisVT<4, i32>, // soffset(SGPR) 103 SDTCisVT<5, i32>, // offset(imm) 104 SDTCisVT<6, i32>, // format(imm) 105 SDTCisVT<7, i32>, // cachecontrol(imm) 106 SDTCisVT<8, i1> // idxen(imm) 107 ]>; 108 109def SItbuffer_store : SDNode<"AMDGPUISD::TBUFFER_STORE_FORMAT", SDTtbuffer_store, 110 [SDNPMayStore, SDNPMemOperand, SDNPHasChain]>; 111def SItbuffer_store_d16 : SDNode<"AMDGPUISD::TBUFFER_STORE_FORMAT_D16", 112 SDTtbuffer_store, 113 [SDNPMayStore, SDNPMemOperand, SDNPHasChain]>; 114 115def SDTBufferLoad : SDTypeProfile<1, 7, 116 [ // vdata 117 SDTCisVT<1, v4i32>, // rsrc 118 SDTCisVT<2, i32>, // vindex(VGPR) 119 SDTCisVT<3, i32>, // voffset(VGPR) 120 SDTCisVT<4, i32>, // soffset(SGPR) 121 SDTCisVT<5, i32>, // offset(imm) 122 SDTCisVT<6, i32>, // cachepolicy(imm) 123 SDTCisVT<7, i1>]>; // idxen(imm) 124 125def SIbuffer_load : SDNode <"AMDGPUISD::BUFFER_LOAD", SDTBufferLoad, 126 [SDNPMemOperand, SDNPHasChain, SDNPMayLoad]>; 127def SIbuffer_load_ubyte : SDNode <"AMDGPUISD::BUFFER_LOAD_UBYTE", SDTBufferLoad, 128 [SDNPMemOperand, SDNPHasChain, SDNPMayLoad]>; 129def SIbuffer_load_ushort : SDNode <"AMDGPUISD::BUFFER_LOAD_USHORT", SDTBufferLoad, 130 [SDNPMemOperand, SDNPHasChain, SDNPMayLoad]>; 131def SIbuffer_load_byte : SDNode <"AMDGPUISD::BUFFER_LOAD_BYTE", SDTBufferLoad, 132 [SDNPMemOperand, SDNPHasChain, SDNPMayLoad]>; 133def SIbuffer_load_short: SDNode <"AMDGPUISD::BUFFER_LOAD_SHORT", SDTBufferLoad, 134 [SDNPMemOperand, SDNPHasChain, SDNPMayLoad]>; 135def SIbuffer_load_format : SDNode <"AMDGPUISD::BUFFER_LOAD_FORMAT", SDTBufferLoad, 136 [SDNPMemOperand, SDNPHasChain, SDNPMayLoad]>; 137def SIbuffer_load_format_d16 : SDNode <"AMDGPUISD::BUFFER_LOAD_FORMAT_D16", 138 SDTBufferLoad, 139 [SDNPMemOperand, SDNPHasChain, SDNPMayLoad]>; 140 141def SDTBufferStore : SDTypeProfile<0, 8, 142 [ // vdata 143 SDTCisVT<1, v4i32>, // rsrc 144 SDTCisVT<2, i32>, // vindex(VGPR) 145 SDTCisVT<3, i32>, // voffset(VGPR) 146 SDTCisVT<4, i32>, // soffset(SGPR) 147 SDTCisVT<5, i32>, // offset(imm) 148 SDTCisVT<6, i32>, // cachepolicy(imm) 149 SDTCisVT<7, i1>]>; // idxen(imm) 150 151def SIbuffer_store : SDNode <"AMDGPUISD::BUFFER_STORE", SDTBufferStore, 152 [SDNPMayStore, SDNPMemOperand, SDNPHasChain]>; 153def SIbuffer_store_byte: SDNode <"AMDGPUISD::BUFFER_STORE_BYTE", 154 SDTBufferStore, 155 [SDNPMayStore, SDNPMemOperand, SDNPHasChain]>; 156def SIbuffer_store_short : SDNode <"AMDGPUISD::BUFFER_STORE_SHORT", 157 SDTBufferStore, 158 [SDNPMayStore, SDNPMemOperand, SDNPHasChain]>; 159def SIbuffer_store_format : SDNode <"AMDGPUISD::BUFFER_STORE_FORMAT", 160 SDTBufferStore, 161 [SDNPMayStore, SDNPMemOperand, SDNPHasChain]>; 162def SIbuffer_store_format_d16 : SDNode <"AMDGPUISD::BUFFER_STORE_FORMAT_D16", 163 SDTBufferStore, 164 [SDNPMayStore, SDNPMemOperand, SDNPHasChain]>; 165 166class SDBufferAtomic<string opcode> : SDNode <opcode, 167 SDTypeProfile<1, 8, 168 [SDTCisVT<2, v4i32>, // rsrc 169 SDTCisVT<3, i32>, // vindex(VGPR) 170 SDTCisVT<4, i32>, // voffset(VGPR) 171 SDTCisVT<5, i32>, // soffset(SGPR) 172 SDTCisVT<6, i32>, // offset(imm) 173 SDTCisVT<7, i32>, // cachepolicy(imm) 174 SDTCisVT<8, i1>]>, // idxen(imm) 175 [SDNPMemOperand, SDNPHasChain, SDNPMayLoad, SDNPMayStore] 176>; 177 178def SIbuffer_atomic_swap : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_SWAP">; 179def SIbuffer_atomic_add : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_ADD">; 180def SIbuffer_atomic_sub : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_SUB">; 181def SIbuffer_atomic_smin : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_SMIN">; 182def SIbuffer_atomic_umin : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_UMIN">; 183def SIbuffer_atomic_smax : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_SMAX">; 184def SIbuffer_atomic_umax : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_UMAX">; 185def SIbuffer_atomic_and : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_AND">; 186def SIbuffer_atomic_or : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_OR">; 187def SIbuffer_atomic_xor : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_XOR">; 188 189def SIbuffer_atomic_cmpswap : SDNode <"AMDGPUISD::BUFFER_ATOMIC_CMPSWAP", 190 SDTypeProfile<1, 9, 191 [SDTCisVT<0, i32>, // dst 192 SDTCisVT<1, i32>, // src 193 SDTCisVT<2, i32>, // cmp 194 SDTCisVT<3, v4i32>, // rsrc 195 SDTCisVT<4, i32>, // vindex(VGPR) 196 SDTCisVT<5, i32>, // voffset(VGPR) 197 SDTCisVT<6, i32>, // soffset(SGPR) 198 SDTCisVT<7, i32>, // offset(imm) 199 SDTCisVT<8, i32>, // cachepolicy(imm) 200 SDTCisVT<9, i1>]>, // idxen(imm) 201 [SDNPMemOperand, SDNPHasChain, SDNPMayLoad, SDNPMayStore] 202>; 203 204def SIpc_add_rel_offset : SDNode<"AMDGPUISD::PC_ADD_REL_OFFSET", 205 SDTypeProfile<1, 2, [SDTCisVT<0, iPTR>, SDTCisSameAs<0,1>, SDTCisSameAs<0,2>]> 206>; 207 208def SIload_d16_lo : SDNode<"AMDGPUISD::LOAD_D16_LO", 209 SIload_d16, 210 [SDNPMayLoad, SDNPMemOperand, SDNPHasChain] 211>; 212 213def SIload_d16_lo_u8 : SDNode<"AMDGPUISD::LOAD_D16_LO_U8", 214 SIload_d16, 215 [SDNPMayLoad, SDNPMemOperand, SDNPHasChain] 216>; 217 218def SIload_d16_lo_i8 : SDNode<"AMDGPUISD::LOAD_D16_LO_I8", 219 SIload_d16, 220 [SDNPMayLoad, SDNPMemOperand, SDNPHasChain] 221>; 222 223def SIload_d16_hi : SDNode<"AMDGPUISD::LOAD_D16_HI", 224 SIload_d16, 225 [SDNPMayLoad, SDNPMemOperand, SDNPHasChain] 226>; 227 228def SIload_d16_hi_u8 : SDNode<"AMDGPUISD::LOAD_D16_HI_U8", 229 SIload_d16, 230 [SDNPMayLoad, SDNPMemOperand, SDNPHasChain] 231>; 232 233def SIload_d16_hi_i8 : SDNode<"AMDGPUISD::LOAD_D16_HI_I8", 234 SIload_d16, 235 [SDNPMayLoad, SDNPMemOperand, SDNPHasChain] 236>; 237 238//===----------------------------------------------------------------------===// 239// ValueType helpers 240//===----------------------------------------------------------------------===// 241 242// Returns 1 if the source arguments have modifiers, 0 if they do not. 243// XXX - do f16 instructions? 244class isFloatType<ValueType SrcVT> { 245 bit ret = 246 !if(!eq(SrcVT.Value, f16.Value), 1, 247 !if(!eq(SrcVT.Value, f32.Value), 1, 248 !if(!eq(SrcVT.Value, f64.Value), 1, 249 !if(!eq(SrcVT.Value, v2f16.Value), 1, 250 0)))); 251} 252 253class isIntType<ValueType SrcVT> { 254 bit ret = 255 !if(!eq(SrcVT.Value, i16.Value), 1, 256 !if(!eq(SrcVT.Value, i32.Value), 1, 257 !if(!eq(SrcVT.Value, i64.Value), 1, 258 0))); 259} 260 261class isPackedType<ValueType SrcVT> { 262 bit ret = 263 !if(!eq(SrcVT.Value, v2i16.Value), 1, 264 !if(!eq(SrcVT.Value, v2f16.Value), 1, 0) 265 ); 266} 267 268//===----------------------------------------------------------------------===// 269// PatFrags for global memory operations 270//===----------------------------------------------------------------------===// 271 272defm atomic_inc_global : global_binary_atomic_op<SIatomic_inc>; 273defm atomic_dec_global : global_binary_atomic_op<SIatomic_dec>; 274 275def atomic_inc_local : local_binary_atomic_op<SIatomic_inc>; 276def atomic_dec_local : local_binary_atomic_op<SIatomic_dec>; 277def atomic_load_fadd_local : local_binary_atomic_op<atomic_load_fadd>; 278def atomic_load_fmin_local : local_binary_atomic_op<SIatomic_fmin>; 279def atomic_load_fmax_local : local_binary_atomic_op<SIatomic_fmax>; 280 281//===----------------------------------------------------------------------===// 282// SDNodes PatFrags for loads/stores with a glue input. 283// This is for SDNodes and PatFrag for local loads and stores to 284// enable s_mov_b32 m0, -1 to be glued to the memory instructions. 285// 286// These mirror the regular load/store PatFrags and rely on special 287// processing during Select() to add the glued copy. 288// 289//===----------------------------------------------------------------------===// 290 291def AMDGPUld_glue : SDNode <"ISD::LOAD", SDTLoad, 292 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand, SDNPInGlue] 293>; 294 295def AMDGPUatomic_ld_glue : SDNode <"ISD::ATOMIC_LOAD", SDTAtomicLoad, 296 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand, SDNPInGlue] 297>; 298 299def unindexedload_glue : PatFrag <(ops node:$ptr), (AMDGPUld_glue node:$ptr), [{ 300 return cast<LoadSDNode>(N)->getAddressingMode() == ISD::UNINDEXED; 301}]>; 302 303def load_glue : PatFrag <(ops node:$ptr), (unindexedload_glue node:$ptr), [{ 304 return cast<LoadSDNode>(N)->getExtensionType() == ISD::NON_EXTLOAD; 305}]>; 306 307def atomic_load_32_glue : PatFrag<(ops node:$ptr), 308 (AMDGPUatomic_ld_glue node:$ptr)> { 309 let IsAtomic = 1; 310 let MemoryVT = i32; 311} 312 313def atomic_load_64_glue : PatFrag<(ops node:$ptr), 314 (AMDGPUatomic_ld_glue node:$ptr)> { 315 let IsAtomic = 1; 316 let MemoryVT = i64; 317} 318 319def extload_glue : PatFrag<(ops node:$ptr), (load_glue node:$ptr), [{ 320 return cast<LoadSDNode>(N)->getExtensionType() == ISD::EXTLOAD; 321}]>; 322 323def sextload_glue : PatFrag<(ops node:$ptr), (unindexedload_glue node:$ptr), [{ 324 return cast<LoadSDNode>(N)->getExtensionType() == ISD::SEXTLOAD; 325}]>; 326 327def zextload_glue : PatFrag<(ops node:$ptr), (unindexedload_glue node:$ptr), [{ 328 return cast<LoadSDNode>(N)->getExtensionType() == ISD::ZEXTLOAD; 329}]>; 330 331def az_extload_glue : AZExtLoadBase <unindexedload_glue>; 332 333def az_extloadi8_glue : PatFrag<(ops node:$ptr), (az_extload_glue node:$ptr), [{ 334 return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i8; 335}]>; 336 337def az_extloadi16_glue : PatFrag<(ops node:$ptr), (az_extload_glue node:$ptr), [{ 338 return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i16; 339}]>; 340 341def sextloadi8_glue : PatFrag<(ops node:$ptr), (sextload_glue node:$ptr), [{ 342 return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i8; 343}]>; 344 345def sextloadi16_glue : PatFrag<(ops node:$ptr), (sextload_glue node:$ptr), [{ 346 return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i16; 347}]>; 348 349def load_glue_align8 : Aligned8Bytes < 350 (ops node:$ptr), (load_glue node:$ptr) 351>; 352def load_glue_align16 : Aligned16Bytes < 353 (ops node:$ptr), (load_glue node:$ptr) 354>; 355 356 357def load_local_m0 : LoadFrag<load_glue>, LocalAddress; 358def sextloadi8_local_m0 : LoadFrag<sextloadi8_glue>, LocalAddress; 359def sextloadi16_local_m0 : LoadFrag<sextloadi16_glue>, LocalAddress; 360def az_extloadi8_local_m0 : LoadFrag<az_extloadi8_glue>, LocalAddress; 361def az_extloadi16_local_m0 : LoadFrag<az_extloadi16_glue>, LocalAddress; 362def load_align8_local_m0 : LoadFrag <load_glue_align8>, LocalAddress; 363def load_align16_local_m0 : LoadFrag <load_glue_align16>, LocalAddress; 364def atomic_load_32_local_m0 : LoadFrag<atomic_load_32_glue>, LocalAddress; 365def atomic_load_64_local_m0 : LoadFrag<atomic_load_64_glue>, LocalAddress; 366 367 368def AMDGPUst_glue : SDNode <"ISD::STORE", SDTStore, 369 [SDNPHasChain, SDNPMayStore, SDNPMemOperand, SDNPInGlue] 370>; 371 372def AMDGPUatomic_st_glue : SDNode <"ISD::ATOMIC_STORE", SDTAtomicStore, 373 [SDNPHasChain, SDNPMayStore, SDNPMemOperand, SDNPInGlue] 374>; 375 376def atomic_store_glue : PatFrag<(ops node:$ptr, node:$val), 377 (AMDGPUatomic_st_glue node:$ptr, node:$val)> { 378} 379 380def unindexedstore_glue : PatFrag<(ops node:$val, node:$ptr), 381 (AMDGPUst_glue node:$val, node:$ptr), [{ 382 return cast<StoreSDNode>(N)->getAddressingMode() == ISD::UNINDEXED; 383}]>; 384 385def store_glue : PatFrag<(ops node:$val, node:$ptr), 386 (unindexedstore_glue node:$val, node:$ptr), [{ 387 return !cast<StoreSDNode>(N)->isTruncatingStore(); 388}]>; 389 390def truncstore_glue : PatFrag<(ops node:$val, node:$ptr), 391 (unindexedstore_glue node:$val, node:$ptr), [{ 392 return cast<StoreSDNode>(N)->isTruncatingStore(); 393}]>; 394 395def truncstorei8_glue : PatFrag<(ops node:$val, node:$ptr), 396 (truncstore_glue node:$val, node:$ptr), [{ 397 return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i8; 398}]>; 399 400def truncstorei16_glue : PatFrag<(ops node:$val, node:$ptr), 401 (truncstore_glue node:$val, node:$ptr), [{ 402 return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i16; 403}]>; 404 405def store_glue_align8 : Aligned8Bytes < 406 (ops node:$value, node:$ptr), (store_glue node:$value, node:$ptr) 407>; 408 409def store_glue_align16 : Aligned16Bytes < 410 (ops node:$value, node:$ptr), (store_glue node:$value, node:$ptr) 411>; 412 413def store_local_m0 : StoreFrag<store_glue>, LocalAddress; 414def truncstorei8_local_m0 : StoreFrag<truncstorei8_glue>, LocalAddress; 415def truncstorei16_local_m0 : StoreFrag<truncstorei16_glue>, LocalAddress; 416def atomic_store_local_m0 : StoreFrag<AMDGPUatomic_st_glue>, LocalAddress; 417 418def store_align8_local_m0 : StoreFrag<store_glue_align8>, LocalAddress; 419def store_align16_local_m0 : StoreFrag<store_glue_align16>, LocalAddress; 420 421def si_setcc_uniform : PatFrag < 422 (ops node:$lhs, node:$rhs, node:$cond), 423 (setcc node:$lhs, node:$rhs, node:$cond), [{ 424 for (SDNode *Use : N->uses()) { 425 if (Use->isMachineOpcode() || Use->getOpcode() != ISD::CopyToReg) 426 return false; 427 428 unsigned Reg = cast<RegisterSDNode>(Use->getOperand(1))->getReg(); 429 if (Reg != AMDGPU::SCC) 430 return false; 431 } 432 return true; 433}]>; 434 435//===----------------------------------------------------------------------===// 436// SDNodes PatFrags for d16 loads 437//===----------------------------------------------------------------------===// 438 439class LoadD16Frag <SDPatternOperator op> : PatFrag<(ops node:$ptr, node:$tied_in), (op node:$ptr, node:$tied_in)>; 440class LocalLoadD16 <SDPatternOperator op> : LoadD16Frag <op>, LocalAddress; 441class GlobalLoadD16 <SDPatternOperator op> : LoadD16Frag <op>, GlobalLoadAddress; 442class PrivateLoadD16 <SDPatternOperator op> : LoadD16Frag <op>, PrivateAddress; 443class FlatLoadD16 <SDPatternOperator op> : LoadD16Frag <op>, FlatLoadAddress; 444 445def load_d16_hi_local : LocalLoadD16 <SIload_d16_hi>; 446def az_extloadi8_d16_hi_local : LocalLoadD16 <SIload_d16_hi_u8>; 447def sextloadi8_d16_hi_local : LocalLoadD16 <SIload_d16_hi_i8>; 448 449def load_d16_hi_global : GlobalLoadD16 <SIload_d16_hi>; 450def az_extloadi8_d16_hi_global : GlobalLoadD16 <SIload_d16_hi_u8>; 451def sextloadi8_d16_hi_global : GlobalLoadD16 <SIload_d16_hi_i8>; 452 453def load_d16_hi_private : PrivateLoadD16 <SIload_d16_hi>; 454def az_extloadi8_d16_hi_private : PrivateLoadD16 <SIload_d16_hi_u8>; 455def sextloadi8_d16_hi_private : PrivateLoadD16 <SIload_d16_hi_i8>; 456 457def load_d16_hi_flat : FlatLoadD16 <SIload_d16_hi>; 458def az_extloadi8_d16_hi_flat : FlatLoadD16 <SIload_d16_hi_u8>; 459def sextloadi8_d16_hi_flat : FlatLoadD16 <SIload_d16_hi_i8>; 460 461 462def load_d16_lo_local : LocalLoadD16 <SIload_d16_lo>; 463def az_extloadi8_d16_lo_local : LocalLoadD16 <SIload_d16_lo_u8>; 464def sextloadi8_d16_lo_local : LocalLoadD16 <SIload_d16_lo_i8>; 465 466def load_d16_lo_global : GlobalLoadD16 <SIload_d16_lo>; 467def az_extloadi8_d16_lo_global : GlobalLoadD16 <SIload_d16_lo_u8>; 468def sextloadi8_d16_lo_global : GlobalLoadD16 <SIload_d16_lo_i8>; 469 470def load_d16_lo_private : PrivateLoadD16 <SIload_d16_lo>; 471def az_extloadi8_d16_lo_private : PrivateLoadD16 <SIload_d16_lo_u8>; 472def sextloadi8_d16_lo_private : PrivateLoadD16 <SIload_d16_lo_i8>; 473 474def load_d16_lo_flat : FlatLoadD16 <SIload_d16_lo>; 475def az_extloadi8_d16_lo_flat : FlatLoadD16 <SIload_d16_lo_u8>; 476def sextloadi8_d16_lo_flat : FlatLoadD16 <SIload_d16_lo_i8>; 477 478 479 480def lshr_rev : PatFrag < 481 (ops node:$src1, node:$src0), 482 (srl $src0, $src1) 483>; 484 485def ashr_rev : PatFrag < 486 (ops node:$src1, node:$src0), 487 (sra $src0, $src1) 488>; 489 490def lshl_rev : PatFrag < 491 (ops node:$src1, node:$src0), 492 (shl $src0, $src1) 493>; 494 495multiclass SIAtomicM0Glue2 <string op_name, bit is_amdgpu = 0, 496 SDTypeProfile tc = SDTAtomic2> { 497 498 def _glue : SDNode < 499 !if(is_amdgpu, "AMDGPUISD", "ISD")#"::ATOMIC_"#op_name, tc, 500 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand, SDNPInGlue] 501 >; 502 503 def _local_m0 : local_binary_atomic_op <!cast<SDNode>(NAME#"_glue")>; 504} 505 506defm atomic_load_add : SIAtomicM0Glue2 <"LOAD_ADD">; 507defm atomic_load_sub : SIAtomicM0Glue2 <"LOAD_SUB">; 508defm atomic_inc : SIAtomicM0Glue2 <"INC", 1>; 509defm atomic_dec : SIAtomicM0Glue2 <"DEC", 1>; 510defm atomic_load_and : SIAtomicM0Glue2 <"LOAD_AND">; 511defm atomic_load_min : SIAtomicM0Glue2 <"LOAD_MIN">; 512defm atomic_load_max : SIAtomicM0Glue2 <"LOAD_MAX">; 513defm atomic_load_or : SIAtomicM0Glue2 <"LOAD_OR">; 514defm atomic_load_xor : SIAtomicM0Glue2 <"LOAD_XOR">; 515defm atomic_load_umin : SIAtomicM0Glue2 <"LOAD_UMIN">; 516defm atomic_load_umax : SIAtomicM0Glue2 <"LOAD_UMAX">; 517defm atomic_swap : SIAtomicM0Glue2 <"SWAP">; 518defm atomic_load_fadd : SIAtomicM0Glue2 <"LOAD_FADD", 0, SDTAtomic2_f32>; 519defm atomic_load_fmin : SIAtomicM0Glue2 <"LOAD_FMIN", 1, SDTAtomic2_f32>; 520defm atomic_load_fmax : SIAtomicM0Glue2 <"LOAD_FMAX", 1, SDTAtomic2_f32>; 521 522def atomic_cmp_swap_glue : SDNode <"ISD::ATOMIC_CMP_SWAP", SDTAtomic3, 523 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand, SDNPInGlue] 524>; 525 526def atomic_cmp_swap_local_m0 : AtomicCmpSwapLocal<atomic_cmp_swap_glue>; 527 528 529def as_i1imm : SDNodeXForm<imm, [{ 530 return CurDAG->getTargetConstant(N->getZExtValue(), SDLoc(N), MVT::i1); 531}]>; 532 533def as_i8imm : SDNodeXForm<imm, [{ 534 return CurDAG->getTargetConstant(N->getZExtValue(), SDLoc(N), MVT::i8); 535}]>; 536 537def as_i16imm : SDNodeXForm<imm, [{ 538 return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i16); 539}]>; 540 541def as_i32imm: SDNodeXForm<imm, [{ 542 return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i32); 543}]>; 544 545def as_i64imm: SDNodeXForm<imm, [{ 546 return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i64); 547}]>; 548 549def cond_as_i32imm: SDNodeXForm<cond, [{ 550 return CurDAG->getTargetConstant(N->get(), SDLoc(N), MVT::i32); 551}]>; 552 553// Copied from the AArch64 backend: 554def bitcast_fpimm_to_i32 : SDNodeXForm<fpimm, [{ 555return CurDAG->getTargetConstant( 556 N->getValueAPF().bitcastToAPInt().getZExtValue(), SDLoc(N), MVT::i32); 557}]>; 558 559def frameindex_to_targetframeindex : SDNodeXForm<frameindex, [{ 560 auto FI = cast<FrameIndexSDNode>(N); 561 return CurDAG->getTargetFrameIndex(FI->getIndex(), MVT::i32); 562}]>; 563 564// Copied from the AArch64 backend: 565def bitcast_fpimm_to_i64 : SDNodeXForm<fpimm, [{ 566return CurDAG->getTargetConstant( 567 N->getValueAPF().bitcastToAPInt().getZExtValue(), SDLoc(N), MVT::i64); 568}]>; 569 570class bitextract_imm<int bitnum> : SDNodeXForm<imm, [{ 571 uint64_t Imm = N->getZExtValue(); 572 unsigned Bit = (Imm >> }] # bitnum # [{ ) & 1; 573 return CurDAG->getTargetConstant(Bit, SDLoc(N), MVT::i1); 574}]>; 575 576def SIMM16bit : PatLeaf <(imm), 577 [{return isInt<16>(N->getSExtValue());}] 578>; 579 580class InlineImm <ValueType vt> : PatLeaf <(vt imm), [{ 581 return isInlineImmediate(N); 582}]>; 583 584class InlineFPImm <ValueType vt> : PatLeaf <(vt fpimm), [{ 585 return isInlineImmediate(N); 586}]>; 587 588class VGPRImm <dag frag> : PatLeaf<frag, [{ 589 return isVGPRImm(N); 590}]>; 591 592def NegateImm : SDNodeXForm<imm, [{ 593 return CurDAG->getConstant(-N->getSExtValue(), SDLoc(N), MVT::i32); 594}]>; 595 596// TODO: When FP inline imm values work? 597def NegSubInlineConst32 : ImmLeaf<i32, [{ 598 return Imm < -16 && Imm >= -64; 599}], NegateImm>; 600 601def NegSubInlineConst16 : ImmLeaf<i16, [{ 602 return Imm < -16 && Imm >= -64; 603}], NegateImm>; 604 605def ShiftAmt32Imm : PatLeaf <(imm), [{ 606 return N->getZExtValue() < 32; 607}]>; 608 609//===----------------------------------------------------------------------===// 610// Custom Operands 611//===----------------------------------------------------------------------===// 612 613def SoppBrTarget : AsmOperandClass { 614 let Name = "SoppBrTarget"; 615 let ParserMethod = "parseSOppBrTarget"; 616} 617 618def sopp_brtarget : Operand<OtherVT> { 619 let EncoderMethod = "getSOPPBrEncoding"; 620 let DecoderMethod = "decodeSoppBrTarget"; 621 let OperandType = "OPERAND_PCREL"; 622 let ParserMatchClass = SoppBrTarget; 623} 624 625def si_ga : Operand<iPTR>; 626 627def InterpSlotMatchClass : AsmOperandClass { 628 let Name = "InterpSlot"; 629 let PredicateMethod = "isInterpSlot"; 630 let ParserMethod = "parseInterpSlot"; 631 let RenderMethod = "addImmOperands"; 632} 633 634def InterpSlot : Operand<i32> { 635 let PrintMethod = "printInterpSlot"; 636 let ParserMatchClass = InterpSlotMatchClass; 637 let OperandType = "OPERAND_IMMEDIATE"; 638} 639 640def AttrMatchClass : AsmOperandClass { 641 let Name = "Attr"; 642 let PredicateMethod = "isInterpAttr"; 643 let ParserMethod = "parseInterpAttr"; 644 let RenderMethod = "addImmOperands"; 645} 646 647// It appears to be necessary to create a separate operand for this to 648// be able to parse attr<num> with no space. 649def Attr : Operand<i32> { 650 let PrintMethod = "printInterpAttr"; 651 let ParserMatchClass = AttrMatchClass; 652 let OperandType = "OPERAND_IMMEDIATE"; 653} 654 655def AttrChanMatchClass : AsmOperandClass { 656 let Name = "AttrChan"; 657 let PredicateMethod = "isAttrChan"; 658 let RenderMethod = "addImmOperands"; 659} 660 661def AttrChan : Operand<i32> { 662 let PrintMethod = "printInterpAttrChan"; 663 let ParserMatchClass = AttrChanMatchClass; 664 let OperandType = "OPERAND_IMMEDIATE"; 665} 666 667def SendMsgMatchClass : AsmOperandClass { 668 let Name = "SendMsg"; 669 let PredicateMethod = "isSendMsg"; 670 let ParserMethod = "parseSendMsgOp"; 671 let RenderMethod = "addImmOperands"; 672} 673 674def SwizzleMatchClass : AsmOperandClass { 675 let Name = "Swizzle"; 676 let PredicateMethod = "isSwizzle"; 677 let ParserMethod = "parseSwizzleOp"; 678 let RenderMethod = "addImmOperands"; 679 let IsOptional = 1; 680} 681 682def EndpgmMatchClass : AsmOperandClass { 683 let Name = "EndpgmImm"; 684 let PredicateMethod = "isEndpgm"; 685 let ParserMethod = "parseEndpgmOp"; 686 let RenderMethod = "addImmOperands"; 687 let IsOptional = 1; 688} 689 690def ExpTgtMatchClass : AsmOperandClass { 691 let Name = "ExpTgt"; 692 let PredicateMethod = "isExpTgt"; 693 let ParserMethod = "parseExpTgt"; 694 let RenderMethod = "printExpTgt"; 695} 696 697def SendMsgImm : Operand<i32> { 698 let PrintMethod = "printSendMsg"; 699 let ParserMatchClass = SendMsgMatchClass; 700} 701 702def SwizzleImm : Operand<i16> { 703 let PrintMethod = "printSwizzle"; 704 let ParserMatchClass = SwizzleMatchClass; 705} 706 707def EndpgmImm : Operand<i16> { 708 let PrintMethod = "printEndpgm"; 709 let ParserMatchClass = EndpgmMatchClass; 710} 711 712def SWaitMatchClass : AsmOperandClass { 713 let Name = "SWaitCnt"; 714 let RenderMethod = "addImmOperands"; 715 let ParserMethod = "parseSWaitCntOps"; 716} 717 718def VReg32OrOffClass : AsmOperandClass { 719 let Name = "VReg32OrOff"; 720 let ParserMethod = "parseVReg32OrOff"; 721} 722 723def WAIT_FLAG : Operand <i32> { 724 let ParserMatchClass = SWaitMatchClass; 725 let PrintMethod = "printWaitFlag"; 726} 727 728include "SIInstrFormats.td" 729include "VIInstrFormats.td" 730 731// ===----------------------------------------------------------------------===// 732// ExpSrc* Special cases for exp src operands which are printed as 733// "off" depending on en operand. 734// ===----------------------------------------------------------------------===// 735 736def ExpSrc0 : RegisterOperand<VGPR_32> { 737 let PrintMethod = "printExpSrc0"; 738 let ParserMatchClass = VReg32OrOffClass; 739} 740 741def ExpSrc1 : RegisterOperand<VGPR_32> { 742 let PrintMethod = "printExpSrc1"; 743 let ParserMatchClass = VReg32OrOffClass; 744} 745 746def ExpSrc2 : RegisterOperand<VGPR_32> { 747 let PrintMethod = "printExpSrc2"; 748 let ParserMatchClass = VReg32OrOffClass; 749} 750 751def ExpSrc3 : RegisterOperand<VGPR_32> { 752 let PrintMethod = "printExpSrc3"; 753 let ParserMatchClass = VReg32OrOffClass; 754} 755 756class SDWASrc<ValueType vt> : RegisterOperand<VS_32> { 757 let OperandNamespace = "AMDGPU"; 758 string Type = !if(isFloatType<vt>.ret, "FP", "INT"); 759 let OperandType = "OPERAND_REG_INLINE_C_"#Type#vt.Size; 760 let DecoderMethod = "decodeSDWASrc"#vt.Size; 761 let EncoderMethod = "getSDWASrcEncoding"; 762} 763 764def SDWASrc_i32 : SDWASrc<i32>; 765def SDWASrc_i16 : SDWASrc<i16>; 766def SDWASrc_f32 : SDWASrc<f32>; 767def SDWASrc_f16 : SDWASrc<f16>; 768 769def SDWAVopcDst : VOPDstOperand<SReg_64> { 770 let OperandNamespace = "AMDGPU"; 771 let OperandType = "OPERAND_SDWA_VOPC_DST"; 772 let EncoderMethod = "getSDWAVopcDstEncoding"; 773 let DecoderMethod = "decodeSDWAVopcDst"; 774} 775 776class NamedMatchClass<string CName, bit Optional = 1> : AsmOperandClass { 777 let Name = "Imm"#CName; 778 let PredicateMethod = "is"#CName; 779 let ParserMethod = !if(Optional, "parseOptionalOperand", "parse"#CName); 780 let RenderMethod = "addImmOperands"; 781 let IsOptional = Optional; 782 let DefaultMethod = !if(Optional, "default"#CName, ?); 783} 784 785class NamedOperandBit<string Name, AsmOperandClass MatchClass> : Operand<i1> { 786 let PrintMethod = "print"#Name; 787 let ParserMatchClass = MatchClass; 788} 789 790class NamedOperandU8<string Name, AsmOperandClass MatchClass> : Operand<i8> { 791 let PrintMethod = "print"#Name; 792 let ParserMatchClass = MatchClass; 793} 794 795class NamedOperandU12<string Name, AsmOperandClass MatchClass> : Operand<i16> { 796 let PrintMethod = "print"#Name; 797 let ParserMatchClass = MatchClass; 798} 799 800class NamedOperandU16<string Name, AsmOperandClass MatchClass> : Operand<i16> { 801 let PrintMethod = "print"#Name; 802 let ParserMatchClass = MatchClass; 803} 804 805class NamedOperandS13<string Name, AsmOperandClass MatchClass> : Operand<i16> { 806 let PrintMethod = "print"#Name; 807 let ParserMatchClass = MatchClass; 808} 809 810class NamedOperandU32<string Name, AsmOperandClass MatchClass> : Operand<i32> { 811 let PrintMethod = "print"#Name; 812 let ParserMatchClass = MatchClass; 813} 814 815class NamedOperandU32Default0<string Name, AsmOperandClass MatchClass> : 816 OperandWithDefaultOps<i32, (ops (i32 0))> { 817 let PrintMethod = "print"#Name; 818 let ParserMatchClass = MatchClass; 819} 820 821let OperandType = "OPERAND_IMMEDIATE" in { 822 823def offen : NamedOperandBit<"Offen", NamedMatchClass<"Offen">>; 824def idxen : NamedOperandBit<"Idxen", NamedMatchClass<"Idxen">>; 825def addr64 : NamedOperandBit<"Addr64", NamedMatchClass<"Addr64">>; 826 827def offset_u12 : NamedOperandU12<"Offset", NamedMatchClass<"OffsetU12">>; 828def offset_s13 : NamedOperandS13<"OffsetS13", NamedMatchClass<"OffsetS13">>; 829def offset : NamedOperandU16<"Offset", NamedMatchClass<"Offset">>; 830def offset0 : NamedOperandU8<"Offset0", NamedMatchClass<"Offset0">>; 831def offset1 : NamedOperandU8<"Offset1", NamedMatchClass<"Offset1">>; 832 833def gds : NamedOperandBit<"GDS", NamedMatchClass<"GDS">>; 834 835def omod : NamedOperandU32<"OModSI", NamedMatchClass<"OModSI">>; 836def clampmod : NamedOperandBit<"ClampSI", NamedMatchClass<"ClampSI">>; 837def highmod : NamedOperandBit<"High", NamedMatchClass<"High">>; 838 839def GLC : NamedOperandBit<"GLC", NamedMatchClass<"GLC">>; 840def SLC : NamedOperandBit<"SLC", NamedMatchClass<"SLC">>; 841def TFE : NamedOperandBit<"TFE", NamedMatchClass<"TFE">>; 842def UNorm : NamedOperandBit<"UNorm", NamedMatchClass<"UNorm">>; 843def DA : NamedOperandBit<"DA", NamedMatchClass<"DA">>; 844def R128A16 : NamedOperandBit<"R128A16", NamedMatchClass<"R128A16">>; 845def D16 : NamedOperandBit<"D16", NamedMatchClass<"D16">>; 846def LWE : NamedOperandBit<"LWE", NamedMatchClass<"LWE">>; 847def exp_compr : NamedOperandBit<"ExpCompr", NamedMatchClass<"ExpCompr">>; 848def exp_vm : NamedOperandBit<"ExpVM", NamedMatchClass<"ExpVM">>; 849 850def FORMAT : NamedOperandU8<"FORMAT", NamedMatchClass<"FORMAT">>; 851 852def DMask : NamedOperandU16<"DMask", NamedMatchClass<"DMask">>; 853 854def dpp_ctrl : NamedOperandU32<"DPPCtrl", NamedMatchClass<"DPPCtrl", 0>>; 855def row_mask : NamedOperandU32<"RowMask", NamedMatchClass<"RowMask">>; 856def bank_mask : NamedOperandU32<"BankMask", NamedMatchClass<"BankMask">>; 857def bound_ctrl : NamedOperandBit<"BoundCtrl", NamedMatchClass<"BoundCtrl">>; 858 859def dst_sel : NamedOperandU32<"SDWADstSel", NamedMatchClass<"SDWADstSel">>; 860def src0_sel : NamedOperandU32<"SDWASrc0Sel", NamedMatchClass<"SDWASrc0Sel">>; 861def src1_sel : NamedOperandU32<"SDWASrc1Sel", NamedMatchClass<"SDWASrc1Sel">>; 862def dst_unused : NamedOperandU32<"SDWADstUnused", NamedMatchClass<"SDWADstUnused">>; 863 864def op_sel : NamedOperandU32Default0<"OpSel", NamedMatchClass<"OpSel">>; 865def op_sel_hi : NamedOperandU32Default0<"OpSelHi", NamedMatchClass<"OpSelHi">>; 866def neg_lo : NamedOperandU32Default0<"NegLo", NamedMatchClass<"NegLo">>; 867def neg_hi : NamedOperandU32Default0<"NegHi", NamedMatchClass<"NegHi">>; 868 869def hwreg : NamedOperandU16<"Hwreg", NamedMatchClass<"Hwreg", 0>>; 870 871def exp_tgt : NamedOperandU8<"ExpTgt", NamedMatchClass<"ExpTgt", 0>> { 872 873} 874 875} // End OperandType = "OPERAND_IMMEDIATE" 876 877class KImmMatchClass<int size> : AsmOperandClass { 878 let Name = "KImmFP"#size; 879 let PredicateMethod = "isKImmFP"#size; 880 let ParserMethod = "parseImm"; 881 let RenderMethod = "addKImmFP"#size#"Operands"; 882} 883 884class kimmOperand<ValueType vt> : Operand<vt> { 885 let OperandNamespace = "AMDGPU"; 886 let OperandType = "OPERAND_KIMM"#vt.Size; 887 let PrintMethod = "printU"#vt.Size#"ImmOperand"; 888 let ParserMatchClass = !cast<AsmOperandClass>("KImmFP"#vt.Size#"MatchClass"); 889} 890 891// 32-bit VALU immediate operand that uses the constant bus. 892def KImmFP32MatchClass : KImmMatchClass<32>; 893def f32kimm : kimmOperand<i32>; 894 895// 32-bit VALU immediate operand with a 16-bit value that uses the 896// constant bus. 897def KImmFP16MatchClass : KImmMatchClass<16>; 898def f16kimm : kimmOperand<i16>; 899 900 901def VOPDstS64 : VOPDstOperand <SReg_64>; 902 903class FPInputModsMatchClass <int opSize> : AsmOperandClass { 904 let Name = "RegOrImmWithFP"#opSize#"InputMods"; 905 let ParserMethod = "parseRegOrImmWithFPInputMods"; 906 let PredicateMethod = "isRegOrImmWithFP"#opSize#"InputMods"; 907} 908 909def FP16InputModsMatchClass : FPInputModsMatchClass<16>; 910def FP32InputModsMatchClass : FPInputModsMatchClass<32>; 911def FP64InputModsMatchClass : FPInputModsMatchClass<64>; 912 913class InputMods <AsmOperandClass matchClass> : Operand <i32> { 914 let OperandNamespace = "AMDGPU"; 915 let OperandType = "OPERAND_INPUT_MODS"; 916 let ParserMatchClass = matchClass; 917} 918 919class FPInputMods <FPInputModsMatchClass matchClass> : InputMods <matchClass> { 920 let PrintMethod = "printOperandAndFPInputMods"; 921} 922 923def FP16InputMods : FPInputMods<FP16InputModsMatchClass>; 924def FP32InputMods : FPInputMods<FP32InputModsMatchClass>; 925def FP64InputMods : FPInputMods<FP64InputModsMatchClass>; 926 927class IntInputModsMatchClass <int opSize> : AsmOperandClass { 928 let Name = "RegOrImmWithInt"#opSize#"InputMods"; 929 let ParserMethod = "parseRegOrImmWithIntInputMods"; 930 let PredicateMethod = "isRegOrImmWithInt"#opSize#"InputMods"; 931} 932def Int32InputModsMatchClass : IntInputModsMatchClass<32>; 933def Int64InputModsMatchClass : IntInputModsMatchClass<64>; 934 935class IntInputMods <IntInputModsMatchClass matchClass> : InputMods <matchClass> { 936 let PrintMethod = "printOperandAndIntInputMods"; 937} 938def Int32InputMods : IntInputMods<Int32InputModsMatchClass>; 939def Int64InputMods : IntInputMods<Int64InputModsMatchClass>; 940 941class OpSelModsMatchClass : AsmOperandClass { 942 let Name = "OpSelMods"; 943 let ParserMethod = "parseRegOrImm"; 944 let PredicateMethod = "isRegOrImm"; 945} 946 947def IntOpSelModsMatchClass : OpSelModsMatchClass; 948def IntOpSelMods : InputMods<IntOpSelModsMatchClass>; 949 950class FPSDWAInputModsMatchClass <int opSize> : AsmOperandClass { 951 let Name = "SDWAWithFP"#opSize#"InputMods"; 952 let ParserMethod = "parseRegOrImmWithFPInputMods"; 953 let PredicateMethod = "isSDWAFP"#opSize#"Operand"; 954} 955 956def FP16SDWAInputModsMatchClass : FPSDWAInputModsMatchClass<16>; 957def FP32SDWAInputModsMatchClass : FPSDWAInputModsMatchClass<32>; 958 959class FPSDWAInputMods <FPSDWAInputModsMatchClass matchClass> : 960 InputMods <matchClass> { 961 let PrintMethod = "printOperandAndFPInputMods"; 962} 963 964def FP16SDWAInputMods : FPSDWAInputMods<FP16SDWAInputModsMatchClass>; 965def FP32SDWAInputMods : FPSDWAInputMods<FP32SDWAInputModsMatchClass>; 966 967def FPVRegInputModsMatchClass : AsmOperandClass { 968 let Name = "VRegWithFPInputMods"; 969 let ParserMethod = "parseRegWithFPInputMods"; 970 let PredicateMethod = "isVReg32"; 971} 972 973def FPVRegInputMods : InputMods <FPVRegInputModsMatchClass> { 974 let PrintMethod = "printOperandAndFPInputMods"; 975} 976 977class IntSDWAInputModsMatchClass <int opSize> : AsmOperandClass { 978 let Name = "SDWAWithInt"#opSize#"InputMods"; 979 let ParserMethod = "parseRegOrImmWithIntInputMods"; 980 let PredicateMethod = "isSDWAInt"#opSize#"Operand"; 981} 982 983def Int16SDWAInputModsMatchClass : IntSDWAInputModsMatchClass<16>; 984def Int32SDWAInputModsMatchClass : IntSDWAInputModsMatchClass<32>; 985 986class IntSDWAInputMods <IntSDWAInputModsMatchClass matchClass> : 987 InputMods <matchClass> { 988 let PrintMethod = "printOperandAndIntInputMods"; 989} 990 991def Int16SDWAInputMods : IntSDWAInputMods<Int16SDWAInputModsMatchClass>; 992def Int32SDWAInputMods : IntSDWAInputMods<Int32SDWAInputModsMatchClass>; 993 994def IntVRegInputModsMatchClass : AsmOperandClass { 995 let Name = "VRegWithIntInputMods"; 996 let ParserMethod = "parseRegWithIntInputMods"; 997 let PredicateMethod = "isVReg32"; 998} 999 1000def IntVRegInputMods : InputMods <IntVRegInputModsMatchClass> { 1001 let PrintMethod = "printOperandAndIntInputMods"; 1002} 1003 1004class PackedFPInputModsMatchClass <int opSize> : AsmOperandClass { 1005 let Name = "PackedFP"#opSize#"InputMods"; 1006 let ParserMethod = "parseRegOrImm"; 1007 let PredicateMethod = "isRegOrImm"; 1008// let PredicateMethod = "isPackedFP"#opSize#"InputMods"; 1009} 1010 1011class PackedIntInputModsMatchClass <int opSize> : AsmOperandClass { 1012 let Name = "PackedInt"#opSize#"InputMods"; 1013 let ParserMethod = "parseRegOrImm"; 1014 let PredicateMethod = "isRegOrImm"; 1015// let PredicateMethod = "isPackedInt"#opSize#"InputMods"; 1016} 1017 1018def PackedF16InputModsMatchClass : PackedFPInputModsMatchClass<16>; 1019def PackedI16InputModsMatchClass : PackedIntInputModsMatchClass<16>; 1020 1021class PackedFPInputMods <PackedFPInputModsMatchClass matchClass> : InputMods <matchClass> { 1022// let PrintMethod = "printPackedFPInputMods"; 1023} 1024 1025class PackedIntInputMods <PackedIntInputModsMatchClass matchClass> : InputMods <matchClass> { 1026 //let PrintMethod = "printPackedIntInputMods"; 1027} 1028 1029def PackedF16InputMods : PackedFPInputMods<PackedF16InputModsMatchClass>; 1030def PackedI16InputMods : PackedIntInputMods<PackedI16InputModsMatchClass>; 1031 1032//===----------------------------------------------------------------------===// 1033// Complex patterns 1034//===----------------------------------------------------------------------===// 1035 1036def DS1Addr1Offset : ComplexPattern<i32, 2, "SelectDS1Addr1Offset">; 1037def DS64Bit4ByteAligned : ComplexPattern<i32, 3, "SelectDS64Bit4ByteAligned">; 1038 1039def MOVRELOffset : ComplexPattern<i32, 2, "SelectMOVRELOffset">; 1040 1041def VOP3Mods0 : ComplexPattern<untyped, 4, "SelectVOP3Mods0">; 1042def VOP3Mods0Clamp : ComplexPattern<untyped, 3, "SelectVOP3Mods0Clamp">; 1043def VOP3Mods0Clamp0OMod : ComplexPattern<untyped, 4, "SelectVOP3Mods0Clamp0OMod">; 1044def VOP3Mods : ComplexPattern<untyped, 2, "SelectVOP3Mods">; 1045def VOP3NoMods : ComplexPattern<untyped, 1, "SelectVOP3NoMods">; 1046// VOP3Mods, but the input source is known to never be NaN. 1047def VOP3Mods_nnan : ComplexPattern<fAny, 2, "SelectVOP3Mods_NNaN">; 1048 1049def VOP3OMods : ComplexPattern<untyped, 3, "SelectVOP3OMods">; 1050 1051def VOP3PMods : ComplexPattern<untyped, 2, "SelectVOP3PMods">; 1052def VOP3PMods0 : ComplexPattern<untyped, 3, "SelectVOP3PMods0">; 1053 1054def VOP3OpSel : ComplexPattern<untyped, 2, "SelectVOP3OpSel">; 1055def VOP3OpSel0 : ComplexPattern<untyped, 3, "SelectVOP3OpSel0">; 1056 1057def VOP3OpSelMods : ComplexPattern<untyped, 2, "SelectVOP3OpSelMods">; 1058def VOP3OpSelMods0 : ComplexPattern<untyped, 3, "SelectVOP3OpSelMods0">; 1059 1060def VOP3PMadMixMods : ComplexPattern<untyped, 2, "SelectVOP3PMadMixMods">; 1061 1062 1063def Hi16Elt : ComplexPattern<untyped, 1, "SelectHi16Elt">; 1064 1065//===----------------------------------------------------------------------===// 1066// SI assembler operands 1067//===----------------------------------------------------------------------===// 1068 1069def SIOperand { 1070 int ZERO = 0x80; 1071 int VCC = 0x6A; 1072 int FLAT_SCR = 0x68; 1073} 1074 1075// This should be kept in sync with SISrcMods enum 1076def SRCMODS { 1077 int NONE = 0; 1078 int NEG = 1; 1079 int ABS = 2; 1080 int NEG_ABS = 3; 1081 1082 int NEG_HI = ABS; 1083 int OP_SEL_0 = 4; 1084 int OP_SEL_1 = 8; 1085 int DST_OP_SEL = 8; 1086} 1087 1088def DSTCLAMP { 1089 int NONE = 0; 1090 int ENABLE = 1; 1091} 1092 1093def DSTOMOD { 1094 int NONE = 0; 1095} 1096 1097def TRAPID{ 1098 int LLVM_TRAP = 2; 1099 int LLVM_DEBUG_TRAP = 3; 1100} 1101 1102//===----------------------------------------------------------------------===// 1103// 1104// SI Instruction multiclass helpers. 1105// 1106// Instructions with _32 take 32-bit operands. 1107// Instructions with _64 take 64-bit operands. 1108// 1109// VOP_* instructions can use either a 32-bit or 64-bit encoding. The 32-bit 1110// encoding is the standard encoding, but instruction that make use of 1111// any of the instruction modifiers must use the 64-bit encoding. 1112// 1113// Instructions with _e32 use the 32-bit encoding. 1114// Instructions with _e64 use the 64-bit encoding. 1115// 1116//===----------------------------------------------------------------------===// 1117 1118class SIMCInstr <string pseudo, int subtarget> { 1119 string PseudoInstr = pseudo; 1120 int Subtarget = subtarget; 1121} 1122 1123//===----------------------------------------------------------------------===// 1124// EXP classes 1125//===----------------------------------------------------------------------===// 1126 1127class EXP_Helper<bit done, SDPatternOperator node = null_frag> : EXPCommon< 1128 (outs), 1129 (ins exp_tgt:$tgt, 1130 ExpSrc0:$src0, ExpSrc1:$src1, ExpSrc2:$src2, ExpSrc3:$src3, 1131 exp_vm:$vm, exp_compr:$compr, i8imm:$en), 1132 "exp$tgt $src0, $src1, $src2, $src3"#!if(done, " done", "")#"$compr$vm", 1133 [(node (i8 timm:$tgt), (i8 timm:$en), 1134 f32:$src0, f32:$src1, f32:$src2, f32:$src3, 1135 (i1 timm:$compr), (i1 timm:$vm))]> { 1136 let AsmMatchConverter = "cvtExp"; 1137} 1138 1139// Split EXP instruction into EXP and EXP_DONE so we can set 1140// mayLoad for done=1. 1141multiclass EXP_m<bit done, SDPatternOperator node> { 1142 let mayLoad = done, DisableWQM = 1 in { 1143 let isPseudo = 1, isCodeGenOnly = 1 in { 1144 def "" : EXP_Helper<done, node>, 1145 SIMCInstr <"exp"#!if(done, "_done", ""), SIEncodingFamily.NONE>; 1146 } 1147 1148 let done = done in { 1149 def _si : EXP_Helper<done>, 1150 SIMCInstr <"exp"#!if(done, "_done", ""), SIEncodingFamily.SI>, 1151 EXPe { 1152 let AssemblerPredicates = [isSICI]; 1153 let DecoderNamespace = "SICI"; 1154 let DisableDecoder = DisableSIDecoder; 1155 } 1156 1157 def _vi : EXP_Helper<done>, 1158 SIMCInstr <"exp"#!if(done, "_done", ""), SIEncodingFamily.VI>, 1159 EXPe_vi { 1160 let AssemblerPredicates = [isVI]; 1161 let DecoderNamespace = "VI"; 1162 let DisableDecoder = DisableVIDecoder; 1163 } 1164 } 1165 } 1166} 1167 1168//===----------------------------------------------------------------------===// 1169// Vector ALU classes 1170//===----------------------------------------------------------------------===// 1171 1172class getNumSrcArgs<ValueType Src0, ValueType Src1, ValueType Src2> { 1173 int ret = 1174 !if (!eq(Src0.Value, untyped.Value), 0, 1175 !if (!eq(Src1.Value, untyped.Value), 1, // VOP1 1176 !if (!eq(Src2.Value, untyped.Value), 2, // VOP2 1177 3))); // VOP3 1178} 1179 1180// Returns the register class to use for the destination of VOP[123C] 1181// instructions for the given VT. 1182class getVALUDstForVT<ValueType VT> { 1183 RegisterOperand ret = !if(!eq(VT.Size, 32), VOPDstOperand<VGPR_32>, 1184 !if(!eq(VT.Size, 128), VOPDstOperand<VReg_128>, 1185 !if(!eq(VT.Size, 64), VOPDstOperand<VReg_64>, 1186 !if(!eq(VT.Size, 16), VOPDstOperand<VGPR_32>, 1187 VOPDstOperand<SReg_64>)))); // else VT == i1 1188} 1189 1190// Returns the register class to use for the destination of VOP[12C] 1191// instructions with SDWA extension 1192class getSDWADstForVT<ValueType VT> { 1193 RegisterOperand ret = !if(!eq(VT.Size, 1), 1194 SDWAVopcDst, // VOPC 1195 VOPDstOperand<VGPR_32>); // VOP1/2 32-bit dst 1196} 1197 1198// Returns the register class to use for source 0 of VOP[12C] 1199// instructions for the given VT. 1200class getVOPSrc0ForVT<ValueType VT> { 1201 bit isFP = !if(!eq(VT.Value, f16.Value), 1, 1202 !if(!eq(VT.Value, v2f16.Value), 1, 1203 !if(!eq(VT.Value, f32.Value), 1, 1204 !if(!eq(VT.Value, f64.Value), 1, 1205 0)))); 1206 1207 RegisterOperand ret = 1208 !if(isFP, 1209 !if(!eq(VT.Size, 64), 1210 VSrc_f64, 1211 !if(!eq(VT.Value, f16.Value), 1212 VSrc_f16, 1213 !if(!eq(VT.Value, v2f16.Value), 1214 VCSrc_v2f16, 1215 VSrc_f32 1216 ) 1217 ) 1218 ), 1219 !if(!eq(VT.Size, 64), 1220 VSrc_b64, 1221 !if(!eq(VT.Value, i16.Value), 1222 VSrc_b16, 1223 !if(!eq(VT.Value, v2i16.Value), 1224 VCSrc_v2b16, 1225 VSrc_b32 1226 ) 1227 ) 1228 ) 1229 ); 1230} 1231 1232// Returns the vreg register class to use for source operand given VT 1233class getVregSrcForVT<ValueType VT> { 1234 RegisterClass ret = !if(!eq(VT.Size, 128), VReg_128, 1235 !if(!eq(VT.Size, 64), VReg_64, VGPR_32)); 1236} 1237 1238class getSDWASrcForVT <ValueType VT> { 1239 bit isFP = !if(!eq(VT.Value, f16.Value), 1, 1240 !if(!eq(VT.Value, f32.Value), 1, 1241 0)); 1242 RegisterOperand retFlt = !if(!eq(VT.Size, 16), SDWASrc_f16, SDWASrc_f32); 1243 RegisterOperand retInt = !if(!eq(VT.Size, 16), SDWASrc_i16, SDWASrc_i32); 1244 RegisterOperand ret = !if(isFP, retFlt, retInt); 1245} 1246 1247// Returns the register class to use for sources of VOP3 instructions for the 1248// given VT. 1249class getVOP3SrcForVT<ValueType VT> { 1250 bit isFP = !if(!eq(VT.Value, f16.Value), 1, 1251 !if(!eq(VT.Value, v2f16.Value), 1, 1252 !if(!eq(VT.Value, f32.Value), 1, 1253 !if(!eq(VT.Value, f64.Value), 1, 1254 0)))); 1255 RegisterOperand ret = 1256 !if(!eq(VT.Size, 128), 1257 VSrc_128, 1258 !if(!eq(VT.Size, 64), 1259 !if(isFP, 1260 VCSrc_f64, 1261 VCSrc_b64), 1262 !if(!eq(VT.Value, i1.Value), 1263 SCSrc_i1, 1264 !if(isFP, 1265 !if(!eq(VT.Value, f16.Value), 1266 VCSrc_f16, 1267 !if(!eq(VT.Value, v2f16.Value), 1268 VCSrc_v2f16, 1269 VCSrc_f32 1270 ) 1271 ), 1272 !if(!eq(VT.Value, i16.Value), 1273 VCSrc_b16, 1274 !if(!eq(VT.Value, v2i16.Value), 1275 VCSrc_v2b16, 1276 VCSrc_b32 1277 ) 1278 ) 1279 ) 1280 ) 1281 ) 1282 ); 1283} 1284 1285// Float or packed int 1286class isModifierType<ValueType SrcVT> { 1287 bit ret = 1288 !if(!eq(SrcVT.Value, f16.Value), 1, 1289 !if(!eq(SrcVT.Value, f32.Value), 1, 1290 !if(!eq(SrcVT.Value, f64.Value), 1, 1291 !if(!eq(SrcVT.Value, v2f16.Value), 1, 1292 !if(!eq(SrcVT.Value, v2i16.Value), 1, 1293 0))))); 1294} 1295 1296// Return type of input modifiers operand for specified input operand 1297class getSrcMod <ValueType VT, bit EnableF32SrcMods> { 1298 bit isFP = !if(!eq(VT.Value, f16.Value), 1, 1299 !if(!eq(VT.Value, f32.Value), 1, 1300 !if(!eq(VT.Value, f64.Value), 1, 1301 0))); 1302 bit isPacked = isPackedType<VT>.ret; 1303 Operand ret = !if(!eq(VT.Size, 64), 1304 !if(isFP, FP64InputMods, Int64InputMods), 1305 !if(isFP, 1306 !if(!eq(VT.Value, f16.Value), 1307 FP16InputMods, 1308 FP32InputMods 1309 ), 1310 !if(EnableF32SrcMods, FP32InputMods, Int32InputMods)) 1311 ); 1312} 1313 1314class getOpSelMod <ValueType VT> { 1315 Operand ret = !if(!eq(VT.Value, f16.Value), FP16InputMods, IntOpSelMods); 1316} 1317 1318// Return type of input modifiers operand specified input operand for DPP 1319class getSrcModExt <ValueType VT> { 1320 bit isFP = !if(!eq(VT.Value, f16.Value), 1, 1321 !if(!eq(VT.Value, f32.Value), 1, 1322 !if(!eq(VT.Value, f64.Value), 1, 1323 0))); 1324 Operand ret = !if(isFP, FPVRegInputMods, IntVRegInputMods); 1325} 1326 1327// Return type of input modifiers operand specified input operand for SDWA 1328class getSrcModSDWA <ValueType VT> { 1329 Operand ret = !if(!eq(VT.Value, f16.Value), FP16SDWAInputMods, 1330 !if(!eq(VT.Value, f32.Value), FP32SDWAInputMods, 1331 !if(!eq(VT.Value, i16.Value), Int16SDWAInputMods, 1332 Int32SDWAInputMods))); 1333} 1334 1335// Returns the input arguments for VOP[12C] instructions for the given SrcVT. 1336class getIns32 <RegisterOperand Src0RC, RegisterClass Src1RC, int NumSrcArgs> { 1337 dag ret = !if(!eq(NumSrcArgs, 1), (ins Src0RC:$src0), // VOP1 1338 !if(!eq(NumSrcArgs, 2), (ins Src0RC:$src0, Src1RC:$src1), // VOP2 1339 (ins))); 1340} 1341 1342// Returns the input arguments for VOP3 instructions for the given SrcVT. 1343class getIns64 <RegisterOperand Src0RC, RegisterOperand Src1RC, 1344 RegisterOperand Src2RC, int NumSrcArgs, 1345 bit HasIntClamp, bit HasModifiers, bit HasSrc2Mods, bit HasOMod, 1346 Operand Src0Mod, Operand Src1Mod, Operand Src2Mod> { 1347 1348 dag ret = 1349 !if (!eq(NumSrcArgs, 0), 1350 // VOP1 without input operands (V_NOP, V_CLREXCP) 1351 (ins), 1352 /* else */ 1353 !if (!eq(NumSrcArgs, 1), 1354 !if (!eq(HasModifiers, 1), 1355 // VOP1 with modifiers 1356 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 1357 clampmod:$clamp, omod:$omod) 1358 /* else */, 1359 // VOP1 without modifiers 1360 !if (!eq(HasIntClamp, 1), 1361 (ins Src0RC:$src0, clampmod:$clamp), 1362 (ins Src0RC:$src0)) 1363 /* endif */ ), 1364 !if (!eq(NumSrcArgs, 2), 1365 !if (!eq(HasModifiers, 1), 1366 // VOP 2 with modifiers 1367 !if( !eq(HasOMod, 1), 1368 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 1369 Src1Mod:$src1_modifiers, Src1RC:$src1, 1370 clampmod:$clamp, omod:$omod), 1371 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 1372 Src1Mod:$src1_modifiers, Src1RC:$src1, 1373 clampmod:$clamp)) 1374 /* else */, 1375 // VOP2 without modifiers 1376 !if (!eq(HasIntClamp, 1), 1377 (ins Src0RC:$src0, Src1RC:$src1, clampmod:$clamp), 1378 (ins Src0RC:$src0, Src1RC:$src1)) 1379 1380 /* endif */ ) 1381 /* NumSrcArgs == 3 */, 1382 !if (!eq(HasModifiers, 1), 1383 !if (!eq(HasSrc2Mods, 1), 1384 // VOP3 with modifiers 1385 !if (!eq(HasOMod, 1), 1386 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 1387 Src1Mod:$src1_modifiers, Src1RC:$src1, 1388 Src2Mod:$src2_modifiers, Src2RC:$src2, 1389 clampmod:$clamp, omod:$omod), 1390 !if (!eq(HasIntClamp, 1), 1391 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 1392 Src1Mod:$src1_modifiers, Src1RC:$src1, 1393 Src2Mod:$src2_modifiers, Src2RC:$src2, 1394 clampmod:$clamp), 1395 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 1396 Src1Mod:$src1_modifiers, Src1RC:$src1, 1397 Src2Mod:$src2_modifiers, Src2RC:$src2))), 1398 // VOP3 with modifiers except src2 1399 !if (!eq(HasOMod, 1), 1400 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 1401 Src1Mod:$src1_modifiers, Src1RC:$src1, 1402 Src2RC:$src2, clampmod:$clamp, omod:$omod), 1403 !if (!eq(HasIntClamp, 1), 1404 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 1405 Src1Mod:$src1_modifiers, Src1RC:$src1, 1406 Src2RC:$src2, clampmod:$clamp), 1407 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 1408 Src1Mod:$src1_modifiers, Src1RC:$src1, 1409 Src2RC:$src2)))) 1410 /* else */, 1411 // VOP3 without modifiers 1412 !if (!eq(HasIntClamp, 1), 1413 (ins Src0RC:$src0, Src1RC:$src1, Src2RC:$src2, clampmod:$clamp), 1414 (ins Src0RC:$src0, Src1RC:$src1, Src2RC:$src2)) 1415 /* endif */ )))); 1416} 1417 1418/// XXX - src1 may only allow VGPRs? 1419 1420// The modifiers (except clamp) are dummy operands for the benefit of 1421// printing and parsing. They defer their values to looking at the 1422// srcN_modifiers for what to print. 1423class getInsVOP3P <RegisterOperand Src0RC, RegisterOperand Src1RC, 1424 RegisterOperand Src2RC, int NumSrcArgs, 1425 bit HasClamp, 1426 Operand Src0Mod, Operand Src1Mod, Operand Src2Mod> { 1427 dag ret = !if (!eq(NumSrcArgs, 2), 1428 !if (HasClamp, 1429 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 1430 Src1Mod:$src1_modifiers, Src1RC:$src1, 1431 clampmod:$clamp, 1432 op_sel:$op_sel, op_sel_hi:$op_sel_hi, 1433 neg_lo:$neg_lo, neg_hi:$neg_hi), 1434 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 1435 Src1Mod:$src1_modifiers, Src1RC:$src1, 1436 op_sel:$op_sel, op_sel_hi:$op_sel_hi, 1437 neg_lo:$neg_lo, neg_hi:$neg_hi)), 1438 // else NumSrcArgs == 3 1439 !if (HasClamp, 1440 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 1441 Src1Mod:$src1_modifiers, Src1RC:$src1, 1442 Src2Mod:$src2_modifiers, Src2RC:$src2, 1443 clampmod:$clamp, 1444 op_sel:$op_sel, op_sel_hi:$op_sel_hi, 1445 neg_lo:$neg_lo, neg_hi:$neg_hi), 1446 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 1447 Src1Mod:$src1_modifiers, Src1RC:$src1, 1448 Src2Mod:$src2_modifiers, Src2RC:$src2, 1449 op_sel:$op_sel, op_sel_hi:$op_sel_hi, 1450 neg_lo:$neg_lo, neg_hi:$neg_hi)) 1451 ); 1452} 1453 1454class getInsVOP3OpSel <RegisterOperand Src0RC, 1455 RegisterOperand Src1RC, 1456 RegisterOperand Src2RC, 1457 int NumSrcArgs, 1458 bit HasClamp, 1459 Operand Src0Mod, 1460 Operand Src1Mod, 1461 Operand Src2Mod> { 1462 dag ret = !if (!eq(NumSrcArgs, 2), 1463 !if (HasClamp, 1464 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 1465 Src1Mod:$src1_modifiers, Src1RC:$src1, 1466 clampmod:$clamp, 1467 op_sel:$op_sel), 1468 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 1469 Src1Mod:$src1_modifiers, Src1RC:$src1, 1470 op_sel:$op_sel)), 1471 // else NumSrcArgs == 3 1472 !if (HasClamp, 1473 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 1474 Src1Mod:$src1_modifiers, Src1RC:$src1, 1475 Src2Mod:$src2_modifiers, Src2RC:$src2, 1476 clampmod:$clamp, 1477 op_sel:$op_sel), 1478 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 1479 Src1Mod:$src1_modifiers, Src1RC:$src1, 1480 Src2Mod:$src2_modifiers, Src2RC:$src2, 1481 op_sel:$op_sel)) 1482 ); 1483} 1484 1485class getInsDPP <RegisterOperand DstRC, RegisterClass Src0RC, RegisterClass Src1RC, 1486 int NumSrcArgs, bit HasModifiers, 1487 Operand Src0Mod, Operand Src1Mod> { 1488 1489 dag ret = !if (!eq(NumSrcArgs, 0), 1490 // VOP1 without input operands (V_NOP) 1491 (ins dpp_ctrl:$dpp_ctrl, row_mask:$row_mask, 1492 bank_mask:$bank_mask, bound_ctrl:$bound_ctrl), 1493 !if (!eq(NumSrcArgs, 1), 1494 !if (!eq(HasModifiers, 1), 1495 // VOP1_DPP with modifiers 1496 (ins DstRC:$old, Src0Mod:$src0_modifiers, 1497 Src0RC:$src0, dpp_ctrl:$dpp_ctrl, row_mask:$row_mask, 1498 bank_mask:$bank_mask, bound_ctrl:$bound_ctrl) 1499 /* else */, 1500 // VOP1_DPP without modifiers 1501 (ins DstRC:$old, Src0RC:$src0, 1502 dpp_ctrl:$dpp_ctrl, row_mask:$row_mask, 1503 bank_mask:$bank_mask, bound_ctrl:$bound_ctrl) 1504 /* endif */) 1505 /* NumSrcArgs == 2 */, 1506 !if (!eq(HasModifiers, 1), 1507 // VOP2_DPP with modifiers 1508 (ins DstRC:$old, 1509 Src0Mod:$src0_modifiers, Src0RC:$src0, 1510 Src1Mod:$src1_modifiers, Src1RC:$src1, 1511 dpp_ctrl:$dpp_ctrl, row_mask:$row_mask, 1512 bank_mask:$bank_mask, bound_ctrl:$bound_ctrl) 1513 /* else */, 1514 // VOP2_DPP without modifiers 1515 (ins DstRC:$old, 1516 Src0RC:$src0, Src1RC:$src1, dpp_ctrl:$dpp_ctrl, 1517 row_mask:$row_mask, bank_mask:$bank_mask, 1518 bound_ctrl:$bound_ctrl) 1519 /* endif */))); 1520} 1521 1522 1523 1524// Ins for SDWA 1525class getInsSDWA <RegisterOperand Src0RC, RegisterOperand Src1RC, int NumSrcArgs, 1526 bit HasSDWAOMod, Operand Src0Mod, Operand Src1Mod, 1527 ValueType DstVT> { 1528 1529 dag ret = !if(!eq(NumSrcArgs, 0), 1530 // VOP1 without input operands (V_NOP) 1531 (ins), 1532 !if(!eq(NumSrcArgs, 1), 1533 // VOP1 1534 !if(!eq(HasSDWAOMod, 0), 1535 // VOP1_SDWA without omod 1536 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 1537 clampmod:$clamp, 1538 dst_sel:$dst_sel, dst_unused:$dst_unused, 1539 src0_sel:$src0_sel), 1540 // VOP1_SDWA with omod 1541 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 1542 clampmod:$clamp, omod:$omod, 1543 dst_sel:$dst_sel, dst_unused:$dst_unused, 1544 src0_sel:$src0_sel)), 1545 !if(!eq(NumSrcArgs, 2), 1546 !if(!eq(DstVT.Size, 1), 1547 // VOPC_SDWA 1548 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 1549 Src1Mod:$src1_modifiers, Src1RC:$src1, 1550 clampmod:$clamp, src0_sel:$src0_sel, src1_sel:$src1_sel), 1551 // VOP2_SDWA 1552 !if(!eq(HasSDWAOMod, 0), 1553 // VOP2_SDWA without omod 1554 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 1555 Src1Mod:$src1_modifiers, Src1RC:$src1, 1556 clampmod:$clamp, 1557 dst_sel:$dst_sel, dst_unused:$dst_unused, 1558 src0_sel:$src0_sel, src1_sel:$src1_sel), 1559 // VOP2_SDWA with omod 1560 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 1561 Src1Mod:$src1_modifiers, Src1RC:$src1, 1562 clampmod:$clamp, omod:$omod, 1563 dst_sel:$dst_sel, dst_unused:$dst_unused, 1564 src0_sel:$src0_sel, src1_sel:$src1_sel))), 1565 (ins)/* endif */))); 1566} 1567 1568// Outs for DPP and SDWA 1569class getOutsExt <bit HasDst, ValueType DstVT, RegisterOperand DstRCExt> { 1570 dag ret = !if(HasDst, 1571 !if(!eq(DstVT.Size, 1), 1572 (outs), // no dst for VOPC, we use "vcc"-token as dst in SDWA VOPC instructions 1573 (outs DstRCExt:$vdst)), 1574 (outs)); // V_NOP 1575} 1576 1577// Outs for SDWA 1578class getOutsSDWA <bit HasDst, ValueType DstVT, RegisterOperand DstRCSDWA> { 1579 dag ret = !if(HasDst, 1580 !if(!eq(DstVT.Size, 1), 1581 (outs DstRCSDWA:$sdst), 1582 (outs DstRCSDWA:$vdst)), 1583 (outs)); // V_NOP 1584} 1585 1586// Returns the assembly string for the inputs and outputs of a VOP[12C] 1587// instruction. This does not add the _e32 suffix, so it can be reused 1588// by getAsm64. 1589class getAsm32 <bit HasDst, int NumSrcArgs, ValueType DstVT = i32> { 1590 string dst = !if(!eq(DstVT.Size, 1), "$sdst", "$vdst"); // use $sdst for VOPC 1591 string src0 = ", $src0"; 1592 string src1 = ", $src1"; 1593 string src2 = ", $src2"; 1594 string ret = !if(HasDst, dst, "") # 1595 !if(!eq(NumSrcArgs, 1), src0, "") # 1596 !if(!eq(NumSrcArgs, 2), src0#src1, "") # 1597 !if(!eq(NumSrcArgs, 3), src0#src1#src2, ""); 1598} 1599 1600// Returns the assembly string for the inputs and outputs of a VOP3 1601// instruction. 1602class getAsm64 <bit HasDst, int NumSrcArgs, bit HasIntClamp, bit HasModifiers, 1603 bit HasOMod, ValueType DstVT = i32> { 1604 string dst = !if(!eq(DstVT.Size, 1), "$sdst", "$vdst"); // use $sdst for VOPC 1605 string src0 = !if(!eq(NumSrcArgs, 1), "$src0_modifiers", "$src0_modifiers,"); 1606 string src1 = !if(!eq(NumSrcArgs, 1), "", 1607 !if(!eq(NumSrcArgs, 2), " $src1_modifiers", 1608 " $src1_modifiers,")); 1609 string src2 = !if(!eq(NumSrcArgs, 3), " $src2_modifiers", ""); 1610 string iclamp = !if(HasIntClamp, "$clamp", ""); 1611 string ret = 1612 !if(!eq(HasModifiers, 0), 1613 getAsm32<HasDst, NumSrcArgs, DstVT>.ret # iclamp, 1614 dst#", "#src0#src1#src2#"$clamp"#!if(HasOMod, "$omod", "")); 1615} 1616 1617// Returns the assembly string for the inputs and outputs of a VOP3P 1618// instruction. 1619class getAsmVOP3P <bit HasDst, int NumSrcArgs, bit HasModifiers, 1620 bit HasClamp, ValueType DstVT = i32> { 1621 string dst = " $vdst"; 1622 string src0 = !if(!eq(NumSrcArgs, 1), "$src0", "$src0,"); 1623 string src1 = !if(!eq(NumSrcArgs, 1), "", 1624 !if(!eq(NumSrcArgs, 2), " $src1", 1625 " $src1,")); 1626 string src2 = !if(!eq(NumSrcArgs, 3), " $src2", ""); 1627 1628 string mods = !if(HasModifiers, "$neg_lo$neg_hi", ""); 1629 string clamp = !if(HasClamp, "$clamp", ""); 1630 1631 // Each modifier is printed as an array of bits for each operand, so 1632 // all operands are printed as part of src0_modifiers. 1633 string ret = dst#", "#src0#src1#src2#"$op_sel$op_sel_hi"#mods#clamp; 1634} 1635 1636class getAsmVOP3OpSel <int NumSrcArgs, 1637 bit HasClamp, 1638 bit Src0HasMods, 1639 bit Src1HasMods, 1640 bit Src2HasMods> { 1641 string dst = " $vdst"; 1642 1643 string isrc0 = !if(!eq(NumSrcArgs, 1), "$src0", "$src0,"); 1644 string isrc1 = !if(!eq(NumSrcArgs, 1), "", 1645 !if(!eq(NumSrcArgs, 2), " $src1", 1646 " $src1,")); 1647 string isrc2 = !if(!eq(NumSrcArgs, 3), " $src2", ""); 1648 1649 string fsrc0 = !if(!eq(NumSrcArgs, 1), "$src0_modifiers", "$src0_modifiers,"); 1650 string fsrc1 = !if(!eq(NumSrcArgs, 1), "", 1651 !if(!eq(NumSrcArgs, 2), " $src1_modifiers", 1652 " $src1_modifiers,")); 1653 string fsrc2 = !if(!eq(NumSrcArgs, 3), " $src2_modifiers", ""); 1654 1655 string src0 = !if(Src0HasMods, fsrc0, isrc0); 1656 string src1 = !if(Src1HasMods, fsrc1, isrc1); 1657 string src2 = !if(Src2HasMods, fsrc2, isrc2); 1658 1659 string clamp = !if(HasClamp, "$clamp", ""); 1660 1661 string ret = dst#", "#src0#src1#src2#"$op_sel"#clamp; 1662} 1663 1664class getAsmDPP <bit HasDst, int NumSrcArgs, bit HasModifiers, ValueType DstVT = i32> { 1665 string dst = !if(HasDst, 1666 !if(!eq(DstVT.Size, 1), 1667 "$sdst", 1668 "$vdst"), 1669 ""); // use $sdst for VOPC 1670 string src0 = !if(!eq(NumSrcArgs, 1), "$src0_modifiers", "$src0_modifiers,"); 1671 string src1 = !if(!eq(NumSrcArgs, 1), "", 1672 !if(!eq(NumSrcArgs, 2), " $src1_modifiers", 1673 " $src1_modifiers,")); 1674 string args = !if(!eq(HasModifiers, 0), 1675 getAsm32<0, NumSrcArgs, DstVT>.ret, 1676 ", "#src0#src1); 1677 string ret = dst#args#" $dpp_ctrl$row_mask$bank_mask$bound_ctrl"; 1678} 1679 1680class getAsmSDWA <bit HasDst, int NumSrcArgs, ValueType DstVT = i32> { 1681 string dst = !if(HasDst, 1682 !if(!eq(DstVT.Size, 1), 1683 " vcc", // use vcc token as dst for VOPC instructioins 1684 "$vdst"), 1685 ""); 1686 string src0 = "$src0_modifiers"; 1687 string src1 = "$src1_modifiers"; 1688 string args = !if(!eq(NumSrcArgs, 0), 1689 "", 1690 !if(!eq(NumSrcArgs, 1), 1691 ", "#src0#"$clamp", 1692 ", "#src0#", "#src1#"$clamp" 1693 ) 1694 ); 1695 string sdwa = !if(!eq(NumSrcArgs, 0), 1696 "", 1697 !if(!eq(NumSrcArgs, 1), 1698 " $dst_sel $dst_unused $src0_sel", 1699 !if(!eq(DstVT.Size, 1), 1700 " $src0_sel $src1_sel", // No dst_sel and dst_unused for VOPC 1701 " $dst_sel $dst_unused $src0_sel $src1_sel" 1702 ) 1703 ) 1704 ); 1705 string ret = dst#args#sdwa; 1706} 1707 1708class getAsmSDWA9 <bit HasDst, bit HasOMod, int NumSrcArgs, 1709 ValueType DstVT = i32> { 1710 string dst = !if(HasDst, 1711 !if(!eq(DstVT.Size, 1), 1712 "$sdst", // VOPC 1713 "$vdst"), // VOP1/2 1714 ""); 1715 string src0 = "$src0_modifiers"; 1716 string src1 = "$src1_modifiers"; 1717 string out_mods = !if(!eq(HasOMod, 0), "$clamp", "$clamp$omod"); 1718 string args = !if(!eq(NumSrcArgs, 0), "", 1719 !if(!eq(NumSrcArgs, 1), 1720 ", "#src0, 1721 ", "#src0#", "#src1 1722 ) 1723 ); 1724 string sdwa = !if(!eq(NumSrcArgs, 0), "", 1725 !if(!eq(NumSrcArgs, 1), 1726 out_mods#" $dst_sel $dst_unused $src0_sel", 1727 !if(!eq(DstVT.Size, 1), 1728 " $src0_sel $src1_sel", // No dst_sel, dst_unused and output modifiers for VOPC 1729 out_mods#" $dst_sel $dst_unused $src0_sel $src1_sel" 1730 ) 1731 ) 1732 ); 1733 string ret = dst#args#sdwa; 1734} 1735 1736 1737// Function that checks if instruction supports DPP and SDWA 1738class getHasExt <int NumSrcArgs, ValueType DstVT = i32, ValueType Src0VT = i32, 1739 ValueType Src1VT = i32> { 1740 bit ret = !if(!eq(NumSrcArgs, 3), 1741 0, // NumSrcArgs == 3 - No DPP or SDWA for VOP3 1742 !if(!eq(DstVT.Size, 64), 1743 0, // 64-bit dst - No DPP or SDWA for 64-bit operands 1744 !if(!eq(Src0VT.Size, 64), 1745 0, // 64-bit src0 1746 !if(!eq(Src1VT.Size, 64), 1747 0, // 64-bit src2 1748 1 1749 ) 1750 ) 1751 ) 1752 ); 1753} 1754 1755class getHasDPP <int NumSrcArgs, ValueType DstVT = i32, ValueType Src0VT = i32, 1756 ValueType Src1VT = i32> { 1757 bit ret = !if(!eq(NumSrcArgs, 0), 0, 1758 getHasExt<NumSrcArgs, DstVT, Src0VT, Src1VT>.ret); 1759} 1760 1761class BitOr<bit a, bit b> { 1762 bit ret = !if(a, 1, !if(b, 1, 0)); 1763} 1764 1765class BitAnd<bit a, bit b> { 1766 bit ret = !if(a, !if(b, 1, 0), 0); 1767} 1768 1769def PatGenMode { 1770 int NoPattern = 0; 1771 int Pattern = 1; 1772} 1773 1774class VOPProfile <list<ValueType> _ArgVT, bit _EnableF32SrcMods = 0, 1775 bit _EnableClamp = 0> { 1776 1777 field list<ValueType> ArgVT = _ArgVT; 1778 field bit EnableF32SrcMods = _EnableF32SrcMods; 1779 field bit EnableClamp = _EnableClamp; 1780 1781 field ValueType DstVT = ArgVT[0]; 1782 field ValueType Src0VT = ArgVT[1]; 1783 field ValueType Src1VT = ArgVT[2]; 1784 field ValueType Src2VT = ArgVT[3]; 1785 field RegisterOperand DstRC = getVALUDstForVT<DstVT>.ret; 1786 field RegisterOperand DstRCDPP = getVALUDstForVT<DstVT>.ret; 1787 field RegisterOperand DstRCSDWA = getSDWADstForVT<DstVT>.ret; 1788 field RegisterOperand Src0RC32 = getVOPSrc0ForVT<Src0VT>.ret; 1789 field RegisterClass Src1RC32 = getVregSrcForVT<Src1VT>.ret; 1790 field RegisterOperand Src0RC64 = getVOP3SrcForVT<Src0VT>.ret; 1791 field RegisterOperand Src1RC64 = getVOP3SrcForVT<Src1VT>.ret; 1792 field RegisterOperand Src2RC64 = getVOP3SrcForVT<Src2VT>.ret; 1793 field RegisterClass Src0DPP = getVregSrcForVT<Src0VT>.ret; 1794 field RegisterClass Src1DPP = getVregSrcForVT<Src1VT>.ret; 1795 field RegisterOperand Src0SDWA = getSDWASrcForVT<Src0VT>.ret; 1796 field RegisterOperand Src1SDWA = getSDWASrcForVT<Src0VT>.ret; 1797 field Operand Src0Mod = getSrcMod<Src0VT, EnableF32SrcMods>.ret; 1798 field Operand Src1Mod = getSrcMod<Src1VT, EnableF32SrcMods>.ret; 1799 field Operand Src2Mod = getSrcMod<Src2VT, EnableF32SrcMods>.ret; 1800 field Operand Src0ModDPP = getSrcModExt<Src0VT>.ret; 1801 field Operand Src1ModDPP = getSrcModExt<Src1VT>.ret; 1802 field Operand Src0ModSDWA = getSrcModSDWA<Src0VT>.ret; 1803 field Operand Src1ModSDWA = getSrcModSDWA<Src1VT>.ret; 1804 1805 1806 field bit HasDst = !if(!eq(DstVT.Value, untyped.Value), 0, 1); 1807 field bit HasDst32 = HasDst; 1808 field bit EmitDst = HasDst; // force dst encoding, see v_movreld_b32 special case 1809 field int NumSrcArgs = getNumSrcArgs<Src0VT, Src1VT, Src2VT>.ret; 1810 field bit HasSrc0 = !if(!eq(Src0VT.Value, untyped.Value), 0, 1); 1811 field bit HasSrc1 = !if(!eq(Src1VT.Value, untyped.Value), 0, 1); 1812 field bit HasSrc2 = !if(!eq(Src2VT.Value, untyped.Value), 0, 1); 1813 1814 // TODO: Modifiers logic is somewhat adhoc here, to be refined later 1815 // HasModifiers affects the normal and DPP encodings. We take note of EnableF32SrcMods, which 1816 // enables modifiers for i32 type. 1817 field bit HasModifiers = BitOr<isModifierType<Src0VT>.ret, EnableF32SrcMods>.ret; 1818 1819 // HasSrc*FloatMods affects the SDWA encoding. We ignore EnableF32SrcMods. 1820 field bit HasSrc0FloatMods = isFloatType<Src0VT>.ret; 1821 field bit HasSrc1FloatMods = isFloatType<Src1VT>.ret; 1822 field bit HasSrc2FloatMods = isFloatType<Src2VT>.ret; 1823 1824 // HasSrc*IntMods affects the SDWA encoding. We ignore EnableF32SrcMods. 1825 field bit HasSrc0IntMods = isIntType<Src0VT>.ret; 1826 field bit HasSrc1IntMods = isIntType<Src1VT>.ret; 1827 field bit HasSrc2IntMods = isIntType<Src2VT>.ret; 1828 1829 field bit HasSrc0Mods = HasModifiers; 1830 field bit HasSrc1Mods = !if(HasModifiers, BitOr<HasSrc1FloatMods, HasSrc1IntMods>.ret, 0); 1831 field bit HasSrc2Mods = !if(HasModifiers, BitOr<HasSrc2FloatMods, HasSrc2IntMods>.ret, 0); 1832 1833 field bit HasClamp = BitOr<isModifierType<Src0VT>.ret, EnableClamp>.ret; 1834 field bit HasSDWAClamp = EmitDst; 1835 field bit HasFPClamp = BitAnd<isFloatType<DstVT>.ret, HasClamp>.ret; 1836 field bit HasIntClamp = !if(isFloatType<DstVT>.ret, 0, HasClamp); 1837 field bit HasClampLo = HasClamp; 1838 field bit HasClampHi = BitAnd<isPackedType<DstVT>.ret, HasClamp>.ret; 1839 field bit HasHigh = 0; 1840 1841 field bit IsPacked = isPackedType<Src0VT>.ret; 1842 field bit HasOpSel = IsPacked; 1843 field bit HasOMod = !if(HasOpSel, 0, isFloatType<DstVT>.ret); 1844 field bit HasSDWAOMod = isFloatType<DstVT>.ret; 1845 1846 field bit HasExt = getHasExt<NumSrcArgs, DstVT, Src0VT, Src1VT>.ret; 1847 field bit HasExtDPP = getHasDPP<NumSrcArgs, DstVT, Src0VT, Src1VT>.ret; 1848 field bit HasExtSDWA = HasExt; 1849 field bit HasExtSDWA9 = HasExt; 1850 field int NeedPatGen = PatGenMode.NoPattern; 1851 1852 field Operand Src0PackedMod = !if(HasSrc0FloatMods, PackedF16InputMods, PackedI16InputMods); 1853 field Operand Src1PackedMod = !if(HasSrc1FloatMods, PackedF16InputMods, PackedI16InputMods); 1854 field Operand Src2PackedMod = !if(HasSrc2FloatMods, PackedF16InputMods, PackedI16InputMods); 1855 1856 field dag Outs = !if(HasDst,(outs DstRC:$vdst),(outs)); 1857 1858 // VOP3b instructions are a special case with a second explicit 1859 // output. This is manually overridden for them. 1860 field dag Outs32 = Outs; 1861 field dag Outs64 = Outs; 1862 field dag OutsDPP = getOutsExt<HasDst, DstVT, DstRCDPP>.ret; 1863 field dag OutsSDWA = getOutsSDWA<HasDst, DstVT, DstRCSDWA>.ret; 1864 1865 field dag Ins32 = getIns32<Src0RC32, Src1RC32, NumSrcArgs>.ret; 1866 field dag Ins64 = getIns64<Src0RC64, Src1RC64, Src2RC64, NumSrcArgs, 1867 HasIntClamp, HasModifiers, HasSrc2Mods, 1868 HasOMod, Src0Mod, Src1Mod, Src2Mod>.ret; 1869 field dag InsVOP3P = getInsVOP3P<Src0RC64, Src1RC64, Src2RC64, 1870 NumSrcArgs, HasClamp, 1871 Src0PackedMod, Src1PackedMod, Src2PackedMod>.ret; 1872 field dag InsVOP3OpSel = getInsVOP3OpSel<Src0RC64, Src1RC64, Src2RC64, 1873 NumSrcArgs, 1874 HasClamp, 1875 getOpSelMod<Src0VT>.ret, 1876 getOpSelMod<Src1VT>.ret, 1877 getOpSelMod<Src2VT>.ret>.ret; 1878 field dag InsDPP = !if(HasExtDPP, 1879 getInsDPP<DstRCDPP, Src0DPP, Src1DPP, NumSrcArgs, 1880 HasModifiers, Src0ModDPP, Src1ModDPP>.ret, 1881 (ins)); 1882 field dag InsSDWA = getInsSDWA<Src0SDWA, Src1SDWA, NumSrcArgs, 1883 HasSDWAOMod, Src0ModSDWA, Src1ModSDWA, 1884 DstVT>.ret; 1885 1886 1887 field string Asm32 = getAsm32<HasDst, NumSrcArgs, DstVT>.ret; 1888 field string Asm64 = getAsm64<HasDst, NumSrcArgs, HasIntClamp, HasModifiers, HasOMod, DstVT>.ret; 1889 field string AsmVOP3P = getAsmVOP3P<HasDst, NumSrcArgs, HasModifiers, HasClamp, DstVT>.ret; 1890 field string AsmVOP3OpSel = getAsmVOP3OpSel<NumSrcArgs, 1891 HasClamp, 1892 HasSrc0FloatMods, 1893 HasSrc1FloatMods, 1894 HasSrc2FloatMods>.ret; 1895 field string AsmDPP = !if(HasExtDPP, 1896 getAsmDPP<HasDst, NumSrcArgs, HasModifiers, DstVT>.ret, ""); 1897 field string AsmSDWA = getAsmSDWA<HasDst, NumSrcArgs, DstVT>.ret; 1898 field string AsmSDWA9 = getAsmSDWA9<HasDst, HasSDWAOMod, NumSrcArgs, DstVT>.ret; 1899} 1900 1901class VOP_NO_EXT <VOPProfile p> : VOPProfile <p.ArgVT> { 1902 let HasExt = 0; 1903 let HasExtDPP = 0; 1904 let HasExtSDWA = 0; 1905 let HasExtSDWA9 = 0; 1906} 1907 1908class VOP_PAT_GEN <VOPProfile p, int mode=PatGenMode.Pattern> : VOPProfile <p.ArgVT> { 1909 let NeedPatGen = mode; 1910} 1911 1912def VOP_F16_F16 : VOPProfile <[f16, f16, untyped, untyped]>; 1913def VOP_F16_I16 : VOPProfile <[f16, i16, untyped, untyped]>; 1914def VOP_I16_F16 : VOPProfile <[i16, f16, untyped, untyped]>; 1915 1916def VOP_F16_F16_F16 : VOPProfile <[f16, f16, f16, untyped]>; 1917def VOP_F16_F16_I16 : VOPProfile <[f16, f16, i16, untyped]>; 1918def VOP_F16_F16_I32 : VOPProfile <[f16, f16, i32, untyped]>; 1919def VOP_I16_I16_I16 : VOPProfile <[i16, i16, i16, untyped]>; 1920 1921def VOP_I16_I16_I16_I16 : VOPProfile <[i16, i16, i16, i16, untyped]>; 1922def VOP_F16_F16_F16_F16 : VOPProfile <[f16, f16, f16, f16, untyped]>; 1923 1924def VOP_I32_I16_I16_I32 : VOPProfile <[i32, i16, i16, i32, untyped]>; 1925 1926def VOP_V2F16_V2F16_V2F16 : VOPProfile <[v2f16, v2f16, v2f16, untyped]>; 1927def VOP_V2I16_V2I16_V2I16 : VOPProfile <[v2i16, v2i16, v2i16, untyped]>; 1928def VOP_B32_F16_F16 : VOPProfile <[i32, f16, f16, untyped]>; 1929 1930def VOP_V2F16_V2F16_V2F16_V2F16 : VOPProfile <[v2f16, v2f16, v2f16, v2f16]>; 1931def VOP_V2I16_V2I16_V2I16_V2I16 : VOPProfile <[v2i16, v2i16, v2i16, v2i16]>; 1932def VOP_V2I16_F32_F32 : VOPProfile <[v2i16, f32, f32, untyped]>; 1933def VOP_V2I16_I32_I32 : VOPProfile <[v2i16, i32, i32, untyped]>; 1934 1935def VOP_F32_V2F16_V2F16_V2F16 : VOPProfile <[f32, v2f16, v2f16, v2f16]>; 1936 1937def VOP_NONE : VOPProfile <[untyped, untyped, untyped, untyped]>; 1938 1939def VOP_F32_F32 : VOPProfile <[f32, f32, untyped, untyped]>; 1940def VOP_F32_F64 : VOPProfile <[f32, f64, untyped, untyped]>; 1941def VOP_F32_I32 : VOPProfile <[f32, i32, untyped, untyped]>; 1942def VOP_F64_F32 : VOPProfile <[f64, f32, untyped, untyped]>; 1943def VOP_F64_F64 : VOPProfile <[f64, f64, untyped, untyped]>; 1944def VOP_F64_I32 : VOPProfile <[f64, i32, untyped, untyped]>; 1945def VOP_I32_F32 : VOPProfile <[i32, f32, untyped, untyped]>; 1946def VOP_I32_F64 : VOPProfile <[i32, f64, untyped, untyped]>; 1947def VOP_I32_I32 : VOPProfile <[i32, i32, untyped, untyped]>; 1948def VOP_F16_F32 : VOPProfile <[f16, f32, untyped, untyped]>; 1949def VOP_F32_F16 : VOPProfile <[f32, f16, untyped, untyped]>; 1950 1951def VOP_F32_F32_F16 : VOPProfile <[f32, f32, f16, untyped]>; 1952def VOP_F32_F32_F32 : VOPProfile <[f32, f32, f32, untyped]>; 1953def VOP_F32_F32_I32 : VOPProfile <[f32, f32, i32, untyped]>; 1954def VOP_F64_F64_F64 : VOPProfile <[f64, f64, f64, untyped]>; 1955def VOP_F64_F64_I32 : VOPProfile <[f64, f64, i32, untyped]>; 1956def VOP_I32_F32_F32 : VOPProfile <[i32, f32, f32, untyped]>; 1957def VOP_I32_F32_I32 : VOPProfile <[i32, f32, i32, untyped]>; 1958def VOP_I32_I32_I32 : VOPProfile <[i32, i32, i32, untyped]>; 1959def VOP_I32_I32_I32_ARITH : VOPProfile <[i32, i32, i32, untyped], 0, /*EnableClamp=*/1>; 1960def VOP_V2F16_F32_F32 : VOPProfile <[v2f16, f32, f32, untyped]>; 1961def VOP_F32_F16_F16_F16 : VOPProfile <[f32, f16, f16, f16]>; 1962 1963def VOP_I64_I64_I32 : VOPProfile <[i64, i64, i32, untyped]>; 1964def VOP_I64_I32_I64 : VOPProfile <[i64, i32, i64, untyped]>; 1965def VOP_I64_I64_I64 : VOPProfile <[i64, i64, i64, untyped]>; 1966 1967def VOP_F16_F32_F16_F32 : VOPProfile <[f16, f32, f16, f32]>; 1968def VOP_F32_F32_F16_F16 : VOPProfile <[f32, f32, f16, f16]>; 1969def VOP_F32_F32_F32_F32 : VOPProfile <[f32, f32, f32, f32]>; 1970def VOP_F64_F64_F64_F64 : VOPProfile <[f64, f64, f64, f64]>; 1971def VOP_I32_I32_I32_I32 : VOPProfile <[i32, i32, i32, i32]>; 1972def VOP_I64_I32_I32_I64 : VOPProfile <[i64, i32, i32, i64]>; 1973def VOP_I32_F32_I32_I32 : VOPProfile <[i32, f32, i32, i32]>; 1974def VOP_I64_I64_I32_I64 : VOPProfile <[i64, i64, i32, i64]>; 1975def VOP_V4I32_I64_I32_V4I32 : VOPProfile <[v4i32, i64, i32, v4i32]>; 1976 1977def VOP_F32_V2F16_V2F16_F32 : VOPProfile <[f32, v2f16, v2f16, f32]>; 1978def VOP_I32_V2I16_V2I16_I32 : VOPProfile <[i32, v2i16, v2i16, i32]>; 1979 1980class Commutable_REV <string revOp, bit isOrig> { 1981 string RevOp = revOp; 1982 bit IsOrig = isOrig; 1983} 1984 1985class AtomicNoRet <string noRetOp, bit isRet> { 1986 string NoRetOp = noRetOp; 1987 bit IsRet = isRet; 1988} 1989 1990//===----------------------------------------------------------------------===// 1991// Interpolation opcodes 1992//===----------------------------------------------------------------------===// 1993 1994class VINTRPDstOperand <RegisterClass rc> : RegisterOperand <rc, "printVINTRPDst">; 1995 1996class VINTRP_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> : 1997 VINTRPCommon <outs, ins, "", pattern>, 1998 SIMCInstr<opName, SIEncodingFamily.NONE> { 1999 let isPseudo = 1; 2000 let isCodeGenOnly = 1; 2001} 2002 2003class VINTRP_Real_si <bits <2> op, string opName, dag outs, dag ins, 2004 string asm> : 2005 VINTRPCommon <outs, ins, asm, []>, 2006 VINTRPe <op>, 2007 SIMCInstr<opName, SIEncodingFamily.SI> { 2008 let AssemblerPredicate = SIAssemblerPredicate; 2009 let DecoderNamespace = "SICI"; 2010 let DisableDecoder = DisableSIDecoder; 2011} 2012 2013class VINTRP_Real_vi <bits <2> op, string opName, dag outs, dag ins, 2014 string asm> : 2015 VINTRPCommon <outs, ins, asm, []>, 2016 VINTRPe_vi <op>, 2017 SIMCInstr<opName, SIEncodingFamily.VI> { 2018 let AssemblerPredicate = VIAssemblerPredicate; 2019 let DecoderNamespace = "VI"; 2020 let DisableDecoder = DisableVIDecoder; 2021} 2022 2023multiclass VINTRP_m <bits <2> op, dag outs, dag ins, string asm, 2024 list<dag> pattern = []> { 2025 def "" : VINTRP_Pseudo <NAME, outs, ins, pattern>; 2026 2027 def _si : VINTRP_Real_si <op, NAME, outs, ins, asm>; 2028 2029 def _vi : VINTRP_Real_vi <op, NAME, outs, ins, asm>; 2030} 2031 2032//===----------------------------------------------------------------------===// 2033// Vector instruction mappings 2034//===----------------------------------------------------------------------===// 2035 2036// Maps an opcode in e32 form to its e64 equivalent 2037def getVOPe64 : InstrMapping { 2038 let FilterClass = "VOP"; 2039 let RowFields = ["OpName"]; 2040 let ColFields = ["Size", "VOP3"]; 2041 let KeyCol = ["4", "0"]; 2042 let ValueCols = [["8", "1"]]; 2043} 2044 2045// Maps an opcode in e64 form to its e32 equivalent 2046def getVOPe32 : InstrMapping { 2047 let FilterClass = "VOP"; 2048 let RowFields = ["OpName"]; 2049 let ColFields = ["Size", "VOP3"]; 2050 let KeyCol = ["8", "1"]; 2051 let ValueCols = [["4", "0"]]; 2052} 2053 2054// Maps ordinary instructions to their SDWA counterparts 2055def getSDWAOp : InstrMapping { 2056 let FilterClass = "VOP"; 2057 let RowFields = ["OpName"]; 2058 let ColFields = ["AsmVariantName"]; 2059 let KeyCol = ["Default"]; 2060 let ValueCols = [["SDWA"]]; 2061} 2062 2063// Maps SDWA instructions to their ordinary counterparts 2064def getBasicFromSDWAOp : InstrMapping { 2065 let FilterClass = "VOP"; 2066 let RowFields = ["OpName"]; 2067 let ColFields = ["AsmVariantName"]; 2068 let KeyCol = ["SDWA"]; 2069 let ValueCols = [["Default"]]; 2070} 2071 2072// Maps ordinary instructions to their DPP counterparts 2073def getDPPOp32 : InstrMapping { 2074 let FilterClass = "VOP"; 2075 let RowFields = ["OpName"]; 2076 let ColFields = ["AsmVariantName"]; 2077 let KeyCol = ["Default"]; 2078 let ValueCols = [["DPP"]]; 2079} 2080 2081// Maps an commuted opcode to its original version 2082def getCommuteOrig : InstrMapping { 2083 let FilterClass = "Commutable_REV"; 2084 let RowFields = ["RevOp"]; 2085 let ColFields = ["IsOrig"]; 2086 let KeyCol = ["0"]; 2087 let ValueCols = [["1"]]; 2088} 2089 2090// Maps an original opcode to its commuted version 2091def getCommuteRev : InstrMapping { 2092 let FilterClass = "Commutable_REV"; 2093 let RowFields = ["RevOp"]; 2094 let ColFields = ["IsOrig"]; 2095 let KeyCol = ["1"]; 2096 let ValueCols = [["0"]]; 2097} 2098 2099def getMCOpcodeGen : InstrMapping { 2100 let FilterClass = "SIMCInstr"; 2101 let RowFields = ["PseudoInstr"]; 2102 let ColFields = ["Subtarget"]; 2103 let KeyCol = [!cast<string>(SIEncodingFamily.NONE)]; 2104 let ValueCols = [[!cast<string>(SIEncodingFamily.SI)], 2105 [!cast<string>(SIEncodingFamily.VI)], 2106 [!cast<string>(SIEncodingFamily.SDWA)], 2107 [!cast<string>(SIEncodingFamily.SDWA9)], 2108 // GFX80 encoding is added to work around a multiple matching 2109 // issue for buffer instructions with unpacked d16 data. This 2110 // does not actually change the encoding, and thus may be 2111 // removed later. 2112 [!cast<string>(SIEncodingFamily.GFX80)], 2113 [!cast<string>(SIEncodingFamily.GFX9)]]; 2114} 2115 2116// Get equivalent SOPK instruction. 2117def getSOPKOp : InstrMapping { 2118 let FilterClass = "SOPKInstTable"; 2119 let RowFields = ["BaseCmpOp"]; 2120 let ColFields = ["IsSOPK"]; 2121 let KeyCol = ["0"]; 2122 let ValueCols = [["1"]]; 2123} 2124 2125def getAddr64Inst : InstrMapping { 2126 let FilterClass = "MUBUFAddr64Table"; 2127 let RowFields = ["OpName"]; 2128 let ColFields = ["IsAddr64"]; 2129 let KeyCol = ["0"]; 2130 let ValueCols = [["1"]]; 2131} 2132 2133def getIfAddr64Inst : InstrMapping { 2134 let FilterClass = "MUBUFAddr64Table"; 2135 let RowFields = ["OpName"]; 2136 let ColFields = ["IsAddr64"]; 2137 let KeyCol = ["1"]; 2138 let ValueCols = [["1"]]; 2139} 2140 2141def getMUBUFNoLdsInst : InstrMapping { 2142 let FilterClass = "MUBUFLdsTable"; 2143 let RowFields = ["OpName"]; 2144 let ColFields = ["IsLds"]; 2145 let KeyCol = ["1"]; 2146 let ValueCols = [["0"]]; 2147} 2148 2149// Maps an atomic opcode to its version with a return value. 2150def getAtomicRetOp : InstrMapping { 2151 let FilterClass = "AtomicNoRet"; 2152 let RowFields = ["NoRetOp"]; 2153 let ColFields = ["IsRet"]; 2154 let KeyCol = ["0"]; 2155 let ValueCols = [["1"]]; 2156} 2157 2158// Maps an atomic opcode to its returnless version. 2159def getAtomicNoRetOp : InstrMapping { 2160 let FilterClass = "AtomicNoRet"; 2161 let RowFields = ["NoRetOp"]; 2162 let ColFields = ["IsRet"]; 2163 let KeyCol = ["1"]; 2164 let ValueCols = [["0"]]; 2165} 2166 2167// Maps a GLOBAL to its SADDR form. 2168def getGlobalSaddrOp : InstrMapping { 2169 let FilterClass = "GlobalSaddrTable"; 2170 let RowFields = ["SaddrOp"]; 2171 let ColFields = ["IsSaddr"]; 2172 let KeyCol = ["0"]; 2173 let ValueCols = [["1"]]; 2174} 2175 2176include "SIInstructions.td" 2177 2178include "DSInstructions.td" 2179include "MIMGInstructions.td" 2180