LLVM 24.0.0git
AMDGPUPALMetadata.cpp
Go to the documentation of this file.
1//===-- AMDGPUPALMetadata.cpp - Accumulate and print AMDGPU PAL metadata -===//
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/// \file
10///
11/// This class has methods called by AMDGPUAsmPrinter to accumulate and print
12/// the PAL metadata.
13//
14//===----------------------------------------------------------------------===//
15//
16
17#include "AMDGPUPALMetadata.h"
18#include "AMDGPUPTNote.h"
19#include "SIDefines.h"
20#include "llvm/ADT/Enum.h"
22#include "llvm/IR/Constants.h"
23#include "llvm/IR/Module.h"
24#include "llvm/MC/MCExpr.h"
28
29using namespace llvm;
30using namespace llvm::AMDGPU;
31
32// Return the PAL metadata hardware shader stage name.
33static const char *getStageName(CallingConv::ID CC) {
34 switch (CC) {
36 return ".ps";
38 return ".vs";
40 return ".gs";
42 return ".es";
44 return ".hs";
46 return ".ls";
49 llvm_unreachable("Callable shader has no hardware stage");
50 default:
51 return ".cs";
52 }
53}
54
55// Read the PAL metadata from IR metadata, where it was put by the frontend.
57 auto *NamedMD = M.getNamedMetadata("amdgpu.pal.metadata.msgpack");
58 if (NamedMD && NamedMD->getNumOperands()) {
59 // This is the new msgpack format for metadata. It is a NamedMD containing
60 // an MDTuple containing an MDString containing the msgpack data.
61 BlobType = ELF::NT_AMDGPU_METADATA;
62 auto *MDN = dyn_cast<MDTuple>(NamedMD->getOperand(0));
63 if (MDN && MDN->getNumOperands()) {
64 if (auto *MDS = dyn_cast<MDString>(MDN->getOperand(0)))
65 setFromMsgPackBlob(MDS->getString());
66 }
67 return;
68 }
69 BlobType = ELF::NT_AMD_PAL_METADATA;
70 NamedMD = M.getNamedMetadata("amdgpu.pal.metadata");
71 if (!NamedMD || !NamedMD->getNumOperands()) {
72 // Emit msgpack metadata by default
73 BlobType = ELF::NT_AMDGPU_METADATA;
74 return;
75 }
76 // This is the old reg=value pair format for metadata. It is a NamedMD
77 // containing an MDTuple containing a number of MDNodes each of which is an
78 // integer value, and each two integer values forms a key=value pair that we
79 // store as Registers[key]=value in the map.
80 auto *Tuple = dyn_cast<MDTuple>(NamedMD->getOperand(0));
81 if (!Tuple)
82 return;
83 for (unsigned I = 0, E = Tuple->getNumOperands() & -2; I != E; I += 2) {
84 auto *Key = mdconst::dyn_extract<ConstantInt>(Tuple->getOperand(I));
85 auto *Val = mdconst::dyn_extract<ConstantInt>(Tuple->getOperand(I + 1));
86 if (!Key || !Val)
87 continue;
88 setRegister(Key->getZExtValue(), Val->getZExtValue());
89 }
90}
91
92// Set PAL metadata from msgpack blob.
93bool AMDGPUPALMetadata::setFromMsgPackBlob(StringRef Blob) {
94 return MsgPackDoc.readFromBlob(Blob, /*Multi=*/false);
95}
96
97// Given the calling convention, calculate the register number for rsrc1. In
98// principle the register number could change in future hardware, but we know
99// it is the same for gfx6-9 (except that LS and ES don't exist on gfx9), so
100// we can use fixed values.
119
120// Calculate the PAL metadata key for *S_SCRATCH_SIZE. It can be used
121// with a constant offset to access any non-register shader-specific PAL
122// metadata key.
141
142// Set the rsrc1 register in the metadata for a particular shader stage.
143// In fact this ORs the value into any previous setting of the register.
145 setRegister(getRsrc1Reg(CC), Val);
146}
147
149 MCContext &Ctx) {
150 setRegister(getRsrc1Reg(CC), Val, Ctx);
151}
152
153// Set the rsrc2 register in the metadata for a particular shader stage.
154// In fact this ORs the value into any previous setting of the register.
156 setRegister(getRsrc1Reg(CC) + 1, Val);
157}
158
160 MCContext &Ctx) {
161 setRegister(getRsrc1Reg(CC) + 1, Val, Ctx);
162}
163
164// Set the SPI_PS_INPUT_ENA register in the metadata.
165// In fact this ORs the value into any previous setting of the register.
169
170// Set the SPI_PS_INPUT_ADDR register in the metadata.
171// In fact this ORs the value into any previous setting of the register.
175
176// Get a register from the metadata, or 0 if not currently set.
177unsigned AMDGPUPALMetadata::getRegister(unsigned Reg) {
178 auto Regs = getRegisters();
179 auto It = Regs.find(MsgPackDoc.getNode(Reg));
180 if (It == Regs.end())
181 return 0;
182 auto N = It->second;
183 if (N.getKind() != msgpack::Type::UInt)
184 return 0;
185 return N.getUInt();
186}
187
188// Set a register in the metadata.
189// In fact this ORs the value into any previous setting of the register.
190void AMDGPUPALMetadata::setRegister(unsigned Reg, unsigned Val) {
191 if (!isLegacy()) {
192 // In the new MsgPack format, ignore register numbered >= 0x10000000. It
193 // is a PAL ABI pseudo-register in the old non-MsgPack format.
194 if (Reg >= 0x10000000)
195 return;
196 }
197 auto &N = getRegisters()[MsgPackDoc.getNode(Reg)];
198 if (N.getKind() == msgpack::Type::UInt)
199 Val |= N.getUInt();
200 N = N.getDocument()->getNode(Val);
201}
202
203// Set a register in the metadata.
204// In fact this ORs the value into any previous setting of the register.
205void AMDGPUPALMetadata::setRegister(unsigned Reg, const MCExpr *Val,
206 MCContext &Ctx) {
207 if (!isLegacy()) {
208 // In the new MsgPack format, ignore register numbered >= 0x10000000. It
209 // is a PAL ABI pseudo-register in the old non-MsgPack format.
210 if (Reg >= 0x10000000)
211 return;
212 }
213 auto &N = getRegisters()[MsgPackDoc.getNode(Reg)];
214 auto [ExprIt, Inserted] = REM.try_emplace(Reg);
215
216 if (!Inserted) {
217 Val = MCBinaryExpr::createOr(Val, ExprIt->getSecond(), Ctx);
218 // This conditional may be redundant most of the time, but the alternate
219 // setRegister(unsigned, unsigned) could've been called while the
220 // conditional returns true (i.e., Reg exists in REM).
221 if (N.getKind() == msgpack::Type::UInt) {
222 const MCExpr *NExpr = MCConstantExpr::create(N.getUInt(), Ctx);
223 Val = MCBinaryExpr::createOr(Val, NExpr, Ctx);
224 }
225 } else if (N.getKind() == msgpack::Type::UInt) {
226 const MCExpr *NExpr = MCConstantExpr::create(N.getUInt(), Ctx);
227 Val = MCBinaryExpr::createOr(Val, NExpr, Ctx);
228 } else {
229 // Default to uint64_t 0 so additional calls to setRegister will allow
230 // propagate ORs.
231 N = (uint64_t)0;
232 }
233 ExprIt->second = Val;
234 DelayedExprs.assignDocNode(N, msgpack::Type::UInt, Val);
235}
236
237// Set the entry point name for one shader.
239 if (isLegacy())
240 return;
241 // Msgpack format.
242 // Entry point is updated to .entry_point_symbol and is set to the function
243 // name
244 getHwStage(CC)[".entry_point_symbol"] =
245 MsgPackDoc.getNode(Name, /*Copy=*/true);
246
247 // For PAL version 3.6 and above, entry_point is no longer required.
248 if (getPALVersion() < VersionTuple(3, 6)) {
249 // Set .entry_point which is defined to be _amdgpu_<stage>_main and
250 // _amdgpu_cs_main for non-shader functions.
251 SmallString<16> EPName("_amdgpu_");
252 raw_svector_ostream EPNameOS(EPName);
253 EPNameOS << getStageName(CC) + 1 << "_main";
254 getHwStage(CC)[".entry_point"] =
255 MsgPackDoc.getNode(EPNameOS.str(), /*Copy=*/true);
256 }
257}
258
259// Set the number of used vgprs in the metadata. This is an optional
260// advisory record for logging etc; wave dispatch actually uses the rsrc1
261// register for the shader stage to determine the number of vgprs to
262// allocate.
264 if (isLegacy()) {
265 // Old non-msgpack format.
266 unsigned NumUsedVgprsKey = getScratchSizeKey(CC) +
269 setRegister(NumUsedVgprsKey, Val);
270 return;
271 }
272 // Msgpack format.
273 getHwStage(CC)[".vgpr_count"] = MsgPackDoc.getNode(Val);
274}
275
277 MCContext &Ctx) {
278 if (isLegacy()) {
279 // Old non-msgpack format.
280 unsigned NumUsedVgprsKey = getScratchSizeKey(CC) +
283 setRegister(NumUsedVgprsKey, Val, Ctx);
284 return;
285 }
286 // Msgpack format.
287 setHwStage(CC, ".vgpr_count", msgpack::Type::UInt, Val);
288}
289
290// Set the number of used agprs in the metadata.
292 getHwStage(CC)[".agpr_count"] = Val;
293}
294
295void AMDGPUPALMetadata::setNumUsedAgprs(unsigned CC, const MCExpr *Val) {
296 setHwStage(CC, ".agpr_count", msgpack::Type::UInt, Val);
297}
298
299// Set the number of used sgprs in the metadata. This is an optional advisory
300// record for logging etc; wave dispatch actually uses the rsrc1 register for
301// the shader stage to determine the number of sgprs to allocate.
303 if (isLegacy()) {
304 // Old non-msgpack format.
305 unsigned NumUsedSgprsKey = getScratchSizeKey(CC) +
308 setRegister(NumUsedSgprsKey, Val);
309 return;
310 }
311 // Msgpack format.
312 getHwStage(CC)[".sgpr_count"] = MsgPackDoc.getNode(Val);
313}
314
315void AMDGPUPALMetadata::setNumUsedSgprs(unsigned CC, const MCExpr *Val,
316 MCContext &Ctx) {
317 if (isLegacy()) {
318 // Old non-msgpack format.
319 unsigned NumUsedSgprsKey = getScratchSizeKey(CC) +
322 setRegister(NumUsedSgprsKey, Val, Ctx);
323 return;
324 }
325 // Msgpack format.
326 setHwStage(CC, ".sgpr_count", msgpack::Type::UInt, Val);
327}
328
329// Set the scratch size in the metadata.
331 if (isLegacy()) {
332 // Old non-msgpack format.
334 return;
335 }
336 // Msgpack format.
337 getHwStage(CC)[".scratch_memory_size"] = MsgPackDoc.getNode(Val);
338}
339
340void AMDGPUPALMetadata::setScratchSize(unsigned CC, const MCExpr *Val,
341 MCContext &Ctx) {
342 if (isLegacy()) {
343 // Old non-msgpack format.
344 setRegister(getScratchSizeKey(CC), Val, Ctx);
345 return;
346 }
347 // Msgpack format.
348 setHwStage(CC, ".scratch_memory_size", msgpack::Type::UInt, Val);
349}
350
351// Set the stack frame size of a function in the metadata.
353 auto Node = getShaderFunction(FnName);
354 Node[".stack_frame_size_in_bytes"] = MsgPackDoc.getNode(Val);
355 Node[".backend_stack_size"] = MsgPackDoc.getNode(Val);
356}
357
358// Set the amount of LDS used in bytes in the metadata.
360 auto Node = getShaderFunction(FnName);
361 Node[".lds_size"] = MsgPackDoc.getNode(Val);
362}
363
364// Set the number of used vgprs in the metadata.
366 unsigned Val) {
367 auto Node = getShaderFunction(FnName);
368 Node[".vgpr_count"] = MsgPackDoc.getNode(Val);
369}
370
372 const MCExpr *Val) {
373 auto Node = getShaderFunction(FnName);
374 DelayedExprs.assignDocNode(Node[".vgpr_count"], msgpack::Type::UInt, Val);
375}
376
377// Set the number of used vgprs in the metadata.
379 unsigned Val) {
380 auto Node = getShaderFunction(FnName);
381 Node[".sgpr_count"] = MsgPackDoc.getNode(Val);
382}
383
385 const MCExpr *Val) {
386 auto Node = getShaderFunction(FnName);
387 DelayedExprs.assignDocNode(Node[".sgpr_count"], msgpack::Type::UInt, Val);
388}
389
390// Set the hardware register bit in PAL metadata to enable wave32 on the
391// shader of the given calling convention.
412
413// Convert a register number to name, for display by toString().
414// Returns nullptr if none.
415static StringRef getRegisterName(unsigned RegNum) {
416 // Table of registers.
417 constexpr EnumStringDef<uint16_t> RegInfoTableDefs[] = {
418 // Registers that code generation sets/modifies metadata for.
419 {{"SPI_SHADER_PGM_RSRC1_VS"}, PALMD::R_2C4A_SPI_SHADER_PGM_RSRC1_VS},
420 {{"SPI_SHADER_PGM_RSRC2_VS"}, PALMD::R_2C4A_SPI_SHADER_PGM_RSRC1_VS + 1},
421 {{"SPI_SHADER_PGM_RSRC1_LS"}, PALMD::R_2D4A_SPI_SHADER_PGM_RSRC1_LS},
422 {{"SPI_SHADER_PGM_RSRC2_LS"}, PALMD::R_2D4A_SPI_SHADER_PGM_RSRC1_LS + 1},
423 {{"SPI_SHADER_PGM_RSRC1_HS"}, PALMD::R_2D0A_SPI_SHADER_PGM_RSRC1_HS},
424 {{"SPI_SHADER_PGM_RSRC2_HS"}, PALMD::R_2D0A_SPI_SHADER_PGM_RSRC1_HS + 1},
425 {{"SPI_SHADER_PGM_RSRC1_ES"}, PALMD::R_2CCA_SPI_SHADER_PGM_RSRC1_ES},
426 {{"SPI_SHADER_PGM_RSRC2_ES"}, PALMD::R_2CCA_SPI_SHADER_PGM_RSRC1_ES + 1},
427 {{"SPI_SHADER_PGM_RSRC1_GS"}, PALMD::R_2C8A_SPI_SHADER_PGM_RSRC1_GS},
428 {{"SPI_SHADER_PGM_RSRC2_GS"}, PALMD::R_2C8A_SPI_SHADER_PGM_RSRC1_GS + 1},
429 {{"COMPUTE_DISPATCH_INITIATOR"},
431 {{"COMPUTE_PGM_RSRC1"}, PALMD::R_2E12_COMPUTE_PGM_RSRC1},
432 {{"COMPUTE_PGM_RSRC2"}, PALMD::R_2E12_COMPUTE_PGM_RSRC1 + 1},
433 {{"SPI_SHADER_PGM_RSRC1_PS"}, PALMD::R_2C0A_SPI_SHADER_PGM_RSRC1_PS},
434 {{"SPI_SHADER_PGM_RSRC2_PS"}, PALMD::R_2C0A_SPI_SHADER_PGM_RSRC1_PS + 1},
435 {{"SPI_PS_INPUT_ENA"}, PALMD::R_A1B3_SPI_PS_INPUT_ENA},
436 {{"SPI_PS_INPUT_ADDR"}, PALMD::R_A1B4_SPI_PS_INPUT_ADDR},
437 {{"SPI_PS_IN_CONTROL"}, PALMD::R_A1B6_SPI_PS_IN_CONTROL},
438 {{"VGT_SHADER_STAGES_EN"}, PALMD::R_A2D5_VGT_SHADER_STAGES_EN},
439
440 // Registers not known to code generation.
441 {{"SPI_SHADER_PGM_RSRC3_PS"}, 0x2c07},
442 {{"SPI_SHADER_PGM_RSRC3_VS"}, 0x2c46},
443 {{"SPI_SHADER_PGM_RSRC3_GS"}, 0x2c87},
444 {{"SPI_SHADER_PGM_RSRC3_ES"}, 0x2cc7},
445 {{"SPI_SHADER_PGM_RSRC3_HS"}, 0x2d07},
446 {{"SPI_SHADER_PGM_RSRC3_LS"}, 0x2d47},
447
448 {{"SPI_SHADER_POS_FORMAT"}, 0xa1c3},
449 {{"SPI_VS_OUT_CONFIG"}, 0xa1b1},
450 {{"PA_CL_VS_OUT_CNTL"}, 0xa207},
451 {{"PA_CL_CLIP_CNTL"}, 0xa204},
452 {{"PA_CL_VTE_CNTL"}, 0xa206},
453 {{"PA_SU_VTX_CNTL"}, 0xa2f9},
454 {{"PA_SC_MODE_CNTL_1"}, 0xa293},
455 {{"VGT_PRIMITIVEID_EN"}, 0xa2a1},
456 {{"SPI_SHADER_PGM_RSRC4_GS"}, 0x2c81},
457 {{"COMPUTE_TMPRING_SIZE"}, 0x2e18},
458 {{"SPI_INTERP_CONTROL_0"}, 0xa1b5},
459 {{"SPI_TMPRING_SIZE"}, 0xa1ba},
460 {{"SPI_SHADER_Z_FORMAT"}, 0xa1c4},
461 {{"SPI_SHADER_COL_FORMAT"}, 0xa1c5},
462 {{"DB_SHADER_CONTROL"}, 0xa203},
463 {{"CB_SHADER_MASK"}, 0xa08f},
464 {{"SPI_PS_INPUT_CNTL_0"}, 0xa191},
465 {{"SPI_PS_INPUT_CNTL_1"}, 0xa192},
466 {{"SPI_PS_INPUT_CNTL_2"}, 0xa193},
467 {{"SPI_PS_INPUT_CNTL_3"}, 0xa194},
468 {{"SPI_PS_INPUT_CNTL_4"}, 0xa195},
469 {{"SPI_PS_INPUT_CNTL_5"}, 0xa196},
470 {{"SPI_PS_INPUT_CNTL_6"}, 0xa197},
471 {{"SPI_PS_INPUT_CNTL_7"}, 0xa198},
472 {{"SPI_PS_INPUT_CNTL_8"}, 0xa199},
473 {{"SPI_PS_INPUT_CNTL_9"}, 0xa19a},
474 {{"SPI_PS_INPUT_CNTL_10"}, 0xa19b},
475 {{"SPI_PS_INPUT_CNTL_11"}, 0xa19c},
476 {{"SPI_PS_INPUT_CNTL_12"}, 0xa19d},
477 {{"SPI_PS_INPUT_CNTL_13"}, 0xa19e},
478 {{"SPI_PS_INPUT_CNTL_14"}, 0xa19f},
479 {{"SPI_PS_INPUT_CNTL_15"}, 0xa1a0},
480 {{"SPI_PS_INPUT_CNTL_16"}, 0xa1a1},
481 {{"SPI_PS_INPUT_CNTL_17"}, 0xa1a2},
482 {{"SPI_PS_INPUT_CNTL_18"}, 0xa1a3},
483 {{"SPI_PS_INPUT_CNTL_19"}, 0xa1a4},
484 {{"SPI_PS_INPUT_CNTL_20"}, 0xa1a5},
485 {{"SPI_PS_INPUT_CNTL_21"}, 0xa1a6},
486 {{"SPI_PS_INPUT_CNTL_22"}, 0xa1a7},
487 {{"SPI_PS_INPUT_CNTL_23"}, 0xa1a8},
488 {{"SPI_PS_INPUT_CNTL_24"}, 0xa1a9},
489 {{"SPI_PS_INPUT_CNTL_25"}, 0xa1aa},
490 {{"SPI_PS_INPUT_CNTL_26"}, 0xa1ab},
491 {{"SPI_PS_INPUT_CNTL_27"}, 0xa1ac},
492 {{"SPI_PS_INPUT_CNTL_28"}, 0xa1ad},
493 {{"SPI_PS_INPUT_CNTL_29"}, 0xa1ae},
494 {{"SPI_PS_INPUT_CNTL_30"}, 0xa1af},
495 {{"SPI_PS_INPUT_CNTL_31"}, 0xa1b0},
496
497 {{"VGT_GS_MAX_VERT_OUT"}, 0xa2ce},
498 {{"VGT_ESGS_RING_ITEMSIZE"}, 0xa2ab},
499 {{"VGT_GS_MODE"}, 0xa290},
500 {{"VGT_GS_ONCHIP_CNTL"}, 0xa291},
501 {{"VGT_GS_VERT_ITEMSIZE"}, 0xa2d7},
502 {{"VGT_GS_VERT_ITEMSIZE_1"}, 0xa2d8},
503 {{"VGT_GS_VERT_ITEMSIZE_2"}, 0xa2d9},
504 {{"VGT_GS_VERT_ITEMSIZE_3"}, 0xa2da},
505 {{"VGT_GSVS_RING_OFFSET_1"}, 0xa298},
506 {{"VGT_GSVS_RING_OFFSET_2"}, 0xa299},
507 {{"VGT_GSVS_RING_OFFSET_3"}, 0xa29a},
508
509 {{"VGT_GS_INSTANCE_CNT"}, 0xa2e4},
510 {{"VGT_GS_PER_VS"}, 0xa297},
511 {{"VGT_GS_OUT_PRIM_TYPE"}, 0xa29b},
512 {{"VGT_GSVS_RING_ITEMSIZE"}, 0xa2ac},
513
514 {{"VGT_REUSE_OFF"}, 0xa2ad},
515 {{"SPI_BARYC_CNTL"}, 0xa1b8},
516
517 {{"SPI_SHADER_USER_DATA_VS_0"}, 0x2c4c},
518 {{"SPI_SHADER_USER_DATA_VS_1"}, 0x2c4d},
519 {{"SPI_SHADER_USER_DATA_VS_2"}, 0x2c4e},
520 {{"SPI_SHADER_USER_DATA_VS_3"}, 0x2c4f},
521 {{"SPI_SHADER_USER_DATA_VS_4"}, 0x2c50},
522 {{"SPI_SHADER_USER_DATA_VS_5"}, 0x2c51},
523 {{"SPI_SHADER_USER_DATA_VS_6"}, 0x2c52},
524 {{"SPI_SHADER_USER_DATA_VS_7"}, 0x2c53},
525 {{"SPI_SHADER_USER_DATA_VS_8"}, 0x2c54},
526 {{"SPI_SHADER_USER_DATA_VS_9"}, 0x2c55},
527 {{"SPI_SHADER_USER_DATA_VS_10"}, 0x2c56},
528 {{"SPI_SHADER_USER_DATA_VS_11"}, 0x2c57},
529 {{"SPI_SHADER_USER_DATA_VS_12"}, 0x2c58},
530 {{"SPI_SHADER_USER_DATA_VS_13"}, 0x2c59},
531 {{"SPI_SHADER_USER_DATA_VS_14"}, 0x2c5a},
532 {{"SPI_SHADER_USER_DATA_VS_15"}, 0x2c5b},
533 {{"SPI_SHADER_USER_DATA_VS_16"}, 0x2c5c},
534 {{"SPI_SHADER_USER_DATA_VS_17"}, 0x2c5d},
535 {{"SPI_SHADER_USER_DATA_VS_18"}, 0x2c5e},
536 {{"SPI_SHADER_USER_DATA_VS_19"}, 0x2c5f},
537 {{"SPI_SHADER_USER_DATA_VS_20"}, 0x2c60},
538 {{"SPI_SHADER_USER_DATA_VS_21"}, 0x2c61},
539 {{"SPI_SHADER_USER_DATA_VS_22"}, 0x2c62},
540 {{"SPI_SHADER_USER_DATA_VS_23"}, 0x2c63},
541 {{"SPI_SHADER_USER_DATA_VS_24"}, 0x2c64},
542 {{"SPI_SHADER_USER_DATA_VS_25"}, 0x2c65},
543 {{"SPI_SHADER_USER_DATA_VS_26"}, 0x2c66},
544 {{"SPI_SHADER_USER_DATA_VS_27"}, 0x2c67},
545 {{"SPI_SHADER_USER_DATA_VS_28"}, 0x2c68},
546 {{"SPI_SHADER_USER_DATA_VS_29"}, 0x2c69},
547 {{"SPI_SHADER_USER_DATA_VS_30"}, 0x2c6a},
548 {{"SPI_SHADER_USER_DATA_VS_31"}, 0x2c6b},
549
550 {{"SPI_SHADER_USER_DATA_GS_0"}, 0x2c8c},
551 {{"SPI_SHADER_USER_DATA_GS_1"}, 0x2c8d},
552 {{"SPI_SHADER_USER_DATA_GS_2"}, 0x2c8e},
553 {{"SPI_SHADER_USER_DATA_GS_3"}, 0x2c8f},
554 {{"SPI_SHADER_USER_DATA_GS_4"}, 0x2c90},
555 {{"SPI_SHADER_USER_DATA_GS_5"}, 0x2c91},
556 {{"SPI_SHADER_USER_DATA_GS_6"}, 0x2c92},
557 {{"SPI_SHADER_USER_DATA_GS_7"}, 0x2c93},
558 {{"SPI_SHADER_USER_DATA_GS_8"}, 0x2c94},
559 {{"SPI_SHADER_USER_DATA_GS_9"}, 0x2c95},
560 {{"SPI_SHADER_USER_DATA_GS_10"}, 0x2c96},
561 {{"SPI_SHADER_USER_DATA_GS_11"}, 0x2c97},
562 {{"SPI_SHADER_USER_DATA_GS_12"}, 0x2c98},
563 {{"SPI_SHADER_USER_DATA_GS_13"}, 0x2c99},
564 {{"SPI_SHADER_USER_DATA_GS_14"}, 0x2c9a},
565 {{"SPI_SHADER_USER_DATA_GS_15"}, 0x2c9b},
566 {{"SPI_SHADER_USER_DATA_GS_16"}, 0x2c9c},
567 {{"SPI_SHADER_USER_DATA_GS_17"}, 0x2c9d},
568 {{"SPI_SHADER_USER_DATA_GS_18"}, 0x2c9e},
569 {{"SPI_SHADER_USER_DATA_GS_19"}, 0x2c9f},
570 {{"SPI_SHADER_USER_DATA_GS_20"}, 0x2ca0},
571 {{"SPI_SHADER_USER_DATA_GS_21"}, 0x2ca1},
572 {{"SPI_SHADER_USER_DATA_GS_22"}, 0x2ca2},
573 {{"SPI_SHADER_USER_DATA_GS_23"}, 0x2ca3},
574 {{"SPI_SHADER_USER_DATA_GS_24"}, 0x2ca4},
575 {{"SPI_SHADER_USER_DATA_GS_25"}, 0x2ca5},
576 {{"SPI_SHADER_USER_DATA_GS_26"}, 0x2ca6},
577 {{"SPI_SHADER_USER_DATA_GS_27"}, 0x2ca7},
578 {{"SPI_SHADER_USER_DATA_GS_28"}, 0x2ca8},
579 {{"SPI_SHADER_USER_DATA_GS_29"}, 0x2ca9},
580 {{"SPI_SHADER_USER_DATA_GS_30"}, 0x2caa},
581 {{"SPI_SHADER_USER_DATA_GS_31"}, 0x2cab},
582
583 {{"SPI_SHADER_USER_DATA_ES_0"}, 0x2ccc},
584 {{"SPI_SHADER_USER_DATA_ES_1"}, 0x2ccd},
585 {{"SPI_SHADER_USER_DATA_ES_2"}, 0x2cce},
586 {{"SPI_SHADER_USER_DATA_ES_3"}, 0x2ccf},
587 {{"SPI_SHADER_USER_DATA_ES_4"}, 0x2cd0},
588 {{"SPI_SHADER_USER_DATA_ES_5"}, 0x2cd1},
589 {{"SPI_SHADER_USER_DATA_ES_6"}, 0x2cd2},
590 {{"SPI_SHADER_USER_DATA_ES_7"}, 0x2cd3},
591 {{"SPI_SHADER_USER_DATA_ES_8"}, 0x2cd4},
592 {{"SPI_SHADER_USER_DATA_ES_9"}, 0x2cd5},
593 {{"SPI_SHADER_USER_DATA_ES_10"}, 0x2cd6},
594 {{"SPI_SHADER_USER_DATA_ES_11"}, 0x2cd7},
595 {{"SPI_SHADER_USER_DATA_ES_12"}, 0x2cd8},
596 {{"SPI_SHADER_USER_DATA_ES_13"}, 0x2cd9},
597 {{"SPI_SHADER_USER_DATA_ES_14"}, 0x2cda},
598 {{"SPI_SHADER_USER_DATA_ES_15"}, 0x2cdb},
599 {{"SPI_SHADER_USER_DATA_ES_16"}, 0x2cdc},
600 {{"SPI_SHADER_USER_DATA_ES_17"}, 0x2cdd},
601 {{"SPI_SHADER_USER_DATA_ES_18"}, 0x2cde},
602 {{"SPI_SHADER_USER_DATA_ES_19"}, 0x2cdf},
603 {{"SPI_SHADER_USER_DATA_ES_20"}, 0x2ce0},
604 {{"SPI_SHADER_USER_DATA_ES_21"}, 0x2ce1},
605 {{"SPI_SHADER_USER_DATA_ES_22"}, 0x2ce2},
606 {{"SPI_SHADER_USER_DATA_ES_23"}, 0x2ce3},
607 {{"SPI_SHADER_USER_DATA_ES_24"}, 0x2ce4},
608 {{"SPI_SHADER_USER_DATA_ES_25"}, 0x2ce5},
609 {{"SPI_SHADER_USER_DATA_ES_26"}, 0x2ce6},
610 {{"SPI_SHADER_USER_DATA_ES_27"}, 0x2ce7},
611 {{"SPI_SHADER_USER_DATA_ES_28"}, 0x2ce8},
612 {{"SPI_SHADER_USER_DATA_ES_29"}, 0x2ce9},
613 {{"SPI_SHADER_USER_DATA_ES_30"}, 0x2cea},
614 {{"SPI_SHADER_USER_DATA_ES_31"}, 0x2ceb},
615
616 {{"SPI_SHADER_USER_DATA_PS_0"}, 0x2c0c},
617 {{"SPI_SHADER_USER_DATA_PS_1"}, 0x2c0d},
618 {{"SPI_SHADER_USER_DATA_PS_2"}, 0x2c0e},
619 {{"SPI_SHADER_USER_DATA_PS_3"}, 0x2c0f},
620 {{"SPI_SHADER_USER_DATA_PS_4"}, 0x2c10},
621 {{"SPI_SHADER_USER_DATA_PS_5"}, 0x2c11},
622 {{"SPI_SHADER_USER_DATA_PS_6"}, 0x2c12},
623 {{"SPI_SHADER_USER_DATA_PS_7"}, 0x2c13},
624 {{"SPI_SHADER_USER_DATA_PS_8"}, 0x2c14},
625 {{"SPI_SHADER_USER_DATA_PS_9"}, 0x2c15},
626 {{"SPI_SHADER_USER_DATA_PS_10"}, 0x2c16},
627 {{"SPI_SHADER_USER_DATA_PS_11"}, 0x2c17},
628 {{"SPI_SHADER_USER_DATA_PS_12"}, 0x2c18},
629 {{"SPI_SHADER_USER_DATA_PS_13"}, 0x2c19},
630 {{"SPI_SHADER_USER_DATA_PS_14"}, 0x2c1a},
631 {{"SPI_SHADER_USER_DATA_PS_15"}, 0x2c1b},
632 {{"SPI_SHADER_USER_DATA_PS_16"}, 0x2c1c},
633 {{"SPI_SHADER_USER_DATA_PS_17"}, 0x2c1d},
634 {{"SPI_SHADER_USER_DATA_PS_18"}, 0x2c1e},
635 {{"SPI_SHADER_USER_DATA_PS_19"}, 0x2c1f},
636 {{"SPI_SHADER_USER_DATA_PS_20"}, 0x2c20},
637 {{"SPI_SHADER_USER_DATA_PS_21"}, 0x2c21},
638 {{"SPI_SHADER_USER_DATA_PS_22"}, 0x2c22},
639 {{"SPI_SHADER_USER_DATA_PS_23"}, 0x2c23},
640 {{"SPI_SHADER_USER_DATA_PS_24"}, 0x2c24},
641 {{"SPI_SHADER_USER_DATA_PS_25"}, 0x2c25},
642 {{"SPI_SHADER_USER_DATA_PS_26"}, 0x2c26},
643 {{"SPI_SHADER_USER_DATA_PS_27"}, 0x2c27},
644 {{"SPI_SHADER_USER_DATA_PS_28"}, 0x2c28},
645 {{"SPI_SHADER_USER_DATA_PS_29"}, 0x2c29},
646 {{"SPI_SHADER_USER_DATA_PS_30"}, 0x2c2a},
647 {{"SPI_SHADER_USER_DATA_PS_31"}, 0x2c2b},
648
649 {{"COMPUTE_USER_DATA_0"}, 0x2e40},
650 {{"COMPUTE_USER_DATA_1"}, 0x2e41},
651 {{"COMPUTE_USER_DATA_2"}, 0x2e42},
652 {{"COMPUTE_USER_DATA_3"}, 0x2e43},
653 {{"COMPUTE_USER_DATA_4"}, 0x2e44},
654 {{"COMPUTE_USER_DATA_5"}, 0x2e45},
655 {{"COMPUTE_USER_DATA_6"}, 0x2e46},
656 {{"COMPUTE_USER_DATA_7"}, 0x2e47},
657 {{"COMPUTE_USER_DATA_8"}, 0x2e48},
658 {{"COMPUTE_USER_DATA_9"}, 0x2e49},
659 {{"COMPUTE_USER_DATA_10"}, 0x2e4a},
660 {{"COMPUTE_USER_DATA_11"}, 0x2e4b},
661 {{"COMPUTE_USER_DATA_12"}, 0x2e4c},
662 {{"COMPUTE_USER_DATA_13"}, 0x2e4d},
663 {{"COMPUTE_USER_DATA_14"}, 0x2e4e},
664 {{"COMPUTE_USER_DATA_15"}, 0x2e4f},
665 {{"COMPUTE_USER_DATA_16"}, 0x2e50},
666 {{"COMPUTE_USER_DATA_17"}, 0x2e51},
667 {{"COMPUTE_USER_DATA_18"}, 0x2e52},
668 {{"COMPUTE_USER_DATA_19"}, 0x2e53},
669 {{"COMPUTE_USER_DATA_20"}, 0x2e54},
670 {{"COMPUTE_USER_DATA_21"}, 0x2e55},
671 {{"COMPUTE_USER_DATA_22"}, 0x2e56},
672 {{"COMPUTE_USER_DATA_23"}, 0x2e57},
673 {{"COMPUTE_USER_DATA_24"}, 0x2e58},
674 {{"COMPUTE_USER_DATA_25"}, 0x2e59},
675 {{"COMPUTE_USER_DATA_26"}, 0x2e5a},
676 {{"COMPUTE_USER_DATA_27"}, 0x2e5b},
677 {{"COMPUTE_USER_DATA_28"}, 0x2e5c},
678 {{"COMPUTE_USER_DATA_29"}, 0x2e5d},
679 {{"COMPUTE_USER_DATA_30"}, 0x2e5e},
680 {{"COMPUTE_USER_DATA_31"}, 0x2e5f},
681
682 {{"COMPUTE_NUM_THREAD_X"}, 0x2e07},
683 {{"COMPUTE_NUM_THREAD_Y"}, 0x2e08},
684 {{"COMPUTE_NUM_THREAD_Z"}, 0x2e09},
685 {{"VGT_TF_PARAM"}, 0xa2db},
686 {{"VGT_LS_HS_CONFIG"}, 0xa2d6},
687 {{"VGT_HOS_MIN_TESS_LEVEL"}, 0xa287},
688 {{"VGT_HOS_MAX_TESS_LEVEL"}, 0xa286},
689 {{"PA_SC_AA_CONFIG"}, 0xa2f8},
690 {{"PA_SC_SHADER_CONTROL"}, 0xa310},
691 {{"PA_SC_CONSERVATIVE_RASTERIZATION_CNTL"}, 0xa313},
692
693 {{"SPI_SHADER_USER_DATA_HS_0"}, 0x2d0c},
694 {{"SPI_SHADER_USER_DATA_HS_1"}, 0x2d0d},
695 {{"SPI_SHADER_USER_DATA_HS_2"}, 0x2d0e},
696 {{"SPI_SHADER_USER_DATA_HS_3"}, 0x2d0f},
697 {{"SPI_SHADER_USER_DATA_HS_4"}, 0x2d10},
698 {{"SPI_SHADER_USER_DATA_HS_5"}, 0x2d11},
699 {{"SPI_SHADER_USER_DATA_HS_6"}, 0x2d12},
700 {{"SPI_SHADER_USER_DATA_HS_7"}, 0x2d13},
701 {{"SPI_SHADER_USER_DATA_HS_8"}, 0x2d14},
702 {{"SPI_SHADER_USER_DATA_HS_9"}, 0x2d15},
703 {{"SPI_SHADER_USER_DATA_HS_10"}, 0x2d16},
704 {{"SPI_SHADER_USER_DATA_HS_11"}, 0x2d17},
705 {{"SPI_SHADER_USER_DATA_HS_12"}, 0x2d18},
706 {{"SPI_SHADER_USER_DATA_HS_13"}, 0x2d19},
707 {{"SPI_SHADER_USER_DATA_HS_14"}, 0x2d1a},
708 {{"SPI_SHADER_USER_DATA_HS_15"}, 0x2d1b},
709 {{"SPI_SHADER_USER_DATA_HS_16"}, 0x2d1c},
710 {{"SPI_SHADER_USER_DATA_HS_17"}, 0x2d1d},
711 {{"SPI_SHADER_USER_DATA_HS_18"}, 0x2d1e},
712 {{"SPI_SHADER_USER_DATA_HS_19"}, 0x2d1f},
713 {{"SPI_SHADER_USER_DATA_HS_20"}, 0x2d20},
714 {{"SPI_SHADER_USER_DATA_HS_21"}, 0x2d21},
715 {{"SPI_SHADER_USER_DATA_HS_22"}, 0x2d22},
716 {{"SPI_SHADER_USER_DATA_HS_23"}, 0x2d23},
717 {{"SPI_SHADER_USER_DATA_HS_24"}, 0x2d24},
718 {{"SPI_SHADER_USER_DATA_HS_25"}, 0x2d25},
719 {{"SPI_SHADER_USER_DATA_HS_26"}, 0x2d26},
720 {{"SPI_SHADER_USER_DATA_HS_27"}, 0x2d27},
721 {{"SPI_SHADER_USER_DATA_HS_28"}, 0x2d28},
722 {{"SPI_SHADER_USER_DATA_HS_29"}, 0x2d29},
723 {{"SPI_SHADER_USER_DATA_HS_30"}, 0x2d2a},
724 {{"SPI_SHADER_USER_DATA_HS_31"}, 0x2d2b},
725
726 {{"SPI_SHADER_USER_DATA_LS_0"}, 0x2d4c},
727 {{"SPI_SHADER_USER_DATA_LS_1"}, 0x2d4d},
728 {{"SPI_SHADER_USER_DATA_LS_2"}, 0x2d4e},
729 {{"SPI_SHADER_USER_DATA_LS_3"}, 0x2d4f},
730 {{"SPI_SHADER_USER_DATA_LS_4"}, 0x2d50},
731 {{"SPI_SHADER_USER_DATA_LS_5"}, 0x2d51},
732 {{"SPI_SHADER_USER_DATA_LS_6"}, 0x2d52},
733 {{"SPI_SHADER_USER_DATA_LS_7"}, 0x2d53},
734 {{"SPI_SHADER_USER_DATA_LS_8"}, 0x2d54},
735 {{"SPI_SHADER_USER_DATA_LS_9"}, 0x2d55},
736 {{"SPI_SHADER_USER_DATA_LS_10"}, 0x2d56},
737 {{"SPI_SHADER_USER_DATA_LS_11"}, 0x2d57},
738 {{"SPI_SHADER_USER_DATA_LS_12"}, 0x2d58},
739 {{"SPI_SHADER_USER_DATA_LS_13"}, 0x2d59},
740 {{"SPI_SHADER_USER_DATA_LS_14"}, 0x2d5a},
741 {{"SPI_SHADER_USER_DATA_LS_15"}, 0x2d5b},
742
743 {{"IA_MULTI_VGT_PARAM"}, 0xa2aa},
744 {{"VGT_GS_MAX_PRIMS_PER_SUBGROUP"}, 0xa2a5},
745 {{"VGT_STRMOUT_BUFFER_CONFIG"}, 0xa2e6},
746 {{"VGT_STRMOUT_CONFIG"}, 0xa2e5},
747 {{"VGT_STRMOUT_VTX_STRIDE_0"}, 0xa2b5},
748 {{"VGT_STRMOUT_VTX_STRIDE_1"}, 0xa2b9},
749 {{"VGT_STRMOUT_VTX_STRIDE_2"}, 0xa2bd},
750 {{"VGT_STRMOUT_VTX_STRIDE_3"}, 0xa2c1},
751 {{"VGT_VERTEX_REUSE_BLOCK_CNTL"}, 0xa316},
752
753 {{"COMPUTE_PGM_RSRC3"}, 0x2e28},
754 {{"COMPUTE_SHADER_CHKSUM"}, 0x2e2a},
755 {{"COMPUTE_USER_ACCUM_0"}, 0x2e24},
756 {{"COMPUTE_USER_ACCUM_1"}, 0x2e25},
757 {{"COMPUTE_USER_ACCUM_2"}, 0x2e26},
758 {{"COMPUTE_USER_ACCUM_3"}, 0x2e27},
759 {{"GE_MAX_OUTPUT_PER_SUBGROUP"}, 0xa1ff},
760 {{"GE_NGG_SUBGRP_CNTL"}, 0xa2d3},
761 {{"GE_STEREO_CNTL"}, 0xc25f},
762 {{"GE_USER_VGPR_EN"}, 0xc262},
763 {{"IA_MULTI_VGT_PARAM_PIPED"}, 0xc258},
764 {{"PA_STEREO_CNTL"}, 0xa210},
765 {{"SPI_SHADER_IDX_FORMAT"}, 0xa1c2},
766 {{"SPI_SHADER_PGM_CHKSUM_GS"}, 0x2c80},
767 {{"SPI_SHADER_PGM_CHKSUM_HS"}, 0x2d00},
768 {{"SPI_SHADER_PGM_CHKSUM_PS"}, 0x2c06},
769 {{"SPI_SHADER_PGM_CHKSUM_VS"}, 0x2c45},
770 {{"SPI_SHADER_PGM_LO_GS"}, 0x2c88},
771 {{"SPI_SHADER_USER_ACCUM_ESGS_0"}, 0x2cb2},
772 {{"SPI_SHADER_USER_ACCUM_ESGS_1"}, 0x2cb3},
773 {{"SPI_SHADER_USER_ACCUM_ESGS_2"}, 0x2cb4},
774 {{"SPI_SHADER_USER_ACCUM_ESGS_3"}, 0x2cb5},
775 {{"SPI_SHADER_USER_ACCUM_LSHS_0"}, 0x2d32},
776 {{"SPI_SHADER_USER_ACCUM_LSHS_1"}, 0x2d33},
777 {{"SPI_SHADER_USER_ACCUM_LSHS_2"}, 0x2d34},
778 {{"SPI_SHADER_USER_ACCUM_LSHS_3"}, 0x2d35},
779 {{"SPI_SHADER_USER_ACCUM_PS_0"}, 0x2c32},
780 {{"SPI_SHADER_USER_ACCUM_PS_1"}, 0x2c33},
781 {{"SPI_SHADER_USER_ACCUM_PS_2"}, 0x2c34},
782 {{"SPI_SHADER_USER_ACCUM_PS_3"}, 0x2c35},
783 {{"SPI_SHADER_USER_ACCUM_VS_0"}, 0x2c72},
784 {{"SPI_SHADER_USER_ACCUM_VS_1"}, 0x2c73},
785 {{"SPI_SHADER_USER_ACCUM_VS_2"}, 0x2c74},
786 {{"SPI_SHADER_USER_ACCUM_VS_3"}, 0x2c75},
787 };
788 static constexpr auto RegInfoTable = BUILD_ENUM_STRINGS(RegInfoTableDefs);
789 return EnumStrings(RegInfoTable).toString(RegNum);
790}
791
792// Convert the accumulated PAL metadata into an asm directive.
794 String.clear();
795 if (!BlobType)
796 return;
797 ResolvedAll = DelayedExprs.resolveDelayedExpressions();
799 if (isLegacy()) {
800 if (MsgPackDoc.getRoot().getKind() == msgpack::Type::Nil)
801 return;
802 // Old linear reg=val format.
803 Stream << '\t' << AMDGPU::PALMD::AssemblerDirective << ' ';
804 auto Regs = getRegisters();
805 for (auto I = Regs.begin(), E = Regs.end(); I != E; ++I) {
806 if (I != Regs.begin())
807 Stream << ',';
808 unsigned Reg = I->first.getUInt();
809 unsigned Val = I->second.getUInt();
810 Stream << "0x" << Twine::utohexstr(Reg) << ",0x" << Twine::utohexstr(Val);
811 }
812 Stream << '\n';
813 return;
814 }
815
816 // New msgpack-based format -- output as YAML (with unsigned numbers in hex),
817 // but first change the registers map to use names.
818 MsgPackDoc.setHexMode();
819 auto &RegsObj = refRegisters();
820 auto OrigRegs = RegsObj.getMap();
821 RegsObj = MsgPackDoc.getMapNode();
822 for (auto I : OrigRegs) {
823 auto Key = I.first;
824 if (StringRef RegName = getRegisterName(Key.getUInt()); !RegName.empty()) {
825 std::string KeyName = Key.toString();
826 KeyName += " (";
827 KeyName += RegName;
828 KeyName += ')';
829 Key = MsgPackDoc.getNode(KeyName, /*Copy=*/true);
830 }
831 RegsObj.getMap()[Key] = I.second;
832 }
833
834 // Output as YAML.
835 Stream << '\t' << AMDGPU::PALMD::AssemblerDirectiveBegin << '\n';
836 MsgPackDoc.toYAML(Stream);
837 Stream << '\t' << AMDGPU::PALMD::AssemblerDirectiveEnd << '\n';
838
839 // Restore original registers map.
840 RegsObj = OrigRegs;
841}
842
843// Convert the accumulated PAL metadata into a binary blob for writing as
844// a .note record of the specified AMD type. Returns an empty blob if
845// there is no PAL metadata,
846void AMDGPUPALMetadata::toBlob(unsigned Type, std::string &Blob) {
847 ResolvedAll = DelayedExprs.resolveDelayedExpressions();
849 toLegacyBlob(Blob);
850 else if (Type)
851 toMsgPackBlob(Blob);
852}
853
854void AMDGPUPALMetadata::toLegacyBlob(std::string &Blob) {
855 Blob.clear();
856 auto Registers = getRegisters();
857 if (Registers.getMap().empty())
858 return;
859 raw_string_ostream OS(Blob);
861 for (auto I : Registers.getMap()) {
862 EW.write(uint32_t(I.first.getUInt()));
863 EW.write(uint32_t(I.second.getUInt()));
864 }
865}
866
867void AMDGPUPALMetadata::toMsgPackBlob(std::string &Blob) {
868 Blob.clear();
869 MsgPackDoc.writeToBlob(Blob);
870}
871
872// Set PAL metadata from YAML text. Returns false if failed.
874 BlobType = ELF::NT_AMDGPU_METADATA;
875 if (!MsgPackDoc.fromYAML(S))
876 return false;
877
878 // In the registers map, some keys may be of the form "0xa191
879 // (SPI_PS_INPUT_CNTL_0)", in which case the YAML input code made it a
880 // string. We need to turn it into a number.
881 auto &RegsObj = refRegisters();
882 auto OrigRegs = RegsObj;
883 RegsObj = MsgPackDoc.getMapNode();
884 Registers = RegsObj.getMap();
885 bool Ok = true;
886 for (auto I : OrigRegs.getMap()) {
887 auto Key = I.first;
888 if (Key.getKind() == msgpack::Type::String) {
889 StringRef S = Key.getString();
890 uint64_t Val;
891 if (S.consumeInteger(0, Val)) {
892 Ok = false;
893 errs() << "Unrecognized PAL metadata register key '" << S << "'\n";
894 continue;
895 }
896 Key = MsgPackDoc.getNode(Val);
897 }
898 Registers.getMap()[Key] = I.second;
899 }
900 return Ok;
901}
902
903// Reference (create if necessary) the node for the registers map.
904msgpack::DocNode &AMDGPUPALMetadata::refRegisters() {
905 auto &N =
906 MsgPackDoc.getRoot()
907 .getMap(/*Convert=*/true)[MsgPackDoc.getNode("amdpal.pipelines")]
908 .getArray(/*Convert=*/true)[0]
909 .getMap(/*Convert=*/true)[MsgPackDoc.getNode(".registers")];
910 N.getMap(/*Convert=*/true);
911 return N;
912}
913
914// Get (create if necessary) the registers map.
915msgpack::MapDocNode AMDGPUPALMetadata::getRegisters() {
916 if (Registers.isEmpty())
917 Registers = refRegisters();
918 return Registers.getMap();
919}
920
921// Reference (create if necessary) the node for the shader functions map.
922msgpack::DocNode &AMDGPUPALMetadata::refShaderFunctions() {
923 auto &N =
924 MsgPackDoc.getRoot()
925 .getMap(/*Convert=*/true)[MsgPackDoc.getNode("amdpal.pipelines")]
926 .getArray(/*Convert=*/true)[0]
927 .getMap(/*Convert=*/true)[MsgPackDoc.getNode(".shader_functions")];
928 N.getMap(/*Convert=*/true);
929 return N;
930}
931
932// Get (create if necessary) the shader functions map.
933msgpack::MapDocNode AMDGPUPALMetadata::getShaderFunctions() {
934 if (ShaderFunctions.isEmpty())
935 ShaderFunctions = refShaderFunctions();
936 return ShaderFunctions.getMap();
937}
938
939// Get (create if necessary) a function in the shader functions map.
940msgpack::MapDocNode AMDGPUPALMetadata::getShaderFunction(StringRef Name) {
941 auto Functions = getShaderFunctions();
942 return Functions[Name].getMap(/*Convert=*/true);
943}
944
945msgpack::DocNode &AMDGPUPALMetadata::refComputeRegisters() {
946 auto &N =
947 MsgPackDoc.getRoot()
948 .getMap(/*Convert=*/true)[MsgPackDoc.getNode("amdpal.pipelines")]
949 .getArray(/*Convert=*/true)[0]
950 .getMap(/*Convert=*/true)[MsgPackDoc.getNode(".compute_registers")];
951 N.getMap(/*Convert=*/true);
952 return N;
953}
954
955msgpack::MapDocNode AMDGPUPALMetadata::getComputeRegisters() {
956 if (ComputeRegisters.isEmpty())
957 ComputeRegisters = refComputeRegisters();
958 return ComputeRegisters.getMap();
959}
960
961msgpack::DocNode &AMDGPUPALMetadata::refGraphicsRegisters() {
962 auto &N =
963 MsgPackDoc.getRoot()
964 .getMap(/*Convert=*/true)[MsgPackDoc.getNode("amdpal.pipelines")]
965 .getArray(/*Convert=*/true)[0]
966 .getMap(/*Convert=*/true)[MsgPackDoc.getNode(".graphics_registers")];
967 N.getMap(/*Convert=*/true);
968 return N;
969}
970
971msgpack::MapDocNode AMDGPUPALMetadata::getGraphicsRegisters() {
972 if (GraphicsRegisters.isEmpty())
973 GraphicsRegisters = refGraphicsRegisters();
974 return GraphicsRegisters.getMap();
975}
976
977msgpack::DocNode &AMDGPUPALMetadata::refHwStage() {
978 auto &N =
979 MsgPackDoc.getRoot()
980 .getMap(/*Convert=*/true)[MsgPackDoc.getNode("amdpal.pipelines")]
981 .getArray(/*Convert=*/true)[0]
982 .getMap(/*Convert=*/true)[MsgPackDoc.getNode(".hardware_stages")];
983 N.getMap(/*Convert=*/true);
984 return N;
985}
986
987// Get (create if necessary) the .hardware_stages entry for the given calling
988// convention.
989msgpack::MapDocNode AMDGPUPALMetadata::getHwStage(unsigned CC) {
990 if (HwStages.isEmpty())
991 HwStages = refHwStage();
992 return HwStages.getMap()[getStageName(CC)].getMap(/*Convert=*/true);
993}
994
995// Get .note record vendor name of metadata blob to be emitted.
996const char *AMDGPUPALMetadata::getVendor() const {
997 return isLegacy() ? ElfNote::NoteNameV2 : ElfNote::NoteNameV3;
998}
999
1000// Get .note record type of metadata blob to be emitted:
1001// ELF::NT_AMD_PAL_METADATA (legacy key=val format), or
1002// ELF::NT_AMDGPU_METADATA (MsgPack format), or
1003// 0 (no PAL metadata).
1005 return BlobType;
1006}
1007
1008// Return whether the blob type is legacy PAL metadata.
1009bool AMDGPUPALMetadata::isLegacy() const {
1010 return BlobType == ELF::NT_AMD_PAL_METADATA;
1011}
1012
1013// Set legacy PAL metadata format.
1017
1018// Erase all PAL metadata.
1020 MsgPackDoc.clear();
1021 REM.clear();
1022 DelayedExprs.clear();
1023 Registers = MsgPackDoc.getEmptyNode();
1024 HwStages = MsgPackDoc.getEmptyNode();
1025 ShaderFunctions = MsgPackDoc.getEmptyNode();
1026}
1027
1029 return ResolvedAll && DelayedExprs.empty();
1030}
1031
1032unsigned AMDGPUPALMetadata::getPALVersion(unsigned idx) {
1033 assert(idx < 2 &&
1034 "illegal index to PAL version - should be 0 (major) or 1 (minor)");
1035 if (!VersionChecked) {
1036 if (Version.isEmpty()) {
1037 auto &M = MsgPackDoc.getRoot().getMap(/*Convert=*/true);
1038 auto I = M.find(MsgPackDoc.getNode("amdpal.version"));
1039 if (I != M.end())
1040 Version = I->second;
1041 }
1042 VersionChecked = true;
1043 }
1044 if (Version.isEmpty())
1045 // Default to 2.6 if there's no version info
1046 return idx ? 6 : 2;
1047 return Version.getArray()[idx].getUInt();
1048}
1049
1051
1055
1056// Set the field in a given .hardware_stages entry to a maximum value
1058 unsigned Val) {
1059 msgpack::MapDocNode HwStageFieldMapNode = getHwStage(CC);
1060 auto &Node = HwStageFieldMapNode[field];
1061 if (Node.isEmpty())
1062 Node = Val;
1063 else
1064 Node = std::max<unsigned>(Node.getUInt(), Val);
1065}
1066
1067// Set the field in a given .hardware_stages entry
1068void AMDGPUPALMetadata::setHwStage(unsigned CC, StringRef field, unsigned Val) {
1069 getHwStage(CC)[field] = Val;
1070}
1071
1072void AMDGPUPALMetadata::setHwStage(unsigned CC, StringRef field, bool Val) {
1073 getHwStage(CC)[field] = Val;
1074}
1075
1077 msgpack::Type Type, const MCExpr *Val) {
1078 DelayedExprs.assignDocNode(getHwStage(CC)[field], Type, Val);
1079}
1080
1082 getComputeRegisters()[field] = Val;
1083}
1084
1086 getComputeRegisters()[field] = Val;
1087}
1088
1090 auto M = getComputeRegisters();
1091 auto I = M.find(field);
1092 return I == M.end() ? nullptr : &I->second;
1093}
1094
1096 if (auto *N = refComputeRegister(field))
1097 return N->getUInt() == Val;
1098 return false;
1099}
1100
1102 if (auto *N = refComputeRegister(field))
1103 return N->getBool() == Val;
1104 return false;
1105}
1106
1108 getGraphicsRegisters()[field] = Val;
1109}
1110
1112 getGraphicsRegisters()[field] = Val;
1113}
1114
1116 unsigned Val) {
1117 getGraphicsRegisters()[field1].getMap(true)[field2] = Val;
1118}
1119
1121 bool Val) {
1122 getGraphicsRegisters()[field1].getMap(true)[field2] = Val;
1123}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU metadata definitions and in-memory representations.
static unsigned getScratchSizeKey(CallingConv::ID CC)
static unsigned getRsrc1Reg(CallingConv::ID CC)
static const char * getStageName(CallingConv::ID CC)
PAL metadata handling.
Enums and constants for AMDGPU PT_NOTE sections.
AMDGPU Reserve WWM Registers
This file contains the declarations for the subclasses of Constant, which represent the different fla...
#define BUILD_ENUM_STRINGS(Tab)
Definition Enum.h:120
Module.h This file contains the declarations for the Module class.
#define RegName(no)
#define I(x, y, z)
Definition MD5.cpp:57
static std::string getRegisterName(const TargetRegisterInfo *TRI, Register Reg)
#define S_0286D8_PS_W32_EN(x)
Definition SIDefines.h:1530
#define S_00B800_CS_W32_EN(x)
Definition SIDefines.h:1532
#define S_028B54_GS_W32_EN(x)
Definition SIDefines.h:1527
#define S_028B54_VS_W32_EN(x)
Definition SIDefines.h:1528
#define S_028B54_HS_W32_EN(x)
Definition SIDefines.h:1526
Defines the llvm::VersionTuple class, which represents a version in the form major[....
void setSpiPsInputAddr(unsigned Val)
void setEntryPoint(unsigned CC, StringRef Name)
const char * getVendor() const
void setFunctionScratchSize(StringRef FnName, unsigned Val)
bool setFromString(StringRef S)
void setNumUsedVgprs(unsigned CC, unsigned Val)
unsigned getRegister(unsigned Reg)
msgpack::DocNode * refComputeRegister(StringRef field)
void setFunctionNumUsedVgprs(StringRef FnName, unsigned Val)
void setFunctionNumUsedSgprs(StringRef FnName, unsigned Val)
void setScratchSize(unsigned CC, unsigned Val)
void setRegister(unsigned Reg, unsigned Val)
void setHwStage(unsigned CC, StringRef field, unsigned Val)
void setRsrc1(unsigned CC, unsigned Val)
void setSpiPsInputEna(unsigned Val)
void setNumUsedAgprs(unsigned CC, unsigned Val)
void setGraphicsRegisters(StringRef field, unsigned Val)
bool checkComputeRegisters(StringRef field, unsigned Val)
void toBlob(unsigned Type, std::string &S)
void toString(std::string &S)
void setFunctionLdsSize(StringRef FnName, unsigned Val)
void updateHwStageMaximum(unsigned CC, StringRef field, unsigned Val)
void setRsrc2(unsigned CC, unsigned Val)
void setNumUsedSgprs(unsigned CC, unsigned Val)
void setComputeRegisters(StringRef field, unsigned Val)
static const MCBinaryExpr * createOr(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition MCExpr.h:407
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition MCExpr.cpp:212
Context object for machine code objects.
Definition MCContext.h:83
Base class for the full range of assembler expressions which are needed for parsing.
Definition MCExpr.h:34
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition SmallString.h:26
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
bool consumeInteger(unsigned Radix, T &Result)
Parse the current string as an integer of the specified radix.
Definition StringRef.h:519
static Twine utohexstr(uint64_t Val)
Definition Twine.h:385
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
Represents a version number in the form major[.minor[.subminor[.build]]].
A node in a MsgPack Document.
MapDocNode & getMap(bool Convert=false)
Get a MapDocNode for a map node.
ArrayDocNode & getArray(bool Convert=false)
Get an ArrayDocNode for an array node.
DocNode & getRoot()
Get ref to the document's root element.
DocNode getNode()
Create a nil node associated with this Document.
LLVM_ABI bool readFromBlob(StringRef Blob, bool Multi, function_ref< int(DocNode *DestNode, DocNode SrcNode, DocNode MapKey)> Merger=[](DocNode *DestNode, DocNode SrcNode, DocNode MapKey) { return -1;})
Read a document from a binary msgpack blob, merging into anything already in the Document.
A DocNode that is a map.
A raw_ostream that writes to an std::string.
A raw_ostream that writes to an SmallVector or SmallString.
StringRef str() const
Return a StringRef for the vector contents.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const char NoteNameV2[]
const char NoteNameV3[]
constexpr char AssemblerDirective[]
PAL metadata (old linear format) assembler directive.
constexpr char AssemblerDirectiveBegin[]
PAL metadata (new MsgPack format) beginning assembler directive.
constexpr char AssemblerDirectiveEnd[]
PAL metadata (new MsgPack format) ending assembler directive.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ AMDGPU_CS
Used for Mesa/AMDPAL compute shaders.
@ AMDGPU_VS
Used for Mesa vertex shaders, or AMDPAL last shader stage before rasterization (vertex shader if tess...
@ AMDGPU_Gfx
Used for AMD graphics targets.
@ AMDGPU_HS
Used for Mesa/AMDPAL hull shaders (= tessellation control shaders).
@ AMDGPU_GS
Used for Mesa/AMDPAL geometry shaders.
@ AMDGPU_PS
Used for Mesa/AMDPAL pixel shaders.
@ AMDGPU_ES
Used for AMDPAL shader stage before geometry shader if geometry is in use.
@ AMDGPU_LS
Used for AMDPAL vertex shader if tessellation is in use.
@ NT_AMDGPU_METADATA
Definition ELF.h:2005
@ NT_AMD_PAL_METADATA
Definition ELF.h:1999
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > dyn_extract(Y &&MD)
Extract a Value from Metadata, if any.
Definition Metadata.h:707
Type
MessagePack types as defined in the standard, with the exception of Integer being divided into a sign...
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
EnumStrings(const EnumStringsStorage< T, NumStrs, N, StrLen > &) -> EnumStrings< T, NumStrs >
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
#define N
Compile-time data representation of enum entries.
Definition Enum.h:47
Adapter to write values to a stream in a particular byte order.