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