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