1//===- AMDGPUDisassembler.hpp - Disassembler for AMDGPU ISA -----*- C++ -*-===//
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/// \file
10///
11/// This file contains declaration for AMDGPU ISA disassembler
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_LIB_TARGET_AMDGPU_DISASSEMBLER_AMDGPUDISASSEMBLER_H
16#define LLVM_LIB_TARGET_AMDGPU_DISASSEMBLER_AMDGPUDISASSEMBLER_H
17
18#include "SIDefines.h"
19#include "llvm/ADT/APInt.h"
20#include "llvm/ADT/SmallString.h"
21#include "llvm/MC/MCDisassembler/MCDisassembler.h"
22#include "llvm/MC/MCInst.h"
23#include "llvm/MC/MCInstrInfo.h"
24#include "llvm/Support/DataExtractor.h"
25#include <memory>
26
27namespace llvm {
28
29class MCAsmInfo;
30class MCInst;
31class MCOperand;
32class MCSubtargetInfo;
33class Twine;
34
35//===----------------------------------------------------------------------===//
36// AMDGPUDisassembler
37//===----------------------------------------------------------------------===//
38
39class AMDGPUDisassembler : public MCDisassembler {
40private:
41 std::unique_ptr<MCInstrInfo const> const MCII;
42 const MCRegisterInfo &MRI;
43 const MCAsmInfo &MAI;
44 const unsigned HwModeRegClass;
45 const unsigned TargetMaxInstBytes;
46 mutable ArrayRef<uint8_t> Bytes;
47 mutable uint64_t Literal;
48 mutable bool HasLiteral;
49 mutable std::optional<bool> EnableWavefrontSize32;
50 unsigned CodeObjectVersion;
51 const MCExpr *UCVersionW64Expr;
52 const MCExpr *UCVersionW32Expr;
53 const MCExpr *UCVersionMDPExpr;
54
55 const MCExpr *createConstantSymbolExpr(StringRef Id, int64_t Val);
56
57 void decodeImmOperands(MCInst &MI, const MCInstrInfo &MCII) const;
58
59public:
60 AMDGPUDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
61 MCInstrInfo const *MCII);
62 ~AMDGPUDisassembler() override = default;
63
64 void setABIVersion(unsigned Version) override;
65
66 void emitTargetIDIfSupported(raw_ostream &OS, unsigned EFlags) const override;
67
68 DecodeStatus getInstruction(MCInst &MI, uint64_t &Size,
69 ArrayRef<uint8_t> Bytes, uint64_t Address,
70 raw_ostream &CS) const override;
71
72 const char* getRegClassName(unsigned RegClassID) const;
73
74 MCOperand createRegOperand(MCRegister Reg) const;
75 MCOperand createRegOperand(unsigned RegClassID, unsigned Val) const;
76 MCOperand createSRegOperand(unsigned SRegClassID, unsigned Val) const;
77 MCOperand createVGPR16Operand(unsigned RegIdx, bool IsHi) const;
78
79 MCOperand errOperand(unsigned V, const Twine& ErrMsg) const;
80
81 template <typename InsnType>
82 DecodeStatus tryDecodeInst(const uint8_t *Table, MCInst &MI, InsnType Inst,
83 uint64_t Address, raw_ostream &Comments) const;
84 template <typename InsnType>
85 DecodeStatus tryDecodeInst(const uint8_t *Table1, const uint8_t *Table2,
86 MCInst &MI, InsnType Inst, uint64_t Address,
87 raw_ostream &Comments) const;
88
89 Expected<bool> onSymbolStart(SymbolInfoTy &Symbol, uint64_t &Size,
90 ArrayRef<uint8_t> Bytes,
91 uint64_t Address) const override;
92
93 Expected<bool> decodeKernelDescriptor(StringRef KdName,
94 ArrayRef<uint8_t> Bytes,
95 uint64_t KdAddress) const;
96
97 Expected<bool>
98 decodeKernelDescriptorDirective(DataExtractor::Cursor &Cursor,
99 ArrayRef<uint8_t> Bytes,
100 raw_string_ostream &KdStream) const;
101
102 /// Decode as directives that handle COMPUTE_PGM_RSRC1.
103 /// \param FourByteBuffer - Bytes holding contents of COMPUTE_PGM_RSRC1.
104 /// \param KdStream - Stream to write the disassembled directives to.
105 // NOLINTNEXTLINE(readability-identifier-naming)
106 Expected<bool> decodeCOMPUTE_PGM_RSRC1(uint32_t FourByteBuffer,
107 raw_string_ostream &KdStream) const;
108
109 /// Decode as directives that handle COMPUTE_PGM_RSRC2.
110 /// \param FourByteBuffer - Bytes holding contents of COMPUTE_PGM_RSRC2.
111 /// \param KdStream - Stream to write the disassembled directives to.
112 // NOLINTNEXTLINE(readability-identifier-naming)
113 Expected<bool> decodeCOMPUTE_PGM_RSRC2(uint32_t FourByteBuffer,
114 raw_string_ostream &KdStream) const;
115
116 /// Decode as directives that handle COMPUTE_PGM_RSRC3.
117 /// \param FourByteBuffer - Bytes holding contents of COMPUTE_PGM_RSRC3.
118 /// \param KdStream - Stream to write the disassembled directives to.
119 // NOLINTNEXTLINE(readability-identifier-naming)
120 Expected<bool> decodeCOMPUTE_PGM_RSRC3(uint32_t FourByteBuffer,
121 raw_string_ostream &KdStream) const;
122
123 void convertEXPInst(MCInst &MI) const;
124 void convertVINTERPInst(MCInst &MI) const;
125 void convertFMAanyK(MCInst &MI) const;
126 void convertSDWAInst(MCInst &MI) const;
127 void convertMAIInst(MCInst &MI) const;
128 void convertWMMAInst(MCInst &MI) const;
129 void convertDPP8Inst(MCInst &MI) const;
130 void convertMIMGInst(MCInst &MI) const;
131 void convertVOP3DPPInst(MCInst &MI) const;
132 void convertVOP3PDPPInst(MCInst &MI) const;
133 void convertVOPCDPPInst(MCInst &MI) const;
134 void convertVOPC64DPPInst(MCInst &MI) const;
135 void convertMacDPPInst(MCInst &MI) const;
136 void convertTrue16OpSel(MCInst &MI) const;
137
138 unsigned getVgprClassId(unsigned Width) const;
139 unsigned getAgprClassId(unsigned Width) const;
140 unsigned getSgprClassId(unsigned Width) const;
141 unsigned getTtmpClassId(unsigned Width) const;
142
143 static MCOperand decodeIntImmed(unsigned Imm);
144
145 MCOperand decodeMandatoryLiteralConstant(unsigned Imm) const;
146 MCOperand decodeMandatoryLiteral64Constant(uint64_t Imm) const;
147 MCOperand decodeLiteralConstant(const MCInstrDesc &Desc,
148 const MCOperandInfo &OpDesc) const;
149 MCOperand decodeLiteral64Constant() const;
150
151 MCOperand decodeSrcOp(const MCInst &Inst, unsigned Width, unsigned Val) const;
152
153 MCOperand decodeNonVGPRSrcOp(const MCInst &Inst, unsigned Width,
154 unsigned Val) const;
155
156 MCOperand decodeVOPDDstYOp(MCInst &Inst, unsigned Val) const;
157 MCOperand decodeSpecialReg32(unsigned Val) const;
158 MCOperand decodeSpecialReg64(unsigned Val) const;
159 MCOperand decodeSpecialReg96Plus(unsigned Val) const;
160
161 MCOperand decodeSDWASrc(unsigned Width, unsigned Val) const;
162 MCOperand decodeSDWASrc16(unsigned Val) const;
163 MCOperand decodeSDWASrc32(unsigned Val) const;
164 MCOperand decodeSDWAVopcDst(unsigned Val) const;
165
166 MCOperand decodeBoolReg(const MCInst &Inst, unsigned Val) const;
167 MCOperand decodeSplitBarrier(const MCInst &Inst, unsigned Val) const;
168 MCOperand decodeDpp8FI(unsigned Val) const;
169
170 MCOperand decodeVersionImm(unsigned Imm) const;
171
172 int getTTmpIdx(unsigned Val) const;
173
174 const MCInstrInfo *getMCII() const { return MCII.get(); }
175
176 bool isVI() const;
177 bool isGFX9() const;
178 bool isGFX90A() const;
179 bool isGFX9Plus() const;
180 bool isGFX10() const;
181 bool isGFX10Plus() const;
182 bool isGFX11() const;
183 bool isGFX1170() const;
184 bool isGFX11Plus() const;
185 bool isGFX12() const;
186 bool isGFX12Plus() const;
187 bool isGFX1250() const;
188 bool isGFX1250Plus() const;
189 bool isGFX13() const;
190 bool isGFX13Plus() const;
191
192 bool hasArchitectedFlatScratch() const;
193 bool hasKernargPreload() const;
194
195 bool isMacDPP(MCInst &MI) const;
196
197 /// Check if the instruction is a buffer operation (MUBUF, MTBUF, or S_BUFFER)
198 bool isBufferInstruction(const MCInst &MI) const;
199};
200
201//===----------------------------------------------------------------------===//
202// AMDGPUSymbolizer
203//===----------------------------------------------------------------------===//
204
205class AMDGPUSymbolizer : public MCSymbolizer {
206private:
207 void *DisInfo;
208 std::vector<uint64_t> ReferencedAddresses;
209
210public:
211 AMDGPUSymbolizer(MCContext &Ctx, std::unique_ptr<MCRelocationInfo> &&RelInfo,
212 void *disInfo)
213 : MCSymbolizer(Ctx, std::move(RelInfo)), DisInfo(disInfo) {}
214
215 bool tryAddingSymbolicOperand(MCInst &Inst, raw_ostream &cStream,
216 int64_t Value, uint64_t Address, bool IsBranch,
217 uint64_t Offset, uint64_t OpSize,
218 uint64_t InstSize) override;
219
220 void tryAddingPcLoadReferenceComment(raw_ostream &cStream,
221 int64_t Value,
222 uint64_t Address) override;
223
224 ArrayRef<uint64_t> getReferencedAddresses() const override {
225 return ReferencedAddresses;
226 }
227};
228
229} // end namespace llvm
230
231#endif // LLVM_LIB_TARGET_AMDGPU_DISASSEMBLER_AMDGPUDISASSEMBLER_H
232