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