10b57cec5SDimitry Andric //===-- AMDGPUPALMetadata.cpp - Accumulate and print AMDGPU PAL metadata -===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric /// \file 100b57cec5SDimitry Andric /// 110b57cec5SDimitry Andric /// This class has methods called by AMDGPUAsmPrinter to accumulate and print 120b57cec5SDimitry Andric /// the PAL metadata. 130b57cec5SDimitry Andric // 140b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 150b57cec5SDimitry Andric // 160b57cec5SDimitry Andric 170b57cec5SDimitry Andric #include "AMDGPUPALMetadata.h" 18e8d8bef9SDimitry Andric #include "AMDGPUPTNote.h" 190b57cec5SDimitry Andric #include "SIDefines.h" 200b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELF.h" 218bcb0991SDimitry Andric #include "llvm/IR/Constants.h" 228bcb0991SDimitry Andric #include "llvm/IR/Module.h" 23*0fca6ea1SDimitry Andric #include "llvm/MC/MCExpr.h" 240b57cec5SDimitry Andric #include "llvm/Support/AMDGPUMetadata.h" 250b57cec5SDimitry Andric #include "llvm/Support/EndianStream.h" 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric using namespace llvm; 280b57cec5SDimitry Andric using namespace llvm::AMDGPU; 290b57cec5SDimitry Andric 300b57cec5SDimitry Andric // Read the PAL metadata from IR metadata, where it was put by the frontend. 310b57cec5SDimitry Andric void AMDGPUPALMetadata::readFromIR(Module &M) { 320b57cec5SDimitry Andric auto NamedMD = M.getNamedMetadata("amdgpu.pal.metadata.msgpack"); 330b57cec5SDimitry Andric if (NamedMD && NamedMD->getNumOperands()) { 340b57cec5SDimitry Andric // This is the new msgpack format for metadata. It is a NamedMD containing 350b57cec5SDimitry Andric // an MDTuple containing an MDString containing the msgpack data. 360b57cec5SDimitry Andric BlobType = ELF::NT_AMDGPU_METADATA; 370b57cec5SDimitry Andric auto MDN = dyn_cast<MDTuple>(NamedMD->getOperand(0)); 380b57cec5SDimitry Andric if (MDN && MDN->getNumOperands()) { 390b57cec5SDimitry Andric if (auto MDS = dyn_cast<MDString>(MDN->getOperand(0))) 400b57cec5SDimitry Andric setFromMsgPackBlob(MDS->getString()); 410b57cec5SDimitry Andric } 420b57cec5SDimitry Andric return; 430b57cec5SDimitry Andric } 44fe6060f1SDimitry Andric BlobType = ELF::NT_AMD_PAL_METADATA; 450b57cec5SDimitry Andric NamedMD = M.getNamedMetadata("amdgpu.pal.metadata"); 46e8d8bef9SDimitry Andric if (!NamedMD || !NamedMD->getNumOperands()) { 47e8d8bef9SDimitry Andric // Emit msgpack metadata by default 48e8d8bef9SDimitry Andric BlobType = ELF::NT_AMDGPU_METADATA; 490b57cec5SDimitry Andric return; 50e8d8bef9SDimitry Andric } 510b57cec5SDimitry Andric // This is the old reg=value pair format for metadata. It is a NamedMD 520b57cec5SDimitry Andric // containing an MDTuple containing a number of MDNodes each of which is an 530b57cec5SDimitry Andric // integer value, and each two integer values forms a key=value pair that we 540b57cec5SDimitry Andric // store as Registers[key]=value in the map. 550b57cec5SDimitry Andric auto Tuple = dyn_cast<MDTuple>(NamedMD->getOperand(0)); 560b57cec5SDimitry Andric if (!Tuple) 570b57cec5SDimitry Andric return; 580b57cec5SDimitry Andric for (unsigned I = 0, E = Tuple->getNumOperands() & -2; I != E; I += 2) { 590b57cec5SDimitry Andric auto Key = mdconst::dyn_extract<ConstantInt>(Tuple->getOperand(I)); 600b57cec5SDimitry Andric auto Val = mdconst::dyn_extract<ConstantInt>(Tuple->getOperand(I + 1)); 610b57cec5SDimitry Andric if (!Key || !Val) 620b57cec5SDimitry Andric continue; 630b57cec5SDimitry Andric setRegister(Key->getZExtValue(), Val->getZExtValue()); 640b57cec5SDimitry Andric } 650b57cec5SDimitry Andric } 660b57cec5SDimitry Andric 670b57cec5SDimitry Andric // Set PAL metadata from a binary blob from the applicable .note record. 680b57cec5SDimitry Andric // Returns false if bad format. Blob must remain valid for the lifetime of the 690b57cec5SDimitry Andric // Metadata. 700b57cec5SDimitry Andric bool AMDGPUPALMetadata::setFromBlob(unsigned Type, StringRef Blob) { 710b57cec5SDimitry Andric BlobType = Type; 72fe6060f1SDimitry Andric if (Type == ELF::NT_AMD_PAL_METADATA) 730b57cec5SDimitry Andric return setFromLegacyBlob(Blob); 740b57cec5SDimitry Andric return setFromMsgPackBlob(Blob); 750b57cec5SDimitry Andric } 760b57cec5SDimitry Andric 770b57cec5SDimitry Andric // Set PAL metadata from legacy (array of key=value pairs) blob. 780b57cec5SDimitry Andric bool AMDGPUPALMetadata::setFromLegacyBlob(StringRef Blob) { 790b57cec5SDimitry Andric auto Data = reinterpret_cast<const uint32_t *>(Blob.data()); 800b57cec5SDimitry Andric for (unsigned I = 0; I != Blob.size() / sizeof(uint32_t) / 2; ++I) 810b57cec5SDimitry Andric setRegister(Data[I * 2], Data[I * 2 + 1]); 820b57cec5SDimitry Andric return true; 830b57cec5SDimitry Andric } 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric // Set PAL metadata from msgpack blob. 860b57cec5SDimitry Andric bool AMDGPUPALMetadata::setFromMsgPackBlob(StringRef Blob) { 870b57cec5SDimitry Andric return MsgPackDoc.readFromBlob(Blob, /*Multi=*/false); 880b57cec5SDimitry Andric } 890b57cec5SDimitry Andric 900b57cec5SDimitry Andric // Given the calling convention, calculate the register number for rsrc1. In 910b57cec5SDimitry Andric // principle the register number could change in future hardware, but we know 920b57cec5SDimitry Andric // it is the same for gfx6-9 (except that LS and ES don't exist on gfx9), so 930b57cec5SDimitry Andric // we can use fixed values. 940b57cec5SDimitry Andric static unsigned getRsrc1Reg(CallingConv::ID CC) { 950b57cec5SDimitry Andric switch (CC) { 960b57cec5SDimitry Andric default: 970b57cec5SDimitry Andric return PALMD::R_2E12_COMPUTE_PGM_RSRC1; 980b57cec5SDimitry Andric case CallingConv::AMDGPU_LS: 990b57cec5SDimitry Andric return PALMD::R_2D4A_SPI_SHADER_PGM_RSRC1_LS; 1000b57cec5SDimitry Andric case CallingConv::AMDGPU_HS: 1010b57cec5SDimitry Andric return PALMD::R_2D0A_SPI_SHADER_PGM_RSRC1_HS; 1020b57cec5SDimitry Andric case CallingConv::AMDGPU_ES: 1030b57cec5SDimitry Andric return PALMD::R_2CCA_SPI_SHADER_PGM_RSRC1_ES; 1040b57cec5SDimitry Andric case CallingConv::AMDGPU_GS: 1050b57cec5SDimitry Andric return PALMD::R_2C8A_SPI_SHADER_PGM_RSRC1_GS; 1060b57cec5SDimitry Andric case CallingConv::AMDGPU_VS: 1070b57cec5SDimitry Andric return PALMD::R_2C4A_SPI_SHADER_PGM_RSRC1_VS; 1080b57cec5SDimitry Andric case CallingConv::AMDGPU_PS: 1090b57cec5SDimitry Andric return PALMD::R_2C0A_SPI_SHADER_PGM_RSRC1_PS; 1100b57cec5SDimitry Andric } 1110b57cec5SDimitry Andric } 1120b57cec5SDimitry Andric 1130b57cec5SDimitry Andric // Calculate the PAL metadata key for *S_SCRATCH_SIZE. It can be used 1140b57cec5SDimitry Andric // with a constant offset to access any non-register shader-specific PAL 1150b57cec5SDimitry Andric // metadata key. 1160b57cec5SDimitry Andric static unsigned getScratchSizeKey(CallingConv::ID CC) { 1170b57cec5SDimitry Andric switch (CC) { 1180b57cec5SDimitry Andric case CallingConv::AMDGPU_PS: 1190b57cec5SDimitry Andric return PALMD::Key::PS_SCRATCH_SIZE; 1200b57cec5SDimitry Andric case CallingConv::AMDGPU_VS: 1210b57cec5SDimitry Andric return PALMD::Key::VS_SCRATCH_SIZE; 1220b57cec5SDimitry Andric case CallingConv::AMDGPU_GS: 1230b57cec5SDimitry Andric return PALMD::Key::GS_SCRATCH_SIZE; 1240b57cec5SDimitry Andric case CallingConv::AMDGPU_ES: 1250b57cec5SDimitry Andric return PALMD::Key::ES_SCRATCH_SIZE; 1260b57cec5SDimitry Andric case CallingConv::AMDGPU_HS: 1270b57cec5SDimitry Andric return PALMD::Key::HS_SCRATCH_SIZE; 1280b57cec5SDimitry Andric case CallingConv::AMDGPU_LS: 1290b57cec5SDimitry Andric return PALMD::Key::LS_SCRATCH_SIZE; 1300b57cec5SDimitry Andric default: 1310b57cec5SDimitry Andric return PALMD::Key::CS_SCRATCH_SIZE; 1320b57cec5SDimitry Andric } 1330b57cec5SDimitry Andric } 1340b57cec5SDimitry Andric 1350b57cec5SDimitry Andric // Set the rsrc1 register in the metadata for a particular shader stage. 1360b57cec5SDimitry Andric // In fact this ORs the value into any previous setting of the register. 1370b57cec5SDimitry Andric void AMDGPUPALMetadata::setRsrc1(CallingConv::ID CC, unsigned Val) { 1380b57cec5SDimitry Andric setRegister(getRsrc1Reg(CC), Val); 1390b57cec5SDimitry Andric } 1400b57cec5SDimitry Andric 141*0fca6ea1SDimitry Andric void AMDGPUPALMetadata::setRsrc1(CallingConv::ID CC, const MCExpr *Val, 142*0fca6ea1SDimitry Andric MCContext &Ctx) { 143*0fca6ea1SDimitry Andric setRegister(getRsrc1Reg(CC), Val, Ctx); 144*0fca6ea1SDimitry Andric } 145*0fca6ea1SDimitry Andric 1460b57cec5SDimitry Andric // Set the rsrc2 register in the metadata for a particular shader stage. 1470b57cec5SDimitry Andric // In fact this ORs the value into any previous setting of the register. 1480b57cec5SDimitry Andric void AMDGPUPALMetadata::setRsrc2(CallingConv::ID CC, unsigned Val) { 1490b57cec5SDimitry Andric setRegister(getRsrc1Reg(CC) + 1, Val); 1500b57cec5SDimitry Andric } 1510b57cec5SDimitry Andric 152*0fca6ea1SDimitry Andric void AMDGPUPALMetadata::setRsrc2(CallingConv::ID CC, const MCExpr *Val, 153*0fca6ea1SDimitry Andric MCContext &Ctx) { 154*0fca6ea1SDimitry Andric setRegister(getRsrc1Reg(CC) + 1, Val, Ctx); 155*0fca6ea1SDimitry Andric } 156*0fca6ea1SDimitry Andric 1570b57cec5SDimitry Andric // Set the SPI_PS_INPUT_ENA register in the metadata. 1580b57cec5SDimitry Andric // In fact this ORs the value into any previous setting of the register. 1590b57cec5SDimitry Andric void AMDGPUPALMetadata::setSpiPsInputEna(unsigned Val) { 1600b57cec5SDimitry Andric setRegister(PALMD::R_A1B3_SPI_PS_INPUT_ENA, Val); 1610b57cec5SDimitry Andric } 1620b57cec5SDimitry Andric 1630b57cec5SDimitry Andric // Set the SPI_PS_INPUT_ADDR register in the metadata. 1640b57cec5SDimitry Andric // In fact this ORs the value into any previous setting of the register. 1650b57cec5SDimitry Andric void AMDGPUPALMetadata::setSpiPsInputAddr(unsigned Val) { 1660b57cec5SDimitry Andric setRegister(PALMD::R_A1B4_SPI_PS_INPUT_ADDR, Val); 1670b57cec5SDimitry Andric } 1680b57cec5SDimitry Andric 1690b57cec5SDimitry Andric // Get a register from the metadata, or 0 if not currently set. 1700b57cec5SDimitry Andric unsigned AMDGPUPALMetadata::getRegister(unsigned Reg) { 1710b57cec5SDimitry Andric auto Regs = getRegisters(); 1720b57cec5SDimitry Andric auto It = Regs.find(MsgPackDoc.getNode(Reg)); 1730b57cec5SDimitry Andric if (It == Regs.end()) 1740b57cec5SDimitry Andric return 0; 1750b57cec5SDimitry Andric auto N = It->second; 1760b57cec5SDimitry Andric if (N.getKind() != msgpack::Type::UInt) 1770b57cec5SDimitry Andric return 0; 1780b57cec5SDimitry Andric return N.getUInt(); 1790b57cec5SDimitry Andric } 1800b57cec5SDimitry Andric 1810b57cec5SDimitry Andric // Set a register in the metadata. 1820b57cec5SDimitry Andric // In fact this ORs the value into any previous setting of the register. 1830b57cec5SDimitry Andric void AMDGPUPALMetadata::setRegister(unsigned Reg, unsigned Val) { 1840b57cec5SDimitry Andric if (!isLegacy()) { 1850b57cec5SDimitry Andric // In the new MsgPack format, ignore register numbered >= 0x10000000. It 1860b57cec5SDimitry Andric // is a PAL ABI pseudo-register in the old non-MsgPack format. 1870b57cec5SDimitry Andric if (Reg >= 0x10000000) 1880b57cec5SDimitry Andric return; 1890b57cec5SDimitry Andric } 1900b57cec5SDimitry Andric auto &N = getRegisters()[MsgPackDoc.getNode(Reg)]; 1910b57cec5SDimitry Andric if (N.getKind() == msgpack::Type::UInt) 1920b57cec5SDimitry Andric Val |= N.getUInt(); 1930b57cec5SDimitry Andric N = N.getDocument()->getNode(Val); 1940b57cec5SDimitry Andric } 1950b57cec5SDimitry Andric 196*0fca6ea1SDimitry Andric // Set a register in the metadata. 197*0fca6ea1SDimitry Andric // In fact this ORs the value into any previous setting of the register. 198*0fca6ea1SDimitry Andric void AMDGPUPALMetadata::setRegister(unsigned Reg, const MCExpr *Val, 199*0fca6ea1SDimitry Andric MCContext &Ctx) { 200*0fca6ea1SDimitry Andric if (!isLegacy()) { 201*0fca6ea1SDimitry Andric // In the new MsgPack format, ignore register numbered >= 0x10000000. It 202*0fca6ea1SDimitry Andric // is a PAL ABI pseudo-register in the old non-MsgPack format. 203*0fca6ea1SDimitry Andric if (Reg >= 0x10000000) 204*0fca6ea1SDimitry Andric return; 205*0fca6ea1SDimitry Andric } 206*0fca6ea1SDimitry Andric auto &N = getRegisters()[MsgPackDoc.getNode(Reg)]; 207*0fca6ea1SDimitry Andric auto ExprIt = REM.find(Reg); 208*0fca6ea1SDimitry Andric 209*0fca6ea1SDimitry Andric if (ExprIt != REM.end()) { 210*0fca6ea1SDimitry Andric Val = MCBinaryExpr::createOr(Val, ExprIt->getSecond(), Ctx); 211*0fca6ea1SDimitry Andric // This conditional may be redundant most of the time, but the alternate 212*0fca6ea1SDimitry Andric // setRegister(unsigned, unsigned) could've been called while the 213*0fca6ea1SDimitry Andric // conditional returns true (i.e., Reg exists in REM). 214*0fca6ea1SDimitry Andric if (N.getKind() == msgpack::Type::UInt) { 215*0fca6ea1SDimitry Andric const MCExpr *NExpr = MCConstantExpr::create(N.getUInt(), Ctx); 216*0fca6ea1SDimitry Andric Val = MCBinaryExpr::createOr(Val, NExpr, Ctx); 217*0fca6ea1SDimitry Andric } 218*0fca6ea1SDimitry Andric ExprIt->getSecond() = Val; 219*0fca6ea1SDimitry Andric } else if (N.getKind() == msgpack::Type::UInt) { 220*0fca6ea1SDimitry Andric const MCExpr *NExpr = MCConstantExpr::create(N.getUInt(), Ctx); 221*0fca6ea1SDimitry Andric Val = MCBinaryExpr::createOr(Val, NExpr, Ctx); 222*0fca6ea1SDimitry Andric int64_t Unused; 223*0fca6ea1SDimitry Andric if (!Val->evaluateAsAbsolute(Unused)) 224*0fca6ea1SDimitry Andric REM[Reg] = Val; 225*0fca6ea1SDimitry Andric (void)Unused; 226*0fca6ea1SDimitry Andric } 227*0fca6ea1SDimitry Andric DelayedExprs.assignDocNode(N, msgpack::Type::UInt, Val); 228*0fca6ea1SDimitry Andric } 229*0fca6ea1SDimitry Andric 2300b57cec5SDimitry Andric // Set the entry point name for one shader. 2310b57cec5SDimitry Andric void AMDGPUPALMetadata::setEntryPoint(unsigned CC, StringRef Name) { 2320b57cec5SDimitry Andric if (isLegacy()) 2330b57cec5SDimitry Andric return; 2340b57cec5SDimitry Andric // Msgpack format. 2350b57cec5SDimitry Andric getHwStage(CC)[".entry_point"] = MsgPackDoc.getNode(Name, /*Copy=*/true); 2360b57cec5SDimitry Andric } 2370b57cec5SDimitry Andric 2380b57cec5SDimitry Andric // Set the number of used vgprs in the metadata. This is an optional 2390b57cec5SDimitry Andric // advisory record for logging etc; wave dispatch actually uses the rsrc1 2400b57cec5SDimitry Andric // register for the shader stage to determine the number of vgprs to 2410b57cec5SDimitry Andric // allocate. 2420b57cec5SDimitry Andric void AMDGPUPALMetadata::setNumUsedVgprs(CallingConv::ID CC, unsigned Val) { 2430b57cec5SDimitry Andric if (isLegacy()) { 2440b57cec5SDimitry Andric // Old non-msgpack format. 2450b57cec5SDimitry Andric unsigned NumUsedVgprsKey = getScratchSizeKey(CC) + 2460b57cec5SDimitry Andric PALMD::Key::VS_NUM_USED_VGPRS - 2470b57cec5SDimitry Andric PALMD::Key::VS_SCRATCH_SIZE; 2480b57cec5SDimitry Andric setRegister(NumUsedVgprsKey, Val); 2490b57cec5SDimitry Andric return; 2500b57cec5SDimitry Andric } 2510b57cec5SDimitry Andric // Msgpack format. 2520b57cec5SDimitry Andric getHwStage(CC)[".vgpr_count"] = MsgPackDoc.getNode(Val); 2530b57cec5SDimitry Andric } 2540b57cec5SDimitry Andric 255*0fca6ea1SDimitry Andric void AMDGPUPALMetadata::setNumUsedVgprs(CallingConv::ID CC, const MCExpr *Val, 256*0fca6ea1SDimitry Andric MCContext &Ctx) { 257*0fca6ea1SDimitry Andric if (isLegacy()) { 258*0fca6ea1SDimitry Andric // Old non-msgpack format. 259*0fca6ea1SDimitry Andric unsigned NumUsedVgprsKey = getScratchSizeKey(CC) + 260*0fca6ea1SDimitry Andric PALMD::Key::VS_NUM_USED_VGPRS - 261*0fca6ea1SDimitry Andric PALMD::Key::VS_SCRATCH_SIZE; 262*0fca6ea1SDimitry Andric setRegister(NumUsedVgprsKey, Val, Ctx); 263*0fca6ea1SDimitry Andric return; 264*0fca6ea1SDimitry Andric } 265*0fca6ea1SDimitry Andric // Msgpack format. 266*0fca6ea1SDimitry Andric setHwStage(CC, ".vgpr_count", msgpack::Type::UInt, Val); 267*0fca6ea1SDimitry Andric } 268*0fca6ea1SDimitry Andric 26981ad6265SDimitry Andric // Set the number of used agprs in the metadata. 27081ad6265SDimitry Andric void AMDGPUPALMetadata::setNumUsedAgprs(CallingConv::ID CC, unsigned Val) { 27181ad6265SDimitry Andric getHwStage(CC)[".agpr_count"] = Val; 27281ad6265SDimitry Andric } 27381ad6265SDimitry Andric 274*0fca6ea1SDimitry Andric void AMDGPUPALMetadata::setNumUsedAgprs(unsigned CC, const MCExpr *Val) { 275*0fca6ea1SDimitry Andric setHwStage(CC, ".agpr_count", msgpack::Type::UInt, Val); 276*0fca6ea1SDimitry Andric } 277*0fca6ea1SDimitry Andric 2780b57cec5SDimitry Andric // Set the number of used sgprs in the metadata. This is an optional advisory 2790b57cec5SDimitry Andric // record for logging etc; wave dispatch actually uses the rsrc1 register for 2800b57cec5SDimitry Andric // the shader stage to determine the number of sgprs to allocate. 2810b57cec5SDimitry Andric void AMDGPUPALMetadata::setNumUsedSgprs(CallingConv::ID CC, unsigned Val) { 2820b57cec5SDimitry Andric if (isLegacy()) { 2830b57cec5SDimitry Andric // Old non-msgpack format. 2840b57cec5SDimitry Andric unsigned NumUsedSgprsKey = getScratchSizeKey(CC) + 2850b57cec5SDimitry Andric PALMD::Key::VS_NUM_USED_SGPRS - 2860b57cec5SDimitry Andric PALMD::Key::VS_SCRATCH_SIZE; 2870b57cec5SDimitry Andric setRegister(NumUsedSgprsKey, Val); 2880b57cec5SDimitry Andric return; 2890b57cec5SDimitry Andric } 2900b57cec5SDimitry Andric // Msgpack format. 2910b57cec5SDimitry Andric getHwStage(CC)[".sgpr_count"] = MsgPackDoc.getNode(Val); 2920b57cec5SDimitry Andric } 2930b57cec5SDimitry Andric 294*0fca6ea1SDimitry Andric void AMDGPUPALMetadata::setNumUsedSgprs(unsigned CC, const MCExpr *Val, 295*0fca6ea1SDimitry Andric MCContext &Ctx) { 296*0fca6ea1SDimitry Andric if (isLegacy()) { 297*0fca6ea1SDimitry Andric // Old non-msgpack format. 298*0fca6ea1SDimitry Andric unsigned NumUsedSgprsKey = getScratchSizeKey(CC) + 299*0fca6ea1SDimitry Andric PALMD::Key::VS_NUM_USED_SGPRS - 300*0fca6ea1SDimitry Andric PALMD::Key::VS_SCRATCH_SIZE; 301*0fca6ea1SDimitry Andric setRegister(NumUsedSgprsKey, Val, Ctx); 302*0fca6ea1SDimitry Andric return; 303*0fca6ea1SDimitry Andric } 304*0fca6ea1SDimitry Andric // Msgpack format. 305*0fca6ea1SDimitry Andric setHwStage(CC, ".sgpr_count", msgpack::Type::UInt, Val); 306*0fca6ea1SDimitry Andric } 307*0fca6ea1SDimitry Andric 3080b57cec5SDimitry Andric // Set the scratch size in the metadata. 3090b57cec5SDimitry Andric void AMDGPUPALMetadata::setScratchSize(CallingConv::ID CC, unsigned Val) { 3100b57cec5SDimitry Andric if (isLegacy()) { 3110b57cec5SDimitry Andric // Old non-msgpack format. 3120b57cec5SDimitry Andric setRegister(getScratchSizeKey(CC), Val); 3130b57cec5SDimitry Andric return; 3140b57cec5SDimitry Andric } 3150b57cec5SDimitry Andric // Msgpack format. 3160b57cec5SDimitry Andric getHwStage(CC)[".scratch_memory_size"] = MsgPackDoc.getNode(Val); 3170b57cec5SDimitry Andric } 3180b57cec5SDimitry Andric 319*0fca6ea1SDimitry Andric void AMDGPUPALMetadata::setScratchSize(unsigned CC, const MCExpr *Val, 320*0fca6ea1SDimitry Andric MCContext &Ctx) { 321*0fca6ea1SDimitry Andric if (isLegacy()) { 322*0fca6ea1SDimitry Andric // Old non-msgpack format. 323*0fca6ea1SDimitry Andric setRegister(getScratchSizeKey(CC), Val, Ctx); 324*0fca6ea1SDimitry Andric return; 325*0fca6ea1SDimitry Andric } 326*0fca6ea1SDimitry Andric // Msgpack format. 327*0fca6ea1SDimitry Andric setHwStage(CC, ".scratch_memory_size", msgpack::Type::UInt, Val); 328*0fca6ea1SDimitry Andric } 329*0fca6ea1SDimitry Andric 330e8d8bef9SDimitry Andric // Set the stack frame size of a function in the metadata. 3315f757f3fSDimitry Andric void AMDGPUPALMetadata::setFunctionScratchSize(StringRef FnName, unsigned Val) { 3325f757f3fSDimitry Andric auto Node = getShaderFunction(FnName); 333e8d8bef9SDimitry Andric Node[".stack_frame_size_in_bytes"] = MsgPackDoc.getNode(Val); 3345f757f3fSDimitry Andric Node[".backend_stack_size"] = MsgPackDoc.getNode(Val); 335e8d8bef9SDimitry Andric } 336e8d8bef9SDimitry Andric 337fe6060f1SDimitry Andric // Set the amount of LDS used in bytes in the metadata. 3385f757f3fSDimitry Andric void AMDGPUPALMetadata::setFunctionLdsSize(StringRef FnName, unsigned Val) { 3395f757f3fSDimitry Andric auto Node = getShaderFunction(FnName); 340fe6060f1SDimitry Andric Node[".lds_size"] = MsgPackDoc.getNode(Val); 341fe6060f1SDimitry Andric } 342fe6060f1SDimitry Andric 343fe6060f1SDimitry Andric // Set the number of used vgprs in the metadata. 3445f757f3fSDimitry Andric void AMDGPUPALMetadata::setFunctionNumUsedVgprs(StringRef FnName, 345fe6060f1SDimitry Andric unsigned Val) { 3465f757f3fSDimitry Andric auto Node = getShaderFunction(FnName); 347fe6060f1SDimitry Andric Node[".vgpr_count"] = MsgPackDoc.getNode(Val); 348fe6060f1SDimitry Andric } 349fe6060f1SDimitry Andric 350*0fca6ea1SDimitry Andric void AMDGPUPALMetadata::setFunctionNumUsedVgprs(StringRef FnName, 351*0fca6ea1SDimitry Andric const MCExpr *Val) { 352*0fca6ea1SDimitry Andric auto Node = getShaderFunction(FnName); 353*0fca6ea1SDimitry Andric DelayedExprs.assignDocNode(Node[".vgpr_count"], msgpack::Type::UInt, Val); 354*0fca6ea1SDimitry Andric } 355*0fca6ea1SDimitry Andric 356fe6060f1SDimitry Andric // Set the number of used vgprs in the metadata. 3575f757f3fSDimitry Andric void AMDGPUPALMetadata::setFunctionNumUsedSgprs(StringRef FnName, 358fe6060f1SDimitry Andric unsigned Val) { 3595f757f3fSDimitry Andric auto Node = getShaderFunction(FnName); 360fe6060f1SDimitry Andric Node[".sgpr_count"] = MsgPackDoc.getNode(Val); 361fe6060f1SDimitry Andric } 362fe6060f1SDimitry Andric 363*0fca6ea1SDimitry Andric void AMDGPUPALMetadata::setFunctionNumUsedSgprs(StringRef FnName, 364*0fca6ea1SDimitry Andric const MCExpr *Val) { 365*0fca6ea1SDimitry Andric auto Node = getShaderFunction(FnName); 366*0fca6ea1SDimitry Andric DelayedExprs.assignDocNode(Node[".sgpr_count"], msgpack::Type::UInt, Val); 367*0fca6ea1SDimitry Andric } 368*0fca6ea1SDimitry Andric 3690b57cec5SDimitry Andric // Set the hardware register bit in PAL metadata to enable wave32 on the 3700b57cec5SDimitry Andric // shader of the given calling convention. 3710b57cec5SDimitry Andric void AMDGPUPALMetadata::setWave32(unsigned CC) { 3720b57cec5SDimitry Andric switch (CC) { 3730b57cec5SDimitry Andric case CallingConv::AMDGPU_HS: 3740b57cec5SDimitry Andric setRegister(PALMD::R_A2D5_VGT_SHADER_STAGES_EN, S_028B54_HS_W32_EN(1)); 3750b57cec5SDimitry Andric break; 3760b57cec5SDimitry Andric case CallingConv::AMDGPU_GS: 3770b57cec5SDimitry Andric setRegister(PALMD::R_A2D5_VGT_SHADER_STAGES_EN, S_028B54_GS_W32_EN(1)); 3780b57cec5SDimitry Andric break; 3790b57cec5SDimitry Andric case CallingConv::AMDGPU_VS: 3800b57cec5SDimitry Andric setRegister(PALMD::R_A2D5_VGT_SHADER_STAGES_EN, S_028B54_VS_W32_EN(1)); 3810b57cec5SDimitry Andric break; 3820b57cec5SDimitry Andric case CallingConv::AMDGPU_PS: 3830b57cec5SDimitry Andric setRegister(PALMD::R_A1B6_SPI_PS_IN_CONTROL, S_0286D8_PS_W32_EN(1)); 3840b57cec5SDimitry Andric break; 3850b57cec5SDimitry Andric case CallingConv::AMDGPU_CS: 3860b57cec5SDimitry Andric setRegister(PALMD::R_2E00_COMPUTE_DISPATCH_INITIATOR, 3870b57cec5SDimitry Andric S_00B800_CS_W32_EN(1)); 3880b57cec5SDimitry Andric break; 3890b57cec5SDimitry Andric } 3900b57cec5SDimitry Andric } 3910b57cec5SDimitry Andric 3920b57cec5SDimitry Andric // Convert a register number to name, for display by toString(). 3930b57cec5SDimitry Andric // Returns nullptr if none. 3940b57cec5SDimitry Andric static const char *getRegisterName(unsigned RegNum) { 3950b57cec5SDimitry Andric // Table of registers. 3960b57cec5SDimitry Andric static const struct RegInfo { 3970b57cec5SDimitry Andric unsigned Num; 3980b57cec5SDimitry Andric const char *Name; 3990b57cec5SDimitry Andric } RegInfoTable[] = { 4000b57cec5SDimitry Andric // Registers that code generation sets/modifies metadata for. 4010b57cec5SDimitry Andric {PALMD::R_2C4A_SPI_SHADER_PGM_RSRC1_VS, "SPI_SHADER_PGM_RSRC1_VS"}, 4020b57cec5SDimitry Andric {PALMD::R_2C4A_SPI_SHADER_PGM_RSRC1_VS + 1, "SPI_SHADER_PGM_RSRC2_VS"}, 4030b57cec5SDimitry Andric {PALMD::R_2D4A_SPI_SHADER_PGM_RSRC1_LS, "SPI_SHADER_PGM_RSRC1_LS"}, 4040b57cec5SDimitry Andric {PALMD::R_2D4A_SPI_SHADER_PGM_RSRC1_LS + 1, "SPI_SHADER_PGM_RSRC2_LS"}, 4050b57cec5SDimitry Andric {PALMD::R_2D0A_SPI_SHADER_PGM_RSRC1_HS, "SPI_SHADER_PGM_RSRC1_HS"}, 4060b57cec5SDimitry Andric {PALMD::R_2D0A_SPI_SHADER_PGM_RSRC1_HS + 1, "SPI_SHADER_PGM_RSRC2_HS"}, 4070b57cec5SDimitry Andric {PALMD::R_2CCA_SPI_SHADER_PGM_RSRC1_ES, "SPI_SHADER_PGM_RSRC1_ES"}, 4080b57cec5SDimitry Andric {PALMD::R_2CCA_SPI_SHADER_PGM_RSRC1_ES + 1, "SPI_SHADER_PGM_RSRC2_ES"}, 4090b57cec5SDimitry Andric {PALMD::R_2C8A_SPI_SHADER_PGM_RSRC1_GS, "SPI_SHADER_PGM_RSRC1_GS"}, 4100b57cec5SDimitry Andric {PALMD::R_2C8A_SPI_SHADER_PGM_RSRC1_GS + 1, "SPI_SHADER_PGM_RSRC2_GS"}, 4110b57cec5SDimitry Andric {PALMD::R_2E00_COMPUTE_DISPATCH_INITIATOR, "COMPUTE_DISPATCH_INITIATOR"}, 4120b57cec5SDimitry Andric {PALMD::R_2E12_COMPUTE_PGM_RSRC1, "COMPUTE_PGM_RSRC1"}, 4130b57cec5SDimitry Andric {PALMD::R_2E12_COMPUTE_PGM_RSRC1 + 1, "COMPUTE_PGM_RSRC2"}, 4140b57cec5SDimitry Andric {PALMD::R_2C0A_SPI_SHADER_PGM_RSRC1_PS, "SPI_SHADER_PGM_RSRC1_PS"}, 4150b57cec5SDimitry Andric {PALMD::R_2C0A_SPI_SHADER_PGM_RSRC1_PS + 1, "SPI_SHADER_PGM_RSRC2_PS"}, 4160b57cec5SDimitry Andric {PALMD::R_A1B3_SPI_PS_INPUT_ENA, "SPI_PS_INPUT_ENA"}, 4170b57cec5SDimitry Andric {PALMD::R_A1B4_SPI_PS_INPUT_ADDR, "SPI_PS_INPUT_ADDR"}, 4180b57cec5SDimitry Andric {PALMD::R_A1B6_SPI_PS_IN_CONTROL, "SPI_PS_IN_CONTROL"}, 4190b57cec5SDimitry Andric {PALMD::R_A2D5_VGT_SHADER_STAGES_EN, "VGT_SHADER_STAGES_EN"}, 4200b57cec5SDimitry Andric 4210b57cec5SDimitry Andric // Registers not known to code generation. 4220b57cec5SDimitry Andric {0x2c07, "SPI_SHADER_PGM_RSRC3_PS"}, 4230b57cec5SDimitry Andric {0x2c46, "SPI_SHADER_PGM_RSRC3_VS"}, 4240b57cec5SDimitry Andric {0x2c87, "SPI_SHADER_PGM_RSRC3_GS"}, 4250b57cec5SDimitry Andric {0x2cc7, "SPI_SHADER_PGM_RSRC3_ES"}, 4260b57cec5SDimitry Andric {0x2d07, "SPI_SHADER_PGM_RSRC3_HS"}, 4270b57cec5SDimitry Andric {0x2d47, "SPI_SHADER_PGM_RSRC3_LS"}, 4280b57cec5SDimitry Andric 4290b57cec5SDimitry Andric {0xa1c3, "SPI_SHADER_POS_FORMAT"}, 4300b57cec5SDimitry Andric {0xa1b1, "SPI_VS_OUT_CONFIG"}, 4310b57cec5SDimitry Andric {0xa207, "PA_CL_VS_OUT_CNTL"}, 4320b57cec5SDimitry Andric {0xa204, "PA_CL_CLIP_CNTL"}, 4330b57cec5SDimitry Andric {0xa206, "PA_CL_VTE_CNTL"}, 4340b57cec5SDimitry Andric {0xa2f9, "PA_SU_VTX_CNTL"}, 4350b57cec5SDimitry Andric {0xa293, "PA_SC_MODE_CNTL_1"}, 4360b57cec5SDimitry Andric {0xa2a1, "VGT_PRIMITIVEID_EN"}, 4370b57cec5SDimitry Andric {0x2c81, "SPI_SHADER_PGM_RSRC4_GS"}, 4380b57cec5SDimitry Andric {0x2e18, "COMPUTE_TMPRING_SIZE"}, 4390b57cec5SDimitry Andric {0xa1b5, "SPI_INTERP_CONTROL_0"}, 4400b57cec5SDimitry Andric {0xa1ba, "SPI_TMPRING_SIZE"}, 4410b57cec5SDimitry Andric {0xa1c4, "SPI_SHADER_Z_FORMAT"}, 4420b57cec5SDimitry Andric {0xa1c5, "SPI_SHADER_COL_FORMAT"}, 4430b57cec5SDimitry Andric {0xa203, "DB_SHADER_CONTROL"}, 4440b57cec5SDimitry Andric {0xa08f, "CB_SHADER_MASK"}, 4450b57cec5SDimitry Andric {0xa191, "SPI_PS_INPUT_CNTL_0"}, 4460b57cec5SDimitry Andric {0xa192, "SPI_PS_INPUT_CNTL_1"}, 4470b57cec5SDimitry Andric {0xa193, "SPI_PS_INPUT_CNTL_2"}, 4480b57cec5SDimitry Andric {0xa194, "SPI_PS_INPUT_CNTL_3"}, 4490b57cec5SDimitry Andric {0xa195, "SPI_PS_INPUT_CNTL_4"}, 4500b57cec5SDimitry Andric {0xa196, "SPI_PS_INPUT_CNTL_5"}, 4510b57cec5SDimitry Andric {0xa197, "SPI_PS_INPUT_CNTL_6"}, 4520b57cec5SDimitry Andric {0xa198, "SPI_PS_INPUT_CNTL_7"}, 4530b57cec5SDimitry Andric {0xa199, "SPI_PS_INPUT_CNTL_8"}, 4540b57cec5SDimitry Andric {0xa19a, "SPI_PS_INPUT_CNTL_9"}, 4550b57cec5SDimitry Andric {0xa19b, "SPI_PS_INPUT_CNTL_10"}, 4560b57cec5SDimitry Andric {0xa19c, "SPI_PS_INPUT_CNTL_11"}, 4570b57cec5SDimitry Andric {0xa19d, "SPI_PS_INPUT_CNTL_12"}, 4580b57cec5SDimitry Andric {0xa19e, "SPI_PS_INPUT_CNTL_13"}, 4590b57cec5SDimitry Andric {0xa19f, "SPI_PS_INPUT_CNTL_14"}, 4600b57cec5SDimitry Andric {0xa1a0, "SPI_PS_INPUT_CNTL_15"}, 4610b57cec5SDimitry Andric {0xa1a1, "SPI_PS_INPUT_CNTL_16"}, 4620b57cec5SDimitry Andric {0xa1a2, "SPI_PS_INPUT_CNTL_17"}, 4630b57cec5SDimitry Andric {0xa1a3, "SPI_PS_INPUT_CNTL_18"}, 4640b57cec5SDimitry Andric {0xa1a4, "SPI_PS_INPUT_CNTL_19"}, 4650b57cec5SDimitry Andric {0xa1a5, "SPI_PS_INPUT_CNTL_20"}, 4660b57cec5SDimitry Andric {0xa1a6, "SPI_PS_INPUT_CNTL_21"}, 4670b57cec5SDimitry Andric {0xa1a7, "SPI_PS_INPUT_CNTL_22"}, 4680b57cec5SDimitry Andric {0xa1a8, "SPI_PS_INPUT_CNTL_23"}, 4690b57cec5SDimitry Andric {0xa1a9, "SPI_PS_INPUT_CNTL_24"}, 4700b57cec5SDimitry Andric {0xa1aa, "SPI_PS_INPUT_CNTL_25"}, 4710b57cec5SDimitry Andric {0xa1ab, "SPI_PS_INPUT_CNTL_26"}, 4720b57cec5SDimitry Andric {0xa1ac, "SPI_PS_INPUT_CNTL_27"}, 4730b57cec5SDimitry Andric {0xa1ad, "SPI_PS_INPUT_CNTL_28"}, 4740b57cec5SDimitry Andric {0xa1ae, "SPI_PS_INPUT_CNTL_29"}, 4750b57cec5SDimitry Andric {0xa1af, "SPI_PS_INPUT_CNTL_30"}, 4760b57cec5SDimitry Andric {0xa1b0, "SPI_PS_INPUT_CNTL_31"}, 4770b57cec5SDimitry Andric 4780b57cec5SDimitry Andric {0xa2ce, "VGT_GS_MAX_VERT_OUT"}, 4790b57cec5SDimitry Andric {0xa2ab, "VGT_ESGS_RING_ITEMSIZE"}, 4800b57cec5SDimitry Andric {0xa290, "VGT_GS_MODE"}, 4810b57cec5SDimitry Andric {0xa291, "VGT_GS_ONCHIP_CNTL"}, 4820b57cec5SDimitry Andric {0xa2d7, "VGT_GS_VERT_ITEMSIZE"}, 4830b57cec5SDimitry Andric {0xa2d8, "VGT_GS_VERT_ITEMSIZE_1"}, 4840b57cec5SDimitry Andric {0xa2d9, "VGT_GS_VERT_ITEMSIZE_2"}, 4850b57cec5SDimitry Andric {0xa2da, "VGT_GS_VERT_ITEMSIZE_3"}, 4860b57cec5SDimitry Andric {0xa298, "VGT_GSVS_RING_OFFSET_1"}, 4870b57cec5SDimitry Andric {0xa299, "VGT_GSVS_RING_OFFSET_2"}, 4880b57cec5SDimitry Andric {0xa29a, "VGT_GSVS_RING_OFFSET_3"}, 4890b57cec5SDimitry Andric 4900b57cec5SDimitry Andric {0xa2e4, "VGT_GS_INSTANCE_CNT"}, 4910b57cec5SDimitry Andric {0xa297, "VGT_GS_PER_VS"}, 4920b57cec5SDimitry Andric {0xa29b, "VGT_GS_OUT_PRIM_TYPE"}, 4930b57cec5SDimitry Andric {0xa2ac, "VGT_GSVS_RING_ITEMSIZE"}, 4940b57cec5SDimitry Andric 4950b57cec5SDimitry Andric {0xa2ad, "VGT_REUSE_OFF"}, 4960b57cec5SDimitry Andric {0xa1b8, "SPI_BARYC_CNTL"}, 4970b57cec5SDimitry Andric 4980b57cec5SDimitry Andric {0x2c4c, "SPI_SHADER_USER_DATA_VS_0"}, 4990b57cec5SDimitry Andric {0x2c4d, "SPI_SHADER_USER_DATA_VS_1"}, 5000b57cec5SDimitry Andric {0x2c4e, "SPI_SHADER_USER_DATA_VS_2"}, 5010b57cec5SDimitry Andric {0x2c4f, "SPI_SHADER_USER_DATA_VS_3"}, 5020b57cec5SDimitry Andric {0x2c50, "SPI_SHADER_USER_DATA_VS_4"}, 5030b57cec5SDimitry Andric {0x2c51, "SPI_SHADER_USER_DATA_VS_5"}, 5040b57cec5SDimitry Andric {0x2c52, "SPI_SHADER_USER_DATA_VS_6"}, 5050b57cec5SDimitry Andric {0x2c53, "SPI_SHADER_USER_DATA_VS_7"}, 5060b57cec5SDimitry Andric {0x2c54, "SPI_SHADER_USER_DATA_VS_8"}, 5070b57cec5SDimitry Andric {0x2c55, "SPI_SHADER_USER_DATA_VS_9"}, 5080b57cec5SDimitry Andric {0x2c56, "SPI_SHADER_USER_DATA_VS_10"}, 5090b57cec5SDimitry Andric {0x2c57, "SPI_SHADER_USER_DATA_VS_11"}, 5100b57cec5SDimitry Andric {0x2c58, "SPI_SHADER_USER_DATA_VS_12"}, 5110b57cec5SDimitry Andric {0x2c59, "SPI_SHADER_USER_DATA_VS_13"}, 5120b57cec5SDimitry Andric {0x2c5a, "SPI_SHADER_USER_DATA_VS_14"}, 5130b57cec5SDimitry Andric {0x2c5b, "SPI_SHADER_USER_DATA_VS_15"}, 5140b57cec5SDimitry Andric {0x2c5c, "SPI_SHADER_USER_DATA_VS_16"}, 5150b57cec5SDimitry Andric {0x2c5d, "SPI_SHADER_USER_DATA_VS_17"}, 5160b57cec5SDimitry Andric {0x2c5e, "SPI_SHADER_USER_DATA_VS_18"}, 5170b57cec5SDimitry Andric {0x2c5f, "SPI_SHADER_USER_DATA_VS_19"}, 5180b57cec5SDimitry Andric {0x2c60, "SPI_SHADER_USER_DATA_VS_20"}, 5190b57cec5SDimitry Andric {0x2c61, "SPI_SHADER_USER_DATA_VS_21"}, 5200b57cec5SDimitry Andric {0x2c62, "SPI_SHADER_USER_DATA_VS_22"}, 5210b57cec5SDimitry Andric {0x2c63, "SPI_SHADER_USER_DATA_VS_23"}, 5220b57cec5SDimitry Andric {0x2c64, "SPI_SHADER_USER_DATA_VS_24"}, 5230b57cec5SDimitry Andric {0x2c65, "SPI_SHADER_USER_DATA_VS_25"}, 5240b57cec5SDimitry Andric {0x2c66, "SPI_SHADER_USER_DATA_VS_26"}, 5250b57cec5SDimitry Andric {0x2c67, "SPI_SHADER_USER_DATA_VS_27"}, 5260b57cec5SDimitry Andric {0x2c68, "SPI_SHADER_USER_DATA_VS_28"}, 5270b57cec5SDimitry Andric {0x2c69, "SPI_SHADER_USER_DATA_VS_29"}, 5280b57cec5SDimitry Andric {0x2c6a, "SPI_SHADER_USER_DATA_VS_30"}, 5290b57cec5SDimitry Andric {0x2c6b, "SPI_SHADER_USER_DATA_VS_31"}, 5300b57cec5SDimitry Andric 5315ffd83dbSDimitry Andric {0x2c8c, "SPI_SHADER_USER_DATA_GS_0"}, 5325ffd83dbSDimitry Andric {0x2c8d, "SPI_SHADER_USER_DATA_GS_1"}, 5335ffd83dbSDimitry Andric {0x2c8e, "SPI_SHADER_USER_DATA_GS_2"}, 5345ffd83dbSDimitry Andric {0x2c8f, "SPI_SHADER_USER_DATA_GS_3"}, 5355ffd83dbSDimitry Andric {0x2c90, "SPI_SHADER_USER_DATA_GS_4"}, 5365ffd83dbSDimitry Andric {0x2c91, "SPI_SHADER_USER_DATA_GS_5"}, 5375ffd83dbSDimitry Andric {0x2c92, "SPI_SHADER_USER_DATA_GS_6"}, 5385ffd83dbSDimitry Andric {0x2c93, "SPI_SHADER_USER_DATA_GS_7"}, 5395ffd83dbSDimitry Andric {0x2c94, "SPI_SHADER_USER_DATA_GS_8"}, 5405ffd83dbSDimitry Andric {0x2c95, "SPI_SHADER_USER_DATA_GS_9"}, 5415ffd83dbSDimitry Andric {0x2c96, "SPI_SHADER_USER_DATA_GS_10"}, 5425ffd83dbSDimitry Andric {0x2c97, "SPI_SHADER_USER_DATA_GS_11"}, 5435ffd83dbSDimitry Andric {0x2c98, "SPI_SHADER_USER_DATA_GS_12"}, 5445ffd83dbSDimitry Andric {0x2c99, "SPI_SHADER_USER_DATA_GS_13"}, 5455ffd83dbSDimitry Andric {0x2c9a, "SPI_SHADER_USER_DATA_GS_14"}, 5465ffd83dbSDimitry Andric {0x2c9b, "SPI_SHADER_USER_DATA_GS_15"}, 5475ffd83dbSDimitry Andric {0x2c9c, "SPI_SHADER_USER_DATA_GS_16"}, 5485ffd83dbSDimitry Andric {0x2c9d, "SPI_SHADER_USER_DATA_GS_17"}, 5495ffd83dbSDimitry Andric {0x2c9e, "SPI_SHADER_USER_DATA_GS_18"}, 5505ffd83dbSDimitry Andric {0x2c9f, "SPI_SHADER_USER_DATA_GS_19"}, 5515ffd83dbSDimitry Andric {0x2ca0, "SPI_SHADER_USER_DATA_GS_20"}, 5525ffd83dbSDimitry Andric {0x2ca1, "SPI_SHADER_USER_DATA_GS_21"}, 5535ffd83dbSDimitry Andric {0x2ca2, "SPI_SHADER_USER_DATA_GS_22"}, 5545ffd83dbSDimitry Andric {0x2ca3, "SPI_SHADER_USER_DATA_GS_23"}, 5555ffd83dbSDimitry Andric {0x2ca4, "SPI_SHADER_USER_DATA_GS_24"}, 5565ffd83dbSDimitry Andric {0x2ca5, "SPI_SHADER_USER_DATA_GS_25"}, 5575ffd83dbSDimitry Andric {0x2ca6, "SPI_SHADER_USER_DATA_GS_26"}, 5585ffd83dbSDimitry Andric {0x2ca7, "SPI_SHADER_USER_DATA_GS_27"}, 5595ffd83dbSDimitry Andric {0x2ca8, "SPI_SHADER_USER_DATA_GS_28"}, 5605ffd83dbSDimitry Andric {0x2ca9, "SPI_SHADER_USER_DATA_GS_29"}, 5615ffd83dbSDimitry Andric {0x2caa, "SPI_SHADER_USER_DATA_GS_30"}, 5625ffd83dbSDimitry Andric {0x2cab, "SPI_SHADER_USER_DATA_GS_31"}, 5635ffd83dbSDimitry Andric 5640b57cec5SDimitry Andric {0x2ccc, "SPI_SHADER_USER_DATA_ES_0"}, 5650b57cec5SDimitry Andric {0x2ccd, "SPI_SHADER_USER_DATA_ES_1"}, 5660b57cec5SDimitry Andric {0x2cce, "SPI_SHADER_USER_DATA_ES_2"}, 5670b57cec5SDimitry Andric {0x2ccf, "SPI_SHADER_USER_DATA_ES_3"}, 5680b57cec5SDimitry Andric {0x2cd0, "SPI_SHADER_USER_DATA_ES_4"}, 5690b57cec5SDimitry Andric {0x2cd1, "SPI_SHADER_USER_DATA_ES_5"}, 5700b57cec5SDimitry Andric {0x2cd2, "SPI_SHADER_USER_DATA_ES_6"}, 5710b57cec5SDimitry Andric {0x2cd3, "SPI_SHADER_USER_DATA_ES_7"}, 5720b57cec5SDimitry Andric {0x2cd4, "SPI_SHADER_USER_DATA_ES_8"}, 5730b57cec5SDimitry Andric {0x2cd5, "SPI_SHADER_USER_DATA_ES_9"}, 5740b57cec5SDimitry Andric {0x2cd6, "SPI_SHADER_USER_DATA_ES_10"}, 5750b57cec5SDimitry Andric {0x2cd7, "SPI_SHADER_USER_DATA_ES_11"}, 5760b57cec5SDimitry Andric {0x2cd8, "SPI_SHADER_USER_DATA_ES_12"}, 5770b57cec5SDimitry Andric {0x2cd9, "SPI_SHADER_USER_DATA_ES_13"}, 5780b57cec5SDimitry Andric {0x2cda, "SPI_SHADER_USER_DATA_ES_14"}, 5790b57cec5SDimitry Andric {0x2cdb, "SPI_SHADER_USER_DATA_ES_15"}, 5800b57cec5SDimitry Andric {0x2cdc, "SPI_SHADER_USER_DATA_ES_16"}, 5810b57cec5SDimitry Andric {0x2cdd, "SPI_SHADER_USER_DATA_ES_17"}, 5820b57cec5SDimitry Andric {0x2cde, "SPI_SHADER_USER_DATA_ES_18"}, 5830b57cec5SDimitry Andric {0x2cdf, "SPI_SHADER_USER_DATA_ES_19"}, 5840b57cec5SDimitry Andric {0x2ce0, "SPI_SHADER_USER_DATA_ES_20"}, 5850b57cec5SDimitry Andric {0x2ce1, "SPI_SHADER_USER_DATA_ES_21"}, 5860b57cec5SDimitry Andric {0x2ce2, "SPI_SHADER_USER_DATA_ES_22"}, 5870b57cec5SDimitry Andric {0x2ce3, "SPI_SHADER_USER_DATA_ES_23"}, 5880b57cec5SDimitry Andric {0x2ce4, "SPI_SHADER_USER_DATA_ES_24"}, 5890b57cec5SDimitry Andric {0x2ce5, "SPI_SHADER_USER_DATA_ES_25"}, 5900b57cec5SDimitry Andric {0x2ce6, "SPI_SHADER_USER_DATA_ES_26"}, 5910b57cec5SDimitry Andric {0x2ce7, "SPI_SHADER_USER_DATA_ES_27"}, 5920b57cec5SDimitry Andric {0x2ce8, "SPI_SHADER_USER_DATA_ES_28"}, 5930b57cec5SDimitry Andric {0x2ce9, "SPI_SHADER_USER_DATA_ES_29"}, 5940b57cec5SDimitry Andric {0x2cea, "SPI_SHADER_USER_DATA_ES_30"}, 5950b57cec5SDimitry Andric {0x2ceb, "SPI_SHADER_USER_DATA_ES_31"}, 5960b57cec5SDimitry Andric 5970b57cec5SDimitry Andric {0x2c0c, "SPI_SHADER_USER_DATA_PS_0"}, 5980b57cec5SDimitry Andric {0x2c0d, "SPI_SHADER_USER_DATA_PS_1"}, 5990b57cec5SDimitry Andric {0x2c0e, "SPI_SHADER_USER_DATA_PS_2"}, 6000b57cec5SDimitry Andric {0x2c0f, "SPI_SHADER_USER_DATA_PS_3"}, 6010b57cec5SDimitry Andric {0x2c10, "SPI_SHADER_USER_DATA_PS_4"}, 6020b57cec5SDimitry Andric {0x2c11, "SPI_SHADER_USER_DATA_PS_5"}, 6030b57cec5SDimitry Andric {0x2c12, "SPI_SHADER_USER_DATA_PS_6"}, 6040b57cec5SDimitry Andric {0x2c13, "SPI_SHADER_USER_DATA_PS_7"}, 6050b57cec5SDimitry Andric {0x2c14, "SPI_SHADER_USER_DATA_PS_8"}, 6060b57cec5SDimitry Andric {0x2c15, "SPI_SHADER_USER_DATA_PS_9"}, 6070b57cec5SDimitry Andric {0x2c16, "SPI_SHADER_USER_DATA_PS_10"}, 6080b57cec5SDimitry Andric {0x2c17, "SPI_SHADER_USER_DATA_PS_11"}, 6090b57cec5SDimitry Andric {0x2c18, "SPI_SHADER_USER_DATA_PS_12"}, 6100b57cec5SDimitry Andric {0x2c19, "SPI_SHADER_USER_DATA_PS_13"}, 6110b57cec5SDimitry Andric {0x2c1a, "SPI_SHADER_USER_DATA_PS_14"}, 6120b57cec5SDimitry Andric {0x2c1b, "SPI_SHADER_USER_DATA_PS_15"}, 6130b57cec5SDimitry Andric {0x2c1c, "SPI_SHADER_USER_DATA_PS_16"}, 6140b57cec5SDimitry Andric {0x2c1d, "SPI_SHADER_USER_DATA_PS_17"}, 6150b57cec5SDimitry Andric {0x2c1e, "SPI_SHADER_USER_DATA_PS_18"}, 6160b57cec5SDimitry Andric {0x2c1f, "SPI_SHADER_USER_DATA_PS_19"}, 6170b57cec5SDimitry Andric {0x2c20, "SPI_SHADER_USER_DATA_PS_20"}, 6180b57cec5SDimitry Andric {0x2c21, "SPI_SHADER_USER_DATA_PS_21"}, 6190b57cec5SDimitry Andric {0x2c22, "SPI_SHADER_USER_DATA_PS_22"}, 6200b57cec5SDimitry Andric {0x2c23, "SPI_SHADER_USER_DATA_PS_23"}, 6210b57cec5SDimitry Andric {0x2c24, "SPI_SHADER_USER_DATA_PS_24"}, 6220b57cec5SDimitry Andric {0x2c25, "SPI_SHADER_USER_DATA_PS_25"}, 6230b57cec5SDimitry Andric {0x2c26, "SPI_SHADER_USER_DATA_PS_26"}, 6240b57cec5SDimitry Andric {0x2c27, "SPI_SHADER_USER_DATA_PS_27"}, 6250b57cec5SDimitry Andric {0x2c28, "SPI_SHADER_USER_DATA_PS_28"}, 6260b57cec5SDimitry Andric {0x2c29, "SPI_SHADER_USER_DATA_PS_29"}, 6270b57cec5SDimitry Andric {0x2c2a, "SPI_SHADER_USER_DATA_PS_30"}, 6280b57cec5SDimitry Andric {0x2c2b, "SPI_SHADER_USER_DATA_PS_31"}, 6290b57cec5SDimitry Andric 6300b57cec5SDimitry Andric {0x2e40, "COMPUTE_USER_DATA_0"}, 6310b57cec5SDimitry Andric {0x2e41, "COMPUTE_USER_DATA_1"}, 6320b57cec5SDimitry Andric {0x2e42, "COMPUTE_USER_DATA_2"}, 6330b57cec5SDimitry Andric {0x2e43, "COMPUTE_USER_DATA_3"}, 6340b57cec5SDimitry Andric {0x2e44, "COMPUTE_USER_DATA_4"}, 6350b57cec5SDimitry Andric {0x2e45, "COMPUTE_USER_DATA_5"}, 6360b57cec5SDimitry Andric {0x2e46, "COMPUTE_USER_DATA_6"}, 6370b57cec5SDimitry Andric {0x2e47, "COMPUTE_USER_DATA_7"}, 6380b57cec5SDimitry Andric {0x2e48, "COMPUTE_USER_DATA_8"}, 6390b57cec5SDimitry Andric {0x2e49, "COMPUTE_USER_DATA_9"}, 6400b57cec5SDimitry Andric {0x2e4a, "COMPUTE_USER_DATA_10"}, 6410b57cec5SDimitry Andric {0x2e4b, "COMPUTE_USER_DATA_11"}, 6420b57cec5SDimitry Andric {0x2e4c, "COMPUTE_USER_DATA_12"}, 6430b57cec5SDimitry Andric {0x2e4d, "COMPUTE_USER_DATA_13"}, 6440b57cec5SDimitry Andric {0x2e4e, "COMPUTE_USER_DATA_14"}, 6450b57cec5SDimitry Andric {0x2e4f, "COMPUTE_USER_DATA_15"}, 6460b57cec5SDimitry Andric 6470b57cec5SDimitry Andric {0x2e07, "COMPUTE_NUM_THREAD_X"}, 6480b57cec5SDimitry Andric {0x2e08, "COMPUTE_NUM_THREAD_Y"}, 6490b57cec5SDimitry Andric {0x2e09, "COMPUTE_NUM_THREAD_Z"}, 6500b57cec5SDimitry Andric {0xa2db, "VGT_TF_PARAM"}, 6510b57cec5SDimitry Andric {0xa2d6, "VGT_LS_HS_CONFIG"}, 6520b57cec5SDimitry Andric {0xa287, "VGT_HOS_MIN_TESS_LEVEL"}, 6530b57cec5SDimitry Andric {0xa286, "VGT_HOS_MAX_TESS_LEVEL"}, 6540b57cec5SDimitry Andric {0xa2f8, "PA_SC_AA_CONFIG"}, 6550b57cec5SDimitry Andric {0xa310, "PA_SC_SHADER_CONTROL"}, 6560b57cec5SDimitry Andric {0xa313, "PA_SC_CONSERVATIVE_RASTERIZATION_CNTL"}, 6570b57cec5SDimitry Andric 6585ffd83dbSDimitry Andric {0x2d0c, "SPI_SHADER_USER_DATA_HS_0"}, 6595ffd83dbSDimitry Andric {0x2d0d, "SPI_SHADER_USER_DATA_HS_1"}, 6605ffd83dbSDimitry Andric {0x2d0e, "SPI_SHADER_USER_DATA_HS_2"}, 6615ffd83dbSDimitry Andric {0x2d0f, "SPI_SHADER_USER_DATA_HS_3"}, 6625ffd83dbSDimitry Andric {0x2d10, "SPI_SHADER_USER_DATA_HS_4"}, 6635ffd83dbSDimitry Andric {0x2d11, "SPI_SHADER_USER_DATA_HS_5"}, 6645ffd83dbSDimitry Andric {0x2d12, "SPI_SHADER_USER_DATA_HS_6"}, 6655ffd83dbSDimitry Andric {0x2d13, "SPI_SHADER_USER_DATA_HS_7"}, 6665ffd83dbSDimitry Andric {0x2d14, "SPI_SHADER_USER_DATA_HS_8"}, 6675ffd83dbSDimitry Andric {0x2d15, "SPI_SHADER_USER_DATA_HS_9"}, 6685ffd83dbSDimitry Andric {0x2d16, "SPI_SHADER_USER_DATA_HS_10"}, 6695ffd83dbSDimitry Andric {0x2d17, "SPI_SHADER_USER_DATA_HS_11"}, 6705ffd83dbSDimitry Andric {0x2d18, "SPI_SHADER_USER_DATA_HS_12"}, 6715ffd83dbSDimitry Andric {0x2d19, "SPI_SHADER_USER_DATA_HS_13"}, 6725ffd83dbSDimitry Andric {0x2d1a, "SPI_SHADER_USER_DATA_HS_14"}, 6735ffd83dbSDimitry Andric {0x2d1b, "SPI_SHADER_USER_DATA_HS_15"}, 6745ffd83dbSDimitry Andric {0x2d1c, "SPI_SHADER_USER_DATA_HS_16"}, 6755ffd83dbSDimitry Andric {0x2d1d, "SPI_SHADER_USER_DATA_HS_17"}, 6765ffd83dbSDimitry Andric {0x2d1e, "SPI_SHADER_USER_DATA_HS_18"}, 6775ffd83dbSDimitry Andric {0x2d1f, "SPI_SHADER_USER_DATA_HS_19"}, 6785ffd83dbSDimitry Andric {0x2d20, "SPI_SHADER_USER_DATA_HS_20"}, 6795ffd83dbSDimitry Andric {0x2d21, "SPI_SHADER_USER_DATA_HS_21"}, 6805ffd83dbSDimitry Andric {0x2d22, "SPI_SHADER_USER_DATA_HS_22"}, 6815ffd83dbSDimitry Andric {0x2d23, "SPI_SHADER_USER_DATA_HS_23"}, 6825ffd83dbSDimitry Andric {0x2d24, "SPI_SHADER_USER_DATA_HS_24"}, 6835ffd83dbSDimitry Andric {0x2d25, "SPI_SHADER_USER_DATA_HS_25"}, 6845ffd83dbSDimitry Andric {0x2d26, "SPI_SHADER_USER_DATA_HS_26"}, 6855ffd83dbSDimitry Andric {0x2d27, "SPI_SHADER_USER_DATA_HS_27"}, 6865ffd83dbSDimitry Andric {0x2d28, "SPI_SHADER_USER_DATA_HS_28"}, 6875ffd83dbSDimitry Andric {0x2d29, "SPI_SHADER_USER_DATA_HS_29"}, 6885ffd83dbSDimitry Andric {0x2d2a, "SPI_SHADER_USER_DATA_HS_30"}, 6895ffd83dbSDimitry Andric {0x2d2b, "SPI_SHADER_USER_DATA_HS_31"}, 6905ffd83dbSDimitry Andric 6915ffd83dbSDimitry Andric {0x2d4c, "SPI_SHADER_USER_DATA_LS_0"}, 6925ffd83dbSDimitry Andric {0x2d4d, "SPI_SHADER_USER_DATA_LS_1"}, 6935ffd83dbSDimitry Andric {0x2d4e, "SPI_SHADER_USER_DATA_LS_2"}, 6945ffd83dbSDimitry Andric {0x2d4f, "SPI_SHADER_USER_DATA_LS_3"}, 6955ffd83dbSDimitry Andric {0x2d50, "SPI_SHADER_USER_DATA_LS_4"}, 6965ffd83dbSDimitry Andric {0x2d51, "SPI_SHADER_USER_DATA_LS_5"}, 6975ffd83dbSDimitry Andric {0x2d52, "SPI_SHADER_USER_DATA_LS_6"}, 6985ffd83dbSDimitry Andric {0x2d53, "SPI_SHADER_USER_DATA_LS_7"}, 6995ffd83dbSDimitry Andric {0x2d54, "SPI_SHADER_USER_DATA_LS_8"}, 7005ffd83dbSDimitry Andric {0x2d55, "SPI_SHADER_USER_DATA_LS_9"}, 7015ffd83dbSDimitry Andric {0x2d56, "SPI_SHADER_USER_DATA_LS_10"}, 7025ffd83dbSDimitry Andric {0x2d57, "SPI_SHADER_USER_DATA_LS_11"}, 7035ffd83dbSDimitry Andric {0x2d58, "SPI_SHADER_USER_DATA_LS_12"}, 7045ffd83dbSDimitry Andric {0x2d59, "SPI_SHADER_USER_DATA_LS_13"}, 7055ffd83dbSDimitry Andric {0x2d5a, "SPI_SHADER_USER_DATA_LS_14"}, 7065ffd83dbSDimitry Andric {0x2d5b, "SPI_SHADER_USER_DATA_LS_15"}, 7070b57cec5SDimitry Andric 7080b57cec5SDimitry Andric {0xa2aa, "IA_MULTI_VGT_PARAM"}, 7090b57cec5SDimitry Andric {0xa2a5, "VGT_GS_MAX_PRIMS_PER_SUBGROUP"}, 7100b57cec5SDimitry Andric {0xa2e6, "VGT_STRMOUT_BUFFER_CONFIG"}, 7110b57cec5SDimitry Andric {0xa2e5, "VGT_STRMOUT_CONFIG"}, 7120b57cec5SDimitry Andric {0xa2b5, "VGT_STRMOUT_VTX_STRIDE_0"}, 7130b57cec5SDimitry Andric {0xa2b9, "VGT_STRMOUT_VTX_STRIDE_1"}, 7140b57cec5SDimitry Andric {0xa2bd, "VGT_STRMOUT_VTX_STRIDE_2"}, 7150b57cec5SDimitry Andric {0xa2c1, "VGT_STRMOUT_VTX_STRIDE_3"}, 7160b57cec5SDimitry Andric {0xa316, "VGT_VERTEX_REUSE_BLOCK_CNTL"}, 7170b57cec5SDimitry Andric 718fe6060f1SDimitry Andric {0x2e28, "COMPUTE_PGM_RSRC3"}, 719fe6060f1SDimitry Andric {0x2e2a, "COMPUTE_SHADER_CHKSUM"}, 720fe6060f1SDimitry Andric {0x2e24, "COMPUTE_USER_ACCUM_0"}, 721fe6060f1SDimitry Andric {0x2e25, "COMPUTE_USER_ACCUM_1"}, 722fe6060f1SDimitry Andric {0x2e26, "COMPUTE_USER_ACCUM_2"}, 723fe6060f1SDimitry Andric {0x2e27, "COMPUTE_USER_ACCUM_3"}, 724fe6060f1SDimitry Andric {0xa1ff, "GE_MAX_OUTPUT_PER_SUBGROUP"}, 725fe6060f1SDimitry Andric {0xa2d3, "GE_NGG_SUBGRP_CNTL"}, 726fe6060f1SDimitry Andric {0xc25f, "GE_STEREO_CNTL"}, 727fe6060f1SDimitry Andric {0xc262, "GE_USER_VGPR_EN"}, 728fe6060f1SDimitry Andric {0xc258, "IA_MULTI_VGT_PARAM_PIPED"}, 729fe6060f1SDimitry Andric {0xa210, "PA_STEREO_CNTL"}, 730fe6060f1SDimitry Andric {0xa1c2, "SPI_SHADER_IDX_FORMAT"}, 731fe6060f1SDimitry Andric {0x2c80, "SPI_SHADER_PGM_CHKSUM_GS"}, 732fe6060f1SDimitry Andric {0x2d00, "SPI_SHADER_PGM_CHKSUM_HS"}, 733fe6060f1SDimitry Andric {0x2c06, "SPI_SHADER_PGM_CHKSUM_PS"}, 734fe6060f1SDimitry Andric {0x2c45, "SPI_SHADER_PGM_CHKSUM_VS"}, 735fe6060f1SDimitry Andric {0x2c88, "SPI_SHADER_PGM_LO_GS"}, 736fe6060f1SDimitry Andric {0x2cb2, "SPI_SHADER_USER_ACCUM_ESGS_0"}, 737fe6060f1SDimitry Andric {0x2cb3, "SPI_SHADER_USER_ACCUM_ESGS_1"}, 738fe6060f1SDimitry Andric {0x2cb4, "SPI_SHADER_USER_ACCUM_ESGS_2"}, 739fe6060f1SDimitry Andric {0x2cb5, "SPI_SHADER_USER_ACCUM_ESGS_3"}, 740fe6060f1SDimitry Andric {0x2d32, "SPI_SHADER_USER_ACCUM_LSHS_0"}, 741fe6060f1SDimitry Andric {0x2d33, "SPI_SHADER_USER_ACCUM_LSHS_1"}, 742fe6060f1SDimitry Andric {0x2d34, "SPI_SHADER_USER_ACCUM_LSHS_2"}, 743fe6060f1SDimitry Andric {0x2d35, "SPI_SHADER_USER_ACCUM_LSHS_3"}, 744fe6060f1SDimitry Andric {0x2c32, "SPI_SHADER_USER_ACCUM_PS_0"}, 745fe6060f1SDimitry Andric {0x2c33, "SPI_SHADER_USER_ACCUM_PS_1"}, 746fe6060f1SDimitry Andric {0x2c34, "SPI_SHADER_USER_ACCUM_PS_2"}, 747fe6060f1SDimitry Andric {0x2c35, "SPI_SHADER_USER_ACCUM_PS_3"}, 748fe6060f1SDimitry Andric {0x2c72, "SPI_SHADER_USER_ACCUM_VS_0"}, 749fe6060f1SDimitry Andric {0x2c73, "SPI_SHADER_USER_ACCUM_VS_1"}, 750fe6060f1SDimitry Andric {0x2c74, "SPI_SHADER_USER_ACCUM_VS_2"}, 751fe6060f1SDimitry Andric {0x2c75, "SPI_SHADER_USER_ACCUM_VS_3"}, 752fe6060f1SDimitry Andric 7530b57cec5SDimitry Andric {0, nullptr}}; 7540b57cec5SDimitry Andric auto Entry = RegInfoTable; 7550b57cec5SDimitry Andric for (; Entry->Num && Entry->Num != RegNum; ++Entry) 7560b57cec5SDimitry Andric ; 7570b57cec5SDimitry Andric return Entry->Name; 7580b57cec5SDimitry Andric } 7590b57cec5SDimitry Andric 7600b57cec5SDimitry Andric // Convert the accumulated PAL metadata into an asm directive. 7610b57cec5SDimitry Andric void AMDGPUPALMetadata::toString(std::string &String) { 7620b57cec5SDimitry Andric String.clear(); 7630b57cec5SDimitry Andric if (!BlobType) 7640b57cec5SDimitry Andric return; 765*0fca6ea1SDimitry Andric ResolvedAll = DelayedExprs.resolveDelayedExpressions(); 7660b57cec5SDimitry Andric raw_string_ostream Stream(String); 7670b57cec5SDimitry Andric if (isLegacy()) { 7680b57cec5SDimitry Andric if (MsgPackDoc.getRoot().getKind() == msgpack::Type::Nil) 7690b57cec5SDimitry Andric return; 7700b57cec5SDimitry Andric // Old linear reg=val format. 7710b57cec5SDimitry Andric Stream << '\t' << AMDGPU::PALMD::AssemblerDirective << ' '; 7720b57cec5SDimitry Andric auto Regs = getRegisters(); 7730b57cec5SDimitry Andric for (auto I = Regs.begin(), E = Regs.end(); I != E; ++I) { 7740b57cec5SDimitry Andric if (I != Regs.begin()) 7750b57cec5SDimitry Andric Stream << ','; 7760b57cec5SDimitry Andric unsigned Reg = I->first.getUInt(); 7770b57cec5SDimitry Andric unsigned Val = I->second.getUInt(); 7780b57cec5SDimitry Andric Stream << "0x" << Twine::utohexstr(Reg) << ",0x" << Twine::utohexstr(Val); 7790b57cec5SDimitry Andric } 7800b57cec5SDimitry Andric Stream << '\n'; 7810b57cec5SDimitry Andric return; 7820b57cec5SDimitry Andric } 7830b57cec5SDimitry Andric 7840b57cec5SDimitry Andric // New msgpack-based format -- output as YAML (with unsigned numbers in hex), 7850b57cec5SDimitry Andric // but first change the registers map to use names. 7860b57cec5SDimitry Andric MsgPackDoc.setHexMode(); 7870b57cec5SDimitry Andric auto &RegsObj = refRegisters(); 7880b57cec5SDimitry Andric auto OrigRegs = RegsObj.getMap(); 7890b57cec5SDimitry Andric RegsObj = MsgPackDoc.getMapNode(); 7900b57cec5SDimitry Andric for (auto I : OrigRegs) { 7910b57cec5SDimitry Andric auto Key = I.first; 7920b57cec5SDimitry Andric if (const char *RegName = getRegisterName(Key.getUInt())) { 7930b57cec5SDimitry Andric std::string KeyName = Key.toString(); 7940b57cec5SDimitry Andric KeyName += " ("; 7950b57cec5SDimitry Andric KeyName += RegName; 7960b57cec5SDimitry Andric KeyName += ')'; 7970b57cec5SDimitry Andric Key = MsgPackDoc.getNode(KeyName, /*Copy=*/true); 7980b57cec5SDimitry Andric } 7990b57cec5SDimitry Andric RegsObj.getMap()[Key] = I.second; 8000b57cec5SDimitry Andric } 8010b57cec5SDimitry Andric 8020b57cec5SDimitry Andric // Output as YAML. 8030b57cec5SDimitry Andric Stream << '\t' << AMDGPU::PALMD::AssemblerDirectiveBegin << '\n'; 8040b57cec5SDimitry Andric MsgPackDoc.toYAML(Stream); 8050b57cec5SDimitry Andric Stream << '\t' << AMDGPU::PALMD::AssemblerDirectiveEnd << '\n'; 8060b57cec5SDimitry Andric 8070b57cec5SDimitry Andric // Restore original registers map. 8080b57cec5SDimitry Andric RegsObj = OrigRegs; 8090b57cec5SDimitry Andric } 8100b57cec5SDimitry Andric 8110b57cec5SDimitry Andric // Convert the accumulated PAL metadata into a binary blob for writing as 8120b57cec5SDimitry Andric // a .note record of the specified AMD type. Returns an empty blob if 8130b57cec5SDimitry Andric // there is no PAL metadata, 8140b57cec5SDimitry Andric void AMDGPUPALMetadata::toBlob(unsigned Type, std::string &Blob) { 815*0fca6ea1SDimitry Andric ResolvedAll = DelayedExprs.resolveDelayedExpressions(); 816fe6060f1SDimitry Andric if (Type == ELF::NT_AMD_PAL_METADATA) 8170b57cec5SDimitry Andric toLegacyBlob(Blob); 8180b57cec5SDimitry Andric else if (Type) 8190b57cec5SDimitry Andric toMsgPackBlob(Blob); 8200b57cec5SDimitry Andric } 8210b57cec5SDimitry Andric 8220b57cec5SDimitry Andric void AMDGPUPALMetadata::toLegacyBlob(std::string &Blob) { 8230b57cec5SDimitry Andric Blob.clear(); 8240b57cec5SDimitry Andric auto Registers = getRegisters(); 8250b57cec5SDimitry Andric if (Registers.getMap().empty()) 8260b57cec5SDimitry Andric return; 8270b57cec5SDimitry Andric raw_string_ostream OS(Blob); 8285f757f3fSDimitry Andric support::endian::Writer EW(OS, llvm::endianness::little); 8290b57cec5SDimitry Andric for (auto I : Registers.getMap()) { 8300b57cec5SDimitry Andric EW.write(uint32_t(I.first.getUInt())); 8310b57cec5SDimitry Andric EW.write(uint32_t(I.second.getUInt())); 8320b57cec5SDimitry Andric } 8330b57cec5SDimitry Andric } 8340b57cec5SDimitry Andric 8350b57cec5SDimitry Andric void AMDGPUPALMetadata::toMsgPackBlob(std::string &Blob) { 8360b57cec5SDimitry Andric Blob.clear(); 8370b57cec5SDimitry Andric MsgPackDoc.writeToBlob(Blob); 8380b57cec5SDimitry Andric } 8390b57cec5SDimitry Andric 8400b57cec5SDimitry Andric // Set PAL metadata from YAML text. Returns false if failed. 8410b57cec5SDimitry Andric bool AMDGPUPALMetadata::setFromString(StringRef S) { 8420b57cec5SDimitry Andric BlobType = ELF::NT_AMDGPU_METADATA; 8430b57cec5SDimitry Andric if (!MsgPackDoc.fromYAML(S)) 8440b57cec5SDimitry Andric return false; 8450b57cec5SDimitry Andric 8460b57cec5SDimitry Andric // In the registers map, some keys may be of the form "0xa191 8470b57cec5SDimitry Andric // (SPI_PS_INPUT_CNTL_0)", in which case the YAML input code made it a 8480b57cec5SDimitry Andric // string. We need to turn it into a number. 8490b57cec5SDimitry Andric auto &RegsObj = refRegisters(); 8500b57cec5SDimitry Andric auto OrigRegs = RegsObj; 8510b57cec5SDimitry Andric RegsObj = MsgPackDoc.getMapNode(); 8520b57cec5SDimitry Andric Registers = RegsObj.getMap(); 8530b57cec5SDimitry Andric bool Ok = true; 8540b57cec5SDimitry Andric for (auto I : OrigRegs.getMap()) { 8550b57cec5SDimitry Andric auto Key = I.first; 8560b57cec5SDimitry Andric if (Key.getKind() == msgpack::Type::String) { 8570b57cec5SDimitry Andric StringRef S = Key.getString(); 8580b57cec5SDimitry Andric uint64_t Val; 8590b57cec5SDimitry Andric if (S.consumeInteger(0, Val)) { 8600b57cec5SDimitry Andric Ok = false; 8610b57cec5SDimitry Andric errs() << "Unrecognized PAL metadata register key '" << S << "'\n"; 8620b57cec5SDimitry Andric continue; 8630b57cec5SDimitry Andric } 8640b57cec5SDimitry Andric Key = MsgPackDoc.getNode(uint64_t(Val)); 8650b57cec5SDimitry Andric } 8660b57cec5SDimitry Andric Registers.getMap()[Key] = I.second; 8670b57cec5SDimitry Andric } 8680b57cec5SDimitry Andric return Ok; 8690b57cec5SDimitry Andric } 8700b57cec5SDimitry Andric 8710b57cec5SDimitry Andric // Reference (create if necessary) the node for the registers map. 8720b57cec5SDimitry Andric msgpack::DocNode &AMDGPUPALMetadata::refRegisters() { 8730b57cec5SDimitry Andric auto &N = 8740b57cec5SDimitry Andric MsgPackDoc.getRoot() 8750b57cec5SDimitry Andric .getMap(/*Convert=*/true)[MsgPackDoc.getNode("amdpal.pipelines")] 8760b57cec5SDimitry Andric .getArray(/*Convert=*/true)[0] 8770b57cec5SDimitry Andric .getMap(/*Convert=*/true)[MsgPackDoc.getNode(".registers")]; 8780b57cec5SDimitry Andric N.getMap(/*Convert=*/true); 8790b57cec5SDimitry Andric return N; 8800b57cec5SDimitry Andric } 8810b57cec5SDimitry Andric 8820b57cec5SDimitry Andric // Get (create if necessary) the registers map. 8830b57cec5SDimitry Andric msgpack::MapDocNode AMDGPUPALMetadata::getRegisters() { 8840b57cec5SDimitry Andric if (Registers.isEmpty()) 8850b57cec5SDimitry Andric Registers = refRegisters(); 8860b57cec5SDimitry Andric return Registers.getMap(); 8870b57cec5SDimitry Andric } 8880b57cec5SDimitry Andric 889e8d8bef9SDimitry Andric // Reference (create if necessary) the node for the shader functions map. 890e8d8bef9SDimitry Andric msgpack::DocNode &AMDGPUPALMetadata::refShaderFunctions() { 891e8d8bef9SDimitry Andric auto &N = 892e8d8bef9SDimitry Andric MsgPackDoc.getRoot() 893e8d8bef9SDimitry Andric .getMap(/*Convert=*/true)[MsgPackDoc.getNode("amdpal.pipelines")] 894e8d8bef9SDimitry Andric .getArray(/*Convert=*/true)[0] 895e8d8bef9SDimitry Andric .getMap(/*Convert=*/true)[MsgPackDoc.getNode(".shader_functions")]; 896e8d8bef9SDimitry Andric N.getMap(/*Convert=*/true); 897e8d8bef9SDimitry Andric return N; 898e8d8bef9SDimitry Andric } 899e8d8bef9SDimitry Andric 900e8d8bef9SDimitry Andric // Get (create if necessary) the shader functions map. 901e8d8bef9SDimitry Andric msgpack::MapDocNode AMDGPUPALMetadata::getShaderFunctions() { 902e8d8bef9SDimitry Andric if (ShaderFunctions.isEmpty()) 903e8d8bef9SDimitry Andric ShaderFunctions = refShaderFunctions(); 904e8d8bef9SDimitry Andric return ShaderFunctions.getMap(); 905e8d8bef9SDimitry Andric } 906e8d8bef9SDimitry Andric 907e8d8bef9SDimitry Andric // Get (create if necessary) a function in the shader functions map. 908e8d8bef9SDimitry Andric msgpack::MapDocNode AMDGPUPALMetadata::getShaderFunction(StringRef Name) { 909e8d8bef9SDimitry Andric auto Functions = getShaderFunctions(); 910e8d8bef9SDimitry Andric return Functions[Name].getMap(/*Convert=*/true); 911e8d8bef9SDimitry Andric } 912e8d8bef9SDimitry Andric 91306c3fb27SDimitry Andric msgpack::DocNode &AMDGPUPALMetadata::refComputeRegisters() { 91406c3fb27SDimitry Andric auto &N = 91506c3fb27SDimitry Andric MsgPackDoc.getRoot() 91606c3fb27SDimitry Andric .getMap(/*Convert=*/true)[MsgPackDoc.getNode("amdpal.pipelines")] 91706c3fb27SDimitry Andric .getArray(/*Convert=*/true)[0] 91806c3fb27SDimitry Andric .getMap(/*Convert=*/true)[MsgPackDoc.getNode(".compute_registers")]; 91906c3fb27SDimitry Andric N.getMap(/*Convert=*/true); 92006c3fb27SDimitry Andric return N; 92106c3fb27SDimitry Andric } 92206c3fb27SDimitry Andric 92306c3fb27SDimitry Andric msgpack::MapDocNode AMDGPUPALMetadata::getComputeRegisters() { 92406c3fb27SDimitry Andric if (ComputeRegisters.isEmpty()) 92506c3fb27SDimitry Andric ComputeRegisters = refComputeRegisters(); 92606c3fb27SDimitry Andric return ComputeRegisters.getMap(); 92706c3fb27SDimitry Andric } 92806c3fb27SDimitry Andric 92906c3fb27SDimitry Andric msgpack::DocNode &AMDGPUPALMetadata::refGraphicsRegisters() { 93006c3fb27SDimitry Andric auto &N = 93106c3fb27SDimitry Andric MsgPackDoc.getRoot() 93206c3fb27SDimitry Andric .getMap(/*Convert=*/true)[MsgPackDoc.getNode("amdpal.pipelines")] 93306c3fb27SDimitry Andric .getArray(/*Convert=*/true)[0] 93406c3fb27SDimitry Andric .getMap(/*Convert=*/true)[MsgPackDoc.getNode(".graphics_registers")]; 93506c3fb27SDimitry Andric N.getMap(/*Convert=*/true); 93606c3fb27SDimitry Andric return N; 93706c3fb27SDimitry Andric } 93806c3fb27SDimitry Andric 93906c3fb27SDimitry Andric msgpack::MapDocNode AMDGPUPALMetadata::getGraphicsRegisters() { 94006c3fb27SDimitry Andric if (GraphicsRegisters.isEmpty()) 94106c3fb27SDimitry Andric GraphicsRegisters = refGraphicsRegisters(); 94206c3fb27SDimitry Andric return GraphicsRegisters.getMap(); 94306c3fb27SDimitry Andric } 94406c3fb27SDimitry Andric 9450b57cec5SDimitry Andric // Return the PAL metadata hardware shader stage name. 9460b57cec5SDimitry Andric static const char *getStageName(CallingConv::ID CC) { 9470b57cec5SDimitry Andric switch (CC) { 9480b57cec5SDimitry Andric case CallingConv::AMDGPU_PS: 9490b57cec5SDimitry Andric return ".ps"; 9500b57cec5SDimitry Andric case CallingConv::AMDGPU_VS: 9510b57cec5SDimitry Andric return ".vs"; 9520b57cec5SDimitry Andric case CallingConv::AMDGPU_GS: 9530b57cec5SDimitry Andric return ".gs"; 9540b57cec5SDimitry Andric case CallingConv::AMDGPU_ES: 9550b57cec5SDimitry Andric return ".es"; 9560b57cec5SDimitry Andric case CallingConv::AMDGPU_HS: 9570b57cec5SDimitry Andric return ".hs"; 9580b57cec5SDimitry Andric case CallingConv::AMDGPU_LS: 9590b57cec5SDimitry Andric return ".ls"; 960e8d8bef9SDimitry Andric case CallingConv::AMDGPU_Gfx: 961e8d8bef9SDimitry Andric llvm_unreachable("Callable shader has no hardware stage"); 9620b57cec5SDimitry Andric default: 9630b57cec5SDimitry Andric return ".cs"; 9640b57cec5SDimitry Andric } 9650b57cec5SDimitry Andric } 9660b57cec5SDimitry Andric 96706c3fb27SDimitry Andric msgpack::DocNode &AMDGPUPALMetadata::refHwStage() { 96806c3fb27SDimitry Andric auto &N = 96906c3fb27SDimitry Andric MsgPackDoc.getRoot() 97006c3fb27SDimitry Andric .getMap(/*Convert=*/true)[MsgPackDoc.getNode("amdpal.pipelines")] 97106c3fb27SDimitry Andric .getArray(/*Convert=*/true)[0] 97206c3fb27SDimitry Andric .getMap(/*Convert=*/true)[MsgPackDoc.getNode(".hardware_stages")]; 97306c3fb27SDimitry Andric N.getMap(/*Convert=*/true); 97406c3fb27SDimitry Andric return N; 97506c3fb27SDimitry Andric } 97606c3fb27SDimitry Andric 9770b57cec5SDimitry Andric // Get (create if necessary) the .hardware_stages entry for the given calling 9780b57cec5SDimitry Andric // convention. 9790b57cec5SDimitry Andric msgpack::MapDocNode AMDGPUPALMetadata::getHwStage(unsigned CC) { 9800b57cec5SDimitry Andric if (HwStages.isEmpty()) 98106c3fb27SDimitry Andric HwStages = refHwStage(); 9820b57cec5SDimitry Andric return HwStages.getMap()[getStageName(CC)].getMap(/*Convert=*/true); 9830b57cec5SDimitry Andric } 9840b57cec5SDimitry Andric 9850b57cec5SDimitry Andric // Get .note record vendor name of metadata blob to be emitted. 9860b57cec5SDimitry Andric const char *AMDGPUPALMetadata::getVendor() const { 9870b57cec5SDimitry Andric return isLegacy() ? ElfNote::NoteNameV2 : ElfNote::NoteNameV3; 9880b57cec5SDimitry Andric } 9890b57cec5SDimitry Andric 9900b57cec5SDimitry Andric // Get .note record type of metadata blob to be emitted: 991fe6060f1SDimitry Andric // ELF::NT_AMD_PAL_METADATA (legacy key=val format), or 9920b57cec5SDimitry Andric // ELF::NT_AMDGPU_METADATA (MsgPack format), or 9930b57cec5SDimitry Andric // 0 (no PAL metadata). 9940b57cec5SDimitry Andric unsigned AMDGPUPALMetadata::getType() const { 9950b57cec5SDimitry Andric return BlobType; 9960b57cec5SDimitry Andric } 9970b57cec5SDimitry Andric 9980b57cec5SDimitry Andric // Return whether the blob type is legacy PAL metadata. 9990b57cec5SDimitry Andric bool AMDGPUPALMetadata::isLegacy() const { 1000fe6060f1SDimitry Andric return BlobType == ELF::NT_AMD_PAL_METADATA; 10010b57cec5SDimitry Andric } 10020b57cec5SDimitry Andric 10030b57cec5SDimitry Andric // Set legacy PAL metadata format. 10040b57cec5SDimitry Andric void AMDGPUPALMetadata::setLegacy() { 1005fe6060f1SDimitry Andric BlobType = ELF::NT_AMD_PAL_METADATA; 10060b57cec5SDimitry Andric } 10070b57cec5SDimitry Andric 1008e8d8bef9SDimitry Andric // Erase all PAL metadata. 1009e8d8bef9SDimitry Andric void AMDGPUPALMetadata::reset() { 1010e8d8bef9SDimitry Andric MsgPackDoc.clear(); 1011*0fca6ea1SDimitry Andric REM.clear(); 1012*0fca6ea1SDimitry Andric DelayedExprs.clear(); 1013e8d8bef9SDimitry Andric Registers = MsgPackDoc.getEmptyNode(); 1014e8d8bef9SDimitry Andric HwStages = MsgPackDoc.getEmptyNode(); 10155f757f3fSDimitry Andric ShaderFunctions = MsgPackDoc.getEmptyNode(); 1016e8d8bef9SDimitry Andric } 101706c3fb27SDimitry Andric 1018*0fca6ea1SDimitry Andric bool AMDGPUPALMetadata::resolvedAllMCExpr() { 1019*0fca6ea1SDimitry Andric return ResolvedAll && DelayedExprs.empty(); 1020*0fca6ea1SDimitry Andric } 1021*0fca6ea1SDimitry Andric 102206c3fb27SDimitry Andric unsigned AMDGPUPALMetadata::getPALVersion(unsigned idx) { 102306c3fb27SDimitry Andric assert(idx < 2 && 102406c3fb27SDimitry Andric "illegal index to PAL version - should be 0 (major) or 1 (minor)"); 102506c3fb27SDimitry Andric if (!VersionChecked) { 102606c3fb27SDimitry Andric if (Version.isEmpty()) { 102706c3fb27SDimitry Andric auto &M = MsgPackDoc.getRoot().getMap(/*Convert=*/true); 102806c3fb27SDimitry Andric auto I = M.find(MsgPackDoc.getNode("amdpal.version")); 102906c3fb27SDimitry Andric if (I != M.end()) 103006c3fb27SDimitry Andric Version = I->second; 103106c3fb27SDimitry Andric } 103206c3fb27SDimitry Andric VersionChecked = true; 103306c3fb27SDimitry Andric } 103406c3fb27SDimitry Andric if (Version.isEmpty()) 103506c3fb27SDimitry Andric // Default to 2.6 if there's no version info 103606c3fb27SDimitry Andric return idx ? 6 : 2; 103706c3fb27SDimitry Andric return Version.getArray()[idx].getUInt(); 103806c3fb27SDimitry Andric } 103906c3fb27SDimitry Andric 104006c3fb27SDimitry Andric unsigned AMDGPUPALMetadata::getPALMajorVersion() { return getPALVersion(0); } 104106c3fb27SDimitry Andric 104206c3fb27SDimitry Andric unsigned AMDGPUPALMetadata::getPALMinorVersion() { return getPALVersion(1); } 104306c3fb27SDimitry Andric 104406c3fb27SDimitry Andric // Set the field in a given .hardware_stages entry 104506c3fb27SDimitry Andric void AMDGPUPALMetadata::setHwStage(unsigned CC, StringRef field, unsigned Val) { 104606c3fb27SDimitry Andric getHwStage(CC)[field] = Val; 104706c3fb27SDimitry Andric } 104806c3fb27SDimitry Andric 104906c3fb27SDimitry Andric void AMDGPUPALMetadata::setHwStage(unsigned CC, StringRef field, bool Val) { 105006c3fb27SDimitry Andric getHwStage(CC)[field] = Val; 105106c3fb27SDimitry Andric } 105206c3fb27SDimitry Andric 1053*0fca6ea1SDimitry Andric void AMDGPUPALMetadata::setHwStage(unsigned CC, StringRef field, 1054*0fca6ea1SDimitry Andric msgpack::Type Type, const MCExpr *Val) { 1055*0fca6ea1SDimitry Andric DelayedExprs.assignDocNode(getHwStage(CC)[field], Type, Val); 1056*0fca6ea1SDimitry Andric } 1057*0fca6ea1SDimitry Andric 105806c3fb27SDimitry Andric void AMDGPUPALMetadata::setComputeRegisters(StringRef field, unsigned Val) { 105906c3fb27SDimitry Andric getComputeRegisters()[field] = Val; 106006c3fb27SDimitry Andric } 106106c3fb27SDimitry Andric 106206c3fb27SDimitry Andric void AMDGPUPALMetadata::setComputeRegisters(StringRef field, bool Val) { 106306c3fb27SDimitry Andric getComputeRegisters()[field] = Val; 106406c3fb27SDimitry Andric } 106506c3fb27SDimitry Andric 106606c3fb27SDimitry Andric msgpack::DocNode *AMDGPUPALMetadata::refComputeRegister(StringRef field) { 106706c3fb27SDimitry Andric auto M = getComputeRegisters(); 106806c3fb27SDimitry Andric auto I = M.find(field); 106906c3fb27SDimitry Andric return I == M.end() ? nullptr : &I->second; 107006c3fb27SDimitry Andric } 107106c3fb27SDimitry Andric 107206c3fb27SDimitry Andric bool AMDGPUPALMetadata::checkComputeRegisters(StringRef field, unsigned Val) { 107306c3fb27SDimitry Andric if (auto N = refComputeRegister(field)) 107406c3fb27SDimitry Andric return N->getUInt() == Val; 107506c3fb27SDimitry Andric return false; 107606c3fb27SDimitry Andric } 107706c3fb27SDimitry Andric 107806c3fb27SDimitry Andric bool AMDGPUPALMetadata::checkComputeRegisters(StringRef field, bool Val) { 107906c3fb27SDimitry Andric if (auto N = refComputeRegister(field)) 108006c3fb27SDimitry Andric return N->getBool() == Val; 108106c3fb27SDimitry Andric return false; 108206c3fb27SDimitry Andric } 108306c3fb27SDimitry Andric 108406c3fb27SDimitry Andric void AMDGPUPALMetadata::setGraphicsRegisters(StringRef field, unsigned Val) { 108506c3fb27SDimitry Andric getGraphicsRegisters()[field] = Val; 108606c3fb27SDimitry Andric } 108706c3fb27SDimitry Andric 108806c3fb27SDimitry Andric void AMDGPUPALMetadata::setGraphicsRegisters(StringRef field, bool Val) { 108906c3fb27SDimitry Andric getGraphicsRegisters()[field] = Val; 109006c3fb27SDimitry Andric } 109106c3fb27SDimitry Andric 109206c3fb27SDimitry Andric void AMDGPUPALMetadata::setGraphicsRegisters(StringRef field1, StringRef field2, 109306c3fb27SDimitry Andric unsigned Val) { 109406c3fb27SDimitry Andric getGraphicsRegisters()[field1].getMap(true)[field2] = Val; 109506c3fb27SDimitry Andric } 109606c3fb27SDimitry Andric 109706c3fb27SDimitry Andric void AMDGPUPALMetadata::setGraphicsRegisters(StringRef field1, StringRef field2, 109806c3fb27SDimitry Andric bool Val) { 109906c3fb27SDimitry Andric getGraphicsRegisters()[field1].getMap(true)[field2] = Val; 110006c3fb27SDimitry Andric } 1101