LLVM 19.0.0git
AMDKernelCodeTUtils.cpp
Go to the documentation of this file.
1//===- AMDKernelCodeTUtils.cpp --------------------------------------------===//
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 - utility functions to parse/print AMDGPUMCKernelCodeT structure
10//
11//===----------------------------------------------------------------------===//
12
13#include "AMDKernelCodeTUtils.h"
14#include "AMDKernelCodeT.h"
15#include "SIDefines.h"
17#include "llvm/ADT/IndexedMap.h"
18#include "llvm/ADT/StringRef.h"
19#include "llvm/MC/MCContext.h"
20#include "llvm/MC/MCExpr.h"
23#include "llvm/MC/MCStreamer.h"
26
27using namespace llvm;
28using namespace llvm::AMDGPU;
29
30// Generates the following for AMDGPUMCKernelCodeT struct members:
31// - HasMemberXXXXX class
32// A check to see if AMDGPUMCKernelCodeT has a specific member so it can
33// determine which of the original amd_kernel_code_t members are duplicated
34// (if the names don't match, the table driven strategy won't work).
35// - IsMCExprXXXXX class
36// Check whether a AMDGPUMCKernelcodeT struct member is MCExpr-ified or not.
37// - GetMemberXXXXX class
38// A retrieval helper for said member (of type const MCExpr *&). Will return
39// a `Phony` const MCExpr * initialized to nullptr to preserve reference
40// returns.
41#define GEN_HAS_MEMBER(member) \
42 class HasMember##member { \
43 private: \
44 struct KnownWithMember { \
45 int member; \
46 }; \
47 class AmbiguousDerived : public AMDGPUMCKernelCodeT, \
48 public KnownWithMember {}; \
49 template <typename U> \
50 static constexpr std::false_type Test(decltype(U::member) *); \
51 template <typename U> static constexpr std::true_type Test(...); \
52 \
53 public: \
54 static constexpr bool RESULT = \
55 std::is_same_v<decltype(Test<AmbiguousDerived>(nullptr)), \
56 std::true_type>; \
57 }; \
58 class IsMCExpr##member { \
59 template <typename U, \
60 typename std::enable_if_t< \
61 HasMember##member::RESULT && \
62 std::is_same_v<decltype(U::member), const MCExpr *>, \
63 U> * = nullptr> \
64 static constexpr std::true_type HasMCExprType(decltype(U::member) *); \
65 template <typename U> static constexpr std::false_type HasMCExprType(...); \
66 \
67 public: \
68 static constexpr bool RESULT = \
69 std::is_same_v<decltype(HasMCExprType<AMDGPUMCKernelCodeT>(nullptr)), \
70 std::true_type>; \
71 }; \
72 class GetMember##member { \
73 public: \
74 static const MCExpr *Phony; \
75 template <typename U, typename std::enable_if_t<IsMCExpr##member::RESULT, \
76 U> * = nullptr> \
77 static const MCExpr *&Get(U &C) { \
78 assert(IsMCExpr##member::RESULT && \
79 "Trying to retrieve member that does not exist."); \
80 return C.member; \
81 } \
82 template <typename U, typename std::enable_if_t<!IsMCExpr##member::RESULT, \
83 U> * = nullptr> \
84 static const MCExpr *&Get(U &C) { \
85 return Phony; \
86 } \
87 }; \
88 const MCExpr *GetMember##member::Phony = nullptr;
89
90// Cannot generate class declarations using the table driver approach (see table
91// in AMDKernelCodeTInfo.h). Luckily, if any are missing here or eventually
92// added to the table, an error should occur when trying to retrieve the table
93// in getMCExprIndexTable.
94GEN_HAS_MEMBER(amd_code_version_major)
95GEN_HAS_MEMBER(amd_code_version_minor)
96GEN_HAS_MEMBER(amd_machine_kind)
97GEN_HAS_MEMBER(amd_machine_version_major)
98GEN_HAS_MEMBER(amd_machine_version_minor)
99GEN_HAS_MEMBER(amd_machine_version_stepping)
100
101GEN_HAS_MEMBER(kernel_code_entry_byte_offset)
102GEN_HAS_MEMBER(kernel_code_prefetch_byte_size)
103
104GEN_HAS_MEMBER(granulated_workitem_vgpr_count)
105GEN_HAS_MEMBER(granulated_wavefront_sgpr_count)
106GEN_HAS_MEMBER(priority)
107GEN_HAS_MEMBER(float_mode)
108GEN_HAS_MEMBER(priv)
109GEN_HAS_MEMBER(enable_dx10_clamp)
110GEN_HAS_MEMBER(debug_mode)
111GEN_HAS_MEMBER(enable_ieee_mode)
112GEN_HAS_MEMBER(enable_wgp_mode)
113GEN_HAS_MEMBER(enable_mem_ordered)
114GEN_HAS_MEMBER(enable_fwd_progress)
115
116GEN_HAS_MEMBER(enable_sgpr_private_segment_wave_byte_offset)
117GEN_HAS_MEMBER(user_sgpr_count)
118GEN_HAS_MEMBER(enable_trap_handler)
119GEN_HAS_MEMBER(enable_sgpr_workgroup_id_x)
120GEN_HAS_MEMBER(enable_sgpr_workgroup_id_y)
121GEN_HAS_MEMBER(enable_sgpr_workgroup_id_z)
122GEN_HAS_MEMBER(enable_sgpr_workgroup_info)
123GEN_HAS_MEMBER(enable_vgpr_workitem_id)
124GEN_HAS_MEMBER(enable_exception_msb)
125GEN_HAS_MEMBER(granulated_lds_size)
126GEN_HAS_MEMBER(enable_exception)
127
128GEN_HAS_MEMBER(enable_sgpr_private_segment_buffer)
129GEN_HAS_MEMBER(enable_sgpr_dispatch_ptr)
130GEN_HAS_MEMBER(enable_sgpr_queue_ptr)
131GEN_HAS_MEMBER(enable_sgpr_kernarg_segment_ptr)
132GEN_HAS_MEMBER(enable_sgpr_dispatch_id)
133GEN_HAS_MEMBER(enable_sgpr_flat_scratch_init)
134GEN_HAS_MEMBER(enable_sgpr_private_segment_size)
135GEN_HAS_MEMBER(enable_sgpr_grid_workgroup_count_x)
136GEN_HAS_MEMBER(enable_sgpr_grid_workgroup_count_y)
137GEN_HAS_MEMBER(enable_sgpr_grid_workgroup_count_z)
138GEN_HAS_MEMBER(enable_wavefront_size32)
139GEN_HAS_MEMBER(enable_ordered_append_gds)
140GEN_HAS_MEMBER(private_element_size)
141GEN_HAS_MEMBER(is_ptr64)
142GEN_HAS_MEMBER(is_dynamic_callstack)
143GEN_HAS_MEMBER(is_debug_enabled)
144GEN_HAS_MEMBER(is_xnack_enabled)
145
146GEN_HAS_MEMBER(workitem_private_segment_byte_size)
147GEN_HAS_MEMBER(workgroup_group_segment_byte_size)
148GEN_HAS_MEMBER(gds_segment_byte_size)
149GEN_HAS_MEMBER(kernarg_segment_byte_size)
150GEN_HAS_MEMBER(workgroup_fbarrier_count)
151GEN_HAS_MEMBER(wavefront_sgpr_count)
152GEN_HAS_MEMBER(workitem_vgpr_count)
153GEN_HAS_MEMBER(reserved_vgpr_first)
154GEN_HAS_MEMBER(reserved_vgpr_count)
155GEN_HAS_MEMBER(reserved_sgpr_first)
156GEN_HAS_MEMBER(reserved_sgpr_count)
157GEN_HAS_MEMBER(debug_wavefront_private_segment_offset_sgpr)
158GEN_HAS_MEMBER(debug_private_segment_buffer_sgpr)
159GEN_HAS_MEMBER(kernarg_segment_alignment)
160GEN_HAS_MEMBER(group_segment_alignment)
161GEN_HAS_MEMBER(private_segment_alignment)
162GEN_HAS_MEMBER(wavefront_size)
163GEN_HAS_MEMBER(call_convention)
164GEN_HAS_MEMBER(runtime_loader_kernel_symbol)
165
167 static constexpr StringLiteral const Table[] = {
168 "", // not found placeholder
169#define RECORD(name, altName, print, parse) #name
171#undef RECORD
172 };
173 return ArrayRef(Table);
174}
175
177 static constexpr StringLiteral const Table[] = {
178 "", // not found placeholder
179#define RECORD(name, altName, print, parse) #altName
181#undef RECORD
182 };
183 return ArrayRef(Table);
184}
185
187 static bool const Table[] = {
188#define RECORD(name, altName, print, parse) (IsMCExpr##name::RESULT)
190#undef RECORD
191 };
192 return ArrayRef(Table);
193}
194
195using RetrieveFx = const MCExpr *&(*)(AMDGPUMCKernelCodeT &);
196
198 static const RetrieveFx Table[] = {
199#define RECORD(name, altName, print, parse) GetMember##name::Get
201#undef RECORD
202 };
203 return ArrayRef(Table);
204}
205
207 ArrayRef<StringLiteral> altNames) {
208 StringMap<int> map;
209 assert(names.size() == altNames.size());
210 for (unsigned i = 0; i < names.size(); ++i) {
211 map.insert(std::pair(names[i], i));
212 map.insert(std::pair(altNames[i], i));
213 }
214 return map;
215}
216
218 static const auto map = createIndexMap(get_amd_kernel_code_t_FldNames(),
220 return map.lookup(name) - 1; // returns -1 if not found
221}
222
223static constexpr std::pair<unsigned, unsigned> getShiftMask(unsigned Value) {
224 unsigned Shift = 0;
225 unsigned Mask = 0;
226
227 Mask = ~Value;
228 for (; !(Mask & 1); Shift++, Mask >>= 1) {
229 }
230
231 return std::make_pair(Shift, Mask);
232}
233
234static const MCExpr *MaskShiftSet(const MCExpr *Val, uint32_t Mask,
235 uint32_t Shift, MCContext &Ctx) {
236 if (Mask) {
237 const MCExpr *MaskExpr = MCConstantExpr::create(Mask, Ctx);
238 Val = MCBinaryExpr::createAnd(Val, MaskExpr, Ctx);
239 }
240 if (Shift) {
241 const MCExpr *ShiftExpr = MCConstantExpr::create(Shift, Ctx);
242 Val = MCBinaryExpr::createShl(Val, ShiftExpr, Ctx);
243 }
244 return Val;
245}
246
247static const MCExpr *MaskShiftGet(const MCExpr *Val, uint32_t Mask,
248 uint32_t Shift, MCContext &Ctx) {
249 if (Shift) {
250 const MCExpr *ShiftExpr = MCConstantExpr::create(Shift, Ctx);
251 Val = MCBinaryExpr::createLShr(Val, ShiftExpr, Ctx);
252 }
253 if (Mask) {
254 const MCExpr *MaskExpr = MCConstantExpr::create(Mask, Ctx);
255 Val = MCBinaryExpr::createAnd(Val, MaskExpr, Ctx);
256 }
257 return Val;
258}
259
261public:
262 template <typename T, T AMDGPUMCKernelCodeT::*ptr,
263 typename std::enable_if_t<!std::is_integral_v<T>, T> * = nullptr>
265 raw_ostream &OS, MCContext &Ctx) {
266 OS << Name << " = ";
267 const MCExpr *Value = C.*ptr;
268 int64_t Val;
269 if (Value->evaluateAsAbsolute(Val))
270 OS << Val;
271 else
272 Value->print(OS, Ctx.getAsmInfo());
273 }
274
275 template <typename T, T AMDGPUMCKernelCodeT::*ptr,
276 typename std::enable_if_t<std::is_integral_v<T>, T> * = nullptr>
279 OS << Name << " = " << (int)(C.*ptr);
280 }
281};
282
283template <typename T, T AMDGPUMCKernelCodeT::*ptr, int shift, int width = 1>
286 const auto Mask = (static_cast<T>(1) << width) - 1;
287 OS << Name << " = " << (int)((C.*ptr >> shift) & Mask);
288}
289
291 MCContext &);
292
294 static const PrintFx Table[] = {
295#define COMPPGM1(name, aname, AccMacro) \
296 COMPPGM(name, aname, C_00B848_##AccMacro, S_00B848_##AccMacro, 0)
297#define COMPPGM2(name, aname, AccMacro) \
298 COMPPGM(name, aname, C_00B84C_##AccMacro, S_00B84C_##AccMacro, 32)
299#define PRINTFIELD(sname, aname, name) PrintField::printField<FLD_T(name)>
300#define PRINTCOMP(Complement, PGMType) \
301 [](StringRef Name, const AMDGPUMCKernelCodeT &C, raw_ostream &OS, \
302 MCContext &Ctx) { \
303 OS << Name << " = "; \
304 auto [Shift, Mask] = getShiftMask(Complement); \
305 const MCExpr *Value; \
306 if (PGMType == 0) { \
307 Value = \
308 MaskShiftGet(C.compute_pgm_resource1_registers, Mask, Shift, Ctx); \
309 } else { \
310 Value = \
311 MaskShiftGet(C.compute_pgm_resource2_registers, Mask, Shift, Ctx); \
312 } \
313 int64_t Val; \
314 if (Value->evaluateAsAbsolute(Val)) \
315 OS << Val; \
316 else \
317 Value->print(OS, Ctx.getAsmInfo()); \
318 }
319#define RECORD(name, altName, print, parse) print
321#undef RECORD
322 };
323 return ArrayRef(Table);
324}
325
326static bool expectAbsExpression(MCAsmParser &MCParser, int64_t &Value,
327 raw_ostream &Err) {
328
329 if (MCParser.getLexer().isNot(AsmToken::Equal)) {
330 Err << "expected '='";
331 return false;
332 }
333 MCParser.getLexer().Lex();
334
335 if (MCParser.parseAbsoluteExpression(Value)) {
336 Err << "integer absolute expression expected";
337 return false;
338 }
339 return true;
340}
341
342template <typename T, T AMDGPUMCKernelCodeT::*ptr>
344 raw_ostream &Err) {
345 int64_t Value = 0;
346 if (!expectAbsExpression(MCParser, Value, Err))
347 return false;
348 C.*ptr = (T)Value;
349 return true;
350}
351
352template <typename T, T AMDGPUMCKernelCodeT::*ptr, int shift, int width = 1>
354 raw_ostream &Err) {
355 int64_t Value = 0;
356 if (!expectAbsExpression(MCParser, Value, Err))
357 return false;
358 const uint64_t Mask = ((UINT64_C(1) << width) - 1) << shift;
359 C.*ptr &= (T)~Mask;
360 C.*ptr |= (T)((Value << shift) & Mask);
361 return true;
362}
363
364static bool parseExpr(MCAsmParser &MCParser, const MCExpr *&Value,
365 raw_ostream &Err) {
366 if (MCParser.getLexer().isNot(AsmToken::Equal)) {
367 Err << "expected '='";
368 return false;
369 }
370 MCParser.getLexer().Lex();
371
372 if (MCParser.parseExpression(Value)) {
373 Err << "Could not parse expression";
374 return false;
375 }
376 return true;
377}
378
380
382 static const ParseFx Table[] = {
383#define COMPPGM1(name, aname, AccMacro) \
384 COMPPGM(name, aname, G_00B848_##AccMacro, C_00B848_##AccMacro, 0)
385#define COMPPGM2(name, aname, AccMacro) \
386 COMPPGM(name, aname, G_00B84C_##AccMacro, C_00B84C_##AccMacro, 32)
387#define PARSECOMP(Complement, PGMType) \
388 [](AMDGPUMCKernelCodeT &C, MCAsmParser &MCParser, \
389 raw_ostream &Err) -> bool { \
390 MCContext &Ctx = MCParser.getContext(); \
391 const MCExpr *Value; \
392 if (!parseExpr(MCParser, Value, Err)) \
393 return false; \
394 auto [Shift, Mask] = getShiftMask(Complement); \
395 Value = MaskShiftSet(Value, Mask, Shift, Ctx); \
396 const MCExpr *Compl = MCConstantExpr::create(Complement, Ctx); \
397 if (PGMType == 0) { \
398 C.compute_pgm_resource1_registers = MCBinaryExpr::createAnd( \
399 C.compute_pgm_resource1_registers, Compl, Ctx); \
400 C.compute_pgm_resource1_registers = MCBinaryExpr::createOr( \
401 C.compute_pgm_resource1_registers, Value, Ctx); \
402 } else { \
403 C.compute_pgm_resource2_registers = MCBinaryExpr::createAnd( \
404 C.compute_pgm_resource2_registers, Compl, Ctx); \
405 C.compute_pgm_resource2_registers = MCBinaryExpr::createOr( \
406 C.compute_pgm_resource2_registers, Value, Ctx); \
407 } \
408 return true; \
409 }
410#define RECORD(name, altName, print, parse) parse
412#undef RECORD
413 };
414 return ArrayRef(Table);
415}
416
417static void printAmdKernelCodeField(const AMDGPUMCKernelCodeT &C, int FldIndex,
418 raw_ostream &OS, MCContext &Ctx) {
419 auto Printer = getPrinterTable()[FldIndex];
420 if (Printer)
421 Printer(get_amd_kernel_code_t_FldNames()[FldIndex + 1], C, OS, Ctx);
422}
423
425 MCContext &Ctx, bool InitMCExpr) {
427
429
430 if (InitMCExpr) {
431 const MCExpr *ZeroExpr = MCConstantExpr::create(0, Ctx);
436 is_dynamic_callstack = ZeroExpr;
437 wavefront_sgpr_count = ZeroExpr;
438 workitem_vgpr_count = ZeroExpr;
440 }
441}
442
444 int64_t Value;
445 if (!compute_pgm_resource1_registers->evaluateAsAbsolute(Value))
446 return;
447
449 Ctx.reportError({}, "enable_dx10_clamp=1 is not allowed on GFX12+");
450 return;
451 }
452
454 Ctx.reportError({}, "enable_ieee_mode=1 is not allowed on GFX12+");
455 return;
456 }
457
459 Ctx.reportError({}, "enable_wgp_mode=1 is only allowed on GFX10+");
460 return;
461 }
462
464 Ctx.reportError({}, "enable_mem_ordered=1 is only allowed on GFX10+");
465 return;
466 }
467
469 Ctx.reportError({}, "enable_fwd_progress=1 is only allowed on GFX10+");
470 return;
471 }
472}
473
475 static const auto IndexTable = getMCExprIndexTable();
476 return IndexTable[Index](*this);
477}
478
480 raw_ostream &Err) {
482 if (Idx < 0) {
483 Err << "unexpected amd_kernel_code_t field name " << ID;
484 return false;
485 }
486
487 if (hasMCExprVersionTable()[Idx]) {
488 const MCExpr *Value;
489 if (!parseExpr(MCParser, Value, Err))
490 return false;
492 return true;
493 }
494 auto Parser = getParserTable()[Idx];
495 return Parser ? Parser(*this, MCParser, Err) : false;
496}
497
499 const int Size = hasMCExprVersionTable().size();
500 for (int i = 0; i < Size; ++i) {
501 OS << "\t\t";
502 if (hasMCExprVersionTable()[i]) {
503 OS << get_amd_kernel_code_t_FldNames()[i + 1] << " = ";
504 int64_t Val;
505 const MCExpr *Value = getMCExprForIndex(i);
506 if (Value->evaluateAsAbsolute(Val))
507 OS << Val;
508 else
509 Value->print(OS, Ctx.getAsmInfo());
510 } else {
511 printAmdKernelCodeField(*this, i, OS, Ctx);
512 }
513 OS << '\n';
514 }
515}
516
518 OS.emitIntValue(amd_kernel_code_version_major, /*Size=*/4);
519 OS.emitIntValue(amd_kernel_code_version_minor, /*Size=*/4);
520 OS.emitIntValue(amd_machine_kind, /*Size=*/2);
521 OS.emitIntValue(amd_machine_version_major, /*Size=*/2);
522 OS.emitIntValue(amd_machine_version_minor, /*Size=*/2);
523 OS.emitIntValue(amd_machine_version_stepping, /*Size=*/2);
524 OS.emitIntValue(kernel_code_entry_byte_offset, /*Size=*/8);
525 OS.emitIntValue(kernel_code_prefetch_byte_offset, /*Size=*/8);
526 OS.emitIntValue(kernel_code_prefetch_byte_size, /*Size=*/8);
527 OS.emitIntValue(reserved0, /*Size=*/8);
528
529 if (compute_pgm_resource1_registers != nullptr)
530 OS.emitValue(compute_pgm_resource1_registers, /*Size=*/4);
531 else
533 /*Size=*/4);
534
535 if (compute_pgm_resource2_registers != nullptr)
536 OS.emitValue(compute_pgm_resource2_registers, /*Size=*/4);
537 else
539 /*Size=*/4);
540
541 if (is_dynamic_callstack != nullptr) {
542 const MCExpr *CodeProps = MCConstantExpr::create(code_properties, Ctx);
543 CodeProps = MCBinaryExpr::createOr(
544 CodeProps,
548 Ctx);
549 OS.emitValue(CodeProps, /*Size=*/4);
550 } else
551 OS.emitIntValue(code_properties, /*Size=*/4);
552
554 OS.emitValue(workitem_private_segment_byte_size, /*Size=*/4);
555 else
556 OS.emitIntValue(0, /*Size=*/4);
557
558 OS.emitIntValue(workgroup_group_segment_byte_size, /*Size=*/4);
559 OS.emitIntValue(gds_segment_byte_size, /*Size=*/4);
560 OS.emitIntValue(kernarg_segment_byte_size, /*Size=*/8);
561 OS.emitIntValue(workgroup_fbarrier_count, /*Size=*/4);
562
563 if (wavefront_sgpr_count != nullptr)
564 OS.emitValue(wavefront_sgpr_count, /*Size=*/2);
565 else
566 OS.emitIntValue(0, /*Size=*/2);
567
568 if (workitem_vgpr_count != nullptr)
569 OS.emitValue(workitem_vgpr_count, /*Size=*/2);
570 else
571 OS.emitIntValue(0, /*Size=*/2);
572
573 OS.emitIntValue(reserved_vgpr_first, /*Size=*/2);
574 OS.emitIntValue(reserved_vgpr_count, /*Size=*/2);
575 OS.emitIntValue(reserved_sgpr_first, /*Size=*/2);
576 OS.emitIntValue(reserved_sgpr_count, /*Size=*/2);
578 /*Size=*/2);
579 OS.emitIntValue(debug_private_segment_buffer_sgpr, /*Size=*/2);
580 OS.emitIntValue(kernarg_segment_alignment, /*Size=*/1);
581 OS.emitIntValue(group_segment_alignment, /*Size=*/1);
582 OS.emitIntValue(private_segment_alignment, /*Size=*/1);
583 OS.emitIntValue(wavefront_size, /*Size=*/1);
584
585 OS.emitIntValue(call_convention, /*Size=*/4);
586 OS.emitBytes(StringRef((const char *)reserved3, /*Size=*/12));
587 OS.emitIntValue(runtime_loader_kernel_symbol, /*Size=*/8);
588 OS.emitBytes(StringRef((const char *)control_directives, /*Size=*/16 * 8));
589}
static ArrayRef< StringLiteral > get_amd_kernel_code_t_FldNames()
static ArrayRef< StringLiteral > get_amd_kernel_code_t_FldAltNames()
static ArrayRef< bool > hasMCExprVersionTable()
static ArrayRef< PrintFx > getPrinterTable()
static const MCExpr * MaskShiftGet(const MCExpr *Val, uint32_t Mask, uint32_t Shift, MCContext &Ctx)
static void printBitField(StringRef Name, const AMDGPUMCKernelCodeT &C, raw_ostream &OS, MCContext &)
void(*)(StringRef, const AMDGPUMCKernelCodeT &, raw_ostream &, MCContext &) PrintFx
static void printAmdKernelCodeField(const AMDGPUMCKernelCodeT &C, int FldIndex, raw_ostream &OS, MCContext &Ctx)
static bool expectAbsExpression(MCAsmParser &MCParser, int64_t &Value, raw_ostream &Err)
static bool parseExpr(MCAsmParser &MCParser, const MCExpr *&Value, raw_ostream &Err)
static bool parseField(AMDGPUMCKernelCodeT &C, MCAsmParser &MCParser, raw_ostream &Err)
const MCExpr *&(*)(AMDGPUMCKernelCodeT &) RetrieveFx
static ArrayRef< RetrieveFx > getMCExprIndexTable()
bool(*)(AMDGPUMCKernelCodeT &, MCAsmParser &, raw_ostream &) ParseFx
#define GEN_HAS_MEMBER(member)
static bool parseBitField(AMDGPUMCKernelCodeT &C, MCAsmParser &MCParser, raw_ostream &Err)
static const MCExpr * MaskShiftSet(const MCExpr *Val, uint32_t Mask, uint32_t Shift, MCContext &Ctx)
static constexpr std::pair< unsigned, unsigned > getShiftMask(unsigned Value)
static StringMap< int > createIndexMap(ArrayRef< StringLiteral > names, ArrayRef< StringLiteral > altNames)
static ArrayRef< ParseFx > getParserTable()
static int get_amd_kernel_code_t_FieldIndex(StringRef name)
MC layer struct for AMDGPUMCKernelCodeT, provides MCExpr functionality where required.
@ AMD_CODE_PROPERTY_IS_DYNAMIC_CALLSTACK_SHIFT
Indicate if the generated ISA is using a dynamically sized call stack.
@ AMD_CODE_PROPERTY_IS_DYNAMIC_CALLSTACK_WIDTH
dxil pretty DXIL Metadata Pretty Printer
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
std::string Name
uint64_t Size
This file implements an indexed map.
#define G_00B848_FWD_PROGRESS(x)
Definition: SIDefines.h:1154
#define G_00B848_MEM_ORDERED(x)
Definition: SIDefines.h:1151
#define G_00B848_IEEE_MODE(x)
Definition: SIDefines.h:1145
#define G_00B848_DX10_CLAMP(x)
Definition: SIDefines.h:1136
#define G_00B848_WGP_MODE(x)
Definition: SIDefines.h:1148
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static const char * name
Definition: SMEABIPass.cpp:49
raw_pwrite_stream & OS
static void printField(StringRef Name, const AMDGPUMCKernelCodeT &C, raw_ostream &OS, MCContext &Ctx)
static void printField(StringRef Name, const AMDGPUMCKernelCodeT &C, raw_ostream &OS, MCContext &)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:165
bool isNot(AsmToken::TokenKind K) const
Check if the current token has kind K.
Definition: MCAsmLexer.h:144
const AsmToken & Lex()
Consume the next token from the input stream and return it.
Definition: MCAsmLexer.h:79
Generic assembler parser interface, for use by target specific assembly parsers.
Definition: MCAsmParser.h:123
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
virtual MCAsmLexer & getLexer()=0
virtual bool parseAbsoluteExpression(int64_t &Res)=0
Parse an expression which must evaluate to an absolute value.
static const MCBinaryExpr * createLShr(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:616
static const MCBinaryExpr * createAnd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:541
static const MCBinaryExpr * createOr(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:601
static const MCBinaryExpr * createShl(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:606
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition: MCExpr.cpp:194
Context object for machine code objects.
Definition: MCContext.h:81
const MCAsmInfo * getAsmInfo() const
Definition: MCContext.h:437
void reportError(SMLoc L, const Twine &Msg)
Definition: MCContext.cpp:1073
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
Streaming machine code generation interface.
Definition: MCStreamer.h:212
Generic base class for all target subtargets.
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
Definition: StringRef.h:846
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition: StringMap.h:128
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
Definition: StringMap.h:308
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
LLVM Value Representation.
Definition: Value.h:74
void print(raw_ostream &O, bool IsForDebug=false) const
Implement operator<< on Value.
Definition: AsmWriter.cpp:5021
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
bool isGFX12Plus(const MCSubtargetInfo &STI)
bool isGFX10Plus(const MCSubtargetInfo &STI)
void initDefaultAMDKernelCodeT(AMDGPUMCKernelCodeT &KernelCode, const MCSubtargetInfo *STI)
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
Definition: MathExtras.h:138
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
Definition: MathExtras.h:143
void validate(const MCSubtargetInfo *STI, MCContext &Ctx)
void initDefault(const MCSubtargetInfo *STI, MCContext &Ctx, bool InitMCExpr=true)
void EmitKernelCodeT(raw_ostream &OS, MCContext &Ctx)
bool ParseKernelCodeT(StringRef ID, MCAsmParser &MCParser, raw_ostream &Err)
const MCExpr *& getMCExprForIndex(int Index)