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