1 //===- AMDGPUBaseInfo.cpp - AMDGPU Base encoding information --------------===// 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 9 #include "AMDGPUBaseInfo.h" 10 #include "AMDGPU.h" 11 #include "AMDGPUAsmUtils.h" 12 #include "AMDKernelCodeT.h" 13 #include "MCTargetDesc/AMDGPUMCTargetDesc.h" 14 #include "llvm/BinaryFormat/ELF.h" 15 #include "llvm/IR/Attributes.h" 16 #include "llvm/IR/Constants.h" 17 #include "llvm/IR/Function.h" 18 #include "llvm/IR/GlobalValue.h" 19 #include "llvm/IR/IntrinsicsAMDGPU.h" 20 #include "llvm/IR/IntrinsicsR600.h" 21 #include "llvm/IR/LLVMContext.h" 22 #include "llvm/MC/MCInstrInfo.h" 23 #include "llvm/MC/MCRegisterInfo.h" 24 #include "llvm/MC/MCSubtargetInfo.h" 25 #include "llvm/Support/AMDHSAKernelDescriptor.h" 26 #include "llvm/Support/CommandLine.h" 27 #include "llvm/TargetParser/TargetParser.h" 28 #include <optional> 29 30 #define GET_INSTRINFO_NAMED_OPS 31 #define GET_INSTRMAP_INFO 32 #include "AMDGPUGenInstrInfo.inc" 33 34 static llvm::cl::opt<unsigned> DefaultAMDHSACodeObjectVersion( 35 "amdhsa-code-object-version", llvm::cl::Hidden, 36 llvm::cl::init(llvm::AMDGPU::AMDHSA_COV5), 37 llvm::cl::desc("Set default AMDHSA Code Object Version (module flag " 38 "or asm directive still take priority if present)")); 39 40 namespace { 41 42 /// \returns Bit mask for given bit \p Shift and bit \p Width. 43 unsigned getBitMask(unsigned Shift, unsigned Width) { 44 return ((1 << Width) - 1) << Shift; 45 } 46 47 /// Packs \p Src into \p Dst for given bit \p Shift and bit \p Width. 48 /// 49 /// \returns Packed \p Dst. 50 unsigned packBits(unsigned Src, unsigned Dst, unsigned Shift, unsigned Width) { 51 unsigned Mask = getBitMask(Shift, Width); 52 return ((Src << Shift) & Mask) | (Dst & ~Mask); 53 } 54 55 /// Unpacks bits from \p Src for given bit \p Shift and bit \p Width. 56 /// 57 /// \returns Unpacked bits. 58 unsigned unpackBits(unsigned Src, unsigned Shift, unsigned Width) { 59 return (Src & getBitMask(Shift, Width)) >> Shift; 60 } 61 62 /// \returns Vmcnt bit shift (lower bits). 63 unsigned getVmcntBitShiftLo(unsigned VersionMajor) { 64 return VersionMajor >= 11 ? 10 : 0; 65 } 66 67 /// \returns Vmcnt bit width (lower bits). 68 unsigned getVmcntBitWidthLo(unsigned VersionMajor) { 69 return VersionMajor >= 11 ? 6 : 4; 70 } 71 72 /// \returns Expcnt bit shift. 73 unsigned getExpcntBitShift(unsigned VersionMajor) { 74 return VersionMajor >= 11 ? 0 : 4; 75 } 76 77 /// \returns Expcnt bit width. 78 unsigned getExpcntBitWidth(unsigned VersionMajor) { return 3; } 79 80 /// \returns Lgkmcnt bit shift. 81 unsigned getLgkmcntBitShift(unsigned VersionMajor) { 82 return VersionMajor >= 11 ? 4 : 8; 83 } 84 85 /// \returns Lgkmcnt bit width. 86 unsigned getLgkmcntBitWidth(unsigned VersionMajor) { 87 return VersionMajor >= 10 ? 6 : 4; 88 } 89 90 /// \returns Vmcnt bit shift (higher bits). 91 unsigned getVmcntBitShiftHi(unsigned VersionMajor) { return 14; } 92 93 /// \returns Vmcnt bit width (higher bits). 94 unsigned getVmcntBitWidthHi(unsigned VersionMajor) { 95 return (VersionMajor == 9 || VersionMajor == 10) ? 2 : 0; 96 } 97 98 /// \returns Loadcnt bit width 99 unsigned getLoadcntBitWidth(unsigned VersionMajor) { 100 return VersionMajor >= 12 ? 6 : 0; 101 } 102 103 /// \returns Samplecnt bit width. 104 unsigned getSamplecntBitWidth(unsigned VersionMajor) { 105 return VersionMajor >= 12 ? 6 : 0; 106 } 107 108 /// \returns Bvhcnt bit width. 109 unsigned getBvhcntBitWidth(unsigned VersionMajor) { 110 return VersionMajor >= 12 ? 3 : 0; 111 } 112 113 /// \returns Dscnt bit width. 114 unsigned getDscntBitWidth(unsigned VersionMajor) { 115 return VersionMajor >= 12 ? 6 : 0; 116 } 117 118 /// \returns Dscnt bit shift in combined S_WAIT instructions. 119 unsigned getDscntBitShift(unsigned VersionMajor) { return 0; } 120 121 /// \returns Storecnt or Vscnt bit width, depending on VersionMajor. 122 unsigned getStorecntBitWidth(unsigned VersionMajor) { 123 return VersionMajor >= 10 ? 6 : 0; 124 } 125 126 /// \returns Kmcnt bit width. 127 unsigned getKmcntBitWidth(unsigned VersionMajor) { 128 return VersionMajor >= 12 ? 5 : 0; 129 } 130 131 /// \returns shift for Loadcnt/Storecnt in combined S_WAIT instructions. 132 unsigned getLoadcntStorecntBitShift(unsigned VersionMajor) { 133 return VersionMajor >= 12 ? 8 : 0; 134 } 135 136 /// \returns VmVsrc bit width 137 inline unsigned getVmVsrcBitWidth() { return 3; } 138 139 /// \returns VmVsrc bit shift 140 inline unsigned getVmVsrcBitShift() { return 2; } 141 142 /// \returns VaVdst bit width 143 inline unsigned getVaVdstBitWidth() { return 4; } 144 145 /// \returns VaVdst bit shift 146 inline unsigned getVaVdstBitShift() { return 12; } 147 148 /// \returns SaSdst bit width 149 inline unsigned getSaSdstBitWidth() { return 1; } 150 151 /// \returns SaSdst bit shift 152 inline unsigned getSaSdstBitShift() { return 0; } 153 154 } // end namespace anonymous 155 156 namespace llvm { 157 158 namespace AMDGPU { 159 160 /// \returns True if \p STI is AMDHSA. 161 bool isHsaAbi(const MCSubtargetInfo &STI) { 162 return STI.getTargetTriple().getOS() == Triple::AMDHSA; 163 } 164 165 unsigned getAMDHSACodeObjectVersion(const Module &M) { 166 if (auto Ver = mdconst::extract_or_null<ConstantInt>( 167 M.getModuleFlag("amdgpu_code_object_version"))) { 168 return (unsigned)Ver->getZExtValue() / 100; 169 } 170 171 return getDefaultAMDHSACodeObjectVersion(); 172 } 173 174 unsigned getDefaultAMDHSACodeObjectVersion() { 175 return DefaultAMDHSACodeObjectVersion; 176 } 177 178 uint8_t getELFABIVersion(const Triple &T, unsigned CodeObjectVersion) { 179 if (T.getOS() != Triple::AMDHSA) 180 return 0; 181 182 switch (CodeObjectVersion) { 183 case 4: 184 return ELF::ELFABIVERSION_AMDGPU_HSA_V4; 185 case 5: 186 return ELF::ELFABIVERSION_AMDGPU_HSA_V5; 187 default: 188 report_fatal_error("Unsupported AMDHSA Code Object Version " + 189 Twine(CodeObjectVersion)); 190 } 191 } 192 193 unsigned getMultigridSyncArgImplicitArgPosition(unsigned CodeObjectVersion) { 194 switch (CodeObjectVersion) { 195 case AMDHSA_COV4: 196 return 48; 197 case AMDHSA_COV5: 198 default: 199 return AMDGPU::ImplicitArg::MULTIGRID_SYNC_ARG_OFFSET; 200 } 201 } 202 203 204 // FIXME: All such magic numbers about the ABI should be in a 205 // central TD file. 206 unsigned getHostcallImplicitArgPosition(unsigned CodeObjectVersion) { 207 switch (CodeObjectVersion) { 208 case AMDHSA_COV4: 209 return 24; 210 case AMDHSA_COV5: 211 default: 212 return AMDGPU::ImplicitArg::HOSTCALL_PTR_OFFSET; 213 } 214 } 215 216 unsigned getDefaultQueueImplicitArgPosition(unsigned CodeObjectVersion) { 217 switch (CodeObjectVersion) { 218 case AMDHSA_COV4: 219 return 32; 220 case AMDHSA_COV5: 221 default: 222 return AMDGPU::ImplicitArg::DEFAULT_QUEUE_OFFSET; 223 } 224 } 225 226 unsigned getCompletionActionImplicitArgPosition(unsigned CodeObjectVersion) { 227 switch (CodeObjectVersion) { 228 case AMDHSA_COV4: 229 return 40; 230 case AMDHSA_COV5: 231 default: 232 return AMDGPU::ImplicitArg::COMPLETION_ACTION_OFFSET; 233 } 234 } 235 236 #define GET_MIMGBaseOpcodesTable_IMPL 237 #define GET_MIMGDimInfoTable_IMPL 238 #define GET_MIMGInfoTable_IMPL 239 #define GET_MIMGLZMappingTable_IMPL 240 #define GET_MIMGMIPMappingTable_IMPL 241 #define GET_MIMGBiasMappingTable_IMPL 242 #define GET_MIMGOffsetMappingTable_IMPL 243 #define GET_MIMGG16MappingTable_IMPL 244 #define GET_MAIInstInfoTable_IMPL 245 #include "AMDGPUGenSearchableTables.inc" 246 247 int getMIMGOpcode(unsigned BaseOpcode, unsigned MIMGEncoding, 248 unsigned VDataDwords, unsigned VAddrDwords) { 249 const MIMGInfo *Info = getMIMGOpcodeHelper(BaseOpcode, MIMGEncoding, 250 VDataDwords, VAddrDwords); 251 return Info ? Info->Opcode : -1; 252 } 253 254 const MIMGBaseOpcodeInfo *getMIMGBaseOpcode(unsigned Opc) { 255 const MIMGInfo *Info = getMIMGInfo(Opc); 256 return Info ? getMIMGBaseOpcodeInfo(Info->BaseOpcode) : nullptr; 257 } 258 259 int getMaskedMIMGOp(unsigned Opc, unsigned NewChannels) { 260 const MIMGInfo *OrigInfo = getMIMGInfo(Opc); 261 const MIMGInfo *NewInfo = 262 getMIMGOpcodeHelper(OrigInfo->BaseOpcode, OrigInfo->MIMGEncoding, 263 NewChannels, OrigInfo->VAddrDwords); 264 return NewInfo ? NewInfo->Opcode : -1; 265 } 266 267 unsigned getAddrSizeMIMGOp(const MIMGBaseOpcodeInfo *BaseOpcode, 268 const MIMGDimInfo *Dim, bool IsA16, 269 bool IsG16Supported) { 270 unsigned AddrWords = BaseOpcode->NumExtraArgs; 271 unsigned AddrComponents = (BaseOpcode->Coordinates ? Dim->NumCoords : 0) + 272 (BaseOpcode->LodOrClampOrMip ? 1 : 0); 273 if (IsA16) 274 AddrWords += divideCeil(AddrComponents, 2); 275 else 276 AddrWords += AddrComponents; 277 278 // Note: For subtargets that support A16 but not G16, enabling A16 also 279 // enables 16 bit gradients. 280 // For subtargets that support A16 (operand) and G16 (done with a different 281 // instruction encoding), they are independent. 282 283 if (BaseOpcode->Gradients) { 284 if ((IsA16 && !IsG16Supported) || BaseOpcode->G16) 285 // There are two gradients per coordinate, we pack them separately. 286 // For the 3d case, 287 // we get (dy/du, dx/du) (-, dz/du) (dy/dv, dx/dv) (-, dz/dv) 288 AddrWords += alignTo<2>(Dim->NumGradients / 2); 289 else 290 AddrWords += Dim->NumGradients; 291 } 292 return AddrWords; 293 } 294 295 struct MUBUFInfo { 296 uint16_t Opcode; 297 uint16_t BaseOpcode; 298 uint8_t elements; 299 bool has_vaddr; 300 bool has_srsrc; 301 bool has_soffset; 302 bool IsBufferInv; 303 }; 304 305 struct MTBUFInfo { 306 uint16_t Opcode; 307 uint16_t BaseOpcode; 308 uint8_t elements; 309 bool has_vaddr; 310 bool has_srsrc; 311 bool has_soffset; 312 }; 313 314 struct SMInfo { 315 uint16_t Opcode; 316 bool IsBuffer; 317 }; 318 319 struct VOPInfo { 320 uint16_t Opcode; 321 bool IsSingle; 322 }; 323 324 struct VOPC64DPPInfo { 325 uint16_t Opcode; 326 }; 327 328 struct VOPDComponentInfo { 329 uint16_t BaseVOP; 330 uint16_t VOPDOp; 331 bool CanBeVOPDX; 332 }; 333 334 struct VOPDInfo { 335 uint16_t Opcode; 336 uint16_t OpX; 337 uint16_t OpY; 338 uint16_t Subtarget; 339 }; 340 341 struct VOPTrue16Info { 342 uint16_t Opcode; 343 bool IsTrue16; 344 }; 345 346 #define GET_MTBUFInfoTable_DECL 347 #define GET_MTBUFInfoTable_IMPL 348 #define GET_MUBUFInfoTable_DECL 349 #define GET_MUBUFInfoTable_IMPL 350 #define GET_SMInfoTable_DECL 351 #define GET_SMInfoTable_IMPL 352 #define GET_VOP1InfoTable_DECL 353 #define GET_VOP1InfoTable_IMPL 354 #define GET_VOP2InfoTable_DECL 355 #define GET_VOP2InfoTable_IMPL 356 #define GET_VOP3InfoTable_DECL 357 #define GET_VOP3InfoTable_IMPL 358 #define GET_VOPC64DPPTable_DECL 359 #define GET_VOPC64DPPTable_IMPL 360 #define GET_VOPC64DPP8Table_DECL 361 #define GET_VOPC64DPP8Table_IMPL 362 #define GET_VOPDComponentTable_DECL 363 #define GET_VOPDComponentTable_IMPL 364 #define GET_VOPDPairs_DECL 365 #define GET_VOPDPairs_IMPL 366 #define GET_VOPTrue16Table_DECL 367 #define GET_VOPTrue16Table_IMPL 368 #define GET_WMMAOpcode2AddrMappingTable_DECL 369 #define GET_WMMAOpcode2AddrMappingTable_IMPL 370 #define GET_WMMAOpcode3AddrMappingTable_DECL 371 #define GET_WMMAOpcode3AddrMappingTable_IMPL 372 #include "AMDGPUGenSearchableTables.inc" 373 374 int getMTBUFBaseOpcode(unsigned Opc) { 375 const MTBUFInfo *Info = getMTBUFInfoFromOpcode(Opc); 376 return Info ? Info->BaseOpcode : -1; 377 } 378 379 int getMTBUFOpcode(unsigned BaseOpc, unsigned Elements) { 380 const MTBUFInfo *Info = getMTBUFInfoFromBaseOpcodeAndElements(BaseOpc, Elements); 381 return Info ? Info->Opcode : -1; 382 } 383 384 int getMTBUFElements(unsigned Opc) { 385 const MTBUFInfo *Info = getMTBUFOpcodeHelper(Opc); 386 return Info ? Info->elements : 0; 387 } 388 389 bool getMTBUFHasVAddr(unsigned Opc) { 390 const MTBUFInfo *Info = getMTBUFOpcodeHelper(Opc); 391 return Info ? Info->has_vaddr : false; 392 } 393 394 bool getMTBUFHasSrsrc(unsigned Opc) { 395 const MTBUFInfo *Info = getMTBUFOpcodeHelper(Opc); 396 return Info ? Info->has_srsrc : false; 397 } 398 399 bool getMTBUFHasSoffset(unsigned Opc) { 400 const MTBUFInfo *Info = getMTBUFOpcodeHelper(Opc); 401 return Info ? Info->has_soffset : false; 402 } 403 404 int getMUBUFBaseOpcode(unsigned Opc) { 405 const MUBUFInfo *Info = getMUBUFInfoFromOpcode(Opc); 406 return Info ? Info->BaseOpcode : -1; 407 } 408 409 int getMUBUFOpcode(unsigned BaseOpc, unsigned Elements) { 410 const MUBUFInfo *Info = getMUBUFInfoFromBaseOpcodeAndElements(BaseOpc, Elements); 411 return Info ? Info->Opcode : -1; 412 } 413 414 int getMUBUFElements(unsigned Opc) { 415 const MUBUFInfo *Info = getMUBUFOpcodeHelper(Opc); 416 return Info ? Info->elements : 0; 417 } 418 419 bool getMUBUFHasVAddr(unsigned Opc) { 420 const MUBUFInfo *Info = getMUBUFOpcodeHelper(Opc); 421 return Info ? Info->has_vaddr : false; 422 } 423 424 bool getMUBUFHasSrsrc(unsigned Opc) { 425 const MUBUFInfo *Info = getMUBUFOpcodeHelper(Opc); 426 return Info ? Info->has_srsrc : false; 427 } 428 429 bool getMUBUFHasSoffset(unsigned Opc) { 430 const MUBUFInfo *Info = getMUBUFOpcodeHelper(Opc); 431 return Info ? Info->has_soffset : false; 432 } 433 434 bool getMUBUFIsBufferInv(unsigned Opc) { 435 const MUBUFInfo *Info = getMUBUFOpcodeHelper(Opc); 436 return Info ? Info->IsBufferInv : false; 437 } 438 439 bool getSMEMIsBuffer(unsigned Opc) { 440 const SMInfo *Info = getSMEMOpcodeHelper(Opc); 441 return Info ? Info->IsBuffer : false; 442 } 443 444 bool getVOP1IsSingle(unsigned Opc) { 445 const VOPInfo *Info = getVOP1OpcodeHelper(Opc); 446 return Info ? Info->IsSingle : false; 447 } 448 449 bool getVOP2IsSingle(unsigned Opc) { 450 const VOPInfo *Info = getVOP2OpcodeHelper(Opc); 451 return Info ? Info->IsSingle : false; 452 } 453 454 bool getVOP3IsSingle(unsigned Opc) { 455 const VOPInfo *Info = getVOP3OpcodeHelper(Opc); 456 return Info ? Info->IsSingle : false; 457 } 458 459 bool isVOPC64DPP(unsigned Opc) { 460 return isVOPC64DPPOpcodeHelper(Opc) || isVOPC64DPP8OpcodeHelper(Opc); 461 } 462 463 bool getMAIIsDGEMM(unsigned Opc) { 464 const MAIInstInfo *Info = getMAIInstInfoHelper(Opc); 465 return Info ? Info->is_dgemm : false; 466 } 467 468 bool getMAIIsGFX940XDL(unsigned Opc) { 469 const MAIInstInfo *Info = getMAIInstInfoHelper(Opc); 470 return Info ? Info->is_gfx940_xdl : false; 471 } 472 473 unsigned getVOPDEncodingFamily(const MCSubtargetInfo &ST) { 474 if (ST.hasFeature(AMDGPU::FeatureGFX12Insts)) 475 return SIEncodingFamily::GFX12; 476 if (ST.hasFeature(AMDGPU::FeatureGFX11Insts)) 477 return SIEncodingFamily::GFX11; 478 llvm_unreachable("Subtarget generation does not support VOPD!"); 479 } 480 481 CanBeVOPD getCanBeVOPD(unsigned Opc) { 482 const VOPDComponentInfo *Info = getVOPDComponentHelper(Opc); 483 if (Info) 484 return {Info->CanBeVOPDX, true}; 485 else 486 return {false, false}; 487 } 488 489 unsigned getVOPDOpcode(unsigned Opc) { 490 const VOPDComponentInfo *Info = getVOPDComponentHelper(Opc); 491 return Info ? Info->VOPDOp : ~0u; 492 } 493 494 bool isVOPD(unsigned Opc) { 495 return AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::src0X); 496 } 497 498 bool isMAC(unsigned Opc) { 499 return Opc == AMDGPU::V_MAC_F32_e64_gfx6_gfx7 || 500 Opc == AMDGPU::V_MAC_F32_e64_gfx10 || 501 Opc == AMDGPU::V_MAC_F32_e64_vi || 502 Opc == AMDGPU::V_MAC_LEGACY_F32_e64_gfx6_gfx7 || 503 Opc == AMDGPU::V_MAC_LEGACY_F32_e64_gfx10 || 504 Opc == AMDGPU::V_MAC_F16_e64_vi || 505 Opc == AMDGPU::V_FMAC_F64_e64_gfx90a || 506 Opc == AMDGPU::V_FMAC_F32_e64_gfx10 || 507 Opc == AMDGPU::V_FMAC_F32_e64_gfx11 || 508 Opc == AMDGPU::V_FMAC_F32_e64_gfx12 || 509 Opc == AMDGPU::V_FMAC_F32_e64_vi || 510 Opc == AMDGPU::V_FMAC_LEGACY_F32_e64_gfx10 || 511 Opc == AMDGPU::V_FMAC_DX9_ZERO_F32_e64_gfx11 || 512 Opc == AMDGPU::V_FMAC_F16_e64_gfx10 || 513 Opc == AMDGPU::V_FMAC_F16_t16_e64_gfx11 || 514 Opc == AMDGPU::V_FMAC_F16_t16_e64_gfx12 || 515 Opc == AMDGPU::V_DOT2C_F32_F16_e64_vi || 516 Opc == AMDGPU::V_DOT2C_I32_I16_e64_vi || 517 Opc == AMDGPU::V_DOT4C_I32_I8_e64_vi || 518 Opc == AMDGPU::V_DOT8C_I32_I4_e64_vi; 519 } 520 521 bool isPermlane16(unsigned Opc) { 522 return Opc == AMDGPU::V_PERMLANE16_B32_gfx10 || 523 Opc == AMDGPU::V_PERMLANEX16_B32_gfx10 || 524 Opc == AMDGPU::V_PERMLANE16_B32_e64_gfx11 || 525 Opc == AMDGPU::V_PERMLANEX16_B32_e64_gfx11 || 526 Opc == AMDGPU::V_PERMLANE16_B32_e64_gfx12 || 527 Opc == AMDGPU::V_PERMLANEX16_B32_e64_gfx12 || 528 Opc == AMDGPU::V_PERMLANE16_VAR_B32_e64_gfx12 || 529 Opc == AMDGPU::V_PERMLANEX16_VAR_B32_e64_gfx12; 530 } 531 532 bool isGenericAtomic(unsigned Opc) { 533 return Opc == AMDGPU::G_AMDGPU_ATOMIC_FMIN || 534 Opc == AMDGPU::G_AMDGPU_ATOMIC_FMAX || 535 Opc == AMDGPU::G_AMDGPU_BUFFER_ATOMIC_SWAP || 536 Opc == AMDGPU::G_AMDGPU_BUFFER_ATOMIC_ADD || 537 Opc == AMDGPU::G_AMDGPU_BUFFER_ATOMIC_SUB || 538 Opc == AMDGPU::G_AMDGPU_BUFFER_ATOMIC_SMIN || 539 Opc == AMDGPU::G_AMDGPU_BUFFER_ATOMIC_UMIN || 540 Opc == AMDGPU::G_AMDGPU_BUFFER_ATOMIC_SMAX || 541 Opc == AMDGPU::G_AMDGPU_BUFFER_ATOMIC_UMAX || 542 Opc == AMDGPU::G_AMDGPU_BUFFER_ATOMIC_AND || 543 Opc == AMDGPU::G_AMDGPU_BUFFER_ATOMIC_OR || 544 Opc == AMDGPU::G_AMDGPU_BUFFER_ATOMIC_XOR || 545 Opc == AMDGPU::G_AMDGPU_BUFFER_ATOMIC_INC || 546 Opc == AMDGPU::G_AMDGPU_BUFFER_ATOMIC_DEC || 547 Opc == AMDGPU::G_AMDGPU_BUFFER_ATOMIC_FADD || 548 Opc == AMDGPU::G_AMDGPU_BUFFER_ATOMIC_FMIN || 549 Opc == AMDGPU::G_AMDGPU_BUFFER_ATOMIC_FMAX || 550 Opc == AMDGPU::G_AMDGPU_BUFFER_ATOMIC_CMPSWAP || 551 Opc == AMDGPU::G_AMDGPU_ATOMIC_CMPXCHG; 552 } 553 554 bool isTrue16Inst(unsigned Opc) { 555 const VOPTrue16Info *Info = getTrue16OpcodeHelper(Opc); 556 return Info ? Info->IsTrue16 : false; 557 } 558 559 unsigned mapWMMA2AddrTo3AddrOpcode(unsigned Opc) { 560 const WMMAOpcodeMappingInfo *Info = getWMMAMappingInfoFrom2AddrOpcode(Opc); 561 return Info ? Info->Opcode3Addr : ~0u; 562 } 563 564 unsigned mapWMMA3AddrTo2AddrOpcode(unsigned Opc) { 565 const WMMAOpcodeMappingInfo *Info = getWMMAMappingInfoFrom3AddrOpcode(Opc); 566 return Info ? Info->Opcode2Addr : ~0u; 567 } 568 569 // Wrapper for Tablegen'd function. enum Subtarget is not defined in any 570 // header files, so we need to wrap it in a function that takes unsigned 571 // instead. 572 int getMCOpcode(uint16_t Opcode, unsigned Gen) { 573 return getMCOpcodeGen(Opcode, static_cast<Subtarget>(Gen)); 574 } 575 576 int getVOPDFull(unsigned OpX, unsigned OpY, unsigned EncodingFamily) { 577 const VOPDInfo *Info = 578 getVOPDInfoFromComponentOpcodes(OpX, OpY, EncodingFamily); 579 return Info ? Info->Opcode : -1; 580 } 581 582 std::pair<unsigned, unsigned> getVOPDComponents(unsigned VOPDOpcode) { 583 const VOPDInfo *Info = getVOPDOpcodeHelper(VOPDOpcode); 584 assert(Info); 585 auto OpX = getVOPDBaseFromComponent(Info->OpX); 586 auto OpY = getVOPDBaseFromComponent(Info->OpY); 587 assert(OpX && OpY); 588 return {OpX->BaseVOP, OpY->BaseVOP}; 589 } 590 591 namespace VOPD { 592 593 ComponentProps::ComponentProps(const MCInstrDesc &OpDesc) { 594 assert(OpDesc.getNumDefs() == Component::DST_NUM); 595 596 assert(OpDesc.getOperandConstraint(Component::SRC0, MCOI::TIED_TO) == -1); 597 assert(OpDesc.getOperandConstraint(Component::SRC1, MCOI::TIED_TO) == -1); 598 auto TiedIdx = OpDesc.getOperandConstraint(Component::SRC2, MCOI::TIED_TO); 599 assert(TiedIdx == -1 || TiedIdx == Component::DST); 600 HasSrc2Acc = TiedIdx != -1; 601 602 SrcOperandsNum = OpDesc.getNumOperands() - OpDesc.getNumDefs(); 603 assert(SrcOperandsNum <= Component::MAX_SRC_NUM); 604 605 auto OperandsNum = OpDesc.getNumOperands(); 606 unsigned CompOprIdx; 607 for (CompOprIdx = Component::SRC1; CompOprIdx < OperandsNum; ++CompOprIdx) { 608 if (OpDesc.operands()[CompOprIdx].OperandType == AMDGPU::OPERAND_KIMM32) { 609 MandatoryLiteralIdx = CompOprIdx; 610 break; 611 } 612 } 613 } 614 615 unsigned ComponentInfo::getIndexInParsedOperands(unsigned CompOprIdx) const { 616 assert(CompOprIdx < Component::MAX_OPR_NUM); 617 618 if (CompOprIdx == Component::DST) 619 return getIndexOfDstInParsedOperands(); 620 621 auto CompSrcIdx = CompOprIdx - Component::DST_NUM; 622 if (CompSrcIdx < getCompParsedSrcOperandsNum()) 623 return getIndexOfSrcInParsedOperands(CompSrcIdx); 624 625 // The specified operand does not exist. 626 return 0; 627 } 628 629 std::optional<unsigned> InstInfo::getInvalidCompOperandIndex( 630 std::function<unsigned(unsigned, unsigned)> GetRegIdx, bool SkipSrc) const { 631 632 auto OpXRegs = getRegIndices(ComponentIndex::X, GetRegIdx); 633 auto OpYRegs = getRegIndices(ComponentIndex::Y, GetRegIdx); 634 635 const unsigned CompOprNum = 636 SkipSrc ? Component::DST_NUM : Component::MAX_OPR_NUM; 637 unsigned CompOprIdx; 638 for (CompOprIdx = 0; CompOprIdx < CompOprNum; ++CompOprIdx) { 639 unsigned BanksMasks = VOPD_VGPR_BANK_MASKS[CompOprIdx]; 640 if (OpXRegs[CompOprIdx] && OpYRegs[CompOprIdx] && 641 ((OpXRegs[CompOprIdx] & BanksMasks) == 642 (OpYRegs[CompOprIdx] & BanksMasks))) 643 return CompOprIdx; 644 } 645 646 return {}; 647 } 648 649 // Return an array of VGPR registers [DST,SRC0,SRC1,SRC2] used 650 // by the specified component. If an operand is unused 651 // or is not a VGPR, the corresponding value is 0. 652 // 653 // GetRegIdx(Component, MCOperandIdx) must return a VGPR register index 654 // for the specified component and MC operand. The callback must return 0 655 // if the operand is not a register or not a VGPR. 656 InstInfo::RegIndices InstInfo::getRegIndices( 657 unsigned CompIdx, 658 std::function<unsigned(unsigned, unsigned)> GetRegIdx) const { 659 assert(CompIdx < COMPONENTS_NUM); 660 661 const auto &Comp = CompInfo[CompIdx]; 662 InstInfo::RegIndices RegIndices; 663 664 RegIndices[DST] = GetRegIdx(CompIdx, Comp.getIndexOfDstInMCOperands()); 665 666 for (unsigned CompOprIdx : {SRC0, SRC1, SRC2}) { 667 unsigned CompSrcIdx = CompOprIdx - DST_NUM; 668 RegIndices[CompOprIdx] = 669 Comp.hasRegSrcOperand(CompSrcIdx) 670 ? GetRegIdx(CompIdx, Comp.getIndexOfSrcInMCOperands(CompSrcIdx)) 671 : 0; 672 } 673 return RegIndices; 674 } 675 676 } // namespace VOPD 677 678 VOPD::InstInfo getVOPDInstInfo(const MCInstrDesc &OpX, const MCInstrDesc &OpY) { 679 return VOPD::InstInfo(OpX, OpY); 680 } 681 682 VOPD::InstInfo getVOPDInstInfo(unsigned VOPDOpcode, 683 const MCInstrInfo *InstrInfo) { 684 auto [OpX, OpY] = getVOPDComponents(VOPDOpcode); 685 const auto &OpXDesc = InstrInfo->get(OpX); 686 const auto &OpYDesc = InstrInfo->get(OpY); 687 VOPD::ComponentInfo OpXInfo(OpXDesc, VOPD::ComponentKind::COMPONENT_X); 688 VOPD::ComponentInfo OpYInfo(OpYDesc, OpXInfo); 689 return VOPD::InstInfo(OpXInfo, OpYInfo); 690 } 691 692 namespace IsaInfo { 693 694 AMDGPUTargetID::AMDGPUTargetID(const MCSubtargetInfo &STI) 695 : STI(STI), XnackSetting(TargetIDSetting::Any), 696 SramEccSetting(TargetIDSetting::Any) { 697 if (!STI.getFeatureBits().test(FeatureSupportsXNACK)) 698 XnackSetting = TargetIDSetting::Unsupported; 699 if (!STI.getFeatureBits().test(FeatureSupportsSRAMECC)) 700 SramEccSetting = TargetIDSetting::Unsupported; 701 } 702 703 void AMDGPUTargetID::setTargetIDFromFeaturesString(StringRef FS) { 704 // Check if xnack or sramecc is explicitly enabled or disabled. In the 705 // absence of the target features we assume we must generate code that can run 706 // in any environment. 707 SubtargetFeatures Features(FS); 708 std::optional<bool> XnackRequested; 709 std::optional<bool> SramEccRequested; 710 711 for (const std::string &Feature : Features.getFeatures()) { 712 if (Feature == "+xnack") 713 XnackRequested = true; 714 else if (Feature == "-xnack") 715 XnackRequested = false; 716 else if (Feature == "+sramecc") 717 SramEccRequested = true; 718 else if (Feature == "-sramecc") 719 SramEccRequested = false; 720 } 721 722 bool XnackSupported = isXnackSupported(); 723 bool SramEccSupported = isSramEccSupported(); 724 725 if (XnackRequested) { 726 if (XnackSupported) { 727 XnackSetting = 728 *XnackRequested ? TargetIDSetting::On : TargetIDSetting::Off; 729 } else { 730 // If a specific xnack setting was requested and this GPU does not support 731 // xnack emit a warning. Setting will remain set to "Unsupported". 732 if (*XnackRequested) { 733 errs() << "warning: xnack 'On' was requested for a processor that does " 734 "not support it!\n"; 735 } else { 736 errs() << "warning: xnack 'Off' was requested for a processor that " 737 "does not support it!\n"; 738 } 739 } 740 } 741 742 if (SramEccRequested) { 743 if (SramEccSupported) { 744 SramEccSetting = 745 *SramEccRequested ? TargetIDSetting::On : TargetIDSetting::Off; 746 } else { 747 // If a specific sramecc setting was requested and this GPU does not 748 // support sramecc emit a warning. Setting will remain set to 749 // "Unsupported". 750 if (*SramEccRequested) { 751 errs() << "warning: sramecc 'On' was requested for a processor that " 752 "does not support it!\n"; 753 } else { 754 errs() << "warning: sramecc 'Off' was requested for a processor that " 755 "does not support it!\n"; 756 } 757 } 758 } 759 } 760 761 static TargetIDSetting 762 getTargetIDSettingFromFeatureString(StringRef FeatureString) { 763 if (FeatureString.ends_with("-")) 764 return TargetIDSetting::Off; 765 if (FeatureString.ends_with("+")) 766 return TargetIDSetting::On; 767 768 llvm_unreachable("Malformed feature string"); 769 } 770 771 void AMDGPUTargetID::setTargetIDFromTargetIDStream(StringRef TargetID) { 772 SmallVector<StringRef, 3> TargetIDSplit; 773 TargetID.split(TargetIDSplit, ':'); 774 775 for (const auto &FeatureString : TargetIDSplit) { 776 if (FeatureString.starts_with("xnack")) 777 XnackSetting = getTargetIDSettingFromFeatureString(FeatureString); 778 if (FeatureString.starts_with("sramecc")) 779 SramEccSetting = getTargetIDSettingFromFeatureString(FeatureString); 780 } 781 } 782 783 std::string AMDGPUTargetID::toString() const { 784 std::string StringRep; 785 raw_string_ostream StreamRep(StringRep); 786 787 auto TargetTriple = STI.getTargetTriple(); 788 auto Version = getIsaVersion(STI.getCPU()); 789 790 StreamRep << TargetTriple.getArchName() << '-' 791 << TargetTriple.getVendorName() << '-' 792 << TargetTriple.getOSName() << '-' 793 << TargetTriple.getEnvironmentName() << '-'; 794 795 std::string Processor; 796 // TODO: Following else statement is present here because we used various 797 // alias names for GPUs up until GFX9 (e.g. 'fiji' is same as 'gfx803'). 798 // Remove once all aliases are removed from GCNProcessors.td. 799 if (Version.Major >= 9) 800 Processor = STI.getCPU().str(); 801 else 802 Processor = (Twine("gfx") + Twine(Version.Major) + Twine(Version.Minor) + 803 Twine(Version.Stepping)) 804 .str(); 805 806 std::string Features; 807 if (STI.getTargetTriple().getOS() == Triple::AMDHSA) { 808 // sramecc. 809 if (getSramEccSetting() == TargetIDSetting::Off) 810 Features += ":sramecc-"; 811 else if (getSramEccSetting() == TargetIDSetting::On) 812 Features += ":sramecc+"; 813 // xnack. 814 if (getXnackSetting() == TargetIDSetting::Off) 815 Features += ":xnack-"; 816 else if (getXnackSetting() == TargetIDSetting::On) 817 Features += ":xnack+"; 818 } 819 820 StreamRep << Processor << Features; 821 822 StreamRep.flush(); 823 return StringRep; 824 } 825 826 unsigned getWavefrontSize(const MCSubtargetInfo *STI) { 827 if (STI->getFeatureBits().test(FeatureWavefrontSize16)) 828 return 16; 829 if (STI->getFeatureBits().test(FeatureWavefrontSize32)) 830 return 32; 831 832 return 64; 833 } 834 835 unsigned getLocalMemorySize(const MCSubtargetInfo *STI) { 836 unsigned BytesPerCU = 0; 837 if (STI->getFeatureBits().test(FeatureLocalMemorySize32768)) 838 BytesPerCU = 32768; 839 if (STI->getFeatureBits().test(FeatureLocalMemorySize65536)) 840 BytesPerCU = 65536; 841 842 // "Per CU" really means "per whatever functional block the waves of a 843 // workgroup must share". So the effective local memory size is doubled in 844 // WGP mode on gfx10. 845 if (isGFX10Plus(*STI) && !STI->getFeatureBits().test(FeatureCuMode)) 846 BytesPerCU *= 2; 847 848 return BytesPerCU; 849 } 850 851 unsigned getAddressableLocalMemorySize(const MCSubtargetInfo *STI) { 852 if (STI->getFeatureBits().test(FeatureLocalMemorySize32768)) 853 return 32768; 854 if (STI->getFeatureBits().test(FeatureLocalMemorySize65536)) 855 return 65536; 856 return 0; 857 } 858 859 unsigned getEUsPerCU(const MCSubtargetInfo *STI) { 860 // "Per CU" really means "per whatever functional block the waves of a 861 // workgroup must share". For gfx10 in CU mode this is the CU, which contains 862 // two SIMDs. 863 if (isGFX10Plus(*STI) && STI->getFeatureBits().test(FeatureCuMode)) 864 return 2; 865 // Pre-gfx10 a CU contains four SIMDs. For gfx10 in WGP mode the WGP contains 866 // two CUs, so a total of four SIMDs. 867 return 4; 868 } 869 870 unsigned getMaxWorkGroupsPerCU(const MCSubtargetInfo *STI, 871 unsigned FlatWorkGroupSize) { 872 assert(FlatWorkGroupSize != 0); 873 if (STI->getTargetTriple().getArch() != Triple::amdgcn) 874 return 8; 875 unsigned MaxWaves = getMaxWavesPerEU(STI) * getEUsPerCU(STI); 876 unsigned N = getWavesPerWorkGroup(STI, FlatWorkGroupSize); 877 if (N == 1) { 878 // Single-wave workgroups don't consume barrier resources. 879 return MaxWaves; 880 } 881 882 unsigned MaxBarriers = 16; 883 if (isGFX10Plus(*STI) && !STI->getFeatureBits().test(FeatureCuMode)) 884 MaxBarriers = 32; 885 886 return std::min(MaxWaves / N, MaxBarriers); 887 } 888 889 unsigned getMinWavesPerEU(const MCSubtargetInfo *STI) { 890 return 1; 891 } 892 893 unsigned getMaxWavesPerEU(const MCSubtargetInfo *STI) { 894 // FIXME: Need to take scratch memory into account. 895 if (isGFX90A(*STI)) 896 return 8; 897 if (!isGFX10Plus(*STI)) 898 return 10; 899 return hasGFX10_3Insts(*STI) ? 16 : 20; 900 } 901 902 unsigned getWavesPerEUForWorkGroup(const MCSubtargetInfo *STI, 903 unsigned FlatWorkGroupSize) { 904 return divideCeil(getWavesPerWorkGroup(STI, FlatWorkGroupSize), 905 getEUsPerCU(STI)); 906 } 907 908 unsigned getMinFlatWorkGroupSize(const MCSubtargetInfo *STI) { 909 return 1; 910 } 911 912 unsigned getMaxFlatWorkGroupSize(const MCSubtargetInfo *STI) { 913 // Some subtargets allow encoding 2048, but this isn't tested or supported. 914 return 1024; 915 } 916 917 unsigned getWavesPerWorkGroup(const MCSubtargetInfo *STI, 918 unsigned FlatWorkGroupSize) { 919 return divideCeil(FlatWorkGroupSize, getWavefrontSize(STI)); 920 } 921 922 unsigned getSGPRAllocGranule(const MCSubtargetInfo *STI) { 923 IsaVersion Version = getIsaVersion(STI->getCPU()); 924 if (Version.Major >= 10) 925 return getAddressableNumSGPRs(STI); 926 if (Version.Major >= 8) 927 return 16; 928 return 8; 929 } 930 931 unsigned getSGPREncodingGranule(const MCSubtargetInfo *STI) { 932 return 8; 933 } 934 935 unsigned getTotalNumSGPRs(const MCSubtargetInfo *STI) { 936 IsaVersion Version = getIsaVersion(STI->getCPU()); 937 if (Version.Major >= 8) 938 return 800; 939 return 512; 940 } 941 942 unsigned getAddressableNumSGPRs(const MCSubtargetInfo *STI) { 943 if (STI->getFeatureBits().test(FeatureSGPRInitBug)) 944 return FIXED_NUM_SGPRS_FOR_INIT_BUG; 945 946 IsaVersion Version = getIsaVersion(STI->getCPU()); 947 if (Version.Major >= 10) 948 return 106; 949 if (Version.Major >= 8) 950 return 102; 951 return 104; 952 } 953 954 unsigned getMinNumSGPRs(const MCSubtargetInfo *STI, unsigned WavesPerEU) { 955 assert(WavesPerEU != 0); 956 957 IsaVersion Version = getIsaVersion(STI->getCPU()); 958 if (Version.Major >= 10) 959 return 0; 960 961 if (WavesPerEU >= getMaxWavesPerEU(STI)) 962 return 0; 963 964 unsigned MinNumSGPRs = getTotalNumSGPRs(STI) / (WavesPerEU + 1); 965 if (STI->getFeatureBits().test(FeatureTrapHandler)) 966 MinNumSGPRs -= std::min(MinNumSGPRs, (unsigned)TRAP_NUM_SGPRS); 967 MinNumSGPRs = alignDown(MinNumSGPRs, getSGPRAllocGranule(STI)) + 1; 968 return std::min(MinNumSGPRs, getAddressableNumSGPRs(STI)); 969 } 970 971 unsigned getMaxNumSGPRs(const MCSubtargetInfo *STI, unsigned WavesPerEU, 972 bool Addressable) { 973 assert(WavesPerEU != 0); 974 975 unsigned AddressableNumSGPRs = getAddressableNumSGPRs(STI); 976 IsaVersion Version = getIsaVersion(STI->getCPU()); 977 if (Version.Major >= 10) 978 return Addressable ? AddressableNumSGPRs : 108; 979 if (Version.Major >= 8 && !Addressable) 980 AddressableNumSGPRs = 112; 981 unsigned MaxNumSGPRs = getTotalNumSGPRs(STI) / WavesPerEU; 982 if (STI->getFeatureBits().test(FeatureTrapHandler)) 983 MaxNumSGPRs -= std::min(MaxNumSGPRs, (unsigned)TRAP_NUM_SGPRS); 984 MaxNumSGPRs = alignDown(MaxNumSGPRs, getSGPRAllocGranule(STI)); 985 return std::min(MaxNumSGPRs, AddressableNumSGPRs); 986 } 987 988 unsigned getNumExtraSGPRs(const MCSubtargetInfo *STI, bool VCCUsed, 989 bool FlatScrUsed, bool XNACKUsed) { 990 unsigned ExtraSGPRs = 0; 991 if (VCCUsed) 992 ExtraSGPRs = 2; 993 994 IsaVersion Version = getIsaVersion(STI->getCPU()); 995 if (Version.Major >= 10) 996 return ExtraSGPRs; 997 998 if (Version.Major < 8) { 999 if (FlatScrUsed) 1000 ExtraSGPRs = 4; 1001 } else { 1002 if (XNACKUsed) 1003 ExtraSGPRs = 4; 1004 1005 if (FlatScrUsed || 1006 STI->getFeatureBits().test(AMDGPU::FeatureArchitectedFlatScratch)) 1007 ExtraSGPRs = 6; 1008 } 1009 1010 return ExtraSGPRs; 1011 } 1012 1013 unsigned getNumExtraSGPRs(const MCSubtargetInfo *STI, bool VCCUsed, 1014 bool FlatScrUsed) { 1015 return getNumExtraSGPRs(STI, VCCUsed, FlatScrUsed, 1016 STI->getFeatureBits().test(AMDGPU::FeatureXNACK)); 1017 } 1018 1019 unsigned getNumSGPRBlocks(const MCSubtargetInfo *STI, unsigned NumSGPRs) { 1020 NumSGPRs = alignTo(std::max(1u, NumSGPRs), getSGPREncodingGranule(STI)); 1021 // SGPRBlocks is actual number of SGPR blocks minus 1. 1022 return NumSGPRs / getSGPREncodingGranule(STI) - 1; 1023 } 1024 1025 unsigned getVGPRAllocGranule(const MCSubtargetInfo *STI, 1026 std::optional<bool> EnableWavefrontSize32) { 1027 if (STI->getFeatureBits().test(FeatureGFX90AInsts)) 1028 return 8; 1029 1030 bool IsWave32 = EnableWavefrontSize32 ? 1031 *EnableWavefrontSize32 : 1032 STI->getFeatureBits().test(FeatureWavefrontSize32); 1033 1034 if (STI->getFeatureBits().test(FeatureGFX11FullVGPRs)) 1035 return IsWave32 ? 24 : 12; 1036 1037 if (hasGFX10_3Insts(*STI)) 1038 return IsWave32 ? 16 : 8; 1039 1040 return IsWave32 ? 8 : 4; 1041 } 1042 1043 unsigned getVGPREncodingGranule(const MCSubtargetInfo *STI, 1044 std::optional<bool> EnableWavefrontSize32) { 1045 if (STI->getFeatureBits().test(FeatureGFX90AInsts)) 1046 return 8; 1047 1048 bool IsWave32 = EnableWavefrontSize32 ? 1049 *EnableWavefrontSize32 : 1050 STI->getFeatureBits().test(FeatureWavefrontSize32); 1051 1052 return IsWave32 ? 8 : 4; 1053 } 1054 1055 unsigned getTotalNumVGPRs(const MCSubtargetInfo *STI) { 1056 if (STI->getFeatureBits().test(FeatureGFX90AInsts)) 1057 return 512; 1058 if (!isGFX10Plus(*STI)) 1059 return 256; 1060 bool IsWave32 = STI->getFeatureBits().test(FeatureWavefrontSize32); 1061 if (STI->getFeatureBits().test(FeatureGFX11FullVGPRs)) 1062 return IsWave32 ? 1536 : 768; 1063 return IsWave32 ? 1024 : 512; 1064 } 1065 1066 unsigned getAddressableNumVGPRs(const MCSubtargetInfo *STI) { 1067 if (STI->getFeatureBits().test(FeatureGFX90AInsts)) 1068 return 512; 1069 return 256; 1070 } 1071 1072 unsigned getNumWavesPerEUWithNumVGPRs(const MCSubtargetInfo *STI, 1073 unsigned NumVGPRs) { 1074 unsigned MaxWaves = getMaxWavesPerEU(STI); 1075 unsigned Granule = getVGPRAllocGranule(STI); 1076 if (NumVGPRs < Granule) 1077 return MaxWaves; 1078 unsigned RoundedRegs = alignTo(NumVGPRs, Granule); 1079 return std::min(std::max(getTotalNumVGPRs(STI) / RoundedRegs, 1u), MaxWaves); 1080 } 1081 1082 unsigned getMinNumVGPRs(const MCSubtargetInfo *STI, unsigned WavesPerEU) { 1083 assert(WavesPerEU != 0); 1084 1085 unsigned MaxWavesPerEU = getMaxWavesPerEU(STI); 1086 if (WavesPerEU >= MaxWavesPerEU) 1087 return 0; 1088 1089 unsigned TotNumVGPRs = getTotalNumVGPRs(STI); 1090 unsigned AddrsableNumVGPRs = getAddressableNumVGPRs(STI); 1091 unsigned Granule = getVGPRAllocGranule(STI); 1092 unsigned MaxNumVGPRs = alignDown(TotNumVGPRs / WavesPerEU, Granule); 1093 1094 if (MaxNumVGPRs == alignDown(TotNumVGPRs / MaxWavesPerEU, Granule)) 1095 return 0; 1096 1097 unsigned MinWavesPerEU = getNumWavesPerEUWithNumVGPRs(STI, AddrsableNumVGPRs); 1098 if (WavesPerEU < MinWavesPerEU) 1099 return getMinNumVGPRs(STI, MinWavesPerEU); 1100 1101 unsigned MaxNumVGPRsNext = alignDown(TotNumVGPRs / (WavesPerEU + 1), Granule); 1102 unsigned MinNumVGPRs = 1 + std::min(MaxNumVGPRs - Granule, MaxNumVGPRsNext); 1103 return std::min(MinNumVGPRs, AddrsableNumVGPRs); 1104 } 1105 1106 unsigned getMaxNumVGPRs(const MCSubtargetInfo *STI, unsigned WavesPerEU) { 1107 assert(WavesPerEU != 0); 1108 1109 unsigned MaxNumVGPRs = alignDown(getTotalNumVGPRs(STI) / WavesPerEU, 1110 getVGPRAllocGranule(STI)); 1111 unsigned AddressableNumVGPRs = getAddressableNumVGPRs(STI); 1112 return std::min(MaxNumVGPRs, AddressableNumVGPRs); 1113 } 1114 1115 unsigned getNumVGPRBlocks(const MCSubtargetInfo *STI, unsigned NumVGPRs, 1116 std::optional<bool> EnableWavefrontSize32) { 1117 NumVGPRs = alignTo(std::max(1u, NumVGPRs), 1118 getVGPREncodingGranule(STI, EnableWavefrontSize32)); 1119 // VGPRBlocks is actual number of VGPR blocks minus 1. 1120 return NumVGPRs / getVGPREncodingGranule(STI, EnableWavefrontSize32) - 1; 1121 } 1122 1123 } // end namespace IsaInfo 1124 1125 void initDefaultAMDKernelCodeT(amd_kernel_code_t &Header, 1126 const MCSubtargetInfo *STI) { 1127 IsaVersion Version = getIsaVersion(STI->getCPU()); 1128 1129 memset(&Header, 0, sizeof(Header)); 1130 1131 Header.amd_kernel_code_version_major = 1; 1132 Header.amd_kernel_code_version_minor = 2; 1133 Header.amd_machine_kind = 1; // AMD_MACHINE_KIND_AMDGPU 1134 Header.amd_machine_version_major = Version.Major; 1135 Header.amd_machine_version_minor = Version.Minor; 1136 Header.amd_machine_version_stepping = Version.Stepping; 1137 Header.kernel_code_entry_byte_offset = sizeof(Header); 1138 Header.wavefront_size = 6; 1139 1140 // If the code object does not support indirect functions, then the value must 1141 // be 0xffffffff. 1142 Header.call_convention = -1; 1143 1144 // These alignment values are specified in powers of two, so alignment = 1145 // 2^n. The minimum alignment is 2^4 = 16. 1146 Header.kernarg_segment_alignment = 4; 1147 Header.group_segment_alignment = 4; 1148 Header.private_segment_alignment = 4; 1149 1150 if (Version.Major >= 10) { 1151 if (STI->getFeatureBits().test(FeatureWavefrontSize32)) { 1152 Header.wavefront_size = 5; 1153 Header.code_properties |= AMD_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32; 1154 } 1155 Header.compute_pgm_resource_registers |= 1156 S_00B848_WGP_MODE(STI->getFeatureBits().test(FeatureCuMode) ? 0 : 1) | 1157 S_00B848_MEM_ORDERED(1); 1158 } 1159 } 1160 1161 amdhsa::kernel_descriptor_t getDefaultAmdhsaKernelDescriptor( 1162 const MCSubtargetInfo *STI) { 1163 IsaVersion Version = getIsaVersion(STI->getCPU()); 1164 1165 amdhsa::kernel_descriptor_t KD; 1166 memset(&KD, 0, sizeof(KD)); 1167 1168 AMDHSA_BITS_SET(KD.compute_pgm_rsrc1, 1169 amdhsa::COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_16_64, 1170 amdhsa::FLOAT_DENORM_MODE_FLUSH_NONE); 1171 if (Version.Major >= 12) { 1172 AMDHSA_BITS_SET(KD.compute_pgm_rsrc1, 1173 amdhsa::COMPUTE_PGM_RSRC1_GFX12_PLUS_ENABLE_WG_RR_EN, 0); 1174 AMDHSA_BITS_SET(KD.compute_pgm_rsrc1, 1175 amdhsa::COMPUTE_PGM_RSRC1_GFX12_PLUS_DISABLE_PERF, 0); 1176 } else { 1177 AMDHSA_BITS_SET(KD.compute_pgm_rsrc1, 1178 amdhsa::COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_DX10_CLAMP, 1); 1179 AMDHSA_BITS_SET(KD.compute_pgm_rsrc1, 1180 amdhsa::COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_IEEE_MODE, 1); 1181 } 1182 AMDHSA_BITS_SET(KD.compute_pgm_rsrc2, 1183 amdhsa::COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_X, 1); 1184 if (Version.Major >= 10) { 1185 AMDHSA_BITS_SET(KD.kernel_code_properties, 1186 amdhsa::KERNEL_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32, 1187 STI->getFeatureBits().test(FeatureWavefrontSize32) ? 1 : 0); 1188 AMDHSA_BITS_SET(KD.compute_pgm_rsrc1, 1189 amdhsa::COMPUTE_PGM_RSRC1_GFX10_PLUS_WGP_MODE, 1190 STI->getFeatureBits().test(FeatureCuMode) ? 0 : 1); 1191 AMDHSA_BITS_SET(KD.compute_pgm_rsrc1, 1192 amdhsa::COMPUTE_PGM_RSRC1_GFX10_PLUS_MEM_ORDERED, 1); 1193 } 1194 if (AMDGPU::isGFX90A(*STI)) { 1195 AMDHSA_BITS_SET(KD.compute_pgm_rsrc3, 1196 amdhsa::COMPUTE_PGM_RSRC3_GFX90A_TG_SPLIT, 1197 STI->getFeatureBits().test(FeatureTgSplit) ? 1 : 0); 1198 } 1199 return KD; 1200 } 1201 1202 bool isGroupSegment(const GlobalValue *GV) { 1203 return GV->getAddressSpace() == AMDGPUAS::LOCAL_ADDRESS; 1204 } 1205 1206 bool isGlobalSegment(const GlobalValue *GV) { 1207 return GV->getAddressSpace() == AMDGPUAS::GLOBAL_ADDRESS; 1208 } 1209 1210 bool isReadOnlySegment(const GlobalValue *GV) { 1211 unsigned AS = GV->getAddressSpace(); 1212 return AS == AMDGPUAS::CONSTANT_ADDRESS || 1213 AS == AMDGPUAS::CONSTANT_ADDRESS_32BIT; 1214 } 1215 1216 bool shouldEmitConstantsToTextSection(const Triple &TT) { 1217 return TT.getArch() == Triple::r600; 1218 } 1219 1220 std::pair<unsigned, unsigned> 1221 getIntegerPairAttribute(const Function &F, StringRef Name, 1222 std::pair<unsigned, unsigned> Default, 1223 bool OnlyFirstRequired) { 1224 Attribute A = F.getFnAttribute(Name); 1225 if (!A.isStringAttribute()) 1226 return Default; 1227 1228 LLVMContext &Ctx = F.getContext(); 1229 std::pair<unsigned, unsigned> Ints = Default; 1230 std::pair<StringRef, StringRef> Strs = A.getValueAsString().split(','); 1231 if (Strs.first.trim().getAsInteger(0, Ints.first)) { 1232 Ctx.emitError("can't parse first integer attribute " + Name); 1233 return Default; 1234 } 1235 if (Strs.second.trim().getAsInteger(0, Ints.second)) { 1236 if (!OnlyFirstRequired || !Strs.second.trim().empty()) { 1237 Ctx.emitError("can't parse second integer attribute " + Name); 1238 return Default; 1239 } 1240 } 1241 1242 return Ints; 1243 } 1244 1245 unsigned getVmcntBitMask(const IsaVersion &Version) { 1246 return (1 << (getVmcntBitWidthLo(Version.Major) + 1247 getVmcntBitWidthHi(Version.Major))) - 1248 1; 1249 } 1250 1251 unsigned getLoadcntBitMask(const IsaVersion &Version) { 1252 return (1 << getLoadcntBitWidth(Version.Major)) - 1; 1253 } 1254 1255 unsigned getSamplecntBitMask(const IsaVersion &Version) { 1256 return (1 << getSamplecntBitWidth(Version.Major)) - 1; 1257 } 1258 1259 unsigned getBvhcntBitMask(const IsaVersion &Version) { 1260 return (1 << getBvhcntBitWidth(Version.Major)) - 1; 1261 } 1262 1263 unsigned getExpcntBitMask(const IsaVersion &Version) { 1264 return (1 << getExpcntBitWidth(Version.Major)) - 1; 1265 } 1266 1267 unsigned getLgkmcntBitMask(const IsaVersion &Version) { 1268 return (1 << getLgkmcntBitWidth(Version.Major)) - 1; 1269 } 1270 1271 unsigned getDscntBitMask(const IsaVersion &Version) { 1272 return (1 << getDscntBitWidth(Version.Major)) - 1; 1273 } 1274 1275 unsigned getKmcntBitMask(const IsaVersion &Version) { 1276 return (1 << getKmcntBitWidth(Version.Major)) - 1; 1277 } 1278 1279 unsigned getStorecntBitMask(const IsaVersion &Version) { 1280 return (1 << getStorecntBitWidth(Version.Major)) - 1; 1281 } 1282 1283 unsigned getWaitcntBitMask(const IsaVersion &Version) { 1284 unsigned VmcntLo = getBitMask(getVmcntBitShiftLo(Version.Major), 1285 getVmcntBitWidthLo(Version.Major)); 1286 unsigned Expcnt = getBitMask(getExpcntBitShift(Version.Major), 1287 getExpcntBitWidth(Version.Major)); 1288 unsigned Lgkmcnt = getBitMask(getLgkmcntBitShift(Version.Major), 1289 getLgkmcntBitWidth(Version.Major)); 1290 unsigned VmcntHi = getBitMask(getVmcntBitShiftHi(Version.Major), 1291 getVmcntBitWidthHi(Version.Major)); 1292 return VmcntLo | Expcnt | Lgkmcnt | VmcntHi; 1293 } 1294 1295 unsigned decodeVmcnt(const IsaVersion &Version, unsigned Waitcnt) { 1296 unsigned VmcntLo = unpackBits(Waitcnt, getVmcntBitShiftLo(Version.Major), 1297 getVmcntBitWidthLo(Version.Major)); 1298 unsigned VmcntHi = unpackBits(Waitcnt, getVmcntBitShiftHi(Version.Major), 1299 getVmcntBitWidthHi(Version.Major)); 1300 return VmcntLo | VmcntHi << getVmcntBitWidthLo(Version.Major); 1301 } 1302 1303 unsigned decodeExpcnt(const IsaVersion &Version, unsigned Waitcnt) { 1304 return unpackBits(Waitcnt, getExpcntBitShift(Version.Major), 1305 getExpcntBitWidth(Version.Major)); 1306 } 1307 1308 unsigned decodeLgkmcnt(const IsaVersion &Version, unsigned Waitcnt) { 1309 return unpackBits(Waitcnt, getLgkmcntBitShift(Version.Major), 1310 getLgkmcntBitWidth(Version.Major)); 1311 } 1312 1313 void decodeWaitcnt(const IsaVersion &Version, unsigned Waitcnt, 1314 unsigned &Vmcnt, unsigned &Expcnt, unsigned &Lgkmcnt) { 1315 Vmcnt = decodeVmcnt(Version, Waitcnt); 1316 Expcnt = decodeExpcnt(Version, Waitcnt); 1317 Lgkmcnt = decodeLgkmcnt(Version, Waitcnt); 1318 } 1319 1320 Waitcnt decodeWaitcnt(const IsaVersion &Version, unsigned Encoded) { 1321 Waitcnt Decoded; 1322 Decoded.LoadCnt = decodeVmcnt(Version, Encoded); 1323 Decoded.ExpCnt = decodeExpcnt(Version, Encoded); 1324 Decoded.DsCnt = decodeLgkmcnt(Version, Encoded); 1325 return Decoded; 1326 } 1327 1328 unsigned encodeVmcnt(const IsaVersion &Version, unsigned Waitcnt, 1329 unsigned Vmcnt) { 1330 Waitcnt = packBits(Vmcnt, Waitcnt, getVmcntBitShiftLo(Version.Major), 1331 getVmcntBitWidthLo(Version.Major)); 1332 return packBits(Vmcnt >> getVmcntBitWidthLo(Version.Major), Waitcnt, 1333 getVmcntBitShiftHi(Version.Major), 1334 getVmcntBitWidthHi(Version.Major)); 1335 } 1336 1337 unsigned encodeExpcnt(const IsaVersion &Version, unsigned Waitcnt, 1338 unsigned Expcnt) { 1339 return packBits(Expcnt, Waitcnt, getExpcntBitShift(Version.Major), 1340 getExpcntBitWidth(Version.Major)); 1341 } 1342 1343 unsigned encodeLgkmcnt(const IsaVersion &Version, unsigned Waitcnt, 1344 unsigned Lgkmcnt) { 1345 return packBits(Lgkmcnt, Waitcnt, getLgkmcntBitShift(Version.Major), 1346 getLgkmcntBitWidth(Version.Major)); 1347 } 1348 1349 unsigned encodeWaitcnt(const IsaVersion &Version, 1350 unsigned Vmcnt, unsigned Expcnt, unsigned Lgkmcnt) { 1351 unsigned Waitcnt = getWaitcntBitMask(Version); 1352 Waitcnt = encodeVmcnt(Version, Waitcnt, Vmcnt); 1353 Waitcnt = encodeExpcnt(Version, Waitcnt, Expcnt); 1354 Waitcnt = encodeLgkmcnt(Version, Waitcnt, Lgkmcnt); 1355 return Waitcnt; 1356 } 1357 1358 unsigned encodeWaitcnt(const IsaVersion &Version, const Waitcnt &Decoded) { 1359 return encodeWaitcnt(Version, Decoded.LoadCnt, Decoded.ExpCnt, Decoded.DsCnt); 1360 } 1361 1362 static unsigned getCombinedCountBitMask(const IsaVersion &Version, 1363 bool IsStore) { 1364 unsigned Dscnt = getBitMask(getDscntBitShift(Version.Major), 1365 getDscntBitWidth(Version.Major)); 1366 if (IsStore) { 1367 unsigned Storecnt = getBitMask(getLoadcntStorecntBitShift(Version.Major), 1368 getStorecntBitWidth(Version.Major)); 1369 return Dscnt | Storecnt; 1370 } else { 1371 unsigned Loadcnt = getBitMask(getLoadcntStorecntBitShift(Version.Major), 1372 getLoadcntBitWidth(Version.Major)); 1373 return Dscnt | Loadcnt; 1374 } 1375 } 1376 1377 Waitcnt decodeLoadcntDscnt(const IsaVersion &Version, unsigned LoadcntDscnt) { 1378 Waitcnt Decoded; 1379 Decoded.LoadCnt = 1380 unpackBits(LoadcntDscnt, getLoadcntStorecntBitShift(Version.Major), 1381 getLoadcntBitWidth(Version.Major)); 1382 Decoded.DsCnt = unpackBits(LoadcntDscnt, getDscntBitShift(Version.Major), 1383 getDscntBitWidth(Version.Major)); 1384 return Decoded; 1385 } 1386 1387 Waitcnt decodeStorecntDscnt(const IsaVersion &Version, unsigned StorecntDscnt) { 1388 Waitcnt Decoded; 1389 Decoded.StoreCnt = 1390 unpackBits(StorecntDscnt, getLoadcntStorecntBitShift(Version.Major), 1391 getStorecntBitWidth(Version.Major)); 1392 Decoded.DsCnt = unpackBits(StorecntDscnt, getDscntBitShift(Version.Major), 1393 getDscntBitWidth(Version.Major)); 1394 return Decoded; 1395 } 1396 1397 static unsigned encodeLoadcnt(const IsaVersion &Version, unsigned Waitcnt, 1398 unsigned Loadcnt) { 1399 return packBits(Loadcnt, Waitcnt, getLoadcntStorecntBitShift(Version.Major), 1400 getLoadcntBitWidth(Version.Major)); 1401 } 1402 1403 static unsigned encodeStorecnt(const IsaVersion &Version, unsigned Waitcnt, 1404 unsigned Storecnt) { 1405 return packBits(Storecnt, Waitcnt, getLoadcntStorecntBitShift(Version.Major), 1406 getStorecntBitWidth(Version.Major)); 1407 } 1408 1409 static unsigned encodeDscnt(const IsaVersion &Version, unsigned Waitcnt, 1410 unsigned Dscnt) { 1411 return packBits(Dscnt, Waitcnt, getDscntBitShift(Version.Major), 1412 getDscntBitWidth(Version.Major)); 1413 } 1414 1415 static unsigned encodeLoadcntDscnt(const IsaVersion &Version, unsigned Loadcnt, 1416 unsigned Dscnt) { 1417 unsigned Waitcnt = getCombinedCountBitMask(Version, false); 1418 Waitcnt = encodeLoadcnt(Version, Waitcnt, Loadcnt); 1419 Waitcnt = encodeDscnt(Version, Waitcnt, Dscnt); 1420 return Waitcnt; 1421 } 1422 1423 unsigned encodeLoadcntDscnt(const IsaVersion &Version, const Waitcnt &Decoded) { 1424 return encodeLoadcntDscnt(Version, Decoded.LoadCnt, Decoded.DsCnt); 1425 } 1426 1427 static unsigned encodeStorecntDscnt(const IsaVersion &Version, 1428 unsigned Storecnt, unsigned Dscnt) { 1429 unsigned Waitcnt = getCombinedCountBitMask(Version, true); 1430 Waitcnt = encodeStorecnt(Version, Waitcnt, Storecnt); 1431 Waitcnt = encodeDscnt(Version, Waitcnt, Dscnt); 1432 return Waitcnt; 1433 } 1434 1435 unsigned encodeStorecntDscnt(const IsaVersion &Version, 1436 const Waitcnt &Decoded) { 1437 return encodeStorecntDscnt(Version, Decoded.StoreCnt, Decoded.DsCnt); 1438 } 1439 1440 //===----------------------------------------------------------------------===// 1441 // Custom Operands. 1442 // 1443 // A table of custom operands shall describe "primary" operand names 1444 // first followed by aliases if any. It is not required but recommended 1445 // to arrange operands so that operand encoding match operand position 1446 // in the table. This will make disassembly a bit more efficient. 1447 // Unused slots in the table shall have an empty name. 1448 // 1449 //===----------------------------------------------------------------------===// 1450 1451 template <class T> 1452 static bool isValidOpr(int Idx, const CustomOperand<T> OpInfo[], int OpInfoSize, 1453 T Context) { 1454 return 0 <= Idx && Idx < OpInfoSize && !OpInfo[Idx].Name.empty() && 1455 (!OpInfo[Idx].Cond || OpInfo[Idx].Cond(Context)); 1456 } 1457 1458 template <class T> 1459 static int getOprIdx(std::function<bool(const CustomOperand<T> &)> Test, 1460 const CustomOperand<T> OpInfo[], int OpInfoSize, 1461 T Context) { 1462 int InvalidIdx = OPR_ID_UNKNOWN; 1463 for (int Idx = 0; Idx < OpInfoSize; ++Idx) { 1464 if (Test(OpInfo[Idx])) { 1465 if (!OpInfo[Idx].Cond || OpInfo[Idx].Cond(Context)) 1466 return Idx; 1467 InvalidIdx = OPR_ID_UNSUPPORTED; 1468 } 1469 } 1470 return InvalidIdx; 1471 } 1472 1473 template <class T> 1474 static int getOprIdx(const StringRef Name, const CustomOperand<T> OpInfo[], 1475 int OpInfoSize, T Context) { 1476 auto Test = [=](const CustomOperand<T> &Op) { return Op.Name == Name; }; 1477 return getOprIdx<T>(Test, OpInfo, OpInfoSize, Context); 1478 } 1479 1480 template <class T> 1481 static int getOprIdx(int Id, const CustomOperand<T> OpInfo[], int OpInfoSize, 1482 T Context, bool QuickCheck = true) { 1483 auto Test = [=](const CustomOperand<T> &Op) { 1484 return Op.Encoding == Id && !Op.Name.empty(); 1485 }; 1486 // This is an optimization that should work in most cases. 1487 // As a side effect, it may cause selection of an alias 1488 // instead of a primary operand name in case of sparse tables. 1489 if (QuickCheck && isValidOpr<T>(Id, OpInfo, OpInfoSize, Context) && 1490 OpInfo[Id].Encoding == Id) { 1491 return Id; 1492 } 1493 return getOprIdx<T>(Test, OpInfo, OpInfoSize, Context); 1494 } 1495 1496 //===----------------------------------------------------------------------===// 1497 // Custom Operand Values 1498 //===----------------------------------------------------------------------===// 1499 1500 static unsigned getDefaultCustomOperandEncoding(const CustomOperandVal *Opr, 1501 int Size, 1502 const MCSubtargetInfo &STI) { 1503 unsigned Enc = 0; 1504 for (int Idx = 0; Idx < Size; ++Idx) { 1505 const auto &Op = Opr[Idx]; 1506 if (Op.isSupported(STI)) 1507 Enc |= Op.encode(Op.Default); 1508 } 1509 return Enc; 1510 } 1511 1512 static bool isSymbolicCustomOperandEncoding(const CustomOperandVal *Opr, 1513 int Size, unsigned Code, 1514 bool &HasNonDefaultVal, 1515 const MCSubtargetInfo &STI) { 1516 unsigned UsedOprMask = 0; 1517 HasNonDefaultVal = false; 1518 for (int Idx = 0; Idx < Size; ++Idx) { 1519 const auto &Op = Opr[Idx]; 1520 if (!Op.isSupported(STI)) 1521 continue; 1522 UsedOprMask |= Op.getMask(); 1523 unsigned Val = Op.decode(Code); 1524 if (!Op.isValid(Val)) 1525 return false; 1526 HasNonDefaultVal |= (Val != Op.Default); 1527 } 1528 return (Code & ~UsedOprMask) == 0; 1529 } 1530 1531 static bool decodeCustomOperand(const CustomOperandVal *Opr, int Size, 1532 unsigned Code, int &Idx, StringRef &Name, 1533 unsigned &Val, bool &IsDefault, 1534 const MCSubtargetInfo &STI) { 1535 while (Idx < Size) { 1536 const auto &Op = Opr[Idx++]; 1537 if (Op.isSupported(STI)) { 1538 Name = Op.Name; 1539 Val = Op.decode(Code); 1540 IsDefault = (Val == Op.Default); 1541 return true; 1542 } 1543 } 1544 1545 return false; 1546 } 1547 1548 static int encodeCustomOperandVal(const CustomOperandVal &Op, 1549 int64_t InputVal) { 1550 if (InputVal < 0 || InputVal > Op.Max) 1551 return OPR_VAL_INVALID; 1552 return Op.encode(InputVal); 1553 } 1554 1555 static int encodeCustomOperand(const CustomOperandVal *Opr, int Size, 1556 const StringRef Name, int64_t InputVal, 1557 unsigned &UsedOprMask, 1558 const MCSubtargetInfo &STI) { 1559 int InvalidId = OPR_ID_UNKNOWN; 1560 for (int Idx = 0; Idx < Size; ++Idx) { 1561 const auto &Op = Opr[Idx]; 1562 if (Op.Name == Name) { 1563 if (!Op.isSupported(STI)) { 1564 InvalidId = OPR_ID_UNSUPPORTED; 1565 continue; 1566 } 1567 auto OprMask = Op.getMask(); 1568 if (OprMask & UsedOprMask) 1569 return OPR_ID_DUPLICATE; 1570 UsedOprMask |= OprMask; 1571 return encodeCustomOperandVal(Op, InputVal); 1572 } 1573 } 1574 return InvalidId; 1575 } 1576 1577 //===----------------------------------------------------------------------===// 1578 // DepCtr 1579 //===----------------------------------------------------------------------===// 1580 1581 namespace DepCtr { 1582 1583 int getDefaultDepCtrEncoding(const MCSubtargetInfo &STI) { 1584 static int Default = -1; 1585 if (Default == -1) 1586 Default = getDefaultCustomOperandEncoding(DepCtrInfo, DEP_CTR_SIZE, STI); 1587 return Default; 1588 } 1589 1590 bool isSymbolicDepCtrEncoding(unsigned Code, bool &HasNonDefaultVal, 1591 const MCSubtargetInfo &STI) { 1592 return isSymbolicCustomOperandEncoding(DepCtrInfo, DEP_CTR_SIZE, Code, 1593 HasNonDefaultVal, STI); 1594 } 1595 1596 bool decodeDepCtr(unsigned Code, int &Id, StringRef &Name, unsigned &Val, 1597 bool &IsDefault, const MCSubtargetInfo &STI) { 1598 return decodeCustomOperand(DepCtrInfo, DEP_CTR_SIZE, Code, Id, Name, Val, 1599 IsDefault, STI); 1600 } 1601 1602 int encodeDepCtr(const StringRef Name, int64_t Val, unsigned &UsedOprMask, 1603 const MCSubtargetInfo &STI) { 1604 return encodeCustomOperand(DepCtrInfo, DEP_CTR_SIZE, Name, Val, UsedOprMask, 1605 STI); 1606 } 1607 1608 unsigned decodeFieldVmVsrc(unsigned Encoded) { 1609 return unpackBits(Encoded, getVmVsrcBitShift(), getVmVsrcBitWidth()); 1610 } 1611 1612 unsigned decodeFieldVaVdst(unsigned Encoded) { 1613 return unpackBits(Encoded, getVaVdstBitShift(), getVaVdstBitWidth()); 1614 } 1615 1616 unsigned decodeFieldSaSdst(unsigned Encoded) { 1617 return unpackBits(Encoded, getSaSdstBitShift(), getSaSdstBitWidth()); 1618 } 1619 1620 unsigned encodeFieldVmVsrc(unsigned Encoded, unsigned VmVsrc) { 1621 return packBits(VmVsrc, Encoded, getVmVsrcBitShift(), getVmVsrcBitWidth()); 1622 } 1623 1624 unsigned encodeFieldVmVsrc(unsigned VmVsrc) { 1625 return encodeFieldVmVsrc(0xffff, VmVsrc); 1626 } 1627 1628 unsigned encodeFieldVaVdst(unsigned Encoded, unsigned VaVdst) { 1629 return packBits(VaVdst, Encoded, getVaVdstBitShift(), getVaVdstBitWidth()); 1630 } 1631 1632 unsigned encodeFieldVaVdst(unsigned VaVdst) { 1633 return encodeFieldVaVdst(0xffff, VaVdst); 1634 } 1635 1636 unsigned encodeFieldSaSdst(unsigned Encoded, unsigned SaSdst) { 1637 return packBits(SaSdst, Encoded, getSaSdstBitShift(), getSaSdstBitWidth()); 1638 } 1639 1640 unsigned encodeFieldSaSdst(unsigned SaSdst) { 1641 return encodeFieldSaSdst(0xffff, SaSdst); 1642 } 1643 1644 } // namespace DepCtr 1645 1646 //===----------------------------------------------------------------------===// 1647 // hwreg 1648 //===----------------------------------------------------------------------===// 1649 1650 namespace Hwreg { 1651 1652 int64_t getHwregId(const StringRef Name, const MCSubtargetInfo &STI) { 1653 int Idx = getOprIdx<const MCSubtargetInfo &>(Name, Opr, OPR_SIZE, STI); 1654 return (Idx < 0) ? Idx : Opr[Idx].Encoding; 1655 } 1656 1657 bool isValidHwreg(int64_t Id) { 1658 return 0 <= Id && isUInt<ID_WIDTH_>(Id); 1659 } 1660 1661 bool isValidHwregOffset(int64_t Offset) { 1662 return 0 <= Offset && isUInt<OFFSET_WIDTH_>(Offset); 1663 } 1664 1665 bool isValidHwregWidth(int64_t Width) { 1666 return 0 <= (Width - 1) && isUInt<WIDTH_M1_WIDTH_>(Width - 1); 1667 } 1668 1669 uint64_t encodeHwreg(uint64_t Id, uint64_t Offset, uint64_t Width) { 1670 return (Id << ID_SHIFT_) | 1671 (Offset << OFFSET_SHIFT_) | 1672 ((Width - 1) << WIDTH_M1_SHIFT_); 1673 } 1674 1675 StringRef getHwreg(unsigned Id, const MCSubtargetInfo &STI) { 1676 int Idx = getOprIdx<const MCSubtargetInfo &>(Id, Opr, OPR_SIZE, STI); 1677 return (Idx < 0) ? "" : Opr[Idx].Name; 1678 } 1679 1680 void decodeHwreg(unsigned Val, unsigned &Id, unsigned &Offset, unsigned &Width) { 1681 Id = (Val & ID_MASK_) >> ID_SHIFT_; 1682 Offset = (Val & OFFSET_MASK_) >> OFFSET_SHIFT_; 1683 Width = ((Val & WIDTH_M1_MASK_) >> WIDTH_M1_SHIFT_) + 1; 1684 } 1685 1686 } // namespace Hwreg 1687 1688 //===----------------------------------------------------------------------===// 1689 // exp tgt 1690 //===----------------------------------------------------------------------===// 1691 1692 namespace Exp { 1693 1694 struct ExpTgt { 1695 StringLiteral Name; 1696 unsigned Tgt; 1697 unsigned MaxIndex; 1698 }; 1699 1700 static constexpr ExpTgt ExpTgtInfo[] = { 1701 {{"null"}, ET_NULL, ET_NULL_MAX_IDX}, 1702 {{"mrtz"}, ET_MRTZ, ET_MRTZ_MAX_IDX}, 1703 {{"prim"}, ET_PRIM, ET_PRIM_MAX_IDX}, 1704 {{"mrt"}, ET_MRT0, ET_MRT_MAX_IDX}, 1705 {{"pos"}, ET_POS0, ET_POS_MAX_IDX}, 1706 {{"dual_src_blend"}, ET_DUAL_SRC_BLEND0, ET_DUAL_SRC_BLEND_MAX_IDX}, 1707 {{"param"}, ET_PARAM0, ET_PARAM_MAX_IDX}, 1708 }; 1709 1710 bool getTgtName(unsigned Id, StringRef &Name, int &Index) { 1711 for (const ExpTgt &Val : ExpTgtInfo) { 1712 if (Val.Tgt <= Id && Id <= Val.Tgt + Val.MaxIndex) { 1713 Index = (Val.MaxIndex == 0) ? -1 : (Id - Val.Tgt); 1714 Name = Val.Name; 1715 return true; 1716 } 1717 } 1718 return false; 1719 } 1720 1721 unsigned getTgtId(const StringRef Name) { 1722 1723 for (const ExpTgt &Val : ExpTgtInfo) { 1724 if (Val.MaxIndex == 0 && Name == Val.Name) 1725 return Val.Tgt; 1726 1727 if (Val.MaxIndex > 0 && Name.starts_with(Val.Name)) { 1728 StringRef Suffix = Name.drop_front(Val.Name.size()); 1729 1730 unsigned Id; 1731 if (Suffix.getAsInteger(10, Id) || Id > Val.MaxIndex) 1732 return ET_INVALID; 1733 1734 // Disable leading zeroes 1735 if (Suffix.size() > 1 && Suffix[0] == '0') 1736 return ET_INVALID; 1737 1738 return Val.Tgt + Id; 1739 } 1740 } 1741 return ET_INVALID; 1742 } 1743 1744 bool isSupportedTgtId(unsigned Id, const MCSubtargetInfo &STI) { 1745 switch (Id) { 1746 case ET_NULL: 1747 return !isGFX11Plus(STI); 1748 case ET_POS4: 1749 case ET_PRIM: 1750 return isGFX10Plus(STI); 1751 case ET_DUAL_SRC_BLEND0: 1752 case ET_DUAL_SRC_BLEND1: 1753 return isGFX11Plus(STI); 1754 default: 1755 if (Id >= ET_PARAM0 && Id <= ET_PARAM31) 1756 return !isGFX11Plus(STI); 1757 return true; 1758 } 1759 } 1760 1761 } // namespace Exp 1762 1763 //===----------------------------------------------------------------------===// 1764 // MTBUF Format 1765 //===----------------------------------------------------------------------===// 1766 1767 namespace MTBUFFormat { 1768 1769 int64_t getDfmt(const StringRef Name) { 1770 for (int Id = DFMT_MIN; Id <= DFMT_MAX; ++Id) { 1771 if (Name == DfmtSymbolic[Id]) 1772 return Id; 1773 } 1774 return DFMT_UNDEF; 1775 } 1776 1777 StringRef getDfmtName(unsigned Id) { 1778 assert(Id <= DFMT_MAX); 1779 return DfmtSymbolic[Id]; 1780 } 1781 1782 static StringLiteral const *getNfmtLookupTable(const MCSubtargetInfo &STI) { 1783 if (isSI(STI) || isCI(STI)) 1784 return NfmtSymbolicSICI; 1785 if (isVI(STI) || isGFX9(STI)) 1786 return NfmtSymbolicVI; 1787 return NfmtSymbolicGFX10; 1788 } 1789 1790 int64_t getNfmt(const StringRef Name, const MCSubtargetInfo &STI) { 1791 auto lookupTable = getNfmtLookupTable(STI); 1792 for (int Id = NFMT_MIN; Id <= NFMT_MAX; ++Id) { 1793 if (Name == lookupTable[Id]) 1794 return Id; 1795 } 1796 return NFMT_UNDEF; 1797 } 1798 1799 StringRef getNfmtName(unsigned Id, const MCSubtargetInfo &STI) { 1800 assert(Id <= NFMT_MAX); 1801 return getNfmtLookupTable(STI)[Id]; 1802 } 1803 1804 bool isValidDfmtNfmt(unsigned Id, const MCSubtargetInfo &STI) { 1805 unsigned Dfmt; 1806 unsigned Nfmt; 1807 decodeDfmtNfmt(Id, Dfmt, Nfmt); 1808 return isValidNfmt(Nfmt, STI); 1809 } 1810 1811 bool isValidNfmt(unsigned Id, const MCSubtargetInfo &STI) { 1812 return !getNfmtName(Id, STI).empty(); 1813 } 1814 1815 int64_t encodeDfmtNfmt(unsigned Dfmt, unsigned Nfmt) { 1816 return (Dfmt << DFMT_SHIFT) | (Nfmt << NFMT_SHIFT); 1817 } 1818 1819 void decodeDfmtNfmt(unsigned Format, unsigned &Dfmt, unsigned &Nfmt) { 1820 Dfmt = (Format >> DFMT_SHIFT) & DFMT_MASK; 1821 Nfmt = (Format >> NFMT_SHIFT) & NFMT_MASK; 1822 } 1823 1824 int64_t getUnifiedFormat(const StringRef Name, const MCSubtargetInfo &STI) { 1825 if (isGFX11Plus(STI)) { 1826 for (int Id = UfmtGFX11::UFMT_FIRST; Id <= UfmtGFX11::UFMT_LAST; ++Id) { 1827 if (Name == UfmtSymbolicGFX11[Id]) 1828 return Id; 1829 } 1830 } else { 1831 for (int Id = UfmtGFX10::UFMT_FIRST; Id <= UfmtGFX10::UFMT_LAST; ++Id) { 1832 if (Name == UfmtSymbolicGFX10[Id]) 1833 return Id; 1834 } 1835 } 1836 return UFMT_UNDEF; 1837 } 1838 1839 StringRef getUnifiedFormatName(unsigned Id, const MCSubtargetInfo &STI) { 1840 if(isValidUnifiedFormat(Id, STI)) 1841 return isGFX10(STI) ? UfmtSymbolicGFX10[Id] : UfmtSymbolicGFX11[Id]; 1842 return ""; 1843 } 1844 1845 bool isValidUnifiedFormat(unsigned Id, const MCSubtargetInfo &STI) { 1846 return isGFX10(STI) ? Id <= UfmtGFX10::UFMT_LAST : Id <= UfmtGFX11::UFMT_LAST; 1847 } 1848 1849 int64_t convertDfmtNfmt2Ufmt(unsigned Dfmt, unsigned Nfmt, 1850 const MCSubtargetInfo &STI) { 1851 int64_t Fmt = encodeDfmtNfmt(Dfmt, Nfmt); 1852 if (isGFX11Plus(STI)) { 1853 for (int Id = UfmtGFX11::UFMT_FIRST; Id <= UfmtGFX11::UFMT_LAST; ++Id) { 1854 if (Fmt == DfmtNfmt2UFmtGFX11[Id]) 1855 return Id; 1856 } 1857 } else { 1858 for (int Id = UfmtGFX10::UFMT_FIRST; Id <= UfmtGFX10::UFMT_LAST; ++Id) { 1859 if (Fmt == DfmtNfmt2UFmtGFX10[Id]) 1860 return Id; 1861 } 1862 } 1863 return UFMT_UNDEF; 1864 } 1865 1866 bool isValidFormatEncoding(unsigned Val, const MCSubtargetInfo &STI) { 1867 return isGFX10Plus(STI) ? (Val <= UFMT_MAX) : (Val <= DFMT_NFMT_MAX); 1868 } 1869 1870 unsigned getDefaultFormatEncoding(const MCSubtargetInfo &STI) { 1871 if (isGFX10Plus(STI)) 1872 return UFMT_DEFAULT; 1873 return DFMT_NFMT_DEFAULT; 1874 } 1875 1876 } // namespace MTBUFFormat 1877 1878 //===----------------------------------------------------------------------===// 1879 // SendMsg 1880 //===----------------------------------------------------------------------===// 1881 1882 namespace SendMsg { 1883 1884 static uint64_t getMsgIdMask(const MCSubtargetInfo &STI) { 1885 return isGFX11Plus(STI) ? ID_MASK_GFX11Plus_ : ID_MASK_PreGFX11_; 1886 } 1887 1888 int64_t getMsgId(const StringRef Name, const MCSubtargetInfo &STI) { 1889 int Idx = getOprIdx<const MCSubtargetInfo &>(Name, Msg, MSG_SIZE, STI); 1890 return (Idx < 0) ? Idx : Msg[Idx].Encoding; 1891 } 1892 1893 bool isValidMsgId(int64_t MsgId, const MCSubtargetInfo &STI) { 1894 return (MsgId & ~(getMsgIdMask(STI))) == 0; 1895 } 1896 1897 StringRef getMsgName(int64_t MsgId, const MCSubtargetInfo &STI) { 1898 int Idx = getOprIdx<const MCSubtargetInfo &>(MsgId, Msg, MSG_SIZE, STI); 1899 return (Idx < 0) ? "" : Msg[Idx].Name; 1900 } 1901 1902 int64_t getMsgOpId(int64_t MsgId, const StringRef Name) { 1903 const char* const *S = (MsgId == ID_SYSMSG) ? OpSysSymbolic : OpGsSymbolic; 1904 const int F = (MsgId == ID_SYSMSG) ? OP_SYS_FIRST_ : OP_GS_FIRST_; 1905 const int L = (MsgId == ID_SYSMSG) ? OP_SYS_LAST_ : OP_GS_LAST_; 1906 for (int i = F; i < L; ++i) { 1907 if (Name == S[i]) { 1908 return i; 1909 } 1910 } 1911 return OP_UNKNOWN_; 1912 } 1913 1914 bool isValidMsgOp(int64_t MsgId, int64_t OpId, const MCSubtargetInfo &STI, 1915 bool Strict) { 1916 assert(isValidMsgId(MsgId, STI)); 1917 1918 if (!Strict) 1919 return 0 <= OpId && isUInt<OP_WIDTH_>(OpId); 1920 1921 if (MsgId == ID_SYSMSG) 1922 return OP_SYS_FIRST_ <= OpId && OpId < OP_SYS_LAST_; 1923 if (!isGFX11Plus(STI)) { 1924 switch (MsgId) { 1925 case ID_GS_PreGFX11: 1926 return (OP_GS_FIRST_ <= OpId && OpId < OP_GS_LAST_) && OpId != OP_GS_NOP; 1927 case ID_GS_DONE_PreGFX11: 1928 return OP_GS_FIRST_ <= OpId && OpId < OP_GS_LAST_; 1929 } 1930 } 1931 return OpId == OP_NONE_; 1932 } 1933 1934 StringRef getMsgOpName(int64_t MsgId, int64_t OpId, 1935 const MCSubtargetInfo &STI) { 1936 assert(msgRequiresOp(MsgId, STI)); 1937 return (MsgId == ID_SYSMSG)? OpSysSymbolic[OpId] : OpGsSymbolic[OpId]; 1938 } 1939 1940 bool isValidMsgStream(int64_t MsgId, int64_t OpId, int64_t StreamId, 1941 const MCSubtargetInfo &STI, bool Strict) { 1942 assert(isValidMsgOp(MsgId, OpId, STI, Strict)); 1943 1944 if (!Strict) 1945 return 0 <= StreamId && isUInt<STREAM_ID_WIDTH_>(StreamId); 1946 1947 if (!isGFX11Plus(STI)) { 1948 switch (MsgId) { 1949 case ID_GS_PreGFX11: 1950 return STREAM_ID_FIRST_ <= StreamId && StreamId < STREAM_ID_LAST_; 1951 case ID_GS_DONE_PreGFX11: 1952 return (OpId == OP_GS_NOP) ? 1953 (StreamId == STREAM_ID_NONE_) : 1954 (STREAM_ID_FIRST_ <= StreamId && StreamId < STREAM_ID_LAST_); 1955 } 1956 } 1957 return StreamId == STREAM_ID_NONE_; 1958 } 1959 1960 bool msgRequiresOp(int64_t MsgId, const MCSubtargetInfo &STI) { 1961 return MsgId == ID_SYSMSG || 1962 (!isGFX11Plus(STI) && 1963 (MsgId == ID_GS_PreGFX11 || MsgId == ID_GS_DONE_PreGFX11)); 1964 } 1965 1966 bool msgSupportsStream(int64_t MsgId, int64_t OpId, 1967 const MCSubtargetInfo &STI) { 1968 return !isGFX11Plus(STI) && 1969 (MsgId == ID_GS_PreGFX11 || MsgId == ID_GS_DONE_PreGFX11) && 1970 OpId != OP_GS_NOP; 1971 } 1972 1973 void decodeMsg(unsigned Val, uint16_t &MsgId, uint16_t &OpId, 1974 uint16_t &StreamId, const MCSubtargetInfo &STI) { 1975 MsgId = Val & getMsgIdMask(STI); 1976 if (isGFX11Plus(STI)) { 1977 OpId = 0; 1978 StreamId = 0; 1979 } else { 1980 OpId = (Val & OP_MASK_) >> OP_SHIFT_; 1981 StreamId = (Val & STREAM_ID_MASK_) >> STREAM_ID_SHIFT_; 1982 } 1983 } 1984 1985 uint64_t encodeMsg(uint64_t MsgId, 1986 uint64_t OpId, 1987 uint64_t StreamId) { 1988 return MsgId | (OpId << OP_SHIFT_) | (StreamId << STREAM_ID_SHIFT_); 1989 } 1990 1991 } // namespace SendMsg 1992 1993 //===----------------------------------------------------------------------===// 1994 // 1995 //===----------------------------------------------------------------------===// 1996 1997 unsigned getInitialPSInputAddr(const Function &F) { 1998 return F.getFnAttributeAsParsedInteger("InitialPSInputAddr", 0); 1999 } 2000 2001 bool getHasColorExport(const Function &F) { 2002 // As a safe default always respond as if PS has color exports. 2003 return F.getFnAttributeAsParsedInteger( 2004 "amdgpu-color-export", 2005 F.getCallingConv() == CallingConv::AMDGPU_PS ? 1 : 0) != 0; 2006 } 2007 2008 bool getHasDepthExport(const Function &F) { 2009 return F.getFnAttributeAsParsedInteger("amdgpu-depth-export", 0) != 0; 2010 } 2011 2012 bool isShader(CallingConv::ID cc) { 2013 switch(cc) { 2014 case CallingConv::AMDGPU_VS: 2015 case CallingConv::AMDGPU_LS: 2016 case CallingConv::AMDGPU_HS: 2017 case CallingConv::AMDGPU_ES: 2018 case CallingConv::AMDGPU_GS: 2019 case CallingConv::AMDGPU_PS: 2020 case CallingConv::AMDGPU_CS_Chain: 2021 case CallingConv::AMDGPU_CS_ChainPreserve: 2022 case CallingConv::AMDGPU_CS: 2023 return true; 2024 default: 2025 return false; 2026 } 2027 } 2028 2029 bool isGraphics(CallingConv::ID cc) { 2030 return isShader(cc) || cc == CallingConv::AMDGPU_Gfx; 2031 } 2032 2033 bool isCompute(CallingConv::ID cc) { 2034 return !isGraphics(cc) || cc == CallingConv::AMDGPU_CS; 2035 } 2036 2037 bool isEntryFunctionCC(CallingConv::ID CC) { 2038 switch (CC) { 2039 case CallingConv::AMDGPU_KERNEL: 2040 case CallingConv::SPIR_KERNEL: 2041 case CallingConv::AMDGPU_VS: 2042 case CallingConv::AMDGPU_GS: 2043 case CallingConv::AMDGPU_PS: 2044 case CallingConv::AMDGPU_CS: 2045 case CallingConv::AMDGPU_ES: 2046 case CallingConv::AMDGPU_HS: 2047 case CallingConv::AMDGPU_LS: 2048 return true; 2049 default: 2050 return false; 2051 } 2052 } 2053 2054 bool isModuleEntryFunctionCC(CallingConv::ID CC) { 2055 switch (CC) { 2056 case CallingConv::AMDGPU_Gfx: 2057 return true; 2058 default: 2059 return isEntryFunctionCC(CC) || isChainCC(CC); 2060 } 2061 } 2062 2063 bool isChainCC(CallingConv::ID CC) { 2064 switch (CC) { 2065 case CallingConv::AMDGPU_CS_Chain: 2066 case CallingConv::AMDGPU_CS_ChainPreserve: 2067 return true; 2068 default: 2069 return false; 2070 } 2071 } 2072 2073 bool isKernelCC(const Function *Func) { 2074 return AMDGPU::isModuleEntryFunctionCC(Func->getCallingConv()); 2075 } 2076 2077 bool hasXNACK(const MCSubtargetInfo &STI) { 2078 return STI.hasFeature(AMDGPU::FeatureXNACK); 2079 } 2080 2081 bool hasSRAMECC(const MCSubtargetInfo &STI) { 2082 return STI.hasFeature(AMDGPU::FeatureSRAMECC); 2083 } 2084 2085 bool hasMIMG_R128(const MCSubtargetInfo &STI) { 2086 return STI.hasFeature(AMDGPU::FeatureMIMG_R128) && !STI.hasFeature(AMDGPU::FeatureR128A16); 2087 } 2088 2089 bool hasA16(const MCSubtargetInfo &STI) { 2090 return STI.hasFeature(AMDGPU::FeatureA16); 2091 } 2092 2093 bool hasG16(const MCSubtargetInfo &STI) { 2094 return STI.hasFeature(AMDGPU::FeatureG16); 2095 } 2096 2097 bool hasPackedD16(const MCSubtargetInfo &STI) { 2098 return !STI.hasFeature(AMDGPU::FeatureUnpackedD16VMem) && !isCI(STI) && 2099 !isSI(STI); 2100 } 2101 2102 bool hasGDS(const MCSubtargetInfo &STI) { 2103 return STI.hasFeature(AMDGPU::FeatureGDS); 2104 } 2105 2106 unsigned getNSAMaxSize(const MCSubtargetInfo &STI, bool HasSampler) { 2107 auto Version = getIsaVersion(STI.getCPU()); 2108 if (Version.Major == 10) 2109 return Version.Minor >= 3 ? 13 : 5; 2110 if (Version.Major == 11) 2111 return 5; 2112 if (Version.Major >= 12) 2113 return HasSampler ? 4 : 5; 2114 return 0; 2115 } 2116 2117 unsigned getMaxNumUserSGPRs(const MCSubtargetInfo &STI) { return 16; } 2118 2119 bool isSI(const MCSubtargetInfo &STI) { 2120 return STI.hasFeature(AMDGPU::FeatureSouthernIslands); 2121 } 2122 2123 bool isCI(const MCSubtargetInfo &STI) { 2124 return STI.hasFeature(AMDGPU::FeatureSeaIslands); 2125 } 2126 2127 bool isVI(const MCSubtargetInfo &STI) { 2128 return STI.hasFeature(AMDGPU::FeatureVolcanicIslands); 2129 } 2130 2131 bool isGFX9(const MCSubtargetInfo &STI) { 2132 return STI.hasFeature(AMDGPU::FeatureGFX9); 2133 } 2134 2135 bool isGFX9_GFX10(const MCSubtargetInfo &STI) { 2136 return isGFX9(STI) || isGFX10(STI); 2137 } 2138 2139 bool isGFX9_GFX10_GFX11(const MCSubtargetInfo &STI) { 2140 return isGFX9(STI) || isGFX10(STI) || isGFX11(STI); 2141 } 2142 2143 bool isGFX8_GFX9_GFX10(const MCSubtargetInfo &STI) { 2144 return isVI(STI) || isGFX9(STI) || isGFX10(STI); 2145 } 2146 2147 bool isGFX8Plus(const MCSubtargetInfo &STI) { 2148 return isVI(STI) || isGFX9Plus(STI); 2149 } 2150 2151 bool isGFX9Plus(const MCSubtargetInfo &STI) { 2152 return isGFX9(STI) || isGFX10Plus(STI); 2153 } 2154 2155 bool isGFX10(const MCSubtargetInfo &STI) { 2156 return STI.hasFeature(AMDGPU::FeatureGFX10); 2157 } 2158 2159 bool isGFX10_GFX11(const MCSubtargetInfo &STI) { 2160 return isGFX10(STI) || isGFX11(STI); 2161 } 2162 2163 bool isGFX10Plus(const MCSubtargetInfo &STI) { 2164 return isGFX10(STI) || isGFX11Plus(STI); 2165 } 2166 2167 bool isGFX11(const MCSubtargetInfo &STI) { 2168 return STI.hasFeature(AMDGPU::FeatureGFX11); 2169 } 2170 2171 bool isGFX11Plus(const MCSubtargetInfo &STI) { 2172 return isGFX11(STI) || isGFX12Plus(STI); 2173 } 2174 2175 bool isGFX12(const MCSubtargetInfo &STI) { 2176 return STI.getFeatureBits()[AMDGPU::FeatureGFX12]; 2177 } 2178 2179 bool isGFX12Plus(const MCSubtargetInfo &STI) { return isGFX12(STI); } 2180 2181 bool isNotGFX12Plus(const MCSubtargetInfo &STI) { return !isGFX12Plus(STI); } 2182 2183 bool isNotGFX11Plus(const MCSubtargetInfo &STI) { 2184 return !isGFX11Plus(STI); 2185 } 2186 2187 bool isNotGFX10Plus(const MCSubtargetInfo &STI) { 2188 return isSI(STI) || isCI(STI) || isVI(STI) || isGFX9(STI); 2189 } 2190 2191 bool isGFX10Before1030(const MCSubtargetInfo &STI) { 2192 return isGFX10(STI) && !AMDGPU::isGFX10_BEncoding(STI); 2193 } 2194 2195 bool isGCN3Encoding(const MCSubtargetInfo &STI) { 2196 return STI.hasFeature(AMDGPU::FeatureGCN3Encoding); 2197 } 2198 2199 bool isGFX10_AEncoding(const MCSubtargetInfo &STI) { 2200 return STI.hasFeature(AMDGPU::FeatureGFX10_AEncoding); 2201 } 2202 2203 bool isGFX10_BEncoding(const MCSubtargetInfo &STI) { 2204 return STI.hasFeature(AMDGPU::FeatureGFX10_BEncoding); 2205 } 2206 2207 bool hasGFX10_3Insts(const MCSubtargetInfo &STI) { 2208 return STI.hasFeature(AMDGPU::FeatureGFX10_3Insts); 2209 } 2210 2211 bool isGFX10_3_GFX11(const MCSubtargetInfo &STI) { 2212 return isGFX10_BEncoding(STI) && !isGFX12Plus(STI); 2213 } 2214 2215 bool isGFX90A(const MCSubtargetInfo &STI) { 2216 return STI.hasFeature(AMDGPU::FeatureGFX90AInsts); 2217 } 2218 2219 bool isGFX940(const MCSubtargetInfo &STI) { 2220 return STI.hasFeature(AMDGPU::FeatureGFX940Insts); 2221 } 2222 2223 bool hasArchitectedFlatScratch(const MCSubtargetInfo &STI) { 2224 return STI.hasFeature(AMDGPU::FeatureArchitectedFlatScratch); 2225 } 2226 2227 bool hasMAIInsts(const MCSubtargetInfo &STI) { 2228 return STI.hasFeature(AMDGPU::FeatureMAIInsts); 2229 } 2230 2231 bool hasVOPD(const MCSubtargetInfo &STI) { 2232 return STI.hasFeature(AMDGPU::FeatureVOPD); 2233 } 2234 2235 bool hasDPPSrc1SGPR(const MCSubtargetInfo &STI) { 2236 return STI.hasFeature(AMDGPU::FeatureDPPSrc1SGPR); 2237 } 2238 2239 unsigned hasKernargPreload(const MCSubtargetInfo &STI) { 2240 return STI.hasFeature(AMDGPU::FeatureKernargPreload); 2241 } 2242 2243 int32_t getTotalNumVGPRs(bool has90AInsts, int32_t ArgNumAGPR, 2244 int32_t ArgNumVGPR) { 2245 if (has90AInsts && ArgNumAGPR) 2246 return alignTo(ArgNumVGPR, 4) + ArgNumAGPR; 2247 return std::max(ArgNumVGPR, ArgNumAGPR); 2248 } 2249 2250 bool isSGPR(unsigned Reg, const MCRegisterInfo* TRI) { 2251 const MCRegisterClass SGPRClass = TRI->getRegClass(AMDGPU::SReg_32RegClassID); 2252 const unsigned FirstSubReg = TRI->getSubReg(Reg, AMDGPU::sub0); 2253 return SGPRClass.contains(FirstSubReg != 0 ? FirstSubReg : Reg) || 2254 Reg == AMDGPU::SCC; 2255 } 2256 2257 bool isHi(unsigned Reg, const MCRegisterInfo &MRI) { 2258 return MRI.getEncodingValue(Reg) & AMDGPU::HWEncoding::IS_HI; 2259 } 2260 2261 #define MAP_REG2REG \ 2262 using namespace AMDGPU; \ 2263 switch(Reg) { \ 2264 default: return Reg; \ 2265 CASE_CI_VI(FLAT_SCR) \ 2266 CASE_CI_VI(FLAT_SCR_LO) \ 2267 CASE_CI_VI(FLAT_SCR_HI) \ 2268 CASE_VI_GFX9PLUS(TTMP0) \ 2269 CASE_VI_GFX9PLUS(TTMP1) \ 2270 CASE_VI_GFX9PLUS(TTMP2) \ 2271 CASE_VI_GFX9PLUS(TTMP3) \ 2272 CASE_VI_GFX9PLUS(TTMP4) \ 2273 CASE_VI_GFX9PLUS(TTMP5) \ 2274 CASE_VI_GFX9PLUS(TTMP6) \ 2275 CASE_VI_GFX9PLUS(TTMP7) \ 2276 CASE_VI_GFX9PLUS(TTMP8) \ 2277 CASE_VI_GFX9PLUS(TTMP9) \ 2278 CASE_VI_GFX9PLUS(TTMP10) \ 2279 CASE_VI_GFX9PLUS(TTMP11) \ 2280 CASE_VI_GFX9PLUS(TTMP12) \ 2281 CASE_VI_GFX9PLUS(TTMP13) \ 2282 CASE_VI_GFX9PLUS(TTMP14) \ 2283 CASE_VI_GFX9PLUS(TTMP15) \ 2284 CASE_VI_GFX9PLUS(TTMP0_TTMP1) \ 2285 CASE_VI_GFX9PLUS(TTMP2_TTMP3) \ 2286 CASE_VI_GFX9PLUS(TTMP4_TTMP5) \ 2287 CASE_VI_GFX9PLUS(TTMP6_TTMP7) \ 2288 CASE_VI_GFX9PLUS(TTMP8_TTMP9) \ 2289 CASE_VI_GFX9PLUS(TTMP10_TTMP11) \ 2290 CASE_VI_GFX9PLUS(TTMP12_TTMP13) \ 2291 CASE_VI_GFX9PLUS(TTMP14_TTMP15) \ 2292 CASE_VI_GFX9PLUS(TTMP0_TTMP1_TTMP2_TTMP3) \ 2293 CASE_VI_GFX9PLUS(TTMP4_TTMP5_TTMP6_TTMP7) \ 2294 CASE_VI_GFX9PLUS(TTMP8_TTMP9_TTMP10_TTMP11) \ 2295 CASE_VI_GFX9PLUS(TTMP12_TTMP13_TTMP14_TTMP15) \ 2296 CASE_VI_GFX9PLUS(TTMP0_TTMP1_TTMP2_TTMP3_TTMP4_TTMP5_TTMP6_TTMP7) \ 2297 CASE_VI_GFX9PLUS(TTMP4_TTMP5_TTMP6_TTMP7_TTMP8_TTMP9_TTMP10_TTMP11) \ 2298 CASE_VI_GFX9PLUS(TTMP8_TTMP9_TTMP10_TTMP11_TTMP12_TTMP13_TTMP14_TTMP15) \ 2299 CASE_VI_GFX9PLUS(TTMP0_TTMP1_TTMP2_TTMP3_TTMP4_TTMP5_TTMP6_TTMP7_TTMP8_TTMP9_TTMP10_TTMP11_TTMP12_TTMP13_TTMP14_TTMP15) \ 2300 CASE_GFXPRE11_GFX11PLUS(M0) \ 2301 CASE_GFXPRE11_GFX11PLUS(SGPR_NULL) \ 2302 CASE_GFXPRE11_GFX11PLUS_TO(SGPR_NULL64, SGPR_NULL) \ 2303 } 2304 2305 #define CASE_CI_VI(node) \ 2306 assert(!isSI(STI)); \ 2307 case node: return isCI(STI) ? node##_ci : node##_vi; 2308 2309 #define CASE_VI_GFX9PLUS(node) \ 2310 case node: return isGFX9Plus(STI) ? node##_gfx9plus : node##_vi; 2311 2312 #define CASE_GFXPRE11_GFX11PLUS(node) \ 2313 case node: return isGFX11Plus(STI) ? node##_gfx11plus : node##_gfxpre11; 2314 2315 #define CASE_GFXPRE11_GFX11PLUS_TO(node, result) \ 2316 case node: return isGFX11Plus(STI) ? result##_gfx11plus : result##_gfxpre11; 2317 2318 unsigned getMCReg(unsigned Reg, const MCSubtargetInfo &STI) { 2319 if (STI.getTargetTriple().getArch() == Triple::r600) 2320 return Reg; 2321 MAP_REG2REG 2322 } 2323 2324 #undef CASE_CI_VI 2325 #undef CASE_VI_GFX9PLUS 2326 #undef CASE_GFXPRE11_GFX11PLUS 2327 #undef CASE_GFXPRE11_GFX11PLUS_TO 2328 2329 #define CASE_CI_VI(node) case node##_ci: case node##_vi: return node; 2330 #define CASE_VI_GFX9PLUS(node) case node##_vi: case node##_gfx9plus: return node; 2331 #define CASE_GFXPRE11_GFX11PLUS(node) case node##_gfx11plus: case node##_gfxpre11: return node; 2332 #define CASE_GFXPRE11_GFX11PLUS_TO(node, result) 2333 2334 unsigned mc2PseudoReg(unsigned Reg) { 2335 MAP_REG2REG 2336 } 2337 2338 bool isInlineValue(unsigned Reg) { 2339 switch (Reg) { 2340 case AMDGPU::SRC_SHARED_BASE_LO: 2341 case AMDGPU::SRC_SHARED_BASE: 2342 case AMDGPU::SRC_SHARED_LIMIT_LO: 2343 case AMDGPU::SRC_SHARED_LIMIT: 2344 case AMDGPU::SRC_PRIVATE_BASE_LO: 2345 case AMDGPU::SRC_PRIVATE_BASE: 2346 case AMDGPU::SRC_PRIVATE_LIMIT_LO: 2347 case AMDGPU::SRC_PRIVATE_LIMIT: 2348 case AMDGPU::SRC_POPS_EXITING_WAVE_ID: 2349 return true; 2350 case AMDGPU::SRC_VCCZ: 2351 case AMDGPU::SRC_EXECZ: 2352 case AMDGPU::SRC_SCC: 2353 return true; 2354 case AMDGPU::SGPR_NULL: 2355 return true; 2356 default: 2357 return false; 2358 } 2359 } 2360 2361 #undef CASE_CI_VI 2362 #undef CASE_VI_GFX9PLUS 2363 #undef CASE_GFXPRE11_GFX11PLUS 2364 #undef CASE_GFXPRE11_GFX11PLUS_TO 2365 #undef MAP_REG2REG 2366 2367 bool isSISrcOperand(const MCInstrDesc &Desc, unsigned OpNo) { 2368 assert(OpNo < Desc.NumOperands); 2369 unsigned OpType = Desc.operands()[OpNo].OperandType; 2370 return OpType >= AMDGPU::OPERAND_SRC_FIRST && 2371 OpType <= AMDGPU::OPERAND_SRC_LAST; 2372 } 2373 2374 bool isKImmOperand(const MCInstrDesc &Desc, unsigned OpNo) { 2375 assert(OpNo < Desc.NumOperands); 2376 unsigned OpType = Desc.operands()[OpNo].OperandType; 2377 return OpType >= AMDGPU::OPERAND_KIMM_FIRST && 2378 OpType <= AMDGPU::OPERAND_KIMM_LAST; 2379 } 2380 2381 bool isSISrcFPOperand(const MCInstrDesc &Desc, unsigned OpNo) { 2382 assert(OpNo < Desc.NumOperands); 2383 unsigned OpType = Desc.operands()[OpNo].OperandType; 2384 switch (OpType) { 2385 case AMDGPU::OPERAND_REG_IMM_FP32: 2386 case AMDGPU::OPERAND_REG_IMM_FP32_DEFERRED: 2387 case AMDGPU::OPERAND_REG_IMM_FP64: 2388 case AMDGPU::OPERAND_REG_IMM_FP16: 2389 case AMDGPU::OPERAND_REG_IMM_FP16_DEFERRED: 2390 case AMDGPU::OPERAND_REG_IMM_V2FP16: 2391 case AMDGPU::OPERAND_REG_INLINE_C_FP32: 2392 case AMDGPU::OPERAND_REG_INLINE_C_FP64: 2393 case AMDGPU::OPERAND_REG_INLINE_C_FP16: 2394 case AMDGPU::OPERAND_REG_INLINE_C_V2FP16: 2395 case AMDGPU::OPERAND_REG_INLINE_AC_FP32: 2396 case AMDGPU::OPERAND_REG_INLINE_AC_FP16: 2397 case AMDGPU::OPERAND_REG_INLINE_AC_V2FP16: 2398 case AMDGPU::OPERAND_REG_IMM_V2FP32: 2399 case AMDGPU::OPERAND_REG_INLINE_C_V2FP32: 2400 case AMDGPU::OPERAND_REG_INLINE_AC_FP64: 2401 return true; 2402 default: 2403 return false; 2404 } 2405 } 2406 2407 bool isSISrcInlinableOperand(const MCInstrDesc &Desc, unsigned OpNo) { 2408 assert(OpNo < Desc.NumOperands); 2409 unsigned OpType = Desc.operands()[OpNo].OperandType; 2410 return (OpType >= AMDGPU::OPERAND_REG_INLINE_C_FIRST && 2411 OpType <= AMDGPU::OPERAND_REG_INLINE_C_LAST) || 2412 (OpType >= AMDGPU::OPERAND_REG_INLINE_AC_FIRST && 2413 OpType <= AMDGPU::OPERAND_REG_INLINE_AC_LAST); 2414 } 2415 2416 // Avoid using MCRegisterClass::getSize, since that function will go away 2417 // (move from MC* level to Target* level). Return size in bits. 2418 unsigned getRegBitWidth(unsigned RCID) { 2419 switch (RCID) { 2420 case AMDGPU::SGPR_LO16RegClassID: 2421 case AMDGPU::AGPR_LO16RegClassID: 2422 return 16; 2423 case AMDGPU::SGPR_32RegClassID: 2424 case AMDGPU::VGPR_32RegClassID: 2425 case AMDGPU::VRegOrLds_32RegClassID: 2426 case AMDGPU::AGPR_32RegClassID: 2427 case AMDGPU::VS_32RegClassID: 2428 case AMDGPU::AV_32RegClassID: 2429 case AMDGPU::SReg_32RegClassID: 2430 case AMDGPU::SReg_32_XM0RegClassID: 2431 case AMDGPU::SRegOrLds_32RegClassID: 2432 return 32; 2433 case AMDGPU::SGPR_64RegClassID: 2434 case AMDGPU::VS_64RegClassID: 2435 case AMDGPU::SReg_64RegClassID: 2436 case AMDGPU::VReg_64RegClassID: 2437 case AMDGPU::AReg_64RegClassID: 2438 case AMDGPU::SReg_64_XEXECRegClassID: 2439 case AMDGPU::VReg_64_Align2RegClassID: 2440 case AMDGPU::AReg_64_Align2RegClassID: 2441 case AMDGPU::AV_64RegClassID: 2442 case AMDGPU::AV_64_Align2RegClassID: 2443 return 64; 2444 case AMDGPU::SGPR_96RegClassID: 2445 case AMDGPU::SReg_96RegClassID: 2446 case AMDGPU::VReg_96RegClassID: 2447 case AMDGPU::AReg_96RegClassID: 2448 case AMDGPU::VReg_96_Align2RegClassID: 2449 case AMDGPU::AReg_96_Align2RegClassID: 2450 case AMDGPU::AV_96RegClassID: 2451 case AMDGPU::AV_96_Align2RegClassID: 2452 return 96; 2453 case AMDGPU::SGPR_128RegClassID: 2454 case AMDGPU::SReg_128RegClassID: 2455 case AMDGPU::VReg_128RegClassID: 2456 case AMDGPU::AReg_128RegClassID: 2457 case AMDGPU::VReg_128_Align2RegClassID: 2458 case AMDGPU::AReg_128_Align2RegClassID: 2459 case AMDGPU::AV_128RegClassID: 2460 case AMDGPU::AV_128_Align2RegClassID: 2461 return 128; 2462 case AMDGPU::SGPR_160RegClassID: 2463 case AMDGPU::SReg_160RegClassID: 2464 case AMDGPU::VReg_160RegClassID: 2465 case AMDGPU::AReg_160RegClassID: 2466 case AMDGPU::VReg_160_Align2RegClassID: 2467 case AMDGPU::AReg_160_Align2RegClassID: 2468 case AMDGPU::AV_160RegClassID: 2469 case AMDGPU::AV_160_Align2RegClassID: 2470 return 160; 2471 case AMDGPU::SGPR_192RegClassID: 2472 case AMDGPU::SReg_192RegClassID: 2473 case AMDGPU::VReg_192RegClassID: 2474 case AMDGPU::AReg_192RegClassID: 2475 case AMDGPU::VReg_192_Align2RegClassID: 2476 case AMDGPU::AReg_192_Align2RegClassID: 2477 case AMDGPU::AV_192RegClassID: 2478 case AMDGPU::AV_192_Align2RegClassID: 2479 return 192; 2480 case AMDGPU::SGPR_224RegClassID: 2481 case AMDGPU::SReg_224RegClassID: 2482 case AMDGPU::VReg_224RegClassID: 2483 case AMDGPU::AReg_224RegClassID: 2484 case AMDGPU::VReg_224_Align2RegClassID: 2485 case AMDGPU::AReg_224_Align2RegClassID: 2486 case AMDGPU::AV_224RegClassID: 2487 case AMDGPU::AV_224_Align2RegClassID: 2488 return 224; 2489 case AMDGPU::SGPR_256RegClassID: 2490 case AMDGPU::SReg_256RegClassID: 2491 case AMDGPU::VReg_256RegClassID: 2492 case AMDGPU::AReg_256RegClassID: 2493 case AMDGPU::VReg_256_Align2RegClassID: 2494 case AMDGPU::AReg_256_Align2RegClassID: 2495 case AMDGPU::AV_256RegClassID: 2496 case AMDGPU::AV_256_Align2RegClassID: 2497 return 256; 2498 case AMDGPU::SGPR_288RegClassID: 2499 case AMDGPU::SReg_288RegClassID: 2500 case AMDGPU::VReg_288RegClassID: 2501 case AMDGPU::AReg_288RegClassID: 2502 case AMDGPU::VReg_288_Align2RegClassID: 2503 case AMDGPU::AReg_288_Align2RegClassID: 2504 case AMDGPU::AV_288RegClassID: 2505 case AMDGPU::AV_288_Align2RegClassID: 2506 return 288; 2507 case AMDGPU::SGPR_320RegClassID: 2508 case AMDGPU::SReg_320RegClassID: 2509 case AMDGPU::VReg_320RegClassID: 2510 case AMDGPU::AReg_320RegClassID: 2511 case AMDGPU::VReg_320_Align2RegClassID: 2512 case AMDGPU::AReg_320_Align2RegClassID: 2513 case AMDGPU::AV_320RegClassID: 2514 case AMDGPU::AV_320_Align2RegClassID: 2515 return 320; 2516 case AMDGPU::SGPR_352RegClassID: 2517 case AMDGPU::SReg_352RegClassID: 2518 case AMDGPU::VReg_352RegClassID: 2519 case AMDGPU::AReg_352RegClassID: 2520 case AMDGPU::VReg_352_Align2RegClassID: 2521 case AMDGPU::AReg_352_Align2RegClassID: 2522 case AMDGPU::AV_352RegClassID: 2523 case AMDGPU::AV_352_Align2RegClassID: 2524 return 352; 2525 case AMDGPU::SGPR_384RegClassID: 2526 case AMDGPU::SReg_384RegClassID: 2527 case AMDGPU::VReg_384RegClassID: 2528 case AMDGPU::AReg_384RegClassID: 2529 case AMDGPU::VReg_384_Align2RegClassID: 2530 case AMDGPU::AReg_384_Align2RegClassID: 2531 case AMDGPU::AV_384RegClassID: 2532 case AMDGPU::AV_384_Align2RegClassID: 2533 return 384; 2534 case AMDGPU::SGPR_512RegClassID: 2535 case AMDGPU::SReg_512RegClassID: 2536 case AMDGPU::VReg_512RegClassID: 2537 case AMDGPU::AReg_512RegClassID: 2538 case AMDGPU::VReg_512_Align2RegClassID: 2539 case AMDGPU::AReg_512_Align2RegClassID: 2540 case AMDGPU::AV_512RegClassID: 2541 case AMDGPU::AV_512_Align2RegClassID: 2542 return 512; 2543 case AMDGPU::SGPR_1024RegClassID: 2544 case AMDGPU::SReg_1024RegClassID: 2545 case AMDGPU::VReg_1024RegClassID: 2546 case AMDGPU::AReg_1024RegClassID: 2547 case AMDGPU::VReg_1024_Align2RegClassID: 2548 case AMDGPU::AReg_1024_Align2RegClassID: 2549 case AMDGPU::AV_1024RegClassID: 2550 case AMDGPU::AV_1024_Align2RegClassID: 2551 return 1024; 2552 default: 2553 llvm_unreachable("Unexpected register class"); 2554 } 2555 } 2556 2557 unsigned getRegBitWidth(const MCRegisterClass &RC) { 2558 return getRegBitWidth(RC.getID()); 2559 } 2560 2561 unsigned getRegOperandSize(const MCRegisterInfo *MRI, const MCInstrDesc &Desc, 2562 unsigned OpNo) { 2563 assert(OpNo < Desc.NumOperands); 2564 unsigned RCID = Desc.operands()[OpNo].RegClass; 2565 return getRegBitWidth(RCID) / 8; 2566 } 2567 2568 bool isInlinableLiteral64(int64_t Literal, bool HasInv2Pi) { 2569 if (isInlinableIntLiteral(Literal)) 2570 return true; 2571 2572 uint64_t Val = static_cast<uint64_t>(Literal); 2573 return (Val == llvm::bit_cast<uint64_t>(0.0)) || 2574 (Val == llvm::bit_cast<uint64_t>(1.0)) || 2575 (Val == llvm::bit_cast<uint64_t>(-1.0)) || 2576 (Val == llvm::bit_cast<uint64_t>(0.5)) || 2577 (Val == llvm::bit_cast<uint64_t>(-0.5)) || 2578 (Val == llvm::bit_cast<uint64_t>(2.0)) || 2579 (Val == llvm::bit_cast<uint64_t>(-2.0)) || 2580 (Val == llvm::bit_cast<uint64_t>(4.0)) || 2581 (Val == llvm::bit_cast<uint64_t>(-4.0)) || 2582 (Val == 0x3fc45f306dc9c882 && HasInv2Pi); 2583 } 2584 2585 bool isInlinableLiteral32(int32_t Literal, bool HasInv2Pi) { 2586 if (isInlinableIntLiteral(Literal)) 2587 return true; 2588 2589 // The actual type of the operand does not seem to matter as long 2590 // as the bits match one of the inline immediate values. For example: 2591 // 2592 // -nan has the hexadecimal encoding of 0xfffffffe which is -2 in decimal, 2593 // so it is a legal inline immediate. 2594 // 2595 // 1065353216 has the hexadecimal encoding 0x3f800000 which is 1.0f in 2596 // floating-point, so it is a legal inline immediate. 2597 2598 uint32_t Val = static_cast<uint32_t>(Literal); 2599 return (Val == llvm::bit_cast<uint32_t>(0.0f)) || 2600 (Val == llvm::bit_cast<uint32_t>(1.0f)) || 2601 (Val == llvm::bit_cast<uint32_t>(-1.0f)) || 2602 (Val == llvm::bit_cast<uint32_t>(0.5f)) || 2603 (Val == llvm::bit_cast<uint32_t>(-0.5f)) || 2604 (Val == llvm::bit_cast<uint32_t>(2.0f)) || 2605 (Val == llvm::bit_cast<uint32_t>(-2.0f)) || 2606 (Val == llvm::bit_cast<uint32_t>(4.0f)) || 2607 (Val == llvm::bit_cast<uint32_t>(-4.0f)) || 2608 (Val == 0x3e22f983 && HasInv2Pi); 2609 } 2610 2611 bool isInlinableLiteral16(int16_t Literal, bool HasInv2Pi) { 2612 if (!HasInv2Pi) 2613 return false; 2614 2615 if (isInlinableIntLiteral(Literal)) 2616 return true; 2617 2618 uint16_t Val = static_cast<uint16_t>(Literal); 2619 return Val == 0x3C00 || // 1.0 2620 Val == 0xBC00 || // -1.0 2621 Val == 0x3800 || // 0.5 2622 Val == 0xB800 || // -0.5 2623 Val == 0x4000 || // 2.0 2624 Val == 0xC000 || // -2.0 2625 Val == 0x4400 || // 4.0 2626 Val == 0xC400 || // -4.0 2627 Val == 0x3118; // 1/2pi 2628 } 2629 2630 std::optional<unsigned> getInlineEncodingV216(bool IsFloat, uint32_t Literal) { 2631 // Unfortunately, the Instruction Set Architecture Reference Guide is 2632 // misleading about how the inline operands work for (packed) 16-bit 2633 // instructions. In a nutshell, the actual HW behavior is: 2634 // 2635 // - integer encodings (-16 .. 64) are always produced as sign-extended 2636 // 32-bit values 2637 // - float encodings are produced as: 2638 // - for F16 instructions: corresponding half-precision float values in 2639 // the LSBs, 0 in the MSBs 2640 // - for UI16 instructions: corresponding single-precision float value 2641 int32_t Signed = static_cast<int32_t>(Literal); 2642 if (Signed >= 0 && Signed <= 64) 2643 return 128 + Signed; 2644 2645 if (Signed >= -16 && Signed <= -1) 2646 return 192 + std::abs(Signed); 2647 2648 if (IsFloat) { 2649 // clang-format off 2650 switch (Literal) { 2651 case 0x3800: return 240; // 0.5 2652 case 0xB800: return 241; // -0.5 2653 case 0x3C00: return 242; // 1.0 2654 case 0xBC00: return 243; // -1.0 2655 case 0x4000: return 244; // 2.0 2656 case 0xC000: return 245; // -2.0 2657 case 0x4400: return 246; // 4.0 2658 case 0xC400: return 247; // -4.0 2659 case 0x3118: return 248; // 1.0 / (2.0 * pi) 2660 default: break; 2661 } 2662 // clang-format on 2663 } else { 2664 // clang-format off 2665 switch (Literal) { 2666 case 0x3F000000: return 240; // 0.5 2667 case 0xBF000000: return 241; // -0.5 2668 case 0x3F800000: return 242; // 1.0 2669 case 0xBF800000: return 243; // -1.0 2670 case 0x40000000: return 244; // 2.0 2671 case 0xC0000000: return 245; // -2.0 2672 case 0x40800000: return 246; // 4.0 2673 case 0xC0800000: return 247; // -4.0 2674 case 0x3E22F983: return 248; // 1.0 / (2.0 * pi) 2675 default: break; 2676 } 2677 // clang-format on 2678 } 2679 2680 return {}; 2681 } 2682 2683 // Encoding of the literal as an inline constant for a V_PK_*_IU16 instruction 2684 // or nullopt. 2685 std::optional<unsigned> getInlineEncodingV2I16(uint32_t Literal) { 2686 return getInlineEncodingV216(false, Literal); 2687 } 2688 2689 // Encoding of the literal as an inline constant for a V_PK_*_F16 instruction 2690 // or nullopt. 2691 std::optional<unsigned> getInlineEncodingV2F16(uint32_t Literal) { 2692 return getInlineEncodingV216(true, Literal); 2693 } 2694 2695 // Whether the given literal can be inlined for a V_PK_* instruction. 2696 bool isInlinableLiteralV216(uint32_t Literal, uint8_t OpType) { 2697 switch (OpType) { 2698 case AMDGPU::OPERAND_REG_IMM_V2INT16: 2699 case AMDGPU::OPERAND_REG_INLINE_C_V2INT16: 2700 case AMDGPU::OPERAND_REG_INLINE_AC_V2INT16: 2701 return getInlineEncodingV216(false, Literal).has_value(); 2702 case AMDGPU::OPERAND_REG_IMM_V2FP16: 2703 case AMDGPU::OPERAND_REG_INLINE_C_V2FP16: 2704 case AMDGPU::OPERAND_REG_INLINE_AC_V2FP16: 2705 return getInlineEncodingV216(true, Literal).has_value(); 2706 default: 2707 llvm_unreachable("bad packed operand type"); 2708 } 2709 } 2710 2711 // Whether the given literal can be inlined for a V_PK_*_IU16 instruction. 2712 bool isInlinableLiteralV2I16(uint32_t Literal) { 2713 return getInlineEncodingV2I16(Literal).has_value(); 2714 } 2715 2716 // Whether the given literal can be inlined for a V_PK_*_F16 instruction. 2717 bool isInlinableLiteralV2F16(uint32_t Literal) { 2718 return getInlineEncodingV2F16(Literal).has_value(); 2719 } 2720 2721 bool isValid32BitLiteral(uint64_t Val, bool IsFP64) { 2722 if (IsFP64) 2723 return !(Val & 0xffffffffu); 2724 2725 return isUInt<32>(Val) || isInt<32>(Val); 2726 } 2727 2728 bool isArgPassedInSGPR(const Argument *A) { 2729 const Function *F = A->getParent(); 2730 2731 // Arguments to compute shaders are never a source of divergence. 2732 CallingConv::ID CC = F->getCallingConv(); 2733 switch (CC) { 2734 case CallingConv::AMDGPU_KERNEL: 2735 case CallingConv::SPIR_KERNEL: 2736 return true; 2737 case CallingConv::AMDGPU_VS: 2738 case CallingConv::AMDGPU_LS: 2739 case CallingConv::AMDGPU_HS: 2740 case CallingConv::AMDGPU_ES: 2741 case CallingConv::AMDGPU_GS: 2742 case CallingConv::AMDGPU_PS: 2743 case CallingConv::AMDGPU_CS: 2744 case CallingConv::AMDGPU_Gfx: 2745 case CallingConv::AMDGPU_CS_Chain: 2746 case CallingConv::AMDGPU_CS_ChainPreserve: 2747 // For non-compute shaders, SGPR inputs are marked with either inreg or 2748 // byval. Everything else is in VGPRs. 2749 return A->hasAttribute(Attribute::InReg) || 2750 A->hasAttribute(Attribute::ByVal); 2751 default: 2752 // TODO: treat i1 as divergent? 2753 return A->hasAttribute(Attribute::InReg); 2754 } 2755 } 2756 2757 bool isArgPassedInSGPR(const CallBase *CB, unsigned ArgNo) { 2758 // Arguments to compute shaders are never a source of divergence. 2759 CallingConv::ID CC = CB->getCallingConv(); 2760 switch (CC) { 2761 case CallingConv::AMDGPU_KERNEL: 2762 case CallingConv::SPIR_KERNEL: 2763 return true; 2764 case CallingConv::AMDGPU_VS: 2765 case CallingConv::AMDGPU_LS: 2766 case CallingConv::AMDGPU_HS: 2767 case CallingConv::AMDGPU_ES: 2768 case CallingConv::AMDGPU_GS: 2769 case CallingConv::AMDGPU_PS: 2770 case CallingConv::AMDGPU_CS: 2771 case CallingConv::AMDGPU_Gfx: 2772 case CallingConv::AMDGPU_CS_Chain: 2773 case CallingConv::AMDGPU_CS_ChainPreserve: 2774 // For non-compute shaders, SGPR inputs are marked with either inreg or 2775 // byval. Everything else is in VGPRs. 2776 return CB->paramHasAttr(ArgNo, Attribute::InReg) || 2777 CB->paramHasAttr(ArgNo, Attribute::ByVal); 2778 default: 2779 return CB->paramHasAttr(ArgNo, Attribute::InReg); 2780 } 2781 } 2782 2783 static bool hasSMEMByteOffset(const MCSubtargetInfo &ST) { 2784 return isGCN3Encoding(ST) || isGFX10Plus(ST); 2785 } 2786 2787 static bool hasSMRDSignedImmOffset(const MCSubtargetInfo &ST) { 2788 return isGFX9Plus(ST); 2789 } 2790 2791 bool isLegalSMRDEncodedUnsignedOffset(const MCSubtargetInfo &ST, 2792 int64_t EncodedOffset) { 2793 if (isGFX12Plus(ST)) 2794 return isUInt<23>(EncodedOffset); 2795 2796 return hasSMEMByteOffset(ST) ? isUInt<20>(EncodedOffset) 2797 : isUInt<8>(EncodedOffset); 2798 } 2799 2800 bool isLegalSMRDEncodedSignedOffset(const MCSubtargetInfo &ST, 2801 int64_t EncodedOffset, 2802 bool IsBuffer) { 2803 if (isGFX12Plus(ST)) 2804 return isInt<24>(EncodedOffset); 2805 2806 return !IsBuffer && 2807 hasSMRDSignedImmOffset(ST) && 2808 isInt<21>(EncodedOffset); 2809 } 2810 2811 static bool isDwordAligned(uint64_t ByteOffset) { 2812 return (ByteOffset & 3) == 0; 2813 } 2814 2815 uint64_t convertSMRDOffsetUnits(const MCSubtargetInfo &ST, 2816 uint64_t ByteOffset) { 2817 if (hasSMEMByteOffset(ST)) 2818 return ByteOffset; 2819 2820 assert(isDwordAligned(ByteOffset)); 2821 return ByteOffset >> 2; 2822 } 2823 2824 std::optional<int64_t> getSMRDEncodedOffset(const MCSubtargetInfo &ST, 2825 int64_t ByteOffset, bool IsBuffer) { 2826 if (isGFX12Plus(ST)) // 24 bit signed offsets 2827 return isInt<24>(ByteOffset) ? std::optional<int64_t>(ByteOffset) 2828 : std::nullopt; 2829 2830 // The signed version is always a byte offset. 2831 if (!IsBuffer && hasSMRDSignedImmOffset(ST)) { 2832 assert(hasSMEMByteOffset(ST)); 2833 return isInt<20>(ByteOffset) ? std::optional<int64_t>(ByteOffset) 2834 : std::nullopt; 2835 } 2836 2837 if (!isDwordAligned(ByteOffset) && !hasSMEMByteOffset(ST)) 2838 return std::nullopt; 2839 2840 int64_t EncodedOffset = convertSMRDOffsetUnits(ST, ByteOffset); 2841 return isLegalSMRDEncodedUnsignedOffset(ST, EncodedOffset) 2842 ? std::optional<int64_t>(EncodedOffset) 2843 : std::nullopt; 2844 } 2845 2846 std::optional<int64_t> getSMRDEncodedLiteralOffset32(const MCSubtargetInfo &ST, 2847 int64_t ByteOffset) { 2848 if (!isCI(ST) || !isDwordAligned(ByteOffset)) 2849 return std::nullopt; 2850 2851 int64_t EncodedOffset = convertSMRDOffsetUnits(ST, ByteOffset); 2852 return isUInt<32>(EncodedOffset) ? std::optional<int64_t>(EncodedOffset) 2853 : std::nullopt; 2854 } 2855 2856 unsigned getNumFlatOffsetBits(const MCSubtargetInfo &ST) { 2857 if (AMDGPU::isGFX10(ST)) 2858 return 12; 2859 2860 if (AMDGPU::isGFX12(ST)) 2861 return 24; 2862 return 13; 2863 } 2864 2865 namespace { 2866 2867 struct SourceOfDivergence { 2868 unsigned Intr; 2869 }; 2870 const SourceOfDivergence *lookupSourceOfDivergence(unsigned Intr); 2871 2872 struct AlwaysUniform { 2873 unsigned Intr; 2874 }; 2875 const AlwaysUniform *lookupAlwaysUniform(unsigned Intr); 2876 2877 #define GET_SourcesOfDivergence_IMPL 2878 #define GET_UniformIntrinsics_IMPL 2879 #define GET_Gfx9BufferFormat_IMPL 2880 #define GET_Gfx10BufferFormat_IMPL 2881 #define GET_Gfx11PlusBufferFormat_IMPL 2882 #include "AMDGPUGenSearchableTables.inc" 2883 2884 } // end anonymous namespace 2885 2886 bool isIntrinsicSourceOfDivergence(unsigned IntrID) { 2887 return lookupSourceOfDivergence(IntrID); 2888 } 2889 2890 bool isIntrinsicAlwaysUniform(unsigned IntrID) { 2891 return lookupAlwaysUniform(IntrID); 2892 } 2893 2894 const GcnBufferFormatInfo *getGcnBufferFormatInfo(uint8_t BitsPerComp, 2895 uint8_t NumComponents, 2896 uint8_t NumFormat, 2897 const MCSubtargetInfo &STI) { 2898 return isGFX11Plus(STI) 2899 ? getGfx11PlusBufferFormatInfo(BitsPerComp, NumComponents, 2900 NumFormat) 2901 : isGFX10(STI) ? getGfx10BufferFormatInfo(BitsPerComp, 2902 NumComponents, NumFormat) 2903 : getGfx9BufferFormatInfo(BitsPerComp, 2904 NumComponents, NumFormat); 2905 } 2906 2907 const GcnBufferFormatInfo *getGcnBufferFormatInfo(uint8_t Format, 2908 const MCSubtargetInfo &STI) { 2909 return isGFX11Plus(STI) ? getGfx11PlusBufferFormatInfo(Format) 2910 : isGFX10(STI) ? getGfx10BufferFormatInfo(Format) 2911 : getGfx9BufferFormatInfo(Format); 2912 } 2913 2914 bool hasAny64BitVGPROperands(const MCInstrDesc &OpDesc) { 2915 for (auto OpName : { OpName::vdst, OpName::src0, OpName::src1, 2916 OpName::src2 }) { 2917 int Idx = getNamedOperandIdx(OpDesc.getOpcode(), OpName); 2918 if (Idx == -1) 2919 continue; 2920 2921 if (OpDesc.operands()[Idx].RegClass == AMDGPU::VReg_64RegClassID || 2922 OpDesc.operands()[Idx].RegClass == AMDGPU::VReg_64_Align2RegClassID) 2923 return true; 2924 } 2925 2926 return false; 2927 } 2928 2929 bool isDPALU_DPP(const MCInstrDesc &OpDesc) { 2930 return hasAny64BitVGPROperands(OpDesc); 2931 } 2932 2933 } // namespace AMDGPU 2934 2935 raw_ostream &operator<<(raw_ostream &OS, 2936 const AMDGPU::IsaInfo::TargetIDSetting S) { 2937 switch (S) { 2938 case (AMDGPU::IsaInfo::TargetIDSetting::Unsupported): 2939 OS << "Unsupported"; 2940 break; 2941 case (AMDGPU::IsaInfo::TargetIDSetting::Any): 2942 OS << "Any"; 2943 break; 2944 case (AMDGPU::IsaInfo::TargetIDSetting::Off): 2945 OS << "Off"; 2946 break; 2947 case (AMDGPU::IsaInfo::TargetIDSetting::On): 2948 OS << "On"; 2949 break; 2950 } 2951 return OS; 2952 } 2953 2954 } // namespace llvm 2955