xref: /freebsd/contrib/llvm-project/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h (revision 9f23cbd6cae82fd77edfad7173432fa8dccd0a95)
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 "llvm/ADT/APInt.h"
19 #include "llvm/MC/MCDisassembler/MCDisassembler.h"
20 #include "llvm/MC/MCInstrInfo.h"
21 #include "llvm/MC/MCInst.h"
22 #include "llvm/Support/DataExtractor.h"
23 #include <memory>
24 
25 namespace llvm {
26 
27 class MCInst;
28 class MCOperand;
29 class MCSubtargetInfo;
30 class Twine;
31 
32 // Exposes an interface expected by autogenerated code in
33 // FixedLenDecoderEmitter
34 class DecoderUInt128 {
35 private:
36   uint64_t Lo = 0;
37   uint64_t Hi = 0;
38 
39 public:
40   DecoderUInt128() = default;
41   DecoderUInt128(uint64_t Lo, uint64_t Hi = 0) : Lo(Lo), Hi(Hi) {}
42   operator bool() const { return Lo || Hi; }
43   void insertBits(uint64_t SubBits, unsigned BitPosition, unsigned NumBits) {
44     assert(NumBits && NumBits <= 64);
45     assert(SubBits >> 1 >> (NumBits - 1) == 0);
46     assert(BitPosition < 128);
47     if (BitPosition < 64) {
48       Lo |= SubBits << BitPosition;
49       Hi |= SubBits >> 1 >> (63 - BitPosition);
50     } else {
51       Hi |= SubBits << (BitPosition - 64);
52     }
53   }
54   uint64_t extractBitsAsZExtValue(unsigned NumBits,
55                                   unsigned BitPosition) const {
56     assert(NumBits && NumBits <= 64);
57     assert(BitPosition < 128);
58     uint64_t Val;
59     if (BitPosition < 64)
60       Val = Lo >> BitPosition | Hi << 1 << (63 - BitPosition);
61     else
62       Val = Hi >> (BitPosition - 64);
63     return Val & ((uint64_t(2) << (NumBits - 1)) - 1);
64   }
65   DecoderUInt128 operator&(const DecoderUInt128 &RHS) const {
66     return DecoderUInt128(Lo & RHS.Lo, Hi & RHS.Hi);
67   }
68   DecoderUInt128 operator&(const uint64_t &RHS) const {
69     return *this & DecoderUInt128(RHS);
70   }
71   DecoderUInt128 operator~() const { return DecoderUInt128(~Lo, ~Hi); }
72   bool operator==(const DecoderUInt128 &RHS) {
73     return Lo == RHS.Lo && Hi == RHS.Hi;
74   }
75   bool operator!=(const DecoderUInt128 &RHS) {
76     return Lo != RHS.Lo || Hi != RHS.Hi;
77   }
78   bool operator!=(const int &RHS) {
79     return *this != DecoderUInt128(RHS);
80   }
81   friend raw_ostream &operator<<(raw_ostream &OS, const DecoderUInt128 &RHS) {
82     return OS << APInt(128, {RHS.Lo, RHS.Hi});
83   }
84 };
85 
86 //===----------------------------------------------------------------------===//
87 // AMDGPUDisassembler
88 //===----------------------------------------------------------------------===//
89 
90 class AMDGPUDisassembler : public MCDisassembler {
91 private:
92   std::unique_ptr<MCInstrInfo const> const MCII;
93   const MCRegisterInfo &MRI;
94   const unsigned TargetMaxInstBytes;
95   mutable ArrayRef<uint8_t> Bytes;
96   mutable uint32_t Literal;
97   mutable bool HasLiteral;
98 
99 public:
100   AMDGPUDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
101                      MCInstrInfo const *MCII);
102   ~AMDGPUDisassembler() override = default;
103 
104   DecodeStatus getInstruction(MCInst &MI, uint64_t &Size,
105                               ArrayRef<uint8_t> Bytes, uint64_t Address,
106                               raw_ostream &CS) const override;
107 
108   const char* getRegClassName(unsigned RegClassID) const;
109 
110   MCOperand createRegOperand(unsigned int RegId) const;
111   MCOperand createRegOperand(unsigned RegClassID, unsigned Val) const;
112   MCOperand createSRegOperand(unsigned SRegClassID, unsigned Val) const;
113 
114   MCOperand errOperand(unsigned V, const Twine& ErrMsg) const;
115 
116   template <typename InsnType>
117   DecodeStatus tryDecodeInst(const uint8_t *Table, MCInst &MI, InsnType Inst,
118                              uint64_t Address) const {
119     assert(MI.getOpcode() == 0);
120     assert(MI.getNumOperands() == 0);
121     MCInst TmpInst;
122     HasLiteral = false;
123     const auto SavedBytes = Bytes;
124     if (decodeInstruction(Table, TmpInst, Inst, Address, this, STI)) {
125       MI = TmpInst;
126       return MCDisassembler::Success;
127     }
128     Bytes = SavedBytes;
129     return MCDisassembler::Fail;
130   }
131 
132   std::optional<DecodeStatus>
133   onSymbolStart(SymbolInfoTy &Symbol, uint64_t &Size, ArrayRef<uint8_t> Bytes,
134                 uint64_t Address, raw_ostream &CStream) const override;
135 
136   DecodeStatus decodeKernelDescriptor(StringRef KdName, ArrayRef<uint8_t> Bytes,
137                                       uint64_t KdAddress) const;
138 
139   DecodeStatus
140   decodeKernelDescriptorDirective(DataExtractor::Cursor &Cursor,
141                                   ArrayRef<uint8_t> Bytes,
142                                   raw_string_ostream &KdStream) const;
143 
144   /// Decode as directives that handle COMPUTE_PGM_RSRC1.
145   /// \param FourByteBuffer - Bytes holding contents of COMPUTE_PGM_RSRC1.
146   /// \param KdStream       - Stream to write the disassembled directives to.
147   // NOLINTNEXTLINE(readability-identifier-naming)
148   DecodeStatus decodeCOMPUTE_PGM_RSRC1(uint32_t FourByteBuffer,
149                                        raw_string_ostream &KdStream) const;
150 
151   /// Decode as directives that handle COMPUTE_PGM_RSRC2.
152   /// \param FourByteBuffer - Bytes holding contents of COMPUTE_PGM_RSRC2.
153   /// \param KdStream       - Stream to write the disassembled directives to.
154   // NOLINTNEXTLINE(readability-identifier-naming)
155   DecodeStatus decodeCOMPUTE_PGM_RSRC2(uint32_t FourByteBuffer,
156                                        raw_string_ostream &KdStream) const;
157 
158   DecodeStatus convertEXPInst(MCInst &MI) const;
159   DecodeStatus convertVINTERPInst(MCInst &MI) const;
160   DecodeStatus convertFMAanyK(MCInst &MI, int ImmLitIdx) const;
161   DecodeStatus convertSDWAInst(MCInst &MI) const;
162   DecodeStatus convertDPP8Inst(MCInst &MI) const;
163   DecodeStatus convertMIMGInst(MCInst &MI) const;
164   DecodeStatus convertVOP3DPPInst(MCInst &MI) const;
165   DecodeStatus convertVOP3PDPPInst(MCInst &MI) const;
166   DecodeStatus convertVOPCDPPInst(MCInst &MI) const;
167   void convertMacDPPInst(MCInst &MI) const;
168 
169   MCOperand decodeOperand_VGPR_32(unsigned Val) const;
170   MCOperand decodeOperand_VGPR_32_Lo128(unsigned Val) const;
171   MCOperand decodeOperand_VRegOrLds_32(unsigned Val) const;
172 
173   MCOperand decodeOperand_VS_32(unsigned Val) const;
174   MCOperand decodeOperand_VS_64(unsigned Val) const;
175   MCOperand decodeOperand_VS_128(unsigned Val) const;
176   MCOperand decodeOperand_VSrc16(unsigned Val) const;
177   MCOperand decodeOperand_VSrcV216(unsigned Val) const;
178   MCOperand decodeOperand_VSrcV232(unsigned Val) const;
179 
180   MCOperand decodeOperand_VReg_64(unsigned Val) const;
181   MCOperand decodeOperand_VReg_96(unsigned Val) const;
182   MCOperand decodeOperand_VReg_128(unsigned Val) const;
183   MCOperand decodeOperand_VReg_256(unsigned Val) const;
184   MCOperand decodeOperand_VReg_288(unsigned Val) const;
185   MCOperand decodeOperand_VReg_320(unsigned Val) const;
186   MCOperand decodeOperand_VReg_352(unsigned Val) const;
187   MCOperand decodeOperand_VReg_384(unsigned Val) const;
188   MCOperand decodeOperand_VReg_512(unsigned Val) const;
189   MCOperand decodeOperand_VReg_1024(unsigned Val) const;
190 
191   MCOperand decodeOperand_SReg_32(unsigned Val) const;
192   MCOperand decodeOperand_SReg_32_XM0_XEXEC(unsigned Val) const;
193   MCOperand decodeOperand_SReg_32_XEXEC_HI(unsigned Val) const;
194   MCOperand decodeOperand_SRegOrLds_32(unsigned Val) const;
195   MCOperand decodeOperand_SReg_64(unsigned Val) const;
196   MCOperand decodeOperand_SReg_64_XEXEC(unsigned Val) const;
197   MCOperand decodeOperand_SReg_128(unsigned Val) const;
198   MCOperand decodeOperand_SReg_256(unsigned Val) const;
199   MCOperand decodeOperand_SReg_288(unsigned Val) const;
200   MCOperand decodeOperand_SReg_320(unsigned Val) const;
201   MCOperand decodeOperand_SReg_352(unsigned Val) const;
202   MCOperand decodeOperand_SReg_384(unsigned Val) const;
203   MCOperand decodeOperand_SReg_512(unsigned Val) const;
204 
205   MCOperand decodeOperand_AGPR_32(unsigned Val) const;
206   MCOperand decodeOperand_AReg_64(unsigned Val) const;
207   MCOperand decodeOperand_AReg_128(unsigned Val) const;
208   MCOperand decodeOperand_AReg_256(unsigned Val) const;
209   MCOperand decodeOperand_AReg_288(unsigned Val) const;
210   MCOperand decodeOperand_AReg_320(unsigned Val) const;
211   MCOperand decodeOperand_AReg_352(unsigned Val) const;
212   MCOperand decodeOperand_AReg_384(unsigned Val) const;
213   MCOperand decodeOperand_AReg_512(unsigned Val) const;
214   MCOperand decodeOperand_AReg_1024(unsigned Val) const;
215   MCOperand decodeOperand_AV_32(unsigned Val) const;
216   MCOperand decodeOperand_AV_64(unsigned Val) const;
217   MCOperand decodeOperand_AV_128(unsigned Val) const;
218   MCOperand decodeOperand_AVDst_128(unsigned Val) const;
219   MCOperand decodeOperand_AVDst_512(unsigned Val) const;
220 
221   enum OpWidthTy {
222     OPW32,
223     OPW64,
224     OPW96,
225     OPW128,
226     OPW160,
227     OPW256,
228     OPW288,
229     OPW320,
230     OPW352,
231     OPW384,
232     OPW512,
233     OPW1024,
234     OPW16,
235     OPWV216,
236     OPWV232,
237     OPW_LAST_,
238     OPW_FIRST_ = OPW32
239   };
240 
241   unsigned getVgprClassId(const OpWidthTy Width) const;
242   unsigned getAgprClassId(const OpWidthTy Width) const;
243   unsigned getSgprClassId(const OpWidthTy Width) const;
244   unsigned getTtmpClassId(const OpWidthTy Width) const;
245 
246   static MCOperand decodeIntImmed(unsigned Imm);
247   static MCOperand decodeFPImmed(OpWidthTy Width, unsigned Imm);
248   MCOperand decodeMandatoryLiteralConstant(unsigned Imm) const;
249   MCOperand decodeLiteralConstant() const;
250 
251   MCOperand decodeSrcOp(const OpWidthTy Width, unsigned Val,
252                         bool MandatoryLiteral = false) const;
253   MCOperand decodeDstOp(const OpWidthTy Width, unsigned Val) const;
254   MCOperand decodeVOPDDstYOp(MCInst &Inst, unsigned Val) const;
255   MCOperand decodeSpecialReg32(unsigned Val) const;
256   MCOperand decodeSpecialReg64(unsigned Val) const;
257 
258   MCOperand decodeSDWASrc(const OpWidthTy Width, unsigned Val) const;
259   MCOperand decodeSDWASrc16(unsigned Val) const;
260   MCOperand decodeSDWASrc32(unsigned Val) const;
261   MCOperand decodeSDWAVopcDst(unsigned Val) const;
262 
263   MCOperand decodeBoolReg(unsigned Val) const;
264 
265   int getTTmpIdx(unsigned Val) const;
266 
267   const MCInstrInfo *getMCII() const { return MCII.get(); }
268 
269   bool isVI() const;
270   bool isGFX9() const;
271   bool isGFX90A() const;
272   bool isGFX9Plus() const;
273   bool isGFX10() const;
274   bool isGFX10Plus() const;
275   bool isGFX11() const;
276   bool isGFX11Plus() const;
277 
278   bool hasArchitectedFlatScratch() const;
279 
280   bool isMacDPP(MCInst &MI) const;
281 };
282 
283 //===----------------------------------------------------------------------===//
284 // AMDGPUSymbolizer
285 //===----------------------------------------------------------------------===//
286 
287 class AMDGPUSymbolizer : public MCSymbolizer {
288 private:
289   void *DisInfo;
290   std::vector<uint64_t> ReferencedAddresses;
291 
292 public:
293   AMDGPUSymbolizer(MCContext &Ctx, std::unique_ptr<MCRelocationInfo> &&RelInfo,
294                    void *disInfo)
295                    : MCSymbolizer(Ctx, std::move(RelInfo)), DisInfo(disInfo) {}
296 
297   bool tryAddingSymbolicOperand(MCInst &Inst, raw_ostream &cStream,
298                                 int64_t Value, uint64_t Address, bool IsBranch,
299                                 uint64_t Offset, uint64_t OpSize,
300                                 uint64_t InstSize) override;
301 
302   void tryAddingPcLoadReferenceComment(raw_ostream &cStream,
303                                        int64_t Value,
304                                        uint64_t Address) override;
305 
306   ArrayRef<uint64_t> getReferencedAddresses() const override {
307     return ReferencedAddresses;
308   }
309 };
310 
311 } // end namespace llvm
312 
313 #endif // LLVM_LIB_TARGET_AMDGPU_DISASSEMBLER_AMDGPUDISASSEMBLER_H
314