1//===-- SIInstrInfo.td -----------------------------------------------------===// 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//===----------------------------------------------------------------------===// 8 9def isWave32 : Predicate<"Subtarget->getWavefrontSize() == 32">, 10 AssemblerPredicate <(all_of FeatureWavefrontSize32)>; 11def isWave64 : Predicate<"Subtarget->getWavefrontSize() == 64">, 12 AssemblerPredicate <(all_of FeatureWavefrontSize64)>; 13 14class GCNPredicateControl : PredicateControl { 15 Predicate SIAssemblerPredicate = isGFX6GFX7; 16 Predicate VIAssemblerPredicate = isGFX8GFX9; 17} 18 19// Except for the NONE field, this must be kept in sync with the 20// SIEncodingFamily enum in SIInstrInfo.cpp and the columns of the 21// getMCOpcodeGen table. 22def SIEncodingFamily { 23 int NONE = -1; 24 int SI = 0; 25 int VI = 1; 26 int SDWA = 2; 27 int SDWA9 = 3; 28 int GFX80 = 4; 29 int GFX9 = 5; 30 int GFX10 = 6; 31 int SDWA10 = 7; 32 int GFX90A = 8; 33 int GFX940 = 9; 34 int GFX11 = 10; 35} 36 37//===----------------------------------------------------------------------===// 38// SI DAG Nodes 39//===----------------------------------------------------------------------===// 40 41def AMDGPUclamp : SDNode<"AMDGPUISD::CLAMP", SDTFPUnaryOp>; 42 43def SIsbuffer_load : SDNode<"AMDGPUISD::SBUFFER_LOAD", 44 SDTypeProfile<1, 3, [SDTCisVT<1, v4i32>, SDTCisVT<2, i32>, SDTCisVT<3, i32>]>, 45 [SDNPMayLoad, SDNPMemOperand] 46>; 47 48def SIds_ordered_count : SDNode<"AMDGPUISD::DS_ORDERED_COUNT", 49 SDTypeProfile<1, 2, [SDTCisVT<0, i32>, SDTCisVT<1, i32>, SDTCisVT<2, i16>]>, 50 [SDNPMayLoad, SDNPMayStore, SDNPMemOperand, SDNPHasChain, SDNPInGlue] 51>; 52 53def SIatomic_inc : SDNode<"AMDGPUISD::ATOMIC_INC", SDTAtomic2, 54 [SDNPMayLoad, SDNPMayStore, SDNPMemOperand, SDNPHasChain] 55>; 56 57def SIatomic_dec : SDNode<"AMDGPUISD::ATOMIC_DEC", SDTAtomic2, 58 [SDNPMayLoad, SDNPMayStore, SDNPMemOperand, SDNPHasChain] 59>; 60 61def SDTAtomic2_f32 : SDTypeProfile<1, 2, [ 62 SDTCisSameAs<0,2>, SDTCisFP<0>, SDTCisPtrTy<1> 63]>; 64 65def SIatomic_fmin : SDNode<"AMDGPUISD::ATOMIC_LOAD_FMIN", SDTAtomic2_f32, 66 [SDNPMayLoad, SDNPMayStore, SDNPMemOperand, SDNPHasChain] 67>; 68 69def SIatomic_fmax : SDNode<"AMDGPUISD::ATOMIC_LOAD_FMAX", SDTAtomic2_f32, 70 [SDNPMayLoad, SDNPMayStore, SDNPMemOperand, SDNPHasChain] 71>; 72 73// load_d16_{lo|hi} ptr, tied_input 74def SIload_d16 : SDTypeProfile<1, 2, [ 75 SDTCisPtrTy<1>, 76 SDTCisSameAs<0, 2> 77]>; 78 79 80def SDTtbuffer_load : SDTypeProfile<1, 8, 81 [ // vdata 82 SDTCisVT<1, v4i32>, // rsrc 83 SDTCisVT<2, i32>, // vindex(VGPR) 84 SDTCisVT<3, i32>, // voffset(VGPR) 85 SDTCisVT<4, i32>, // soffset(SGPR) 86 SDTCisVT<5, i32>, // offset(imm) 87 SDTCisVT<6, i32>, // format(imm) 88 SDTCisVT<7, i32>, // cachepolicy, swizzled buffer(imm) 89 SDTCisVT<8, i1> // idxen(imm) 90 ]>; 91 92def SItbuffer_load : SDNode<"AMDGPUISD::TBUFFER_LOAD_FORMAT", SDTtbuffer_load, 93 [SDNPMayLoad, SDNPMemOperand, SDNPHasChain]>; 94def SItbuffer_load_d16 : SDNode<"AMDGPUISD::TBUFFER_LOAD_FORMAT_D16", 95 SDTtbuffer_load, 96 [SDNPMayLoad, SDNPMemOperand, SDNPHasChain]>; 97 98def SDTtbuffer_store : SDTypeProfile<0, 9, 99 [ // vdata 100 SDTCisVT<1, v4i32>, // rsrc 101 SDTCisVT<2, i32>, // vindex(VGPR) 102 SDTCisVT<3, i32>, // voffset(VGPR) 103 SDTCisVT<4, i32>, // soffset(SGPR) 104 SDTCisVT<5, i32>, // offset(imm) 105 SDTCisVT<6, i32>, // format(imm) 106 SDTCisVT<7, i32>, // cachepolicy, swizzled buffer(imm) 107 SDTCisVT<8, i1> // idxen(imm) 108 ]>; 109 110def SItbuffer_store : SDNode<"AMDGPUISD::TBUFFER_STORE_FORMAT", SDTtbuffer_store, 111 [SDNPMayStore, SDNPMemOperand, SDNPHasChain]>; 112def SItbuffer_store_d16 : SDNode<"AMDGPUISD::TBUFFER_STORE_FORMAT_D16", 113 SDTtbuffer_store, 114 [SDNPMayStore, SDNPMemOperand, SDNPHasChain]>; 115 116def SDTBufferLoad : SDTypeProfile<1, 7, 117 [ // vdata 118 SDTCisVT<1, v4i32>, // rsrc 119 SDTCisVT<2, i32>, // vindex(VGPR) 120 SDTCisVT<3, i32>, // voffset(VGPR) 121 SDTCisVT<4, i32>, // soffset(SGPR) 122 SDTCisVT<5, i32>, // offset(imm) 123 SDTCisVT<6, i32>, // cachepolicy, swizzled buffer(imm) 124 SDTCisVT<7, i1>]>; // idxen(imm) 125 126def SIbuffer_load : SDNode <"AMDGPUISD::BUFFER_LOAD", SDTBufferLoad, 127 [SDNPMemOperand, SDNPHasChain, SDNPMayLoad]>; 128def SIbuffer_load_ubyte : SDNode <"AMDGPUISD::BUFFER_LOAD_UBYTE", SDTBufferLoad, 129 [SDNPMemOperand, SDNPHasChain, SDNPMayLoad]>; 130def SIbuffer_load_ushort : SDNode <"AMDGPUISD::BUFFER_LOAD_USHORT", SDTBufferLoad, 131 [SDNPMemOperand, SDNPHasChain, SDNPMayLoad]>; 132def SIbuffer_load_byte : SDNode <"AMDGPUISD::BUFFER_LOAD_BYTE", SDTBufferLoad, 133 [SDNPMemOperand, SDNPHasChain, SDNPMayLoad]>; 134def SIbuffer_load_short: SDNode <"AMDGPUISD::BUFFER_LOAD_SHORT", SDTBufferLoad, 135 [SDNPMemOperand, SDNPHasChain, SDNPMayLoad]>; 136def SIbuffer_load_format : SDNode <"AMDGPUISD::BUFFER_LOAD_FORMAT", SDTBufferLoad, 137 [SDNPMemOperand, SDNPHasChain, SDNPMayLoad]>; 138def SIbuffer_load_format_d16 : SDNode <"AMDGPUISD::BUFFER_LOAD_FORMAT_D16", 139 SDTBufferLoad, 140 [SDNPMemOperand, SDNPHasChain, SDNPMayLoad]>; 141 142def SDTBufferStore : SDTypeProfile<0, 8, 143 [ // vdata 144 SDTCisVT<1, v4i32>, // rsrc 145 SDTCisVT<2, i32>, // vindex(VGPR) 146 SDTCisVT<3, i32>, // voffset(VGPR) 147 SDTCisVT<4, i32>, // soffset(SGPR) 148 SDTCisVT<5, i32>, // offset(imm) 149 SDTCisVT<6, i32>, // cachepolicy, swizzled buffer(imm) 150 SDTCisVT<7, i1>]>; // idxen(imm) 151 152def SIbuffer_store : SDNode <"AMDGPUISD::BUFFER_STORE", SDTBufferStore, 153 [SDNPMayStore, SDNPMemOperand, SDNPHasChain]>; 154def SIbuffer_store_byte: SDNode <"AMDGPUISD::BUFFER_STORE_BYTE", 155 SDTBufferStore, 156 [SDNPMayStore, SDNPMemOperand, SDNPHasChain]>; 157def SIbuffer_store_short : SDNode <"AMDGPUISD::BUFFER_STORE_SHORT", 158 SDTBufferStore, 159 [SDNPMayStore, SDNPMemOperand, SDNPHasChain]>; 160def SIbuffer_store_format : SDNode <"AMDGPUISD::BUFFER_STORE_FORMAT", 161 SDTBufferStore, 162 [SDNPMayStore, SDNPMemOperand, SDNPHasChain]>; 163def SIbuffer_store_format_d16 : SDNode <"AMDGPUISD::BUFFER_STORE_FORMAT_D16", 164 SDTBufferStore, 165 [SDNPMayStore, SDNPMemOperand, SDNPHasChain]>; 166 167class SDBufferAtomic<string opcode> : SDNode <opcode, 168 SDTypeProfile<1, 8, 169 [SDTCisVT<2, v4i32>, // rsrc 170 SDTCisVT<3, i32>, // vindex(VGPR) 171 SDTCisVT<4, i32>, // voffset(VGPR) 172 SDTCisVT<5, i32>, // soffset(SGPR) 173 SDTCisVT<6, i32>, // offset(imm) 174 SDTCisVT<7, i32>, // cachepolicy(imm) 175 SDTCisVT<8, i1>]>, // idxen(imm) 176 [SDNPMemOperand, SDNPHasChain, SDNPMayLoad, SDNPMayStore] 177>; 178 179def SIbuffer_atomic_swap : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_SWAP">; 180def SIbuffer_atomic_add : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_ADD">; 181def SIbuffer_atomic_sub : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_SUB">; 182def SIbuffer_atomic_smin : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_SMIN">; 183def SIbuffer_atomic_umin : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_UMIN">; 184def SIbuffer_atomic_smax : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_SMAX">; 185def SIbuffer_atomic_umax : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_UMAX">; 186def SIbuffer_atomic_and : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_AND">; 187def SIbuffer_atomic_or : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_OR">; 188def SIbuffer_atomic_xor : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_XOR">; 189def SIbuffer_atomic_inc : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_INC">; 190def SIbuffer_atomic_dec : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_DEC">; 191def SIbuffer_atomic_csub : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_CSUB">; 192def SIbuffer_atomic_fadd : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_FADD">; 193def SIbuffer_atomic_fmin : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_FMIN">; 194def SIbuffer_atomic_fmax : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_FMAX">; 195 196multiclass SDBufferAtomicNoRet { 197 def "_noret" : PatFrag< 198 (ops node:$vdata_in, node:$rsrc, node:$vindex, node:$voffset, node:$soffset, 199 node:$offset, node:$cachepolicy, node:$idxen), 200 (!cast<SDNode>(NAME) node:$vdata_in, node:$rsrc, node:$vindex, 201 node:$voffset, node:$soffset, node:$offset, node:$cachepolicy, 202 node:$idxen)> { 203 let HasNoUse = true; 204 } 205} 206 207defm SIbuffer_atomic_swap : SDBufferAtomicNoRet; 208defm SIbuffer_atomic_add : SDBufferAtomicNoRet; 209defm SIbuffer_atomic_sub : SDBufferAtomicNoRet; 210defm SIbuffer_atomic_smin : SDBufferAtomicNoRet; 211defm SIbuffer_atomic_umin : SDBufferAtomicNoRet; 212defm SIbuffer_atomic_smax : SDBufferAtomicNoRet; 213defm SIbuffer_atomic_umax : SDBufferAtomicNoRet; 214defm SIbuffer_atomic_and : SDBufferAtomicNoRet; 215defm SIbuffer_atomic_or : SDBufferAtomicNoRet; 216defm SIbuffer_atomic_xor : SDBufferAtomicNoRet; 217defm SIbuffer_atomic_inc : SDBufferAtomicNoRet; 218defm SIbuffer_atomic_dec : SDBufferAtomicNoRet; 219defm SIbuffer_atomic_fadd : SDBufferAtomicNoRet; 220defm SIbuffer_atomic_fmin : SDBufferAtomicNoRet; 221defm SIbuffer_atomic_fmax : SDBufferAtomicNoRet; 222 223def SIbuffer_atomic_cmpswap : SDNode <"AMDGPUISD::BUFFER_ATOMIC_CMPSWAP", 224 SDTypeProfile<1, 9, 225 [SDTCisVT<0, i32>, // dst 226 SDTCisVT<1, i32>, // src 227 SDTCisVT<2, i32>, // cmp 228 SDTCisVT<3, v4i32>, // rsrc 229 SDTCisVT<4, i32>, // vindex(VGPR) 230 SDTCisVT<5, i32>, // voffset(VGPR) 231 SDTCisVT<6, i32>, // soffset(SGPR) 232 SDTCisVT<7, i32>, // offset(imm) 233 SDTCisVT<8, i32>, // cachepolicy(imm) 234 SDTCisVT<9, i1>]>, // idxen(imm) 235 [SDNPMemOperand, SDNPHasChain, SDNPMayLoad, SDNPMayStore] 236>; 237 238def SIbuffer_atomic_cmpswap_noret : PatFrag< 239 (ops node:$src, node:$cmp, node:$rsrc, node:$vindex, node:$voffset, 240 node:$soffset, node:$offset, node:$cachepolicy, node:$idxen), 241 (SIbuffer_atomic_cmpswap node:$src, node:$cmp, node:$rsrc, node:$vindex, 242 node:$voffset, node:$soffset, node:$offset, node:$cachepolicy, 243 node:$idxen)> { 244 let HasNoUse = true; 245} 246 247class SDGlobalAtomicNoRtn<string opcode, ValueType ty> : SDNode <opcode, 248 SDTypeProfile<0, 2, 249 [SDTCisPtrTy<0>, // vaddr 250 SDTCisVT<1, ty>]>, // vdata 251 [SDNPMemOperand, SDNPHasChain, SDNPMayLoad, SDNPMayStore] 252>; 253 254def SIpc_add_rel_offset : SDNode<"AMDGPUISD::PC_ADD_REL_OFFSET", 255 SDTypeProfile<1, 2, [SDTCisVT<0, iPTR>, SDTCisSameAs<0,1>, SDTCisSameAs<0,2>]> 256>; 257 258def SIlds : SDNode<"AMDGPUISD::LDS", 259 SDTypeProfile<1, 1, [SDTCisVT<0, iPTR>, SDTCisSameAs<0,1>]> 260>; 261 262def SIload_d16_lo : SDNode<"AMDGPUISD::LOAD_D16_LO", 263 SIload_d16, 264 [SDNPMayLoad, SDNPMemOperand, SDNPHasChain] 265>; 266 267def SIload_d16_lo_u8 : SDNode<"AMDGPUISD::LOAD_D16_LO_U8", 268 SIload_d16, 269 [SDNPMayLoad, SDNPMemOperand, SDNPHasChain] 270>; 271 272def SIload_d16_lo_i8 : SDNode<"AMDGPUISD::LOAD_D16_LO_I8", 273 SIload_d16, 274 [SDNPMayLoad, SDNPMemOperand, SDNPHasChain] 275>; 276 277def SIload_d16_hi : SDNode<"AMDGPUISD::LOAD_D16_HI", 278 SIload_d16, 279 [SDNPMayLoad, SDNPMemOperand, SDNPHasChain] 280>; 281 282def SIload_d16_hi_u8 : SDNode<"AMDGPUISD::LOAD_D16_HI_U8", 283 SIload_d16, 284 [SDNPMayLoad, SDNPMemOperand, SDNPHasChain] 285>; 286 287def SIload_d16_hi_i8 : SDNode<"AMDGPUISD::LOAD_D16_HI_I8", 288 SIload_d16, 289 [SDNPMayLoad, SDNPMemOperand, SDNPHasChain] 290>; 291 292def SIdenorm_mode : SDNode<"AMDGPUISD::DENORM_MODE", 293 SDTypeProfile<0 ,1, [SDTCisInt<0>]>, 294 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue] 295>; 296 297def SIfptrunc_round_upward : SDNode<"AMDGPUISD::FPTRUNC_ROUND_UPWARD", 298 SDTFPRoundOp 299>; 300 301def SIfptrunc_round_downward : SDNode<"AMDGPUISD::FPTRUNC_ROUND_DOWNWARD", 302 SDTFPRoundOp 303>; 304 305//===----------------------------------------------------------------------===// 306// ValueType helpers 307//===----------------------------------------------------------------------===// 308 309// Returns 1 if the source arguments have modifiers, 0 if they do not. 310class isFloatType<ValueType SrcVT> { 311 bit ret = !or(!eq(SrcVT.Value, f16.Value), 312 !eq(SrcVT.Value, f32.Value), 313 !eq(SrcVT.Value, f64.Value), 314 !eq(SrcVT.Value, v2f16.Value), 315 !eq(SrcVT.Value, v4f16.Value), 316 !eq(SrcVT.Value, v8f16.Value), 317 !eq(SrcVT.Value, v16f16.Value), 318 !eq(SrcVT.Value, v2f32.Value), 319 !eq(SrcVT.Value, v4f32.Value), 320 !eq(SrcVT.Value, v8f32.Value), 321 !eq(SrcVT.Value, v2f64.Value), 322 !eq(SrcVT.Value, v4f64.Value)); 323} 324 325// XXX - do v2i16 instructions? 326class isIntType<ValueType SrcVT> { 327 bit ret = !or(!eq(SrcVT.Value, i16.Value), 328 !eq(SrcVT.Value, i32.Value), 329 !eq(SrcVT.Value, i64.Value), 330 !eq(SrcVT.Value, v4i16.Value), 331 !eq(SrcVT.Value, v8i16.Value), 332 !eq(SrcVT.Value, v16i16.Value), 333 !eq(SrcVT.Value, v2i32.Value), 334 !eq(SrcVT.Value, v4i32.Value), 335 !eq(SrcVT.Value, v8i32.Value)); 336} 337 338class isPackedType<ValueType SrcVT> { 339 bit ret = !or(!eq(SrcVT.Value, v2i16.Value), 340 !eq(SrcVT.Value, v2f16.Value), 341 !eq(SrcVT.Value, v4f16.Value), 342 !eq(SrcVT.Value, v2i32.Value), 343 !eq(SrcVT.Value, v2f32.Value), 344 !eq(SrcVT.Value, v4i32.Value), 345 !eq(SrcVT.Value, v4f32.Value), 346 !eq(SrcVT.Value, v8i32.Value), 347 !eq(SrcVT.Value, v8f32.Value)); 348} 349 350 351//===----------------------------------------------------------------------===// 352// PatFrags for global memory operations 353//===----------------------------------------------------------------------===// 354 355defm atomic_inc : binary_atomic_op_all_as<SIatomic_inc>; 356defm atomic_dec : binary_atomic_op_all_as<SIatomic_dec>; 357defm atomic_load_fmin : binary_atomic_op_all_as<SIatomic_fmin, 0>; 358defm atomic_load_fmax : binary_atomic_op_all_as<SIatomic_fmax, 0>; 359 360//===----------------------------------------------------------------------===// 361// SDNodes PatFrags for loads/stores with a glue input. 362// This is for SDNodes and PatFrag for local loads and stores to 363// enable s_mov_b32 m0, -1 to be glued to the memory instructions. 364// 365// These mirror the regular load/store PatFrags and rely on special 366// processing during Select() to add the glued copy. 367// 368//===----------------------------------------------------------------------===// 369 370def AMDGPUld_glue : SDNode <"ISD::LOAD", SDTLoad, 371 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand, SDNPInGlue] 372>; 373 374def AMDGPUatomic_ld_glue : SDNode <"ISD::ATOMIC_LOAD", SDTAtomicLoad, 375 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand, SDNPInGlue] 376>; 377 378def unindexedload_glue : PatFrag <(ops node:$ptr), (AMDGPUld_glue node:$ptr)> { 379 let IsLoad = 1; 380 let IsUnindexed = 1; 381} 382 383def load_glue : PatFrag <(ops node:$ptr), (unindexedload_glue node:$ptr)> { 384 let IsLoad = 1; 385 let IsNonExtLoad = 1; 386} 387 388def atomic_load_8_glue : PatFrag<(ops node:$ptr), 389 (AMDGPUatomic_ld_glue node:$ptr)> { 390 let IsAtomic = 1; 391 let MemoryVT = i8; 392} 393 394def atomic_load_16_glue : PatFrag<(ops node:$ptr), 395 (AMDGPUatomic_ld_glue node:$ptr)> { 396 let IsAtomic = 1; 397 let MemoryVT = i16; 398} 399 400def atomic_load_32_glue : PatFrag<(ops node:$ptr), 401 (AMDGPUatomic_ld_glue node:$ptr)> { 402 let IsAtomic = 1; 403 let MemoryVT = i32; 404} 405 406def atomic_load_64_glue : PatFrag<(ops node:$ptr), 407 (AMDGPUatomic_ld_glue node:$ptr)> { 408 let IsAtomic = 1; 409 let MemoryVT = i64; 410} 411 412def extload_glue : PatFrag<(ops node:$ptr), (unindexedload_glue node:$ptr)> { 413 let IsLoad = 1; 414 let IsAnyExtLoad = 1; 415} 416 417def sextload_glue : PatFrag<(ops node:$ptr), (unindexedload_glue node:$ptr)> { 418 let IsLoad = 1; 419 let IsSignExtLoad = 1; 420} 421 422def zextload_glue : PatFrag<(ops node:$ptr), (unindexedload_glue node:$ptr)> { 423 let IsLoad = 1; 424 let IsZeroExtLoad = 1; 425} 426 427def extloadi8_glue : PatFrag<(ops node:$ptr), (extload_glue node:$ptr)> { 428 let IsLoad = 1; 429 let MemoryVT = i8; 430} 431 432def zextloadi8_glue : PatFrag<(ops node:$ptr), (zextload_glue node:$ptr)> { 433 let IsLoad = 1; 434 let MemoryVT = i8; 435} 436 437def extloadi16_glue : PatFrag<(ops node:$ptr), (extload_glue node:$ptr)> { 438 let IsLoad = 1; 439 let MemoryVT = i16; 440} 441 442def zextloadi16_glue : PatFrag<(ops node:$ptr), (zextload_glue node:$ptr)> { 443 let IsLoad = 1; 444 let MemoryVT = i16; 445} 446 447def sextloadi8_glue : PatFrag<(ops node:$ptr), (sextload_glue node:$ptr)> { 448 let IsLoad = 1; 449 let MemoryVT = i8; 450} 451 452def sextloadi16_glue : PatFrag<(ops node:$ptr), (sextload_glue node:$ptr)> { 453 let IsLoad = 1; 454 let MemoryVT = i16; 455} 456 457 458let IsLoad = 1, AddressSpaces = LoadAddress_local.AddrSpaces in { 459def load_local_m0 : PatFrag<(ops node:$ptr), (load_glue node:$ptr)> { 460 let IsNonExtLoad = 1; 461} 462 463def extloadi8_local_m0 : PatFrag<(ops node:$ptr), (extloadi8_glue node:$ptr)>; 464def sextloadi8_local_m0 : PatFrag<(ops node:$ptr), (sextloadi8_glue node:$ptr)>; 465def zextloadi8_local_m0 : PatFrag<(ops node:$ptr), (zextloadi8_glue node:$ptr)>; 466 467def extloadi16_local_m0 : PatFrag<(ops node:$ptr), (extloadi16_glue node:$ptr)>; 468def sextloadi16_local_m0 : PatFrag<(ops node:$ptr), (sextloadi16_glue node:$ptr)>; 469def zextloadi16_local_m0 : PatFrag<(ops node:$ptr), (zextloadi16_glue node:$ptr)>; 470} // End IsLoad = 1, , AddressSpaces = LoadAddress_local.AddrSpaces 471 472def load_align8_local_m0 : PatFrag<(ops node:$ptr), 473 (load_local_m0 node:$ptr)> { 474 let IsLoad = 1; 475 int MinAlignment = 8; 476} 477 478def load_align16_local_m0 : PatFrag<(ops node:$ptr), 479 (load_local_m0 node:$ptr)> { 480 let IsLoad = 1; 481 int MinAlignment = 16; 482} 483 484let IsAtomic = 1, AddressSpaces = LoadAddress_local.AddrSpaces in { 485def atomic_load_8_local_m0 : PatFrag<(ops node:$ptr), 486 (atomic_load_8_glue node:$ptr)>; 487def atomic_load_16_local_m0 : PatFrag<(ops node:$ptr), 488 (atomic_load_16_glue node:$ptr)>; 489def atomic_load_32_local_m0 : PatFrag<(ops node:$ptr), 490 (atomic_load_32_glue node:$ptr)>; 491def atomic_load_64_local_m0 : PatFrag<(ops node:$ptr), 492 (atomic_load_64_glue node:$ptr)>; 493} // End let AddressSpaces = LoadAddress_local.AddrSpaces 494 495 496def AMDGPUst_glue : SDNode <"ISD::STORE", SDTStore, 497 [SDNPHasChain, SDNPMayStore, SDNPMemOperand, SDNPInGlue] 498>; 499 500def AMDGPUatomic_st_glue : SDNode <"ISD::ATOMIC_STORE", SDTAtomicStore, 501 [SDNPHasChain, SDNPMayStore, SDNPMemOperand, SDNPInGlue] 502>; 503 504def unindexedstore_glue : PatFrag<(ops node:$val, node:$ptr), 505 (AMDGPUst_glue node:$val, node:$ptr)> { 506 let IsStore = 1; 507 let IsUnindexed = 1; 508} 509 510def store_glue : PatFrag<(ops node:$val, node:$ptr), 511 (unindexedstore_glue node:$val, node:$ptr)> { 512 let IsStore = 1; 513 let IsTruncStore = 0; 514} 515 516def truncstore_glue : PatFrag<(ops node:$val, node:$ptr), 517 (unindexedstore_glue node:$val, node:$ptr)> { 518 let IsStore = 1; 519 let IsTruncStore = 1; 520} 521 522def truncstorei8_glue : PatFrag<(ops node:$val, node:$ptr), 523 (truncstore_glue node:$val, node:$ptr)> { 524 let IsStore = 1; 525 let MemoryVT = i8; 526 let IsTruncStore = 1; 527} 528 529def truncstorei16_glue : PatFrag<(ops node:$val, node:$ptr), 530 (truncstore_glue node:$val, node:$ptr)> { 531 let IsStore = 1; 532 let MemoryVT = i16; 533 let IsTruncStore = 1; 534} 535 536let IsStore = 1, AddressSpaces = StoreAddress_local.AddrSpaces in { 537def store_local_m0 : PatFrag<(ops node:$val, node:$ptr), 538 (store_glue node:$val, node:$ptr)>; 539def truncstorei8_local_m0 : PatFrag<(ops node:$val, node:$ptr), 540 (truncstorei8_glue node:$val, node:$ptr)>; 541def truncstorei16_local_m0 : PatFrag<(ops node:$val, node:$ptr), 542 (truncstorei16_glue node:$val, node:$ptr)>; 543} 544 545def store_align8_local_m0 : PatFrag <(ops node:$value, node:$ptr), 546 (store_local_m0 node:$value, node:$ptr)>, 547 Aligned<8> { 548 let IsStore = 1; 549} 550 551def store_align16_local_m0 : PatFrag <(ops node:$value, node:$ptr), 552 (store_local_m0 node:$value, node:$ptr)>, 553 Aligned<16> { 554 let IsStore = 1; 555} 556 557let PredicateCode = [{return cast<MemSDNode>(N)->getAlignment() < 4;}], 558 GISelPredicateCode = [{return (*MI.memoperands_begin())->getAlign() < 4;}], 559 AddressSpaces = [ AddrSpaces.Local ] in { 560def load_align_less_than_4_local : PatFrag<(ops node:$ptr), 561 (load_local node:$ptr)> { 562 let IsLoad = 1; 563 let IsNonExtLoad = 1; 564} 565 566def load_align_less_than_4_local_m0 : PatFrag<(ops node:$ptr), 567 (load_local_m0 node:$ptr)> { 568 let IsLoad = 1; 569 let IsNonExtLoad = 1; 570} 571 572def store_align_less_than_4_local : PatFrag <(ops node:$value, node:$ptr), 573 (store_local node:$value, node:$ptr)> { 574 let IsStore = 1; 575 let IsTruncStore = 0; 576} 577 578def store_align_less_than_4_local_m0 : PatFrag <(ops node:$value, node:$ptr), 579 (store_local_m0 node:$value, node:$ptr)> { 580 let IsStore = 1; 581 let IsTruncStore = 0; 582} 583} 584 585def atomic_store_8_glue : PatFrag < 586 (ops node:$ptr, node:$value), 587 (AMDGPUatomic_st_glue node:$ptr, node:$value)> { 588 let IsAtomic = 1; 589 let MemoryVT = i8; 590} 591 592def atomic_store_16_glue : PatFrag < 593 (ops node:$ptr, node:$value), 594 (AMDGPUatomic_st_glue node:$ptr, node:$value)> { 595 let IsAtomic = 1; 596 let MemoryVT = i16; 597} 598 599def atomic_store_32_glue : PatFrag < 600 (ops node:$ptr, node:$value), 601 (AMDGPUatomic_st_glue node:$ptr, node:$value)> { 602 let IsAtomic = 1; 603 let MemoryVT = i32; 604} 605 606def atomic_store_64_glue : PatFrag < 607 (ops node:$ptr, node:$value), 608 (AMDGPUatomic_st_glue node:$ptr, node:$value)> { 609 let IsAtomic = 1; 610 let MemoryVT = i64; 611} 612 613let IsAtomic = 1, AddressSpaces = StoreAddress_local.AddrSpaces in { 614def atomic_store_8_local_m0 : PatFrag<(ops node:$ptr, node:$val), 615 (atomic_store_8_glue node:$ptr, node:$val)>; 616def atomic_store_16_local_m0 : PatFrag<(ops node:$ptr, node:$val), 617 (atomic_store_16_glue node:$ptr, node:$val)>; 618def atomic_store_32_local_m0 : PatFrag<(ops node:$ptr, node:$val), 619 (atomic_store_32_glue node:$ptr, node:$val)>; 620def atomic_store_64_local_m0 : PatFrag<(ops node:$ptr, node:$val), 621 (atomic_store_64_glue node:$ptr, node:$val)>; 622} // End let IsAtomic = 1, AddressSpaces = StoreAddress_local.AddrSpaces 623 624 625def si_setcc_uniform : PatFrag < 626 (ops node:$lhs, node:$rhs, node:$cond), 627 (setcc node:$lhs, node:$rhs, node:$cond), [{ 628 return !N->isDivergent(); 629}]>; 630 631//===----------------------------------------------------------------------===// 632// SDNodes PatFrags for a16 loads and stores with 3 components. 633// v3f16/v3i16 is widened to v4f16/v4i16, so we need to match on the memory 634// load/store size. 635//===----------------------------------------------------------------------===// 636 637class mubuf_intrinsic_load<SDPatternOperator name, ValueType vt> : PatFrag < 638 (ops node:$rsrc, node:$vindex, node:$voffset, node:$soffset, node:$offset, 639 node:$auxiliary, node:$idxen), 640 (name node:$rsrc, node:$vindex, node:$voffset, node:$soffset, node:$offset, 641 node:$auxiliary, node:$idxen)> { 642 let IsLoad = 1; 643 let MemoryVT = vt; 644} 645 646class mubuf_intrinsic_store<SDPatternOperator name, ValueType vt> : PatFrag < 647 (ops node:$vdata, node:$rsrc, node:$vindex, node:$voffset, node:$soffset, node:$offset, 648 node:$auxiliary, node:$idxen), 649 (name node:$vdata, node:$rsrc, node:$vindex, node:$voffset, node:$soffset, node:$offset, 650 node:$auxiliary, node:$idxen)> { 651 let IsStore = 1; 652 let MemoryVT = vt; 653} 654 655class mtbuf_intrinsic_load<SDPatternOperator name, ValueType vt> : PatFrag < 656 (ops node:$rsrc, node:$vindex, node:$voffset, node:$soffset, node:$offset, 657 node:$format, node:$auxiliary, node:$idxen), 658 (name node:$rsrc, node:$vindex, node:$voffset, node:$soffset, node:$offset, 659 node:$format, node:$auxiliary, node:$idxen)> { 660 let IsLoad = 1; 661 let MemoryVT = vt; 662} 663 664class mtbuf_intrinsic_store<SDPatternOperator name, ValueType vt> : PatFrag < 665 (ops node:$vdata, node:$rsrc, node:$vindex, node:$voffset, node:$soffset, node:$offset, 666 node:$format, node:$auxiliary, node:$idxen), 667 (name node:$vdata, node:$rsrc, node:$vindex, node:$voffset, node:$soffset, node:$offset, 668 node:$format, node:$auxiliary, node:$idxen)> { 669 let IsStore = 1; 670 let MemoryVT = vt; 671} 672 673//===----------------------------------------------------------------------===// 674// SDNodes PatFrags for d16 loads 675//===----------------------------------------------------------------------===// 676 677class LoadD16Frag <SDPatternOperator op> : PatFrag< 678 (ops node:$ptr, node:$tied_in), 679 (op node:$ptr, node:$tied_in)> { 680 let IsLoad = 1; 681} 682 683foreach as = [ "global", "flat", "constant", "local", "private", "region" ] in { 684let AddressSpaces = !cast<AddressSpaceList>("LoadAddress_"#as).AddrSpaces in { 685 686def load_d16_hi_#as : LoadD16Frag <SIload_d16_hi>; 687 688def az_extloadi8_d16_hi_#as : LoadD16Frag <SIload_d16_hi_u8> { 689 let MemoryVT = i8; 690} 691 692def sextloadi8_d16_hi_#as : LoadD16Frag <SIload_d16_hi_i8> { 693 let MemoryVT = i8; 694} 695 696def load_d16_lo_#as : LoadD16Frag <SIload_d16_lo>; 697 698def az_extloadi8_d16_lo_#as : LoadD16Frag <SIload_d16_lo_u8> { 699 let MemoryVT = i8; 700} 701 702def sextloadi8_d16_lo_#as : LoadD16Frag <SIload_d16_lo_i8> { 703 let MemoryVT = i8; 704} 705 706} // End let AddressSpaces = ... 707} // End foreach AddrSpace 708 709def lshr_rev : PatFrag < 710 (ops node:$src1, node:$src0), 711 (srl $src0, $src1) 712>; 713 714def ashr_rev : PatFrag < 715 (ops node:$src1, node:$src0), 716 (sra $src0, $src1) 717>; 718 719def lshl_rev : PatFrag < 720 (ops node:$src1, node:$src0), 721 (shl $src0, $src1) 722>; 723 724def add_ctpop : PatFrag < 725 (ops node:$src0, node:$src1), 726 (add (ctpop $src0), $src1) 727>; 728 729def xnor : PatFrag < 730 (ops node:$src0, node:$src1), 731 (not (xor $src0, $src1)) 732>; 733 734foreach I = 1-4 in { 735def shl#I#_add : PatFrag < 736 (ops node:$src0, node:$src1), 737 (add (shl_oneuse $src0, (i32 I)), $src1)> { 738 // FIXME: Poor substitute for disabling pattern in SelectionDAG 739 let PredicateCode = [{return false;}]; 740 let GISelPredicateCode = [{return true;}]; 741} 742} 743 744multiclass SIAtomicM0Glue2 <string op_name, bit is_amdgpu = 0, 745 SDTypeProfile tc = SDTAtomic2, 746 bit IsInt = 1> { 747 748 def _glue : SDNode < 749 !if(is_amdgpu, "AMDGPUISD", "ISD")#"::ATOMIC_"#op_name, tc, 750 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand, SDNPInGlue] 751 >; 752 753 let AddressSpaces = StoreAddress_local.AddrSpaces in { 754 defm _local_m0 : binary_atomic_op <!cast<SDNode>(NAME#"_glue"), IsInt>; 755 defm _local_m0 : noret_binary_atomic_op <!cast<SDNode>(NAME#"_glue"), 756 IsInt>; 757 } 758 759 let AddressSpaces = StoreAddress_region.AddrSpaces in { 760 defm _region_m0 : binary_atomic_op <!cast<SDNode>(NAME#"_glue"), IsInt>; 761 defm _region_m0 : noret_binary_atomic_op <!cast<SDNode>(NAME#"_glue"), 762 IsInt>; 763 } 764} 765 766defm atomic_load_add : SIAtomicM0Glue2 <"LOAD_ADD">; 767defm atomic_load_sub : SIAtomicM0Glue2 <"LOAD_SUB">; 768defm atomic_inc : SIAtomicM0Glue2 <"INC", 1>; 769defm atomic_dec : SIAtomicM0Glue2 <"DEC", 1>; 770defm atomic_load_and : SIAtomicM0Glue2 <"LOAD_AND">; 771defm atomic_load_min : SIAtomicM0Glue2 <"LOAD_MIN">; 772defm atomic_load_max : SIAtomicM0Glue2 <"LOAD_MAX">; 773defm atomic_load_or : SIAtomicM0Glue2 <"LOAD_OR">; 774defm atomic_load_xor : SIAtomicM0Glue2 <"LOAD_XOR">; 775defm atomic_load_umin : SIAtomicM0Glue2 <"LOAD_UMIN">; 776defm atomic_load_umax : SIAtomicM0Glue2 <"LOAD_UMAX">; 777defm atomic_swap : SIAtomicM0Glue2 <"SWAP">; 778defm atomic_load_fadd : SIAtomicM0Glue2 <"LOAD_FADD", 0, SDTAtomic2_f32, 0>; 779defm atomic_load_fmin : SIAtomicM0Glue2 <"LOAD_FMIN", 1, SDTAtomic2_f32, 0>; 780defm atomic_load_fmax : SIAtomicM0Glue2 <"LOAD_FMAX", 1, SDTAtomic2_f32, 0>; 781 782def as_i1timm : SDNodeXForm<timm, [{ 783 return CurDAG->getTargetConstant(N->getZExtValue(), SDLoc(N), MVT::i1); 784}]>; 785 786def as_i8imm : SDNodeXForm<imm, [{ 787 return CurDAG->getTargetConstant(N->getZExtValue(), SDLoc(N), MVT::i8); 788}]>; 789 790def as_i8timm : SDNodeXForm<timm, [{ 791 return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i16); 792}]>; 793 794def as_i16imm : SDNodeXForm<imm, [{ 795 return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i16); 796}]>; 797 798def as_i16timm : SDNodeXForm<timm, [{ 799 return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i16); 800}]>; 801 802def as_i32imm: SDNodeXForm<imm, [{ 803 return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i32); 804}]>; 805 806def as_i32timm: SDNodeXForm<timm, [{ 807 return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i32); 808}]>; 809 810def as_i64imm: SDNodeXForm<imm, [{ 811 return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i64); 812}]>; 813 814def cond_as_i32imm: SDNodeXForm<cond, [{ 815 return CurDAG->getTargetConstant(N->get(), SDLoc(N), MVT::i32); 816}]>; 817 818// Copied from the AArch64 backend: 819def bitcast_fpimm_to_i32 : SDNodeXForm<fpimm, [{ 820return CurDAG->getTargetConstant( 821 N->getValueAPF().bitcastToAPInt().getZExtValue(), SDLoc(N), MVT::i32); 822}]>; 823 824def frameindex_to_targetframeindex : SDNodeXForm<frameindex, [{ 825 auto FI = cast<FrameIndexSDNode>(N); 826 return CurDAG->getTargetFrameIndex(FI->getIndex(), MVT::i32); 827}]>; 828 829// Copied from the AArch64 backend: 830def bitcast_fpimm_to_i64 : SDNodeXForm<fpimm, [{ 831return CurDAG->getTargetConstant( 832 N->getValueAPF().bitcastToAPInt().getZExtValue(), SDLoc(N), MVT::i64); 833}]>; 834 835class bitextract_imm<int bitnum> : SDNodeXForm<imm, [{ 836 uint64_t Imm = N->getZExtValue(); 837 unsigned Bit = (Imm >> }] # bitnum # [{ ) & 1; 838 return CurDAG->getTargetConstant(Bit, SDLoc(N), MVT::i1); 839}]>; 840 841def SIMM16bit : ImmLeaf <i32, 842 [{return isInt<16>(Imm);}] 843>; 844 845def UIMM16bit : ImmLeaf <i32, 846 [{return isUInt<16>(Imm);}] 847>; 848 849def i64imm_32bit : ImmLeaf<i64, [{ 850 return (Imm & 0xffffffffULL) == static_cast<uint64_t>(Imm); 851}]>; 852 853def InlineImm16 : ImmLeaf<i16, [{ 854 return isInlineImmediate16(Imm); 855}]>; 856 857def InlineImm32 : ImmLeaf<i32, [{ 858 return isInlineImmediate32(Imm); 859}]>; 860 861def InlineImm64 : ImmLeaf<i64, [{ 862 return isInlineImmediate64(Imm); 863}]>; 864 865def InlineImmFP32 : FPImmLeaf<f32, [{ 866 return isInlineImmediate(Imm); 867}]>; 868 869def InlineImmFP64 : FPImmLeaf<f64, [{ 870 return isInlineImmediate(Imm); 871}]>; 872 873 874class VGPRImm <dag frag> : PatLeaf<frag, [{ 875 return isVGPRImm(N); 876}]>; 877 878def NegateImm : SDNodeXForm<imm, [{ 879 return CurDAG->getConstant(-N->getSExtValue(), SDLoc(N), MVT::i32); 880}]>; 881 882// TODO: When FP inline imm values work? 883def NegSubInlineConst32 : ImmLeaf<i32, [{ 884 return Imm < -16 && Imm >= -64; 885}], NegateImm>; 886 887def NegSubInlineIntConst16 : ImmLeaf<i16, [{ 888 return Imm < -16 && Imm >= -64; 889}], NegateImm>; 890 891def ShiftAmt32Imm : ImmLeaf <i32, [{ 892 return Imm < 32; 893}]>; 894 895def getNegV2I16Imm : SDNodeXForm<build_vector, [{ 896 return SDValue(packNegConstantV2I16(N, *CurDAG), 0); 897}]>; 898 899def NegSubInlineConstV216 : PatLeaf<(build_vector), [{ 900 assert(N->getNumOperands() == 2); 901 assert(N->getOperand(0).getValueType().getSizeInBits() == 16); 902 SDValue Src0 = N->getOperand(0); 903 SDValue Src1 = N->getOperand(1); 904 if (Src0 == Src1) 905 return isNegInlineImmediate(Src0.getNode()); 906 907 return (isNullConstantOrUndef(Src0) && isNegInlineImmediate(Src1.getNode())) || 908 (isNullConstantOrUndef(Src1) && isNegInlineImmediate(Src0.getNode())); 909}], getNegV2I16Imm>; 910 911 912def fp16_zeros_high_16bits : PatLeaf<(f16 VGPR_32:$src), [{ 913 return fp16SrcZerosHighBits(N->getOpcode()); 914}]>; 915 916 917//===----------------------------------------------------------------------===// 918// MUBUF/SMEM Patterns 919//===----------------------------------------------------------------------===// 920 921def extract_cpol : SDNodeXForm<timm, [{ 922 return CurDAG->getTargetConstant(N->getZExtValue() & AMDGPU::CPol::ALL, SDLoc(N), MVT::i8); 923}]>; 924 925def extract_swz : SDNodeXForm<timm, [{ 926 return CurDAG->getTargetConstant((N->getZExtValue() >> 3) & 1, SDLoc(N), MVT::i8); 927}]>; 928 929def set_glc : SDNodeXForm<timm, [{ 930 return CurDAG->getTargetConstant(N->getZExtValue() | AMDGPU::CPol::GLC, SDLoc(N), MVT::i8); 931}]>; 932 933//===----------------------------------------------------------------------===// 934// Custom Operands 935//===----------------------------------------------------------------------===// 936 937def SoppBrTarget : AsmOperandClass { 938 let Name = "SoppBrTarget"; 939 let ParserMethod = "parseSOppBrTarget"; 940} 941 942def sopp_brtarget : Operand<OtherVT> { 943 let EncoderMethod = "getSOPPBrEncoding"; 944 let DecoderMethod = "decodeSoppBrTarget"; 945 let OperandType = "OPERAND_PCREL"; 946 let ParserMatchClass = SoppBrTarget; 947} 948 949def si_ga : Operand<iPTR>; 950 951def InterpSlotMatchClass : AsmOperandClass { 952 let Name = "InterpSlot"; 953 let PredicateMethod = "isInterpSlot"; 954 let ParserMethod = "parseInterpSlot"; 955 let RenderMethod = "addImmOperands"; 956} 957 958def InterpSlot : Operand<i32> { 959 let PrintMethod = "printInterpSlot"; 960 let ParserMatchClass = InterpSlotMatchClass; 961 let OperandType = "OPERAND_IMMEDIATE"; 962} 963 964def AttrMatchClass : AsmOperandClass { 965 let Name = "Attr"; 966 let PredicateMethod = "isInterpAttr"; 967 let ParserMethod = "parseInterpAttr"; 968 let RenderMethod = "addImmOperands"; 969} 970 971// It appears to be necessary to create a separate operand for this to 972// be able to parse attr<num> with no space. 973def Attr : Operand<i32> { 974 let PrintMethod = "printInterpAttr"; 975 let ParserMatchClass = AttrMatchClass; 976 let OperandType = "OPERAND_IMMEDIATE"; 977} 978 979def AttrChanMatchClass : AsmOperandClass { 980 let Name = "AttrChan"; 981 let PredicateMethod = "isAttrChan"; 982 let RenderMethod = "addImmOperands"; 983} 984 985def AttrChan : Operand<i32> { 986 let PrintMethod = "printInterpAttrChan"; 987 let ParserMatchClass = AttrChanMatchClass; 988 let OperandType = "OPERAND_IMMEDIATE"; 989} 990 991def SendMsgMatchClass : AsmOperandClass { 992 let Name = "SendMsg"; 993 let PredicateMethod = "isSendMsg"; 994 let ParserMethod = "parseSendMsgOp"; 995 let RenderMethod = "addImmOperands"; 996} 997 998def SwizzleMatchClass : AsmOperandClass { 999 let Name = "Swizzle"; 1000 let PredicateMethod = "isSwizzle"; 1001 let ParserMethod = "parseSwizzleOp"; 1002 let RenderMethod = "addImmOperands"; 1003 let IsOptional = 1; 1004} 1005 1006def EndpgmMatchClass : AsmOperandClass { 1007 let Name = "EndpgmImm"; 1008 let PredicateMethod = "isEndpgm"; 1009 let ParserMethod = "parseEndpgmOp"; 1010 let RenderMethod = "addImmOperands"; 1011 let IsOptional = 1; 1012} 1013 1014def ExpTgtMatchClass : AsmOperandClass { 1015 let Name = "ExpTgt"; 1016 let PredicateMethod = "isExpTgt"; 1017 let ParserMethod = "parseExpTgt"; 1018 let RenderMethod = "printExpTgt"; 1019} 1020 1021def SWaitMatchClass : AsmOperandClass { 1022 let Name = "SWaitCnt"; 1023 let RenderMethod = "addImmOperands"; 1024 let ParserMethod = "parseSWaitCntOps"; 1025} 1026 1027def DepCtrMatchClass : AsmOperandClass { 1028 let Name = "DepCtr"; 1029 let RenderMethod = "addImmOperands"; 1030 let ParserMethod = "parseDepCtrOps"; 1031} 1032 1033def SDelayMatchClass : AsmOperandClass { 1034 let Name = "SDelayAlu"; 1035 let RenderMethod = "addImmOperands"; 1036 let ParserMethod = "parseSDelayAluOps"; 1037} 1038 1039def VReg32OrOffClass : AsmOperandClass { 1040 let Name = "VReg32OrOff"; 1041 let ParserMethod = "parseVReg32OrOff"; 1042} 1043 1044let OperandType = "OPERAND_IMMEDIATE" in { 1045def SendMsgImm : Operand<i32> { 1046 let PrintMethod = "printSendMsg"; 1047 let ParserMatchClass = SendMsgMatchClass; 1048} 1049 1050def SwizzleImm : Operand<i16> { 1051 let PrintMethod = "printSwizzle"; 1052 let ParserMatchClass = SwizzleMatchClass; 1053} 1054 1055def EndpgmImm : Operand<i16> { 1056 let PrintMethod = "printEndpgm"; 1057 let ParserMatchClass = EndpgmMatchClass; 1058} 1059 1060def WAIT_FLAG : Operand <i32> { 1061 let ParserMatchClass = SWaitMatchClass; 1062 let PrintMethod = "printWaitFlag"; 1063} 1064 1065def DepCtrImm : Operand <i32> { 1066 let ParserMatchClass = DepCtrMatchClass; 1067 let PrintMethod = "printDepCtr"; 1068} 1069 1070def DELAY_FLAG : Operand <i32> { 1071 let ParserMatchClass = SDelayMatchClass; 1072 let PrintMethod = "printDelayFlag"; 1073} 1074} // End OperandType = "OPERAND_IMMEDIATE" 1075 1076include "SIInstrFormats.td" 1077include "VIInstrFormats.td" 1078 1079def BoolReg : AsmOperandClass { 1080 let Name = "BoolReg"; 1081 let ParserMethod = "parseBoolReg"; 1082 let RenderMethod = "addRegOperands"; 1083} 1084 1085class BoolRC : RegisterOperand<SReg_1> { 1086 let ParserMatchClass = BoolReg; 1087 let DecoderMethod = "decodeBoolReg"; 1088} 1089 1090def SSrc_i1 : RegisterOperand<SReg_1_XEXEC> { 1091 let ParserMatchClass = BoolReg; 1092 let DecoderMethod = "decodeBoolReg"; 1093} 1094 1095def VOPDstS64orS32 : BoolRC { 1096 let PrintMethod = "printVOPDst"; 1097} 1098 1099// SCSrc_i1 is the operand for pseudo instructions only. 1100// Boolean immediates shall not be exposed to codegen instructions. 1101def SCSrc_i1 : RegisterOperand<SReg_1_XEXEC> { 1102 let OperandNamespace = "AMDGPU"; 1103 let OperandType = "OPERAND_REG_IMM_INT32"; 1104 let ParserMatchClass = BoolReg; 1105 let DecoderMethod = "decodeBoolReg"; 1106} 1107 1108// ===----------------------------------------------------------------------===// 1109// ExpSrc* Special cases for exp src operands which are printed as 1110// "off" depending on en operand. 1111// ===----------------------------------------------------------------------===// 1112 1113def ExpSrc0 : RegisterOperand<VGPR_32> { 1114 let PrintMethod = "printExpSrc0"; 1115 let ParserMatchClass = VReg32OrOffClass; 1116} 1117 1118def ExpSrc1 : RegisterOperand<VGPR_32> { 1119 let PrintMethod = "printExpSrc1"; 1120 let ParserMatchClass = VReg32OrOffClass; 1121} 1122 1123def ExpSrc2 : RegisterOperand<VGPR_32> { 1124 let PrintMethod = "printExpSrc2"; 1125 let ParserMatchClass = VReg32OrOffClass; 1126} 1127 1128def ExpSrc3 : RegisterOperand<VGPR_32> { 1129 let PrintMethod = "printExpSrc3"; 1130 let ParserMatchClass = VReg32OrOffClass; 1131} 1132 1133class SDWASrc<ValueType vt> : RegisterOperand<VS_32> { 1134 let OperandNamespace = "AMDGPU"; 1135 string Type = !if(isFloatType<vt>.ret, "FP", "INT"); 1136 let OperandType = "OPERAND_REG_INLINE_C_"#Type#vt.Size; 1137 let DecoderMethod = "decodeSDWASrc"#vt.Size; 1138 let EncoderMethod = "getSDWASrcEncoding"; 1139} 1140 1141def SDWASrc_i32 : SDWASrc<i32>; 1142def SDWASrc_i16 : SDWASrc<i16>; 1143def SDWASrc_f32 : SDWASrc<f32>; 1144def SDWASrc_f16 : SDWASrc<f16>; 1145 1146def SDWAVopcDst : BoolRC { 1147 let OperandNamespace = "AMDGPU"; 1148 let OperandType = "OPERAND_SDWA_VOPC_DST"; 1149 let EncoderMethod = "getSDWAVopcDstEncoding"; 1150 let DecoderMethod = "decodeSDWAVopcDst"; 1151 let PrintMethod = "printVOPDst"; 1152} 1153 1154class NamedMatchClass<string CName, bit Optional = 1> : AsmOperandClass { 1155 let Name = "Imm"#CName; 1156 let PredicateMethod = "is"#CName; 1157 let ParserMethod = !if(Optional, "parseOptionalOperand", "parse"#CName); 1158 let RenderMethod = "addImmOperands"; 1159 let IsOptional = Optional; 1160 let DefaultMethod = !if(Optional, "default"#CName, ?); 1161} 1162 1163class NamedOperandBit<string Name, AsmOperandClass MatchClass> : Operand<i1> { 1164 let PrintMethod = "print"#Name; 1165 let ParserMatchClass = MatchClass; 1166} 1167 1168class NamedOperandBit_0<string Name, AsmOperandClass MatchClass> : 1169 OperandWithDefaultOps<i1, (ops (i1 0))> { 1170 let PrintMethod = "print"#Name; 1171 let ParserMatchClass = MatchClass; 1172} 1173 1174class NamedOperandBit_1<string Name, AsmOperandClass MatchClass> : 1175 OperandWithDefaultOps<i1, (ops (i1 1))> { 1176 let PrintMethod = "print"#Name; 1177 let ParserMatchClass = MatchClass; 1178} 1179 1180class NamedOperandU8<string Name, AsmOperandClass MatchClass> : Operand<i8> { 1181 let PrintMethod = "print"#Name; 1182 let ParserMatchClass = MatchClass; 1183} 1184 1185class NamedOperandU16<string Name, AsmOperandClass MatchClass> : Operand<i16> { 1186 let PrintMethod = "print"#Name; 1187 let ParserMatchClass = MatchClass; 1188} 1189 1190class NamedOperandU32<string Name, AsmOperandClass MatchClass> : Operand<i32> { 1191 let PrintMethod = "print"#Name; 1192 let ParserMatchClass = MatchClass; 1193} 1194 1195class NamedOperandU32_0<string Name, AsmOperandClass MatchClass> : 1196 OperandWithDefaultOps<i32, (ops (i32 0))> { 1197 let PrintMethod = "print"#Name; 1198 let ParserMatchClass = MatchClass; 1199} 1200 1201class NamedOperandU32Default0<string Name, AsmOperandClass MatchClass> : 1202 OperandWithDefaultOps<i32, (ops (i32 0))> { 1203 let PrintMethod = "print"#Name; 1204 let ParserMatchClass = MatchClass; 1205} 1206 1207class NamedOperandU32Default1<string Name, AsmOperandClass MatchClass> : 1208 OperandWithDefaultOps<i32, (ops (i32 1))> { 1209 let PrintMethod = "print"#Name; 1210 let ParserMatchClass = MatchClass; 1211} 1212 1213let OperandType = "OPERAND_IMMEDIATE" in { 1214 1215def offen : NamedOperandBit<"Offen", NamedMatchClass<"Offen">>; 1216def idxen : NamedOperandBit<"Idxen", NamedMatchClass<"Idxen">>; 1217def addr64 : NamedOperandBit<"Addr64", NamedMatchClass<"Addr64">>; 1218 1219def flat_offset : NamedOperandU16<"FlatOffset", NamedMatchClass<"FlatOffset">>; 1220def offset : NamedOperandU16<"Offset", NamedMatchClass<"Offset">>; 1221def offset0 : NamedOperandU8<"Offset0", NamedMatchClass<"Offset0">>; 1222def offset1 : NamedOperandU8<"Offset1", NamedMatchClass<"Offset1">>; 1223 1224def gds : NamedOperandBit<"GDS", NamedMatchClass<"GDS">>; 1225 1226def omod : NamedOperandU32<"OModSI", NamedMatchClass<"OModSI">>; 1227def omod0 : NamedOperandU32_0<"OModSI", NamedMatchClass<"OModSI">>; 1228 1229// We need to make the cases with a default of 0 distinct from no 1230// default to help deal with some cases where the operand appears 1231// before a mandatory operand. 1232def clampmod : NamedOperandBit<"ClampSI", NamedMatchClass<"ClampSI">>; 1233def clampmod0 : NamedOperandBit_0<"ClampSI", NamedMatchClass<"ClampSI">>; 1234def highmod : NamedOperandBit<"High", NamedMatchClass<"High">>; 1235 1236def CPol : NamedOperandU32<"CPol", NamedMatchClass<"CPol">>; 1237def CPol_0 : NamedOperandU32Default0<"CPol", NamedMatchClass<"CPol">>; 1238def CPol_GLC1 : NamedOperandU32Default1<"CPol", NamedMatchClass<"CPol">>; 1239 1240def TFE : NamedOperandBit<"TFE", NamedMatchClass<"TFE">>; 1241def TFE_0 : NamedOperandBit_0<"TFE", NamedMatchClass<"TFE">>; 1242def SWZ : NamedOperandBit<"SWZ", NamedMatchClass<"SWZ">>; 1243def SWZ_0 : NamedOperandBit_0<"SWZ", NamedMatchClass<"SWZ">>; 1244def UNorm : NamedOperandBit<"UNorm", NamedMatchClass<"UNorm">>; 1245def DA : NamedOperandBit<"DA", NamedMatchClass<"DA">>; 1246def R128A16 : NamedOperandBit<"R128A16", NamedMatchClass<"R128A16">>; 1247def GFX10A16 : NamedOperandBit<"GFX10A16", NamedMatchClass<"GFX10A16">>; 1248def D16 : NamedOperandBit<"D16", NamedMatchClass<"D16">>; 1249def LWE : NamedOperandBit<"LWE", NamedMatchClass<"LWE">>; 1250def exp_compr : NamedOperandBit<"ExpCompr", NamedMatchClass<"ExpCompr">>; 1251def exp_vm : NamedOperandBit<"ExpVM", NamedMatchClass<"ExpVM">>; 1252 1253def FORMAT : NamedOperandU8<"FORMAT", NamedMatchClass<"FORMAT", 0>>; 1254 1255def DMask : NamedOperandU16<"DMask", NamedMatchClass<"DMask">>; 1256def Dim : NamedOperandU8<"Dim", NamedMatchClass<"Dim", 0>>; 1257 1258def dst_sel : NamedOperandU32<"SDWADstSel", NamedMatchClass<"SDWADstSel">>; 1259def src0_sel : NamedOperandU32<"SDWASrc0Sel", NamedMatchClass<"SDWASrc0Sel">>; 1260def src1_sel : NamedOperandU32<"SDWASrc1Sel", NamedMatchClass<"SDWASrc1Sel">>; 1261def dst_unused : NamedOperandU32<"SDWADstUnused", NamedMatchClass<"SDWADstUnused">>; 1262 1263def op_sel0 : NamedOperandU32Default0<"OpSel", NamedMatchClass<"OpSel">>; 1264def op_sel_hi0 : NamedOperandU32Default0<"OpSelHi", NamedMatchClass<"OpSelHi">>; 1265def neg_lo0 : NamedOperandU32Default0<"NegLo", NamedMatchClass<"NegLo">>; 1266def neg_hi0 : NamedOperandU32Default0<"NegHi", NamedMatchClass<"NegHi">>; 1267 1268def dpp8 : NamedOperandU32<"DPP8", NamedMatchClass<"DPP8", 0>>; 1269def dpp_ctrl : NamedOperandU32<"DPPCtrl", NamedMatchClass<"DPPCtrl", 0>>; 1270 1271def row_mask : NamedOperandU32<"RowMask", NamedMatchClass<"RowMask">>; 1272def bank_mask : NamedOperandU32<"BankMask", NamedMatchClass<"BankMask">>; 1273def bound_ctrl : NamedOperandBit<"BoundCtrl", NamedMatchClass<"BoundCtrl">>; 1274def FI : NamedOperandU32<"FI", NamedMatchClass<"FI">>; 1275 1276def blgp : NamedOperandU32<"BLGP", NamedMatchClass<"BLGP">>; 1277def cbsz : NamedOperandU32<"CBSZ", NamedMatchClass<"CBSZ">>; 1278def abid : NamedOperandU32<"ABID", NamedMatchClass<"ABID">>; 1279 1280def hwreg : NamedOperandU32<"Hwreg", NamedMatchClass<"Hwreg", 0>>; 1281 1282def exp_tgt : NamedOperandU32<"ExpTgt", NamedMatchClass<"ExpTgt", 0>> { 1283 1284} 1285 1286def wait_vdst : NamedOperandU8<"WaitVDST", NamedMatchClass<"WaitVDST">>; 1287def wait_exp : NamedOperandU8<"WaitEXP", NamedMatchClass<"WaitEXP">>; 1288 1289} // End OperandType = "OPERAND_IMMEDIATE" 1290 1291class KImmMatchClass<int size> : AsmOperandClass { 1292 let Name = "KImmFP"#size; 1293 let PredicateMethod = "isKImmFP"#size; 1294 let ParserMethod = "parseImm"; 1295 let RenderMethod = "addKImmFP"#size#"Operands"; 1296} 1297 1298class kimmOperand<ValueType vt> : Operand<vt> { 1299 let OperandNamespace = "AMDGPU"; 1300 let OperandType = "OPERAND_KIMM"#vt.Size; 1301 let PrintMethod = "printU"#vt.Size#"ImmOperand"; 1302 let ParserMatchClass = !cast<AsmOperandClass>("KImmFP"#vt.Size#"MatchClass"); 1303 let DecoderMethod = "decodeOperand_f"#vt.Size#"kimm"; 1304} 1305 1306// 32-bit VALU immediate operand that uses the constant bus. 1307def KImmFP32MatchClass : KImmMatchClass<32>; 1308def f32kimm : kimmOperand<i32>; 1309 1310// 32-bit VALU immediate operand with a 16-bit value that uses the 1311// constant bus. 1312def KImmFP16MatchClass : KImmMatchClass<16>; 1313def f16kimm : kimmOperand<i16>; 1314 1315class FPInputModsMatchClass <int opSize> : AsmOperandClass { 1316 let Name = "RegOrImmWithFP"#opSize#"InputMods"; 1317 let ParserMethod = "parseRegOrImmWithFPInputMods"; 1318 let PredicateMethod = "isRegOrImmWithFP"#opSize#"InputMods"; 1319} 1320 1321class FPVCSrcInputModsMatchClass <int opSize> : FPInputModsMatchClass <opSize> { 1322 let Name = "RegOrInlineImmWithFP"#opSize#"InputMods"; 1323 let PredicateMethod = "isRegOrInlineImmWithFP"#opSize#"InputMods"; 1324} 1325 1326def FP16InputModsMatchClass : FPInputModsMatchClass<16>; 1327def FP32InputModsMatchClass : FPInputModsMatchClass<32>; 1328def FP64InputModsMatchClass : FPInputModsMatchClass<64>; 1329 1330def FP16VCSrcInputModsMatchClass : FPVCSrcInputModsMatchClass<16>; 1331def FP32VCSrcInputModsMatchClass : FPVCSrcInputModsMatchClass<32>; 1332 1333class InputMods <AsmOperandClass matchClass> : Operand <i32> { 1334 let OperandNamespace = "AMDGPU"; 1335 let OperandType = "OPERAND_INPUT_MODS"; 1336 let ParserMatchClass = matchClass; 1337} 1338 1339class FPInputMods <FPInputModsMatchClass matchClass> : InputMods <matchClass> { 1340 let PrintMethod = "printOperandAndFPInputMods"; 1341} 1342 1343def FP16InputMods : FPInputMods<FP16InputModsMatchClass>; 1344def FP32InputMods : FPInputMods<FP32InputModsMatchClass>; 1345def FP64InputMods : FPInputMods<FP64InputModsMatchClass>; 1346 1347def FP16VCSrcInputMods : FPInputMods<FP16VCSrcInputModsMatchClass>; 1348def FP32VCSrcInputMods : FPInputMods<FP32VCSrcInputModsMatchClass>; 1349 1350class IntInputModsMatchClass <int opSize> : AsmOperandClass { 1351 let Name = "RegOrImmWithInt"#opSize#"InputMods"; 1352 let ParserMethod = "parseRegOrImmWithIntInputMods"; 1353 let PredicateMethod = "isRegOrImmWithInt"#opSize#"InputMods"; 1354} 1355class IntVCSrcInputModsMatchClass <int opSize> : IntInputModsMatchClass <opSize> { 1356 let Name = "RegOrInlineImmWithInt"#opSize#"InputMods"; 1357 let PredicateMethod = "isRegOrInlineImmWithInt"#opSize#"InputMods"; 1358} 1359def Int32InputModsMatchClass : IntInputModsMatchClass<32>; 1360def Int64InputModsMatchClass : IntInputModsMatchClass<64>; 1361def Int32VCSrcInputModsMatchClass : IntVCSrcInputModsMatchClass<32>; 1362 1363class IntInputMods <IntInputModsMatchClass matchClass> : InputMods <matchClass> { 1364 let PrintMethod = "printOperandAndIntInputMods"; 1365} 1366def Int32InputMods : IntInputMods<Int32InputModsMatchClass>; 1367def Int64InputMods : IntInputMods<Int64InputModsMatchClass>; 1368def Int32VCSrcInputMods : IntInputMods<Int32VCSrcInputModsMatchClass>; 1369 1370class OpSelModsMatchClass : AsmOperandClass { 1371 let Name = "OpSelMods"; 1372 let ParserMethod = "parseRegOrImm"; 1373 let PredicateMethod = "isRegOrImm"; 1374} 1375 1376def IntOpSelModsMatchClass : OpSelModsMatchClass; 1377def IntOpSelMods : InputMods<IntOpSelModsMatchClass>; 1378 1379class FPSDWAInputModsMatchClass <int opSize> : AsmOperandClass { 1380 let Name = "SDWAWithFP"#opSize#"InputMods"; 1381 let ParserMethod = "parseRegOrImmWithFPInputMods"; 1382 let PredicateMethod = "isSDWAFP"#opSize#"Operand"; 1383} 1384 1385def FP16SDWAInputModsMatchClass : FPSDWAInputModsMatchClass<16>; 1386def FP32SDWAInputModsMatchClass : FPSDWAInputModsMatchClass<32>; 1387 1388class FPSDWAInputMods <FPSDWAInputModsMatchClass matchClass> : 1389 InputMods <matchClass> { 1390 let PrintMethod = "printOperandAndFPInputMods"; 1391} 1392 1393def FP16SDWAInputMods : FPSDWAInputMods<FP16SDWAInputModsMatchClass>; 1394def FP32SDWAInputMods : FPSDWAInputMods<FP32SDWAInputModsMatchClass>; 1395 1396def FPVRegInputModsMatchClass : AsmOperandClass { 1397 let Name = "VRegWithFPInputMods"; 1398 let ParserMethod = "parseRegWithFPInputMods"; 1399 let PredicateMethod = "isVRegWithInputMods"; 1400} 1401 1402def FPVRegInputMods : InputMods <FPVRegInputModsMatchClass> { 1403 let PrintMethod = "printOperandAndFPInputMods"; 1404} 1405 1406class IntSDWAInputModsMatchClass <int opSize> : AsmOperandClass { 1407 let Name = "SDWAWithInt"#opSize#"InputMods"; 1408 let ParserMethod = "parseRegOrImmWithIntInputMods"; 1409 let PredicateMethod = "isSDWAInt"#opSize#"Operand"; 1410} 1411 1412def Int16SDWAInputModsMatchClass : IntSDWAInputModsMatchClass<16>; 1413def Int32SDWAInputModsMatchClass : IntSDWAInputModsMatchClass<32>; 1414 1415class IntSDWAInputMods <IntSDWAInputModsMatchClass matchClass> : 1416 InputMods <matchClass> { 1417 let PrintMethod = "printOperandAndIntInputMods"; 1418} 1419 1420def Int16SDWAInputMods : IntSDWAInputMods<Int16SDWAInputModsMatchClass>; 1421def Int32SDWAInputMods : IntSDWAInputMods<Int32SDWAInputModsMatchClass>; 1422 1423def IntVRegInputModsMatchClass : AsmOperandClass { 1424 let Name = "VRegWithIntInputMods"; 1425 let ParserMethod = "parseRegWithIntInputMods"; 1426 let PredicateMethod = "isVRegWithInputMods"; 1427} 1428 1429def IntVRegInputMods : InputMods <IntVRegInputModsMatchClass> { 1430 let PrintMethod = "printOperandAndIntInputMods"; 1431} 1432 1433class PackedFPInputModsMatchClass <int opSize> : AsmOperandClass { 1434 let Name = "PackedFP"#opSize#"InputMods"; 1435 let ParserMethod = "parseRegOrImm"; 1436 let PredicateMethod = "isRegOrImm"; 1437// let PredicateMethod = "isPackedFP"#opSize#"InputMods"; 1438} 1439 1440class PackedIntInputModsMatchClass <int opSize> : AsmOperandClass { 1441 let Name = "PackedInt"#opSize#"InputMods"; 1442 let ParserMethod = "parseRegOrImm"; 1443 let PredicateMethod = "isRegOrImm"; 1444// let PredicateMethod = "isPackedInt"#opSize#"InputMods"; 1445} 1446 1447def PackedF16InputModsMatchClass : PackedFPInputModsMatchClass<16>; 1448def PackedI16InputModsMatchClass : PackedIntInputModsMatchClass<16>; 1449 1450class PackedFPInputMods <PackedFPInputModsMatchClass matchClass> : InputMods <matchClass> { 1451// let PrintMethod = "printPackedFPInputMods"; 1452} 1453 1454class PackedIntInputMods <PackedIntInputModsMatchClass matchClass> : InputMods <matchClass> { 1455 //let PrintMethod = "printPackedIntInputMods"; 1456} 1457 1458def PackedF16InputMods : PackedFPInputMods<PackedF16InputModsMatchClass>; 1459def PackedI16InputMods : PackedIntInputMods<PackedI16InputModsMatchClass>; 1460 1461//===----------------------------------------------------------------------===// 1462// Complex patterns 1463//===----------------------------------------------------------------------===// 1464 1465def DS1Addr1Offset : ComplexPattern<iPTR, 2, "SelectDS1Addr1Offset">; 1466def DS64Bit4ByteAligned : ComplexPattern<iPTR, 3, "SelectDS64Bit4ByteAligned">; 1467def DS128Bit8ByteAligned : ComplexPattern<iPTR, 3, "SelectDS128Bit8ByteAligned">; 1468 1469def MOVRELOffset : ComplexPattern<iPTR, 2, "SelectMOVRELOffset">; 1470 1471def VOP3Mods0 : ComplexPattern<untyped, 4, "SelectVOP3Mods0">; 1472def VOP3Mods : ComplexPattern<untyped, 2, "SelectVOP3Mods">; 1473def VOP3NoMods : ComplexPattern<untyped, 1, "SelectVOP3NoMods">; 1474// VOP3Mods, but the input source is known to never be NaN. 1475def VOP3Mods_nnan : ComplexPattern<fAny, 2, "SelectVOP3Mods_NNaN">; 1476 1477def VOP3OMods : ComplexPattern<untyped, 3, "SelectVOP3OMods">; 1478 1479def VOP3PMods : ComplexPattern<untyped, 2, "SelectVOP3PMods">; 1480 1481def VOP3PModsDOT : ComplexPattern<untyped, 2, "SelectVOP3PModsDOT">; 1482def DotIUVOP3PMods : ComplexPattern<untyped, 1, "SelectDotIUVOP3PMods">; 1483def WMMAOpSelVOP3PMods : ComplexPattern<untyped, 1, "SelectWMMAOpSelVOP3PMods">; 1484 1485def VOP3OpSel : ComplexPattern<untyped, 2, "SelectVOP3OpSel">; 1486 1487def VOP3OpSelMods : ComplexPattern<untyped, 2, "SelectVOP3OpSelMods">; 1488 1489def VOP3PMadMixMods : ComplexPattern<untyped, 2, "SelectVOP3PMadMixMods">; 1490 1491def VINTERPMods : ComplexPattern<untyped, 2, "SelectVINTERPMods">; 1492def VINTERPModsHi : ComplexPattern<untyped, 2, "SelectVINTERPModsHi">; 1493 1494//===----------------------------------------------------------------------===// 1495// SI assembler operands 1496//===----------------------------------------------------------------------===// 1497 1498def SIOperand { 1499 int ZERO = 0x80; 1500 int VCC = 0x6A; 1501 int FLAT_SCR = 0x68; 1502} 1503 1504// This should be kept in sync with SISrcMods enum 1505def SRCMODS { 1506 int NONE = 0; 1507 int NEG = 1; 1508 int ABS = 2; 1509 int NEG_ABS = 3; 1510 1511 int NEG_HI = ABS; 1512 int OP_SEL_0 = 4; 1513 int OP_SEL_1 = 8; 1514 int DST_OP_SEL = 8; 1515} 1516 1517def DSTCLAMP { 1518 int NONE = 0; 1519 int ENABLE = 1; 1520} 1521 1522def DSTOMOD { 1523 int NONE = 0; 1524} 1525 1526def HWREG { 1527 int MODE = 1; 1528 int STATUS = 2; 1529 int TRAPSTS = 3; 1530 int HW_ID = 4; 1531 int GPR_ALLOC = 5; 1532 int LDS_ALLOC = 6; 1533 int IB_STS = 7; 1534 int MEM_BASES = 15; 1535 int TBA_LO = 16; 1536 int TBA_HI = 17; 1537 int TMA_LO = 18; 1538 int TMA_HI = 19; 1539 int FLAT_SCR_LO = 20; 1540 int FLAT_SCR_HI = 21; 1541 int XNACK_MASK = 22; 1542 int POPS_PACKER = 25; 1543 int SHADER_CYCLES = 29; 1544} 1545 1546class getHwRegImm<int Reg, int Offset = 0, int Size = 32> { 1547 int ret = !and(!or(Reg, 1548 !shl(Offset, 6), 1549 !shl(!add(Size, -1), 11)), 65535); 1550} 1551 1552//===----------------------------------------------------------------------===// 1553// 1554// SI Instruction multiclass helpers. 1555// 1556// Instructions with _32 take 32-bit operands. 1557// Instructions with _64 take 64-bit operands. 1558// 1559// VOP_* instructions can use either a 32-bit or 64-bit encoding. The 32-bit 1560// encoding is the standard encoding, but instruction that make use of 1561// any of the instruction modifiers must use the 64-bit encoding. 1562// 1563// Instructions with _e32 use the 32-bit encoding. 1564// Instructions with _e64 use the 64-bit encoding. 1565// 1566//===----------------------------------------------------------------------===// 1567 1568class SIMCInstr <string pseudo, int subtarget> { 1569 string PseudoInstr = pseudo; 1570 int Subtarget = subtarget; 1571} 1572 1573//===----------------------------------------------------------------------===// 1574// Vector ALU classes 1575//===----------------------------------------------------------------------===// 1576 1577class getNumSrcArgs<ValueType Src0, ValueType Src1, ValueType Src2> { 1578 int ret = 1579 !if (!eq(Src0.Value, untyped.Value), 0, 1580 !if (!eq(Src1.Value, untyped.Value), 1, // VOP1 1581 !if (!eq(Src2.Value, untyped.Value), 2, // VOP2 1582 3))); // VOP3 1583} 1584 1585// Returns the register class to use for the destination of VOP[123C] 1586// instructions for the given VT. 1587class getVALUDstForVT<ValueType VT> { 1588 RegisterOperand ret = !if(!eq(VT.Size, 32), VOPDstOperand<VGPR_32>, 1589 !if(!eq(VT.Size, 128), VOPDstOperand<VReg_128>, 1590 !if(!eq(VT.Size, 64), VOPDstOperand<VReg_64>, 1591 !if(!eq(VT.Size, 16), VOPDstOperand<VGPR_32>, 1592 VOPDstS64orS32)))); // else VT == i1 1593} 1594 1595// Returns the register class to use for the destination of VOP[12C] 1596// instructions with SDWA extension 1597class getSDWADstForVT<ValueType VT> { 1598 RegisterOperand ret = !if(!eq(VT.Size, 1), 1599 SDWAVopcDst, // VOPC 1600 VOPDstOperand<VGPR_32>); // VOP1/2 32-bit dst 1601} 1602 1603// Returns the register class to use for source 0 of VOP[12C] 1604// instructions for the given VT. 1605class getVOPSrc0ForVT<ValueType VT> { 1606 bit isFP = isFloatType<VT>.ret; 1607 1608 RegisterOperand ret = 1609 !if(isFP, 1610 !if(!eq(VT.Size, 64), 1611 VSrc_f64, 1612 !if(!eq(VT.Value, f16.Value), 1613 VSrc_f16, 1614 !if(!eq(VT.Value, v2f16.Value), 1615 VSrc_v2f16, 1616 !if(!eq(VT.Value, v4f16.Value), 1617 AVSrc_64, 1618 VSrc_f32 1619 ) 1620 ) 1621 ) 1622 ), 1623 !if(!eq(VT.Size, 64), 1624 VSrc_b64, 1625 !if(!eq(VT.Value, i16.Value), 1626 VSrc_b16, 1627 !if(!eq(VT.Value, v2i16.Value), 1628 VSrc_v2b16, 1629 VSrc_b32 1630 ) 1631 ) 1632 ) 1633 ); 1634} 1635 1636class getSOPSrcForVT<ValueType VT> { 1637 RegisterOperand ret = !if(!eq(VT.Size, 64), SSrc_b64, SSrc_b32); 1638} 1639 1640// Returns the vreg register class to use for source operand given VT 1641class getVregSrcForVT<ValueType VT> { 1642 RegisterClass ret = !if(!eq(VT.Size, 128), VReg_128, 1643 !if(!eq(VT.Size, 96), VReg_96, 1644 !if(!eq(VT.Size, 64), VReg_64, 1645 !if(!eq(VT.Size, 48), VReg_64, 1646 VGPR_32)))); 1647} 1648 1649class getSDWASrcForVT <ValueType VT> { 1650 bit isFP = isFloatType<VT>.ret; 1651 RegisterOperand retFlt = !if(!eq(VT.Size, 16), SDWASrc_f16, SDWASrc_f32); 1652 RegisterOperand retInt = !if(!eq(VT.Size, 16), SDWASrc_i16, SDWASrc_i32); 1653 RegisterOperand ret = !if(isFP, retFlt, retInt); 1654} 1655 1656// Returns the register class to use for sources of VOP3 instructions for the 1657// given VT. 1658class getVOP3SrcForVT<ValueType VT> { 1659 bit isFP = isFloatType<VT>.ret; 1660 RegisterOperand ret = 1661 !if(!eq(VT.Size, 128), 1662 VSrc_128, 1663 !if(!eq(VT.Size, 64), 1664 !if(isFP, 1665 !if(!eq(VT.Value, v2f32.Value), 1666 VSrc_v2f32, 1667 VSrc_f64), 1668 !if(!eq(VT.Value, v2i32.Value), 1669 VSrc_v2b32, 1670 VSrc_b64)), 1671 !if(!eq(VT.Value, i1.Value), 1672 SSrc_i1, 1673 !if(isFP, 1674 !if(!eq(VT.Value, f16.Value), 1675 VSrc_f16, 1676 !if(!eq(VT.Value, v2f16.Value), 1677 VSrc_v2f16, 1678 !if(!eq(VT.Value, v4f16.Value), 1679 AVSrc_64, 1680 VSrc_f32 1681 ) 1682 ) 1683 ), 1684 !if(!eq(VT.Value, i16.Value), 1685 VSrc_b16, 1686 !if(!eq(VT.Value, v2i16.Value), 1687 VSrc_v2b16, 1688 VSrc_b32 1689 ) 1690 ) 1691 ) 1692 ) 1693 ) 1694 ); 1695} 1696 1697// Src2 of VOP3 DPP instructions cannot be a literal 1698class getVOP3DPPSrcForVT<ValueType VT> { 1699 bit isFP = isFloatType<VT>.ret; 1700 RegisterOperand ret = 1701 !if (!eq(VT.Value, i1.Value), SSrc_i1, 1702 !if (isFP, 1703 !if (!eq(VT.Value, f16.Value), VCSrc_f16, 1704 !if (!eq(VT.Value, v2f16.Value), VCSrc_v2f16, VCSrc_f32)), 1705 !if (!eq(VT.Value, i16.Value), VCSrc_b16, 1706 !if (!eq(VT.Value, v2i16.Value), VCSrc_v2b16, 1707 VCSrc_b32)))); 1708} 1709 1710// Float or packed int 1711class isModifierType<ValueType SrcVT> { 1712 bit ret = !or(!eq(SrcVT.Value, f16.Value), 1713 !eq(SrcVT.Value, f32.Value), 1714 !eq(SrcVT.Value, f64.Value), 1715 !eq(SrcVT.Value, v2f16.Value), 1716 !eq(SrcVT.Value, v2i16.Value), 1717 !eq(SrcVT.Value, v2f32.Value), 1718 !eq(SrcVT.Value, v2i32.Value), 1719 !eq(SrcVT.Value, v4f16.Value), 1720 !eq(SrcVT.Value, v4i16.Value), 1721 !eq(SrcVT.Value, v4f32.Value), 1722 !eq(SrcVT.Value, v4i32.Value), 1723 !eq(SrcVT.Value, v8f16.Value), 1724 !eq(SrcVT.Value, v8i16.Value), 1725 !eq(SrcVT.Value, v8f32.Value), 1726 !eq(SrcVT.Value, v8i32.Value), 1727 !eq(SrcVT.Value, v16f16.Value), 1728 !eq(SrcVT.Value, v16i16.Value)); 1729} 1730 1731// Return type of input modifiers operand for specified input operand 1732class getSrcMod <ValueType VT, bit EnableF32SrcMods> { 1733 bit isFP = isFloatType<VT>.ret; 1734 bit isPacked = isPackedType<VT>.ret; 1735 Operand ret = !if(!eq(VT.Size, 64), 1736 !if(isFP, FP64InputMods, Int64InputMods), 1737 !if(isFP, 1738 !if(!eq(VT.Value, f16.Value), 1739 FP16InputMods, 1740 FP32InputMods 1741 ), 1742 !if(EnableF32SrcMods, FP32InputMods, Int32InputMods)) 1743 ); 1744} 1745 1746class getOpSelMod <ValueType VT> { 1747 Operand ret = !if(!eq(VT.Value, f16.Value), FP16InputMods, IntOpSelMods); 1748} 1749 1750// Return type of input modifiers operand specified input operand for DPP 1751class getSrcModDPP <ValueType VT> { 1752 bit isFP = isFloatType<VT>.ret; 1753 Operand ret = !if(isFP, FPVRegInputMods, IntVRegInputMods); 1754} 1755 1756// Return type of input modifiers operand for specified input operand for DPP 1757class getSrcModVOP3DPP <ValueType VT, bit EnableF32SrcMods> { 1758 bit isFP = isFloatType<VT>.ret; 1759 bit isPacked = isPackedType<VT>.ret; 1760 Operand ret = 1761 !if (isFP, 1762 !if (!eq(VT.Value, f16.Value), FP16VCSrcInputMods, 1763 FP32VCSrcInputMods), 1764 !if (EnableF32SrcMods, FP32VCSrcInputMods, Int32VCSrcInputMods)); 1765} 1766 1767// Return type of input modifiers operand specified input operand for SDWA 1768class getSrcModSDWA <ValueType VT> { 1769 Operand ret = !if(!eq(VT.Value, f16.Value), FP16SDWAInputMods, 1770 !if(!eq(VT.Value, f32.Value), FP32SDWAInputMods, 1771 !if(!eq(VT.Value, i16.Value), Int16SDWAInputMods, 1772 Int32SDWAInputMods))); 1773} 1774 1775// Returns the input arguments for VOP[12C] instructions for the given SrcVT. 1776class getIns32 <RegisterOperand Src0RC, RegisterOperand Src1RC, int NumSrcArgs> { 1777 dag ret = !if(!eq(NumSrcArgs, 1), (ins Src0RC:$src0), // VOP1 1778 !if(!eq(NumSrcArgs, 2), (ins Src0RC:$src0, Src1RC:$src1), // VOP2 1779 (ins))); 1780} 1781 1782// Returns the input arguments for VOP3 instructions for the given SrcVT. 1783class getIns64 <RegisterOperand Src0RC, RegisterOperand Src1RC, 1784 RegisterOperand Src2RC, int NumSrcArgs, 1785 bit HasClamp, bit HasModifiers, bit HasSrc2Mods, bit HasOMod, 1786 Operand Src0Mod, Operand Src1Mod, Operand Src2Mod> { 1787 1788 dag ret = 1789 !if (!eq(NumSrcArgs, 0), 1790 // VOP1 without input operands (V_NOP, V_CLREXCP) 1791 (ins), 1792 /* else */ 1793 !if (!eq(NumSrcArgs, 1), 1794 !if (HasModifiers, 1795 // VOP1 with modifiers 1796 !if(HasOMod, 1797 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 1798 clampmod0:$clamp, omod0:$omod), 1799 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 1800 clampmod0:$clamp)) 1801 /* else */, 1802 // VOP1 without modifiers 1803 !if (HasClamp, 1804 (ins Src0RC:$src0, clampmod0:$clamp), 1805 (ins Src0RC:$src0)) 1806 /* endif */ ), 1807 !if (!eq(NumSrcArgs, 2), 1808 !if (HasModifiers, 1809 // VOP 2 with modifiers 1810 !if(HasOMod, 1811 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 1812 Src1Mod:$src1_modifiers, Src1RC:$src1, 1813 clampmod0:$clamp, omod0:$omod), 1814 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 1815 Src1Mod:$src1_modifiers, Src1RC:$src1, 1816 clampmod0:$clamp)) 1817 /* else */, 1818 // VOP2 without modifiers 1819 !if (HasClamp, 1820 (ins Src0RC:$src0, Src1RC:$src1, clampmod0:$clamp), 1821 (ins Src0RC:$src0, Src1RC:$src1)) 1822 1823 /* endif */ ) 1824 /* NumSrcArgs == 3 */, 1825 !if (HasModifiers, 1826 !if (HasSrc2Mods, 1827 // VOP3 with modifiers 1828 !if (HasOMod, 1829 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 1830 Src1Mod:$src1_modifiers, Src1RC:$src1, 1831 Src2Mod:$src2_modifiers, Src2RC:$src2, 1832 clampmod0:$clamp, omod0:$omod), 1833 !if (HasClamp, 1834 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 1835 Src1Mod:$src1_modifiers, Src1RC:$src1, 1836 Src2Mod:$src2_modifiers, Src2RC:$src2, 1837 clampmod0:$clamp), 1838 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 1839 Src1Mod:$src1_modifiers, Src1RC:$src1, 1840 Src2Mod:$src2_modifiers, Src2RC:$src2))), 1841 // VOP3 with modifiers except src2 1842 !if (HasOMod, 1843 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 1844 Src1Mod:$src1_modifiers, Src1RC:$src1, 1845 Src2RC:$src2, clampmod0:$clamp, omod0:$omod), 1846 !if (HasClamp, 1847 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 1848 Src1Mod:$src1_modifiers, Src1RC:$src1, 1849 Src2RC:$src2, clampmod0:$clamp), 1850 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 1851 Src1Mod:$src1_modifiers, Src1RC:$src1, 1852 Src2RC:$src2)))) 1853 /* else */, 1854 // VOP3 without modifiers 1855 !if (HasClamp, 1856 (ins Src0RC:$src0, Src1RC:$src1, Src2RC:$src2, clampmod0:$clamp), 1857 (ins Src0RC:$src0, Src1RC:$src1, Src2RC:$src2)) 1858 /* endif */ )))); 1859} 1860 1861class getInsVOP3Base<RegisterOperand Src0RC, RegisterOperand Src1RC, 1862 RegisterOperand Src2RC, int NumSrcArgs, 1863 bit HasClamp, bit HasModifiers, bit HasSrc2Mods, bit HasOMod, 1864 Operand Src0Mod, Operand Src1Mod, Operand Src2Mod, bit HasOpSel, 1865 bit IsVOP3P> { 1866 // getInst64 handles clamp and omod. implicit mutex between vop3p and omod 1867 dag base = getIns64 <Src0RC, Src1RC, Src2RC, NumSrcArgs, 1868 HasClamp, HasModifiers, HasSrc2Mods, HasOMod, 1869 Src0Mod, Src1Mod, Src2Mod>.ret; 1870 dag opsel = (ins op_sel0:$op_sel); 1871 dag vop3pOpsel = (ins op_sel_hi0:$op_sel_hi); 1872 dag vop3pFields = !con(!if(HasOpSel, vop3pOpsel, (ins)), (ins neg_lo0:$neg_lo, neg_hi0:$neg_hi)); 1873 1874 dag ret = !con(base, 1875 !if(HasOpSel, opsel,(ins)), 1876 !if(IsVOP3P, vop3pFields,(ins))); 1877} 1878 1879class getInsVOP3P <RegisterOperand Src0RC, RegisterOperand Src1RC, 1880 RegisterOperand Src2RC, int NumSrcArgs, bit HasClamp, bit HasOpSel, 1881 Operand Src0Mod, Operand Src1Mod, Operand Src2Mod> { 1882 dag ret = getInsVOP3Base<Src0RC, Src1RC, Src2RC, NumSrcArgs, 1883 HasClamp, 1/*HasModifiers*/, 1/*HasSrc2Mods*/, 1884 0/*HasOMod*/, Src0Mod, Src1Mod, Src2Mod, 1885 HasOpSel, 1/*IsVOP3P*/>.ret; 1886} 1887 1888class getInsVOP3OpSel <RegisterOperand Src0RC, RegisterOperand Src1RC, 1889 RegisterOperand Src2RC, int NumSrcArgs, 1890 bit HasClamp, bit HasOMod, 1891 Operand Src0Mod, Operand Src1Mod, Operand Src2Mod> { 1892 dag ret = getInsVOP3Base<Src0RC, Src1RC, 1893 Src2RC, NumSrcArgs, 1894 HasClamp, 1/*HasModifiers*/, 1/*HasSrc2Mods*/, HasOMod, 1895 Src0Mod, Src1Mod, Src2Mod, 1/*HasOpSel*/, 0>.ret; 1896} 1897 1898class getInsDPPBase <RegisterOperand OldRC, RegisterClass Src0RC, RegisterClass Src1RC, 1899 RegisterClass Src2RC, int NumSrcArgs, bit HasModifiers, 1900 Operand Src0Mod, Operand Src1Mod, Operand Src2Mod> { 1901 1902 dag ret = !if (!eq(NumSrcArgs, 0), 1903 // VOP1 without input operands (V_NOP) 1904 (ins ), 1905 !if (!eq(NumSrcArgs, 1), 1906 !if (HasModifiers, 1907 // VOP1_DPP with modifiers 1908 (ins OldRC:$old, Src0Mod:$src0_modifiers, 1909 Src0RC:$src0) 1910 /* else */, 1911 // VOP1_DPP without modifiers 1912 (ins OldRC:$old, Src0RC:$src0) 1913 /* endif */), 1914 !if (!eq(NumSrcArgs, 2), 1915 !if (HasModifiers, 1916 // VOP2_DPP with modifiers 1917 (ins OldRC:$old, 1918 Src0Mod:$src0_modifiers, Src0RC:$src0, 1919 Src1Mod:$src1_modifiers, Src1RC:$src1) 1920 /* else */, 1921 // VOP2_DPP without modifiers 1922 (ins OldRC:$old, 1923 Src0RC:$src0, Src1RC:$src1) 1924 ) 1925 /* NumSrcArgs == 3, VOP3 */, 1926 !if (HasModifiers, 1927 // VOP3_DPP with modifiers 1928 (ins OldRC:$old, 1929 Src0Mod:$src0_modifiers, Src0RC:$src0, 1930 Src1Mod:$src1_modifiers, Src1RC:$src1, 1931 Src2Mod:$src2_modifiers, Src2RC:$src2) 1932 /* else */, 1933 // VOP3_DPP without modifiers 1934 (ins OldRC:$old, 1935 Src0RC:$src0, Src1RC:$src1, 1936 Src2RC:$src2) 1937 ) 1938 /* endif */))); 1939} 1940 1941class getInsDPP <RegisterOperand OldRC, RegisterClass Src0RC, RegisterClass Src1RC, 1942 RegisterClass Src2RC, int NumSrcArgs, bit HasModifiers, 1943 Operand Src0Mod, Operand Src1Mod, Operand Src2Mod> { 1944 dag ret = !con(getInsDPPBase<OldRC, Src0RC, Src1RC, Src2RC, NumSrcArgs, 1945 HasModifiers, Src0Mod, Src1Mod, Src2Mod>.ret, 1946 (ins dpp_ctrl:$dpp_ctrl, row_mask:$row_mask, 1947 bank_mask:$bank_mask, bound_ctrl:$bound_ctrl)); 1948} 1949 1950class getInsDPP16 <RegisterOperand OldRC, RegisterClass Src0RC, RegisterClass Src1RC, 1951 RegisterClass Src2RC, int NumSrcArgs, bit HasModifiers, 1952 Operand Src0Mod, Operand Src1Mod, Operand Src2Mod> { 1953 dag ret = !con(getInsDPP<OldRC, Src0RC, Src1RC, Src2RC, NumSrcArgs, 1954 HasModifiers, Src0Mod, Src1Mod, Src2Mod>.ret, 1955 (ins FI:$fi)); 1956} 1957 1958class getInsDPP8 <RegisterOperand OldRC, RegisterClass Src0RC, RegisterClass Src1RC, 1959 RegisterClass Src2RC, int NumSrcArgs, bit HasModifiers, 1960 Operand Src0Mod, Operand Src1Mod, Operand Src2Mod> { 1961 dag ret = !con(getInsDPPBase<OldRC, Src0RC, Src1RC, Src2RC, NumSrcArgs, 1962 HasModifiers, Src0Mod, Src1Mod, Src2Mod>.ret, 1963 (ins dpp8:$dpp8, FI:$fi)); 1964} 1965 1966class getInsVOP3DPPBase<dag VOP3Base, RegisterOperand OldRC, int NumSrcArgs> { 1967 dag old = ( ins OldRC:$old ); 1968 dag base = VOP3Base; 1969 dag ret = !con( 1970 !if(!ne(NumSrcArgs, 0), old, (ins)), 1971 base 1972 ); 1973} 1974 1975class getInsVOP3DPP<dag VOP3Base, RegisterOperand OldRC, int NumSrcArgs> { 1976 dag ret = !con(getInsVOP3DPPBase<VOP3Base,OldRC,NumSrcArgs>.ret, 1977 (ins dpp_ctrl:$dpp_ctrl, row_mask:$row_mask, 1978 bank_mask:$bank_mask, bound_ctrl:$bound_ctrl)); 1979} 1980 1981class getInsVOP3DPP16<dag VOP3Base, RegisterOperand OldRC, int NumSrcArgs> { 1982 dag ret = !con(getInsVOP3DPP<VOP3Base,OldRC,NumSrcArgs>.ret, 1983 (ins FI:$fi)); 1984} 1985 1986class getInsVOP3DPP8<dag VOP3Base, RegisterOperand OldRC, int NumSrcArgs> { 1987 dag ret = !con(getInsVOP3DPPBase<VOP3Base,OldRC,NumSrcArgs>.ret, 1988 (ins dpp8:$dpp8, FI:$fi)); 1989} 1990 1991// Ins for SDWA 1992class getInsSDWA <RegisterOperand Src0RC, RegisterOperand Src1RC, int NumSrcArgs, 1993 bit HasSDWAOMod, Operand Src0Mod, Operand Src1Mod, 1994 ValueType DstVT> { 1995 1996 dag ret = !if(!eq(NumSrcArgs, 0), 1997 // VOP1 without input operands (V_NOP) 1998 (ins), 1999 !if(!eq(NumSrcArgs, 1), 2000 // VOP1 2001 !if(!not(HasSDWAOMod), 2002 // VOP1_SDWA without omod 2003 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 2004 clampmod:$clamp, 2005 dst_sel:$dst_sel, dst_unused:$dst_unused, 2006 src0_sel:$src0_sel), 2007 // VOP1_SDWA with omod 2008 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 2009 clampmod:$clamp, omod:$omod, 2010 dst_sel:$dst_sel, dst_unused:$dst_unused, 2011 src0_sel:$src0_sel)), 2012 !if(!eq(NumSrcArgs, 2), 2013 !if(!eq(DstVT.Size, 1), 2014 // VOPC_SDWA 2015 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 2016 Src1Mod:$src1_modifiers, Src1RC:$src1, 2017 clampmod:$clamp, src0_sel:$src0_sel, src1_sel:$src1_sel), 2018 // VOP2_SDWA 2019 !if(!not(HasSDWAOMod), 2020 // VOP2_SDWA without omod 2021 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 2022 Src1Mod:$src1_modifiers, Src1RC:$src1, 2023 clampmod:$clamp, 2024 dst_sel:$dst_sel, dst_unused:$dst_unused, 2025 src0_sel:$src0_sel, src1_sel:$src1_sel), 2026 // VOP2_SDWA with omod 2027 (ins Src0Mod:$src0_modifiers, Src0RC:$src0, 2028 Src1Mod:$src1_modifiers, Src1RC:$src1, 2029 clampmod:$clamp, omod:$omod, 2030 dst_sel:$dst_sel, dst_unused:$dst_unused, 2031 src0_sel:$src0_sel, src1_sel:$src1_sel))), 2032 (ins)/* endif */))); 2033} 2034 2035// Outs for DPP 2036class getOutsDPP <bit HasDst, ValueType DstVT, RegisterOperand DstRCDPP> { 2037 dag ret = !if(HasDst, 2038 !if(!eq(DstVT.Size, 1), 2039 (outs), // no dst for VOPC, we use "vcc"-token as dst in SDWA VOPC instructions 2040 (outs DstRCDPP:$vdst)), 2041 (outs)); // V_NOP 2042} 2043 2044// Outs for SDWA 2045class getOutsSDWA <bit HasDst, ValueType DstVT, RegisterOperand DstRCSDWA> { 2046 dag ret = !if(HasDst, 2047 !if(!eq(DstVT.Size, 1), 2048 (outs DstRCSDWA:$sdst), 2049 (outs DstRCSDWA:$vdst)), 2050 (outs)); // V_NOP 2051} 2052 2053// Returns the assembly string for the inputs and outputs of a VOP[12C] 2054// instruction. This does not add the _e32 suffix, so it can be reused 2055// by getAsm64. 2056class getAsm32 <bit HasDst, int NumSrcArgs, ValueType DstVT = i32> { 2057 string dst = !if(!eq(DstVT.Size, 1), "$sdst", "$vdst"); // use $sdst for VOPC 2058 string src0 = ", $src0"; 2059 string src1 = ", $src1"; 2060 string src2 = ", $src2"; 2061 string ret = !if(HasDst, dst, "") # 2062 !if(!eq(NumSrcArgs, 1), src0, "") # 2063 !if(!eq(NumSrcArgs, 2), src0#src1, "") # 2064 !if(!eq(NumSrcArgs, 3), src0#src1#src2, ""); 2065} 2066 2067class getAsmVOPDPart <int NumSrcArgs, string XorY> { 2068 string dst = "$vdst" # XorY; 2069 string src0 = ", $src0" # XorY; 2070 string src1 = ", $vsrc1" # XorY; 2071 string ret = dst # 2072 !if(!ge(NumSrcArgs, 1), src0, "") # 2073 !if(!ge(NumSrcArgs, 2), src1, ""); 2074} 2075 2076// Returns the assembly string for the inputs and outputs of a VOP3 2077// instruction. 2078class getAsm64 <bit HasDst, int NumSrcArgs, bit HasIntClamp, bit HasModifiers, 2079 bit HasOMod, ValueType DstVT = i32> { 2080 string dst = !if(!eq(DstVT.Size, 1), "$sdst", "$vdst"); // use $sdst for VOPC 2081 string src0 = !if(!eq(NumSrcArgs, 1), "$src0_modifiers", "$src0_modifiers,"); 2082 string src1 = !if(!eq(NumSrcArgs, 1), "", 2083 !if(!eq(NumSrcArgs, 2), " $src1_modifiers", 2084 " $src1_modifiers,")); 2085 string src2 = !if(!eq(NumSrcArgs, 3), " $src2_modifiers", ""); 2086 string iclamp = !if(HasIntClamp, "$clamp", ""); 2087 string ret = 2088 !if(!not(HasModifiers), 2089 getAsm32<HasDst, NumSrcArgs, DstVT>.ret # iclamp, 2090 dst#", "#src0#src1#src2#"$clamp"#!if(HasOMod, "$omod", "")); 2091} 2092 2093// Returns the assembly string for the inputs and outputs of a VOP3P 2094// instruction. 2095class getAsmVOP3P <int NumSrcArgs, bit HasModifiers, 2096 bit HasClamp, bit HasOpSel> { 2097 string dst = "$vdst"; 2098 string src0 = !if(!eq(NumSrcArgs, 1), "$src0", "$src0,"); 2099 string src1 = !if(!eq(NumSrcArgs, 1), "", 2100 !if(!eq(NumSrcArgs, 2), " $src1", 2101 " $src1,")); 2102 string src2 = !if(!eq(NumSrcArgs, 3), " $src2", ""); 2103 2104 string mods = !if(HasModifiers, "$neg_lo$neg_hi", ""); 2105 string clamp = !if(HasClamp, "$clamp", ""); 2106 string opsel = !if(HasOpSel, "$op_sel$op_sel_hi", ""); 2107 2108 // Each modifier is printed as an array of bits for each operand, so 2109 // all operands are printed as part of src0_modifiers. 2110 string ret = dst#", "#src0#src1#src2#opsel#mods#clamp; 2111} 2112 2113class getAsmVOP3OpSel <int NumSrcArgs, 2114 bit HasClamp, 2115 bit Src0HasMods, 2116 bit Src1HasMods, 2117 bit Src2HasMods> { 2118 string dst = "$vdst"; 2119 2120 string isrc0 = !if(!eq(NumSrcArgs, 1), "$src0", "$src0,"); 2121 string isrc1 = !if(!eq(NumSrcArgs, 1), "", 2122 !if(!eq(NumSrcArgs, 2), " $src1", 2123 " $src1,")); 2124 string isrc2 = !if(!eq(NumSrcArgs, 3), " $src2", ""); 2125 2126 string fsrc0 = !if(!eq(NumSrcArgs, 1), "$src0_modifiers", "$src0_modifiers,"); 2127 string fsrc1 = !if(!eq(NumSrcArgs, 1), "", 2128 !if(!eq(NumSrcArgs, 2), " $src1_modifiers", 2129 " $src1_modifiers,")); 2130 string fsrc2 = !if(!eq(NumSrcArgs, 3), " $src2_modifiers", ""); 2131 2132 string src0 = !if(Src0HasMods, fsrc0, isrc0); 2133 string src1 = !if(Src1HasMods, fsrc1, isrc1); 2134 string src2 = !if(Src2HasMods, fsrc2, isrc2); 2135 2136 string clamp = !if(HasClamp, "$clamp", ""); 2137 string omod = ""; 2138 string ret = dst#", "#src0#src1#src2#"$op_sel"#clamp#omod; 2139} 2140 2141class getAsmDPP <bit HasDst, int NumSrcArgs, bit HasModifiers, ValueType DstVT = i32> { 2142 string dst = !if(HasDst, 2143 !if(!eq(DstVT.Size, 1), 2144 "$sdst", 2145 "$vdst"), 2146 ""); // use $sdst for VOPC 2147 string src0 = !if(!eq(NumSrcArgs, 1), "$src0_modifiers", "$src0_modifiers,"); 2148 string src1 = !if(!eq(NumSrcArgs, 1), "", 2149 !if(!eq(NumSrcArgs, 2), " $src1_modifiers", 2150 " $src1_modifiers,")); 2151 string args = !if(!not(HasModifiers), 2152 getAsm32<0, NumSrcArgs, DstVT>.ret, 2153 ", "#src0#src1); 2154 string ret = dst#args#" $dpp_ctrl$row_mask$bank_mask$bound_ctrl"; 2155} 2156 2157class getAsmDPP16 <bit HasDst, int NumSrcArgs, bit HasModifiers, ValueType DstVT = i32> { 2158 string ret = getAsmDPP<HasDst, NumSrcArgs, HasModifiers, DstVT>.ret#"$fi"; 2159} 2160 2161class getAsmDPP8 <bit HasDst, int NumSrcArgs, bit HasModifiers, ValueType DstVT = i32> 2162 : getAsmDPP<HasDst, NumSrcArgs, HasModifiers, DstVT>{ 2163 let ret = dst#args#" $dpp8$fi"; 2164} 2165 2166class getAsmVOP3DPPBase <int NumSrcArgs, bit HasDst, bit HasClamp, 2167 bit HasOpSel, bit HasOMod, bit IsVOP3P, 2168 bit HasModifiers, bit Src0HasMods, 2169 bit Src1HasMods, bit Src2HasMods, ValueType DstVT = i32> { 2170 string dst = !if(HasDst, 2171 !if(!eq(DstVT.Size, 1), 2172 "$sdst", 2173 "$vdst"), 2174 ""); // use $sdst for VOPC 2175 string src0nomods = !if(!eq(NumSrcArgs, 1), "$src0", "$src0,"); 2176 string src1nomods = !if(!eq(NumSrcArgs, 1), "", 2177 !if(!eq(NumSrcArgs, 2), " $src1", 2178 " $src1,")); 2179 string src2nomods = !if(!eq(NumSrcArgs, 3), " $src2", ""); 2180 2181 string src0mods = !if(!eq(NumSrcArgs, 1), "$src0_modifiers", "$src0_modifiers,"); 2182 string src1mods = !if(!eq(NumSrcArgs, 1), "", 2183 !if(!eq(NumSrcArgs, 2), " $src1_modifiers", 2184 " $src1_modifiers,")); 2185 string src2mods = !if(!eq(NumSrcArgs, 3), " $src2_modifiers", ""); 2186 2187 string src0 = !if(Src0HasMods, src0mods, src0nomods); 2188 string src1 = !if(Src1HasMods, src1mods, src1nomods); 2189 string src2 = !if(Src2HasMods, src2mods, src2nomods); 2190 string opsel = !if(HasOpSel, "$op_sel", ""); 2191 string 3PMods = !if(IsVOP3P, 2192 !if(HasOpSel, "$op_sel_hi", "") 2193 #!if(HasModifiers, "$neg_lo$neg_hi", ""), 2194 ""); 2195 string clamp = !if(HasClamp, "$clamp", ""); 2196 string omod = !if(HasOMod, "$omod", ""); 2197 2198 string ret = dst#", "#src0#src1#src2#opsel#3PMods#clamp#omod; 2199 2200} 2201 2202class getAsmVOP3DPP<string base> { 2203 string ret = base # " $dpp_ctrl$row_mask$bank_mask$bound_ctrl"; 2204} 2205 2206class getAsmVOP3DPP16<string base> { 2207 string ret = getAsmVOP3DPP<base>.ret # "$fi"; 2208} 2209 2210class getAsmVOP3DPP8<string base> { 2211 string ret = base # " $dpp8$fi"; 2212} 2213 2214 2215class getAsmSDWA <bit HasDst, int NumSrcArgs, ValueType DstVT = i32> { 2216 string dst = !if(HasDst, 2217 !if(!eq(DstVT.Size, 1), 2218 " vcc", // use vcc token as dst for VOPC instructions 2219 "$vdst"), 2220 ""); 2221 string src0 = "$src0_modifiers"; 2222 string src1 = "$src1_modifiers"; 2223 string args = !if(!eq(NumSrcArgs, 0), 2224 "", 2225 !if(!eq(NumSrcArgs, 1), 2226 ", "#src0#"$clamp", 2227 ", "#src0#", "#src1#"$clamp" 2228 ) 2229 ); 2230 string sdwa = !if(!eq(NumSrcArgs, 0), 2231 "", 2232 !if(!eq(NumSrcArgs, 1), 2233 " $dst_sel $dst_unused $src0_sel", 2234 !if(!eq(DstVT.Size, 1), 2235 " $src0_sel $src1_sel", // No dst_sel and dst_unused for VOPC 2236 " $dst_sel $dst_unused $src0_sel $src1_sel" 2237 ) 2238 ) 2239 ); 2240 string ret = dst#args#sdwa; 2241} 2242 2243class getAsmSDWA9 <bit HasDst, bit HasOMod, int NumSrcArgs, 2244 ValueType DstVT = i32> { 2245 string dst = !if(HasDst, 2246 !if(!eq(DstVT.Size, 1), 2247 "$sdst", // VOPC 2248 "$vdst"), // VOP1/2 2249 ""); 2250 string src0 = "$src0_modifiers"; 2251 string src1 = "$src1_modifiers"; 2252 string out_mods = !if(!not(HasOMod), "$clamp", "$clamp$omod"); 2253 string args = !if(!eq(NumSrcArgs, 0), "", 2254 !if(!eq(NumSrcArgs, 1), 2255 ", "#src0, 2256 ", "#src0#", "#src1 2257 ) 2258 ); 2259 string sdwa = !if(!eq(NumSrcArgs, 0), "", 2260 !if(!eq(NumSrcArgs, 1), 2261 out_mods#" $dst_sel $dst_unused $src0_sel", 2262 !if(!eq(DstVT.Size, 1), 2263 " $src0_sel $src1_sel", // No dst_sel, dst_unused and output modifiers for VOPC 2264 out_mods#" $dst_sel $dst_unused $src0_sel $src1_sel" 2265 ) 2266 ) 2267 ); 2268 string ret = dst#args#sdwa; 2269} 2270 2271class getHas64BitOps <int NumSrcArgs, ValueType DstVT, ValueType Src0VT, 2272 ValueType Src1VT> { 2273 bit ret = !if(!eq(NumSrcArgs, 3), 2274 0, 2275 !if(!eq(DstVT.Size, 64), 2276 1, 2277 !if(!eq(Src0VT.Size, 64), 2278 1, 2279 !if(!eq(Src1VT.Size, 64), 2280 1, 2281 0 2282 ) 2283 ) 2284 ) 2285 ); 2286} 2287 2288class getHasSDWA <int NumSrcArgs, ValueType DstVT = i32, ValueType Src0VT = i32, 2289 ValueType Src1VT = i32> { 2290 bit ret = !if(!eq(NumSrcArgs, 3), 2291 0, // NumSrcArgs == 3 - No SDWA for VOP3 2292 !if(!eq(DstVT.Size, 64), 2293 0, // 64-bit dst - No SDWA for 64-bit operands 2294 !if(!eq(Src0VT.Size, 64), 2295 0, // 64-bit src0 2296 !if(!eq(Src1VT.Size, 64), 2297 0, // 64-bit src2 2298 1 2299 ) 2300 ) 2301 ) 2302 ); 2303} 2304 2305class getHasDPP <int NumSrcArgs> { 2306 bit ret = !if(!eq(NumSrcArgs, 3), 2307 0, // NumSrcArgs == 3 - No DPP for VOP3 2308 1); 2309} 2310 2311class getHasExt32BitDPP <int NumSrcArgs, ValueType DstVT = i32, ValueType Src0VT = i32, 2312 ValueType Src1VT = i32> { 2313 bit ret = !and(getHasDPP<NumSrcArgs>.ret, 2314 !not(getHas64BitOps<NumSrcArgs, DstVT, Src0VT, Src1VT>.ret)); 2315} 2316 2317class getHasExt64BitDPP <int NumSrcArgs, ValueType DstVT = i32, ValueType Src0VT = i32, 2318 ValueType Src1VT = i32> { 2319 bit ret = !and(getHasDPP<NumSrcArgs>.ret, 2320 getHas64BitOps<NumSrcArgs, DstVT, Src0VT, Src1VT>.ret); 2321} 2322 2323// Function that checks if instruction supports DPP and SDWA 2324class getHasExt <int NumSrcArgs, ValueType DstVT = i32, ValueType Src0VT = i32, 2325 ValueType Src1VT = i32> { 2326 bit ret = !or(getHasDPP<NumSrcArgs>.ret, 2327 getHasSDWA<NumSrcArgs, DstVT, Src0VT, Src1VT>.ret); 2328} 2329 2330// Return an AGPR+VGPR operand class for the given VGPR register class. 2331class getLdStRegisterOperand<RegisterClass RC> { 2332 RegisterOperand ret = 2333 !if(!eq(RC.Size, 32), AVLdSt_32, 2334 !if(!eq(RC.Size, 64), AVLdSt_64, 2335 !if(!eq(RC.Size, 96), AVLdSt_96, 2336 !if(!eq(RC.Size, 128), AVLdSt_128, 2337 !if(!eq(RC.Size, 160), AVLdSt_160, 2338 RegisterOperand<VReg_1> // invalid register 2339 ))))); 2340} 2341 2342class BitOr<bit a, bit b> { 2343 bit ret = !if(a, 1, !if(b, 1, 0)); 2344} 2345 2346class BitAnd<bit a, bit b> { 2347 bit ret = !if(a, !if(b, 1, 0), 0); 2348} 2349 2350class getHasVOP3DPP <ValueType DstVT = i32, ValueType Src0VT = i32, 2351 ValueType Src1VT = i32, ValueType Src2VT = i32> { 2352 bit ret = !if(!eq(DstVT.Size, 64), 2353 0, // 64-bit dst No DPP for 64-bit operands 2354 !if(!eq(Src0VT.Size, 64), 2355 0, // 64-bit src0 2356 !if(!eq(Src1VT.Size, 64), 2357 0, // 64-bit src1 2358 !if(!eq(Src2VT.Size, 64), 2359 0, // 64-bit src2 2360 1 2361 ) 2362 ) 2363 ) 2364 ); 2365} 2366 2367 2368def PatGenMode { 2369 int NoPattern = 0; 2370 int Pattern = 1; 2371} 2372 2373class VOPProfile <list<ValueType> _ArgVT, bit _EnableF32SrcMods = 0, 2374 bit _EnableClamp = 0> { 2375 2376 field list<ValueType> ArgVT = _ArgVT; 2377 field bit EnableF32SrcMods = _EnableF32SrcMods; 2378 field bit EnableClamp = _EnableClamp; 2379 2380 field ValueType DstVT = ArgVT[0]; 2381 field ValueType Src0VT = ArgVT[1]; 2382 field ValueType Src1VT = ArgVT[2]; 2383 field ValueType Src2VT = ArgVT[3]; 2384 field RegisterOperand DstRC = getVALUDstForVT<DstVT>.ret; 2385 field RegisterOperand DstRC64 = DstRC; 2386 field RegisterOperand DstRCDPP = getVALUDstForVT<DstVT>.ret; 2387 field RegisterOperand DstRCSDWA = getSDWADstForVT<DstVT>.ret; 2388 field RegisterOperand Src0RC32 = getVOPSrc0ForVT<Src0VT>.ret; 2389 field RegisterOperand Src1RC32 = RegisterOperand<getVregSrcForVT<Src1VT>.ret>; 2390 field RegisterOperand Src0RC64 = getVOP3SrcForVT<Src0VT>.ret; 2391 field RegisterOperand Src1RC64 = getVOP3SrcForVT<Src1VT>.ret; 2392 field RegisterOperand Src2RC64 = getVOP3SrcForVT<Src2VT>.ret; 2393 field RegisterClass Src0DPP = getVregSrcForVT<Src0VT>.ret; 2394 field RegisterClass Src1DPP = getVregSrcForVT<Src1VT>.ret; 2395 field RegisterClass Src2DPP = getVregSrcForVT<Src2VT>.ret; 2396 field RegisterOperand Src0VOP3DPP = VGPRSrc_32; 2397 field RegisterOperand Src1VOP3DPP = VGPRSrc_32; 2398 field RegisterOperand Src2VOP3DPP = getVOP3DPPSrcForVT<Src2VT>.ret; 2399 field RegisterOperand Src0SDWA = getSDWASrcForVT<Src0VT>.ret; 2400 field RegisterOperand Src1SDWA = getSDWASrcForVT<Src0VT>.ret; 2401 field Operand Src0Mod = getSrcMod<Src0VT, EnableF32SrcMods>.ret; 2402 field Operand Src1Mod = getSrcMod<Src1VT, EnableF32SrcMods>.ret; 2403 field Operand Src2Mod = getSrcMod<Src2VT, EnableF32SrcMods>.ret; 2404 field Operand Src0ModDPP = getSrcModDPP<Src0VT>.ret; 2405 field Operand Src1ModDPP = getSrcModDPP<Src1VT>.ret; 2406 field Operand Src2ModDPP = getSrcModDPP<Src2VT>.ret; 2407 field Operand Src2ModVOP3DPP = getSrcModVOP3DPP<Src2VT, EnableF32SrcMods>.ret; 2408 field Operand Src0ModSDWA = getSrcModSDWA<Src0VT>.ret; 2409 field Operand Src1ModSDWA = getSrcModSDWA<Src1VT>.ret; 2410 2411 2412 field bit HasDst = !ne(DstVT.Value, untyped.Value); 2413 field bit HasDst32 = HasDst; 2414 field bit EmitDst = HasDst; // force dst encoding, see v_movreld_b32 special case 2415 field bit EmitDstSel = EmitDst; 2416 field int NumSrcArgs = getNumSrcArgs<Src0VT, Src1VT, Src2VT>.ret; 2417 field bit HasSrc0 = !ne(Src0VT.Value, untyped.Value); 2418 field bit HasSrc1 = !ne(Src1VT.Value, untyped.Value); 2419 field bit HasSrc2 = !ne(Src2VT.Value, untyped.Value); 2420 2421 // HasSrc*FloatMods affects the SDWA encoding. We ignore EnableF32SrcMods. 2422 field bit HasSrc0FloatMods = isFloatType<Src0VT>.ret; 2423 field bit HasSrc1FloatMods = isFloatType<Src1VT>.ret; 2424 field bit HasSrc2FloatMods = isFloatType<Src2VT>.ret; 2425 2426 // HasSrc*IntMods affects the SDWA encoding. We ignore EnableF32SrcMods. 2427 field bit HasSrc0IntMods = isIntType<Src0VT>.ret; 2428 field bit HasSrc1IntMods = isIntType<Src1VT>.ret; 2429 field bit HasSrc2IntMods = isIntType<Src2VT>.ret; 2430 2431 field bit HasClamp = !or(isModifierType<Src0VT>.ret, EnableClamp); 2432 field bit HasSDWAClamp = EmitDst; 2433 field bit HasFPClamp = !and(isFloatType<DstVT>.ret, HasClamp); 2434 field bit HasIntClamp = !if(isFloatType<DstVT>.ret, 0, HasClamp); 2435 field bit HasClampLo = HasClamp; 2436 field bit HasClampHi = !and(isPackedType<DstVT>.ret, HasClamp); 2437 field bit HasHigh = 0; 2438 2439 field bit IsPacked = isPackedType<Src0VT>.ret; 2440 field bit HasOpSel = IsPacked; 2441 field bit HasOMod = !if(HasOpSel, 0, isFloatType<DstVT>.ret); 2442 field bit HasSDWAOMod = isFloatType<DstVT>.ret; 2443 2444 field bit HasModifiers = !or(isModifierType<Src0VT>.ret, 2445 isModifierType<Src1VT>.ret, 2446 isModifierType<Src2VT>.ret, 2447 HasOMod, 2448 EnableF32SrcMods); 2449 2450 field bit HasSrc0Mods = HasModifiers; 2451 field bit HasSrc1Mods = !if(HasModifiers, !or(HasSrc1FloatMods, HasSrc1IntMods), 0); 2452 field bit HasSrc2Mods = !if(HasModifiers, !or(HasSrc2FloatMods, HasSrc2IntMods), 0); 2453 2454 field bit HasExt = getHasExt<NumSrcArgs, DstVT, Src0VT, Src1VT>.ret; 2455 field bit HasExtVOP3DPP = getHasVOP3DPP<DstVT, Src0VT, Src1VT, Src2VT>.ret; 2456 field bit HasExtDPP = !if(!or(getHasDPP<NumSrcArgs>.ret, 2457 HasExtVOP3DPP), 1, 0); 2458 field bit HasExt32BitDPP = getHasExt32BitDPP<NumSrcArgs, DstVT, Src0VT, Src1VT>.ret; 2459 field bit HasExt64BitDPP = getHasExt64BitDPP<NumSrcArgs, DstVT, Src0VT, Src1VT>.ret; 2460 field bit HasExtSDWA = getHasSDWA<NumSrcArgs, DstVT, Src0VT, Src1VT>.ret; 2461 field bit HasExtSDWA9 = HasExtSDWA; 2462 field int NeedPatGen = PatGenMode.NoPattern; 2463 2464 field bit IsMAI = 0; 2465 field bit IsVOP3P = 0; 2466 field bit IsDOT = 0; 2467 field bit IsSingle = 0; 2468 field bit IsWMMA = 0; 2469 2470 field Operand Src0PackedMod = !if(HasSrc0FloatMods, PackedF16InputMods, PackedI16InputMods); 2471 field Operand Src1PackedMod = !if(HasSrc1FloatMods, PackedF16InputMods, PackedI16InputMods); 2472 field Operand Src2PackedMod = !if(HasSrc2FloatMods, PackedF16InputMods, PackedI16InputMods); 2473 2474 field dag Outs = !if(HasDst,(outs DstRC:$vdst),(outs)); 2475 2476 // VOP3b instructions are a special case with a second explicit 2477 // output. This is manually overridden for them. 2478 field dag Outs32 = Outs; 2479 field dag Outs64 = !if(HasDst,(outs DstRC64:$vdst),(outs)); 2480 field dag OutsDPP = getOutsDPP<HasDst, DstVT, DstRCDPP>.ret; 2481 field dag OutsDPP8 = getOutsDPP<HasDst, DstVT, DstRCDPP>.ret; 2482 field dag OutsVOP3DPP = OutsDPP; 2483 field dag OutsVOP3DPP8 = OutsDPP8; 2484 field dag OutsSDWA = getOutsSDWA<HasDst, DstVT, DstRCSDWA>.ret; 2485 2486 field dag Ins32 = getIns32<Src0RC32, Src1RC32, NumSrcArgs>.ret; 2487 field dag Ins64 = getIns64<Src0RC64, Src1RC64, Src2RC64, NumSrcArgs, 2488 HasIntClamp, HasModifiers, HasSrc2Mods, 2489 HasOMod, Src0Mod, Src1Mod, Src2Mod>.ret; 2490 field dag InsVOP3P = getInsVOP3P<Src0RC64, Src1RC64, Src2RC64, 2491 NumSrcArgs, HasClamp, HasOpSel, 2492 Src0PackedMod, Src1PackedMod, Src2PackedMod>.ret; 2493 field dag InsVOP3OpSel = getInsVOP3OpSel<Src0RC64, Src1RC64, Src2RC64, 2494 NumSrcArgs, HasClamp, HasOMod, 2495 getOpSelMod<Src0VT>.ret, 2496 getOpSelMod<Src1VT>.ret, 2497 getOpSelMod<Src2VT>.ret>.ret; 2498 field dag InsDPP = !if(HasExtDPP, 2499 getInsDPP<DstRCDPP, Src0DPP, Src1DPP, Src2DPP, NumSrcArgs, 2500 HasModifiers, Src0ModDPP, Src1ModDPP, Src2ModDPP>.ret, 2501 (ins)); 2502 field dag InsDPP16 = getInsDPP16<DstRCDPP, Src0DPP, Src1DPP, Src2DPP, NumSrcArgs, 2503 HasModifiers, Src0ModDPP, Src1ModDPP, Src2ModDPP>.ret; 2504 field dag InsDPP8 = getInsDPP8<DstRCDPP, Src0DPP, Src1DPP, Src2DPP, 2505 NumSrcArgs, HasModifiers, 2506 Src0ModDPP, Src1ModDPP, Src2ModDPP>.ret; 2507 field dag InsVOP3Base = getInsVOP3Base<Src0VOP3DPP, Src1VOP3DPP, 2508 Src2VOP3DPP, NumSrcArgs, HasClamp, HasModifiers, HasSrc2Mods, HasOMod, 2509 Src0ModDPP, Src1ModDPP, Src2ModVOP3DPP, HasOpSel, IsVOP3P>.ret; 2510 field dag InsVOP3DPP = getInsVOP3DPP<InsVOP3Base, DstRCDPP, NumSrcArgs>.ret; 2511 field dag InsVOP3DPP16 = getInsVOP3DPP16<InsVOP3Base, DstRCDPP, NumSrcArgs>.ret; 2512 field dag InsVOP3DPP8 = getInsVOP3DPP8<InsVOP3Base, DstRCDPP, NumSrcArgs>.ret; 2513 field dag InsSDWA = getInsSDWA<Src0SDWA, Src1SDWA, NumSrcArgs, 2514 HasSDWAOMod, Src0ModSDWA, Src1ModSDWA, 2515 DstVT>.ret; 2516 field dag InsVOPDX = (ins Src0RC32:$src0X, Src1RC32:$vsrc1X); 2517 // It is a slight misnomer to use the deferred f32 operand type for non-float 2518 // operands, but this operand type will only be used if the other dual 2519 // component is FMAAK or FMAMK 2520 field dag InsVOPDXDeferred = (ins !if(!eq(Src0VT.Size, 32), VSrc_f32_Deferred, VSrc_f16_Deferred):$src0X, VGPR_32:$vsrc1X); 2521 field dag InsVOPDY = (ins Src0RC32:$src0Y, Src1RC32:$vsrc1Y); 2522 field dag InsVOPDYDeferred = (ins !if(!eq(Src1VT.Size, 32), VSrc_f32_Deferred, VSrc_f16_Deferred):$src0Y, VGPR_32:$vsrc1Y); 2523 2524 2525 field string Asm32 = getAsm32<HasDst, NumSrcArgs, DstVT>.ret; 2526 field string Asm64 = getAsm64<HasDst, NumSrcArgs, HasIntClamp, HasModifiers, HasOMod, DstVT>.ret; 2527 field string AsmVOP3P = getAsmVOP3P<NumSrcArgs, HasModifiers, HasClamp, HasOpSel>.ret; 2528 field string AsmVOP3OpSel = getAsmVOP3OpSel<NumSrcArgs, 2529 HasClamp, 2530 HasSrc0FloatMods, 2531 HasSrc1FloatMods, 2532 HasSrc2FloatMods>.ret; 2533 field string AsmDPP = !if(HasExtDPP, 2534 getAsmDPP<HasDst, NumSrcArgs, HasModifiers, DstVT>.ret, ""); 2535 field string AsmDPP16 = getAsmDPP16<HasDst, NumSrcArgs, HasModifiers, DstVT>.ret; 2536 // DPP8 encoding has no fields for modifiers, and it is enforced by setting 2537 // the asm operand name via this HasModifiers flag 2538 field string AsmDPP8 = getAsmDPP8<HasDst, NumSrcArgs, 0 /*HasModifiers*/, DstVT>.ret; 2539 field string AsmVOP3DPPBase = getAsmVOP3DPPBase<NumSrcArgs, HasDst, HasClamp, 2540 HasOpSel, HasOMod, IsVOP3P, HasModifiers, HasModifiers, HasModifiers, 2541 HasModifiers, DstVT>.ret; 2542 field string AsmVOP3DPP = getAsmVOP3DPP<AsmVOP3DPPBase>.ret; 2543 field string AsmVOP3DPP16 = getAsmVOP3DPP16<AsmVOP3DPPBase>.ret; 2544 field string AsmVOP3DPP8 = getAsmVOP3DPP8<AsmVOP3DPPBase>.ret; 2545 field string AsmSDWA = getAsmSDWA<HasDst, NumSrcArgs, DstVT>.ret; 2546 field string AsmSDWA9 = getAsmSDWA9<HasDst, HasSDWAOMod, NumSrcArgs, DstVT>.ret; 2547 field string AsmVOPDX = getAsmVOPDPart<NumSrcArgs, "X">.ret; 2548 field string AsmVOPDY = getAsmVOPDPart<NumSrcArgs, "Y">.ret; 2549 field string TieRegDPP = "$old"; 2550} 2551 2552 class VOP_NO_EXT <VOPProfile p> : VOPProfile <p.ArgVT> { 2553 let HasExt = 0; 2554 let HasExtDPP = 0; 2555 let HasExtVOP3DPP = 0; 2556 let HasExt32BitDPP = 0; 2557 let HasExt64BitDPP = 0; 2558 let HasExtSDWA = 0; 2559 let HasExtSDWA9 = 0; 2560} 2561 2562class VOP_PAT_GEN <VOPProfile p, int mode=PatGenMode.NoPattern> : VOPProfile <p.ArgVT> { 2563 let NeedPatGen = mode; 2564} 2565def VOP_F16_F16 : VOPProfile <[f16, f16, untyped, untyped]>; 2566def VOP_F16_I16 : VOPProfile <[f16, i16, untyped, untyped]>; 2567def VOP_I16_F16 : VOPProfile <[i16, f16, untyped, untyped]>; 2568def VOP_I16_I16 : VOPProfile <[i16, i16, untyped, untyped]>; 2569 2570def VOP_F16_F16_F16 : VOPProfile <[f16, f16, f16, untyped]>; 2571def VOP_F16_F16_I16 : VOPProfile <[f16, f16, i16, untyped]>; 2572def VOP_F16_F16_I32 : VOPProfile <[f16, f16, i32, untyped]>; 2573def VOP_I16_I16_I16 : VOPProfile <[i16, i16, i16, untyped]>; 2574def VOP_I16_I16_I16_ARITH : VOPProfile <[i16, i16, i16, untyped], 0, /*EnableClamp=*/1>; 2575 2576def VOP_I16_I16_I16_I16 : VOPProfile <[i16, i16, i16, i16, untyped]>; 2577def VOP_F16_F16_F16_F16 : VOPProfile <[f16, f16, f16, f16, untyped]>; 2578 2579def VOP_I32_I16_I16_I32 : VOPProfile <[i32, i16, i16, i32, untyped]>; 2580def VOP_I32_I16 : VOPProfile <[i32, i16, untyped, untyped]>; 2581 2582def VOP_V2F16_V2F16_V2F16 : VOPProfile <[v2f16, v2f16, v2f16, untyped]>; 2583def VOP_V2I16_V2I16_V2I16 : VOPProfile <[v2i16, v2i16, v2i16, untyped]>; 2584def VOP_B32_F16_F16 : VOPProfile <[i32, f16, f16, untyped]>; 2585 2586def VOP_V2F16_V2F16_V2F16_V2F16 : VOPProfile <[v2f16, v2f16, v2f16, v2f16]>; 2587def VOP_V2I16_V2I16_V2I16_V2I16 : VOPProfile <[v2i16, v2i16, v2i16, v2i16]>; 2588def VOP_V2I16_F32_F32 : VOPProfile <[v2i16, f32, f32, untyped]>; 2589def VOP_V2I16_I32_I32 : VOPProfile <[v2i16, i32, i32, untyped]>; 2590 2591def VOP_F16_V2F16_V2F16_F16 : VOPProfile <[f16, v2f16, v2f16, f16]>; 2592def VOP_I16_V2I16_V2I16_I16 : VOPProfile <[i16, v2i16, v2i16, i16]>; 2593def VOP_F32_V2I16_V2I16_F32 : VOPProfile <[f32, v2i16, v2i16, f32]>; 2594 2595def VOP_F32_V2F16_V2F16_V2F16 : VOPProfile <[f32, v2f16, v2f16, v2f16]>; 2596 2597def VOP_NONE : VOPProfile <[untyped, untyped, untyped, untyped]>; 2598 2599def VOP_F32_F32 : VOPProfile <[f32, f32, untyped, untyped]>; 2600def VOP_F32_F64 : VOPProfile <[f32, f64, untyped, untyped]>; 2601def VOP_F32_I32 : VOPProfile <[f32, i32, untyped, untyped]>; 2602def VOP_F64_F32 : VOPProfile <[f64, f32, untyped, untyped]>; 2603def VOP_F64_F64 : VOPProfile <[f64, f64, untyped, untyped]>; 2604def VOP_F64_I32 : VOPProfile <[f64, i32, untyped, untyped]>; 2605def VOP_I32_F32 : VOPProfile <[i32, f32, untyped, untyped]>; 2606def VOP_I32_F64 : VOPProfile <[i32, f64, untyped, untyped]>; 2607def VOP_I32_I32 : VOPProfile <[i32, i32, untyped, untyped]>; 2608def VOP_F16_F32 : VOPProfile <[f16, f32, untyped, untyped]>; 2609def VOP_F32_F16 : VOPProfile <[f32, f16, untyped, untyped]>; 2610def VOP_I64_I64 : VOPProfile <[i64, i64, untyped, untyped]>; 2611 2612def VOP_F32_F32_F16 : VOPProfile <[f32, f32, f16, untyped]>; 2613def VOP_F32_F32_F32 : VOPProfile <[f32, f32, f32, untyped]>; 2614def VOP_F32_F32_I32 : VOPProfile <[f32, f32, i32, untyped]>; 2615def VOP_F64_F64_F64 : VOPProfile <[f64, f64, f64, untyped]>; 2616def VOP_F64_F64_I32 : VOPProfile <[f64, f64, i32, untyped]>; 2617def VOP_I32_F32_F32 : VOPProfile <[i32, f32, f32, untyped]>; 2618def VOP_I32_F32_I32 : VOPProfile <[i32, f32, i32, untyped]>; 2619def VOP_I32_I32_I32 : VOPProfile <[i32, i32, i32, untyped]>; 2620def VOP_I32_I32_I32_ARITH : VOPProfile <[i32, i32, i32, untyped], 0, /*EnableClamp=*/1>; 2621def VOP_V2F16_F32_F32 : VOPProfile <[v2f16, f32, f32, untyped]>; 2622def VOP_F32_F16_F16_F16 : VOPProfile <[f32, f16, f16, f16]>; 2623 2624def VOP_I64_I64_I32 : VOPProfile <[i64, i64, i32, untyped]>; 2625def VOP_I64_I32_I64 : VOPProfile <[i64, i32, i64, untyped]>; 2626def VOP_I64_I64_I64 : VOPProfile <[i64, i64, i64, untyped]>; 2627 2628def VOP_F16_F32_F16_F32 : VOPProfile <[f16, f32, f16, f32]>; 2629def VOP_F32_F32_F16_F16 : VOPProfile <[f32, f32, f16, f16]>; 2630def VOP_F32_F32_F32_F32 : VOPProfile <[f32, f32, f32, f32]>; 2631def VOP_F64_F64_F64_F64 : VOPProfile <[f64, f64, f64, f64]>; 2632def VOP_I32_I32_I32_I32 : VOPProfile <[i32, i32, i32, i32]>; 2633def VOP_I64_I32_I32_I64 : VOPProfile <[i64, i32, i32, i64]>; 2634def VOP_I32_F32_I32_I32 : VOPProfile <[i32, f32, i32, i32]>; 2635def VOP_I64_I64_I32_I64 : VOPProfile <[i64, i64, i32, i64]>; 2636def VOP_V4I32_I64_I32_V4I32 : VOPProfile <[v4i32, i64, i32, v4i32]>; 2637 2638def VOP_F32_V2F16_V2F16_F32 : VOPProfile <[f32, v2f16, v2f16, f32]>; 2639def VOP_I32_V2I16_V2I16_I32 : VOPProfile <[i32, v2i16, v2i16, i32]>; 2640 2641def VOP_V4F32_F32_F32_V4F32 : VOPProfile <[v4f32, f32, f32, v4f32]>; 2642def VOP_V16F32_F32_F32_V16F32 : VOPProfile <[v16f32, f32, f32, v16f32]>; 2643def VOP_V32F32_F32_F32_V32F32 : VOPProfile <[v32f32, f32, f32, v32f32]>; 2644def VOP_V4F32_V4F16_V4F16_V4F32 : VOPProfile <[v4f32, v4f16, v4f16, v4f32]>; 2645def VOP_V16F32_V4F16_V4F16_V16F32 : VOPProfile <[v16f32, v4f16, v4f16, v16f32]>; 2646def VOP_V32F32_V4F16_V4F16_V32F32 : VOPProfile <[v32f32, v4f16, v4f16, v32f32]>; 2647def VOP_V4F32_V2I16_V2I16_V4F32 : VOPProfile <[v4f32, v2i16, v2i16, v4f32]>; 2648def VOP_V16F32_V2I16_V2I16_V16F32 : VOPProfile <[v16f32, v2i16, v2i16, v16f32]>; 2649def VOP_V32F32_V2I16_V2I16_V32F32 : VOPProfile <[v32f32, v2i16, v2i16, v32f32]>; 2650def VOP_V4I32_I32_I32_V4I32 : VOPProfile <[v4i32, i32, i32, v4i32]>; 2651def VOP_V16I32_I32_I32_V16I32 : VOPProfile <[v16i32, i32, i32, v16i32]>; 2652def VOP_V32I32_I32_I32_V32I32 : VOPProfile <[v32i32, i32, i32, v32i32]>; 2653 2654def VOP_V4F64_F64_F64_V4F64 : VOPProfile <[v4f64, f64, f64, v4f64]>; 2655def VOP_V1F64_F64_F64_V1F64 : VOPProfile <[v1f64, f64, f64, v1f64]>; 2656 2657def VOP_V2F32_V2F32_V2F32_V2F32 : VOPProfile <[v2f32, v2f32, v2f32, v2f32]>; 2658def VOP_V2F32_V2F32_V2F32 : VOPProfile <[v2f32, v2f32, v2f32, untyped]>; 2659def VOP_V2I32_V2I32_V2I32 : VOPProfile <[v2i32, v2i32, v2i32, untyped]>; 2660def VOP_V4F32_V4I16_V4I16_V4F32 : VOPProfile <[v4f32, v4i16, v4i16, v4f32]>; 2661def VOP_V16F32_V4I16_V4I16_V16F32 : VOPProfile <[v16f32, v4i16, v4i16, v16f32]>; 2662def VOP_V32F32_V4I16_V4I16_V32F32 : VOPProfile <[v32f32, v4i16, v4i16, v32f32]>; 2663 2664def VOP_V4I32_I64_I64_V4I32 : VOPProfile <[v4i32, i64, i64, v4i32]>; 2665def VOP_V16I32_I64_I64_V16I32 : VOPProfile <[v16i32, i64, i64, v16i32]>; 2666def VOP_V4F32_V2F32_V2F32_V4F32 : VOPProfile <[v4f32, v2f32, v2f32, v4f32]>; 2667def VOP_V16F32_V2F32_V2F32_V16F32 : VOPProfile <[v16f32, v2f32, v2f32, v16f32]>; 2668 2669def VOP_V4F32_V4F16_V8F16_I32 : VOPProfile <[v4f32, v4f16, v8f16, i32]>; 2670def VOP_V16F32_V4F16_V8F16_I32 : VOPProfile <[v16f32, v4f16, v8f16, i32]>; 2671def VOP_V4F32_V4I16_V8I16_I32 : VOPProfile <[v4f32, v4i16, v8i16, i32]>; 2672def VOP_V16F32_V4I16_V8I16_I32 : VOPProfile <[v16f32, v4i16, v8i16, i32]>; 2673def VOP_V4I32_V2I32_V4I32_I32 : VOPProfile <[v4i32, v2i32, v4i32, i32]>; 2674def VOP_V16I32_V2I32_V4I32_I32 : VOPProfile <[v16i32, v2i32, v4i32, i32]>; 2675 2676class Commutable_REV <string revOp, bit isOrig> { 2677 string RevOp = revOp; 2678 bit IsOrig = isOrig; 2679} 2680 2681class AtomicNoRet <string noRetOp, bit isRet> { 2682 string NoRetOp = noRetOp; 2683 bit IsRet = isRet; 2684} 2685 2686//===----------------------------------------------------------------------===// 2687// Interpolation opcodes 2688//===----------------------------------------------------------------------===// 2689 2690class VINTRPDstOperand <RegisterClass rc> : RegisterOperand <rc, "printVINTRPDst">; 2691 2692class VINTRP_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> : 2693 VINTRPCommon <outs, ins, "", pattern>, 2694 SIMCInstr<opName, SIEncodingFamily.NONE> { 2695 let isPseudo = 1; 2696 let isCodeGenOnly = 1; 2697} 2698 2699// FIXME-GFX10: WIP. 2700class VINTRP_Real_si <bits <2> op, string opName, dag outs, dag ins, 2701 string asm, int encodingFamily> : 2702 VINTRPCommon <outs, ins, asm, []>, 2703 VINTRPe <op>, 2704 SIMCInstr<opName, encodingFamily> { 2705} 2706 2707class VINTRP_Real_vi <bits <2> op, string opName, dag outs, dag ins, 2708 string asm> : 2709 VINTRPCommon <outs, ins, asm, []>, 2710 VINTRPe_vi <op>, 2711 SIMCInstr<opName, SIEncodingFamily.VI> { 2712 let AssemblerPredicate = VIAssemblerPredicate; 2713 let DecoderNamespace = "GFX8"; 2714} 2715 2716// FIXME-GFX10: WIP. 2717multiclass VINTRP_m <bits <2> op, dag outs, dag ins, string asm, 2718 list<dag> pattern = []> { 2719 def "" : VINTRP_Pseudo <NAME, outs, ins, pattern>; 2720 2721 let AssemblerPredicate = isGFX6GFX7, DecoderNamespace = "GFX6GFX7" in { 2722 def _si : VINTRP_Real_si <op, NAME, outs, ins, asm, SIEncodingFamily.SI>; 2723 } // End AssemblerPredicate = isGFX6GFX7, DecoderNamespace = "GFX6GFX7" 2724 2725 def _vi : VINTRP_Real_vi <op, NAME, outs, ins, asm>; 2726 2727 let AssemblerPredicate = isGFX10Only, DecoderNamespace = "GFX10" in { 2728 def _gfx10 : VINTRP_Real_si<op, NAME, outs, ins, asm, SIEncodingFamily.GFX10>; 2729 } // End AssemblerPredicate = isGFX10Only, DecoderNamespace = "GFX10" 2730} 2731 2732//===----------------------------------------------------------------------===// 2733// Vector instruction mappings 2734//===----------------------------------------------------------------------===// 2735 2736// Maps an opcode in e32 form to its e64 equivalent 2737def getVOPe64 : InstrMapping { 2738 let FilterClass = "VOP"; 2739 let RowFields = ["OpName"]; 2740 let ColFields = ["Size", "VOP3"]; 2741 let KeyCol = ["4", "0"]; 2742 let ValueCols = [["8", "1"]]; 2743} 2744 2745// Maps an opcode in e64 form to its e32 equivalent 2746def getVOPe32 : InstrMapping { 2747 let FilterClass = "VOP"; 2748 let RowFields = ["OpName"]; 2749 let ColFields = ["Size", "VOP3"]; 2750 let KeyCol = ["8", "1"]; 2751 let ValueCols = [["4", "0"]]; 2752} 2753 2754// Maps ordinary instructions to their SDWA counterparts 2755def getSDWAOp : InstrMapping { 2756 let FilterClass = "VOP"; 2757 let RowFields = ["OpName"]; 2758 let ColFields = ["AsmVariantName"]; 2759 let KeyCol = ["Default"]; 2760 let ValueCols = [["SDWA"]]; 2761} 2762 2763// Maps SDWA instructions to their ordinary counterparts 2764def getBasicFromSDWAOp : InstrMapping { 2765 let FilterClass = "VOP"; 2766 let RowFields = ["OpName"]; 2767 let ColFields = ["AsmVariantName"]; 2768 let KeyCol = ["SDWA"]; 2769 let ValueCols = [["Default"]]; 2770} 2771 2772// Maps ordinary instructions to their DPP counterparts 2773def getDPPOp32 : InstrMapping { 2774 let FilterClass = "VOP"; 2775 let RowFields = ["OpName"]; 2776 let ColFields = ["AsmVariantName"]; 2777 let KeyCol = ["Default"]; 2778 let ValueCols = [["DPP"]]; 2779} 2780 2781def getDPPOp64 : InstrMapping { 2782 let FilterClass = "VOP"; 2783 let RowFields = ["OpName"]; 2784 let ColFields = ["AsmVariantName"]; 2785 let KeyCol = ["VOP3"]; 2786 let ValueCols = [["VOP3_DPP"]]; 2787} 2788 2789// Maps an commuted opcode to its original version 2790def getCommuteOrig : InstrMapping { 2791 let FilterClass = "Commutable_REV"; 2792 let RowFields = ["RevOp"]; 2793 let ColFields = ["IsOrig"]; 2794 let KeyCol = ["0"]; 2795 let ValueCols = [["1"]]; 2796} 2797 2798// Maps an original opcode to its commuted version 2799def getCommuteRev : InstrMapping { 2800 let FilterClass = "Commutable_REV"; 2801 let RowFields = ["RevOp"]; 2802 let ColFields = ["IsOrig"]; 2803 let KeyCol = ["1"]; 2804 let ValueCols = [["0"]]; 2805} 2806 2807def getMCOpcodeGen : InstrMapping { 2808 let FilterClass = "SIMCInstr"; 2809 let RowFields = ["PseudoInstr"]; 2810 let ColFields = ["Subtarget"]; 2811 let KeyCol = [!cast<string>(SIEncodingFamily.NONE)]; 2812 // These columns must be kept in sync with the SIEncodingFamily enumeration. 2813 let ValueCols = [[!cast<string>(SIEncodingFamily.SI)], 2814 [!cast<string>(SIEncodingFamily.VI)], 2815 [!cast<string>(SIEncodingFamily.SDWA)], 2816 [!cast<string>(SIEncodingFamily.SDWA9)], 2817 // GFX80 encoding is added to work around a multiple matching 2818 // issue for buffer instructions with unpacked d16 data. This 2819 // does not actually change the encoding, and thus may be 2820 // removed later. 2821 [!cast<string>(SIEncodingFamily.GFX80)], 2822 [!cast<string>(SIEncodingFamily.GFX9)], 2823 [!cast<string>(SIEncodingFamily.GFX10)], 2824 [!cast<string>(SIEncodingFamily.SDWA10)], 2825 [!cast<string>(SIEncodingFamily.GFX90A)], 2826 [!cast<string>(SIEncodingFamily.GFX940)], 2827 [!cast<string>(SIEncodingFamily.GFX11)]]; 2828} 2829 2830// Get equivalent SOPK instruction. 2831def getSOPKOp : InstrMapping { 2832 let FilterClass = "SOPKInstTable"; 2833 let RowFields = ["BaseCmpOp"]; 2834 let ColFields = ["IsSOPK"]; 2835 let KeyCol = ["0"]; 2836 let ValueCols = [["1"]]; 2837} 2838 2839def getAddr64Inst : InstrMapping { 2840 let FilterClass = "MUBUFAddr64Table"; 2841 let RowFields = ["OpName"]; 2842 let ColFields = ["IsAddr64"]; 2843 let KeyCol = ["0"]; 2844 let ValueCols = [["1"]]; 2845} 2846 2847def getIfAddr64Inst : InstrMapping { 2848 let FilterClass = "MUBUFAddr64Table"; 2849 let RowFields = ["OpName"]; 2850 let ColFields = ["IsAddr64"]; 2851 let KeyCol = ["1"]; 2852 let ValueCols = [["1"]]; 2853} 2854 2855// Maps an atomic opcode to its returnless version. 2856def getAtomicNoRetOp : InstrMapping { 2857 let FilterClass = "AtomicNoRet"; 2858 let RowFields = ["NoRetOp"]; 2859 let ColFields = ["IsRet"]; 2860 let KeyCol = ["1"]; 2861 let ValueCols = [["0"]]; 2862} 2863 2864// Maps a GLOBAL to its SADDR form. 2865def getGlobalSaddrOp : InstrMapping { 2866 let FilterClass = "GlobalSaddrTable"; 2867 let RowFields = ["SaddrOp"]; 2868 let ColFields = ["IsSaddr"]; 2869 let KeyCol = ["0"]; 2870 let ValueCols = [["1"]]; 2871} 2872 2873// Maps a GLOBAL SADDR to its VADDR form. 2874def getGlobalVaddrOp : InstrMapping { 2875 let FilterClass = "GlobalSaddrTable"; 2876 let RowFields = ["SaddrOp"]; 2877 let ColFields = ["IsSaddr"]; 2878 let KeyCol = ["1"]; 2879 let ValueCols = [["0"]]; 2880} 2881 2882// Maps a v_cmpx opcode with sdst to opcode without sdst. 2883def getVCMPXNoSDstOp : InstrMapping { 2884 let FilterClass = "VCMPXNoSDstTable"; 2885 let RowFields = ["NoSDstOp"]; 2886 let ColFields = ["HasSDst"]; 2887 let KeyCol = ["1"]; 2888 let ValueCols = [["0"]]; 2889} 2890 2891// Maps a SOPP to a SOPP with S_NOP 2892def getSOPPWithRelaxation : InstrMapping { 2893 let FilterClass = "SOPPRelaxTable"; 2894 let RowFields = ["KeyName"]; 2895 let ColFields = ["IsRelaxed"]; 2896 let KeyCol = ["0"]; 2897 let ValueCols = [["1"]]; 2898} 2899 2900// Maps flat scratch opcodes by addressing modes 2901def getFlatScratchInstSTfromSS : InstrMapping { 2902 let FilterClass = "FlatScratchInst"; 2903 let RowFields = ["SVOp"]; 2904 let ColFields = ["Mode"]; 2905 let KeyCol = ["SS"]; 2906 let ValueCols = [["ST"]]; 2907} 2908 2909def getFlatScratchInstSSfromSV : InstrMapping { 2910 let FilterClass = "FlatScratchInst"; 2911 let RowFields = ["SVOp"]; 2912 let ColFields = ["Mode"]; 2913 let KeyCol = ["SV"]; 2914 let ValueCols = [["SS"]]; 2915} 2916 2917def getFlatScratchInstSVfromSVS : InstrMapping { 2918 let FilterClass = "FlatScratchInst"; 2919 let RowFields = ["SVOp"]; 2920 let ColFields = ["Mode"]; 2921 let KeyCol = ["SVS"]; 2922 let ValueCols = [["SV"]]; 2923} 2924 2925def getFlatScratchInstSVfromSS : InstrMapping { 2926 let FilterClass = "FlatScratchInst"; 2927 let RowFields = ["SVOp"]; 2928 let ColFields = ["Mode"]; 2929 let KeyCol = ["SS"]; 2930 let ValueCols = [["SV"]]; 2931} 2932 2933def getMFMAEarlyClobberOp : InstrMapping { 2934 let FilterClass = "MFMATable"; 2935 let RowFields = ["FMAOp"]; 2936 let ColFields = ["IsMac"]; 2937 let KeyCol = ["1"]; 2938 let ValueCols = [["0"]]; 2939} 2940 2941// Maps an v_cmp instruction to its v_cmpx equivalent. 2942def getVCMPXOpFromVCMP : InstrMapping { 2943 let FilterClass = "VCMPVCMPXTable"; 2944 let RowFields = ["VCMPOp"]; 2945 let ColFields = ["IsVCMPX"]; 2946 let KeyCol = ["0"]; 2947 let ValueCols = [["1"]]; 2948} 2949 2950def VOPDComponentTable : GenericTable { 2951 let FilterClass = "VOPD_Component"; 2952 let CppTypeName = "VOPDComponentInfo"; 2953 let Fields = ["BaseVOP", "VOPDOp", "CanBeVOPDX"]; 2954 let PrimaryKey = ["BaseVOP"]; 2955 let PrimaryKeyName = "getVOPDComponentHelper"; 2956} 2957 2958def VOPDPairs : GenericTable { 2959 let FilterClass = "VOPD_Base"; 2960 let CppTypeName = "VOPDInfo"; 2961 let Fields = ["Opcode", "OpX", "OpY"]; 2962 let PrimaryKey = ["Opcode"]; 2963 let PrimaryKeyName = "getVOPDOpcodeHelper"; 2964} 2965 2966def getVOPDInfoFromComponentOpcodes : SearchIndex { 2967 let Table = VOPDPairs; 2968 let Key = ["OpX", "OpY"]; 2969} 2970 2971include "SIInstructions.td" 2972 2973include "DSInstructions.td" 2974include "MIMGInstructions.td" 2975