LLVM 24.0.0git
AMDGPUDisassembler.cpp
Go to the documentation of this file.
1//===- AMDGPUDisassembler.cpp - Disassembler for AMDGPU ISA ---------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9//===----------------------------------------------------------------------===//
10//
11/// \file
12///
13/// This file contains definition for AMDGPU ISA disassembler
14//
15//===----------------------------------------------------------------------===//
16
17// ToDo: What to do with instruction suffixes (v_mov_b32 vs v_mov_b32_e32)?
18
22#include "SIDefines.h"
23#include "SIRegisterInfo.h"
29#include "llvm/MC/MCAsmInfo.h"
30#include "llvm/MC/MCContext.h"
31#include "llvm/MC/MCDecoder.h"
33#include "llvm/MC/MCExpr.h"
34#include "llvm/MC/MCInstrDesc.h"
40
41using namespace llvm;
42using namespace llvm::MCD;
43
44#define DEBUG_TYPE "amdgpu-disassembler"
45
46#define SGPR_MAX \
47 (isGFX10Plus() ? AMDGPU::EncValues::SGPR_MAX_GFX10 \
48 : AMDGPU::EncValues::SGPR_MAX_SI)
49
51
52static int64_t getInlineImmValF16(unsigned Imm);
53static int64_t getInlineImmValBF16(unsigned Imm);
54static int64_t getInlineImmVal32(unsigned Imm);
55static int64_t getInlineImmVal64(unsigned Imm);
56
58 MCContext &Ctx, MCInstrInfo const *MCII)
59 : MCDisassembler(STI, Ctx), MCII(MCII), MRI(*Ctx.getRegisterInfo()),
60 MAI(Ctx.getAsmInfo()),
61 HwModeRegClass(STI.getHwMode(MCSubtargetInfo::HwMode_RegInfo)),
62 TargetMaxInstBytes(MAI.getMaxInstLength(&STI)),
63 CodeObjectVersion(AMDGPU::getDefaultAMDHSACodeObjectVersion()) {
64 // ToDo: AMDGPUDisassembler supports only VI ISA.
65 if (!STI.hasFeature(AMDGPU::FeatureGCN3Encoding) && !isGFX10Plus())
66 reportFatalUsageError("disassembly not yet supported for subtarget");
67
68 for (auto [Symbol, Code] : AMDGPU::UCVersion::getGFXVersions())
69 createConstantSymbolExpr(Symbol, Code);
70
71 UCVersionW64Expr = createConstantSymbolExpr("UC_VERSION_W64_BIT", 0x2000);
72 UCVersionW32Expr = createConstantSymbolExpr("UC_VERSION_W32_BIT", 0x4000);
73 UCVersionMDPExpr = createConstantSymbolExpr("UC_VERSION_MDP_BIT", 0x8000);
74}
75
79
81 unsigned EFlags) const {
82 OS << "\t.amdgcn_target \""
83 << STI.getTargetTriple().normalize(Triple::CanonicalForm::FOUR_IDENT)
84 << '-';
85
86 // Get CPU name from ELF e_flags MACH field
87 unsigned MACH = EFlags & ELF::EF_AMDGPU_MACH;
88
89#define X(NUM, ENUM, NAME) \
90 case ELF::ENUM: \
91 OS << NAME; \
92 break;
93 switch (MACH) {
95 default:
96 OS << "unknown";
97 break;
98 }
99#undef X
100
101 // Add xnack and sramecc from ELF flags (v4 format)
102 if (CodeObjectVersion >= AMDGPU::AMDHSA_COV4) {
103 unsigned SrameccSetting = EFlags & ELF::EF_AMDGPU_FEATURE_SRAMECC_V4;
104 switch (SrameccSetting) {
107 break;
109 OS << ":sramecc-";
110 break;
112 OS << ":sramecc+";
113 break;
114 }
115
117 switch (XnackSetting) {
120 break;
122 OS << ":xnack-";
123 break;
125 OS << ":xnack+";
126 XnackOnFromEFlags = true;
127 break;
128 }
129 }
130
131 OS << "\"\n";
132}
133
135addOperand(MCInst &Inst, const MCOperand& Opnd) {
136 Inst.addOperand(Opnd);
137 return Opnd.isValid() ?
140}
141
143 AMDGPU::OpName Name) {
144 int OpIdx = AMDGPU::getNamedOperandIdx(MI.getOpcode(), Name);
145 if (OpIdx != -1) {
146 auto *I = MI.begin();
147 std::advance(I, OpIdx);
148 MI.insert(I, Op);
149 }
150 return OpIdx;
151}
152
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>(Imm) * 4 + 4 + Addr;
160
161 if (DAsm->tryAddingSymbolicOperand(Inst, Offset, Addr, true, 2, 2, 0))
163 return addOperand(Inst, MCOperand::createImm(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.
172 } else if (DAsm->isVI()) { // VI supports 20-bit unsigned offsets.
173 Offset = Imm & 0xFFFFF;
174 } else { // GFX9+ supports 21-bit signed offsets.
176 }
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, 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, 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, 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, DAsm->decodeSrcOp(Inst, OpWidth, 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, 10, OpWidth, Imm, 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, 9, OpWidth, Imm, 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.
273 return decodeSrcOp(Inst, 9, OpWidth, Imm, 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.
286 return decodeSrcOp(Inst, 10, OpWidth, Imm, 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>
296 uint64_t /* Addr */,
297 const MCDisassembler *Decoder) {
298 return decodeSrcOp(Inst, 9, OpWidth, Imm, 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>
305 uint64_t /* Addr */,
306 const MCDisassembler *Decoder) {
307 return decodeSrcOp(Inst, 9, OpWidth, Imm, 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
315DECODE_OPERAND_REG_8(VGPR_32_Lo128)
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
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
352 uint64_t /*Addr*/,
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, DAsm->createVGPR16Operand(RegIdx, IsHi));
361}
362
363static DecodeStatus
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, DAsm->createVGPR16Operand(RegIdx, IsHi));
372}
373
374template <unsigned OpWidth>
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);
382 bool IsHi = Imm & (1 << 7);
383 unsigned RegIdx = Imm & 0x7f;
384 return addOperand(Inst, DAsm->createVGPR16Operand(RegIdx, IsHi));
385 }
386 return addOperand(Inst, DAsm->decodeNonVGPRSrcOp(Inst, OpWidth, Imm & 0xFF));
387}
388
389template <unsigned OpWidth>
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);
397 bool IsHi = Imm & (1 << 9);
398 unsigned RegIdx = Imm & 0xff;
399 return addOperand(Inst, DAsm->createVGPR16Operand(RegIdx, IsHi));
400 }
401 return addOperand(Inst, DAsm->decodeNonVGPRSrcOp(Inst, OpWidth, Imm & 0xFF));
402}
403
405 uint64_t /*Addr*/,
406 const MCDisassembler *Decoder) {
407 assert(isUInt<10>(Imm) && "10-bit encoding expected");
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, DAsm->createVGPR16Operand(RegIdx, IsHi));
416}
417
419 uint64_t Addr,
420 const MCDisassembler *Decoder) {
421 const auto *DAsm = static_cast<const AMDGPUDisassembler *>(Decoder);
422 return addOperand(Inst, DAsm->decodeMandatoryLiteralConstant(Imm));
423}
424
426 uint64_t Addr,
427 const MCDisassembler *Decoder) {
428 const auto *DAsm = static_cast<const AMDGPUDisassembler *>(Decoder);
429 return addOperand(Inst, 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, 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, DAsm->decodeSrcOp(Inst, Opw, 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
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, DAsm->decodeSrcOp(Inst, 64, 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.
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 */,
485 const auto *DAsm = static_cast<const AMDGPUDisassembler *>(Decoder);
486 return addOperand(Inst, 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>
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(TmpInst, *MCII))
521
522 CommentStream = nullptr;
523
524 if (Res != MCDisassembler::Fail) {
525 MI = TmpInst;
526 Comments << LocalComments;
528 }
529 Bytes = SavedBytes;
531}
532
533template <typename InsnType>
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 }
543}
544
545template <typename T> static inline T eatBytes(ArrayRef<uint8_t>& Bytes) {
546 assert(Bytes.size() >= sizeof(T));
547 const auto Res =
549 Bytes = Bytes.slice(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>(Bytes.data()));
557 Bytes = Bytes.slice(8);
558 std::bitset<96> Hi(read<uint32_t, endianness::little>(Bytes.data()));
559 Bytes = Bytes.slice(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>(Bytes.data()));
567 Bytes = Bytes.slice(8);
568 std::bitset<128> Hi(read<uint64_t, endianness::little>(Bytes.data()));
569 Bytes = Bytes.slice(8);
570 return (Hi << 64) | Lo;
571}
572
573bool AMDGPUDisassembler::decodeImmOperands(MCInst &MI,
574 const MCInstrInfo &MCII) const {
575 const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
576 for (auto [OpNo, OpDesc] : enumerate(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(OpNo);
588 if (!Op.isImm())
589 continue;
590 int64_t Imm = Op.getImm();
594 continue;
595 }
596
598 Op = decodeLiteralConstant(Desc, OpDesc);
599 if (!Op.isValid())
600 return false;
601 continue;
602 }
603
606 switch (OpDesc.OperandType) {
612 break;
616 break;
620 break;
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 {
630 }
631 break;
632 }
641 break;
642 default:
644 }
645 Op.setImm(Imm);
646 }
647 }
648 return true;
649}
650
652 ArrayRef<uint8_t> Bytes_,
653 uint64_t Address,
654 raw_ostream &CS) const {
655 unsigned MaxInstBytesNum = std::min((size_t)TargetMaxInstBytes, Bytes_.size());
656 Bytes = Bytes_.slice(0, 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((size_t)4, 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(DecoderTableGFX1250128, MI, DecW, Address, CS))
671 break;
672 Bytes = Bytes_.slice(0, MaxInstBytesNum);
673 }
674
675 if (isGFX11Plus() && Bytes.size() >= 12) {
676 std::bitset<96> DecW = eat12Bytes(Bytes);
677
678 if (isGFX1170() &&
679 tryDecodeInst(DecoderTableGFX117096, DecoderTableGFX1170_FAKE1696, MI,
680 DecW, Address, CS))
681 break;
682
683 if (isGFX11() &&
684 tryDecodeInst(DecoderTableGFX1196, DecoderTableGFX11_FAKE1696, MI,
685 DecW, Address, CS))
686 break;
687
688 if (isGFX1250() &&
689 tryDecodeInst(DecoderTableGFX125096, DecoderTableGFX1250_FAKE1696, MI,
690 DecW, Address, CS))
691 break;
692
693 if (isGFX12() &&
694 tryDecodeInst(DecoderTableGFX1296, DecoderTableGFX12_FAKE1696, MI,
695 DecW, Address, CS))
696 break;
697
698 if (isGFX12() &&
699 tryDecodeInst(DecoderTableGFX12W6496, MI, DecW, Address, CS))
700 break;
701
702 if (isGFX13() &&
703 tryDecodeInst(DecoderTableGFX1396, DecoderTableGFX13_FAKE1696, MI,
704 DecW, Address, CS))
705 break;
706
707 if (STI.hasFeature(AMDGPU::Feature64BitLiterals)) {
708 // Return 8 bytes for a potential literal.
709 Bytes = Bytes_.slice(4, MaxInstBytesNum - 4);
710
711 if (isGFX1250() &&
712 tryDecodeInst(DecoderTableGFX125096, MI, DecW, Address, CS))
713 break;
714 }
715
716 // Reinitialize Bytes
717 Bytes = Bytes_.slice(0, MaxInstBytesNum);
718
719 } else if (Bytes.size() >= 16 &&
720 STI.hasFeature(AMDGPU::FeatureGFX950Insts)) {
721 std::bitset<128> DecW = eat16Bytes(Bytes);
722 if (tryDecodeInst(DecoderTableGFX940128, MI, DecW, Address, CS))
723 break;
724
725 // Reinitialize Bytes
726 Bytes = Bytes_.slice(0, MaxInstBytesNum);
727 }
728
729 if (Bytes.size() >= 8) {
730 const uint64_t QW = eatBytes<uint64_t>(Bytes);
731
732 if (STI.hasFeature(AMDGPU::FeatureGFX10_BEncoding) &&
733 tryDecodeInst(DecoderTableGFX10_B64, MI, QW, Address, CS))
734 break;
735
736 if (STI.hasFeature(AMDGPU::FeatureUnpackedD16VMem) &&
737 tryDecodeInst(DecoderTableGFX80_UNPACKED64, MI, QW, Address, CS))
738 break;
739
740 if (STI.hasFeature(AMDGPU::FeatureGFX950Insts) &&
741 tryDecodeInst(DecoderTableGFX95064, MI, QW, Address, 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(AMDGPU::FeatureFmaMixInsts) &&
748 tryDecodeInst(DecoderTableGFX9_DL64, MI, QW, Address, CS))
749 break;
750
751 if (STI.hasFeature(AMDGPU::FeatureGFX940Insts) &&
752 tryDecodeInst(DecoderTableGFX94064, MI, QW, Address, CS))
753 break;
754
755 if (STI.hasFeature(AMDGPU::FeatureGFX90AInsts) &&
756 tryDecodeInst(DecoderTableGFX90A64, MI, QW, Address, CS))
757 break;
758
759 if ((isVI() || isGFX9()) &&
760 tryDecodeInst(DecoderTableGFX864, MI, QW, Address, CS))
761 break;
762
763 if (isGFX9() && tryDecodeInst(DecoderTableGFX964, MI, QW, Address, CS))
764 break;
765
766 if (isGFX10() && tryDecodeInst(DecoderTableGFX1064, MI, QW, Address, CS))
767 break;
768
769 if (isGFX1250() &&
770 tryDecodeInst(DecoderTableGFX125064, DecoderTableGFX1250_FAKE1664, MI,
771 QW, Address, CS))
772 break;
773
774 if (isGFX12() &&
775 tryDecodeInst(DecoderTableGFX1264, DecoderTableGFX12_FAKE1664, MI, QW,
776 Address, CS))
777 break;
778
779 if (isGFX1170() &&
780 tryDecodeInst(DecoderTableGFX117064, DecoderTableGFX1170_FAKE1664, MI,
781 QW, Address, CS))
782 break;
783
784 if (isGFX11() &&
785 tryDecodeInst(DecoderTableGFX1164, DecoderTableGFX11_FAKE1664, MI, QW,
786 Address, CS))
787 break;
788
789 if (isGFX1170() &&
790 tryDecodeInst(DecoderTableGFX1170W6464, MI, QW, Address, CS))
791 break;
792
793 if (isGFX11() &&
794 tryDecodeInst(DecoderTableGFX11W6464, MI, QW, Address, CS))
795 break;
796
797 if (isGFX12() &&
798 tryDecodeInst(DecoderTableGFX12W6464, MI, QW, Address, CS))
799 break;
800
801 if (isGFX13() &&
802 tryDecodeInst(DecoderTableGFX1364, DecoderTableGFX13_FAKE1664, MI, QW,
803 Address, CS))
804 break;
805
806 // Reinitialize Bytes
807 Bytes = Bytes_.slice(0, 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(DecoderTableGFX832, MI, DW, Address, CS))
816 break;
817
818 if (tryDecodeInst(DecoderTableAMDGPU32, MI, DW, Address, CS))
819 break;
820
821 if (isGFX9() && tryDecodeInst(DecoderTableGFX932, MI, DW, Address, CS))
822 break;
823
824 if (STI.hasFeature(AMDGPU::FeatureGFX950Insts) &&
825 tryDecodeInst(DecoderTableGFX95032, MI, DW, Address, CS))
826 break;
827
828 if (STI.hasFeature(AMDGPU::FeatureGFX90AInsts) &&
829 tryDecodeInst(DecoderTableGFX90A32, MI, DW, Address, CS))
830 break;
831
832 if (STI.hasFeature(AMDGPU::FeatureGFX10_BEncoding) &&
833 tryDecodeInst(DecoderTableGFX10_B32, MI, DW, Address, CS))
834 break;
835
836 if (isGFX10() && tryDecodeInst(DecoderTableGFX1032, MI, DW, Address, CS))
837 break;
838
839 if (isGFX1170() &&
840 tryDecodeInst(DecoderTableGFX117032, DecoderTableGFX1170_FAKE1632, MI,
841 DW, Address, CS))
842 break;
843
844 if (isGFX11() &&
845 tryDecodeInst(DecoderTableGFX1132, DecoderTableGFX11_FAKE1632, MI, DW,
846 Address, CS))
847 break;
848
849 if (isGFX1250() &&
850 tryDecodeInst(DecoderTableGFX125032, DecoderTableGFX1250_FAKE1632, MI,
851 DW, Address, CS))
852 break;
853
854 if (isGFX12() &&
855 tryDecodeInst(DecoderTableGFX1232, DecoderTableGFX12_FAKE1632, MI, DW,
856 Address, CS))
857 break;
858
859 if (isGFX13() &&
860 tryDecodeInst(DecoderTableGFX1332, DecoderTableGFX13_FAKE1632, MI, DW,
861 Address, CS))
862 break;
863 }
864
866 } while (false);
867
869
870 if (SIInstrFlags::isDPP(*MCII, MI)) {
871 if (isMacDPP(MI))
873
874 if (SIInstrFlags::isVOP3P(*MCII, MI))
876 else if (SIInstrFlags::isVOPC(*MCII, MI))
877 convertVOPCDPPInst(MI); // Special VOP3 case
878 else if (AMDGPU::isVOPC64DPP(MI.getOpcode()))
879 convertVOPC64DPPInst(MI); // Special VOP3 case
880 else if (AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::dpp8) !=
881 -1)
883 else if (SIInstrFlags::isVOP3(*MCII, MI))
884 convertVOP3DPPInst(MI); // Regular VOP3 case
885 }
886
888
889 if (AMDGPU::isMAC(MI.getOpcode())) {
890 // Insert dummy unused src2_modifiers.
892 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.
899 AMDGPU::OpName::src2_modifiers);
900 }
901
902 if (SIInstrFlags::isDS(*MCII, MI) && !AMDGPU::hasGDS(STI)) {
903 insertNamedMCOperand(MI, MCOperand::createImm(0), AMDGPU::OpName::gds);
904 }
905
906 if (SIInstrFlags::isMUBUF(*MCII, MI) || SIInstrFlags::isFLAT(*MCII, MI) ||
907 SIInstrFlags::isSMRD(*MCII, MI)) {
908 int CPolPos = AMDGPU::getNamedOperandIdx(MI.getOpcode(),
909 AMDGPU::OpName::cpol);
910 if (CPolPos != -1) {
911 unsigned CPol =
913 if (MI.getNumOperands() <= (unsigned)CPolPos) {
915 AMDGPU::OpName::cpol);
916 } else if (CPol) {
917 MI.getOperand(CPolPos).setImm(MI.getOperand(CPolPos).getImm() | CPol);
918 }
919 }
920 }
921
922 if (SIInstrFlags::isBuffer(*MCII, MI) &&
923 (STI.hasFeature(AMDGPU::FeatureGFX90AInsts))) {
924 // GFX90A lost TFE, its place is occupied by ACC.
925 int TFEOpIdx =
926 AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::tfe);
927 if (TFEOpIdx != -1) {
928 auto *TFEIter = MI.begin();
929 std::advance(TFEIter, TFEOpIdx);
930 MI.insert(TFEIter, MCOperand::createImm(0));
931 }
932 }
933
934 // Validate buffer instruction offsets for GFX12+ - must not be a negative.
936 int OffsetIdx =
937 AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::offset);
938 if (OffsetIdx != -1) {
939 uint32_t Imm = MI.getOperand(OffsetIdx).getImm();
940 int64_t SignedOffset = SignExtend64<24>(Imm);
941 if (SignedOffset < 0)
943 }
944 }
945
946 if (SIInstrFlags::isBuffer(*MCII, MI)) {
947 int SWZOpIdx =
948 AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::swz);
949 if (SWZOpIdx != -1) {
950 auto *SWZIter = MI.begin();
951 std::advance(SWZIter, SWZOpIdx);
952 MI.insert(SWZIter, MCOperand::createImm(0));
953 }
954 }
955
956 const MCInstrDesc &Desc = MCII->get(MI.getOpcode());
958 int VAddr0Idx =
959 AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::vaddr0);
960 int RsrcIdx =
961 AMDGPU::getNamedOperandIdx(MI.getOpcode(), 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)
967 for (unsigned i = 0; i < NSAArgs; ++i) {
968 const unsigned VAddrIdx = VAddr0Idx + 1 + i;
969 auto VAddrRCID =
970 MCII->getOpRegClassID(Desc.operands()[VAddrIdx], HwModeRegClass);
971 MI.insert(MI.begin() + VAddrIdx, createRegOperand(VAddrRCID, Bytes[i]));
972 }
973 Bytes = Bytes.slice(4 * NSAWords);
974 }
975
977 }
978
981
982 if (SIInstrFlags::isEXP(*MCII, MI))
984
985 if (SIInstrFlags::isVINTERP(*MCII, MI))
987
988 if (SIInstrFlags::isSDWA(*MCII, MI))
990
991 if (SIInstrFlags::isMAI(*MCII, MI) && !convertMAIInst(MI))
993
994 if (SIInstrFlags::isWMMA(*MCII, MI) && !convertWMMAInst(MI))
996
997 int VDstIn_Idx = AMDGPU::getNamedOperandIdx(MI.getOpcode(),
998 AMDGPU::OpName::vdst_in);
999 if (VDstIn_Idx != -1) {
1000 int Tied = MCII->get(MI.getOpcode()).getOperandConstraint(VDstIn_Idx,
1002 if (Tied != -1 && (MI.getNumOperands() <= (unsigned)VDstIn_Idx ||
1003 !MI.getOperand(VDstIn_Idx).isReg() ||
1004 MI.getOperand(VDstIn_Idx).getReg() != MI.getOperand(Tied).getReg())) {
1005 if (MI.getNumOperands() > (unsigned)VDstIn_Idx)
1006 MI.erase(&MI.getOperand(VDstIn_Idx));
1008 MCOperand::createReg(MI.getOperand(Tied).getReg()),
1009 AMDGPU::OpName::vdst_in);
1010 }
1011 }
1012
1013 bool IsSOPK = SIInstrFlags::isSOPK(*MCII, MI);
1014 if (AMDGPU::hasNamedOperand(MI.getOpcode(), AMDGPU::OpName::imm) && !IsSOPK)
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(*MCII, MI) &&
1021 MCII->get(MI.getOpcode()).getNumDefs() == 0 &&
1022 MCII->get(MI.getOpcode()).hasImplicitDefOfPhysReg(AMDGPU::EXEC)) {
1023 auto ExecEncoding = MRI.getEncodingValue(AMDGPU::EXEC_LO);
1024 if (Bytes_[0] != ExecEncoding)
1026 }
1027
1028 Size = MaxInstBytesNum - Bytes.size();
1029 return Status;
1030}
1031
1033 if (STI.hasFeature(AMDGPU::FeatureGFX11Insts)) {
1034 // The MCInst still has these fields even though they are no longer encoded
1035 // in the GFX11 instruction.
1036 insertNamedMCOperand(MI, MCOperand::createImm(0), AMDGPU::OpName::vm);
1037 insertNamedMCOperand(MI, MCOperand::createImm(0), AMDGPU::OpName::compr);
1038 }
1039}
1040
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, MCOperand::createImm(0), AMDGPU::OpName::op_sel);
1070 }
1071}
1072
1074 if (STI.hasFeature(AMDGPU::FeatureGFX9) ||
1075 STI.hasFeature(AMDGPU::FeatureGFX10)) {
1076 if (AMDGPU::hasNamedOperand(MI.getOpcode(), AMDGPU::OpName::sdst))
1077 // VOPC - insert clamp
1078 insertNamedMCOperand(MI, MCOperand::createImm(0), AMDGPU::OpName::clamp);
1079 } else if (STI.hasFeature(AMDGPU::FeatureVolcanicIslands)) {
1080 int SDst = AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::sdst);
1081 if (SDst != -1) {
1082 // VOPC - insert VCC register as sdst
1084 AMDGPU::OpName::sdst);
1085 } else {
1086 // VOP1/2 - insert omod if present in instruction
1087 insertNamedMCOperand(MI, MCOperand::createImm(0), 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.
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(MO.getReg(), AMDGPU::sub0_sub1_sub2_sub3);
1107 break;
1108 case 6:
1109 NewReg = MRI.getSubReg(MO.getReg(), AMDGPU::sub0_sub1_sub2_sub3_sub4_sub5);
1110 break;
1111 case 8:
1112 NewReg = MRI.getSubReg(MO.getReg(),
1113 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(MO.getReg(), AMDGPU::sub0)) {
1122 NewReg = MRI.getMatchingSuperReg(
1123 BaseReg, AMDGPU::sub0, &MRI.getRegClass(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.
1146 int BlgpIdx =
1147 AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::blgp);
1148 if (BlgpIdx == -1)
1149 return true;
1150
1151 int CbszIdx =
1152 AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::cbsz);
1153
1154 unsigned CBSZ = MI.getOperand(CbszIdx).getImm();
1155 unsigned BLGP = MI.getOperand(BlgpIdx).getImm();
1156
1157 const AMDGPU::MFMA_F8F6F4_Info *AdjustedRegClassOpcode =
1158 AMDGPU::getMFMA_F8F6F4_WithFormatArgs(CBSZ, BLGP, 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(MI.getOpcode(), AMDGPU::OpName::src0);
1166 int Src1Idx =
1167 AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::src1);
1168 return adjustMFMA_F8F6F4OpRegClass(MRI, MI.getOperand(Src0Idx),
1169 AdjustedRegClassOpcode->NumRegsSrcA) &&
1170 adjustMFMA_F8F6F4OpRegClass(MRI, MI.getOperand(Src1Idx),
1171 AdjustedRegClassOpcode->NumRegsSrcB);
1172}
1173
1175 int FmtAIdx =
1176 AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::matrix_a_fmt);
1177 if (FmtAIdx == -1)
1178 return true;
1179
1180 int FmtBIdx =
1181 AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::matrix_b_fmt);
1182
1183 unsigned FmtA = MI.getOperand(FmtAIdx).getImm();
1184 unsigned FmtB = MI.getOperand(FmtBIdx).getImm();
1185
1186 const AMDGPU::MFMA_F8F6F4_Info *AdjustedRegClassOpcode =
1187 AMDGPU::getWMMA_F8F6F4_WithFormatArgs(FmtA, FmtB, 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(MI.getOpcode(), AMDGPU::OpName::src0);
1195 int Src1Idx =
1196 AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::src1);
1197 return adjustMFMA_F8F6F4OpRegClass(MRI, MI.getOperand(Src0Idx),
1198 AdjustedRegClassOpcode->NumRegsSrcA) &&
1199 adjustMFMA_F8F6F4OpRegClass(MRI, MI.getOperand(Src1Idx),
1200 AdjustedRegClassOpcode->NumRegsSrcB);
1201}
1202
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.
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(Opc, ModOps[J]);
1222 if (OpIdx == -1)
1223 continue;
1224
1225 unsigned Val = MI.getOperand(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.
1243 const unsigned Opc = MI.getOpcode();
1244 const MCRegisterClass &ConversionRC =
1245 MRI.getRegClass(AMDGPU::VGPR_16RegClassID);
1246 constexpr std::array<std::tuple<AMDGPU::OpName, AMDGPU::OpName, unsigned>, 4>
1247 OpAndOpMods = {{{AMDGPU::OpName::src0, AMDGPU::OpName::src0_modifiers,
1249 {AMDGPU::OpName::src1, AMDGPU::OpName::src1_modifiers,
1251 {AMDGPU::OpName::src2, AMDGPU::OpName::src2_modifiers,
1253 {AMDGPU::OpName::vdst, AMDGPU::OpName::src0_modifiers,
1255 for (const auto &[OpName, OpModsName, OpSelMask] : OpAndOpMods) {
1256 int OpIdx = AMDGPU::getNamedOperandIdx(Opc, OpName);
1257 int OpModsIdx = AMDGPU::getNamedOperandIdx(Opc, OpModsName);
1258 if (OpIdx == -1 || OpModsIdx == -1)
1259 continue;
1260 MCOperand &Op = MI.getOperand(OpIdx);
1261 if (!Op.isReg())
1262 continue;
1263 if (!ConversionRC.contains(Op.getReg()))
1264 continue;
1265 unsigned OpEnc = MRI.getEncodingValue(Op.getReg());
1266 const MCOperand &OpMods = MI.getOperand(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(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).
1278 constexpr int DST_IDX = 0;
1279 auto Opcode = MI.getOpcode();
1280 const auto &Desc = MCII->get(Opcode);
1281 auto OldIdx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::old);
1282
1283 if (OldIdx != -1 && Desc.getOperandConstraint(
1284 OldIdx, MCOI::OperandConstraint::TIED_TO) == -1) {
1285 assert(AMDGPU::hasNamedOperand(Opcode, AMDGPU::OpName::src2));
1286 assert(Desc.getOperandConstraint(
1287 AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src2),
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
1298 assert(MI.getNumOperands() + 1 < MCII->get(MI.getOpcode()).getNumOperands());
1299 insertNamedMCOperand(MI, MCOperand::createReg(0), AMDGPU::OpName::old);
1301 AMDGPU::OpName::src2_modifiers);
1302}
1303
1305 unsigned Opc = MI.getOpcode();
1306
1307 int VDstInIdx =
1308 AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::vdst_in);
1309 if (VDstInIdx != -1)
1310 insertNamedMCOperand(MI, MI.getOperand(0), AMDGPU::OpName::vdst_in);
1311
1312 unsigned DescNumOps = MCII->get(Opc).getNumOperands();
1313 if (MI.getNumOperands() < DescNumOps &&
1314 AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::op_sel)) {
1316 auto Mods = collectVOPModifiers(MI);
1318 AMDGPU::OpName::op_sel);
1319 } else {
1320 // Insert dummy unused src modifiers.
1321 if (MI.getNumOperands() < DescNumOps &&
1322 AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::src0_modifiers))
1324 AMDGPU::OpName::src0_modifiers);
1325
1326 if (MI.getNumOperands() < DescNumOps &&
1327 AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::src1_modifiers))
1329 AMDGPU::OpName::src1_modifiers);
1330 }
1331}
1332
1335
1336 int VDstInIdx =
1337 AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::vdst_in);
1338 if (VDstInIdx != -1)
1339 insertNamedMCOperand(MI, MI.getOperand(0), AMDGPU::OpName::vdst_in);
1340
1341 unsigned Opc = MI.getOpcode();
1342 unsigned DescNumOps = MCII->get(Opc).getNumOperands();
1343 if (MI.getNumOperands() < DescNumOps &&
1344 AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::op_sel)) {
1345 auto Mods = collectVOPModifiers(MI);
1347 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.
1354 const MCRegisterInfo &MRI) {
1355 unsigned NumRegs = RC.getSizeInBits() / 32;
1356 MCRegister Sub0 = MRI.getSubReg(Reg, AMDGPU::sub0);
1357 if (!Sub0)
1358 return Reg;
1359
1360 MCRegister BaseReg;
1361 if (MRI.getRegClass(AMDGPU::VGPR_32RegClassID).contains(Sub0))
1362 BaseReg = AMDGPU::VGPR0;
1363 else if (MRI.getRegClass(AMDGPU::AGPR_32RegClassID).contains(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.
1375 int VDstIdx = AMDGPU::getNamedOperandIdx(MI.getOpcode(),
1376 AMDGPU::OpName::vdst);
1377
1378 int VDataIdx = AMDGPU::getNamedOperandIdx(MI.getOpcode(),
1379 AMDGPU::OpName::vdata);
1380 int VAddr0Idx =
1381 AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::vaddr0);
1382 AMDGPU::OpName RsrcOpName = SIInstrFlags::isMIMG(*MCII, MI)
1383 ? AMDGPU::OpName::srsrc
1384 : AMDGPU::OpName::rsrc;
1385 int RsrcIdx = AMDGPU::getNamedOperandIdx(MI.getOpcode(), RsrcOpName);
1386 int DMaskIdx = AMDGPU::getNamedOperandIdx(MI.getOpcode(),
1387 AMDGPU::OpName::dmask);
1388
1389 int TFEIdx = AMDGPU::getNamedOperandIdx(MI.getOpcode(),
1390 AMDGPU::OpName::tfe);
1391 int D16Idx = AMDGPU::getNamedOperandIdx(MI.getOpcode(),
1392 AMDGPU::OpName::d16);
1393
1394 const AMDGPU::MIMGInfo *Info = AMDGPU::getMIMGInfo(MI.getOpcode());
1395 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
1396 AMDGPU::getMIMGBaseOpcodeInfo(Info->BaseOpcode);
1397
1398 assert(VDataIdx != -1);
1399 if (BaseOpcode->BVH) {
1400 // Add A16 operand for intersect_ray instructions
1401 addOperand(MI, MCOperand::createImm(BaseOpcode->A16));
1402 return;
1403 }
1404
1405 bool IsAtomic = (VDstIdx != -1);
1406 bool IsGather4 = SIInstrFlags::isGather4(*MCII, MI);
1407 bool IsVSample = SIInstrFlags::isVSAMPLE(*MCII, MI);
1408 bool IsNSA = false;
1409 bool IsPartialNSA = false;
1410 unsigned AddrSize = Info->VAddrDwords;
1411
1412 if (isGFX10Plus()) {
1413 unsigned DimIdx =
1414 AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::dim);
1415 int A16Idx =
1416 AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::a16);
1417 const AMDGPU::MIMGDimInfo *Dim =
1418 AMDGPU::getMIMGDimInfoByEncoding(MI.getOperand(DimIdx).getImm());
1419 const bool IsA16 = (A16Idx != -1 && MI.getOperand(A16Idx).getImm());
1420
1421 AddrSize =
1422 AMDGPU::getAddrSizeMIMGOp(BaseOpcode, Dim, IsA16, 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(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(DMaskIdx).getImm() & 0xf;
1446 unsigned DstSize = IsGather4 ? 4 : std::max(llvm::popcount(DMask), 1);
1447
1448 bool D16 = D16Idx >= 0 && MI.getOperand(D16Idx).getImm();
1449 if (D16 && AMDGPU::hasPackedD16(STI)) {
1450 DstSize = (DstSize + 1) / 2;
1451 }
1452
1453 if (TFEIdx != -1 && MI.getOperand(TFEIdx).getImm())
1454 DstSize += 1;
1455
1456 if (DstSize == Info->VDataDwords && AddrSize == Info->VAddrDwords)
1457 return;
1458
1459 int NewOpcode =
1460 AMDGPU::getMIMGOpcode(Info->BaseOpcode, Info->MIMGEncoding, DstSize, 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 MCII->get(NewOpcode).operands()[VDataIdx], HwModeRegClass);
1469
1470 // Get first subregister of VData
1471 MCRegister Vdata0 = MI.getOperand(VDataIdx).getReg();
1472 MCRegister VdataSub0 = MRI.getSubReg(Vdata0, AMDGPU::sub0);
1473 Vdata0 = (VdataSub0 != 0)? VdataSub0 : Vdata0;
1474
1475 const MCRegisterClass &NewRC = MRI.getRegClass(DataRCID);
1476 NewVdata = MRI.getMatchingSuperReg(Vdata0, AMDGPU::sub0, &NewRC);
1477 NewVdata = CheckVGPROverflow(NewVdata, 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(AMDGPU::FeatureNSAEncoding) && (!IsNSA || IsPartialNSA) &&
1490 AddrSize != Info->VAddrDwords) {
1491 MCRegister VAddrSA = MI.getOperand(VAddrSAIdx).getReg();
1492 MCRegister VAddrSubSA = MRI.getSubReg(VAddrSA, AMDGPU::sub0);
1493 VAddrSA = VAddrSubSA ? VAddrSubSA : VAddrSA;
1494
1495 auto AddrRCID = MCII->getOpRegClassID(
1496 MCII->get(NewOpcode).operands()[VAddrSAIdx], HwModeRegClass);
1497
1498 const MCRegisterClass &NewRC = MRI.getRegClass(AddrRCID);
1499 NewVAddrSA = MRI.getMatchingSuperReg(VAddrSA, AMDGPU::sub0, &NewRC);
1500 NewVAddrSA = CheckVGPROverflow(NewVAddrSA, NewRC, MRI);
1501 if (!NewVAddrSA)
1502 return;
1503 }
1504
1505 MI.setOpcode(NewOpcode);
1506
1507 if (NewVdata != AMDGPU::NoRegister) {
1508 MI.getOperand(VDataIdx) = MCOperand::createReg(NewVdata);
1509
1510 if (IsAtomic) {
1511 // Atomic operations have an additional operand (a copy of data)
1512 MI.getOperand(VDstIdx) = MCOperand::createReg(NewVdata);
1513 }
1514 }
1515
1516 if (NewVAddrSA) {
1517 MI.getOperand(VAddrSAIdx) = MCOperand::createReg(NewVAddrSA);
1518 } else if (IsNSA) {
1519 assert(AddrSize <= Info->VAddrDwords);
1520 MI.erase(MI.begin() + VAddr0Idx + AddrSize,
1521 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.
1529 unsigned Opc = MI.getOpcode();
1530 unsigned DescNumOps = MCII->get(Opc).getNumOperands();
1531 auto Mods = collectVOPModifiers(MI, true);
1532
1533 if (MI.getNumOperands() < DescNumOps &&
1534 AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::vdst_in))
1535 insertNamedMCOperand(MI, MCOperand::createImm(0), AMDGPU::OpName::vdst_in);
1536
1537 if (MI.getNumOperands() < DescNumOps &&
1538 AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::op_sel))
1540 AMDGPU::OpName::op_sel);
1541 if (MI.getNumOperands() < DescNumOps &&
1542 AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::op_sel_hi))
1544 AMDGPU::OpName::op_sel_hi);
1545 if (MI.getNumOperands() < DescNumOps &&
1546 AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::neg_lo))
1548 AMDGPU::OpName::neg_lo);
1549 if (MI.getNumOperands() < DescNumOps &&
1550 AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::neg_hi))
1552 AMDGPU::OpName::neg_hi);
1553}
1554
1555// Create dummy old operand and insert optional operands
1557 unsigned Opc = MI.getOpcode();
1558 unsigned DescNumOps = MCII->get(Opc).getNumOperands();
1559
1560 if (MI.getNumOperands() < DescNumOps &&
1561 AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::old))
1562 insertNamedMCOperand(MI, MCOperand::createReg(0), AMDGPU::OpName::old);
1563
1564 if (MI.getNumOperands() < DescNumOps &&
1565 AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::src0_modifiers))
1567 AMDGPU::OpName::src0_modifiers);
1568
1569 if (MI.getNumOperands() < DescNumOps &&
1570 AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::src1_modifiers))
1572 AMDGPU::OpName::src1_modifiers);
1573}
1574
1576 unsigned Opc = MI.getOpcode();
1577 unsigned DescNumOps = MCII->get(Opc).getNumOperands();
1578
1580
1581 if (MI.getNumOperands() < DescNumOps &&
1582 AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::op_sel)) {
1585 AMDGPU::OpName::op_sel);
1586 }
1587}
1588
1590 assert(HasLiteral && "Should have decoded a literal");
1591 insertNamedMCOperand(MI, MCOperand::createImm(Literal), AMDGPU::OpName::immX);
1592}
1593
1594const char* AMDGPUDisassembler::getRegClassName(unsigned RegClassID) const {
1596 &getAMDGPUMCRegisterClass(RegClassID));
1597}
1598
1599inline
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
1612
1613inline
1615 unsigned Val) const {
1616 const auto &RegCl = getAMDGPUMCRegisterClass(RegClassID);
1617 if (Val >= RegCl.getNumRegs())
1618 return errOperand(Val, Twine(getRegClassName(RegClassID)) +
1619 ": unknown register " + Twine(Val));
1620 return createRegOperand(RegCl.getRegister(Val));
1621}
1622
1623inline
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(SRegClassID)
1667 << ": scalar reg isn't aligned " << Val;
1668 }
1669
1670 return createRegOperand(SRegClassID, Val >> shift);
1671}
1672
1674 bool IsHi) const {
1675 unsigned RegIdxInVGPR16 = RegIdx * 2 + (IsHi ? 1 : 0);
1676 return createRegOperand(AMDGPU::VGPR_16RegClassID, RegIdxInVGPR16);
1677}
1678
1679// Decode Literals for insts which always have a literal in the encoding
1682 if (HasLiteral) {
1683 assert(
1685 "Should only decode multiple kimm with VOPD, check VSrc operand types");
1686 if (Literal != Val)
1687 return errOperand(Val, "More than one unique literal is illegal");
1688 }
1689 HasLiteral = true;
1690 Literal = Val;
1691 return MCOperand::createImm(Literal);
1692}
1693
1696 if (HasLiteral) {
1697 if (Literal != Val)
1698 return errOperand(Val, "More than one unique literal is illegal");
1699 }
1700 HasLiteral = true;
1701 Literal = Val;
1702
1703 bool UseLit64 = Hi_32(Literal) == 0;
1705 LitModifier::Lit64, Literal, getContext()))
1706 : MCOperand::createImm(Literal);
1707}
1708
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(0, "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!");
1737 UseLit = AMDGPU::isInlinableLiteralBF16(Val, HasInv2Pi);
1738 break;
1741 break;
1745 UseLit = AMDGPU::isInlinableLiteralFP16(Val, HasInv2Pi);
1746 break;
1748 UseLit = AMDGPU::isInlinableLiteralV2F16(Val);
1749 break;
1752 break;
1754 break;
1758 UseLit = AMDGPU::isInlinableLiteralI16(Val, HasInv2Pi);
1759 break;
1761 UseLit = AMDGPU::isInlinableLiteralV2I16(Val);
1762 break;
1772 UseLit = AMDGPU::isInlinableLiteral32(Val, HasInv2Pi);
1773 break;
1778 UseLit = AMDGPU::isInlinableLiteral64(Val << 32, HasInv2Pi);
1779 if (!UseLit)
1780 Val <<= 32;
1781 break;
1785 UseLit = AMDGPU::isInlinableLiteral64(Val, HasInv2Pi);
1786 break;
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
1797 : MCOperand::createImm(Val);
1798}
1799
1801 assert(STI.hasFeature(AMDGPU::Feature64BitLiterals));
1802
1803 if (!HasLiteral) {
1804 if (Bytes.size() < 8) {
1805 return errOperand(0, "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(Literal) == 0;
1813
1814 UseLit64 |= AMDGPU::isInlinableLiteral64(
1815 Literal, STI.hasFeature(AMDGPU::FeatureInv2PiInlineImm));
1816
1818 LitModifier::Lit64, Literal, getContext()))
1819 : MCOperand::createImm(Literal);
1820}
1821
1823 using namespace AMDGPU::EncValues;
1824
1825 assert(Imm >= INLINE_INTEGER_C_MIN && Imm <= INLINE_INTEGER_C_MAX);
1826 return MCOperand::createImm((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>(0.5f);
1836 case 241:
1837 return llvm::bit_cast<uint32_t>(-0.5f);
1838 case 242:
1839 return llvm::bit_cast<uint32_t>(1.0f);
1840 case 243:
1841 return llvm::bit_cast<uint32_t>(-1.0f);
1842 case 244:
1843 return llvm::bit_cast<uint32_t>(2.0f);
1844 case 245:
1845 return llvm::bit_cast<uint32_t>(-2.0f);
1846 case 246:
1847 return llvm::bit_cast<uint32_t>(4.0f);
1848 case 247:
1849 return llvm::bit_cast<uint32_t>(-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>(0.5);
1861 case 241:
1862 return llvm::bit_cast<uint64_t>(-0.5);
1863 case 242:
1864 return llvm::bit_cast<uint64_t>(1.0);
1865 case 243:
1866 return llvm::bit_cast<uint64_t>(-1.0);
1867 case 244:
1868 return llvm::bit_cast<uint64_t>(2.0);
1869 case 245:
1870 return llvm::bit_cast<uint64_t>(-2.0);
1871 case 246:
1872 return llvm::bit_cast<uint64_t>(4.0);
1873 case 247:
1874 return llvm::bit_cast<uint64_t>(-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>
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>
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
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(IsAGPR ? getAgprClassId(Width)
2080 : getVgprClassId(Width), Val - VGPR_MIN);
2081 }
2082 return decodeNonVGPRSrcOp(Inst, Width, Val & 0xFF);
2083}
2084
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(Val, "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(*ClassId, 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(*ClassId, 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(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(*MCII, Inst) ||
2126 AMDGPU::isVOPD(Inst.getOpcode())) {
2127 return errOperand(Val,
2128 "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.
2152 unsigned Val) const {
2153 int VDstXInd =
2154 AMDGPU::getNamedOperandIdx(Inst.getOpcode(), AMDGPU::OpName::vdstX);
2155 assert(VDstXInd != -1);
2156 assert(Inst.getOperand(VDstXInd).isReg());
2157 unsigned XDstReg = MRI.getEncodingValue(Inst.getOperand(VDstXInd).getReg());
2158 Val |= ~XDstReg & 1;
2159 return createRegOperand(getVgprClassId(32), Val);
2160}
2161
2163 using namespace AMDGPU;
2164
2165 switch (Val) {
2166 // clang-format off
2167 case 102: return createRegOperand(FLAT_SCR_LO);
2168 case 103: return createRegOperand(FLAT_SCR_HI);
2169 case 104: return createRegOperand(XNACK_MASK_LO);
2170 case 105: return createRegOperand(XNACK_MASK_HI);
2171 case 106: return createRegOperand(VCC_LO);
2172 case 107: return createRegOperand(VCC_HI);
2173 case 108: return createRegOperand(TBA_LO);
2174 case 109: return createRegOperand(TBA_HI);
2175 case 110: return createRegOperand(TMA_LO);
2176 case 111: return createRegOperand(TMA_HI);
2177 case 124:
2178 return isGFX11Plus() ? createRegOperand(SGPR_NULL) : createRegOperand(M0);
2179 case 125:
2180 return isGFX11Plus() ? createRegOperand(M0) : createRegOperand(SGPR_NULL);
2181 case 126: return createRegOperand(EXEC_LO);
2182 case 127: return createRegOperand(EXEC_HI);
2183 case 230: return createRegOperand(SRC_FLAT_SCRATCH_BASE_LO);
2184 case 231: return createRegOperand(SRC_FLAT_SCRATCH_BASE_HI);
2185 case 235: return createRegOperand(SRC_SHARED_BASE_LO);
2186 case 236: return createRegOperand(SRC_SHARED_LIMIT_LO);
2187 case 237:
2189 return createRegOperand(SRC_PRIVATE_BASE_LO);
2190 break;
2191 case 238:
2193 return createRegOperand(SRC_PRIVATE_LIMIT_LO);
2194 break;
2195 case 239:
2197 return createRegOperand(SRC_POPS_EXITING_WAVE_ID);
2198 break;
2199 case 251:
2200 if (!isGFX11Plus())
2201 return createRegOperand(SRC_VCCZ);
2202 break;
2203 case 252:
2204 if (!isGFX11Plus())
2205 return createRegOperand(SRC_EXECZ);
2206 break;
2207 case 253: return createRegOperand(SRC_SCC);
2208 case 254: return createRegOperand(LDS_DIRECT);
2209 default: break;
2210 // clang-format on
2211 }
2212 return errOperand(Val, "unknown operand encoding " + Twine(Val));
2213}
2214
2216 using namespace AMDGPU;
2217
2218 switch (Val) {
2219 case 102: return createRegOperand(FLAT_SCR);
2220 case 104: return createRegOperand(XNACK_MASK);
2221 case 106: return createRegOperand(VCC);
2222 case 108: return createRegOperand(TBA);
2223 case 110: return createRegOperand(TMA);
2224 case 124:
2225 if (isGFX11Plus())
2226 return createRegOperand(SGPR_NULL);
2227 break;
2228 case 125:
2229 if (!isGFX11Plus())
2230 return createRegOperand(SGPR_NULL);
2231 break;
2232 case 126: return createRegOperand(EXEC);
2233 case 230: return createRegOperand(SRC_FLAT_SCRATCH_BASE_LO);
2234 case 235: return createRegOperand(SRC_SHARED_BASE);
2235 case 236: return createRegOperand(SRC_SHARED_LIMIT);
2236 case 237:
2238 return createRegOperand(SRC_PRIVATE_BASE);
2239 break;
2240 case 238:
2242 return createRegOperand(SRC_PRIVATE_LIMIT);
2243 break;
2244 case 239:
2246 return createRegOperand(SRC_POPS_EXITING_WAVE_ID);
2247 break;
2248 case 251:
2249 if (!isGFX11Plus())
2250 return createRegOperand(SRC_VCCZ);
2251 break;
2252 case 252:
2253 if (!isGFX11Plus())
2254 return createRegOperand(SRC_EXECZ);
2255 break;
2256 case 253: return createRegOperand(SRC_SCC);
2257 default: break;
2258 }
2259 return errOperand(Val, "unknown operand encoding " + Twine(Val));
2260}
2261
2263 using namespace AMDGPU;
2264
2265 switch (Val) {
2266 case 124:
2267 if (isGFX11Plus())
2268 return createRegOperand(SGPR_NULL);
2269 break;
2270 case 125:
2271 if (!isGFX11Plus())
2272 return createRegOperand(SGPR_NULL);
2273 break;
2274 default:
2275 break;
2276 }
2277 return errOperand(Val, "unknown operand encoding " + Twine(Val));
2278}
2279
2281 const unsigned Val) const {
2282 using namespace AMDGPU::SDWA;
2283 using namespace AMDGPU::EncValues;
2284
2285 if (STI.hasFeature(AMDGPU::FeatureGFX9) ||
2286 STI.hasFeature(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(getVgprClassId(Width),
2292 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(*getSgprClassId(Width),
2298 Val - SDWA9EncValues::SRC_SGPR_MIN);
2299 }
2300 if (SDWA9EncValues::SRC_TTMP_MIN <= Val &&
2301 Val <= SDWA9EncValues::SRC_TTMP_MAX) {
2302 return createSRegOperand(*getTtmpClassId(Width),
2303 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(SVal);
2311
2312 return decodeSpecialReg32(SVal);
2313 }
2314 if (STI.hasFeature(AMDGPU::FeatureVolcanicIslands))
2315 return createRegOperand(getVgprClassId(Width), Val);
2316 llvm_unreachable("unsupported target");
2317}
2318
2320 return decodeSDWASrc(16, Val);
2321}
2322
2324 return decodeSDWASrc(32, Val);
2325}
2326
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(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(*getTtmpClassId(IsWave32 ? 32 : 64), TTmpIdx);
2342 if (Val > SGPR_MAX) {
2343 return IsWave32 ? decodeSpecialReg32(Val) : decodeSpecialReg64(Val);
2344 }
2345 return createSRegOperand(*getSgprClassId(IsWave32 ? 32 : 64), Val);
2346 }
2347 return createRegOperand(IsWave32 ? AMDGPU::VCC_LO : AMDGPU::VCC);
2348}
2349
2351 unsigned Val) const {
2352 return STI.hasFeature(AMDGPU::FeatureWavefrontSize32)
2353 ? decodeSrcOp(Inst, 32, Val)
2354 : decodeSrcOp(Inst, 64, Val);
2355}
2356
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, 32, Val);
2369}
2370
2373 return MCOperand();
2374 return MCOperand::createImm(Val);
2375}
2376
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>;
2383
2384 auto [Version, W64, W32, MDP] = Encoding::decode(Imm);
2385
2386 // Decode into a plain immediate if any unused bits are raised.
2387 if (Encoding::encode(Version, W64, W32, MDP) != Imm)
2388 return MCOperand::createImm(Imm);
2389
2390 const auto &Versions = AMDGPU::UCVersion::getGFXVersions();
2391 const auto *I = find_if(
2392 Versions, [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())
2399 else
2400 E = MCSymbolRefExpr::create(Ctx.getOrCreateSymbol(I->Symbol), Ctx);
2401
2402 if (W64)
2403 E = MCBinaryExpr::createOr(E, UCVersionW64Expr, Ctx);
2404 if (W32)
2405 E = MCBinaryExpr::createOr(E, UCVersionW32Expr, Ctx);
2406 if (MDP)
2407 E = MCBinaryExpr::createOr(E, UCVersionMDPExpr, Ctx);
2408
2409 return MCOperand::createExpr(E);
2410}
2411
2413 return STI.hasFeature(AMDGPU::FeatureVolcanicIslands);
2414}
2415
2417
2419 return STI.hasFeature(AMDGPU::FeatureGFX90AInsts);
2420}
2421
2423
2425
2429
2431 return STI.hasFeature(AMDGPU::FeatureGFX11);
2432}
2433
2437
2439 return STI.hasFeature(AMDGPU::FeatureGFX11_7Insts);
2440}
2441
2443 return STI.hasFeature(AMDGPU::FeatureGFX12);
2444}
2445
2449
2451
2455
2457
2461
2463 return STI.hasFeature(AMDGPU::FeatureArchitectedFlatScratch);
2464}
2465
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(Mask);
2482 int PopCount = llvm::popcount(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)
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) *
2572
2573 KdStream << Indent << ".amdhsa_reserve_vcc " << 0 << '\n';
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(AMDGPU::FeatureXNACK) || XnackOnFromEFlags;
2581 if (STI.hasFeature(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(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(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)
2656 uint32_t FourByteBuffer, raw_string_ostream &KdStream) const {
2657 using namespace amdhsa;
2658 StringRef Indent = "\t";
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
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);
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)
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 {
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()) {
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);
2771 "ENABLE_DYNAMIC_VGPR", COMPUTE_PGM_RSRC3_GFX125_ENABLE_DYNAMIC_VGPR);
2773 COMPUTE_PGM_RSRC3_GFX125_TCP_SPLIT);
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()) {
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 std::errc::invalid_argument,
2799 "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 std::errc::invalid_argument, "kernel descriptor reserved %s set%s%s",
2818 getBitRangeFromMask(Mask, BaseBytes).c_str(), *Msg ? ", " : "", 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 std::errc::invalid_argument,
2829 "kernel descriptor reserved bits in range (%u:%u) set",
2830 (BaseInBytes + WidthInBytes) * CHAR_BIT - 1, BaseInBytes * CHAR_BIT);
2831}
2832
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()) {
2853 FourByteBuffer = DE.getU32(Cursor);
2854 KdStream << Indent << ".amdhsa_group_segment_fixed_size " << FourByteBuffer
2855 << '\n';
2856 return true;
2857
2859 FourByteBuffer = DE.getU32(Cursor);
2860 KdStream << Indent << ".amdhsa_private_segment_fixed_size "
2861 << FourByteBuffer << '\n';
2862 return true;
2863
2865 FourByteBuffer = DE.getU32(Cursor);
2866 KdStream << Indent << ".amdhsa_kernarg_size "
2867 << FourByteBuffer << '\n';
2868 return true;
2869
2871 // 4 reserved bytes, must be 0.
2872 ReservedBytes = DE.getBytes(Cursor, 4);
2873 for (char B : ReservedBytes) {
2874 if (B != 0)
2876 }
2877 return true;
2878
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(Cursor, 8);
2884 return true;
2885
2887 // 20 reserved bytes, must be 0.
2888 ReservedBytes = DE.getBytes(Cursor, 20);
2889 for (char B : ReservedBytes) {
2890 if (B != 0)
2892 }
2893 return true;
2894
2896 FourByteBuffer = DE.getU32(Cursor);
2897 return decodeCOMPUTE_PGM_RSRC3(FourByteBuffer, KdStream);
2898
2900 FourByteBuffer = DE.getU32(Cursor);
2901 return decodeCOMPUTE_PGM_RSRC1(FourByteBuffer, KdStream);
2902
2904 FourByteBuffer = DE.getU32(Cursor);
2905 return decodeCOMPUTE_PGM_RSRC2(FourByteBuffer, KdStream);
2906
2908 using namespace amdhsa;
2909 TwoByteBuffer = DE.getU16(Cursor);
2910
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);
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(KERNEL_CODE_PROPERTY_RESERVED0,
2931
2932 // Reserved for GFX9
2933 if (isGFX9() &&
2934 (TwoByteBuffer & KERNEL_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32)) {
2936 KERNEL_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32,
2937 amdhsa::KERNEL_CODE_PROPERTIES_OFFSET, "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(KERNEL_CODE_PROPERTY_RESERVED1,
2951 }
2952
2953 return true;
2954
2956 using namespace amdhsa;
2957 TwoByteBuffer = DE.getU16(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
2970 // 4 bytes from here are reserved, must be 0.
2971 ReservedBytes = DE.getBytes(Cursor, 4);
2972 for (char B : ReservedBytes) {
2973 if (B != 0)
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
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(std::errc::invalid_argument,
2991 "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 =
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
3012 while (C && C.tell() < Bytes.size()) {
3013 Expected<bool> Res = decodeKernelDescriptorDirective(C, Bytes, KdStream);
3014
3015 cantFail(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
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(std::errc::invalid_argument,
3039 "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(StringRef(".kd"))) {
3045 Size = 64; // Size = 64 regardless of success or failure.
3046 return decodeKernelDescriptor(Name.drop_back(3), Bytes, 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(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()) {
3060 } else {
3061 int64_t Res = ~Val;
3062 bool Valid = Sym->getVariableValue()->evaluateAsAbsolute(Res);
3063 if (!Valid || Res != Val)
3064 Ctx.reportWarning(SMLoc(), "unsupported redefinition of " + Id);
3065 }
3066 return MCSymbolRefExpr::create(Sym, Ctx);
3067}
3068
3070 // Check for MUBUF and MTBUF instructions
3071 if (SIInstrFlags::isBuffer(*MCII, MI))
3072 return true;
3073
3074 // Check for SMEM buffer instructions (S_BUFFER_* instructions)
3075 if (SIInstrFlags::isSMRD(*MCII, MI) &&
3076 AMDGPU::getSMEMIsBuffer(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
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(*Symbols, [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(Result->Name);
3106 const auto *Add = MCSymbolRefExpr::create(Sym, Ctx);
3108 return true;
3109 }
3110 // Add to list of referenced addresses, so caller can synthesize a label.
3111 ReferencedAddresses.push_back(static_cast<uint64_t>(Value));
3112 return false;
3113}
3114
3116 int64_t Value,
3117 uint64_t Address) {
3118 llvm_unreachable("unimplemented");
3119}
3120
3121//===----------------------------------------------------------------------===//
3122// Initialization
3123//===----------------------------------------------------------------------===//
3124
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
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
MCDisassembler::DecodeStatus DecodeStatus
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
aarch64 promote const
#define CHECK_RESERVED_BITS_DESC(MASK, DESC)
static VOPModifiers collectVOPModifiers(const MCInst &MI, bool IsVOP3P=false)
static int insertNamedMCOperand(MCInst &MI, const MCOperand &Op, AMDGPU::OpName Name)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAMDGPUDisassembler()
static DecodeStatus decodeOperand_VSrcT16_Lo128(MCInst &Inst, unsigned Imm, uint64_t, const MCDisassembler *Decoder)
static DecodeStatus decodeOperand_KImmFP64(MCInst &Inst, uint64_t Imm, uint64_t Addr, const MCDisassembler *Decoder)
static SmallString< 32 > getBitRangeFromMask(uint32_t Mask, unsigned BaseBytes)
Print a string describing the reserved bit range specified by Mask with offset BaseBytes for use in e...
#define DECODE_OPERAND_SREG_8(RegClass, OpWidth)
static DecodeStatus decodeSMEMOffset(MCInst &Inst, unsigned Imm, uint64_t Addr, const MCDisassembler *Decoder)
static std::bitset< 128 > eat16Bytes(ArrayRef< uint8_t > &Bytes)
#define DECODE_OPERAND_SREG_7(RegClass, OpWidth)
static DecodeStatus decodeSrcA9(MCInst &Inst, unsigned Imm, uint64_t, const MCDisassembler *Decoder)
static DecodeStatus decodeOperand_VGPR_16(MCInst &Inst, unsigned Imm, uint64_t, const MCDisassembler *Decoder)
#define PRINT_PSEUDO_DIRECTIVE_COMMENT(DIRECTIVE, MASK)
static DecodeStatus decodeSrcOp(MCInst &Inst, unsigned EncSize, unsigned OpWidth, unsigned Imm, unsigned EncImm, const MCDisassembler *Decoder)
unsigned Imm
static DecodeStatus decodeDpp8FI(MCInst &Inst, unsigned Val, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus decodeOperand_VSrc_f64(MCInst &Inst, unsigned Imm, uint64_t Addr, const MCDisassembler *Decoder)
static MCRegister CheckVGPROverflow(MCRegister Reg, const MCRegisterClass &RC, const MCRegisterInfo &MRI)
static int64_t getInlineImmValBF16(unsigned Imm)
#define DECODE_SDWA(DecName)
static DecodeStatus decodeSOPPBrTarget(MCInst &Inst, unsigned Imm, uint64_t Addr, const MCDisassembler *Decoder)
#define DECODE_OPERAND_REG_8(RegClass)
#define PRINT_DIRECTIVE(DIRECTIVE, MASK)
static DecodeStatus decodeSrcRegOrImm9(MCInst &Inst, unsigned Imm, uint64_t, const MCDisassembler *Decoder)
static DecodeStatus DecodeVGPR_16RegisterClass(MCInst &Inst, unsigned Imm, uint64_t, const MCDisassembler *Decoder)
static DecodeStatus decodeSrcReg9(MCInst &Inst, unsigned Imm, uint64_t, const MCDisassembler *Decoder)
static int64_t getInlineImmVal32(unsigned Imm)
unsigned uint64_t
static MCDisassembler::DecodeStatus addOperand(MCInst &Inst, const MCOperand &Opnd)
#define CHECK_RESERVED_BITS(MASK)
static DecodeStatus decodeSrcAV10(MCInst &Inst, unsigned Imm, uint64_t, const MCDisassembler *Decoder)
#define SGPR_MAX
static int64_t getInlineImmVal64(unsigned Imm)
static T eatBytes(ArrayRef< uint8_t > &Bytes)
static DecodeStatus decodeOperand_KImmFP(MCInst &Inst, unsigned Imm, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus decodeAVLdSt(MCInst &Inst, unsigned Imm, unsigned Opw, const MCDisassembler *Decoder)
#define DECODE_SDWA_IMM_FIELD(Name, MaxImm)
static MCDisassembler * createAMDGPUDisassembler(const Target &T, const MCSubtargetInfo &STI, MCContext &Ctx)
static DecodeStatus decodeSrcRegOrImmA9(MCInst &Inst, unsigned Imm, uint64_t, const MCDisassembler *Decoder)
static DecodeStatus DecodeVGPR_16_Lo128RegisterClass(MCInst &Inst, unsigned Imm, uint64_t, const MCDisassembler *Decoder)
#define CHECK_RESERVED_BITS_MSG(MASK, MSG)
static DecodeStatus decodeOperandVOPDDstY(MCInst &Inst, unsigned Val, uint64_t Addr, const void *Decoder)
static MCSymbolizer * createAMDGPUSymbolizer(const Triple &, LLVMOpInfoCallback, LLVMSymbolLookupCallback, void *DisInfo, MCContext *Ctx, std::unique_ptr< MCRelocationInfo > &&RelInfo)
static DecodeStatus decodeBoolReg(MCInst &Inst, unsigned Val, uint64_t Addr, const MCDisassembler *Decoder)
static int64_t getInlineImmValF16(unsigned Imm)
unsigned const MCDisassembler * Decoder
#define GET_FIELD(MASK)
static std::bitset< 96 > eat12Bytes(ArrayRef< uint8_t > &Bytes)
static DecodeStatus decodeOperand_VSrcT16(MCInst &Inst, unsigned Imm, uint64_t, const MCDisassembler *Decoder)
static Error createReservedKDBytesError(unsigned BaseInBytes, unsigned WidthInBytes)
Create an error object to return from onSymbolStart for reserved kernel descriptor bytes being set.
static DecodeStatus decodeSplitBarrier(MCInst &Inst, unsigned Val, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus decodeAV10(MCInst &Inst, unsigned Imm, uint64_t, const MCDisassembler *Decoder)
static bool adjustMFMA_F8F6F4OpRegClass(const MCRegisterInfo &MRI, MCOperand &MO, uint8_t NumRegs)
Adjust the register values used by V_MFMA_F8F6F4_f8_f8 instructions to the appropriate subregister fo...
#define CHECK_RESERVED_BITS_DESC_MSG(MASK, DESC, MSG)
static Error createReservedKDBitsError(uint32_t Mask, unsigned BaseBytes, const char *Msg="")
Create an error object to return from onSymbolStart for reserved kernel descriptor bits being set.
This file contains declaration for AMDGPU ISA disassembler.
Provides AMDGPU specific target descriptions.
static cl::opt< bool > XnackSetting("amdgpu-xnack", cl::desc("Force amdgpu.xnack value for testing"), cl::ReallyHidden)
AMDHSA kernel descriptor definitions.
#define AMDHSA_BITS_GET(SRC, MSK)
#define X(NUM, ENUM, NAME)
Definition ELF.h:856
#define AMDGPU_MACH_LIST(X)
Definition ELF.h:768
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_ABI
Definition Compiler.h:215
#define LLVM_EXTERNAL_VISIBILITY
Definition Compiler.h:132
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition MD5.cpp:57
Register Reg
#define T
Interface definition for SIRegisterInfo.
const char * Msg
std::optional< unsigned > getSgprClassId(unsigned Width) const
Return the SGPR/TTMP register class accepted by source decoding for Width, or std::nullopt if that wi...
MCOperand decodeNonVGPRSrcOp(const MCInst &Inst, unsigned Width, unsigned Val) const
MCOperand decodeLiteral64Constant() const
void convertVOPC64DPPInst(MCInst &MI) const
bool isBufferInstruction(const MCInst &MI) const
Check if the instruction is a buffer operation (MUBUF, MTBUF, or S_BUFFER)
void convertEXPInst(MCInst &MI) const
MCOperand decodeSpecialReg64(unsigned Val) const
const char * getRegClassName(unsigned RegClassID) const
Expected< bool > decodeCOMPUTE_PGM_RSRC1(uint32_t FourByteBuffer, raw_string_ostream &KdStream) const
Decode as directives that handle COMPUTE_PGM_RSRC1.
MCOperand decodeSplitBarrier(const MCInst &Inst, unsigned Val) const
Expected< bool > decodeKernelDescriptorDirective(DataExtractor::Cursor &Cursor, ArrayRef< uint8_t > Bytes, raw_string_ostream &KdStream) const
void convertVOPCDPPInst(MCInst &MI) const
MCOperand decodeSpecialReg96Plus(unsigned Val) const
MCOperand decodeSDWASrc32(unsigned Val) const
void setABIVersion(unsigned Version) override
ELF-specific, set the ABI version from the object header.
Expected< bool > decodeCOMPUTE_PGM_RSRC2(uint32_t FourByteBuffer, raw_string_ostream &KdStream) const
Decode as directives that handle COMPUTE_PGM_RSRC2.
unsigned getAgprClassId(unsigned Width) const
MCOperand decodeDpp8FI(unsigned Val) const
MCOperand decodeSDWASrc(unsigned Width, unsigned Val) const
void convertFMAanyK(MCInst &MI) const
DecodeStatus tryDecodeInst(const uint8_t *Table, MCInst &MI, InsnType Inst, uint64_t Address, raw_ostream &Comments) const
void convertMacDPPInst(MCInst &MI) const
MCOperand decodeVOPDDstYOp(MCInst &Inst, unsigned Val) const
void convertDPP8Inst(MCInst &MI) const
MCOperand createVGPR16Operand(unsigned RegIdx, bool IsHi) const
MCOperand errOperand(unsigned V, const Twine &ErrMsg) const
MCOperand decodeVersionImm(unsigned Imm) const
Expected< bool > decodeKernelDescriptor(StringRef KdName, ArrayRef< uint8_t > Bytes, uint64_t KdAddress) const
void convertVOP3DPPInst(MCInst &MI) const
void convertTrue16OpSel(MCInst &MI) const
MCOperand decodeSrcOp(const MCInst &Inst, unsigned Width, unsigned Val) const
bool convertMAIInst(MCInst &MI) const
f8f6f4 instructions have different pseudos depending on the used formats.
MCOperand decodeMandatoryLiteralConstant(unsigned Imm) const
MCOperand decodeLiteralConstant(const MCInstrDesc &Desc, const MCOperandInfo &OpDesc) const
Expected< bool > decodeCOMPUTE_PGM_RSRC3(uint32_t FourByteBuffer, raw_string_ostream &KdStream) const
Decode as directives that handle COMPUTE_PGM_RSRC3.
AMDGPUDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, MCInstrInfo const *MCII)
MCOperand decodeSpecialReg32(unsigned Val) const
MCOperand createRegOperand(MCRegister Reg) const
MCOperand decodeSDWAVopcDst(unsigned Val) const
void convertVINTERPInst(MCInst &MI) const
void convertSDWAInst(MCInst &MI) const
static MCOperand decodeIntImmed(unsigned Imm)
MCOperand decodeBoolReg(const MCInst &Inst, unsigned Val) const
void emitTargetIDIfSupported(raw_ostream &OS, unsigned EFlags) const override
Emit something based on ELF's e_flags if the target needs to.
unsigned getVgprClassId(unsigned Width) const
DecodeStatus getInstruction(MCInst &MI, uint64_t &Size, ArrayRef< uint8_t > Bytes, uint64_t Address, raw_ostream &CS) const override
Returns the disassembly of a single instruction.
std::optional< unsigned > getTtmpClassId(unsigned Width) const
MCOperand decodeMandatoryLiteral64Constant(uint64_t Imm) const
void convertMIMGInst(MCInst &MI) const
bool isMacDPP(MCInst &MI) const
int getTTmpIdx(unsigned Val) const
void convertVOP3PDPPInst(MCInst &MI) const
bool convertWMMAInst(MCInst &MI) const
MCOperand createSRegOperand(unsigned SRegClassID, unsigned Val) const
MCOperand decodeSDWASrc16(unsigned Val) const
Expected< bool > onSymbolStart(SymbolInfoTy &Symbol, uint64_t &Size, ArrayRef< uint8_t > Bytes, uint64_t Address) const override
Used to perform separate target specific disassembly for a particular symbol.
static const AMDGPUMCExpr * createLit(LitModifier Lit, int64_t Value, MCContext &Ctx)
bool tryAddingSymbolicOperand(MCInst &Inst, raw_ostream &cStream, int64_t Value, uint64_t Address, bool IsBranch, uint64_t Offset, uint64_t OpSize, uint64_t InstSize) override
Try to add a symbolic operand instead of Value to the MCInst.
void tryAddingPcLoadReferenceComment(raw_ostream &cStream, int64_t Value, uint64_t Address) override
Try to add a comment on the PC-relative load.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
Get the array size.
Definition ArrayRef.h:141
const T * data() const
Definition ArrayRef.h:138
ArrayRef< T > slice(size_t N, size_t M) const
slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array.
Definition ArrayRef.h:185
A class representing a position in a DataExtractor, as well as any error encountered during extractio...
LLVM_ABI uint32_t getU32(uint64_t *offset_ptr, Error *Err=nullptr) const
Extract a uint32_t value from *offset_ptr.
LLVM_ABI uint16_t getU16(uint64_t *offset_ptr, Error *Err=nullptr) const
Extract a uint16_t value from *offset_ptr.
LLVM_ABI void skip(Cursor &C, uint64_t Length) const
Advance the Cursor position by the given number of bytes.
LLVM_ABI StringRef getBytes(uint64_t *OffsetPtr, uint64_t Length, Error *Err=nullptr) const
Extract a fixed number of bytes from the specified offset.
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
Tagged union holding either a T or a Error.
Definition Error.h:485
static const MCBinaryExpr * createOr(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition MCExpr.h:407
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition MCExpr.cpp:212
Context object for machine code objects.
Definition MCContext.h:83
const MCRegisterInfo * getRegisterInfo() const
Definition MCContext.h:411
Superclass for all disassemblers.
MCDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
MCContext & getContext() const
const MCSubtargetInfo & STI
raw_ostream * CommentStream
DecodeStatus
Ternary decode status.
Base class for the full range of assembler expressions which are needed for parsing.
Definition MCExpr.h:34
Instances of this class represent a single low-level machine instruction.
Definition MCInst.h:188
unsigned getOpcode() const
Definition MCInst.h:202
void addOperand(const MCOperand Op)
Definition MCInst.h:215
const MCOperand & getOperand(unsigned i) const
Definition MCInst.h:210
Describe properties that are true of each instruction in the target description file.
Interface to description of machine instruction set.
Definition MCInstrInfo.h:27
This holds information about one operand of a machine instruction, indicating the register class for ...
Definition MCInstrDesc.h:86
uint8_t OperandType
Information about the type of the operand.
Definition MCInstrDesc.h:98
Instances of this class represent operands of the MCInst class.
Definition MCInst.h:40
static MCOperand createExpr(const MCExpr *Val)
Definition MCInst.h:166
int64_t getImm() const
Definition MCInst.h:84
static MCOperand createReg(MCRegister Reg)
Definition MCInst.h:138
static MCOperand createImm(int64_t Val)
Definition MCInst.h:145
void setReg(MCRegister Reg)
Set the register number.
Definition MCInst.h:79
bool isReg() const
Definition MCInst.h:65
MCRegister getReg() const
Returns the register number.
Definition MCInst.h:73
bool isValid() const
Definition MCInst.h:64
MCRegisterClass - Base class of TargetRegisterClass.
MCRegister getRegister(unsigned i) const
getRegister - Return the specified register in the class.
unsigned getSizeInBits() const
Return the size of the physical register in bits if we are able to determine it.
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
MCRegister getMatchingSuperReg(MCRegister Reg, unsigned SubIdx, const MCRegisterClass *RC) const
Return a super-register of the specified register Reg so its sub-register of index SubIdx is Reg.
const char * getRegClassName(const MCRegisterClass *Class) const
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
Generic base class for all target subtargets.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.h:213
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition MCSymbol.h:42
bool isVariable() const
isVariable - Check if this is a variable symbol.
Definition MCSymbol.h:267
LLVM_ABI void setVariableValue(const MCExpr *Value)
Definition MCSymbol.cpp:50
const MCExpr * getVariableValue() const
Get the expression of the variable symbol.
Definition MCSymbol.h:270
Symbolize and annotate disassembled instructions.
Represents a location in source code.
Definition SMLoc.h:22
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition SmallString.h:26
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Target - Wrapper for Target specific information.
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
LLVM Value Representation.
Definition Value.h:75
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
A raw_ostream that writes to an std::string.
std::string & str()
Returns the string's reference.
A raw_ostream that writes to an SmallVector or SmallString.
const char *(* LLVMSymbolLookupCallback)(void *DisInfo, uint64_t ReferenceValue, uint64_t *ReferenceType, uint64_t ReferencePC, const char **ReferenceName)
The type for the symbol lookup function.
int(* LLVMOpInfoCallback)(void *DisInfo, uint64_t PC, uint64_t Offset, uint64_t OpSize, uint64_t InstSize, int TagType, void *TagBuf)
The type for the operand information call back function.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned getVGPREncodingGranule(const MCSubtargetInfo &STI, std::optional< bool > EnableWavefrontSize32)
unsigned getSGPREncodingGranule(const MCSubtargetInfo &STI)
ArrayRef< GFXVersion > getGFXVersions()
bool isInlinableLiteralBF16(int16_t Literal, bool HasInv2Pi)
EncodingField< Bit, Bit, D > EncodingBit
bool isPKFMACF16InlineConstant(uint32_t Literal, bool IsGFX11Plus)
LLVM_READONLY const MIMGInfo * getMIMGInfo(unsigned Opc)
bool isInlinableLiteralFP16(int16_t Literal, bool HasInv2Pi)
MCRegister getMCReg(MCRegister Reg, const MCSubtargetInfo &STI)
If Reg is a pseudo reg, return the correct hardware register given STI otherwise return Reg.
int getMIMGOpcode(unsigned BaseOpcode, unsigned MIMGEncoding, unsigned VDataDwords, unsigned VAddrDwords)
bool isInlinableLiteralV2I16(uint32_t Literal)
bool isGFX10(const MCSubtargetInfo &STI)
bool isInlinableLiteralV2BF16(uint32_t Literal)
bool isGFX12Plus(const MCSubtargetInfo &STI)
bool hasPackedD16(const MCSubtargetInfo &STI)
bool isInlinableLiteralV2F16(uint32_t Literal)
bool getSMEMIsBuffer(unsigned Opc)
bool isGFX13(const MCSubtargetInfo &STI)
bool isVOPC64DPP(unsigned Opc)
bool hasPrivateApertureRegs(const MCSubtargetInfo &STI)
unsigned getAMDHSACodeObjectVersion(const Module &M)
LLVM_READONLY bool hasNamedOperand(uint64_t Opcode, OpName NamedIdx)
bool isGFX9(const MCSubtargetInfo &STI)
LLVM_READONLY const MIMGDimInfo * getMIMGDimInfoByEncoding(uint8_t DimEnc)
bool isInlinableLiteral32(int32_t Literal, bool HasInv2Pi)
const MFMA_F8F6F4_Info * getWMMA_F8F6F4_WithFormatArgs(unsigned FmtA, unsigned FmtB, unsigned F8F8Opcode)
bool hasG16(const MCSubtargetInfo &STI)
unsigned getAddrSizeMIMGOp(const MIMGBaseOpcodeInfo *BaseOpcode, const MIMGDimInfo *Dim, bool IsA16, bool IsG16Supported)
bool isGFX13Plus(const MCSubtargetInfo &STI)
bool isGFX11Plus(const MCSubtargetInfo &STI)
bool isGFX10Plus(const MCSubtargetInfo &STI)
@ OPERAND_REG_IMM_V2FP64
Definition SIDefines.h:447
@ OPERAND_KIMM32
Operand with 32-bit immediate that uses the constant bus.
Definition SIDefines.h:465
@ OPERAND_REG_IMM_INT64
Definition SIDefines.h:433
@ OPERAND_REG_IMM_V2FP16
Definition SIDefines.h:440
@ OPERAND_REG_INLINE_C_FP64
Definition SIDefines.h:456
@ OPERAND_REG_INLINE_C_BF16
Definition SIDefines.h:453
@ OPERAND_REG_INLINE_C_V2BF16
Definition SIDefines.h:458
@ OPERAND_REG_IMM_V2INT64
Definition SIDefines.h:443
@ OPERAND_REG_IMM_V2INT16
Definition SIDefines.h:442
@ OPERAND_REG_IMM_BF16
Definition SIDefines.h:437
@ OPERAND_REG_IMM_INT32
Operands with register, 32-bit, or 64-bit immediate.
Definition SIDefines.h:432
@ OPERAND_REG_IMM_V2BF16
Definition SIDefines.h:439
@ OPERAND_REG_IMM_FP16
Definition SIDefines.h:438
@ OPERAND_REG_IMM_V2FP16_SPLAT
Definition SIDefines.h:441
@ OPERAND_REG_INLINE_C_INT64
Definition SIDefines.h:452
@ OPERAND_REG_INLINE_C_INT16
Operands with register or inline constant.
Definition SIDefines.h:450
@ OPERAND_REG_IMM_NOINLINE_V2FP16
Definition SIDefines.h:444
@ OPERAND_REG_IMM_FP64
Definition SIDefines.h:436
@ OPERAND_REG_INLINE_C_V2FP16
Definition SIDefines.h:459
@ OPERAND_REG_INLINE_AC_INT32
Operands with an AccVGPR register or inline constant.
Definition SIDefines.h:470
@ OPERAND_REG_INLINE_AC_FP32
Definition SIDefines.h:471
@ OPERAND_REG_IMM_V2INT32
Definition SIDefines.h:445
@ OPERAND_REG_IMM_FP32
Definition SIDefines.h:435
@ OPERAND_REG_INLINE_C_FP32
Definition SIDefines.h:455
@ OPERAND_REG_INLINE_C_INT32
Definition SIDefines.h:451
@ OPERAND_REG_INLINE_C_V2INT16
Definition SIDefines.h:457
@ OPERAND_REG_IMM_V2FP32
Definition SIDefines.h:446
@ OPERAND_REG_INLINE_AC_FP64
Definition SIDefines.h:472
@ OPERAND_REG_INLINE_C_FP16
Definition SIDefines.h:454
@ OPERAND_REG_IMM_INT16
Definition SIDefines.h:434
bool hasGDS(const MCSubtargetInfo &STI)
bool isGFX9Plus(const MCSubtargetInfo &STI)
bool isVOPD(unsigned Opc)
bool isGFX1250(const MCSubtargetInfo &STI)
unsigned hasKernargPreload(const MCSubtargetInfo &STI)
bool isMAC(unsigned Opc)
LLVM_READONLY const MIMGBaseOpcodeInfo * getMIMGBaseOpcodeInfo(unsigned BaseOpcode)
bool isGFX1250Plus(const MCSubtargetInfo &STI)
bool hasPopsExitingWaveID(const MCSubtargetInfo &STI)
bool isInlinableLiteralI16(int32_t Literal, bool HasInv2Pi)
bool hasVOPD(const MCSubtargetInfo &STI)
bool isInlinableLiteral64(int64_t Literal, bool HasInv2Pi)
Is this literal inlinable.
const MFMA_F8F6F4_Info * getMFMA_F8F6F4_WithFormatArgs(unsigned CBSZ, unsigned BLGP, unsigned F8F8Opcode)
@ STT_NOTYPE
Definition ELF.h:1426
@ STT_AMDGPU_HSA_KERNEL
Definition ELF.h:1440
@ STT_OBJECT
Definition ELF.h:1427
@ EF_AMDGPU_FEATURE_XNACK_ANY_V4
Definition ELF.h:909
@ EF_AMDGPU_FEATURE_SRAMECC_UNSUPPORTED_V4
Definition ELF.h:920
@ EF_AMDGPU_FEATURE_SRAMECC_OFF_V4
Definition ELF.h:924
@ EF_AMDGPU_FEATURE_XNACK_UNSUPPORTED_V4
Definition ELF.h:907
@ EF_AMDGPU_FEATURE_XNACK_OFF_V4
Definition ELF.h:911
@ EF_AMDGPU_FEATURE_XNACK_V4
Definition ELF.h:905
@ EF_AMDGPU_FEATURE_SRAMECC_V4
Definition ELF.h:918
@ EF_AMDGPU_FEATURE_XNACK_ON_V4
Definition ELF.h:913
@ EF_AMDGPU_MACH
Definition ELF.h:851
@ EF_AMDGPU_FEATURE_SRAMECC_ANY_V4
Definition ELF.h:922
@ EF_AMDGPU_FEATURE_SRAMECC_ON_V4
Definition ELF.h:926
constexpr bool isAtomicRet(const T &...O)
Definition SIDefines.h:368
constexpr bool isVOPC(const T &...O)
Definition SIDefines.h:237
constexpr bool isVOP3(const T &...O)
Definition SIDefines.h:240
constexpr bool isMAI(const T &...O)
Definition SIDefines.h:356
constexpr bool isFLAT(const T &...O)
Definition SIDefines.h:287
constexpr bool isVOP3P(const T &...O)
Definition SIDefines.h:243
constexpr bool isBuffer(const T &...O)
Definition SIDefines.h:268
constexpr bool isVIMAGE(const T &...O)
Definition SIDefines.h:278
constexpr bool isSMRD(const T &...O)
Definition SIDefines.h:272
constexpr bool isVOP3Like(const T &...O)
Definition SIDefines.h:246
constexpr bool isMIMG(const T &...O)
Definition SIDefines.h:275
constexpr bool isWMMA(const T &...O)
Definition SIDefines.h:371
constexpr bool isMUBUF(const T &...O)
Definition SIDefines.h:262
constexpr bool isSDWA(const T &...O)
Definition SIDefines.h:253
constexpr bool isEXP(const T &...O)
Definition SIDefines.h:284
constexpr bool isSOPK(const T &...O)
Definition SIDefines.h:225
constexpr bool isVINTERP(const T &...O)
Definition SIDefines.h:299
constexpr bool isVSAMPLE(const T &...O)
Definition SIDefines.h:281
constexpr bool isDS(const T &...O)
Definition SIDefines.h:290
constexpr bool isGather4(const T &...O)
Definition SIDefines.h:308
constexpr bool isDPP(const T &...O)
Definition SIDefines.h:256
value_type read(const void *memory, endianness endian)
Read a value of a particular endianness from memory.
Definition Endian.h:53
uint16_t read16(const void *P, endianness E)
Definition Endian.h:389
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:578
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Definition STLExtras.h:2554
LLVM_ABI raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
SmallVectorImpl< T >::const_pointer c_str(SmallVectorImpl< T > &str)
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition Error.h:1321
Op::Description Desc
constexpr int popcount(T Value) noexcept
Count the number of set bits in a value.
Definition bit.h:156
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
Definition bit.h:204
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
Definition MathExtras.h:151
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:190
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
Definition Error.h:769
Target & getTheGCNTarget()
The target for GCN GPUs.
To bit_cast(const From &from) noexcept
Definition bit.h:90
@ Add
Sum of integers.
DWARFExpression::Operation Op
unsigned M0(unsigned Val)
Definition VE.h:376
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1772
Target & getTheGCNLegacyTarget()
The target for GCN GPUs, registered under the legacy "amdgcn" architecture name for use with -march.
std::vector< SymbolInfoTy > SectionSymbolsTy
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
Definition MathExtras.h:567
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
Definition Error.cpp:177
static void RegisterMCSymbolizer(Target &T, Target::MCSymbolizerCtorTy Fn)
RegisterMCSymbolizer - Register an MCSymbolizer implementation for the given target.
static void RegisterMCDisassembler(Target &T, Target::MCDisassemblerCtorTy Fn)
RegisterMCDisassembler - Register a MCDisassembler implementation for the given target.