xref: /freebsd/contrib/llvm-project/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h (revision e3f4a63af63bea70bc86b6c790b14aa5ee99fcd0)
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 
27 namespace llvm {
28 
29 class MCAsmInfo;
30 class MCInst;
31 class MCOperand;
32 class MCSubtargetInfo;
33 class Twine;
34 
35 // Exposes an interface expected by autogenerated code in
36 // FixedLenDecoderEmitter
37 class DecoderUInt128 {
38 private:
39   uint64_t Lo = 0;
40   uint64_t Hi = 0;
41 
42 public:
43   DecoderUInt128() = default;
44   DecoderUInt128(uint64_t Lo, uint64_t Hi = 0) : Lo(Lo), Hi(Hi) {}
45   operator bool() const { return Lo || Hi; }
46   uint64_t extractBitsAsZExtValue(unsigned NumBits,
47                                   unsigned BitPosition) const {
48     assert(NumBits && NumBits <= 64);
49     assert(BitPosition < 128);
50     uint64_t Val;
51     if (BitPosition < 64)
52       Val = Lo >> BitPosition | Hi << 1 << (63 - BitPosition);
53     else
54       Val = Hi >> (BitPosition - 64);
55     return Val & ((uint64_t(2) << (NumBits - 1)) - 1);
56   }
57   DecoderUInt128 operator&(const DecoderUInt128 &RHS) const {
58     return DecoderUInt128(Lo & RHS.Lo, Hi & RHS.Hi);
59   }
60   DecoderUInt128 operator&(const uint64_t &RHS) const {
61     return *this & DecoderUInt128(RHS);
62   }
63   DecoderUInt128 operator~() const { return DecoderUInt128(~Lo, ~Hi); }
64   bool operator==(const DecoderUInt128 &RHS) {
65     return Lo == RHS.Lo && Hi == RHS.Hi;
66   }
67   bool operator!=(const DecoderUInt128 &RHS) {
68     return Lo != RHS.Lo || Hi != RHS.Hi;
69   }
70   bool operator!=(const int &RHS) { return *this != DecoderUInt128(RHS); }
71 };
72 
73 //===----------------------------------------------------------------------===//
74 // AMDGPUDisassembler
75 //===----------------------------------------------------------------------===//
76 
77 class AMDGPUDisassembler : public MCDisassembler {
78 private:
79   std::unique_ptr<MCInstrInfo const> const MCII;
80   const MCRegisterInfo &MRI;
81   const MCAsmInfo &MAI;
82   const unsigned TargetMaxInstBytes;
83   mutable ArrayRef<uint8_t> Bytes;
84   mutable uint32_t Literal;
85   mutable uint64_t Literal64;
86   mutable bool HasLiteral;
87   mutable std::optional<bool> EnableWavefrontSize32;
88   unsigned CodeObjectVersion;
89   const MCExpr *UCVersionW64Expr;
90   const MCExpr *UCVersionW32Expr;
91   const MCExpr *UCVersionMDPExpr;
92 
93   const MCExpr *createConstantSymbolExpr(StringRef Id, int64_t Val);
94 
95   void decodeImmOperands(MCInst &MI, const MCInstrInfo &MCII) const;
96 
97 public:
98   AMDGPUDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
99                      MCInstrInfo const *MCII);
100   ~AMDGPUDisassembler() override = default;
101 
102   void setABIVersion(unsigned Version) override;
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   MCOperand createVGPR16Operand(unsigned RegIdx, bool IsHi) const;
114 
115   MCOperand errOperand(unsigned V, const Twine& ErrMsg) const;
116 
117   template <typename InsnType>
118   DecodeStatus tryDecodeInst(const uint8_t *Table, MCInst &MI, InsnType Inst,
119                              uint64_t Address, raw_ostream &Comments) const;
120   template <typename InsnType>
121   DecodeStatus tryDecodeInst(const uint8_t *Table1, const uint8_t *Table2,
122                              MCInst &MI, InsnType Inst, uint64_t Address,
123                              raw_ostream &Comments) const;
124 
125   Expected<bool> onSymbolStart(SymbolInfoTy &Symbol, uint64_t &Size,
126                                ArrayRef<uint8_t> Bytes,
127                                uint64_t Address) const override;
128 
129   Expected<bool> decodeKernelDescriptor(StringRef KdName,
130                                         ArrayRef<uint8_t> Bytes,
131                                         uint64_t KdAddress) const;
132 
133   Expected<bool>
134   decodeKernelDescriptorDirective(DataExtractor::Cursor &Cursor,
135                                   ArrayRef<uint8_t> Bytes,
136                                   raw_string_ostream &KdStream) const;
137 
138   /// Decode as directives that handle COMPUTE_PGM_RSRC1.
139   /// \param FourByteBuffer - Bytes holding contents of COMPUTE_PGM_RSRC1.
140   /// \param KdStream       - Stream to write the disassembled directives to.
141   // NOLINTNEXTLINE(readability-identifier-naming)
142   Expected<bool> decodeCOMPUTE_PGM_RSRC1(uint32_t FourByteBuffer,
143                                          raw_string_ostream &KdStream) const;
144 
145   /// Decode as directives that handle COMPUTE_PGM_RSRC2.
146   /// \param FourByteBuffer - Bytes holding contents of COMPUTE_PGM_RSRC2.
147   /// \param KdStream       - Stream to write the disassembled directives to.
148   // NOLINTNEXTLINE(readability-identifier-naming)
149   Expected<bool> decodeCOMPUTE_PGM_RSRC2(uint32_t FourByteBuffer,
150                                          raw_string_ostream &KdStream) const;
151 
152   /// Decode as directives that handle COMPUTE_PGM_RSRC3.
153   /// \param FourByteBuffer - Bytes holding contents of COMPUTE_PGM_RSRC3.
154   /// \param KdStream       - Stream to write the disassembled directives to.
155   // NOLINTNEXTLINE(readability-identifier-naming)
156   Expected<bool> decodeCOMPUTE_PGM_RSRC3(uint32_t FourByteBuffer,
157                                          raw_string_ostream &KdStream) const;
158 
159   void convertEXPInst(MCInst &MI) const;
160   void convertVINTERPInst(MCInst &MI) const;
161   void convertFMAanyK(MCInst &MI) const;
162   void convertSDWAInst(MCInst &MI) const;
163   void convertMAIInst(MCInst &MI) const;
164   void convertDPP8Inst(MCInst &MI) const;
165   void convertMIMGInst(MCInst &MI) const;
166   void convertVOP3DPPInst(MCInst &MI) const;
167   void convertVOP3PDPPInst(MCInst &MI) const;
168   void convertVOPCDPPInst(MCInst &MI) const;
169   void convertVOPC64DPPInst(MCInst &MI) const;
170   void convertMacDPPInst(MCInst &MI) const;
171   void convertTrue16OpSel(MCInst &MI) const;
172 
173   unsigned getVgprClassId(unsigned Width) const;
174   unsigned getAgprClassId(unsigned Width) const;
175   unsigned getSgprClassId(unsigned Width) const;
176   unsigned getTtmpClassId(unsigned Width) const;
177 
178   static MCOperand decodeIntImmed(unsigned Imm);
179 
180   MCOperand decodeMandatoryLiteralConstant(unsigned Imm) const;
181   MCOperand decodeMandatoryLiteral64Constant(uint64_t Imm) const;
182   MCOperand decodeLiteralConstant(bool ExtendFP64) const;
183   MCOperand decodeLiteral64Constant() const;
184 
185   MCOperand decodeSrcOp(unsigned Width, unsigned Val) const;
186 
187   MCOperand decodeNonVGPRSrcOp(unsigned Width, unsigned Val) const;
188 
189   MCOperand decodeVOPDDstYOp(MCInst &Inst, unsigned Val) const;
190   MCOperand decodeSpecialReg32(unsigned Val) const;
191   MCOperand decodeSpecialReg64(unsigned Val) const;
192   MCOperand decodeSpecialReg96Plus(unsigned Val) const;
193 
194   MCOperand decodeSDWASrc(unsigned Width, unsigned Val) const;
195   MCOperand decodeSDWASrc16(unsigned Val) const;
196   MCOperand decodeSDWASrc32(unsigned Val) const;
197   MCOperand decodeSDWAVopcDst(unsigned Val) const;
198 
199   MCOperand decodeBoolReg(unsigned Val) const;
200   MCOperand decodeSplitBarrier(unsigned Val) const;
201   MCOperand decodeDpp8FI(unsigned Val) const;
202 
203   MCOperand decodeVersionImm(unsigned Imm) const;
204 
205   int getTTmpIdx(unsigned Val) const;
206 
207   const MCInstrInfo *getMCII() const { return MCII.get(); }
208 
209   bool isVI() const;
210   bool isGFX9() const;
211   bool isGFX90A() const;
212   bool isGFX9Plus() const;
213   bool isGFX10() const;
214   bool isGFX10Plus() const;
215   bool isGFX11() const;
216   bool isGFX11Plus() const;
217   bool isGFX12() const;
218   bool isGFX12Plus() const;
219   bool isGFX1250() const;
220 
221   bool hasArchitectedFlatScratch() const;
222   bool hasKernargPreload() const;
223 
224   bool isMacDPP(MCInst &MI) const;
225 };
226 
227 //===----------------------------------------------------------------------===//
228 // AMDGPUSymbolizer
229 //===----------------------------------------------------------------------===//
230 
231 class AMDGPUSymbolizer : public MCSymbolizer {
232 private:
233   void *DisInfo;
234   std::vector<uint64_t> ReferencedAddresses;
235 
236 public:
237   AMDGPUSymbolizer(MCContext &Ctx, std::unique_ptr<MCRelocationInfo> &&RelInfo,
238                    void *disInfo)
239                    : MCSymbolizer(Ctx, std::move(RelInfo)), DisInfo(disInfo) {}
240 
241   bool tryAddingSymbolicOperand(MCInst &Inst, raw_ostream &cStream,
242                                 int64_t Value, uint64_t Address, bool IsBranch,
243                                 uint64_t Offset, uint64_t OpSize,
244                                 uint64_t InstSize) override;
245 
246   void tryAddingPcLoadReferenceComment(raw_ostream &cStream,
247                                        int64_t Value,
248                                        uint64_t Address) override;
249 
250   ArrayRef<uint64_t> getReferencedAddresses() const override {
251     return ReferencedAddresses;
252   }
253 };
254 
255 } // end namespace llvm
256 
257 #endif // LLVM_LIB_TARGET_AMDGPU_DISASSEMBLER_AMDGPUDISASSEMBLER_H
258