Thanks to visit codestin.com
Credit goes to llvm.org

LLVM 22.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"
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 static constexpr auto HasMCExprType(int) -> std::bool_constant< \
61 HasMember##member::RESULT && \
62 std::is_same_v<decltype(U::member), const MCExpr *>>; \
63 template <typename U> static constexpr std::false_type HasMCExprType(...); \
64 \
65 public: \
66 static constexpr bool RESULT = \
67 decltype(HasMCExprType<AMDGPUMCKernelCodeT>(0))::value; \
68 }; \
69 class GetMember##member { \
70 public: \
71 static const MCExpr *Phony; \
72 template <typename U> static const MCExpr *&Get(U &C) { \
73 if constexpr (IsMCExpr##member::RESULT) \
74 return C.member; \
75 else \
76 return Phony; \
77 } \
78 }; \
79 const MCExpr *GetMember##member::Phony = nullptr;
80
81// Cannot generate class declarations using the table driver approach (see table
82// in AMDKernelCodeTInfo.h). Luckily, if any are missing here or eventually
83// added to the table, an error should occur when trying to retrieve the table
84// in getMCExprIndexTable.
85GEN_HAS_MEMBER(amd_code_version_major)
86GEN_HAS_MEMBER(amd_code_version_minor)
87GEN_HAS_MEMBER(amd_machine_kind)
88GEN_HAS_MEMBER(amd_machine_version_major)
89GEN_HAS_MEMBER(amd_machine_version_minor)
90GEN_HAS_MEMBER(amd_machine_version_stepping)
91
92GEN_HAS_MEMBER(kernel_code_entry_byte_offset)
93GEN_HAS_MEMBER(kernel_code_prefetch_byte_size)
94
95GEN_HAS_MEMBER(granulated_workitem_vgpr_count)
96GEN_HAS_MEMBER(granulated_wavefront_sgpr_count)
97GEN_HAS_MEMBER(priority)
98GEN_HAS_MEMBER(float_mode)
100GEN_HAS_MEMBER(enable_dx10_clamp)
101GEN_HAS_MEMBER(debug_mode)
102GEN_HAS_MEMBER(enable_ieee_mode)
103GEN_HAS_MEMBER(enable_wgp_mode)
104GEN_HAS_MEMBER(enable_mem_ordered)
105GEN_HAS_MEMBER(enable_fwd_progress)
106
107GEN_HAS_MEMBER(enable_sgpr_private_segment_wave_byte_offset)
108GEN_HAS_MEMBER(user_sgpr_count)
109GEN_HAS_MEMBER(enable_trap_handler)
110GEN_HAS_MEMBER(enable_sgpr_workgroup_id_x)
111GEN_HAS_MEMBER(enable_sgpr_workgroup_id_y)
112GEN_HAS_MEMBER(enable_sgpr_workgroup_id_z)
113GEN_HAS_MEMBER(enable_sgpr_workgroup_info)
114GEN_HAS_MEMBER(enable_vgpr_workitem_id)
115GEN_HAS_MEMBER(enable_exception_msb)
116GEN_HAS_MEMBER(granulated_lds_size)
117GEN_HAS_MEMBER(enable_exception)
118
119GEN_HAS_MEMBER(enable_sgpr_private_segment_buffer)
120GEN_HAS_MEMBER(enable_sgpr_dispatch_ptr)
121GEN_HAS_MEMBER(enable_sgpr_queue_ptr)
122GEN_HAS_MEMBER(enable_sgpr_kernarg_segment_ptr)
123GEN_HAS_MEMBER(enable_sgpr_dispatch_id)
124GEN_HAS_MEMBER(enable_sgpr_flat_scratch_init)
125GEN_HAS_MEMBER(enable_sgpr_private_segment_size)
126GEN_HAS_MEMBER(enable_sgpr_grid_workgroup_count_x)
127GEN_HAS_MEMBER(enable_sgpr_grid_workgroup_count_y)
128GEN_HAS_MEMBER(enable_sgpr_grid_workgroup_count_z)
129GEN_HAS_MEMBER(enable_wavefront_size32)
130GEN_HAS_MEMBER(enable_ordered_append_gds)
131GEN_HAS_MEMBER(private_element_size)
132GEN_HAS_MEMBER(is_ptr64)
133GEN_HAS_MEMBER(is_dynamic_callstack)
134GEN_HAS_MEMBER(is_debug_enabled)
135GEN_HAS_MEMBER(is_xnack_enabled)
136
137GEN_HAS_MEMBER(workitem_private_segment_byte_size)
138GEN_HAS_MEMBER(workgroup_group_segment_byte_size)
139GEN_HAS_MEMBER(gds_segment_byte_size)
140GEN_HAS_MEMBER(kernarg_segment_byte_size)
141GEN_HAS_MEMBER(workgroup_fbarrier_count)
142GEN_HAS_MEMBER(wavefront_sgpr_count)
143GEN_HAS_MEMBER(workitem_vgpr_count)
144GEN_HAS_MEMBER(reserved_vgpr_first)
145GEN_HAS_MEMBER(reserved_vgpr_count)
146GEN_HAS_MEMBER(reserved_sgpr_first)
147GEN_HAS_MEMBER(reserved_sgpr_count)
148GEN_HAS_MEMBER(debug_wavefront_private_segment_offset_sgpr)
149GEN_HAS_MEMBER(debug_private_segment_buffer_sgpr)
150GEN_HAS_MEMBER(kernarg_segment_alignment)
151GEN_HAS_MEMBER(group_segment_alignment)
152GEN_HAS_MEMBER(private_segment_alignment)
153GEN_HAS_MEMBER(wavefront_size)
154GEN_HAS_MEMBER(call_convention)
155GEN_HAS_MEMBER(runtime_loader_kernel_symbol)
156
157static ArrayRef<StringLiteral> get_amd_kernel_code_t_FldNames() {
158 static constexpr StringLiteral const Table[] = {
159 "", // not found placeholder
160#define RECORD(name, altName, print, parse) #name
162#undef RECORD
163 };
164 return ArrayRef(Table);
165}
166
167static ArrayRef<StringLiteral> get_amd_kernel_code_t_FldAltNames() {
168 static constexpr StringLiteral const Table[] = {
169 "", // not found placeholder
170#define RECORD(name, altName, print, parse) #altName
172#undef RECORD
173 };
174 return ArrayRef(Table);
175}
176
177static ArrayRef<bool> hasMCExprVersionTable() {
178 static bool const Table[] = {
179#define RECORD(name, altName, print, parse) (IsMCExpr##name::RESULT)
181#undef RECORD
182 };
183 return ArrayRef(Table);
184}
185
186using RetrieveFx = const MCExpr *&(*)(AMDGPUMCKernelCodeT &);
187
188static ArrayRef<RetrieveFx> getMCExprIndexTable() {
189 static const RetrieveFx Table[] = {
190#define RECORD(name, altName, print, parse) GetMember##name::Get
192#undef RECORD
193 };
194 return ArrayRef(Table);
195}
196
198 ArrayRef<StringLiteral> altNames) {
199 StringMap<int> map;
200 assert(names.size() == altNames.size());
201 for (unsigned i = 0; i < names.size(); ++i) {
202 map.insert(std::pair(names[i], i));
203 map.insert(std::pair(altNames[i], i));
204 }
205 return map;
206}
207
209 static const auto map = createIndexMap(get_amd_kernel_code_t_FldNames(),
210 get_amd_kernel_code_t_FldAltNames());
211 return map.lookup(name) - 1; // returns -1 if not found
212}
213
215public:
216 template <typename T, T AMDGPUMCKernelCodeT::*ptr>
217 static void printField(StringRef Name, const AMDGPUMCKernelCodeT &C,
218 raw_ostream &OS, MCContext &Ctx,
220 if constexpr (!std::is_integral_v<T>) {
221 OS << Name << " = ";
222 const MCExpr *Value = C.*ptr;
223 Helper(Value, OS, Ctx.getAsmInfo());
224 } else {
225 OS << Name << " = " << (int)(C.*ptr);
226 }
227 }
228};
229
230template <typename T, T AMDGPUMCKernelCodeT::*ptr, int shift, int width = 1>
232 raw_ostream &OS, MCContext &,
234 const auto Mask = (static_cast<T>(1) << width) - 1;
235 OS << Name << " = " << (int)((C.*ptr >> shift) & Mask);
236}
237
240
242getPrinterTable(AMDGPUMCKernelCodeT::PrintHelper Helper) {
243 static const PrintFx Table[] = {
244#define COMPPGM1(name, aname, AccMacro) \
245 COMPPGM(name, aname, C_00B848_##AccMacro, S_00B848_##AccMacro, 0)
246#define COMPPGM2(name, aname, AccMacro) \
247 COMPPGM(name, aname, C_00B84C_##AccMacro, S_00B84C_##AccMacro, 32)
248#define PRINTFIELD(sname, aname, name) PrintField::printField<FLD_T(name)>
249#define PRINTCOMP(Complement, PGMType) \
250 [](StringRef Name, const AMDGPUMCKernelCodeT &C, raw_ostream &OS, \
251 MCContext &Ctx, AMDGPUMCKernelCodeT::PrintHelper Helper) { \
252 OS << Name << " = "; \
253 auto [Shift, Mask] = getShiftMask(Complement); \
254 const MCExpr *Value; \
255 if (PGMType == 0) { \
256 Value = \
257 maskShiftGet(C.compute_pgm_resource1_registers, Mask, Shift, Ctx); \
258 } else { \
259 Value = \
260 maskShiftGet(C.compute_pgm_resource2_registers, Mask, Shift, Ctx); \
261 } \
262 Helper(Value, OS, Ctx.getAsmInfo()); \
263 }
264#define RECORD(name, altName, print, parse) print
266#undef RECORD
267 };
268 return ArrayRef(Table);
269}
270
271static bool expectAbsExpression(MCAsmParser &MCParser, int64_t &Value,
272 raw_ostream &Err) {
273
274 if (MCParser.getLexer().isNot(AsmToken::Equal)) {
275 Err << "expected '='";
276 return false;
277 }
278 MCParser.getLexer().Lex();
279
280 if (MCParser.parseAbsoluteExpression(Value)) {
281 Err << "integer absolute expression expected";
282 return false;
283 }
284 return true;
285}
286
287template <typename T, T AMDGPUMCKernelCodeT::*ptr>
289 raw_ostream &Err) {
290 int64_t Value = 0;
291 if (!expectAbsExpression(MCParser, Value, Err))
292 return false;
293 C.*ptr = (T)Value;
294 return true;
295}
296
297template <typename T, T AMDGPUMCKernelCodeT::*ptr, int shift, int width = 1>
299 raw_ostream &Err) {
300 int64_t Value = 0;
301 if (!expectAbsExpression(MCParser, Value, Err))
302 return false;
303 const uint64_t Mask = ((UINT64_C(1) << width) - 1) << shift;
304 C.*ptr &= (T)~Mask;
305 C.*ptr |= (T)((Value << shift) & Mask);
306 return true;
307}
308
309static bool parseExpr(MCAsmParser &MCParser, const MCExpr *&Value,
310 raw_ostream &Err) {
311 if (MCParser.getLexer().isNot(AsmToken::Equal)) {
312 Err << "expected '='";
313 return false;
314 }
315 MCParser.getLexer().Lex();
316
317 if (MCParser.parseExpression(Value)) {
318 Err << "Could not parse expression";
319 return false;
320 }
321 return true;
322}
323
325
326static ArrayRef<ParseFx> getParserTable() {
327 static const ParseFx Table[] = {
328#define COMPPGM1(name, aname, AccMacro) \
329 COMPPGM(name, aname, G_00B848_##AccMacro, C_00B848_##AccMacro, 0)
330#define COMPPGM2(name, aname, AccMacro) \
331 COMPPGM(name, aname, G_00B84C_##AccMacro, C_00B84C_##AccMacro, 32)
332#define PARSECOMP(Complement, PGMType) \
333 [](AMDGPUMCKernelCodeT &C, MCAsmParser &MCParser, \
334 raw_ostream &Err) -> bool { \
335 MCContext &Ctx = MCParser.getContext(); \
336 const MCExpr *Value; \
337 if (!parseExpr(MCParser, Value, Err)) \
338 return false; \
339 auto [Shift, Mask] = getShiftMask(Complement); \
340 Value = maskShiftSet(Value, Mask, Shift, Ctx); \
341 const MCExpr *Compl = MCConstantExpr::create(Complement, Ctx); \
342 if (PGMType == 0) { \
343 C.compute_pgm_resource1_registers = MCBinaryExpr::createAnd( \
344 C.compute_pgm_resource1_registers, Compl, Ctx); \
345 C.compute_pgm_resource1_registers = MCBinaryExpr::createOr( \
346 C.compute_pgm_resource1_registers, Value, Ctx); \
347 } else { \
348 C.compute_pgm_resource2_registers = MCBinaryExpr::createAnd( \
349 C.compute_pgm_resource2_registers, Compl, Ctx); \
350 C.compute_pgm_resource2_registers = MCBinaryExpr::createOr( \
351 C.compute_pgm_resource2_registers, Value, Ctx); \
352 } \
353 return true; \
354 }
355#define RECORD(name, altName, print, parse) parse
357#undef RECORD
358 };
359 return ArrayRef(Table);
360}
361
362static void printAmdKernelCodeField(const AMDGPUMCKernelCodeT &C, int FldIndex,
363 raw_ostream &OS, MCContext &Ctx,
365 auto Printer = getPrinterTable(Helper)[FldIndex];
366 if (Printer)
367 Printer(get_amd_kernel_code_t_FldNames()[FldIndex + 1], C, OS, Ctx, Helper);
368}
369
388
390 int64_t Value;
391 if (!compute_pgm_resource1_registers->evaluateAsAbsolute(Value))
392 return;
393
395 Ctx.reportError({}, "enable_dx10_clamp=1 is not allowed on GFX12+");
396 return;
397 }
398
400 Ctx.reportError({}, "enable_ieee_mode=1 is not allowed on GFX12+");
401 return;
402 }
403
405 Ctx.reportError({}, "enable_wgp_mode=1 is only allowed on GFX10+");
406 return;
407 }
408
410 Ctx.reportError({}, "enable_mem_ordered=1 is only allowed on GFX10+");
411 return;
412 }
413
415 Ctx.reportError({}, "enable_fwd_progress=1 is only allowed on GFX10+");
416 return;
417 }
418}
419
421 static const auto IndexTable = getMCExprIndexTable();
422 return IndexTable[Index](*this);
423}
424
426 raw_ostream &Err) {
427 const int Idx = get_amd_kernel_code_t_FieldIndex(ID);
428 if (Idx < 0) {
429 Err << "unexpected amd_kernel_code_t field name " << ID;
430 return false;
431 }
432
433 if (hasMCExprVersionTable()[Idx]) {
434 const MCExpr *Value;
435 if (!parseExpr(MCParser, Value, Err))
436 return false;
438 return true;
439 }
440 auto Parser = getParserTable()[Idx];
441 return Parser && Parser(*this, MCParser, Err);
442}
443
445 PrintHelper Helper) {
446 const int Size = hasMCExprVersionTable().size();
447 for (int i = 0; i < Size; ++i) {
448 OS << "\t\t";
449 if (hasMCExprVersionTable()[i]) {
450 OS << get_amd_kernel_code_t_FldNames()[i + 1] << " = ";
451 const MCExpr *Value = getMCExprForIndex(i);
452 Helper(Value, OS, Ctx.getAsmInfo());
453 } else {
454 printAmdKernelCodeField(*this, i, OS, Ctx, Helper);
455 }
456 OS << '\n';
457 }
458}
459
463 OS.emitIntValue(amd_machine_kind, /*Size=*/2);
470 OS.emitIntValue(reserved0, /*Size=*/8);
471
472 if (compute_pgm_resource1_registers != nullptr)
474 else
476 /*Size=*/4);
477
478 if (compute_pgm_resource2_registers != nullptr)
480 else
482 /*Size=*/4);
483
484 if (is_dynamic_callstack != nullptr) {
485 const MCExpr *CodeProps = MCConstantExpr::create(code_properties, Ctx);
486 CodeProps = MCBinaryExpr::createOr(
487 CodeProps,
491 Ctx);
492 OS.emitValue(CodeProps, /*Size=*/4);
493 } else
494 OS.emitIntValue(code_properties, /*Size=*/4);
495
498 else
499 OS.emitIntValue(0, /*Size=*/4);
500
502 OS.emitIntValue(gds_segment_byte_size, /*Size=*/4);
505
506 if (wavefront_sgpr_count != nullptr)
507 OS.emitValue(wavefront_sgpr_count, /*Size=*/2);
508 else
509 OS.emitIntValue(0, /*Size=*/2);
510
511 if (workitem_vgpr_count != nullptr)
512 OS.emitValue(workitem_vgpr_count, /*Size=*/2);
513 else
514 OS.emitIntValue(0, /*Size=*/2);
515
516 OS.emitIntValue(reserved_vgpr_first, /*Size=*/2);
517 OS.emitIntValue(reserved_vgpr_count, /*Size=*/2);
518 OS.emitIntValue(reserved_sgpr_first, /*Size=*/2);
519 OS.emitIntValue(reserved_sgpr_count, /*Size=*/2);
521 /*Size=*/2);
526 OS.emitIntValue(wavefront_size, /*Size=*/1);
527
528 OS.emitIntValue(call_convention, /*Size=*/4);
529 OS.emitBytes(StringRef((const char *)reserved3, /*Size=*/12));
531 OS.emitBytes(StringRef((const char *)control_directives, /*Size=*/16 * 8));
532}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static void printBitField(StringRef Name, const AMDGPUMCKernelCodeT &C, raw_ostream &OS, MCContext &, AMDGPUMCKernelCodeT::PrintHelper)
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
void(*)(StringRef, const AMDGPUMCKernelCodeT &, raw_ostream &, MCContext &, AMDGPUMCKernelCodeT::PrintHelper Helper) PrintFx
bool(*)(AMDGPUMCKernelCodeT &, MCAsmParser &, raw_ostream &) ParseFx
#define GEN_HAS_MEMBER(member)
static bool parseBitField(AMDGPUMCKernelCodeT &C, MCAsmParser &MCParser, raw_ostream &Err)
static void printAmdKernelCodeField(const AMDGPUMCKernelCodeT &C, int FldIndex, raw_ostream &OS, MCContext &Ctx, AMDGPUMCKernelCodeT::PrintHelper Helper)
static StringMap< int > createIndexMap(ArrayRef< StringLiteral > names, ArrayRef< StringLiteral > altNames)
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
#define T
#define G_00B848_FWD_PROGRESS(x)
Definition SIDefines.h:1237
#define G_00B848_MEM_ORDERED(x)
Definition SIDefines.h:1234
#define G_00B848_IEEE_MODE(x)
Definition SIDefines.h:1228
#define G_00B848_DX10_CLAMP(x)
Definition SIDefines.h:1219
#define G_00B848_WGP_MODE(x)
Definition SIDefines.h:1231
static const char * name
static void printField(StringRef Name, const AMDGPUMCKernelCodeT &C, raw_ostream &OS, MCContext &Ctx, AMDGPUMCKernelCodeT::PrintHelper Helper)
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:147
const AsmToken & Lex()
Consume the next token from the input stream and return it.
Definition AsmLexer.h:92
bool isNot(AsmToken::TokenKind K) const
Check if the current token has kind K.
Definition AsmLexer.h:150
Generic assembler parser interface, for use by target specific assembly parsers.
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
AsmLexer & getLexer()
virtual bool parseAbsoluteExpression(int64_t &Res)=0
Parse an expression which must evaluate to an absolute value.
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
Streaming machine code generation interface.
Definition MCStreamer.h:220
void emitValue(const MCExpr *Value, unsigned Size, SMLoc Loc=SMLoc())
virtual void emitIntValue(uint64_t Value, unsigned Size)
Special case of EmitValue that avoids the client having to pass in a MCExpr for constant integers.
virtual void emitBytes(StringRef Data)
Emit the bytes in Data into the output.
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:862
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition StringMap.h:133
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
Definition StringMap.h:310
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
LLVM Value Representation.
Definition Value.h:75
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
bool isGFX12Plus(const MCSubtargetInfo &STI)
const MCExpr * maskShiftSet(const MCExpr *Val, uint32_t Mask, uint32_t Shift, MCContext &Ctx)
Provided with the MCExpr * Val, uint32 Mask and Shift, will return the masked and left shifted,...
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.
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
Definition MathExtras.h:159
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
Definition MathExtras.h:164
ArrayRef(const T &OneElt) -> ArrayRef< T >
function_ref< void(const MCExpr *, raw_ostream &, const MCAsmInfo *)> PrintHelper
void EmitKernelCodeT(raw_ostream &OS, MCContext &Ctx, PrintHelper Helper)
void validate(const MCSubtargetInfo *STI, MCContext &Ctx)
void initDefault(const MCSubtargetInfo *STI, MCContext &Ctx, bool InitMCExpr=true)
bool ParseKernelCodeT(StringRef ID, MCAsmParser &MCParser, raw_ostream &Err)
const MCExpr *& getMCExprForIndex(int Index)