41#define GEN_HAS_MEMBER(member) \
42 class HasMember##member { \
44 struct KnownWithMember { \
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(...); \
54 static constexpr bool RESULT = \
55 std::is_same_v<decltype(Test<AmbiguousDerived>(nullptr)), \
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 *>, \
64 static constexpr std::true_type HasMCExprType(decltype(U::member) *); \
65 template <typename U> static constexpr std::false_type HasMCExprType(...); \
68 static constexpr bool RESULT = \
69 std::is_same_v<decltype(HasMCExprType<AMDGPUMCKernelCodeT>(nullptr)), \
72 class GetMember##member { \
74 static const MCExpr *Phony; \
75 template <typename U, typename std::enable_if_t<IsMCExpr##member::RESULT, \
77 static const MCExpr *&Get(U &C) { \
78 assert(IsMCExpr##member::RESULT && \
79 "Trying to retrieve member that does not exist."); \
82 template <typename U, typename std::enable_if_t<!IsMCExpr##member::RESULT, \
84 static const MCExpr *&Get(U &C) { \
88 const MCExpr *GetMember##member::Phony = nullptr;
169#define RECORD(name, altName, print, parse) #name
179#define RECORD(name, altName, print, parse) #altName
187 static bool const Table[] = {
188#define RECORD(name, altName, print, parse) (IsMCExpr##name::RESULT)
199#define RECORD(name, altName, print, parse) GetMember##name::Get
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));
220 return map.lookup(
name) - 1;
226 typename std::enable_if_t<!std::is_integral_v<T>,
T> * =
nullptr>
236 typename std::enable_if_t<std::is_integral_v<T>,
T> * =
nullptr>
240 OS <<
Name <<
" = " << (int)(
C.*ptr);
244template <
typename T, T AMDGPUMCKernelCodeT::*ptr,
int shift,
int w
idth = 1>
248 const auto Mask = (
static_cast<T>(1) << width) - 1;
249 OS <<
Name <<
" = " << (int)((
C.*ptr >> shift) & Mask);
257 static const PrintFx Table[] = {
258#define COMPPGM1(name, aname, AccMacro) \
259 COMPPGM(name, aname, C_00B848_##AccMacro, S_00B848_##AccMacro, 0)
260#define COMPPGM2(name, aname, AccMacro) \
261 COMPPGM(name, aname, C_00B84C_##AccMacro, S_00B84C_##AccMacro, 32)
262#define PRINTFIELD(sname, aname, name) PrintField::printField<FLD_T(name)>
263#define PRINTCOMP(Complement, PGMType) \
264 [](StringRef Name, const AMDGPUMCKernelCodeT &C, raw_ostream &OS, \
265 MCContext &Ctx, AMDGPUMCKernelCodeT::PrintHelper Helper) { \
266 OS << Name << " = "; \
267 auto [Shift, Mask] = getShiftMask(Complement); \
268 const MCExpr *Value; \
269 if (PGMType == 0) { \
271 maskShiftGet(C.compute_pgm_resource1_registers, Mask, Shift, Ctx); \
274 maskShiftGet(C.compute_pgm_resource2_registers, Mask, Shift, Ctx); \
276 Helper(Value, OS, Ctx.getAsmInfo()); \
278#define RECORD(name, altName, print, parse) print
289 Err <<
"expected '='";
295 Err <<
"integer absolute expression expected";
301template <
typename T, T AMDGPUMCKernelCodeT::*ptr>
311template <
typename T, T AMDGPUMCKernelCodeT::*ptr,
int shift,
int w
idth = 1>
317 const uint64_t Mask = ((UINT64_C(1) << width) - 1) << shift;
319 C.*ptr |= (
T)((
Value << shift) & Mask);
326 Err <<
"expected '='";
332 Err <<
"Could not parse expression";
341 static const ParseFx Table[] = {
342#define COMPPGM1(name, aname, AccMacro) \
343 COMPPGM(name, aname, G_00B848_##AccMacro, C_00B848_##AccMacro, 0)
344#define COMPPGM2(name, aname, AccMacro) \
345 COMPPGM(name, aname, G_00B84C_##AccMacro, C_00B84C_##AccMacro, 32)
346#define PARSECOMP(Complement, PGMType) \
347 [](AMDGPUMCKernelCodeT &C, MCAsmParser &MCParser, \
348 raw_ostream &Err) -> bool { \
349 MCContext &Ctx = MCParser.getContext(); \
350 const MCExpr *Value; \
351 if (!parseExpr(MCParser, Value, Err)) \
353 auto [Shift, Mask] = getShiftMask(Complement); \
354 Value = maskShiftSet(Value, Mask, Shift, Ctx); \
355 const MCExpr *Compl = MCConstantExpr::create(Complement, Ctx); \
356 if (PGMType == 0) { \
357 C.compute_pgm_resource1_registers = MCBinaryExpr::createAnd( \
358 C.compute_pgm_resource1_registers, Compl, Ctx); \
359 C.compute_pgm_resource1_registers = MCBinaryExpr::createOr( \
360 C.compute_pgm_resource1_registers, Value, Ctx); \
362 C.compute_pgm_resource2_registers = MCBinaryExpr::createAnd( \
363 C.compute_pgm_resource2_registers, Compl, Ctx); \
364 C.compute_pgm_resource2_registers = MCBinaryExpr::createOr( \
365 C.compute_pgm_resource2_registers, Value, Ctx); \
369#define RECORD(name, altName, print, parse) parse
409 Ctx.
reportError({},
"enable_dx10_clamp=1 is not allowed on GFX12+");
414 Ctx.
reportError({},
"enable_ieee_mode=1 is not allowed on GFX12+");
419 Ctx.
reportError({},
"enable_wgp_mode=1 is only allowed on GFX10+");
424 Ctx.
reportError({},
"enable_mem_ordered=1 is only allowed on GFX10+");
429 Ctx.
reportError({},
"enable_fwd_progress=1 is only allowed on GFX10+");
436 return IndexTable[Index](*this);
443 Err <<
"unexpected amd_kernel_code_t field name " <<
ID;
455 return Parser ? Parser(*
this, MCParser, Err) :
false;
461 for (
int i = 0; i <
Size; ++i) {
506 OS.emitValue(CodeProps, 4);
513 OS.emitIntValue(0, 4);
523 OS.emitIntValue(0, 2);
528 OS.emitIntValue(0, 2);
static void printBitField(StringRef Name, const AMDGPUMCKernelCodeT &C, raw_ostream &OS, MCContext &, AMDGPUMCKernelCodeT::PrintHelper)
static ArrayRef< StringLiteral > get_amd_kernel_code_t_FldNames()
static ArrayRef< StringLiteral > get_amd_kernel_code_t_FldAltNames()
static ArrayRef< bool > hasMCExprVersionTable()
static bool expectAbsExpression(MCAsmParser &MCParser, int64_t &Value, raw_ostream &Err)
void(*)(StringRef, const AMDGPUMCKernelCodeT &, raw_ostream &, MCContext &, AMDGPUMCKernelCodeT::PrintHelper Helper) PrintFx
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 void printAmdKernelCodeField(const AMDGPUMCKernelCodeT &C, int FldIndex, raw_ostream &OS, MCContext &Ctx, AMDGPUMCKernelCodeT::PrintHelper Helper)
static ArrayRef< PrintFx > getPrinterTable(AMDGPUMCKernelCodeT::PrintHelper Helper)
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
#define G_00B848_FWD_PROGRESS(x)
#define G_00B848_MEM_ORDERED(x)
#define G_00B848_IEEE_MODE(x)
#define G_00B848_DX10_CLAMP(x)
#define G_00B848_WGP_MODE(x)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static void printField(StringRef Name, const AMDGPUMCKernelCodeT &C, raw_ostream &OS, MCContext &Ctx, AMDGPUMCKernelCodeT::PrintHelper Helper)
static void printField(StringRef Name, const AMDGPUMCKernelCodeT &C, raw_ostream &OS, MCContext &, AMDGPUMCKernelCodeT::PrintHelper)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
bool isNot(AsmToken::TokenKind K) const
Check if the current token has kind K.
const AsmToken & Lex()
Consume the next token from the input stream and return it.
Generic assembler parser interface, for use by target specific assembly parsers.
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 * createOr(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
const MCAsmInfo * getAsmInfo() const
void reportError(SMLoc L, const Twine &Msg)
Base class for the full range of assembler expressions which are needed for parsing.
Streaming machine code generation interface.
Generic base class for all target subtargets.
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
StringRef - Represent a constant reference to a string, i.e.
LLVM Value Representation.
An efficient, type-erasing, non-owning reference to a callable.
This class implements an extremely fast bulk output stream that can only output to a stream.
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)
@ C
The default llvm calling convention, compatible with C.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
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.
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
uint16_t reserved_vgpr_first
uint16_t reserved_vgpr_count
uint16_t amd_machine_version_major
uint16_t amd_machine_kind
uint64_t kernarg_segment_byte_size
uint16_t amd_machine_version_stepping
uint8_t private_segment_alignment
uint16_t debug_wavefront_private_segment_offset_sgpr
int64_t kernel_code_entry_byte_offset
uint64_t control_directives[16]
const MCExpr * workitem_private_segment_byte_size
uint16_t debug_private_segment_buffer_sgpr
uint32_t amd_kernel_code_version_major
void EmitKernelCodeT(raw_ostream &OS, MCContext &Ctx, PrintHelper Helper)
const MCExpr * compute_pgm_resource2_registers
uint16_t amd_machine_version_minor
uint32_t gds_segment_byte_size
uint8_t group_segment_alignment
uint32_t workgroup_fbarrier_count
uint8_t kernarg_segment_alignment
uint16_t reserved_sgpr_first
void validate(const MCSubtargetInfo *STI, MCContext &Ctx)
AMDGPUMCKernelCodeT()=default
uint32_t amd_kernel_code_version_minor
const MCExpr * wavefront_sgpr_count
void initDefault(const MCSubtargetInfo *STI, MCContext &Ctx, bool InitMCExpr=true)
uint16_t reserved_sgpr_count
uint64_t kernel_code_prefetch_byte_size
const MCExpr * workitem_vgpr_count
const MCExpr * is_dynamic_callstack
int64_t kernel_code_prefetch_byte_offset
uint32_t workgroup_group_segment_byte_size
bool ParseKernelCodeT(StringRef ID, MCAsmParser &MCParser, raw_ostream &Err)
uint64_t runtime_loader_kernel_symbol
const MCExpr *& getMCExprForIndex(int Index)
const MCExpr * compute_pgm_resource1_registers
uint64_t compute_pgm_resource_registers