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