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