LLVM: lib/Target/AMDGPU/Utils/AMDKernelCodeTUtils.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
26
27using namespace llvm;
29
30
31
32
33
34
35
36
37
38
39
40
41#define GEN_HAS_MEMBER(member) \
42 class HasMember##member { \
43 template \
44 using check_member = decltype(std::declval().member); \
45 \
46 public: \
47 static constexpr bool RESULT = \
48 llvm::is_detected<check_member, AMDGPUMCKernelCodeT>::value; \
49 }; \
50 class IsMCExpr##member { \
51 template \
52 static constexpr auto HasMCExprType(int) -> std::bool_constant< \
53 HasMember##member::RESULT && \
54 std::is_same_v<decltype(U::member), const MCExpr *>>; \
55 template static constexpr std::false_type HasMCExprType(...); \
56 \
57 public: \
58 static constexpr bool RESULT = \
59 decltype(HasMCExprType(0))::value; \
60 }; \
61 class GetMember##member { \
62 public: \
63 static const MCExpr *Phony; \
64 template static const MCExpr *&Get(U &C) { \
65 if constexpr (IsMCExpr##member::RESULT) \
66 return C.member; \
67 else \
68 return Phony; \
69 } \
70 }; \
71 const MCExpr *GetMember##member::Phony = nullptr;
72
73
74
75
76
83
86
98
99GEN_HAS_MEMBER(enable_sgpr_private_segment_wave_byte_offset)
110
128
140GEN_HAS_MEMBER(debug_wavefront_private_segment_offset_sgpr)
148
151 "",
152#define RECORD(name, altName, print, parse) #name
154#undef RECORD
155 };
157}
158
161 "",
162#define RECORD(name, altName, print, parse) #altName
164#undef RECORD
165 };
167}
168
170 static bool const Table[] = {
171#define RECORD(name, altName, print, parse) (IsMCExpr##name::RESULT)
173#undef RECORD
174 };
176}
177
179
182#define RECORD(name, altName, print, parse) GetMember##name::Get
184#undef RECORD
185 };
187}
188
193 for (unsigned i = 0; i < names.size(); ++i) {
194 map.insert(std::pair(names[i], i));
195 map.insert(std::pair(altNames[i], i));
196 }
197 return map;
198}
199
201 static const auto map = createIndexMap(get_amd_kernel_code_t_FldNames(),
202 get_amd_kernel_code_t_FldAltNames());
203 return map.lookup(name) - 1;
204}
205
207public:
208 template <typename T, T AMDGPUMCKernelCodeT::*ptr>
212 if constexpr (!std::is_integral_v) {
213 OS << Name << " = ";
215 Helper(Value, OS, Ctx.getAsmInfo());
216 } else {
217 OS << Name << " = " << (int)(C.*ptr);
218 }
219 }
220};
221
222template <typename T, T AMDGPUMCKernelCodeT::*ptr, int shift, int width = 1>
226 const auto Mask = (static_cast<T>(1) << width) - 1;
227 OS << Name << " = " << (int)((C.*ptr >> shift) & Mask);
228}
229
232
235 static const PrintFx Table[] = {
236#define COMPPGM1(name, aname, AccMacro) \
237 COMPPGM(name, aname, C_00B848_##AccMacro, S_00B848_##AccMacro, 0)
238#define COMPPGM2(name, aname, AccMacro) \
239 COMPPGM(name, aname, C_00B84C_##AccMacro, S_00B84C_##AccMacro, 32)
240#define PRINTFIELD(sname, aname, name) PrintField::printField<FLD_T(name)>
241#define PRINTCOMP(Complement, PGMType) \
242 [](StringRef Name, const AMDGPUMCKernelCodeT &C, raw_ostream &OS, \
243 MCContext &Ctx, AMDGPUMCKernelCodeT::PrintHelper Helper) { \
244 OS << Name << " = "; \
245 auto [Shift, Mask] = getShiftMask(Complement); \
246 const MCExpr *Value; \
247 if (PGMType == 0) { \
248 Value = \
249 maskShiftGet(C.compute_pgm_resource1_registers, Mask, Shift, Ctx); \
250 } else { \
251 Value = \
252 maskShiftGet(C.compute_pgm_resource2_registers, Mask, Shift, Ctx); \
253 } \
254 Helper(Value, OS, Ctx.getAsmInfo()); \
255 }
256#define RECORD(name, altName, print, parse) print
258#undef RECORD
259 };
261}
262
265
267 Err << "expected '='";
268 return false;
269 }
271
273 Err << "integer absolute expression expected";
274 return false;
275 }
276 return true;
277}
278
279template <typename T, T AMDGPUMCKernelCodeT::*ptr>
282 int64_t Value = 0;
284 return false;
286 return true;
287}
288
289template <typename T, T AMDGPUMCKernelCodeT::*ptr, int shift, int width = 1>
292 int64_t Value = 0;
294 return false;
295 const uint64_t Mask = ((UINT64_C(1) << width) - 1) << shift;
297 C.*ptr |= (T)((Value << shift) & Mask);
298 return true;
299}
300
304 Err << "expected '='";
305 return false;
306 }
308
310 Err << "Could not parse expression";
311 return false;
312 }
313 return true;
314}
315
317
319 static const ParseFx Table[] = {
320#define COMPPGM1(name, aname, AccMacro) \
321 COMPPGM(name, aname, G_00B848_##AccMacro, C_00B848_##AccMacro, 0)
322#define COMPPGM2(name, aname, AccMacro) \
323 COMPPGM(name, aname, G_00B84C_##AccMacro, C_00B84C_##AccMacro, 32)
324#define PARSECOMP(Complement, PGMType) \
325 [](AMDGPUMCKernelCodeT &C, MCAsmParser &MCParser, \
326 raw_ostream &Err) -> bool { \
327 MCContext &Ctx = MCParser.getContext(); \
328 const MCExpr *Value; \
329 if (!parseExpr(MCParser, Value, Err)) \
330 return false; \
331 auto [Shift, Mask] = getShiftMask(Complement); \
332 Value = maskShiftSet(Value, Mask, Shift, Ctx); \
333 const MCExpr *Compl = MCConstantExpr::create(Complement, Ctx); \
334 if (PGMType == 0) { \
335 C.compute_pgm_resource1_registers = MCBinaryExpr::createAnd( \
336 C.compute_pgm_resource1_registers, Compl, Ctx); \
337 C.compute_pgm_resource1_registers = MCBinaryExpr::createOr( \
338 C.compute_pgm_resource1_registers, Value, Ctx); \
339 } else { \
340 C.compute_pgm_resource2_registers = MCBinaryExpr::createAnd( \
341 C.compute_pgm_resource2_registers, Compl, Ctx); \
342 C.compute_pgm_resource2_registers = MCBinaryExpr::createOr( \
343 C.compute_pgm_resource2_registers, Value, Ctx); \
344 } \
345 return true; \
346 }
347#define RECORD(name, altName, print, parse) parse
349#undef RECORD
350 };
352}
353
357 auto Printer = getPrinterTable(Helper)[FldIndex];
359 Printer(get_amd_kernel_code_t_FldNames()[FldIndex + 1], C, OS, Ctx, Helper);
360}
361
363 MCContext &Ctx, bool InitMCExpr) {
365
367
368 if (InitMCExpr) {
378 }
379}
380
384 return;
385
387 Ctx.reportError({}, "enable_dx10_clamp=1 is not allowed on GFX12+");
388 return;
389 }
390
392 Ctx.reportError({}, "enable_ieee_mode=1 is not allowed on GFX12+");
393 return;
394 }
395
397 Ctx.reportError({}, "enable_wgp_mode=1 is only allowed on GFX10+");
398 return;
399 }
400
402 Ctx.reportError({}, "enable_mem_ordered=1 is only allowed on GFX10+");
403 return;
404 }
405
407 Ctx.reportError({}, "enable_fwd_progress=1 is only allowed on GFX10+");
408 return;
409 }
410}
411
413 static const auto IndexTable = getMCExprIndexTable();
414 return IndexTable[Index](*this);
415}
416
420 if (Idx < 0) {
421 Err << "unexpected amd_kernel_code_t field name " << ID;
422 return false;
423 }
424
425 if (hasMCExprVersionTable()[Idx]) {
428 return false;
430 return true;
431 }
432 auto Parser = getParserTable()[Idx];
433 return Parser && Parser(*this, MCParser, Err);
434}
435
438 const int Size = hasMCExprVersionTable().size();
439 for (int i = 0; i < Size; ++i) {
440 OS << "\t\t";
441 if (hasMCExprVersionTable()[i]) {
442 OS << get_amd_kernel_code_t_FldNames()[i + 1] << " = ";
444 Helper(Value, OS, Ctx.getAsmInfo());
445 } else {
447 }
448 OS << '\n';
449 }
450}
451
463
466 else
468 4);
469
472 else
474 4);
475
479 CodeProps,
483 Ctx);
484 OS.emitValue(CodeProps, 4);
485 } else
487
490 else
492
497
500 else
502
505 else
507
513 2);
519
524}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static void printBitField(StringRef Name, const AMDGPUMCKernelCodeT &C, raw_ostream &OS, MCContext &, AMDGPUMCKernelCodeT::PrintHelper)
Definition AMDKernelCodeTUtils.cpp:223
static bool expectAbsExpression(MCAsmParser &MCParser, int64_t &Value, raw_ostream &Err)
Definition AMDKernelCodeTUtils.cpp:263
static bool parseExpr(MCAsmParser &MCParser, const MCExpr *&Value, raw_ostream &Err)
Definition AMDKernelCodeTUtils.cpp:301
static bool parseField(AMDGPUMCKernelCodeT &C, MCAsmParser &MCParser, raw_ostream &Err)
Definition AMDKernelCodeTUtils.cpp:280
const MCExpr *&(*)(AMDGPUMCKernelCodeT &) RetrieveFx
Definition AMDKernelCodeTUtils.cpp:178
void(*)(StringRef, const AMDGPUMCKernelCodeT &, raw_ostream &, MCContext &, AMDGPUMCKernelCodeT::PrintHelper Helper) PrintFx
Definition AMDKernelCodeTUtils.cpp:230
bool(*)(AMDGPUMCKernelCodeT &, MCAsmParser &, raw_ostream &) ParseFx
Definition AMDKernelCodeTUtils.cpp:316
#define GEN_HAS_MEMBER(member)
Definition AMDKernelCodeTUtils.cpp:41
static bool parseBitField(AMDGPUMCKernelCodeT &C, MCAsmParser &MCParser, raw_ostream &Err)
Definition AMDKernelCodeTUtils.cpp:290
static void printAmdKernelCodeField(const AMDGPUMCKernelCodeT &C, int FldIndex, raw_ostream &OS, MCContext &Ctx, AMDGPUMCKernelCodeT::PrintHelper Helper)
Definition AMDKernelCodeTUtils.cpp:354
static StringMap< int > createIndexMap(ArrayRef< StringLiteral > names, ArrayRef< StringLiteral > altNames)
Definition AMDKernelCodeTUtils.cpp:189
static int get_amd_kernel_code_t_FieldIndex(StringRef name)
Definition AMDKernelCodeTUtils.cpp:200
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 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)
static void printField(StringRef Name, const AMDGPUMCKernelCodeT &C, raw_ostream &OS, MCContext &Ctx, AMDGPUMCKernelCodeT::PrintHelper Helper)
Definition AMDKernelCodeTUtils.cpp:209
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
const AsmToken & Lex()
Consume the next token from the input stream and return it.
bool isNot(AsmToken::TokenKind K) const
Check if the current token has kind K.
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 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 LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
Base class for the full range of assembler expressions which are needed for parsing.
Streaming machine code generation interface.
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...
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.
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.
ArrayRef(const T &OneElt) -> ArrayRef< T >
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
function_ref< void(const MCExpr *, raw_ostream &, const MCAsmInfo *)> PrintHelper
void EmitKernelCodeT(raw_ostream &OS, MCContext &Ctx, PrintHelper Helper)
Definition AMDKernelCodeTUtils.cpp:436
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)
Definition AMDKernelCodeTUtils.cpp:381
AMDGPUMCKernelCodeT()=default
uint32_t amd_kernel_code_version_minor
const MCExpr * wavefront_sgpr_count
void initDefault(const MCSubtargetInfo *STI, MCContext &Ctx, bool InitMCExpr=true)
Definition AMDKernelCodeTUtils.cpp:362
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)
Definition AMDKernelCodeTUtils.cpp:417
uint64_t runtime_loader_kernel_symbol
const MCExpr *& getMCExprForIndex(int Index)
Definition AMDKernelCodeTUtils.cpp:412
const MCExpr * compute_pgm_resource1_registers
uint64_t compute_pgm_resource_registers