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;

296 C.*ptr &= (T)~Mask;

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