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>
233 if (
Value->evaluateAsAbsolute(Val))
240 typename std::enable_if_t<std::is_integral_v<T>,
T> * =
nullptr>
243 OS <<
Name <<
" = " << (int)(
C.*ptr);
247template <
typename T, T AMDGPUMCKernelCodeT::*ptr,
int shift,
int w
idth = 1>
250 const auto Mask = (
static_cast<T>(1) << width) - 1;
251 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, \
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); \
278 if (Value->evaluateAsAbsolute(Val)) \
281 Value->print(OS, Ctx.getAsmInfo()); \
283#define RECORD(name, altName, print, parse) print
294 Err <<
"expected '='";
300 Err <<
"integer absolute expression expected";
306template <
typename T, T AMDGPUMCKernelCodeT::*ptr>
316template <
typename T, T AMDGPUMCKernelCodeT::*ptr,
int shift,
int w
idth = 1>
322 const uint64_t Mask = ((UINT64_C(1) << width) - 1) << shift;
324 C.*ptr |= (
T)((
Value << shift) & Mask);
331 Err <<
"expected '='";
337 Err <<
"Could not parse expression";
346 static const ParseFx Table[] = {
347#define COMPPGM1(name, aname, AccMacro) \
348 COMPPGM(name, aname, G_00B848_##AccMacro, C_00B848_##AccMacro, 0)
349#define COMPPGM2(name, aname, AccMacro) \
350 COMPPGM(name, aname, G_00B84C_##AccMacro, C_00B84C_##AccMacro, 32)
351#define PARSECOMP(Complement, PGMType) \
352 [](AMDGPUMCKernelCodeT &C, MCAsmParser &MCParser, \
353 raw_ostream &Err) -> bool { \
354 MCContext &Ctx = MCParser.getContext(); \
355 const MCExpr *Value; \
356 if (!parseExpr(MCParser, Value, Err)) \
358 auto [Shift, Mask] = getShiftMask(Complement); \
359 Value = maskShiftSet(Value, Mask, Shift, Ctx); \
360 const MCExpr *Compl = MCConstantExpr::create(Complement, Ctx); \
361 if (PGMType == 0) { \
362 C.compute_pgm_resource1_registers = MCBinaryExpr::createAnd( \
363 C.compute_pgm_resource1_registers, Compl, Ctx); \
364 C.compute_pgm_resource1_registers = MCBinaryExpr::createOr( \
365 C.compute_pgm_resource1_registers, Value, Ctx); \
367 C.compute_pgm_resource2_registers = MCBinaryExpr::createAnd( \
368 C.compute_pgm_resource2_registers, Compl, Ctx); \
369 C.compute_pgm_resource2_registers = MCBinaryExpr::createOr( \
370 C.compute_pgm_resource2_registers, Value, Ctx); \
374#define RECORD(name, altName, print, parse) parse
413 Ctx.
reportError({},
"enable_dx10_clamp=1 is not allowed on GFX12+");
418 Ctx.
reportError({},
"enable_ieee_mode=1 is not allowed on GFX12+");
423 Ctx.
reportError({},
"enable_wgp_mode=1 is only allowed on GFX10+");
428 Ctx.
reportError({},
"enable_mem_ordered=1 is only allowed on GFX10+");
433 Ctx.
reportError({},
"enable_fwd_progress=1 is only allowed on GFX10+");
440 return IndexTable[
Index](*this);
447 Err <<
"unexpected amd_kernel_code_t field name " <<
ID;
459 return Parser ? Parser(*
this, MCParser, Err) :
false;
464 for (
int i = 0; i <
Size; ++i) {
470 if (
Value->evaluateAsAbsolute(Val))
513 OS.emitValue(CodeProps, 4);
520 OS.emitIntValue(0, 4);
530 OS.emitIntValue(0, 2);
535 OS.emitIntValue(0, 2);
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 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 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)
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),...
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.
void print(raw_ostream &O, bool IsForDebug=false) const
Implement operator<< on Value.
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
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
void EmitKernelCodeT(raw_ostream &OS, MCContext &Ctx)
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