LLVM 23.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"
16#include "SIDefines.h"
19#include "llvm/ADT/StringRef.h"
20#include "llvm/MC/MCContext.h"
21#include "llvm/MC/MCExpr.h"
24#include "llvm/MC/MCStreamer.h"
28
29using namespace llvm;
30using namespace llvm::AMDGPU;
31
32// Generates the following for AMDGPUMCKernelCodeT struct members:
33// - HasMemberXXXXX class
34// A check to see if AMDGPUMCKernelCodeT has a specific member so it can
35// determine which of the original amd_kernel_code_t members are duplicated
36// (if the names don't match, the table driven strategy won't work).
37// - IsMCExprXXXXX class
38// Check whether a AMDGPUMCKernelcodeT struct member is MCExpr-ified or not.
39// - GetMemberXXXXX class
40// A retrieval helper for said member (of type const MCExpr *&). Will return
41// a `Phony` const MCExpr * initialized to nullptr to preserve reference
42// returns.
43#define GEN_HAS_MEMBER(member) \
44 class HasMember##member { \
45 template <typename U> \
46 using check_member = decltype(std::declval<U>().member); \
47 \
48 public: \
49 static constexpr bool RESULT = \
50 llvm::is_detected<check_member, AMDGPUMCKernelCodeT>::value; \
51 }; \
52 class IsMCExpr##member { \
53 template <typename U> \
54 static constexpr auto HasMCExprType(int) -> std::bool_constant< \
55 HasMember##member::RESULT && \
56 std::is_same_v<decltype(U::member), const MCExpr *>>; \
57 template <typename U> static constexpr std::false_type HasMCExprType(...); \
58 \
59 public: \
60 static constexpr bool RESULT = \
61 decltype(HasMCExprType<AMDGPUMCKernelCodeT>(0))::value; \
62 }; \
63 class GetMember##member { \
64 public: \
65 static const MCExpr *Phony; \
66 template <typename U> static const MCExpr *&Get(U &C) { \
67 if constexpr (IsMCExpr##member::RESULT) \
68 return C.member; \
69 else \
70 return Phony; \
71 } \
72 }; \
73 const MCExpr *GetMember##member::Phony = nullptr;
74
75// Cannot generate class declarations using the table driver approach (see table
76// in AMDKernelCodeTInfo.h). Luckily, if any are missing here or eventually
77// added to the table, an error should occur when trying to retrieve the table
78// in getMCExprIndexTable.
79GEN_HAS_MEMBER(amd_code_version_major)
80GEN_HAS_MEMBER(amd_code_version_minor)
81GEN_HAS_MEMBER(amd_machine_kind)
82GEN_HAS_MEMBER(amd_machine_version_major)
83GEN_HAS_MEMBER(amd_machine_version_minor)
84GEN_HAS_MEMBER(amd_machine_version_stepping)
85
86GEN_HAS_MEMBER(kernel_code_entry_byte_offset)
87GEN_HAS_MEMBER(kernel_code_prefetch_byte_size)
88
89GEN_HAS_MEMBER(granulated_workitem_vgpr_count)
90GEN_HAS_MEMBER(granulated_wavefront_sgpr_count)
91GEN_HAS_MEMBER(priority)
92GEN_HAS_MEMBER(float_mode)
94GEN_HAS_MEMBER(enable_dx10_clamp)
95GEN_HAS_MEMBER(debug_mode)
96GEN_HAS_MEMBER(enable_ieee_mode)
97GEN_HAS_MEMBER(enable_wgp_mode)
98GEN_HAS_MEMBER(enable_mem_ordered)
99GEN_HAS_MEMBER(enable_fwd_progress)
100
101GEN_HAS_MEMBER(enable_sgpr_private_segment_wave_byte_offset)
102GEN_HAS_MEMBER(user_sgpr_count)
103GEN_HAS_MEMBER(enable_trap_handler)
104GEN_HAS_MEMBER(enable_sgpr_workgroup_id_x)
105GEN_HAS_MEMBER(enable_sgpr_workgroup_id_y)
106GEN_HAS_MEMBER(enable_sgpr_workgroup_id_z)
107GEN_HAS_MEMBER(enable_sgpr_workgroup_info)
108GEN_HAS_MEMBER(enable_vgpr_workitem_id)
109GEN_HAS_MEMBER(enable_exception_msb)
110GEN_HAS_MEMBER(granulated_lds_size)
111GEN_HAS_MEMBER(enable_exception)
112
113GEN_HAS_MEMBER(enable_sgpr_private_segment_buffer)
114GEN_HAS_MEMBER(enable_sgpr_dispatch_ptr)
115GEN_HAS_MEMBER(enable_sgpr_queue_ptr)
116GEN_HAS_MEMBER(enable_sgpr_kernarg_segment_ptr)
117GEN_HAS_MEMBER(enable_sgpr_dispatch_id)
118GEN_HAS_MEMBER(enable_sgpr_flat_scratch_init)
119GEN_HAS_MEMBER(enable_sgpr_private_segment_size)
120GEN_HAS_MEMBER(enable_sgpr_grid_workgroup_count_x)
121GEN_HAS_MEMBER(enable_sgpr_grid_workgroup_count_y)
122GEN_HAS_MEMBER(enable_sgpr_grid_workgroup_count_z)
123GEN_HAS_MEMBER(enable_wavefront_size32)
124GEN_HAS_MEMBER(enable_ordered_append_gds)
125GEN_HAS_MEMBER(private_element_size)
126GEN_HAS_MEMBER(is_ptr64)
127GEN_HAS_MEMBER(is_dynamic_callstack)
128GEN_HAS_MEMBER(is_debug_enabled)
129GEN_HAS_MEMBER(is_xnack_enabled)
130
131GEN_HAS_MEMBER(workitem_private_segment_byte_size)
132GEN_HAS_MEMBER(workgroup_group_segment_byte_size)
133GEN_HAS_MEMBER(gds_segment_byte_size)
134GEN_HAS_MEMBER(kernarg_segment_byte_size)
135GEN_HAS_MEMBER(workgroup_fbarrier_count)
136GEN_HAS_MEMBER(wavefront_sgpr_count)
137GEN_HAS_MEMBER(workitem_vgpr_count)
138GEN_HAS_MEMBER(reserved_vgpr_first)
139GEN_HAS_MEMBER(reserved_vgpr_count)
140GEN_HAS_MEMBER(reserved_sgpr_first)
141GEN_HAS_MEMBER(reserved_sgpr_count)
142GEN_HAS_MEMBER(debug_wavefront_private_segment_offset_sgpr)
143GEN_HAS_MEMBER(debug_private_segment_buffer_sgpr)
144GEN_HAS_MEMBER(kernarg_segment_alignment)
145GEN_HAS_MEMBER(group_segment_alignment)
146GEN_HAS_MEMBER(private_segment_alignment)
147GEN_HAS_MEMBER(wavefront_size)
148GEN_HAS_MEMBER(call_convention)
149GEN_HAS_MEMBER(runtime_loader_kernel_symbol)
150
151static ArrayRef<StringLiteral> get_amd_kernel_code_t_FldNames() {
152 static constexpr StringLiteral const Table[] = {
153 "", // not found placeholder
154#define RECORD(name, altName, print, parse) #name
156#undef RECORD
157 };
158 return ArrayRef(Table);
159}
160
161static ArrayRef<StringLiteral> get_amd_kernel_code_t_FldAltNames() {
162 static constexpr StringLiteral const Table[] = {
163 "", // not found placeholder
164#define RECORD(name, altName, print, parse) #altName
166#undef RECORD
167 };
168 return ArrayRef(Table);
169}
170
171static ArrayRef<bool> hasMCExprVersionTable() {
172 static bool const Table[] = {
173#define RECORD(name, altName, print, parse) (IsMCExpr##name::RESULT)
175#undef RECORD
176 };
177 return ArrayRef(Table);
178}
179
180using RetrieveFx = const MCExpr *&(*)(AMDGPUMCKernelCodeT &);
181
182static ArrayRef<RetrieveFx> getMCExprIndexTable() {
183 static const RetrieveFx Table[] = {
184#define RECORD(name, altName, print, parse) GetMember##name::Get
186#undef RECORD
187 };
188 return ArrayRef(Table);
189}
190
192 ArrayRef<StringLiteral> altNames) {
193 StringMap<int> map;
194 assert(names.size() == altNames.size());
195 for (unsigned i = 0; i < names.size(); ++i) {
196 map.insert(std::pair(names[i], i));
197 map.insert(std::pair(altNames[i], i));
198 }
199 return map;
200}
201
203 static const auto map = createIndexMap(get_amd_kernel_code_t_FldNames(),
204 get_amd_kernel_code_t_FldAltNames());
205 return map.lookup(name) - 1; // returns -1 if not found
206}
207
209public:
210 template <typename T, T AMDGPUMCKernelCodeT::*ptr>
211 static void printField(StringRef Name, const AMDGPUMCKernelCodeT &C,
212 raw_ostream &OS, MCContext &Ctx,
214 if constexpr (!std::is_integral_v<T>) {
215 OS << Name << " = ";
216 const MCExpr *Value = C.*ptr;
217 Helper(Value, OS, Ctx.getAsmInfo());
218 } else {
219 OS << Name << " = " << (int)(C.*ptr);
220 }
221 }
222};
223
224template <typename T, T AMDGPUMCKernelCodeT::*ptr, int shift, int width = 1>
226 raw_ostream &OS, MCContext &,
228 const auto Mask = (static_cast<T>(1) << width) - 1;
229 OS << Name << " = " << (int)((C.*ptr >> shift) & Mask);
230}
231
234
236getPrinterTable(AMDGPUMCKernelCodeT::PrintHelper Helper) {
237 static const PrintFx Table[] = {
238#define COMPPGM1(name, aname, AccMacro) \
239 COMPPGM(name, aname, C_00B848_##AccMacro, S_00B848_##AccMacro, 0)
240#define COMPPGM2(name, aname, AccMacro) \
241 COMPPGM(name, aname, C_00B84C_##AccMacro, S_00B84C_##AccMacro, 32)
242#define PRINTFIELD(sname, aname, name) PrintField::printField<FLD_T(name)>
243#define PRINTCOMP(Complement, PGMType) \
244 [](StringRef Name, const AMDGPUMCKernelCodeT &C, raw_ostream &OS, \
245 MCContext &Ctx, AMDGPUMCKernelCodeT::PrintHelper Helper) { \
246 OS << Name << " = "; \
247 auto [Shift, Mask] = getShiftMask(Complement); \
248 const MCExpr *Value; \
249 if (PGMType == 0) { \
250 Value = \
251 maskShiftGet(C.compute_pgm_resource1_registers, Mask, Shift, Ctx); \
252 } else { \
253 Value = \
254 maskShiftGet(C.compute_pgm_resource2_registers, Mask, Shift, Ctx); \
255 } \
256 Helper(Value, OS, Ctx.getAsmInfo()); \
257 }
258#define RECORD(name, altName, print, parse) print
260#undef RECORD
261 };
262 return ArrayRef(Table);
263}
264
265static bool expectAbsExpression(MCAsmParser &MCParser, int64_t &Value,
266 raw_ostream &Err) {
267
268 if (MCParser.getLexer().isNot(AsmToken::Equal)) {
269 Err << "expected '='";
270 return false;
271 }
272 MCParser.getLexer().Lex();
273
274 if (MCParser.parseAbsoluteExpression(Value)) {
275 Err << "integer absolute expression expected";
276 return false;
277 }
278 return true;
279}
280
281template <typename T, T AMDGPUMCKernelCodeT::*ptr>
283 raw_ostream &Err) {
284 int64_t Value = 0;
285 if (!expectAbsExpression(MCParser, Value, Err))
286 return false;
287 C.*ptr = (T)Value;
288 return true;
289}
290
291template <typename T, T AMDGPUMCKernelCodeT::*ptr, int shift, int width = 1>
293 raw_ostream &Err) {
294 int64_t Value = 0;
295 if (!expectAbsExpression(MCParser, Value, Err))
296 return false;
297 const uint64_t Mask = ((UINT64_C(1) << width) - 1) << shift;
298 C.*ptr &= (T)~Mask;
299 C.*ptr |= (T)((Value << shift) & Mask);
300 return true;
301}
302
303static bool parseExpr(MCAsmParser &MCParser, const MCExpr *&Value,
304 raw_ostream &Err) {
305 if (MCParser.getLexer().isNot(AsmToken::Equal)) {
306 Err << "expected '='";
307 return false;
308 }
309 MCParser.getLexer().Lex();
310
311 if (MCParser.parseExpression(Value)) {
312 Err << "Could not parse expression";
313 return false;
314 }
315 return true;
316}
317
319
320static ArrayRef<ParseFx> getParserTable() {
321 static const ParseFx Table[] = {
322#define COMPPGM1(name, aname, AccMacro) \
323 COMPPGM(name, aname, G_00B848_##AccMacro, C_00B848_##AccMacro, 0)
324#define COMPPGM2(name, aname, AccMacro) \
325 COMPPGM(name, aname, G_00B84C_##AccMacro, C_00B84C_##AccMacro, 32)
326#define PARSECOMP(Complement, PGMType) \
327 [](AMDGPUMCKernelCodeT &C, MCAsmParser &MCParser, \
328 raw_ostream &Err) -> bool { \
329 MCContext &Ctx = MCParser.getContext(); \
330 const MCExpr *Value; \
331 if (!parseExpr(MCParser, Value, Err)) \
332 return false; \
333 auto [Shift, Mask] = getShiftMask(Complement); \
334 Value = maskShiftSet(Value, Mask, Shift, Ctx); \
335 const MCExpr *Compl = MCConstantExpr::create(Complement, Ctx); \
336 if (PGMType == 0) { \
337 C.compute_pgm_resource1_registers = MCBinaryExpr::createAnd( \
338 C.compute_pgm_resource1_registers, Compl, Ctx); \
339 C.compute_pgm_resource1_registers = MCBinaryExpr::createOr( \
340 C.compute_pgm_resource1_registers, Value, Ctx); \
341 } else { \
342 C.compute_pgm_resource2_registers = MCBinaryExpr::createAnd( \
343 C.compute_pgm_resource2_registers, Compl, Ctx); \
344 C.compute_pgm_resource2_registers = MCBinaryExpr::createOr( \
345 C.compute_pgm_resource2_registers, Value, Ctx); \
346 } \
347 return true; \
348 }
349#define RECORD(name, altName, print, parse) parse
351#undef RECORD
352 };
353 return ArrayRef(Table);
354}
355
356static void printAmdKernelCodeField(const AMDGPUMCKernelCodeT &C, int FldIndex,
357 raw_ostream &OS, MCContext &Ctx,
359 auto Printer = getPrinterTable(Helper)[FldIndex];
360 if (Printer)
361 Printer(get_amd_kernel_code_t_FldNames()[FldIndex + 1], C, OS, Ctx, Helper);
362}
363
382
384 int64_t Value;
385 if (!compute_pgm_resource1_registers->evaluateAsAbsolute(Value))
386 return;
387
389 !STI->hasFeature(AMDGPU::FeatureDX10ClampAndIEEEMode)) {
390 Ctx.reportError({}, "enable_dx10_clamp=1 is not allowed on GFX1170+");
391 return;
392 }
393
395 !STI->hasFeature(AMDGPU::FeatureDX10ClampAndIEEEMode)) {
396 Ctx.reportError({}, "enable_ieee_mode=1 is not allowed on GFX1170+");
397 return;
398 }
399
401 Ctx.reportError({}, "enable_wgp_mode=1 is only allowed on GFX10+");
402 return;
403 }
404
406 Ctx.reportError({}, "enable_mem_ordered=1 is only allowed on GFX10+");
407 return;
408 }
409
411 Ctx.reportError({}, "enable_fwd_progress=1 is only allowed on GFX10+");
412 return;
413 }
414}
415
417 static const auto IndexTable = getMCExprIndexTable();
418 return IndexTable[Index](*this);
419}
420
422 raw_ostream &Err) {
423 const int Idx = get_amd_kernel_code_t_FieldIndex(ID);
424 if (Idx < 0) {
425 Err << "unexpected amd_kernel_code_t field name " << ID;
426 return false;
427 }
428
429 if (hasMCExprVersionTable()[Idx]) {
430 const MCExpr *Value;
431 if (!parseExpr(MCParser, Value, Err))
432 return false;
434 return true;
435 }
436 auto Parser = getParserTable()[Idx];
437 return Parser && Parser(*this, MCParser, Err);
438}
439
441 PrintHelper Helper) {
442 const int Size = hasMCExprVersionTable().size();
443 for (int i = 0; i < Size; ++i) {
444 OS << "\t\t";
445 if (hasMCExprVersionTable()[i]) {
446 OS << get_amd_kernel_code_t_FldNames()[i + 1] << " = ";
447 const MCExpr *Value = getMCExprForIndex(i);
448 Helper(Value, OS, Ctx.getAsmInfo());
449 } else {
450 printAmdKernelCodeField(*this, i, OS, Ctx, Helper);
451 }
452 OS << '\n';
453 }
454}
455
459 OS.emitIntValue(amd_machine_kind, /*Size=*/2);
466 OS.emitIntValue(reserved0, /*Size=*/8);
467
468 if (compute_pgm_resource1_registers != nullptr)
470 else
472 /*Size=*/4);
473
474 if (compute_pgm_resource2_registers != nullptr)
476 else
478 /*Size=*/4);
479
480 if (is_dynamic_callstack != nullptr) {
481 const MCExpr *CodeProps = MCConstantExpr::create(code_properties, Ctx);
482 CodeProps = MCBinaryExpr::createOr(
483 CodeProps,
487 Ctx);
488 OS.emitValue(CodeProps, /*Size=*/4);
489 } else
490 OS.emitIntValue(code_properties, /*Size=*/4);
491
494 else
495 OS.emitIntValue(0, /*Size=*/4);
496
498 OS.emitIntValue(gds_segment_byte_size, /*Size=*/4);
501
502 if (wavefront_sgpr_count != nullptr)
503 OS.emitValue(wavefront_sgpr_count, /*Size=*/2);
504 else
505 OS.emitIntValue(0, /*Size=*/2);
506
507 if (workitem_vgpr_count != nullptr)
508 OS.emitValue(workitem_vgpr_count, /*Size=*/2);
509 else
510 OS.emitIntValue(0, /*Size=*/2);
511
512 OS.emitIntValue(reserved_vgpr_first, /*Size=*/2);
513 OS.emitIntValue(reserved_vgpr_count, /*Size=*/2);
514 OS.emitIntValue(reserved_sgpr_first, /*Size=*/2);
515 OS.emitIntValue(reserved_sgpr_count, /*Size=*/2);
517 /*Size=*/2);
522 OS.emitIntValue(wavefront_size, /*Size=*/1);
523
524 OS.emitIntValue(call_convention, /*Size=*/4);
525 OS.emitBytes(StringRef((const char *)reserved3, /*Size=*/12));
527 OS.emitBytes(StringRef((const char *)control_directives, /*Size=*/16 * 8));
528}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Provides AMDGPU specific target descriptions.
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:1252
#define G_00B848_MEM_ORDERED(x)
Definition SIDefines.h:1249
#define G_00B848_IEEE_MODE(x)
Definition SIDefines.h:1243
#define G_00B848_DX10_CLAMP(x)
Definition SIDefines.h:1234
#define G_00B848_WGP_MODE(x)
Definition SIDefines.h:1246
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:40
size_t size() const
size - Get the array size.
Definition ArrayRef.h:142
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:221
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.
bool hasFeature(unsigned Feature) const
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
Definition StringRef.h:882
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:321
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
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.
Definition Types.h:26
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
Definition MathExtras.h:150
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
Definition MathExtras.h:155
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)