LLVM 24.0.0git
AMDGPUDisassembler.cpp
Go to the documentation of this file.
1//===- AMDGPUDisassembler.cpp - Disassembler for AMDGPU ISA ---------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9//===----------------------------------------------------------------------===//
10//
11/// \file
12///
13/// This file contains definition for AMDGPU ISA disassembler
14//
15//===----------------------------------------------------------------------===//
16
17// ToDo: What to do with instruction suffixes (v_mov_b32 vs v_mov_b32_e32)?
18
22#include "SIDefines.h"
23#include "SIRegisterInfo.h"
29#include "llvm/MC/MCAsmInfo.h"
30#include "llvm/MC/MCContext.h"
31#include "llvm/MC/MCDecoder.h"
33#include "llvm/MC/MCExpr.h"
34#include "llvm/MC/MCInstrDesc.h"
40
41using namespace llvm;
42using namespace llvm::MCD;
43
44#define DEBUG_TYPE "amdgpu-disassembler"
45
46#define SGPR_MAX \
47 (isGFX10Plus() ? AMDGPU::EncValues::SGPR_MAX_GFX10 \
48 : AMDGPU::EncValues::SGPR_MAX_SI)
49
51
52static int64_t getInlineImmValF16(unsigned Imm);
53static int64_t getInlineImmValBF16(unsigned Imm);
54static int64_t getInlineImmVal32(unsigned Imm);
55static int64_t getInlineImmVal64(unsigned Imm);
56
58 MCContext &Ctx, MCInstrInfo const *MCII)
59 : MCDisassembler(STI, Ctx), MCII(MCII), MRI(*Ctx.getRegisterInfo()),
60 MAI(Ctx.getAsmInfo()),
61 HwModeRegClass(STI.getHwMode(MCSubtargetInfo::HwMode_RegInfo)),
62 TargetMaxInstBytes(MAI.getMaxInstLength(&STI)),
63 CodeObjectVersion(AMDGPU::getDefaultAMDHSACodeObjectVersion()) {
64 // ToDo: AMDGPUDisassembler supports only VI ISA.
65 if (!STI.hasFeature(AMDGPU::FeatureGCN3Encoding) && !isGFX10Plus())
66 reportFatalUsageError("disassembly not yet supported for subtarget");
67
68 for (auto [Symbol, Code] : AMDGPU::UCVersion::getGFXVersions())
69 createConstantSymbolExpr(Symbol, Code);
70
71 UCVersionW64Expr = createConstantSymbolExpr("UC_VERSION_W64_BIT", 0x2000);
72 UCVersionW32Expr = createConstantSymbolExpr("UC_VERSION_W32_BIT", 0x4000);
73 UCVersionMDPExpr = createConstantSymbolExpr("UC_VERSION_MDP_BIT", 0x8000);
74}
75
79
81 unsigned EFlags) const {
82 OS << "\t.amdgcn_target \""
83 << STI.getTargetTriple().normalize(Triple::CanonicalForm::FOUR_IDENT)
84 << '-';
85
86 // Get CPU name from ELF e_flags MACH field
87 unsigned MACH = EFlags & ELF::EF_AMDGPU_MACH;
88
89#define X(NUM, ENUM, NAME) \
90 case ELF::ENUM: \
91 OS << NAME; \
92 break;
93 switch (MACH) {
95 default:
96 OS << "unknown";
97 break;
98 }
99#undef X
100
101 // Add xnack and sramecc from ELF flags (v4 format)
102 if (CodeObjectVersion >= AMDGPU::AMDHSA_COV4) {
103 unsigned SrameccSetting = EFlags & ELF::EF_AMDGPU_FEATURE_SRAMECC_V4;
104 switch (SrameccSetting) {
107 break;
109 OS << ":sramecc-";
110 break;
112 OS << ":sramecc+";
113 break;
114 }
115
117 switch (XnackSetting) {
120 break;
122 OS << ":xnack-";
123 break;
125 OS << ":xnack+";
126 break;
127 }
128 }
129
130 OS << "\"\n";
131}
132
134addOperand(MCInst &Inst, const MCOperand& Opnd) {
135 Inst.addOperand(Opnd);
136 return Opnd.isValid() ?
139}
140
142 AMDGPU::OpName Name) {
143 int OpIdx = AMDGPU::getNamedOperandIdx(MI.getOpcode(), Name);
144 if (OpIdx != -1) {
145 auto *I = MI.begin();
146 std::advance(I, OpIdx);
147 MI.insert(I, Op);
148 }
149 return OpIdx;
150}
151
152static DecodeStatus decodeSOPPBrTarget(MCInst &Inst, unsigned Imm,
153 uint64_t Addr,
154 const MCDisassembler *Decoder) {
155 const auto *DAsm = static_cast<const AMDGPUDisassembler *>(Decoder);
156
157 // Our branches take a simm16.
158 int64_t Offset = SignExtend64<16>(Imm) * 4 + 4 + Addr;
159
160 if (DAsm->tryAddingSymbolicOperand(Inst, Offset, Addr, true, 2, 2, 0))
162 return addOperand(Inst, MCOperand::createImm(Imm));
163}
164
165static DecodeStatus decodeSMEMOffset(MCInst &Inst, unsigned Imm, uint64_t Addr,
166 const MCDisassembler *Decoder) {
167 const auto *DAsm = static_cast<const AMDGPUDisassembler *>(Decoder);
168 int64_t Offset;
169 if (DAsm->isGFX12Plus()) { // GFX12 supports 24-bit signed offsets.
171 } else if (DAsm->isVI()) { // VI supports 20-bit unsigned offsets.
172 Offset = Imm & 0xFFFFF;
173 } else { // GFX9+ supports 21-bit signed offsets.
175 }
177}
178
179static DecodeStatus decodeBoolReg(MCInst &Inst, unsigned Val, uint64_t Addr,
180 const MCDisassembler *Decoder) {
181 const auto *DAsm = static_cast<const AMDGPUDisassembler *>(Decoder);
182 return addOperand(Inst, DAsm->decodeBoolReg(Inst, Val));
183}
184
185static DecodeStatus decodeSplitBarrier(MCInst &Inst, unsigned Val,
186 uint64_t Addr,
187 const MCDisassembler *Decoder) {
188 const auto *DAsm = static_cast<const AMDGPUDisassembler *>(Decoder);
189 return addOperand(Inst, DAsm->decodeSplitBarrier(Inst, Val));
190}
191
192static DecodeStatus decodeDpp8FI(MCInst &Inst, unsigned Val, uint64_t Addr,
193 const MCDisassembler *Decoder) {
194 const auto *DAsm = static_cast<const AMDGPUDisassembler *>(Decoder);
195 return addOperand(Inst, DAsm->decodeDpp8FI(Val));
196}
197
198#define DECODE_OPERAND(StaticDecoderName, DecoderName) \
199 static DecodeStatus StaticDecoderName(MCInst &Inst, unsigned Imm, \
200 uint64_t /*Addr*/, \
201 const MCDisassembler *Decoder) { \
202 auto DAsm = static_cast<const AMDGPUDisassembler *>(Decoder); \
203 return addOperand(Inst, DAsm->DecoderName(Imm)); \
204 }
205
206// Decoder for registers, decode directly using RegClassID. Imm(8-bit) is
207// number of register. Used by VGPR only and AGPR only operands.
208#define DECODE_OPERAND_REG_8(RegClass) \
209 static DecodeStatus Decode##RegClass##RegisterClass( \
210 MCInst &Inst, unsigned Imm, uint64_t /*Addr*/, \
211 const MCDisassembler *Decoder) { \
212 assert(Imm < (1 << 8) && "8-bit encoding"); \
213 auto DAsm = static_cast<const AMDGPUDisassembler *>(Decoder); \
214 return addOperand( \
215 Inst, DAsm->createRegOperand(AMDGPU::RegClass##RegClassID, Imm)); \
216 }
217
218#define DECODE_SrcOp(Name, EncSize, OpWidth, EncImm) \
219 static DecodeStatus Name(MCInst &Inst, unsigned Imm, uint64_t /*Addr*/, \
220 const MCDisassembler *Decoder) { \
221 if (!isUInt<EncSize>(Imm)) \
222 return MCDisassembler::Fail; \
223 auto DAsm = static_cast<const AMDGPUDisassembler *>(Decoder); \
224 return addOperand(Inst, DAsm->decodeSrcOp(Inst, OpWidth, EncImm)); \
225 }
226
227static DecodeStatus decodeSrcOp(MCInst &Inst, unsigned EncSize,
228 unsigned OpWidth, unsigned Imm, unsigned EncImm,
229 const MCDisassembler *Decoder) {
230 assert(Imm < (1U << EncSize) && "Operand doesn't fit encoding!");
231 const auto *DAsm = static_cast<const AMDGPUDisassembler *>(Decoder);
232 return addOperand(Inst, DAsm->decodeSrcOp(Inst, OpWidth, EncImm));
233}
234
235// Decoder for registers. Imm(7-bit) is number of register, uses decodeSrcOp to
236// get register class. Used by SGPR only operands.
237#define DECODE_OPERAND_SREG_7(RegClass, OpWidth) \
238 DECODE_SrcOp(Decode##RegClass##RegisterClass, 7, OpWidth, Imm)
239
240#define DECODE_OPERAND_SREG_8(RegClass, OpWidth) \
241 DECODE_SrcOp(Decode##RegClass##RegisterClass, 8, OpWidth, Imm)
242
243// Decoder for registers. Imm(10-bit): Imm{7-0} is number of register,
244// Imm{9} is acc(agpr or vgpr) Imm{8} should be 0 (see VOP3Pe_SMFMAC).
245// Set Imm{8} to 1 (IS_VGPR) to decode using 'enum10' from decodeSrcOp.
246// Used by AV_ register classes (AGPR or VGPR only register operands).
247template <unsigned OpWidth>
248static DecodeStatus decodeAV10(MCInst &Inst, unsigned Imm, uint64_t /* Addr */,
249 const MCDisassembler *Decoder) {
250 return decodeSrcOp(Inst, 10, OpWidth, Imm, Imm | AMDGPU::EncValues::IS_VGPR,
251 Decoder);
252}
253
254// Decoder for Src(9-bit encoding) registers only.
255template <unsigned OpWidth>
256static DecodeStatus decodeSrcReg9(MCInst &Inst, unsigned Imm,
257 uint64_t /* Addr */,
258 const MCDisassembler *Decoder) {
259 return decodeSrcOp(Inst, 9, OpWidth, Imm, Imm, Decoder);
260}
261
262// Decoder for Src(9-bit encoding) AGPR, register number encoded in 9bits, set
263// Imm{9} to 1 (set acc) and decode using 'enum10' from decodeSrcOp, registers
264// only.
265template <unsigned OpWidth>
266static DecodeStatus decodeSrcA9(MCInst &Inst, unsigned Imm, uint64_t /* Addr */,
267 const MCDisassembler *Decoder) {
268 // A clear Imm{8} names an SGPR or an inline constant, which this
269 // register-only operand cannot hold.
270 if (!(Imm & AMDGPU::EncValues::IS_VGPR))
272 return decodeSrcOp(Inst, 9, OpWidth, Imm, Imm | 512, Decoder);
273}
274
275// Decoder for 'enum10' from decodeSrcOp, Imm{0-8} is 9-bit Src encoding
276// Imm{9} is acc, registers only.
277template <unsigned OpWidth>
278static DecodeStatus decodeSrcAV10(MCInst &Inst, unsigned Imm,
279 uint64_t /* Addr */,
280 const MCDisassembler *Decoder) {
281 // A clear Imm{8} names an SGPR or an inline constant, which this
282 // register-only operand cannot hold.
283 if (!(Imm & AMDGPU::EncValues::IS_VGPR))
285 return decodeSrcOp(Inst, 10, OpWidth, Imm, Imm, Decoder);
286}
287
288// Decoder for RegisterOperands using 9-bit Src encoding. Operand can be
289// register from RegClass or immediate. Registers that don't belong to RegClass
290// will be decoded and InstPrinter will report warning. Immediate will be
291// decoded into constant matching the OperandType (important for floating point
292// types).
293template <unsigned OpWidth>
294static DecodeStatus decodeSrcRegOrImm9(MCInst &Inst, unsigned Imm,
295 uint64_t /* Addr */,
296 const MCDisassembler *Decoder) {
297 return decodeSrcOp(Inst, 9, OpWidth, Imm, Imm, Decoder);
298}
299
300// Decoder for Src(9-bit encoding) AGPR or immediate. Set Imm{9} to 1 (set acc)
301// and decode using 'enum10' from decodeSrcOp.
302template <unsigned OpWidth>
303static DecodeStatus decodeSrcRegOrImmA9(MCInst &Inst, unsigned Imm,
304 uint64_t /* Addr */,
305 const MCDisassembler *Decoder) {
306 return decodeSrcOp(Inst, 9, OpWidth, Imm, Imm | 512, Decoder);
307}
308
309// Default decoders generated by tablegen: 'Decode<RegClass>RegisterClass'
310// when RegisterClass is used as an operand. Most often used for destination
311// operands.
312
314DECODE_OPERAND_REG_8(VGPR_32_Lo128)
317DECODE_OPERAND_REG_8(VReg_128)
318DECODE_OPERAND_REG_8(VReg_192)
319DECODE_OPERAND_REG_8(VReg_256)
320DECODE_OPERAND_REG_8(VReg_288)
321DECODE_OPERAND_REG_8(VReg_320)
322DECODE_OPERAND_REG_8(VReg_352)
323DECODE_OPERAND_REG_8(VReg_384)
324DECODE_OPERAND_REG_8(VReg_512)
325DECODE_OPERAND_REG_8(VReg_1024)
326
327DECODE_OPERAND_SREG_7(SReg_32, 32)
328DECODE_OPERAND_SREG_7(SReg_32_XM0, 32)
329DECODE_OPERAND_SREG_7(SReg_32_XEXEC, 32)
330DECODE_OPERAND_SREG_7(SReg_32_XM0_XEXEC, 32)
331DECODE_OPERAND_SREG_7(SReg_32_XEXEC_HI, 32)
332DECODE_OPERAND_SREG_7(SReg_64_XEXEC, 64)
333DECODE_OPERAND_SREG_7(SReg_64_XEXEC_XNULL, 64)
334DECODE_OPERAND_SREG_7(SReg_96, 96)
335DECODE_OPERAND_SREG_7(SReg_128, 128)
336DECODE_OPERAND_SREG_7(SReg_128_XNULL, 128)
337DECODE_OPERAND_SREG_7(SReg_256, 256)
338DECODE_OPERAND_SREG_7(SReg_256_XNULL, 256)
339DECODE_OPERAND_SREG_7(SReg_512, 512)
340
341DECODE_OPERAND_SREG_8(SReg_64, 64)
342
345DECODE_OPERAND_REG_8(AReg_128)
346DECODE_OPERAND_REG_8(AReg_256)
347DECODE_OPERAND_REG_8(AReg_512)
348DECODE_OPERAND_REG_8(AReg_1024)
349
351 uint64_t /*Addr*/,
352 const MCDisassembler *Decoder) {
353 assert(isUInt<10>(Imm) && "10-bit encoding expected");
354 assert((Imm & (1 << 8)) == 0 && "Imm{8} should not be used");
355
356 bool IsHi = Imm & (1 << 9);
357 unsigned RegIdx = Imm & 0xff;
358 const auto *DAsm = static_cast<const AMDGPUDisassembler *>(Decoder);
359 return addOperand(Inst, DAsm->createVGPR16Operand(RegIdx, IsHi));
360}
361
362static DecodeStatus
364 const MCDisassembler *Decoder) {
365 assert(isUInt<8>(Imm) && "8-bit encoding expected");
366
367 bool IsHi = Imm & (1 << 7);
368 unsigned RegIdx = Imm & 0x7f;
369 const auto *DAsm = static_cast<const AMDGPUDisassembler *>(Decoder);
370 return addOperand(Inst, DAsm->createVGPR16Operand(RegIdx, IsHi));
371}
372
373template <unsigned OpWidth>
375 uint64_t /*Addr*/,
376 const MCDisassembler *Decoder) {
377 assert(isUInt<9>(Imm) && "9-bit encoding expected");
378
379 const auto *DAsm = static_cast<const AMDGPUDisassembler *>(Decoder);
380 if (Imm & AMDGPU::EncValues::IS_VGPR) {
381 bool IsHi = Imm & (1 << 7);
382 unsigned RegIdx = Imm & 0x7f;
383 return addOperand(Inst, DAsm->createVGPR16Operand(RegIdx, IsHi));
384 }
385 return addOperand(Inst, DAsm->decodeNonVGPRSrcOp(Inst, OpWidth, Imm & 0xFF));
386}
387
388template <unsigned OpWidth>
389static DecodeStatus decodeOperand_VSrcT16(MCInst &Inst, unsigned Imm,
390 uint64_t /*Addr*/,
391 const MCDisassembler *Decoder) {
392 assert(isUInt<10>(Imm) && "10-bit encoding expected");
393
394 const auto *DAsm = static_cast<const AMDGPUDisassembler *>(Decoder);
395 if (Imm & AMDGPU::EncValues::IS_VGPR) {
396 bool IsHi = Imm & (1 << 9);
397 unsigned RegIdx = Imm & 0xff;
398 return addOperand(Inst, DAsm->createVGPR16Operand(RegIdx, IsHi));
399 }
400 return addOperand(Inst, DAsm->decodeNonVGPRSrcOp(Inst, OpWidth, Imm & 0xFF));
401}
402
403static DecodeStatus decodeOperand_VGPR_16(MCInst &Inst, unsigned Imm,
404 uint64_t /*Addr*/,
405 const MCDisassembler *Decoder) {
406 assert(isUInt<10>(Imm) && "10-bit encoding expected");
407 if (!(Imm & AMDGPU::EncValues::IS_VGPR))
409
410 const auto *DAsm = static_cast<const AMDGPUDisassembler *>(Decoder);
411
412 bool IsHi = Imm & (1 << 9);
413 unsigned RegIdx = Imm & 0xff;
414 return addOperand(Inst, DAsm->createVGPR16Operand(RegIdx, IsHi));
415}
416
417static DecodeStatus decodeOperand_KImmFP(MCInst &Inst, unsigned Imm,
418 uint64_t Addr,
419 const MCDisassembler *Decoder) {
420 const auto *DAsm = static_cast<const AMDGPUDisassembler *>(Decoder);
421 return addOperand(Inst, DAsm->decodeMandatoryLiteralConstant(Imm));
422}
423
425 uint64_t Addr,
426 const MCDisassembler *Decoder) {
427 const auto *DAsm = static_cast<const AMDGPUDisassembler *>(Decoder);
428 return addOperand(Inst, DAsm->decodeMandatoryLiteral64Constant(Imm));
429}
430
431static DecodeStatus decodeOperandVOPDDstY(MCInst &Inst, unsigned Val,
432 uint64_t Addr, const void *Decoder) {
433 const auto *DAsm = static_cast<const AMDGPUDisassembler *>(Decoder);
434 return addOperand(Inst, DAsm->decodeVOPDDstYOp(Inst, Val));
435}
436
437static DecodeStatus decodeAVLdSt(MCInst &Inst, unsigned Imm, unsigned Opw,
438 const MCDisassembler *Decoder) {
439 const auto *DAsm = static_cast<const AMDGPUDisassembler *>(Decoder);
440 return addOperand(Inst, DAsm->decodeSrcOp(Inst, Opw, Imm | 256));
441}
442
443template <unsigned Opw>
444static DecodeStatus decodeAVLdSt(MCInst &Inst, unsigned Imm,
445 uint64_t /* Addr */,
446 const MCDisassembler *Decoder) {
447 return decodeAVLdSt(Inst, Imm, Opw, Decoder);
448}
449
450static DecodeStatus decodeOperand_VSrc_f64(MCInst &Inst, unsigned Imm,
451 uint64_t Addr,
452 const MCDisassembler *Decoder) {
453 assert(Imm < (1 << 9) && "9-bit encoding");
454 const auto *DAsm = static_cast<const AMDGPUDisassembler *>(Decoder);
455 return addOperand(Inst, DAsm->decodeSrcOp(Inst, 64, Imm));
456}
457
458#define DECODE_SDWA(DecName) \
459DECODE_OPERAND(decodeSDWA##DecName, decodeSDWA##DecName)
460
461DECODE_SDWA(Src32)
462DECODE_SDWA(Src16)
463DECODE_SDWA(VopcDst)
464
465static DecodeStatus decodeVersionImm(MCInst &Inst, unsigned Imm,
466 uint64_t /* Addr */,
467 const MCDisassembler *Decoder) {
468 const auto *DAsm = static_cast<const AMDGPUDisassembler *>(Decoder);
469 return addOperand(Inst, DAsm->decodeVersionImm(Imm));
470}
471
472#include "AMDGPUGenDisassemblerTables.inc"
473
474namespace {
475// Define bitwidths for various types used to instantiate the decoder.
476template <> constexpr uint32_t InsnBitWidth<uint32_t> = 32;
477template <> constexpr uint32_t InsnBitWidth<uint64_t> = 64;
478template <> constexpr uint32_t InsnBitWidth<std::bitset<96>> = 96;
479template <> constexpr uint32_t InsnBitWidth<std::bitset<128>> = 128;
480} // namespace
481
482//===----------------------------------------------------------------------===//
483//
484//===----------------------------------------------------------------------===//
485
486template <typename InsnType>
488 InsnType Inst, uint64_t Address,
489 raw_ostream &Comments) const {
490 assert(MI.getOpcode() == 0);
491 assert(MI.getNumOperands() == 0);
492 MCInst TmpInst;
493 HasLiteral = false;
494 const auto SavedBytes = Bytes;
495
496 SmallString<64> LocalComments;
497 raw_svector_ostream LocalCommentStream(LocalComments);
498 CommentStream = &LocalCommentStream;
499
500 DecodeStatus Res =
501 decodeInstruction(Table, TmpInst, Inst, Address, this, STI);
502 if (Res != MCDisassembler::Fail && !decodeImmOperands(TmpInst, *MCII))
504
505 CommentStream = nullptr;
506
507 if (Res != MCDisassembler::Fail) {
508 MI = TmpInst;
509 Comments << LocalComments;
511 }
512 Bytes = SavedBytes;
514}
515
516template <typename InsnType>
519 MCInst &MI, InsnType Inst, uint64_t Address,
520 raw_ostream &Comments) const {
521 for (const uint8_t *T : {Table1, Table2}) {
522 if (DecodeStatus Res = tryDecodeInst(T, MI, Inst, Address, Comments))
523 return Res;
524 }
526}
527
528template <typename T> static inline T eatBytes(ArrayRef<uint8_t>& Bytes) {
529 assert(Bytes.size() >= sizeof(T));
530 const auto Res =
532 Bytes = Bytes.slice(sizeof(T));
533 return Res;
534}
535
536static inline std::bitset<96> eat12Bytes(ArrayRef<uint8_t> &Bytes) {
537 using namespace llvm::support::endian;
538 assert(Bytes.size() >= 12);
539 std::bitset<96> Lo(read<uint64_t, endianness::little>(Bytes.data()));
540 Bytes = Bytes.slice(8);
541 std::bitset<96> Hi(read<uint32_t, endianness::little>(Bytes.data()));
542 Bytes = Bytes.slice(4);
543 return (Hi << 64) | Lo;
544}
545
546static inline std::bitset<128> eat16Bytes(ArrayRef<uint8_t> &Bytes) {
547 using namespace llvm::support::endian;
548 assert(Bytes.size() >= 16);
549 std::bitset<128> Lo(read<uint64_t, endianness::little>(Bytes.data()));
550 Bytes = Bytes.slice(8);
551 std::bitset<128> Hi(read<uint64_t, endianness::little>(Bytes.data()));
552 Bytes = Bytes.slice(8);
553 return (Hi << 64) | Lo;
554}
555
556bool AMDGPUDisassembler::decodeImmOperands(MCInst &MI,
557 const MCInstrInfo &MCII) const {
558 const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
559 for (auto [OpNo, OpDesc] : enumerate(Desc.operands())) {
560 if (OpNo >= MI.getNumOperands())
561 continue;
562
563 // TODO: Fix V_DUAL_FMAMK_F32_X_FMAAK_F32_gfx12 vsrc operands,
564 // defined to take VGPR_32, but in reality allowing inline constants.
565 bool IsSrc = AMDGPU::OPERAND_SRC_FIRST <= OpDesc.OperandType &&
566 OpDesc.OperandType <= AMDGPU::OPERAND_SRC_LAST;
567 if (!IsSrc && OpDesc.OperandType != MCOI::OPERAND_REGISTER)
568 continue;
569
570 MCOperand &Op = MI.getOperand(OpNo);
571 if (!Op.isImm())
572 continue;
573 int64_t Imm = Op.getImm();
576 Op = decodeIntImmed(Imm);
577 continue;
578 }
579
581 Op = decodeLiteralConstant(Desc, OpDesc);
582 if (!Op.isValid())
583 return false;
584 continue;
585 }
586
589 switch (OpDesc.OperandType) {
595 break;
598 Imm = getInlineImmValF16(Imm);
599 break;
602 Imm = getInlineImmValF16(Imm);
603 break;
605 // V_PK_FMAC_F16 on GFX11+ duplicates the f16 inline constant to both
606 // halves, so we need to produce the duplicated value for correct
607 // round-trip.
608 if (isGFX11Plus()) {
609 int64_t F16Val = getInlineImmValF16(Imm);
610 Imm = (F16Val << 16) | (F16Val & 0xFFFF);
611 } else {
612 Imm = getInlineImmValF16(Imm);
613 }
614 break;
615 }
623 Imm = getInlineImmVal64(Imm);
624 break;
625 default:
626 Imm = getInlineImmVal32(Imm);
627 }
628 Op.setImm(Imm);
629 }
630 }
631 return true;
632}
633
635 ArrayRef<uint8_t> Bytes_,
637 raw_ostream &CS) const {
638 unsigned MaxInstBytesNum = std::min((size_t)TargetMaxInstBytes, Bytes_.size());
639 Bytes = Bytes_.slice(0, MaxInstBytesNum);
640
641 // In case the opcode is not recognized we'll assume a Size of 4 bytes (unless
642 // there are fewer bytes left). This will be overridden on success.
643 Size = std::min((size_t)4, Bytes_.size());
644
645 do {
646 // ToDo: better to switch encoding length using some bit predicate
647 // but it is unknown yet, so try all we can
648
649 // Try to decode DPP and SDWA first to solve conflict with VOP1 and VOP2
650 // encodings
651 if (isGFX1250Plus() && Bytes.size() >= 16) {
652 std::bitset<128> DecW = eat16Bytes(Bytes);
653 if (tryDecodeInst(DecoderTableGFX1250128, MI, DecW, Address, CS))
654 break;
655 Bytes = Bytes_.slice(0, MaxInstBytesNum);
656 }
657
658 if (isGFX11Plus() && Bytes.size() >= 12) {
659 std::bitset<96> DecW = eat12Bytes(Bytes);
660
661 if (isGFX1170() &&
662 tryDecodeInst(DecoderTableGFX117096, DecoderTableGFX1170_FAKE1696, MI,
663 DecW, Address, CS))
664 break;
665
666 if (isGFX11() &&
667 tryDecodeInst(DecoderTableGFX1196, DecoderTableGFX11_FAKE1696, MI,
668 DecW, Address, CS))
669 break;
670
671 if (isGFX1250() &&
672 tryDecodeInst(DecoderTableGFX125096, DecoderTableGFX1250_FAKE1696, MI,
673 DecW, Address, CS))
674 break;
675
676 if (isGFX12() &&
677 tryDecodeInst(DecoderTableGFX1296, DecoderTableGFX12_FAKE1696, MI,
678 DecW, Address, CS))
679 break;
680
681 if (isGFX12() &&
682 tryDecodeInst(DecoderTableGFX12W6496, MI, DecW, Address, CS))
683 break;
684
685 if (isGFX13() &&
686 tryDecodeInst(DecoderTableGFX1396, DecoderTableGFX13_FAKE1696, MI,
687 DecW, Address, CS))
688 break;
689
690 if (STI.hasFeature(AMDGPU::Feature64BitLiterals)) {
691 // Return 8 bytes for a potential literal.
692 Bytes = Bytes_.slice(4, MaxInstBytesNum - 4);
693
694 if (isGFX1250() &&
695 tryDecodeInst(DecoderTableGFX125096, MI, DecW, Address, CS))
696 break;
697 }
698
699 // Reinitialize Bytes
700 Bytes = Bytes_.slice(0, MaxInstBytesNum);
701
702 } else if (Bytes.size() >= 16 &&
703 STI.hasFeature(AMDGPU::FeatureGFX950Insts)) {
704 std::bitset<128> DecW = eat16Bytes(Bytes);
705 if (tryDecodeInst(DecoderTableGFX940128, MI, DecW, Address, CS))
706 break;
707
708 // Reinitialize Bytes
709 Bytes = Bytes_.slice(0, MaxInstBytesNum);
710 }
711
712 if (Bytes.size() >= 8) {
713 const uint64_t QW = eatBytes<uint64_t>(Bytes);
714
715 if (STI.hasFeature(AMDGPU::FeatureGFX10_BEncoding) &&
716 tryDecodeInst(DecoderTableGFX10_B64, MI, QW, Address, CS))
717 break;
718
719 if (STI.hasFeature(AMDGPU::FeatureUnpackedD16VMem) &&
720 tryDecodeInst(DecoderTableGFX80_UNPACKED64, MI, QW, Address, CS))
721 break;
722
723 if (STI.hasFeature(AMDGPU::FeatureGFX950Insts) &&
724 tryDecodeInst(DecoderTableGFX95064, MI, QW, Address, CS))
725 break;
726
727 // Some GFX9 subtargets repurposed the v_mad_mix_f32, v_mad_mixlo_f16 and
728 // v_mad_mixhi_f16 for FMA variants. Try to decode using this special
729 // table first so we print the correct name.
730 if (STI.hasFeature(AMDGPU::FeatureFmaMixInsts) &&
731 tryDecodeInst(DecoderTableGFX9_DL64, MI, QW, Address, CS))
732 break;
733
734 if (STI.hasFeature(AMDGPU::FeatureGFX940Insts) &&
735 tryDecodeInst(DecoderTableGFX94064, MI, QW, Address, CS))
736 break;
737
738 if (STI.hasFeature(AMDGPU::FeatureGFX90AInsts) &&
739 tryDecodeInst(DecoderTableGFX90A64, MI, QW, Address, CS))
740 break;
741
742 if ((isVI() || isGFX9()) &&
743 tryDecodeInst(DecoderTableGFX864, MI, QW, Address, CS))
744 break;
745
746 if (isGFX9() && tryDecodeInst(DecoderTableGFX964, MI, QW, Address, CS))
747 break;
748
749 if (isGFX10() && tryDecodeInst(DecoderTableGFX1064, MI, QW, Address, CS))
750 break;
751
752 if (isGFX1250() &&
753 tryDecodeInst(DecoderTableGFX125064, DecoderTableGFX1250_FAKE1664, MI,
754 QW, Address, CS))
755 break;
756
757 if (isGFX12() &&
758 tryDecodeInst(DecoderTableGFX1264, DecoderTableGFX12_FAKE1664, MI, QW,
759 Address, CS))
760 break;
761
762 if (isGFX1170() &&
763 tryDecodeInst(DecoderTableGFX117064, DecoderTableGFX1170_FAKE1664, MI,
764 QW, Address, CS))
765 break;
766
767 if (isGFX11() &&
768 tryDecodeInst(DecoderTableGFX1164, DecoderTableGFX11_FAKE1664, MI, QW,
769 Address, CS))
770 break;
771
772 if (isGFX1170() &&
773 tryDecodeInst(DecoderTableGFX1170W6464, MI, QW, Address, CS))
774 break;
775
776 if (isGFX11() &&
777 tryDecodeInst(DecoderTableGFX11W6464, MI, QW, Address, CS))
778 break;
779
780 if (isGFX12() &&
781 tryDecodeInst(DecoderTableGFX12W6464, MI, QW, Address, CS))
782 break;
783
784 if (isGFX13() &&
785 tryDecodeInst(DecoderTableGFX1364, DecoderTableGFX13_FAKE1664, MI, QW,
786 Address, CS))
787 break;
788
789 // Reinitialize Bytes
790 Bytes = Bytes_.slice(0, MaxInstBytesNum);
791 }
792
793 // Try decode 32-bit instruction
794 if (Bytes.size() >= 4) {
795 const uint32_t DW = eatBytes<uint32_t>(Bytes);
796
797 if ((isVI() || isGFX9()) &&
798 tryDecodeInst(DecoderTableGFX832, MI, DW, Address, CS))
799 break;
800
801 if (tryDecodeInst(DecoderTableAMDGPU32, MI, DW, Address, CS))
802 break;
803
804 if (isGFX9() && tryDecodeInst(DecoderTableGFX932, MI, DW, Address, CS))
805 break;
806
807 if (STI.hasFeature(AMDGPU::FeatureGFX950Insts) &&
808 tryDecodeInst(DecoderTableGFX95032, MI, DW, Address, CS))
809 break;
810
811 if (STI.hasFeature(AMDGPU::FeatureGFX90AInsts) &&
812 tryDecodeInst(DecoderTableGFX90A32, MI, DW, Address, CS))
813 break;
814
815 if (STI.hasFeature(AMDGPU::FeatureGFX10_BEncoding) &&
816 tryDecodeInst(DecoderTableGFX10_B32, MI, DW, Address, CS))
817 break;
818
819 if (isGFX10() && tryDecodeInst(DecoderTableGFX1032, MI, DW, Address, CS))
820 break;
821
822 if (isGFX1170() &&
823 tryDecodeInst(DecoderTableGFX117032, DecoderTableGFX1170_FAKE1632, MI,
824 DW, Address, CS))
825 break;
826
827 if (isGFX11() &&
828 tryDecodeInst(DecoderTableGFX1132, DecoderTableGFX11_FAKE1632, MI, DW,
829 Address, CS))
830 break;
831
832 if (isGFX1250() &&
833 tryDecodeInst(DecoderTableGFX125032, DecoderTableGFX1250_FAKE1632, MI,
834 DW, Address, CS))
835 break;
836
837 if (isGFX12() &&
838 tryDecodeInst(DecoderTableGFX1232, DecoderTableGFX12_FAKE1632, MI, DW,
839 Address, CS))
840 break;
841
842 if (isGFX13() &&
843 tryDecodeInst(DecoderTableGFX1332, DecoderTableGFX13_FAKE1632, MI, DW,
844 Address, CS))
845 break;
846 }
847
849 } while (false);
850
852
853 if (SIInstrFlags::isDPP(*MCII, MI)) {
854 if (isMacDPP(MI))
856
857 if (SIInstrFlags::isVOP3P(*MCII, MI))
859 else if (SIInstrFlags::isVOPC(*MCII, MI))
860 convertVOPCDPPInst(MI); // Special VOP3 case
861 else if (AMDGPU::isVOPC64DPP(MI.getOpcode()))
862 convertVOPC64DPPInst(MI); // Special VOP3 case
863 else if (AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::dpp8) !=
864 -1)
866 else if (SIInstrFlags::isVOP3(*MCII, MI))
867 convertVOP3DPPInst(MI); // Regular VOP3 case
868 }
869
871
872 if (AMDGPU::isMAC(MI.getOpcode())) {
873 // Insert dummy unused src2_modifiers.
875 AMDGPU::OpName::src2_modifiers);
876 }
877
878 if (MI.getOpcode() == AMDGPU::V_CVT_SR_BF8_F32_e64_dpp ||
879 MI.getOpcode() == AMDGPU::V_CVT_SR_FP8_F32_e64_dpp) {
880 // Insert dummy unused src2_modifiers.
882 AMDGPU::OpName::src2_modifiers);
883 }
884
885 if (SIInstrFlags::isDS(*MCII, MI) && !AMDGPU::hasGDS(STI)) {
886 insertNamedMCOperand(MI, MCOperand::createImm(0), AMDGPU::OpName::gds);
887 }
888
889 if (SIInstrFlags::isMUBUF(*MCII, MI) || SIInstrFlags::isFLAT(*MCII, MI) ||
890 SIInstrFlags::isSMRD(*MCII, MI)) {
891 int CPolPos = AMDGPU::getNamedOperandIdx(MI.getOpcode(),
892 AMDGPU::OpName::cpol);
893 if (CPolPos != -1) {
894 unsigned CPol =
896 if (MI.getNumOperands() <= (unsigned)CPolPos) {
898 AMDGPU::OpName::cpol);
899 } else if (CPol) {
900 MI.getOperand(CPolPos).setImm(MI.getOperand(CPolPos).getImm() | CPol);
901 }
902 }
903 }
904
905 if (SIInstrFlags::isBuffer(*MCII, MI) &&
906 (STI.hasFeature(AMDGPU::FeatureGFX90AInsts))) {
907 // GFX90A lost TFE, its place is occupied by ACC.
908 int TFEOpIdx =
909 AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::tfe);
910 if (TFEOpIdx != -1) {
911 auto *TFEIter = MI.begin();
912 std::advance(TFEIter, TFEOpIdx);
913 MI.insert(TFEIter, MCOperand::createImm(0));
914 }
915 }
916
917 // Validate buffer instruction offsets for GFX12+ - must not be a negative.
919 int OffsetIdx =
920 AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::offset);
921 if (OffsetIdx != -1) {
922 uint32_t Imm = MI.getOperand(OffsetIdx).getImm();
923 int64_t SignedOffset = SignExtend64<24>(Imm);
924 if (SignedOffset < 0)
926 }
927 }
928
929 if (SIInstrFlags::isBuffer(*MCII, MI)) {
930 int SWZOpIdx =
931 AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::swz);
932 if (SWZOpIdx != -1) {
933 auto *SWZIter = MI.begin();
934 std::advance(SWZIter, SWZOpIdx);
935 MI.insert(SWZIter, MCOperand::createImm(0));
936 }
937 }
938
939 const MCInstrDesc &Desc = MCII->get(MI.getOpcode());
941 int VAddr0Idx =
942 AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::vaddr0);
943 int RsrcIdx =
944 AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::srsrc);
945 unsigned NSAArgs = RsrcIdx - VAddr0Idx - 1;
946 if (VAddr0Idx >= 0 && NSAArgs > 0) {
947 unsigned NSAWords = (NSAArgs + 3) / 4;
948 if (Bytes.size() < 4 * NSAWords)
950 for (unsigned i = 0; i < NSAArgs; ++i) {
951 const unsigned VAddrIdx = VAddr0Idx + 1 + i;
952 auto VAddrRCID =
953 MCII->getOpRegClassID(Desc.operands()[VAddrIdx], HwModeRegClass);
954 MI.insert(MI.begin() + VAddrIdx, createRegOperand(VAddrRCID, Bytes[i]));
955 }
956 Bytes = Bytes.slice(4 * NSAWords);
957 }
958
960 }
961
964
965 if (SIInstrFlags::isEXP(*MCII, MI))
967
968 if (SIInstrFlags::isVINTERP(*MCII, MI))
970
971 if (SIInstrFlags::isSDWA(*MCII, MI))
973
974 if (SIInstrFlags::isMAI(*MCII, MI) && !convertMAIInst(MI))
976
977 if (SIInstrFlags::isWMMA(*MCII, MI) && !convertWMMAInst(MI))
979
980 int VDstIn_Idx = AMDGPU::getNamedOperandIdx(MI.getOpcode(),
981 AMDGPU::OpName::vdst_in);
982 if (VDstIn_Idx != -1) {
983 int Tied = MCII->get(MI.getOpcode()).getOperandConstraint(VDstIn_Idx,
985 if (Tied != -1 && (MI.getNumOperands() <= (unsigned)VDstIn_Idx ||
986 !MI.getOperand(VDstIn_Idx).isReg() ||
987 MI.getOperand(VDstIn_Idx).getReg() != MI.getOperand(Tied).getReg())) {
988 if (MI.getNumOperands() > (unsigned)VDstIn_Idx)
989 MI.erase(&MI.getOperand(VDstIn_Idx));
991 MCOperand::createReg(MI.getOperand(Tied).getReg()),
992 AMDGPU::OpName::vdst_in);
993 }
994 }
995
996 bool IsSOPK = SIInstrFlags::isSOPK(*MCII, MI);
997 if (AMDGPU::hasNamedOperand(MI.getOpcode(), AMDGPU::OpName::imm) && !IsSOPK)
999
1000 // Some VOPC instructions, e.g., v_cmpx_f_f64, use VOP3 encoding and
1001 // have EXEC as implicit destination. Issue a warning if encoding for
1002 // vdst is not EXEC.
1003 if (SIInstrFlags::isVOP3(*MCII, MI) &&
1004 MCII->get(MI.getOpcode()).getNumDefs() == 0 &&
1005 MCII->get(MI.getOpcode()).hasImplicitDefOfPhysReg(AMDGPU::EXEC)) {
1006 auto ExecEncoding = MRI.getEncodingValue(AMDGPU::EXEC_LO);
1007 if (Bytes_[0] != ExecEncoding)
1009 }
1010
1011 Size = MaxInstBytesNum - Bytes.size();
1012 return Status;
1013}
1014
1016 if (STI.hasFeature(AMDGPU::FeatureGFX11Insts)) {
1017 // The MCInst still has these fields even though they are no longer encoded
1018 // in the GFX11 instruction.
1019 insertNamedMCOperand(MI, MCOperand::createImm(0), AMDGPU::OpName::vm);
1020 insertNamedMCOperand(MI, MCOperand::createImm(0), AMDGPU::OpName::compr);
1021 }
1022}
1023
1026 if (MI.getOpcode() == AMDGPU::V_INTERP_P10_F16_F32_inreg_t16_gfx11 ||
1027 MI.getOpcode() == AMDGPU::V_INTERP_P10_F16_F32_inreg_fake16_gfx11 ||
1028 MI.getOpcode() == AMDGPU::V_INTERP_P10_F16_F32_inreg_t16_gfx12 ||
1029 MI.getOpcode() == AMDGPU::V_INTERP_P10_F16_F32_inreg_fake16_gfx12 ||
1030 MI.getOpcode() == AMDGPU::V_INTERP_P10_F16_F32_inreg_t16_gfx13 ||
1031 MI.getOpcode() == AMDGPU::V_INTERP_P10_F16_F32_inreg_fake16_gfx13 ||
1032 MI.getOpcode() == AMDGPU::V_INTERP_P10_RTZ_F16_F32_inreg_t16_gfx11 ||
1033 MI.getOpcode() == AMDGPU::V_INTERP_P10_RTZ_F16_F32_inreg_fake16_gfx11 ||
1034 MI.getOpcode() == AMDGPU::V_INTERP_P10_RTZ_F16_F32_inreg_t16_gfx12 ||
1035 MI.getOpcode() == AMDGPU::V_INTERP_P10_RTZ_F16_F32_inreg_fake16_gfx12 ||
1036 MI.getOpcode() == AMDGPU::V_INTERP_P10_RTZ_F16_F32_inreg_t16_gfx13 ||
1037 MI.getOpcode() == AMDGPU::V_INTERP_P10_RTZ_F16_F32_inreg_fake16_gfx13 ||
1038 MI.getOpcode() == AMDGPU::V_INTERP_P2_F16_F32_inreg_t16_gfx11 ||
1039 MI.getOpcode() == AMDGPU::V_INTERP_P2_F16_F32_inreg_fake16_gfx11 ||
1040 MI.getOpcode() == AMDGPU::V_INTERP_P2_F16_F32_inreg_t16_gfx12 ||
1041 MI.getOpcode() == AMDGPU::V_INTERP_P2_F16_F32_inreg_fake16_gfx12 ||
1042 MI.getOpcode() == AMDGPU::V_INTERP_P2_F16_F32_inreg_t16_gfx13 ||
1043 MI.getOpcode() == AMDGPU::V_INTERP_P2_F16_F32_inreg_fake16_gfx13 ||
1044 MI.getOpcode() == AMDGPU::V_INTERP_P2_RTZ_F16_F32_inreg_t16_gfx11 ||
1045 MI.getOpcode() == AMDGPU::V_INTERP_P2_RTZ_F16_F32_inreg_fake16_gfx11 ||
1046 MI.getOpcode() == AMDGPU::V_INTERP_P2_RTZ_F16_F32_inreg_t16_gfx12 ||
1047 MI.getOpcode() == AMDGPU::V_INTERP_P2_RTZ_F16_F32_inreg_fake16_gfx12 ||
1048 MI.getOpcode() == AMDGPU::V_INTERP_P2_RTZ_F16_F32_inreg_t16_gfx13 ||
1049 MI.getOpcode() == AMDGPU::V_INTERP_P2_RTZ_F16_F32_inreg_fake16_gfx13) {
1050 // The MCInst has this field that is not directly encoded in the
1051 // instruction.
1052 insertNamedMCOperand(MI, MCOperand::createImm(0), AMDGPU::OpName::op_sel);
1053 }
1054}
1055
1057 if (STI.hasFeature(AMDGPU::FeatureGFX9) ||
1058 STI.hasFeature(AMDGPU::FeatureGFX10)) {
1059 if (AMDGPU::hasNamedOperand(MI.getOpcode(), AMDGPU::OpName::sdst))
1060 // VOPC - insert clamp
1061 insertNamedMCOperand(MI, MCOperand::createImm(0), AMDGPU::OpName::clamp);
1062 } else if (STI.hasFeature(AMDGPU::FeatureVolcanicIslands)) {
1063 int SDst = AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::sdst);
1064 if (SDst != -1) {
1065 // VOPC - insert VCC register as sdst
1067 AMDGPU::OpName::sdst);
1068 } else {
1069 // VOP1/2 - insert omod if present in instruction
1070 insertNamedMCOperand(MI, MCOperand::createImm(0), AMDGPU::OpName::omod);
1071 }
1072 }
1073}
1074
1075/// Adjust the register values used by V_MFMA_F8F6F4_f8_f8 instructions to the
1076/// appropriate subregister for the used format width.
1077///
1078/// \returns false if the operand cannot be narrowed down to \p NumRegs, which
1079/// means the encoding is malformed.
1081 MCOperand &MO, uint8_t NumRegs) {
1082 // A malformed encoding can select an operand that is not a register at all.
1083 if (!MO.isReg())
1084 return false;
1085
1086 MCRegister NewReg;
1087 switch (NumRegs) {
1088 case 4:
1089 NewReg = MRI.getSubReg(MO.getReg(), AMDGPU::sub0_sub1_sub2_sub3);
1090 break;
1091 case 6:
1092 NewReg = MRI.getSubReg(MO.getReg(), AMDGPU::sub0_sub1_sub2_sub3_sub4_sub5);
1093 break;
1094 case 8:
1095 NewReg = MRI.getSubReg(MO.getReg(),
1096 AMDGPU::sub0_sub1_sub2_sub3_sub4_sub5_sub6_sub7);
1097 // For mfma f8/f8 is the widest format, so the operand already has the
1098 // requested width and there is no subregister to select.
1099 if (!NewReg)
1100 return true;
1101 break;
1102 case 12:
1103 // There is no 384-bit subreg index defined.
1104 if (MCRegister BaseReg = MRI.getSubReg(MO.getReg(), AMDGPU::sub0)) {
1105 NewReg = MRI.getMatchingSuperReg(
1106 BaseReg, AMDGPU::sub0, &MRI.getRegClass(AMDGPU::VReg_384RegClassID));
1107 }
1108 break;
1109 case 16:
1110 // No-op in cases where one operand is still f8/bf8.
1111 return true;
1112 default:
1113 llvm_unreachable("Unexpected size for mfma/wmma f8f6f4 operand");
1114 }
1115
1116 if (!NewReg)
1117 return false;
1118
1119 MO.setReg(NewReg);
1120 return true;
1121}
1122
1123/// f8f6f4 instructions have different pseudos depending on the used formats. In
1124/// the disassembler table, we only have the variants with the largest register
1125/// classes which assume using an fp8/bf8 format for both operands. The actual
1126/// register class depends on the format in blgp and cbsz operands. Adjust the
1127/// register classes depending on the used format.
1129 int BlgpIdx =
1130 AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::blgp);
1131 if (BlgpIdx == -1)
1132 return true;
1133
1134 int CbszIdx =
1135 AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::cbsz);
1136
1137 unsigned CBSZ = MI.getOperand(CbszIdx).getImm();
1138 unsigned BLGP = MI.getOperand(BlgpIdx).getImm();
1139
1140 const AMDGPU::MFMA_F8F6F4_Info *AdjustedRegClassOpcode =
1141 AMDGPU::getMFMA_F8F6F4_WithFormatArgs(CBSZ, BLGP, MI.getOpcode());
1142 if (!AdjustedRegClassOpcode ||
1143 AdjustedRegClassOpcode->Opcode == MI.getOpcode())
1144 return true;
1145
1146 MI.setOpcode(AdjustedRegClassOpcode->Opcode);
1147 int Src0Idx =
1148 AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::src0);
1149 int Src1Idx =
1150 AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::src1);
1151 return adjustMFMA_F8F6F4OpRegClass(MRI, MI.getOperand(Src0Idx),
1152 AdjustedRegClassOpcode->NumRegsSrcA) &&
1153 adjustMFMA_F8F6F4OpRegClass(MRI, MI.getOperand(Src1Idx),
1154 AdjustedRegClassOpcode->NumRegsSrcB);
1155}
1156
1158 int FmtAIdx =
1159 AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::matrix_a_fmt);
1160 if (FmtAIdx == -1)
1161 return true;
1162
1163 int FmtBIdx =
1164 AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::matrix_b_fmt);
1165
1166 unsigned FmtA = MI.getOperand(FmtAIdx).getImm();
1167 unsigned FmtB = MI.getOperand(FmtBIdx).getImm();
1168
1169 const AMDGPU::MFMA_F8F6F4_Info *AdjustedRegClassOpcode =
1170 AMDGPU::getWMMA_F8F6F4_WithFormatArgs(FmtA, FmtB, MI.getOpcode());
1171 if (!AdjustedRegClassOpcode ||
1172 AdjustedRegClassOpcode->Opcode == MI.getOpcode())
1173 return true;
1174
1175 MI.setOpcode(AdjustedRegClassOpcode->Opcode);
1176 int Src0Idx =
1177 AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::src0);
1178 int Src1Idx =
1179 AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::src1);
1180 return adjustMFMA_F8F6F4OpRegClass(MRI, MI.getOperand(Src0Idx),
1181 AdjustedRegClassOpcode->NumRegsSrcA) &&
1182 adjustMFMA_F8F6F4OpRegClass(MRI, MI.getOperand(Src1Idx),
1183 AdjustedRegClassOpcode->NumRegsSrcB);
1184}
1185
1187 unsigned OpSel = 0;
1188 unsigned OpSelHi = 0;
1189 unsigned NegLo = 0;
1190 unsigned NegHi = 0;
1191};
1192
1193// Reconstruct values of VOP3/VOP3P operands such as op_sel.
1194// Note that these values do not affect disassembler output,
1195// so this is only necessary for consistency with src_modifiers.
1197 bool IsVOP3P = false) {
1198 VOPModifiers Modifiers;
1199 unsigned Opc = MI.getOpcode();
1200 const AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
1201 AMDGPU::OpName::src1_modifiers,
1202 AMDGPU::OpName::src2_modifiers};
1203 for (int J = 0; J < 3; ++J) {
1204 int OpIdx = AMDGPU::getNamedOperandIdx(Opc, ModOps[J]);
1205 if (OpIdx == -1)
1206 continue;
1207
1208 unsigned Val = MI.getOperand(OpIdx).getImm();
1209
1210 Modifiers.OpSel |= !!(Val & SISrcMods::OP_SEL_0) << J;
1211 if (IsVOP3P) {
1212 Modifiers.OpSelHi |= !!(Val & SISrcMods::OP_SEL_1) << J;
1213 Modifiers.NegLo |= !!(Val & SISrcMods::NEG) << J;
1214 Modifiers.NegHi |= !!(Val & SISrcMods::NEG_HI) << J;
1215 } else if (J == 0) {
1216 Modifiers.OpSel |= !!(Val & SISrcMods::DST_OP_SEL) << 3;
1217 }
1218 }
1219
1220 return Modifiers;
1221}
1222
1223// Instructions decode the op_sel/suffix bits into the src_modifier
1224// operands. Copy those bits into the src operands for true16 VGPRs.
1226 const unsigned Opc = MI.getOpcode();
1227 const MCRegisterClass &ConversionRC =
1228 MRI.getRegClass(AMDGPU::VGPR_16RegClassID);
1229 constexpr std::array<std::tuple<AMDGPU::OpName, AMDGPU::OpName, unsigned>, 4>
1230 OpAndOpMods = {{{AMDGPU::OpName::src0, AMDGPU::OpName::src0_modifiers,
1232 {AMDGPU::OpName::src1, AMDGPU::OpName::src1_modifiers,
1234 {AMDGPU::OpName::src2, AMDGPU::OpName::src2_modifiers,
1236 {AMDGPU::OpName::vdst, AMDGPU::OpName::src0_modifiers,
1238 for (const auto &[OpName, OpModsName, OpSelMask] : OpAndOpMods) {
1239 int OpIdx = AMDGPU::getNamedOperandIdx(Opc, OpName);
1240 int OpModsIdx = AMDGPU::getNamedOperandIdx(Opc, OpModsName);
1241 if (OpIdx == -1 || OpModsIdx == -1)
1242 continue;
1243 MCOperand &Op = MI.getOperand(OpIdx);
1244 if (!Op.isReg())
1245 continue;
1246 if (!ConversionRC.contains(Op.getReg()))
1247 continue;
1248 unsigned OpEnc = MRI.getEncodingValue(Op.getReg());
1249 const MCOperand &OpMods = MI.getOperand(OpModsIdx);
1250 unsigned ModVal = OpMods.getImm();
1251 if (ModVal & OpSelMask) { // isHi
1252 unsigned RegIdx = OpEnc & AMDGPU::HWEncoding::REG_IDX_MASK;
1253 Op.setReg(ConversionRC.getRegister(RegIdx * 2 + 1));
1254 }
1255 }
1256}
1257
1258// MAC opcodes have special old and src2 operands.
1259// src2 is tied to dst, while old is not tied (but assumed to be).
1261 constexpr int DST_IDX = 0;
1262 auto Opcode = MI.getOpcode();
1263 const auto &Desc = MCII->get(Opcode);
1264 auto OldIdx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::old);
1265
1266 if (OldIdx != -1 && Desc.getOperandConstraint(
1267 OldIdx, MCOI::OperandConstraint::TIED_TO) == -1) {
1268 assert(AMDGPU::hasNamedOperand(Opcode, AMDGPU::OpName::src2));
1269 assert(Desc.getOperandConstraint(
1270 AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src2),
1272 (void)DST_IDX;
1273 return true;
1274 }
1275
1276 return false;
1277}
1278
1279// Create dummy old operand and insert dummy unused src2_modifiers
1281 assert(MI.getNumOperands() + 1 < MCII->get(MI.getOpcode()).getNumOperands());
1282 insertNamedMCOperand(MI, MCOperand::createReg(0), AMDGPU::OpName::old);
1284 AMDGPU::OpName::src2_modifiers);
1285}
1286
1288 unsigned Opc = MI.getOpcode();
1289
1290 int VDstInIdx =
1291 AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::vdst_in);
1292 if (VDstInIdx != -1)
1293 insertNamedMCOperand(MI, MI.getOperand(0), AMDGPU::OpName::vdst_in);
1294
1295 unsigned DescNumOps = MCII->get(Opc).getNumOperands();
1296 if (MI.getNumOperands() < DescNumOps &&
1297 AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::op_sel)) {
1299 auto Mods = collectVOPModifiers(MI);
1301 AMDGPU::OpName::op_sel);
1302 } else {
1303 // Insert dummy unused src modifiers.
1304 if (MI.getNumOperands() < DescNumOps &&
1305 AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::src0_modifiers))
1307 AMDGPU::OpName::src0_modifiers);
1308
1309 if (MI.getNumOperands() < DescNumOps &&
1310 AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::src1_modifiers))
1312 AMDGPU::OpName::src1_modifiers);
1313 }
1314}
1315
1318
1319 int VDstInIdx =
1320 AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::vdst_in);
1321 if (VDstInIdx != -1)
1322 insertNamedMCOperand(MI, MI.getOperand(0), AMDGPU::OpName::vdst_in);
1323
1324 unsigned Opc = MI.getOpcode();
1325 unsigned DescNumOps = MCII->get(Opc).getNumOperands();
1326 if (MI.getNumOperands() < DescNumOps &&
1327 AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::op_sel)) {
1328 auto Mods = collectVOPModifiers(MI);
1330 AMDGPU::OpName::op_sel);
1331 }
1332}
1333
1334// Given a wide tuple \p Reg check if it will overflow 256 registers.
1335// \returns \p Reg on success or NoRegister otherwise.
1337 const MCRegisterInfo &MRI) {
1338 unsigned NumRegs = RC.getSizeInBits() / 32;
1339 MCRegister Sub0 = MRI.getSubReg(Reg, AMDGPU::sub0);
1340 if (!Sub0)
1341 return Reg;
1342
1343 MCRegister BaseReg;
1344 if (MRI.getRegClass(AMDGPU::VGPR_32RegClassID).contains(Sub0))
1345 BaseReg = AMDGPU::VGPR0;
1346 else if (MRI.getRegClass(AMDGPU::AGPR_32RegClassID).contains(Sub0))
1347 BaseReg = AMDGPU::AGPR0;
1348
1349 assert(BaseReg && "Only vector registers expected");
1350
1351 return (Sub0 - BaseReg + NumRegs <= 256) ? Reg : MCRegister();
1352}
1353
1354// Note that before gfx10, the MIMG encoding provided no information about
1355// VADDR size. Consequently, decoded instructions always show address as if it
1356// has 1 dword, which could be not really so.
1358 int VDstIdx = AMDGPU::getNamedOperandIdx(MI.getOpcode(),
1359 AMDGPU::OpName::vdst);
1360
1361 int VDataIdx = AMDGPU::getNamedOperandIdx(MI.getOpcode(),
1362 AMDGPU::OpName::vdata);
1363 int VAddr0Idx =
1364 AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::vaddr0);
1365 AMDGPU::OpName RsrcOpName = SIInstrFlags::isMIMG(*MCII, MI)
1366 ? AMDGPU::OpName::srsrc
1367 : AMDGPU::OpName::rsrc;
1368 int RsrcIdx = AMDGPU::getNamedOperandIdx(MI.getOpcode(), RsrcOpName);
1369 int DMaskIdx = AMDGPU::getNamedOperandIdx(MI.getOpcode(),
1370 AMDGPU::OpName::dmask);
1371
1372 int TFEIdx = AMDGPU::getNamedOperandIdx(MI.getOpcode(),
1373 AMDGPU::OpName::tfe);
1374 int D16Idx = AMDGPU::getNamedOperandIdx(MI.getOpcode(),
1375 AMDGPU::OpName::d16);
1376
1377 const AMDGPU::MIMGInfo *Info = AMDGPU::getMIMGInfo(MI.getOpcode());
1378 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
1379 AMDGPU::getMIMGBaseOpcodeInfo(Info->BaseOpcode);
1380
1381 assert(VDataIdx != -1);
1382 if (BaseOpcode->BVH) {
1383 // Add A16 operand for intersect_ray instructions
1384 addOperand(MI, MCOperand::createImm(BaseOpcode->A16));
1385 return;
1386 }
1387
1388 bool IsAtomic = (VDstIdx != -1);
1389 bool IsGather4 = SIInstrFlags::isGather4(*MCII, MI);
1390 bool IsVSample = SIInstrFlags::isVSAMPLE(*MCII, MI);
1391 bool IsNSA = false;
1392 bool IsPartialNSA = false;
1393 unsigned AddrSize = Info->VAddrDwords;
1394
1395 if (isGFX10Plus()) {
1396 unsigned DimIdx =
1397 AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::dim);
1398 int A16Idx =
1399 AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::a16);
1400 const AMDGPU::MIMGDimInfo *Dim =
1401 AMDGPU::getMIMGDimInfoByEncoding(MI.getOperand(DimIdx).getImm());
1402 const bool IsA16 = (A16Idx != -1 && MI.getOperand(A16Idx).getImm());
1403
1404 AddrSize =
1405 AMDGPU::getAddrSizeMIMGOp(BaseOpcode, Dim, IsA16, AMDGPU::hasG16(STI));
1406
1407 // VSAMPLE insts that do not use vaddr3 behave the same as NSA forms.
1408 // VIMAGE insts other than BVH never use vaddr4.
1409 IsNSA = Info->MIMGEncoding == AMDGPU::MIMGEncGfx10NSA ||
1410 Info->MIMGEncoding == AMDGPU::MIMGEncGfx11NSA ||
1411 Info->MIMGEncoding == AMDGPU::MIMGEncGfx12 ||
1412 Info->MIMGEncoding == AMDGPU::MIMGEncGfx13;
1413 if (!IsNSA) {
1414 if (!IsVSample && AddrSize > 12)
1415 AddrSize = 16;
1416 } else {
1417 if (AddrSize > Info->VAddrDwords) {
1418 if (!STI.hasFeature(AMDGPU::FeaturePartialNSAEncoding)) {
1419 // The NSA encoding does not contain enough operands for the
1420 // combination of base opcode / dimension. Should this be an error?
1421 return;
1422 }
1423 IsPartialNSA = true;
1424 }
1425 }
1426 }
1427
1428 unsigned DMask = MI.getOperand(DMaskIdx).getImm() & 0xf;
1429 unsigned DstSize = IsGather4 ? 4 : std::max(llvm::popcount(DMask), 1);
1430
1431 bool D16 = D16Idx >= 0 && MI.getOperand(D16Idx).getImm();
1432 if (D16 && AMDGPU::hasPackedD16(STI)) {
1433 DstSize = (DstSize + 1) / 2;
1434 }
1435
1436 if (TFEIdx != -1 && MI.getOperand(TFEIdx).getImm())
1437 DstSize += 1;
1438
1439 if (DstSize == Info->VDataDwords && AddrSize == Info->VAddrDwords)
1440 return;
1441
1442 int NewOpcode =
1443 AMDGPU::getMIMGOpcode(Info->BaseOpcode, Info->MIMGEncoding, DstSize, AddrSize);
1444 if (NewOpcode == -1)
1445 return;
1446
1447 // Widen the register to the correct number of enabled channels.
1448 MCRegister NewVdata;
1449 if (DstSize != Info->VDataDwords) {
1450 auto DataRCID = MCII->getOpRegClassID(
1451 MCII->get(NewOpcode).operands()[VDataIdx], HwModeRegClass);
1452
1453 // Get first subregister of VData
1454 MCRegister Vdata0 = MI.getOperand(VDataIdx).getReg();
1455 MCRegister VdataSub0 = MRI.getSubReg(Vdata0, AMDGPU::sub0);
1456 Vdata0 = (VdataSub0 != 0)? VdataSub0 : Vdata0;
1457
1458 const MCRegisterClass &NewRC = MRI.getRegClass(DataRCID);
1459 NewVdata = MRI.getMatchingSuperReg(Vdata0, AMDGPU::sub0, &NewRC);
1460 NewVdata = CheckVGPROverflow(NewVdata, NewRC, MRI);
1461 if (!NewVdata) {
1462 // It's possible to encode this such that the low register + enabled
1463 // components exceeds the register count.
1464 return;
1465 }
1466 }
1467
1468 // If not using NSA on GFX10+, widen vaddr0 address register to correct size.
1469 // If using partial NSA on GFX11+ widen last address register.
1470 int VAddrSAIdx = IsPartialNSA ? (RsrcIdx - 1) : VAddr0Idx;
1471 MCRegister NewVAddrSA;
1472 if (STI.hasFeature(AMDGPU::FeatureNSAEncoding) && (!IsNSA || IsPartialNSA) &&
1473 AddrSize != Info->VAddrDwords) {
1474 MCRegister VAddrSA = MI.getOperand(VAddrSAIdx).getReg();
1475 MCRegister VAddrSubSA = MRI.getSubReg(VAddrSA, AMDGPU::sub0);
1476 VAddrSA = VAddrSubSA ? VAddrSubSA : VAddrSA;
1477
1478 auto AddrRCID = MCII->getOpRegClassID(
1479 MCII->get(NewOpcode).operands()[VAddrSAIdx], HwModeRegClass);
1480
1481 const MCRegisterClass &NewRC = MRI.getRegClass(AddrRCID);
1482 NewVAddrSA = MRI.getMatchingSuperReg(VAddrSA, AMDGPU::sub0, &NewRC);
1483 NewVAddrSA = CheckVGPROverflow(NewVAddrSA, NewRC, MRI);
1484 if (!NewVAddrSA)
1485 return;
1486 }
1487
1488 MI.setOpcode(NewOpcode);
1489
1490 if (NewVdata != AMDGPU::NoRegister) {
1491 MI.getOperand(VDataIdx) = MCOperand::createReg(NewVdata);
1492
1493 if (IsAtomic) {
1494 // Atomic operations have an additional operand (a copy of data)
1495 MI.getOperand(VDstIdx) = MCOperand::createReg(NewVdata);
1496 }
1497 }
1498
1499 if (NewVAddrSA) {
1500 MI.getOperand(VAddrSAIdx) = MCOperand::createReg(NewVAddrSA);
1501 } else if (IsNSA) {
1502 assert(AddrSize <= Info->VAddrDwords);
1503 MI.erase(MI.begin() + VAddr0Idx + AddrSize,
1504 MI.begin() + VAddr0Idx + Info->VAddrDwords);
1505 }
1506}
1507
1508// Opsel and neg bits are used in src_modifiers and standalone operands. Autogen
1509// decoder only adds to src_modifiers, so manually add the bits to the other
1510// operands.
1512 unsigned Opc = MI.getOpcode();
1513 unsigned DescNumOps = MCII->get(Opc).getNumOperands();
1514 auto Mods = collectVOPModifiers(MI, true);
1515
1516 if (MI.getNumOperands() < DescNumOps &&
1517 AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::vdst_in))
1518 insertNamedMCOperand(MI, MCOperand::createImm(0), AMDGPU::OpName::vdst_in);
1519
1520 if (MI.getNumOperands() < DescNumOps &&
1521 AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::op_sel))
1523 AMDGPU::OpName::op_sel);
1524 if (MI.getNumOperands() < DescNumOps &&
1525 AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::op_sel_hi))
1527 AMDGPU::OpName::op_sel_hi);
1528 if (MI.getNumOperands() < DescNumOps &&
1529 AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::neg_lo))
1531 AMDGPU::OpName::neg_lo);
1532 if (MI.getNumOperands() < DescNumOps &&
1533 AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::neg_hi))
1535 AMDGPU::OpName::neg_hi);
1536}
1537
1538// Create dummy old operand and insert optional operands
1540 unsigned Opc = MI.getOpcode();
1541 unsigned DescNumOps = MCII->get(Opc).getNumOperands();
1542
1543 if (MI.getNumOperands() < DescNumOps &&
1544 AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::old))
1545 insertNamedMCOperand(MI, MCOperand::createReg(0), AMDGPU::OpName::old);
1546
1547 if (MI.getNumOperands() < DescNumOps &&
1548 AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::src0_modifiers))
1550 AMDGPU::OpName::src0_modifiers);
1551
1552 if (MI.getNumOperands() < DescNumOps &&
1553 AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::src1_modifiers))
1555 AMDGPU::OpName::src1_modifiers);
1556}
1557
1559 unsigned Opc = MI.getOpcode();
1560 unsigned DescNumOps = MCII->get(Opc).getNumOperands();
1561
1563
1564 if (MI.getNumOperands() < DescNumOps &&
1565 AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::op_sel)) {
1568 AMDGPU::OpName::op_sel);
1569 }
1570}
1571
1573 assert(HasLiteral && "Should have decoded a literal");
1574 insertNamedMCOperand(MI, MCOperand::createImm(Literal), AMDGPU::OpName::immX);
1575}
1576
1577const char* AMDGPUDisassembler::getRegClassName(unsigned RegClassID) const {
1579 &getAMDGPUMCRegisterClass(RegClassID));
1580}
1581
1582inline
1584 const Twine& ErrMsg) const {
1585 *CommentStream << "Error: " + ErrMsg;
1586
1587 // ToDo: add support for error operands to MCInst.h
1588 // return MCOperand::createError(V);
1589 return MCOperand();
1590}
1591
1595
1596inline
1598 unsigned Val) const {
1599 const auto &RegCl = getAMDGPUMCRegisterClass(RegClassID);
1600 if (Val >= RegCl.getNumRegs())
1601 return errOperand(Val, Twine(getRegClassName(RegClassID)) +
1602 ": unknown register " + Twine(Val));
1603 return createRegOperand(RegCl.getRegister(Val));
1604}
1605
1606inline
1608 unsigned Val) const {
1609 // ToDo: SI/CI have 104 SGPRs, VI - 102
1610 // Valery: here we accepting as much as we can, let assembler sort it out
1611 int shift = 0;
1612 switch (SRegClassID) {
1613 case AMDGPU::SGPR_32RegClassID:
1614 case AMDGPU::TTMP_32RegClassID:
1615 break;
1616 case AMDGPU::SGPR_64RegClassID:
1617 case AMDGPU::TTMP_64RegClassID:
1618 shift = 1;
1619 break;
1620 case AMDGPU::SGPR_96RegClassID:
1621 case AMDGPU::TTMP_96RegClassID:
1622 case AMDGPU::SGPR_128RegClassID:
1623 case AMDGPU::TTMP_128RegClassID:
1624 // ToDo: unclear if s[100:104] is available on VI. Can we use VCC as SGPR in
1625 // this bundle?
1626 case AMDGPU::SGPR_256RegClassID:
1627 case AMDGPU::TTMP_256RegClassID:
1628 // ToDo: unclear if s[96:104] is available on VI. Can we use VCC as SGPR in
1629 // this bundle?
1630 case AMDGPU::SGPR_288RegClassID:
1631 case AMDGPU::TTMP_288RegClassID:
1632 case AMDGPU::SGPR_320RegClassID:
1633 case AMDGPU::TTMP_320RegClassID:
1634 case AMDGPU::SGPR_352RegClassID:
1635 case AMDGPU::TTMP_352RegClassID:
1636 case AMDGPU::SGPR_384RegClassID:
1637 case AMDGPU::TTMP_384RegClassID:
1638 case AMDGPU::SGPR_512RegClassID:
1639 case AMDGPU::TTMP_512RegClassID:
1640 shift = 2;
1641 break;
1642 // ToDo: unclear if s[88:104] is available on VI. Can we use VCC as SGPR in
1643 // this bundle?
1644 default:
1645 llvm_unreachable("unhandled register class");
1646 }
1647
1648 if (Val % (1 << shift)) {
1649 *CommentStream << "Warning: " << getRegClassName(SRegClassID)
1650 << ": scalar reg isn't aligned " << Val;
1651 }
1652
1653 return createRegOperand(SRegClassID, Val >> shift);
1654}
1655
1657 bool IsHi) const {
1658 unsigned RegIdxInVGPR16 = RegIdx * 2 + (IsHi ? 1 : 0);
1659 return createRegOperand(AMDGPU::VGPR_16RegClassID, RegIdxInVGPR16);
1660}
1661
1662// Decode Literals for insts which always have a literal in the encoding
1665 if (HasLiteral) {
1666 assert(
1668 "Should only decode multiple kimm with VOPD, check VSrc operand types");
1669 if (Literal != Val)
1670 return errOperand(Val, "More than one unique literal is illegal");
1671 }
1672 HasLiteral = true;
1673 Literal = Val;
1674 return MCOperand::createImm(Literal);
1675}
1676
1679 if (HasLiteral) {
1680 if (Literal != Val)
1681 return errOperand(Val, "More than one unique literal is illegal");
1682 }
1683 HasLiteral = true;
1684 Literal = Val;
1685
1686 bool UseLit64 = Hi_32(Literal) == 0;
1688 LitModifier::Lit64, Literal, getContext()))
1689 : MCOperand::createImm(Literal);
1690}
1691
1694 const MCOperandInfo &OpDesc) const {
1695 // For now all literal constants are supposed to be unsigned integer
1696 // ToDo: deal with signed/unsigned 64-bit integer constants
1697 // ToDo: deal with float/double constants
1698 if (!HasLiteral) {
1699 if (Bytes.size() < 4) {
1700 return errOperand(0, "cannot read literal, inst bytes left " +
1701 Twine(Bytes.size()));
1702 }
1703 HasLiteral = true;
1704 Literal = eatBytes<uint32_t>(Bytes);
1705 }
1706
1707 // For disassembling always assume all inline constants are available.
1708 bool HasInv2Pi = true;
1709
1710 // Invalid instruction codes may contain literals for inline-only
1711 // operands, so we support them here as well.
1712 int64_t Val = Literal;
1713 bool UseLit = false;
1714 switch (OpDesc.OperandType) {
1715 default:
1716 llvm_unreachable("Unexpected operand type!");
1720 UseLit = AMDGPU::isInlinableLiteralBF16(Val, HasInv2Pi);
1721 break;
1724 break;
1728 UseLit = AMDGPU::isInlinableLiteralFP16(Val, HasInv2Pi);
1729 break;
1731 UseLit = AMDGPU::isInlinableLiteralV2F16(Val);
1732 break;
1735 break;
1737 break;
1741 UseLit = AMDGPU::isInlinableLiteralI16(Val, HasInv2Pi);
1742 break;
1744 UseLit = AMDGPU::isInlinableLiteralV2I16(Val);
1745 break;
1755 UseLit = AMDGPU::isInlinableLiteral32(Val, HasInv2Pi);
1756 break;
1761 UseLit = AMDGPU::isInlinableLiteral64(Val << 32, HasInv2Pi);
1762 if (!UseLit)
1763 Val <<= 32;
1764 break;
1768 UseLit = AMDGPU::isInlinableLiteral64(Val, HasInv2Pi);
1769 break;
1771 // TODO: Disassembling V_DUAL_FMAMK_F32_X_FMAMK_F32_gfx11 hits
1772 // decoding a literal in a position of a register operand. Give
1773 // it special handling in the caller, decodeImmOperands(), instead
1774 // of quietly allowing it here.
1775 break;
1776 }
1777
1780 : MCOperand::createImm(Val);
1781}
1782
1784 assert(STI.hasFeature(AMDGPU::Feature64BitLiterals));
1785
1786 if (!HasLiteral) {
1787 if (Bytes.size() < 8) {
1788 return errOperand(0, "cannot read literal64, inst bytes left " +
1789 Twine(Bytes.size()));
1790 }
1791 HasLiteral = true;
1792 Literal = eatBytes<uint64_t>(Bytes);
1793 }
1794
1795 bool UseLit64 = Hi_32(Literal) == 0;
1796
1797 UseLit64 |= AMDGPU::isInlinableLiteral64(
1798 Literal, STI.hasFeature(AMDGPU::FeatureInv2PiInlineImm));
1799
1801 LitModifier::Lit64, Literal, getContext()))
1802 : MCOperand::createImm(Literal);
1803}
1804
1806 using namespace AMDGPU::EncValues;
1807
1808 assert(Imm >= INLINE_INTEGER_C_MIN && Imm <= INLINE_INTEGER_C_MAX);
1809 return MCOperand::createImm((Imm <= INLINE_INTEGER_C_POSITIVE_MAX) ?
1810 (static_cast<int64_t>(Imm) - INLINE_INTEGER_C_MIN) :
1811 (INLINE_INTEGER_C_POSITIVE_MAX - static_cast<int64_t>(Imm)));
1812 // Cast prevents negative overflow.
1813}
1814
1815static int64_t getInlineImmVal32(unsigned Imm) {
1816 switch (Imm) {
1817 case 240:
1818 return llvm::bit_cast<uint32_t>(0.5f);
1819 case 241:
1820 return llvm::bit_cast<uint32_t>(-0.5f);
1821 case 242:
1822 return llvm::bit_cast<uint32_t>(1.0f);
1823 case 243:
1824 return llvm::bit_cast<uint32_t>(-1.0f);
1825 case 244:
1826 return llvm::bit_cast<uint32_t>(2.0f);
1827 case 245:
1828 return llvm::bit_cast<uint32_t>(-2.0f);
1829 case 246:
1830 return llvm::bit_cast<uint32_t>(4.0f);
1831 case 247:
1832 return llvm::bit_cast<uint32_t>(-4.0f);
1833 case 248: // 1 / (2 * PI)
1834 return 0x3e22f983;
1835 default:
1836 llvm_unreachable("invalid fp inline imm");
1837 }
1838}
1839
1840static int64_t getInlineImmVal64(unsigned Imm) {
1841 switch (Imm) {
1842 case 240:
1843 return llvm::bit_cast<uint64_t>(0.5);
1844 case 241:
1845 return llvm::bit_cast<uint64_t>(-0.5);
1846 case 242:
1847 return llvm::bit_cast<uint64_t>(1.0);
1848 case 243:
1849 return llvm::bit_cast<uint64_t>(-1.0);
1850 case 244:
1851 return llvm::bit_cast<uint64_t>(2.0);
1852 case 245:
1853 return llvm::bit_cast<uint64_t>(-2.0);
1854 case 246:
1855 return llvm::bit_cast<uint64_t>(4.0);
1856 case 247:
1857 return llvm::bit_cast<uint64_t>(-4.0);
1858 case 248: // 1 / (2 * PI)
1859 return 0x3fc45f306dc9c882;
1860 default:
1861 llvm_unreachable("invalid fp inline imm");
1862 }
1863}
1864
1865static int64_t getInlineImmValF16(unsigned Imm) {
1866 switch (Imm) {
1867 case 240:
1868 return 0x3800;
1869 case 241:
1870 return 0xB800;
1871 case 242:
1872 return 0x3C00;
1873 case 243:
1874 return 0xBC00;
1875 case 244:
1876 return 0x4000;
1877 case 245:
1878 return 0xC000;
1879 case 246:
1880 return 0x4400;
1881 case 247:
1882 return 0xC400;
1883 case 248: // 1 / (2 * PI)
1884 return 0x3118;
1885 default:
1886 llvm_unreachable("invalid fp inline imm");
1887 }
1888}
1889
1890static int64_t getInlineImmValBF16(unsigned Imm) {
1891 switch (Imm) {
1892 case 240:
1893 return 0x3F00;
1894 case 241:
1895 return 0xBF00;
1896 case 242:
1897 return 0x3F80;
1898 case 243:
1899 return 0xBF80;
1900 case 244:
1901 return 0x4000;
1902 case 245:
1903 return 0xC000;
1904 case 246:
1905 return 0x4080;
1906 case 247:
1907 return 0xC080;
1908 case 248: // 1 / (2 * PI)
1909 return 0x3E22;
1910 default:
1911 llvm_unreachable("invalid fp inline imm");
1912 }
1913}
1914
1915unsigned AMDGPUDisassembler::getVgprClassId(unsigned Width) const {
1916 using namespace AMDGPU;
1917
1918 switch (Width) {
1919 case 16:
1920 case 32:
1921 return VGPR_32RegClassID;
1922 case 64:
1923 return VReg_64RegClassID;
1924 case 96:
1925 return VReg_96RegClassID;
1926 case 128:
1927 return VReg_128RegClassID;
1928 case 160:
1929 return VReg_160RegClassID;
1930 case 192:
1931 return VReg_192RegClassID;
1932 case 256:
1933 return VReg_256RegClassID;
1934 case 288:
1935 return VReg_288RegClassID;
1936 case 320:
1937 return VReg_320RegClassID;
1938 case 352:
1939 return VReg_352RegClassID;
1940 case 384:
1941 return VReg_384RegClassID;
1942 case 512:
1943 return VReg_512RegClassID;
1944 case 1024:
1945 return VReg_1024RegClassID;
1946 }
1947 llvm_unreachable("Invalid register width!");
1948}
1949
1950unsigned AMDGPUDisassembler::getAgprClassId(unsigned Width) const {
1951 using namespace AMDGPU;
1952
1953 switch (Width) {
1954 case 16:
1955 case 32:
1956 return AGPR_32RegClassID;
1957 case 64:
1958 return AReg_64RegClassID;
1959 case 96:
1960 return AReg_96RegClassID;
1961 case 128:
1962 return AReg_128RegClassID;
1963 case 160:
1964 return AReg_160RegClassID;
1965 case 256:
1966 return AReg_256RegClassID;
1967 case 288:
1968 return AReg_288RegClassID;
1969 case 320:
1970 return AReg_320RegClassID;
1971 case 352:
1972 return AReg_352RegClassID;
1973 case 384:
1974 return AReg_384RegClassID;
1975 case 512:
1976 return AReg_512RegClassID;
1977 case 1024:
1978 return AReg_1024RegClassID;
1979 }
1980 llvm_unreachable("Invalid register width!");
1981}
1982
1983std::optional<unsigned>
1985 using namespace AMDGPU;
1986
1987 switch (Width) {
1988 case 16:
1989 case 32:
1990 return SGPR_32RegClassID;
1991 case 64:
1992 return SGPR_64RegClassID;
1993 case 96:
1994 return SGPR_96RegClassID;
1995 case 128:
1996 return SGPR_128RegClassID;
1997 case 160:
1998 return SGPR_160RegClassID;
1999 case 256:
2000 return SGPR_256RegClassID;
2001 case 288:
2002 return SGPR_288RegClassID;
2003 case 320:
2004 return SGPR_320RegClassID;
2005 case 352:
2006 return SGPR_352RegClassID;
2007 case 384:
2008 return SGPR_384RegClassID;
2009 case 512:
2010 return SGPR_512RegClassID;
2011 }
2012 return std::nullopt;
2013}
2014
2015std::optional<unsigned>
2017 using namespace AMDGPU;
2018
2019 switch (Width) {
2020 case 16:
2021 case 32:
2022 return TTMP_32RegClassID;
2023 case 64:
2024 return TTMP_64RegClassID;
2025 case 128:
2026 return TTMP_128RegClassID;
2027 case 256:
2028 return TTMP_256RegClassID;
2029 case 288:
2030 return TTMP_288RegClassID;
2031 case 320:
2032 return TTMP_320RegClassID;
2033 case 352:
2034 return TTMP_352RegClassID;
2035 case 384:
2036 return TTMP_384RegClassID;
2037 case 512:
2038 return TTMP_512RegClassID;
2039 }
2040 return std::nullopt;
2041}
2042
2043int AMDGPUDisassembler::getTTmpIdx(unsigned Val) const {
2044 using namespace AMDGPU::EncValues;
2045
2046 unsigned TTmpMin = isGFX9Plus() ? TTMP_GFX9PLUS_MIN : TTMP_VI_MIN;
2047 unsigned TTmpMax = isGFX9Plus() ? TTMP_GFX9PLUS_MAX : TTMP_VI_MAX;
2048
2049 return (TTmpMin <= Val && Val <= TTmpMax)? Val - TTmpMin : -1;
2050}
2051
2053 unsigned Val) const {
2054 using namespace AMDGPU::EncValues;
2055
2056 assert(Val < 1024); // enum10
2057
2058 bool IsAGPR = Val & 512;
2059 Val &= 511;
2060
2061 if (VGPR_MIN <= Val && Val <= VGPR_MAX) {
2062 return createRegOperand(IsAGPR ? getAgprClassId(Width)
2063 : getVgprClassId(Width), Val - VGPR_MIN);
2064 }
2065 return decodeNonVGPRSrcOp(Inst, Width, Val & 0xFF);
2066}
2067
2069 unsigned Width,
2070 unsigned Val) const {
2071 // Cases when Val{8} is 1 (vgpr, agpr or true 16 vgpr) should have been
2072 // decoded earlier.
2073 assert(Val < (1 << 8) && "9-bit Src encoding when Val{8} is 0");
2074 using namespace AMDGPU::EncValues;
2075
2076 // Not every operand width has a supported non-VGPR source encoding.
2077 // Selecting an unsupported SGPR, ttmp, or special register is malformed.
2078 auto UnsupportedWidth = [&]() {
2079 return errOperand(Val, "unsupported " + Twine(Width) +
2080 "-bit non-VGPR operand encoding " + Twine(Val));
2081 };
2082
2083 if (Val <= SGPR_MAX) {
2084 // "SGPR_MIN <= Val" is always true and causes compilation warning.
2085 static_assert(SGPR_MIN == 0);
2086 std::optional<unsigned> ClassId = getSgprClassId(Width);
2087 if (!ClassId)
2088 return UnsupportedWidth();
2089 return createSRegOperand(*ClassId, Val - SGPR_MIN);
2090 }
2091
2092 int TTmpIdx = getTTmpIdx(Val);
2093 if (TTmpIdx >= 0) {
2094 std::optional<unsigned> ClassId = getTtmpClassId(Width);
2095 if (!ClassId)
2096 return UnsupportedWidth();
2097 return createSRegOperand(*ClassId, TTmpIdx);
2098 }
2099
2100 if ((INLINE_INTEGER_C_MIN <= Val && Val <= INLINE_INTEGER_C_MAX) ||
2101 (INLINE_FLOATING_C_MIN <= Val && Val <= INLINE_FLOATING_C_MAX) ||
2102 Val == LITERAL_CONST)
2103 return MCOperand::createImm(Val);
2104
2105 if (Val == LITERAL64_CONST && STI.hasFeature(AMDGPU::Feature64BitLiterals)) {
2106 // Only VOP1, VOP2, VOPC, SOP1, SOP2 and SOPC may encode a 64-bit literal.
2107 // VOP3, VOP3P and VOPD have to use a 32-bit one.
2108 if (SIInstrFlags::isVOP3Like(*MCII, Inst) ||
2109 AMDGPU::isVOPD(Inst.getOpcode())) {
2110 return errOperand(Val,
2111 "64-bit literal is not supported by this instruction");
2112 }
2113 return decodeLiteral64Constant();
2114 }
2115
2116 switch (Width) {
2117 case 32:
2118 case 16:
2119 return decodeSpecialReg32(Val);
2120 case 64:
2121 return decodeSpecialReg64(Val);
2122 case 96:
2123 case 128:
2124 case 256:
2125 case 512:
2126 return decodeSpecialReg96Plus(Val);
2127 default:
2128 return UnsupportedWidth();
2129 }
2130}
2131
2132// Bit 0 of DstY isn't stored in the instruction, because it's always the
2133// opposite of bit 0 of DstX.
2135 unsigned Val) const {
2136 int VDstXInd =
2137 AMDGPU::getNamedOperandIdx(Inst.getOpcode(), AMDGPU::OpName::vdstX);
2138 assert(VDstXInd != -1);
2139 assert(Inst.getOperand(VDstXInd).isReg());
2140 unsigned XDstReg = MRI.getEncodingValue(Inst.getOperand(VDstXInd).getReg());
2141 Val |= ~XDstReg & 1;
2142 return createRegOperand(getVgprClassId(32), Val);
2143}
2144
2146 using namespace AMDGPU;
2147
2148 switch (Val) {
2149 // clang-format off
2150 case 102: return createRegOperand(FLAT_SCR_LO);
2151 case 103: return createRegOperand(FLAT_SCR_HI);
2152 case 104: return createRegOperand(XNACK_MASK_LO);
2153 case 105: return createRegOperand(XNACK_MASK_HI);
2154 case 106: return createRegOperand(VCC_LO);
2155 case 107: return createRegOperand(VCC_HI);
2156 case 108: return createRegOperand(TBA_LO);
2157 case 109: return createRegOperand(TBA_HI);
2158 case 110: return createRegOperand(TMA_LO);
2159 case 111: return createRegOperand(TMA_HI);
2160 case 124:
2161 return isGFX11Plus() ? createRegOperand(SGPR_NULL) : createRegOperand(M0);
2162 case 125:
2163 return isGFX11Plus() ? createRegOperand(M0) : createRegOperand(SGPR_NULL);
2164 case 126: return createRegOperand(EXEC_LO);
2165 case 127: return createRegOperand(EXEC_HI);
2166 case 230: return createRegOperand(SRC_FLAT_SCRATCH_BASE_LO);
2167 case 231: return createRegOperand(SRC_FLAT_SCRATCH_BASE_HI);
2168 case 235: return createRegOperand(SRC_SHARED_BASE_LO);
2169 case 236: return createRegOperand(SRC_SHARED_LIMIT_LO);
2170 case 237:
2172 return createRegOperand(SRC_PRIVATE_BASE_LO);
2173 break;
2174 case 238:
2176 return createRegOperand(SRC_PRIVATE_LIMIT_LO);
2177 break;
2178 case 239:
2180 return createRegOperand(SRC_POPS_EXITING_WAVE_ID);
2181 break;
2182 case 251:
2183 if (!isGFX11Plus())
2184 return createRegOperand(SRC_VCCZ);
2185 break;
2186 case 252:
2187 if (!isGFX11Plus())
2188 return createRegOperand(SRC_EXECZ);
2189 break;
2190 case 253: return createRegOperand(SRC_SCC);
2191 case 254: return createRegOperand(LDS_DIRECT);
2192 default: break;
2193 // clang-format on
2194 }
2195 return errOperand(Val, "unknown operand encoding " + Twine(Val));
2196}
2197
2199 using namespace AMDGPU;
2200
2201 switch (Val) {
2202 case 102: return createRegOperand(FLAT_SCR);
2203 case 104: return createRegOperand(XNACK_MASK);
2204 case 106: return createRegOperand(VCC);
2205 case 108: return createRegOperand(TBA);
2206 case 110: return createRegOperand(TMA);
2207 case 124:
2208 if (isGFX11Plus())
2209 return createRegOperand(SGPR_NULL);
2210 break;
2211 case 125:
2212 if (!isGFX11Plus())
2213 return createRegOperand(SGPR_NULL);
2214 break;
2215 case 126: return createRegOperand(EXEC);
2216 case 230: return createRegOperand(SRC_FLAT_SCRATCH_BASE_LO);
2217 case 235: return createRegOperand(SRC_SHARED_BASE);
2218 case 236: return createRegOperand(SRC_SHARED_LIMIT);
2219 case 237:
2221 return createRegOperand(SRC_PRIVATE_BASE);
2222 break;
2223 case 238:
2225 return createRegOperand(SRC_PRIVATE_LIMIT);
2226 break;
2227 case 239:
2229 return createRegOperand(SRC_POPS_EXITING_WAVE_ID);
2230 break;
2231 case 251:
2232 if (!isGFX11Plus())
2233 return createRegOperand(SRC_VCCZ);
2234 break;
2235 case 252:
2236 if (!isGFX11Plus())
2237 return createRegOperand(SRC_EXECZ);
2238 break;
2239 case 253: return createRegOperand(SRC_SCC);
2240 default: break;
2241 }
2242 return errOperand(Val, "unknown operand encoding " + Twine(Val));
2243}
2244
2246 using namespace AMDGPU;
2247
2248 switch (Val) {
2249 case 124:
2250 if (isGFX11Plus())
2251 return createRegOperand(SGPR_NULL);
2252 break;
2253 case 125:
2254 if (!isGFX11Plus())
2255 return createRegOperand(SGPR_NULL);
2256 break;
2257 default:
2258 break;
2259 }
2260 return errOperand(Val, "unknown operand encoding " + Twine(Val));
2261}
2262
2264 const unsigned Val) const {
2265 using namespace AMDGPU::SDWA;
2266 using namespace AMDGPU::EncValues;
2267
2268 if (STI.hasFeature(AMDGPU::FeatureGFX9) ||
2269 STI.hasFeature(AMDGPU::FeatureGFX10)) {
2270 // XXX: cast to int is needed to avoid stupid warning:
2271 // compare with unsigned is always true
2272 if (int(SDWA9EncValues::SRC_VGPR_MIN) <= int(Val) &&
2273 Val <= SDWA9EncValues::SRC_VGPR_MAX) {
2274 return createRegOperand(getVgprClassId(Width),
2275 Val - SDWA9EncValues::SRC_VGPR_MIN);
2276 }
2277 if (SDWA9EncValues::SRC_SGPR_MIN <= Val &&
2278 Val <= (isGFX10Plus() ? SDWA9EncValues::SRC_SGPR_MAX_GFX10
2279 : SDWA9EncValues::SRC_SGPR_MAX_SI)) {
2280 return createSRegOperand(*getSgprClassId(Width),
2281 Val - SDWA9EncValues::SRC_SGPR_MIN);
2282 }
2283 if (SDWA9EncValues::SRC_TTMP_MIN <= Val &&
2284 Val <= SDWA9EncValues::SRC_TTMP_MAX) {
2285 return createSRegOperand(*getTtmpClassId(Width),
2286 Val - SDWA9EncValues::SRC_TTMP_MIN);
2287 }
2288
2289 const unsigned SVal = Val - SDWA9EncValues::SRC_SGPR_MIN;
2290
2291 if ((INLINE_INTEGER_C_MIN <= SVal && SVal <= INLINE_INTEGER_C_MAX) ||
2292 (INLINE_FLOATING_C_MIN <= SVal && SVal <= INLINE_FLOATING_C_MAX))
2293 return MCOperand::createImm(SVal);
2294
2295 return decodeSpecialReg32(SVal);
2296 }
2297 if (STI.hasFeature(AMDGPU::FeatureVolcanicIslands))
2298 return createRegOperand(getVgprClassId(Width), Val);
2299 llvm_unreachable("unsupported target");
2300}
2301
2303 return decodeSDWASrc(16, Val);
2304}
2305
2307 return decodeSDWASrc(32, Val);
2308}
2309
2311 using namespace AMDGPU::SDWA;
2312
2313 assert((STI.hasFeature(AMDGPU::FeatureGFX9) ||
2314 STI.hasFeature(AMDGPU::FeatureGFX10)) &&
2315 "SDWAVopcDst should be present only on GFX9+");
2316
2317 bool IsWave32 = STI.hasFeature(AMDGPU::FeatureWavefrontSize32);
2318
2319 if (Val & SDWA9EncValues::VOPC_DST_VCC_MASK) {
2320 Val &= SDWA9EncValues::VOPC_DST_SGPR_MASK;
2321
2322 int TTmpIdx = getTTmpIdx(Val);
2323 if (TTmpIdx >= 0)
2324 return createSRegOperand(*getTtmpClassId(IsWave32 ? 32 : 64), TTmpIdx);
2325 if (Val > SGPR_MAX) {
2326 return IsWave32 ? decodeSpecialReg32(Val) : decodeSpecialReg64(Val);
2327 }
2328 return createSRegOperand(*getSgprClassId(IsWave32 ? 32 : 64), Val);
2329 }
2330 return createRegOperand(IsWave32 ? AMDGPU::VCC_LO : AMDGPU::VCC);
2331}
2332
2334 unsigned Val) const {
2335 return STI.hasFeature(AMDGPU::FeatureWavefrontSize32)
2336 ? decodeSrcOp(Inst, 32, Val)
2337 : decodeSrcOp(Inst, 64, Val);
2338}
2339
2341 unsigned Val) const {
2342 using namespace AMDGPU::EncValues;
2343 constexpr unsigned M0Encoding = 125;
2344 bool IsValidBarrier =
2345 Val == M0Encoding ||
2346 (INLINE_INTEGER_C_MIN <= Val && Val < INLINE_INTEGER_C_MIN + 32) ||
2347 (INLINE_INTEGER_C_POSITIVE_MAX < Val &&
2348 Val <= INLINE_INTEGER_C_POSITIVE_MAX + 4);
2349 if (!IsValidBarrier)
2350 return MCOperand();
2351 return decodeSrcOp(Inst, 32, Val);
2352}
2353
2356 return MCOperand();
2357 return MCOperand::createImm(Val);
2358}
2359
2361 using VersionField = AMDGPU::EncodingField<7, 0>;
2362 using W64Bit = AMDGPU::EncodingBit<13>;
2363 using W32Bit = AMDGPU::EncodingBit<14>;
2364 using MDPBit = AMDGPU::EncodingBit<15>;
2366
2367 auto [Version, W64, W32, MDP] = Encoding::decode(Imm);
2368
2369 // Decode into a plain immediate if any unused bits are raised.
2370 if (Encoding::encode(Version, W64, W32, MDP) != Imm)
2371 return MCOperand::createImm(Imm);
2372
2373 const auto &Versions = AMDGPU::UCVersion::getGFXVersions();
2374 const auto *I = find_if(
2375 Versions, [Version = Version](const AMDGPU::UCVersion::GFXVersion &V) {
2376 return V.Code == Version;
2377 });
2378 MCContext &Ctx = getContext();
2379 const MCExpr *E;
2380 if (I == Versions.end())
2382 else
2383 E = MCSymbolRefExpr::create(Ctx.getOrCreateSymbol(I->Symbol), Ctx);
2384
2385 if (W64)
2386 E = MCBinaryExpr::createOr(E, UCVersionW64Expr, Ctx);
2387 if (W32)
2388 E = MCBinaryExpr::createOr(E, UCVersionW32Expr, Ctx);
2389 if (MDP)
2390 E = MCBinaryExpr::createOr(E, UCVersionMDPExpr, Ctx);
2391
2392 return MCOperand::createExpr(E);
2393}
2394
2396 return STI.hasFeature(AMDGPU::FeatureVolcanicIslands);
2397}
2398
2400
2402 return STI.hasFeature(AMDGPU::FeatureGFX90AInsts);
2403}
2404
2406
2408
2412
2414 return STI.hasFeature(AMDGPU::FeatureGFX11);
2415}
2416
2420
2422 return STI.hasFeature(AMDGPU::FeatureGFX11_7Insts);
2423}
2424
2426 return STI.hasFeature(AMDGPU::FeatureGFX12);
2427}
2428
2432
2434
2438
2440
2444
2446 return STI.hasFeature(AMDGPU::FeatureArchitectedFlatScratch);
2447}
2448
2452//===----------------------------------------------------------------------===//
2453// AMDGPU specific symbol handling
2454//===----------------------------------------------------------------------===//
2455
2456/// Print a string describing the reserved bit range specified by Mask with
2457/// offset BaseBytes for use in error comments. Mask is a single continuous
2458/// range of 1s surrounded by zeros. The format here is meant to align with the
2459/// tables that describe these bits in llvm.org/docs/AMDGPUUsage.html.
2460static SmallString<32> getBitRangeFromMask(uint32_t Mask, unsigned BaseBytes) {
2461 SmallString<32> Result;
2462 raw_svector_ostream S(Result);
2463
2464 int TrailingZeros = llvm::countr_zero(Mask);
2465 int PopCount = llvm::popcount(Mask);
2466
2467 if (PopCount == 1) {
2468 S << "bit (" << (TrailingZeros + BaseBytes * CHAR_BIT) << ')';
2469 } else {
2470 S << "bits in range ("
2471 << (TrailingZeros + PopCount - 1 + BaseBytes * CHAR_BIT) << ':'
2472 << (TrailingZeros + BaseBytes * CHAR_BIT) << ')';
2473 }
2474
2475 return Result;
2476}
2477
2478#define GET_FIELD(MASK) (AMDHSA_BITS_GET(FourByteBuffer, MASK))
2479#define PRINT_DIRECTIVE(DIRECTIVE, MASK) \
2480 do { \
2481 KdStream << Indent << DIRECTIVE " " << GET_FIELD(MASK) << '\n'; \
2482 } while (0)
2483#define PRINT_PSEUDO_DIRECTIVE_COMMENT(DIRECTIVE, MASK) \
2484 do { \
2485 KdStream << Indent << MAI.getCommentString() << ' ' << DIRECTIVE " " \
2486 << GET_FIELD(MASK) << '\n'; \
2487 } while (0)
2488
2489#define CHECK_RESERVED_BITS_IMPL(MASK, DESC, MSG) \
2490 do { \
2491 if (FourByteBuffer & (MASK)) { \
2492 return createStringError(std::errc::invalid_argument, \
2493 "kernel descriptor " DESC \
2494 " reserved %s set" MSG, \
2495 getBitRangeFromMask((MASK), 0).c_str()); \
2496 } \
2497 } while (0)
2498
2499#define CHECK_RESERVED_BITS(MASK) CHECK_RESERVED_BITS_IMPL(MASK, #MASK, "")
2500#define CHECK_RESERVED_BITS_MSG(MASK, MSG) \
2501 CHECK_RESERVED_BITS_IMPL(MASK, #MASK, ", " MSG)
2502#define CHECK_RESERVED_BITS_DESC(MASK, DESC) \
2503 CHECK_RESERVED_BITS_IMPL(MASK, DESC, "")
2504#define CHECK_RESERVED_BITS_DESC_MSG(MASK, DESC, MSG) \
2505 CHECK_RESERVED_BITS_IMPL(MASK, DESC, ", " MSG)
2506
2507// NOLINTNEXTLINE(readability-identifier-naming)
2509 uint32_t FourByteBuffer, raw_string_ostream &KdStream) const {
2510 using namespace amdhsa;
2511 StringRef Indent = "\t";
2512
2513 // We cannot accurately backward compute #VGPRs used from
2514 // GRANULATED_WORKITEM_VGPR_COUNT. But we are concerned with getting the same
2515 // value of GRANULATED_WORKITEM_VGPR_COUNT in the reassembled binary. So we
2516 // simply calculate the inverse of what the assembler does.
2517
2518 uint32_t GranulatedWorkitemVGPRCount =
2519 GET_FIELD(COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT);
2520
2521 uint32_t NextFreeVGPR =
2522 (GranulatedWorkitemVGPRCount + 1) *
2523 AMDGPU::IsaInfo::getVGPREncodingGranule(STI, EnableWavefrontSize32);
2524
2525 KdStream << Indent << ".amdhsa_next_free_vgpr " << NextFreeVGPR << '\n';
2526
2527 // We cannot backward compute values used to calculate
2528 // GRANULATED_WAVEFRONT_SGPR_COUNT. Hence the original values for following
2529 // directives can't be computed:
2530 // .amdhsa_reserve_vcc
2531 // .amdhsa_reserve_flat_scratch
2532 // .amdhsa_reserve_xnack_mask
2533 // They take their respective default values if not specified in the assembly.
2534 //
2535 // GRANULATED_WAVEFRONT_SGPR_COUNT
2536 // = f(NEXT_FREE_SGPR + VCC + FLAT_SCRATCH + XNACK_MASK)
2537 //
2538 // We compute the inverse as though all directives apart from NEXT_FREE_SGPR
2539 // are set to 0. So while disassembling we consider that:
2540 //
2541 // GRANULATED_WAVEFRONT_SGPR_COUNT
2542 // = f(NEXT_FREE_SGPR + 0 + 0 + 0)
2543 //
2544 // The disassembler cannot recover the original values of those 3 directives.
2545
2546 uint32_t GranulatedWavefrontSGPRCount =
2547 GET_FIELD(COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT);
2548
2549 if (isGFX10Plus())
2550 CHECK_RESERVED_BITS_MSG(COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT,
2551 "must be zero on gfx10+");
2552
2553 uint32_t NextFreeSGPR = (GranulatedWavefrontSGPRCount + 1) *
2555
2556 KdStream << Indent << ".amdhsa_reserve_vcc " << 0 << '\n';
2558 KdStream << Indent << ".amdhsa_reserve_flat_scratch " << 0 << '\n';
2559 bool ReservedXnackMask = STI.hasFeature(AMDGPU::FeatureXNACK);
2560 assert(!ReservedXnackMask || STI.hasFeature(AMDGPU::FeatureSupportsXNACK));
2561 KdStream << Indent << ".amdhsa_reserve_xnack_mask " << ReservedXnackMask
2562 << '\n';
2563 KdStream << Indent << ".amdhsa_next_free_sgpr " << NextFreeSGPR << "\n";
2564
2565 CHECK_RESERVED_BITS(COMPUTE_PGM_RSRC1_PRIORITY);
2566
2567 PRINT_DIRECTIVE(".amdhsa_float_round_mode_32",
2568 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_32);
2569 PRINT_DIRECTIVE(".amdhsa_float_round_mode_16_64",
2570 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_16_64);
2571 PRINT_DIRECTIVE(".amdhsa_float_denorm_mode_32",
2572 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_32);
2573 PRINT_DIRECTIVE(".amdhsa_float_denorm_mode_16_64",
2574 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_16_64);
2575
2576 CHECK_RESERVED_BITS(COMPUTE_PGM_RSRC1_PRIV);
2577
2578 if (STI.hasFeature(AMDGPU::FeatureDX10ClampAndIEEEMode))
2579 PRINT_DIRECTIVE(".amdhsa_dx10_clamp",
2580 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_DX10_CLAMP);
2581
2582 CHECK_RESERVED_BITS(COMPUTE_PGM_RSRC1_DEBUG_MODE);
2583
2584 if (STI.hasFeature(AMDGPU::FeatureDX10ClampAndIEEEMode))
2585 PRINT_DIRECTIVE(".amdhsa_ieee_mode",
2586 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_IEEE_MODE);
2587
2588 CHECK_RESERVED_BITS(COMPUTE_PGM_RSRC1_BULKY);
2589 CHECK_RESERVED_BITS(COMPUTE_PGM_RSRC1_CDBG_USER);
2590
2591 // Bits [26].
2592 if (isGFX9Plus()) {
2593 PRINT_DIRECTIVE(".amdhsa_fp16_overflow", COMPUTE_PGM_RSRC1_GFX9_PLUS_FP16_OVFL);
2594 } else {
2595 CHECK_RESERVED_BITS_DESC_MSG(COMPUTE_PGM_RSRC1_GFX6_GFX8_RESERVED0,
2596 "COMPUTE_PGM_RSRC1", "must be zero pre-gfx9");
2597 }
2598
2599 // Bits [27].
2600 if (isGFX1250Plus()) {
2601 PRINT_PSEUDO_DIRECTIVE_COMMENT("FLAT_SCRATCH_IS_NV",
2602 COMPUTE_PGM_RSRC1_GFX125_FLAT_SCRATCH_IS_NV);
2603 } else {
2604 CHECK_RESERVED_BITS_DESC(COMPUTE_PGM_RSRC1_GFX6_GFX120_RESERVED1,
2605 "COMPUTE_PGM_RSRC1");
2606 }
2607
2608 // Bits [28].
2609 CHECK_RESERVED_BITS_DESC(COMPUTE_PGM_RSRC1_RESERVED2, "COMPUTE_PGM_RSRC1");
2610
2611 // Bits [29-31].
2612 if (isGFX10Plus()) {
2613 // WGP_MODE is not available on GFX1250.
2614 if (!isGFX1250Plus()) {
2615 PRINT_DIRECTIVE(".amdhsa_workgroup_processor_mode",
2616 COMPUTE_PGM_RSRC1_GFX10_PLUS_WGP_MODE);
2617 }
2618 PRINT_DIRECTIVE(".amdhsa_memory_ordered", COMPUTE_PGM_RSRC1_GFX10_PLUS_MEM_ORDERED);
2619 PRINT_DIRECTIVE(".amdhsa_forward_progress", COMPUTE_PGM_RSRC1_GFX10_PLUS_FWD_PROGRESS);
2620 } else {
2621 CHECK_RESERVED_BITS_DESC(COMPUTE_PGM_RSRC1_GFX6_GFX9_RESERVED3,
2622 "COMPUTE_PGM_RSRC1");
2623 }
2624
2625 if (isGFX12Plus())
2626 PRINT_DIRECTIVE(".amdhsa_round_robin_scheduling",
2627 COMPUTE_PGM_RSRC1_GFX12_PLUS_ENABLE_WG_RR_EN);
2628
2629 return true;
2630}
2631
2632// NOLINTNEXTLINE(readability-identifier-naming)
2634 uint32_t FourByteBuffer, raw_string_ostream &KdStream) const {
2635 using namespace amdhsa;
2636 StringRef Indent = "\t";
2638 PRINT_DIRECTIVE(".amdhsa_enable_private_segment",
2639 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT);
2640 else
2641 PRINT_DIRECTIVE(".amdhsa_system_sgpr_private_segment_wavefront_offset",
2642 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT);
2643 PRINT_DIRECTIVE(".amdhsa_system_sgpr_workgroup_id_x",
2644 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_X);
2645 PRINT_DIRECTIVE(".amdhsa_system_sgpr_workgroup_id_y",
2646 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Y);
2647 PRINT_DIRECTIVE(".amdhsa_system_sgpr_workgroup_id_z",
2648 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Z);
2649 PRINT_DIRECTIVE(".amdhsa_system_sgpr_workgroup_info",
2650 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_INFO);
2651 PRINT_DIRECTIVE(".amdhsa_system_vgpr_workitem_id",
2652 COMPUTE_PGM_RSRC2_ENABLE_VGPR_WORKITEM_ID);
2653
2654 CHECK_RESERVED_BITS(COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_ADDRESS_WATCH);
2655 CHECK_RESERVED_BITS(COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_MEMORY);
2656 CHECK_RESERVED_BITS(COMPUTE_PGM_RSRC2_GRANULATED_LDS_SIZE);
2657
2659 ".amdhsa_exception_fp_ieee_invalid_op",
2660 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INVALID_OPERATION);
2661 PRINT_DIRECTIVE(".amdhsa_exception_fp_denorm_src",
2662 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_FP_DENORMAL_SOURCE);
2664 ".amdhsa_exception_fp_ieee_div_zero",
2665 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_DIVISION_BY_ZERO);
2666 PRINT_DIRECTIVE(".amdhsa_exception_fp_ieee_overflow",
2667 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_OVERFLOW);
2668 PRINT_DIRECTIVE(".amdhsa_exception_fp_ieee_underflow",
2669 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_UNDERFLOW);
2670 PRINT_DIRECTIVE(".amdhsa_exception_fp_ieee_inexact",
2671 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INEXACT);
2672 PRINT_DIRECTIVE(".amdhsa_exception_int_div_zero",
2673 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_INT_DIVIDE_BY_ZERO);
2674
2675 CHECK_RESERVED_BITS_DESC(COMPUTE_PGM_RSRC2_RESERVED0, "COMPUTE_PGM_RSRC2");
2676
2677 return true;
2678}
2679
2680// NOLINTNEXTLINE(readability-identifier-naming)
2682 uint32_t FourByteBuffer, raw_string_ostream &KdStream) const {
2683 using namespace amdhsa;
2684 StringRef Indent = "\t";
2685 if (isGFX90A()) {
2686 KdStream << Indent << ".amdhsa_accum_offset "
2687 << (GET_FIELD(COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET) + 1) * 4
2688 << '\n';
2689
2690 PRINT_DIRECTIVE(".amdhsa_tg_split", COMPUTE_PGM_RSRC3_GFX90A_TG_SPLIT);
2691
2692 CHECK_RESERVED_BITS_DESC_MSG(COMPUTE_PGM_RSRC3_GFX90A_RESERVED0,
2693 "COMPUTE_PGM_RSRC3", "must be zero on gfx90a");
2694 CHECK_RESERVED_BITS_DESC_MSG(COMPUTE_PGM_RSRC3_GFX90A_RESERVED1,
2695 "COMPUTE_PGM_RSRC3", "must be zero on gfx90a");
2696 } else if (isGFX10Plus()) {
2697 // Bits [0-3].
2698 if (!isGFX12Plus()) {
2699 if (!EnableWavefrontSize32 || !*EnableWavefrontSize32) {
2700 PRINT_DIRECTIVE(".amdhsa_shared_vgpr_count",
2701 COMPUTE_PGM_RSRC3_GFX10_GFX11_SHARED_VGPR_COUNT);
2702 } else {
2704 "SHARED_VGPR_COUNT",
2705 COMPUTE_PGM_RSRC3_GFX10_GFX11_SHARED_VGPR_COUNT);
2706 }
2707 } else {
2708 CHECK_RESERVED_BITS_DESC_MSG(COMPUTE_PGM_RSRC3_GFX12_PLUS_RESERVED0,
2709 "COMPUTE_PGM_RSRC3",
2710 "must be zero on gfx12+");
2711 }
2712
2713 // Bits [4-11].
2714 if (isGFX11()) {
2715 PRINT_DIRECTIVE(".amdhsa_inst_pref_size",
2716 COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE);
2717 PRINT_PSEUDO_DIRECTIVE_COMMENT("TRAP_ON_START",
2718 COMPUTE_PGM_RSRC3_GFX11_TRAP_ON_START);
2719 PRINT_PSEUDO_DIRECTIVE_COMMENT("TRAP_ON_END",
2720 COMPUTE_PGM_RSRC3_GFX11_TRAP_ON_END);
2721 } else if (isGFX12Plus()) {
2722 PRINT_DIRECTIVE(".amdhsa_inst_pref_size",
2723 COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE);
2724 } else {
2725 CHECK_RESERVED_BITS_DESC_MSG(COMPUTE_PGM_RSRC3_GFX10_RESERVED1,
2726 "COMPUTE_PGM_RSRC3",
2727 "must be zero on gfx10");
2728 }
2729
2730 // Bits [12].
2731 CHECK_RESERVED_BITS_DESC_MSG(COMPUTE_PGM_RSRC3_GFX10_PLUS_RESERVED2,
2732 "COMPUTE_PGM_RSRC3", "must be zero on gfx10+");
2733
2734 // Bits [13].
2735 if (isGFX12Plus()) {
2737 COMPUTE_PGM_RSRC3_GFX12_PLUS_GLG_EN);
2738 } else {
2739 CHECK_RESERVED_BITS_DESC_MSG(COMPUTE_PGM_RSRC3_GFX10_GFX11_RESERVED3,
2740 "COMPUTE_PGM_RSRC3",
2741 "must be zero on gfx10 or gfx11");
2742 }
2743
2744 // Bits [14-21].
2745 if (isGFX1250Plus()) {
2746 PRINT_DIRECTIVE(".amdhsa_named_barrier_count",
2747 COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT);
2749 "ENABLE_DYNAMIC_VGPR", COMPUTE_PGM_RSRC3_GFX125_ENABLE_DYNAMIC_VGPR);
2751 COMPUTE_PGM_RSRC3_GFX125_TCP_SPLIT);
2753 "ENABLE_DIDT_THROTTLE",
2754 COMPUTE_PGM_RSRC3_GFX125_ENABLE_DIDT_THROTTLE);
2755 } else {
2756 CHECK_RESERVED_BITS_DESC_MSG(COMPUTE_PGM_RSRC3_GFX10_GFX120_RESERVED4,
2757 "COMPUTE_PGM_RSRC3",
2758 "must be zero on gfx10+");
2759 }
2760
2761 // Bits [22-30].
2762 CHECK_RESERVED_BITS_DESC_MSG(COMPUTE_PGM_RSRC3_GFX10_PLUS_RESERVED5,
2763 "COMPUTE_PGM_RSRC3", "must be zero on gfx10+");
2764
2765 // Bits [31].
2766 if (isGFX11Plus()) {
2768 COMPUTE_PGM_RSRC3_GFX11_PLUS_IMAGE_OP);
2769 } else {
2770 CHECK_RESERVED_BITS_DESC_MSG(COMPUTE_PGM_RSRC3_GFX10_RESERVED6,
2771 "COMPUTE_PGM_RSRC3",
2772 "must be zero on gfx10");
2773 }
2774 } else if (FourByteBuffer) {
2775 return createStringError(
2776 std::errc::invalid_argument,
2777 "kernel descriptor COMPUTE_PGM_RSRC3 must be all zero before gfx9");
2778 }
2779 return true;
2780}
2781#undef PRINT_PSEUDO_DIRECTIVE_COMMENT
2782#undef PRINT_DIRECTIVE
2783#undef GET_FIELD
2784#undef CHECK_RESERVED_BITS_IMPL
2785#undef CHECK_RESERVED_BITS
2786#undef CHECK_RESERVED_BITS_MSG
2787#undef CHECK_RESERVED_BITS_DESC
2788#undef CHECK_RESERVED_BITS_DESC_MSG
2789
2790/// Create an error object to return from onSymbolStart for reserved kernel
2791/// descriptor bits being set.
2792static Error createReservedKDBitsError(uint32_t Mask, unsigned BaseBytes,
2793 const char *Msg = "") {
2794 return createStringError(
2795 std::errc::invalid_argument, "kernel descriptor reserved %s set%s%s",
2796 getBitRangeFromMask(Mask, BaseBytes).c_str(), *Msg ? ", " : "", Msg);
2797}
2798
2799/// Create an error object to return from onSymbolStart for reserved kernel
2800/// descriptor bytes being set.
2801static Error createReservedKDBytesError(unsigned BaseInBytes,
2802 unsigned WidthInBytes) {
2803 // Create an error comment in the same format as the "Kernel Descriptor"
2804 // table here: https://llvm.org/docs/AMDGPUUsage.html#kernel-descriptor .
2805 return createStringError(
2806 std::errc::invalid_argument,
2807 "kernel descriptor reserved bits in range (%u:%u) set",
2808 (BaseInBytes + WidthInBytes) * CHAR_BIT - 1, BaseInBytes * CHAR_BIT);
2809}
2810
2813 raw_string_ostream &KdStream) const {
2814#define PRINT_DIRECTIVE(DIRECTIVE, MASK) \
2815 do { \
2816 KdStream << Indent << DIRECTIVE " " \
2817 << ((TwoByteBuffer & MASK) >> (MASK##_SHIFT)) << '\n'; \
2818 } while (0)
2819
2820 uint16_t TwoByteBuffer = 0;
2821 uint32_t FourByteBuffer = 0;
2822
2823 StringRef ReservedBytes;
2824 StringRef Indent = "\t";
2825
2826 assert(Bytes.size() == 64);
2827 DataExtractor DE(Bytes, /*IsLittleEndian=*/true);
2828
2829 switch (Cursor.tell()) {
2831 FourByteBuffer = DE.getU32(Cursor);
2832 KdStream << Indent << ".amdhsa_group_segment_fixed_size " << FourByteBuffer
2833 << '\n';
2834 return true;
2835
2837 FourByteBuffer = DE.getU32(Cursor);
2838 KdStream << Indent << ".amdhsa_private_segment_fixed_size "
2839 << FourByteBuffer << '\n';
2840 return true;
2841
2843 FourByteBuffer = DE.getU32(Cursor);
2844 KdStream << Indent << ".amdhsa_kernarg_size "
2845 << FourByteBuffer << '\n';
2846 return true;
2847
2849 // 4 reserved bytes, must be 0.
2850 ReservedBytes = DE.getBytes(Cursor, 4);
2851 for (char B : ReservedBytes) {
2852 if (B != 0)
2854 }
2855 return true;
2856
2858 // KERNEL_CODE_ENTRY_BYTE_OFFSET
2859 // So far no directive controls this for Code Object V3, so simply skip for
2860 // disassembly.
2861 DE.skip(Cursor, 8);
2862 return true;
2863
2865 // 20 reserved bytes, must be 0.
2866 ReservedBytes = DE.getBytes(Cursor, 20);
2867 for (char B : ReservedBytes) {
2868 if (B != 0)
2870 }
2871 return true;
2872
2874 FourByteBuffer = DE.getU32(Cursor);
2875 return decodeCOMPUTE_PGM_RSRC3(FourByteBuffer, KdStream);
2876
2878 FourByteBuffer = DE.getU32(Cursor);
2879 return decodeCOMPUTE_PGM_RSRC1(FourByteBuffer, KdStream);
2880
2882 FourByteBuffer = DE.getU32(Cursor);
2883 return decodeCOMPUTE_PGM_RSRC2(FourByteBuffer, KdStream);
2884
2886 using namespace amdhsa;
2887 TwoByteBuffer = DE.getU16(Cursor);
2888
2890 PRINT_DIRECTIVE(".amdhsa_user_sgpr_private_segment_buffer",
2891 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER);
2892 PRINT_DIRECTIVE(".amdhsa_user_sgpr_dispatch_ptr",
2893 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_PTR);
2894 PRINT_DIRECTIVE(".amdhsa_user_sgpr_queue_ptr",
2895 KERNEL_CODE_PROPERTY_ENABLE_SGPR_QUEUE_PTR);
2896 PRINT_DIRECTIVE(".amdhsa_user_sgpr_kernarg_segment_ptr",
2897 KERNEL_CODE_PROPERTY_ENABLE_SGPR_KERNARG_SEGMENT_PTR);
2898 PRINT_DIRECTIVE(".amdhsa_user_sgpr_dispatch_id",
2899 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_ID);
2901 PRINT_DIRECTIVE(".amdhsa_user_sgpr_flat_scratch_init",
2902 KERNEL_CODE_PROPERTY_ENABLE_SGPR_FLAT_SCRATCH_INIT);
2903 PRINT_DIRECTIVE(".amdhsa_user_sgpr_private_segment_size",
2904 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_SIZE);
2905
2906 if (TwoByteBuffer & KERNEL_CODE_PROPERTY_RESERVED0)
2907 return createReservedKDBitsError(KERNEL_CODE_PROPERTY_RESERVED0,
2909
2910 // Reserved for GFX9
2911 if (isGFX9() &&
2912 (TwoByteBuffer & KERNEL_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32)) {
2914 KERNEL_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32,
2915 amdhsa::KERNEL_CODE_PROPERTIES_OFFSET, "must be zero on gfx9");
2916 }
2917 if (isGFX10Plus()) {
2918 PRINT_DIRECTIVE(".amdhsa_wavefront_size32",
2919 KERNEL_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32);
2920 }
2921
2922 if (CodeObjectVersion >= AMDGPU::AMDHSA_COV5)
2923 PRINT_DIRECTIVE(".amdhsa_uses_dynamic_stack",
2924 KERNEL_CODE_PROPERTY_USES_DYNAMIC_STACK);
2925
2926 if (TwoByteBuffer & KERNEL_CODE_PROPERTY_RESERVED1) {
2927 return createReservedKDBitsError(KERNEL_CODE_PROPERTY_RESERVED1,
2929 }
2930
2931 return true;
2932
2934 using namespace amdhsa;
2935 TwoByteBuffer = DE.getU16(Cursor);
2936 if (TwoByteBuffer & KERNARG_PRELOAD_SPEC_LENGTH) {
2937 PRINT_DIRECTIVE(".amdhsa_user_sgpr_kernarg_preload_length",
2938 KERNARG_PRELOAD_SPEC_LENGTH);
2939 }
2940
2941 if (TwoByteBuffer & KERNARG_PRELOAD_SPEC_OFFSET) {
2942 PRINT_DIRECTIVE(".amdhsa_user_sgpr_kernarg_preload_offset",
2943 KERNARG_PRELOAD_SPEC_OFFSET);
2944 }
2945 return true;
2946
2948 // 4 bytes from here are reserved, must be 0.
2949 ReservedBytes = DE.getBytes(Cursor, 4);
2950 for (char B : ReservedBytes) {
2951 if (B != 0)
2953 }
2954 return true;
2955
2956 default:
2957 llvm_unreachable("Unhandled index. Case statements cover everything.");
2958 return true;
2959 }
2960#undef PRINT_DIRECTIVE
2961}
2962
2964 StringRef KdName, ArrayRef<uint8_t> Bytes, uint64_t KdAddress) const {
2965
2966 // CP microcode requires the kernel descriptor to be 64 aligned.
2967 if (Bytes.size() != 64 || KdAddress % 64 != 0)
2968 return createStringError(std::errc::invalid_argument,
2969 "kernel descriptor must be 64-byte aligned");
2970
2971 // FIXME: We can't actually decode "in order" as is done below, as e.g. GFX10
2972 // requires us to know the setting of .amdhsa_wavefront_size32 in order to
2973 // accurately produce .amdhsa_next_free_vgpr, and they appear in the wrong
2974 // order. Workaround this by first looking up .amdhsa_wavefront_size32 here
2975 // when required.
2976 if (isGFX10Plus()) {
2977 uint16_t KernelCodeProperties =
2980 EnableWavefrontSize32 =
2981 AMDHSA_BITS_GET(KernelCodeProperties,
2982 amdhsa::KERNEL_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32);
2983 }
2984
2985 std::string Kd;
2986 raw_string_ostream KdStream(Kd);
2987 KdStream << ".amdhsa_kernel " << KdName << '\n';
2988
2990 while (C && C.tell() < Bytes.size()) {
2991 Expected<bool> Res = decodeKernelDescriptorDirective(C, Bytes, KdStream);
2992
2993 cantFail(C.takeError());
2994
2995 if (!Res)
2996 return Res;
2997 }
2998 KdStream << ".end_amdhsa_kernel\n";
2999 outs() << KdStream.str();
3000 return true;
3001}
3002
3004 uint64_t &Size,
3005 ArrayRef<uint8_t> Bytes,
3006 uint64_t Address) const {
3007 // Right now only kernel descriptor needs to be handled.
3008 // We ignore all other symbols for target specific handling.
3009 // TODO:
3010 // Fix the spurious symbol issue for AMDGPU kernels. Exists for both Code
3011 // Object V2 and V3 when symbols are marked protected.
3012
3013 // amd_kernel_code_t for Code Object V2.
3014 if (Symbol.Type == ELF::STT_AMDGPU_HSA_KERNEL) {
3015 Size = 256;
3016 return createStringError(std::errc::invalid_argument,
3017 "code object v2 is not supported");
3018 }
3019
3020 // Code Object V3 kernel descriptors.
3021 StringRef Name = Symbol.Name;
3022 if (Symbol.Type == ELF::STT_OBJECT && Name.ends_with(StringRef(".kd"))) {
3023 Size = 64; // Size = 64 regardless of success or failure.
3024 return decodeKernelDescriptor(Name.drop_back(3), Bytes, Address);
3025 }
3026
3027 return false;
3028}
3029
3030const MCExpr *AMDGPUDisassembler::createConstantSymbolExpr(StringRef Id,
3031 int64_t Val) {
3032 MCContext &Ctx = getContext();
3033 MCSymbol *Sym = Ctx.getOrCreateSymbol(Id);
3034 // Note: only set value to Val on a new symbol in case an dissassembler
3035 // has already been initialized in this context.
3036 if (!Sym->isVariable()) {
3038 } else {
3039 int64_t Res = ~Val;
3040 bool Valid = Sym->getVariableValue()->evaluateAsAbsolute(Res);
3041 if (!Valid || Res != Val)
3042 Ctx.reportWarning(SMLoc(), "unsupported redefinition of " + Id);
3043 }
3044 return MCSymbolRefExpr::create(Sym, Ctx);
3045}
3046
3048 // Check for MUBUF and MTBUF instructions
3049 if (SIInstrFlags::isBuffer(*MCII, MI))
3050 return true;
3051
3052 // Check for SMEM buffer instructions (S_BUFFER_* instructions)
3053 if (SIInstrFlags::isSMRD(*MCII, MI) &&
3054 AMDGPU::getSMEMIsBuffer(MI.getOpcode()))
3055 return true;
3056
3057 return false;
3058}
3059
3060//===----------------------------------------------------------------------===//
3061// AMDGPUSymbolizer
3062//===----------------------------------------------------------------------===//
3063
3064// Try to find symbol name for specified label
3066 MCInst &Inst, raw_ostream & /*cStream*/, int64_t Value,
3067 uint64_t /*Address*/, bool IsBranch, uint64_t /*Offset*/,
3068 uint64_t /*OpSize*/, uint64_t /*InstSize*/) {
3069
3070 if (!IsBranch) {
3071 return false;
3072 }
3073
3074 auto *Symbols = static_cast<SectionSymbolsTy *>(DisInfo);
3075 if (!Symbols)
3076 return false;
3077
3078 auto Result = llvm::find_if(*Symbols, [Value](const SymbolInfoTy &Val) {
3079 return Val.Addr == static_cast<uint64_t>(Value) &&
3080 Val.Type == ELF::STT_NOTYPE;
3081 });
3082 if (Result != Symbols->end()) {
3083 auto *Sym = Ctx.getOrCreateSymbol(Result->Name);
3084 const auto *Add = MCSymbolRefExpr::create(Sym, Ctx);
3086 return true;
3087 }
3088 // Add to list of referenced addresses, so caller can synthesize a label.
3089 ReferencedAddresses.push_back(static_cast<uint64_t>(Value));
3090 return false;
3091}
3092
3094 int64_t Value,
3095 uint64_t Address) {
3096 llvm_unreachable("unimplemented");
3097}
3098
3099//===----------------------------------------------------------------------===//
3100// Initialization
3101//===----------------------------------------------------------------------===//
3102
3104 LLVMOpInfoCallback /*GetOpInfo*/,
3105 LLVMSymbolLookupCallback /*SymbolLookUp*/,
3106 void *DisInfo,
3107 MCContext *Ctx,
3108 std::unique_ptr<MCRelocationInfo> &&RelInfo) {
3109 return new AMDGPUSymbolizer(*Ctx, std::move(RelInfo), DisInfo);
3110}
3111
3113 const MCSubtargetInfo &STI,
3114 MCContext &Ctx) {
3115 return new AMDGPUDisassembler(STI, Ctx, T.createMCInstrInfo());
3116}
3117
3118extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void
MCDisassembler::DecodeStatus DecodeStatus
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
aarch64 promote const
#define CHECK_RESERVED_BITS_DESC(MASK, DESC)
static VOPModifiers collectVOPModifiers(const MCInst &MI, bool IsVOP3P=false)
static int insertNamedMCOperand(MCInst &MI, const MCOperand &Op, AMDGPU::OpName Name)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAMDGPUDisassembler()
static DecodeStatus decodeOperand_VSrcT16_Lo128(MCInst &Inst, unsigned Imm, uint64_t, const MCDisassembler *Decoder)
static DecodeStatus decodeOperand_KImmFP64(MCInst &Inst, uint64_t Imm, uint64_t Addr, const MCDisassembler *Decoder)
static SmallString< 32 > getBitRangeFromMask(uint32_t Mask, unsigned BaseBytes)
Print a string describing the reserved bit range specified by Mask with offset BaseBytes for use in e...
#define DECODE_OPERAND_SREG_8(RegClass, OpWidth)
static DecodeStatus decodeSMEMOffset(MCInst &Inst, unsigned Imm, uint64_t Addr, const MCDisassembler *Decoder)
static std::bitset< 128 > eat16Bytes(ArrayRef< uint8_t > &Bytes)
static DecodeStatus decodeVersionImm(MCInst &Inst, unsigned Imm, uint64_t, const MCDisassembler *Decoder)
#define DECODE_OPERAND_SREG_7(RegClass, OpWidth)
static DecodeStatus decodeSrcA9(MCInst &Inst, unsigned Imm, uint64_t, const MCDisassembler *Decoder)
static DecodeStatus decodeOperand_VGPR_16(MCInst &Inst, unsigned Imm, uint64_t, const MCDisassembler *Decoder)
#define PRINT_PSEUDO_DIRECTIVE_COMMENT(DIRECTIVE, MASK)
static DecodeStatus decodeSrcOp(MCInst &Inst, unsigned EncSize, unsigned OpWidth, unsigned Imm, unsigned EncImm, const MCDisassembler *Decoder)
static DecodeStatus decodeDpp8FI(MCInst &Inst, unsigned Val, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus decodeOperand_VSrc_f64(MCInst &Inst, unsigned Imm, uint64_t Addr, const MCDisassembler *Decoder)
static MCRegister CheckVGPROverflow(MCRegister Reg, const MCRegisterClass &RC, const MCRegisterInfo &MRI)
static int64_t getInlineImmValBF16(unsigned Imm)
#define DECODE_SDWA(DecName)
static DecodeStatus decodeSOPPBrTarget(MCInst &Inst, unsigned Imm, uint64_t Addr, const MCDisassembler *Decoder)
#define DECODE_OPERAND_REG_8(RegClass)
#define PRINT_DIRECTIVE(DIRECTIVE, MASK)
static DecodeStatus decodeSrcRegOrImm9(MCInst &Inst, unsigned Imm, uint64_t, const MCDisassembler *Decoder)
static DecodeStatus DecodeVGPR_16RegisterClass(MCInst &Inst, unsigned Imm, uint64_t, const MCDisassembler *Decoder)
static DecodeStatus decodeSrcReg9(MCInst &Inst, unsigned Imm, uint64_t, const MCDisassembler *Decoder)
static int64_t getInlineImmVal32(unsigned Imm)
static MCDisassembler::DecodeStatus addOperand(MCInst &Inst, const MCOperand &Opnd)
#define CHECK_RESERVED_BITS(MASK)
static DecodeStatus decodeSrcAV10(MCInst &Inst, unsigned Imm, uint64_t, const MCDisassembler *Decoder)
#define SGPR_MAX
static int64_t getInlineImmVal64(unsigned Imm)
static T eatBytes(ArrayRef< uint8_t > &Bytes)
static DecodeStatus decodeOperand_KImmFP(MCInst &Inst, unsigned Imm, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus decodeAVLdSt(MCInst &Inst, unsigned Imm, unsigned Opw, const MCDisassembler *Decoder)
static MCDisassembler * createAMDGPUDisassembler(const Target &T, const MCSubtargetInfo &STI, MCContext &Ctx)
static DecodeStatus decodeSrcRegOrImmA9(MCInst &Inst, unsigned Imm, uint64_t, const MCDisassembler *Decoder)
static DecodeStatus DecodeVGPR_16_Lo128RegisterClass(MCInst &Inst, unsigned Imm, uint64_t, const MCDisassembler *Decoder)
#define CHECK_RESERVED_BITS_MSG(MASK, MSG)
static DecodeStatus decodeOperandVOPDDstY(MCInst &Inst, unsigned Val, uint64_t Addr, const void *Decoder)
static MCSymbolizer * createAMDGPUSymbolizer(const Triple &, LLVMOpInfoCallback, LLVMSymbolLookupCallback, void *DisInfo, MCContext *Ctx, std::unique_ptr< MCRelocationInfo > &&RelInfo)
static DecodeStatus decodeBoolReg(MCInst &Inst, unsigned Val, uint64_t Addr, const MCDisassembler *Decoder)
static int64_t getInlineImmValF16(unsigned Imm)
#define GET_FIELD(MASK)
static std::bitset< 96 > eat12Bytes(ArrayRef< uint8_t > &Bytes)
static DecodeStatus decodeOperand_VSrcT16(MCInst &Inst, unsigned Imm, uint64_t, const MCDisassembler *Decoder)
static Error createReservedKDBytesError(unsigned BaseInBytes, unsigned WidthInBytes)
Create an error object to return from onSymbolStart for reserved kernel descriptor bytes being set.
static DecodeStatus decodeSplitBarrier(MCInst &Inst, unsigned Val, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus decodeAV10(MCInst &Inst, unsigned Imm, uint64_t, const MCDisassembler *Decoder)
static bool adjustMFMA_F8F6F4OpRegClass(const MCRegisterInfo &MRI, MCOperand &MO, uint8_t NumRegs)
Adjust the register values used by V_MFMA_F8F6F4_f8_f8 instructions to the appropriate subregister fo...
#define CHECK_RESERVED_BITS_DESC_MSG(MASK, DESC, MSG)
static Error createReservedKDBitsError(uint32_t Mask, unsigned BaseBytes, const char *Msg="")
Create an error object to return from onSymbolStart for reserved kernel descriptor bits being set.
This file contains declaration for AMDGPU ISA disassembler.
Provides AMDGPU specific target descriptions.
static cl::opt< bool > XnackSetting("amdgpu-xnack", cl::desc("Force amdgpu.xnack value for testing"), cl::ReallyHidden)
AMDHSA kernel descriptor definitions.
#define AMDHSA_BITS_GET(SRC, MSK)
#define X(NUM, ENUM, NAME)
Definition ELF.h:856
#define AMDGPU_MACH_LIST(X)
Definition ELF.h:768
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_ABI
Definition Compiler.h:215
#define LLVM_EXTERNAL_VISIBILITY
Definition Compiler.h:132
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition MD5.cpp:57
Register Reg
#define T
Interface definition for SIRegisterInfo.
const char * Msg
std::optional< unsigned > getSgprClassId(unsigned Width) const
Return the SGPR/TTMP register class accepted by source decoding for Width, or std::nullopt if that wi...
MCOperand decodeNonVGPRSrcOp(const MCInst &Inst, unsigned Width, unsigned Val) const
MCOperand decodeLiteral64Constant() const
void convertVOPC64DPPInst(MCInst &MI) const
bool isBufferInstruction(const MCInst &MI) const
Check if the instruction is a buffer operation (MUBUF, MTBUF, or S_BUFFER)
void convertEXPInst(MCInst &MI) const
MCOperand decodeSpecialReg64(unsigned Val) const
const char * getRegClassName(unsigned RegClassID) const
Expected< bool > decodeCOMPUTE_PGM_RSRC1(uint32_t FourByteBuffer, raw_string_ostream &KdStream) const
Decode as directives that handle COMPUTE_PGM_RSRC1.
MCOperand decodeSplitBarrier(const MCInst &Inst, unsigned Val) const
Expected< bool > decodeKernelDescriptorDirective(DataExtractor::Cursor &Cursor, ArrayRef< uint8_t > Bytes, raw_string_ostream &KdStream) const
void convertVOPCDPPInst(MCInst &MI) const
MCOperand decodeSpecialReg96Plus(unsigned Val) const
MCOperand decodeSDWASrc32(unsigned Val) const
void setABIVersion(unsigned Version) override
ELF-specific, set the ABI version from the object header.
Expected< bool > decodeCOMPUTE_PGM_RSRC2(uint32_t FourByteBuffer, raw_string_ostream &KdStream) const
Decode as directives that handle COMPUTE_PGM_RSRC2.
unsigned getAgprClassId(unsigned Width) const
MCOperand decodeDpp8FI(unsigned Val) const
MCOperand decodeSDWASrc(unsigned Width, unsigned Val) const
void convertFMAanyK(MCInst &MI) const
DecodeStatus tryDecodeInst(const uint8_t *Table, MCInst &MI, InsnType Inst, uint64_t Address, raw_ostream &Comments) const
void convertMacDPPInst(MCInst &MI) const
MCOperand decodeVOPDDstYOp(MCInst &Inst, unsigned Val) const
void convertDPP8Inst(MCInst &MI) const
MCOperand createVGPR16Operand(unsigned RegIdx, bool IsHi) const
MCOperand errOperand(unsigned V, const Twine &ErrMsg) const
MCOperand decodeVersionImm(unsigned Imm) const
Expected< bool > decodeKernelDescriptor(StringRef KdName, ArrayRef< uint8_t > Bytes, uint64_t KdAddress) const
void convertVOP3DPPInst(MCInst &MI) const
void convertTrue16OpSel(MCInst &MI) const
MCOperand decodeSrcOp(const MCInst &Inst, unsigned Width, unsigned Val) const
bool convertMAIInst(MCInst &MI) const
f8f6f4 instructions have different pseudos depending on the used formats.
MCOperand decodeMandatoryLiteralConstant(unsigned Imm) const
MCOperand decodeLiteralConstant(const MCInstrDesc &Desc, const MCOperandInfo &OpDesc) const
Expected< bool > decodeCOMPUTE_PGM_RSRC3(uint32_t FourByteBuffer, raw_string_ostream &KdStream) const
Decode as directives that handle COMPUTE_PGM_RSRC3.
AMDGPUDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, MCInstrInfo const *MCII)
MCOperand decodeSpecialReg32(unsigned Val) const
MCOperand createRegOperand(MCRegister Reg) const
MCOperand decodeSDWAVopcDst(unsigned Val) const
void convertVINTERPInst(MCInst &MI) const
void convertSDWAInst(MCInst &MI) const
static MCOperand decodeIntImmed(unsigned Imm)
MCOperand decodeBoolReg(const MCInst &Inst, unsigned Val) const
void emitTargetIDIfSupported(raw_ostream &OS, unsigned EFlags) const override
Emit something based on ELF's e_flags if the target needs to.
unsigned getVgprClassId(unsigned Width) const
DecodeStatus getInstruction(MCInst &MI, uint64_t &Size, ArrayRef< uint8_t > Bytes, uint64_t Address, raw_ostream &CS) const override
Returns the disassembly of a single instruction.
std::optional< unsigned > getTtmpClassId(unsigned Width) const
MCOperand decodeMandatoryLiteral64Constant(uint64_t Imm) const
void convertMIMGInst(MCInst &MI) const
bool isMacDPP(MCInst &MI) const
int getTTmpIdx(unsigned Val) const
void convertVOP3PDPPInst(MCInst &MI) const
bool convertWMMAInst(MCInst &MI) const
MCOperand createSRegOperand(unsigned SRegClassID, unsigned Val) const
MCOperand decodeSDWASrc16(unsigned Val) const
Expected< bool > onSymbolStart(SymbolInfoTy &Symbol, uint64_t &Size, ArrayRef< uint8_t > Bytes, uint64_t Address) const override
Used to perform separate target specific disassembly for a particular symbol.
static const AMDGPUMCExpr * createLit(LitModifier Lit, int64_t Value, MCContext &Ctx)
bool tryAddingSymbolicOperand(MCInst &Inst, raw_ostream &cStream, int64_t Value, uint64_t Address, bool IsBranch, uint64_t Offset, uint64_t OpSize, uint64_t InstSize) override
Try to add a symbolic operand instead of Value to the MCInst.
void tryAddingPcLoadReferenceComment(raw_ostream &cStream, int64_t Value, uint64_t Address) override
Try to add a comment on the PC-relative load.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
Get the array size.
Definition ArrayRef.h:141
const T * data() const
Definition ArrayRef.h:138
ArrayRef< T > slice(size_t N, size_t M) const
slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array.
Definition ArrayRef.h:185
A class representing a position in a DataExtractor, as well as any error encountered during extractio...
LLVM_ABI uint32_t getU32(uint64_t *offset_ptr, Error *Err=nullptr) const
Extract a uint32_t value from *offset_ptr.
LLVM_ABI uint16_t getU16(uint64_t *offset_ptr, Error *Err=nullptr) const
Extract a uint16_t value from *offset_ptr.
LLVM_ABI void skip(Cursor &C, uint64_t Length) const
Advance the Cursor position by the given number of bytes.
LLVM_ABI StringRef getBytes(uint64_t *OffsetPtr, uint64_t Length, Error *Err=nullptr) const
Extract a fixed number of bytes from the specified offset.
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
Tagged union holding either a T or a Error.
Definition Error.h:485
static const MCBinaryExpr * createOr(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition MCExpr.h:407
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition MCExpr.cpp:212
Context object for machine code objects.
Definition MCContext.h:83
const MCRegisterInfo * getRegisterInfo() const
Definition MCContext.h:411
Superclass for all disassemblers.
MCDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
MCContext & getContext() const
const MCSubtargetInfo & STI
raw_ostream * CommentStream
DecodeStatus
Ternary decode status.
Base class for the full range of assembler expressions which are needed for parsing.
Definition MCExpr.h:34
Instances of this class represent a single low-level machine instruction.
Definition MCInst.h:188
unsigned getOpcode() const
Definition MCInst.h:202
void addOperand(const MCOperand Op)
Definition MCInst.h:215
const MCOperand & getOperand(unsigned i) const
Definition MCInst.h:210
Describe properties that are true of each instruction in the target description file.
Interface to description of machine instruction set.
Definition MCInstrInfo.h:27
This holds information about one operand of a machine instruction, indicating the register class for ...
Definition MCInstrDesc.h:86
uint8_t OperandType
Information about the type of the operand.
Definition MCInstrDesc.h:98
Instances of this class represent operands of the MCInst class.
Definition MCInst.h:40
static MCOperand createExpr(const MCExpr *Val)
Definition MCInst.h:166
int64_t getImm() const
Definition MCInst.h:84
static MCOperand createReg(MCRegister Reg)
Definition MCInst.h:138
static MCOperand createImm(int64_t Val)
Definition MCInst.h:145
void setReg(MCRegister Reg)
Set the register number.
Definition MCInst.h:79
bool isReg() const
Definition MCInst.h:65
MCRegister getReg() const
Returns the register number.
Definition MCInst.h:73
bool isValid() const
Definition MCInst.h:64
MCRegisterClass - Base class of TargetRegisterClass.
MCRegister getRegister(unsigned i) const
getRegister - Return the specified register in the class.
unsigned getSizeInBits() const
Return the size of the physical register in bits if we are able to determine it.
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
MCRegister getMatchingSuperReg(MCRegister Reg, unsigned SubIdx, const MCRegisterClass *RC) const
Return a super-register of the specified register Reg so its sub-register of index SubIdx is Reg.
const char * getRegClassName(const MCRegisterClass *Class) const
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
Generic base class for all target subtargets.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.h:213
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition MCSymbol.h:42
bool isVariable() const
isVariable - Check if this is a variable symbol.
Definition MCSymbol.h:267
LLVM_ABI void setVariableValue(const MCExpr *Value)
Definition MCSymbol.cpp:50
const MCExpr * getVariableValue() const
Get the expression of the variable symbol.
Definition MCSymbol.h:270
Symbolize and annotate disassembled instructions.
Represents a location in source code.
Definition SMLoc.h:22
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition SmallString.h:26
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Target - Wrapper for Target specific information.
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
LLVM Value Representation.
Definition Value.h:75
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
A raw_ostream that writes to an std::string.
std::string & str()
Returns the string's reference.
A raw_ostream that writes to an SmallVector or SmallString.
const char *(* LLVMSymbolLookupCallback)(void *DisInfo, uint64_t ReferenceValue, uint64_t *ReferenceType, uint64_t ReferencePC, const char **ReferenceName)
The type for the symbol lookup function.
int(* LLVMOpInfoCallback)(void *DisInfo, uint64_t PC, uint64_t Offset, uint64_t OpSize, uint64_t InstSize, int TagType, void *TagBuf)
The type for the operand information call back function.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned getVGPREncodingGranule(const MCSubtargetInfo &STI, std::optional< bool > EnableWavefrontSize32)
unsigned getSGPREncodingGranule(const MCSubtargetInfo &STI)
ArrayRef< GFXVersion > getGFXVersions()
bool isInlinableLiteralBF16(int16_t Literal, bool HasInv2Pi)
EncodingField< Bit, Bit, D > EncodingBit
bool isPKFMACF16InlineConstant(uint32_t Literal, bool IsGFX11Plus)
LLVM_READONLY const MIMGInfo * getMIMGInfo(unsigned Opc)
bool isInlinableLiteralFP16(int16_t Literal, bool HasInv2Pi)
MCRegister getMCReg(MCRegister Reg, const MCSubtargetInfo &STI)
If Reg is a pseudo reg, return the correct hardware register given STI otherwise return Reg.
int getMIMGOpcode(unsigned BaseOpcode, unsigned MIMGEncoding, unsigned VDataDwords, unsigned VAddrDwords)
bool isInlinableLiteralV2I16(uint32_t Literal)
bool isGFX10(const MCSubtargetInfo &STI)
bool isInlinableLiteralV2BF16(uint32_t Literal)
bool isGFX12Plus(const MCSubtargetInfo &STI)
bool hasPackedD16(const MCSubtargetInfo &STI)
bool isInlinableLiteralV2F16(uint32_t Literal)
bool getSMEMIsBuffer(unsigned Opc)
bool isGFX13(const MCSubtargetInfo &STI)
bool isVOPC64DPP(unsigned Opc)
bool hasPrivateApertureRegs(const MCSubtargetInfo &STI)
unsigned getAMDHSACodeObjectVersion(const Module &M)
LLVM_READONLY bool hasNamedOperand(uint64_t Opcode, OpName NamedIdx)
bool isGFX9(const MCSubtargetInfo &STI)
LLVM_READONLY const MIMGDimInfo * getMIMGDimInfoByEncoding(uint8_t DimEnc)
bool isInlinableLiteral32(int32_t Literal, bool HasInv2Pi)
const MFMA_F8F6F4_Info * getWMMA_F8F6F4_WithFormatArgs(unsigned FmtA, unsigned FmtB, unsigned F8F8Opcode)
bool hasG16(const MCSubtargetInfo &STI)
unsigned getAddrSizeMIMGOp(const MIMGBaseOpcodeInfo *BaseOpcode, const MIMGDimInfo *Dim, bool IsA16, bool IsG16Supported)
bool isGFX13Plus(const MCSubtargetInfo &STI)
bool isGFX11Plus(const MCSubtargetInfo &STI)
bool isGFX10Plus(const MCSubtargetInfo &STI)
@ OPERAND_REG_IMM_V2FP64
Definition SIDefines.h:447
@ OPERAND_KIMM32
Operand with 32-bit immediate that uses the constant bus.
Definition SIDefines.h:465
@ OPERAND_REG_IMM_INT64
Definition SIDefines.h:433
@ OPERAND_REG_IMM_V2FP16
Definition SIDefines.h:440
@ OPERAND_REG_INLINE_C_FP64
Definition SIDefines.h:456
@ OPERAND_REG_INLINE_C_BF16
Definition SIDefines.h:453
@ OPERAND_REG_INLINE_C_V2BF16
Definition SIDefines.h:458
@ OPERAND_REG_IMM_V2INT64
Definition SIDefines.h:443
@ OPERAND_REG_IMM_V2INT16
Definition SIDefines.h:442
@ OPERAND_REG_IMM_BF16
Definition SIDefines.h:437
@ OPERAND_REG_IMM_INT32
Operands with register, 32-bit, or 64-bit immediate.
Definition SIDefines.h:432
@ OPERAND_REG_IMM_V2BF16
Definition SIDefines.h:439
@ OPERAND_REG_IMM_FP16
Definition SIDefines.h:438
@ OPERAND_REG_IMM_V2FP16_SPLAT
Definition SIDefines.h:441
@ OPERAND_REG_INLINE_C_INT64
Definition SIDefines.h:452
@ OPERAND_REG_INLINE_C_INT16
Operands with register or inline constant.
Definition SIDefines.h:450
@ OPERAND_REG_IMM_NOINLINE_V2FP16
Definition SIDefines.h:444
@ OPERAND_REG_IMM_FP64
Definition SIDefines.h:436
@ OPERAND_REG_INLINE_C_V2FP16
Definition SIDefines.h:459
@ OPERAND_REG_INLINE_AC_INT32
Operands with an AccVGPR register or inline constant.
Definition SIDefines.h:470
@ OPERAND_REG_INLINE_AC_FP32
Definition SIDefines.h:471
@ OPERAND_REG_IMM_V2INT32
Definition SIDefines.h:445
@ OPERAND_REG_IMM_FP32
Definition SIDefines.h:435
@ OPERAND_REG_INLINE_C_FP32
Definition SIDefines.h:455
@ OPERAND_REG_INLINE_C_INT32
Definition SIDefines.h:451
@ OPERAND_REG_INLINE_C_V2INT16
Definition SIDefines.h:457
@ OPERAND_REG_IMM_V2FP32
Definition SIDefines.h:446
@ OPERAND_REG_INLINE_AC_FP64
Definition SIDefines.h:472
@ OPERAND_REG_INLINE_C_FP16
Definition SIDefines.h:454
@ OPERAND_REG_IMM_INT16
Definition SIDefines.h:434
bool hasGDS(const MCSubtargetInfo &STI)
bool isGFX9Plus(const MCSubtargetInfo &STI)
bool isVOPD(unsigned Opc)
bool isGFX1250(const MCSubtargetInfo &STI)
unsigned hasKernargPreload(const MCSubtargetInfo &STI)
bool isMAC(unsigned Opc)
LLVM_READONLY const MIMGBaseOpcodeInfo * getMIMGBaseOpcodeInfo(unsigned BaseOpcode)
bool isGFX1250Plus(const MCSubtargetInfo &STI)
bool hasPopsExitingWaveID(const MCSubtargetInfo &STI)
bool isInlinableLiteralI16(int32_t Literal, bool HasInv2Pi)
bool hasVOPD(const MCSubtargetInfo &STI)
bool isInlinableLiteral64(int64_t Literal, bool HasInv2Pi)
Is this literal inlinable.
const MFMA_F8F6F4_Info * getMFMA_F8F6F4_WithFormatArgs(unsigned CBSZ, unsigned BLGP, unsigned F8F8Opcode)
@ STT_NOTYPE
Definition ELF.h:1426
@ STT_AMDGPU_HSA_KERNEL
Definition ELF.h:1440
@ STT_OBJECT
Definition ELF.h:1427
@ EF_AMDGPU_FEATURE_XNACK_ANY_V4
Definition ELF.h:909
@ EF_AMDGPU_FEATURE_SRAMECC_UNSUPPORTED_V4
Definition ELF.h:920
@ EF_AMDGPU_FEATURE_SRAMECC_OFF_V4
Definition ELF.h:924
@ EF_AMDGPU_FEATURE_XNACK_UNSUPPORTED_V4
Definition ELF.h:907
@ EF_AMDGPU_FEATURE_XNACK_OFF_V4
Definition ELF.h:911
@ EF_AMDGPU_FEATURE_XNACK_V4
Definition ELF.h:905
@ EF_AMDGPU_FEATURE_SRAMECC_V4
Definition ELF.h:918
@ EF_AMDGPU_FEATURE_XNACK_ON_V4
Definition ELF.h:913
@ EF_AMDGPU_MACH
Definition ELF.h:851
@ EF_AMDGPU_FEATURE_SRAMECC_ANY_V4
Definition ELF.h:922
@ EF_AMDGPU_FEATURE_SRAMECC_ON_V4
Definition ELF.h:926
constexpr bool isAtomicRet(const T &...O)
Definition SIDefines.h:368
constexpr bool isVOPC(const T &...O)
Definition SIDefines.h:237
constexpr bool isVOP3(const T &...O)
Definition SIDefines.h:240
constexpr bool isMAI(const T &...O)
Definition SIDefines.h:356
constexpr bool isFLAT(const T &...O)
Definition SIDefines.h:287
constexpr bool isVOP3P(const T &...O)
Definition SIDefines.h:243
constexpr bool isBuffer(const T &...O)
Definition SIDefines.h:268
constexpr bool isVIMAGE(const T &...O)
Definition SIDefines.h:278
constexpr bool isSMRD(const T &...O)
Definition SIDefines.h:272
constexpr bool isVOP3Like(const T &...O)
Definition SIDefines.h:246
constexpr bool isMIMG(const T &...O)
Definition SIDefines.h:275
constexpr bool isWMMA(const T &...O)
Definition SIDefines.h:371
constexpr bool isMUBUF(const T &...O)
Definition SIDefines.h:262
constexpr bool isSDWA(const T &...O)
Definition SIDefines.h:253
constexpr bool isEXP(const T &...O)
Definition SIDefines.h:284
constexpr bool isSOPK(const T &...O)
Definition SIDefines.h:225
constexpr bool isVINTERP(const T &...O)
Definition SIDefines.h:299
constexpr bool isVSAMPLE(const T &...O)
Definition SIDefines.h:281
constexpr bool isDS(const T &...O)
Definition SIDefines.h:290
constexpr bool isGather4(const T &...O)
Definition SIDefines.h:308
constexpr bool isDPP(const T &...O)
Definition SIDefines.h:256
value_type read(const void *memory, endianness endian)
Read a value of a particular endianness from memory.
Definition Endian.h:53
uint16_t read16(const void *P, endianness E)
Definition Endian.h:389
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:578
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Definition STLExtras.h:2554
LLVM_ABI raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
SmallVectorImpl< T >::const_pointer c_str(SmallVectorImpl< T > &str)
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition Error.h:1321
Op::Description Desc
constexpr int popcount(T Value) noexcept
Count the number of set bits in a value.
Definition bit.h:156
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
Definition bit.h:204
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
Definition MathExtras.h:151
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:190
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
Definition Error.h:769
Target & getTheGCNTarget()
The target for GCN GPUs.
To bit_cast(const From &from) noexcept
Definition bit.h:90
@ Add
Sum of integers.
DWARFExpression::Operation Op
unsigned M0(unsigned Val)
Definition VE.h:376
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1772
Target & getTheGCNLegacyTarget()
The target for GCN GPUs, registered under the legacy "amdgcn" architecture name for use with -march.
std::vector< SymbolInfoTy > SectionSymbolsTy
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
Definition MathExtras.h:573
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
Definition Error.cpp:177
static void RegisterMCSymbolizer(Target &T, Target::MCSymbolizerCtorTy Fn)
RegisterMCSymbolizer - Register an MCSymbolizer implementation for the given target.
static void RegisterMCDisassembler(Target &T, Target::MCDisassemblerCtorTy Fn)
RegisterMCDisassembler - Register a MCDisassembler implementation for the given target.