42#define GEN_HAS_MEMBER(member) \
43 class HasMember##member { \
45 struct KnownWithMember { \
48 class AmbiguousDerived : public AMDGPUMCKernelCodeT, \
49 public KnownWithMember {}; \
50 template <typename U> \
51 static constexpr std::false_type Test(decltype(U::member) *); \
52 template <typename U> static constexpr std::true_type Test(...); \
55 static constexpr bool RESULT = \
56 std::is_same_v<decltype(Test<AmbiguousDerived>(nullptr)), \
59 class IsMCExpr##member { \
60 template <typename U, \
61 typename std::enable_if_t< \
62 HasMember##member::RESULT && \
63 std::is_same_v<decltype(U::member), const MCExpr *>, \
65 static constexpr std::true_type HasMCExprType(decltype(U::member) *); \
66 template <typename U> static constexpr std::false_type HasMCExprType(...); \
69 static constexpr bool RESULT = \
70 std::is_same_v<decltype(HasMCExprType<AMDGPUMCKernelCodeT>(nullptr)), \
73 class GetMember##member { \
75 static const MCExpr *Phony; \
76 template <typename U, typename std::enable_if_t<IsMCExpr##member::RESULT, \
78 static const MCExpr *&Get(U &C) { \
79 assert(IsMCExpr##member::RESULT && \
80 "Trying to retrieve member that does not exist."); \
83 template <typename U, typename std::enable_if_t<!IsMCExpr##member::RESULT, \
85 static const MCExpr *&Get(U &C) { \
89 const MCExpr *GetMember##member::Phony = nullptr;
170#define RECORD(name, altName, print, parse) #name
180#define RECORD(name, altName, print, parse) #altName
188 static bool const Table[] = {
189#define RECORD(name, altName, print, parse) (IsMCExpr##name::RESULT)
200#define RECORD(name, altName, print, parse) GetMember##name::Get
211 for (
unsigned i = 0; i < names.
size(); ++i) {
212 map.
insert(std::pair(names[i], i));
213 map.
insert(std::pair(altNames[i], i));
221 return map.lookup(
name) - 1;
227 typename std::enable_if_t<!std::is_integral_v<T>,
T> * =
nullptr>
237 typename std::enable_if_t<std::is_integral_v<T>,
T> * =
nullptr>
241 OS <<
Name <<
" = " << (int)(
C.*ptr);
245template <
typename T, T AMDGPUMCKernelCodeT::*ptr,
int shift,
int w
idth = 1>
249 const auto Mask = (
static_cast<T>(1) << width) - 1;
250 OS <<
Name <<
" = " << (int)((
C.*ptr >> shift) & Mask);
258 static const PrintFx Table[] = {
259#define COMPPGM1(name, aname, AccMacro) \
260 COMPPGM(name, aname, C_00B848_##AccMacro, S_00B848_##AccMacro, 0)
261#define COMPPGM2(name, aname, AccMacro) \
262 COMPPGM(name, aname, C_00B84C_##AccMacro, S_00B84C_##AccMacro, 32)
263#define PRINTFIELD(sname, aname, name) PrintField::printField<FLD_T(name)>
264#define PRINTCOMP(Complement, PGMType) \
265 [](StringRef Name, const AMDGPUMCKernelCodeT &C, raw_ostream &OS, \
266 MCContext &Ctx, AMDGPUMCKernelCodeT::PrintHelper Helper) { \
267 OS << Name << " = "; \
268 auto [Shift, Mask] = getShiftMask(Complement); \
269 const MCExpr *Value; \
270 if (PGMType == 0) { \
272 maskShiftGet(C.compute_pgm_resource1_registers, Mask, Shift, Ctx); \
275 maskShiftGet(C.compute_pgm_resource2_registers, Mask, Shift, Ctx); \
277 Helper(Value, OS, Ctx.getAsmInfo()); \
279#define RECORD(name, altName, print, parse) print
290 Err <<
"expected '='";
296 Err <<
"integer absolute expression expected";
302template <
typename T, T AMDGPUMCKernelCodeT::*ptr>
312template <
typename T, T AMDGPUMCKernelCodeT::*ptr,
int shift,
int w
idth = 1>
318 const uint64_t Mask = ((UINT64_C(1) << width) - 1) << shift;
320 C.*ptr |= (
T)((
Value << shift) & Mask);
327 Err <<
"expected '='";
333 Err <<
"Could not parse expression";
342 static const ParseFx Table[] = {
343#define COMPPGM1(name, aname, AccMacro) \
344 COMPPGM(name, aname, G_00B848_##AccMacro, C_00B848_##AccMacro, 0)
345#define COMPPGM2(name, aname, AccMacro) \
346 COMPPGM(name, aname, G_00B84C_##AccMacro, C_00B84C_##AccMacro, 32)
347#define PARSECOMP(Complement, PGMType) \
348 [](AMDGPUMCKernelCodeT &C, MCAsmParser &MCParser, \
349 raw_ostream &Err) -> bool { \
350 MCContext &Ctx = MCParser.getContext(); \
351 const MCExpr *Value; \
352 if (!parseExpr(MCParser, Value, Err)) \
354 auto [Shift, Mask] = getShiftMask(Complement); \
355 Value = maskShiftSet(Value, Mask, Shift, Ctx); \
356 const MCExpr *Compl = MCConstantExpr::create(Complement, Ctx); \
357 if (PGMType == 0) { \
358 C.compute_pgm_resource1_registers = MCBinaryExpr::createAnd( \
359 C.compute_pgm_resource1_registers, Compl, Ctx); \
360 C.compute_pgm_resource1_registers = MCBinaryExpr::createOr( \
361 C.compute_pgm_resource1_registers, Value, Ctx); \
363 C.compute_pgm_resource2_registers = MCBinaryExpr::createAnd( \
364 C.compute_pgm_resource2_registers, Compl, Ctx); \
365 C.compute_pgm_resource2_registers = MCBinaryExpr::createOr( \
366 C.compute_pgm_resource2_registers, Value, Ctx); \
370#define RECORD(name, altName, print, parse) parse
410 Ctx.
reportError({},
"enable_dx10_clamp=1 is not allowed on GFX12+");
415 Ctx.
reportError({},
"enable_ieee_mode=1 is not allowed on GFX12+");
420 Ctx.
reportError({},
"enable_wgp_mode=1 is only allowed on GFX10+");
425 Ctx.
reportError({},
"enable_mem_ordered=1 is only allowed on GFX10+");
430 Ctx.
reportError({},
"enable_fwd_progress=1 is only allowed on GFX10+");
437 return IndexTable[
Index](*this);
444 Err <<
"unexpected amd_kernel_code_t field name " <<
ID;
456 return Parser ? Parser(*
this, MCParser, Err) :
false;
462 for (
int i = 0; i <
Size; ++i) {
507 OS.emitValue(CodeProps, 4);
514 OS.emitIntValue(0, 4);
524 OS.emitIntValue(0, 2);
529 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
This file implements an indexed map.
#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)
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
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