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/MC/MCDisassembler/MCDisassembler.h"
19 #include "llvm/MC/MCInstrInfo.h"
20 #include "llvm/MC/MCInst.h"
21 #include "llvm/Support/DataExtractor.h"
22 #include <memory>
23 
24 namespace llvm {
25 
26 class MCInst;
27 class MCOperand;
28 class MCSubtargetInfo;
29 class Twine;
30 
31 //===----------------------------------------------------------------------===//
32 // AMDGPUDisassembler
33 //===----------------------------------------------------------------------===//
34 
35 class AMDGPUDisassembler : public MCDisassembler {
36 private:
37   std::unique_ptr<MCInstrInfo const> const MCII;
38   const MCRegisterInfo &MRI;
39   const unsigned TargetMaxInstBytes;
40   mutable ArrayRef<uint8_t> Bytes;
41   mutable uint32_t Literal;
42   mutable bool HasLiteral;
43 
44 public:
45   AMDGPUDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
46                      MCInstrInfo const *MCII);
47   ~AMDGPUDisassembler() override = default;
48 
49   DecodeStatus getInstruction(MCInst &MI, uint64_t &Size,
50                               ArrayRef<uint8_t> Bytes, uint64_t Address,
51                               raw_ostream &CS) const override;
52 
53   const char* getRegClassName(unsigned RegClassID) const;
54 
55   MCOperand createRegOperand(unsigned int RegId) const;
56   MCOperand createRegOperand(unsigned RegClassID, unsigned Val) const;
57   MCOperand createSRegOperand(unsigned SRegClassID, unsigned Val) const;
58 
59   MCOperand errOperand(unsigned V, const Twine& ErrMsg) const;
60 
61   template <typename InsnType>
62   DecodeStatus tryDecodeInst(const uint8_t *Table, MCInst &MI, InsnType Inst,
63                              uint64_t Address) const {
64     assert(MI.getOpcode() == 0);
65     assert(MI.getNumOperands() == 0);
66     MCInst TmpInst;
67     HasLiteral = false;
68     const auto SavedBytes = Bytes;
69     if (decodeInstruction(Table, TmpInst, Inst, Address, this, STI)) {
70       MI = TmpInst;
71       return MCDisassembler::Success;
72     }
73     Bytes = SavedBytes;
74     return MCDisassembler::Fail;
75   }
76 
77   Optional<DecodeStatus> onSymbolStart(SymbolInfoTy &Symbol, uint64_t &Size,
78                                        ArrayRef<uint8_t> Bytes,
79                                        uint64_t Address,
80                                        raw_ostream &CStream) const override;
81 
82   DecodeStatus decodeKernelDescriptor(StringRef KdName, ArrayRef<uint8_t> Bytes,
83                                       uint64_t KdAddress) const;
84 
85   DecodeStatus
86   decodeKernelDescriptorDirective(DataExtractor::Cursor &Cursor,
87                                   ArrayRef<uint8_t> Bytes,
88                                   raw_string_ostream &KdStream) const;
89 
90   /// Decode as directives that handle COMPUTE_PGM_RSRC1.
91   /// \param FourByteBuffer - Bytes holding contents of COMPUTE_PGM_RSRC1.
92   /// \param KdStream       - Stream to write the disassembled directives to.
93   // NOLINTNEXTLINE(readability-identifier-naming)
94   DecodeStatus decodeCOMPUTE_PGM_RSRC1(uint32_t FourByteBuffer,
95                                        raw_string_ostream &KdStream) const;
96 
97   /// Decode as directives that handle COMPUTE_PGM_RSRC2.
98   /// \param FourByteBuffer - Bytes holding contents of COMPUTE_PGM_RSRC2.
99   /// \param KdStream       - Stream to write the disassembled directives to.
100   // NOLINTNEXTLINE(readability-identifier-naming)
101   DecodeStatus decodeCOMPUTE_PGM_RSRC2(uint32_t FourByteBuffer,
102                                        raw_string_ostream &KdStream) const;
103 
104   DecodeStatus convertEXPInst(MCInst &MI) const;
105   DecodeStatus convertVINTERPInst(MCInst &MI) const;
106   DecodeStatus convertFMAanyK(MCInst &MI, int ImmLitIdx) const;
107   DecodeStatus convertSDWAInst(MCInst &MI) const;
108   DecodeStatus convertDPP8Inst(MCInst &MI) const;
109   DecodeStatus convertMIMGInst(MCInst &MI) const;
110 
111   MCOperand decodeOperand_VGPR_32(unsigned Val) const;
112   MCOperand decodeOperand_VRegOrLds_32(unsigned Val) const;
113 
114   MCOperand decodeOperand_VS_32(unsigned Val) const;
115   MCOperand decodeOperand_VS_64(unsigned Val) const;
116   MCOperand decodeOperand_VS_128(unsigned Val) const;
117   MCOperand decodeOperand_VSrc16(unsigned Val) const;
118   MCOperand decodeOperand_VSrcV216(unsigned Val) const;
119   MCOperand decodeOperand_VSrcV232(unsigned Val) const;
120 
121   MCOperand decodeOperand_VReg_64(unsigned Val) const;
122   MCOperand decodeOperand_VReg_96(unsigned Val) const;
123   MCOperand decodeOperand_VReg_128(unsigned Val) const;
124   MCOperand decodeOperand_VReg_256(unsigned Val) const;
125   MCOperand decodeOperand_VReg_512(unsigned Val) const;
126   MCOperand decodeOperand_VReg_1024(unsigned Val) const;
127 
128   MCOperand decodeOperand_SReg_32(unsigned Val) const;
129   MCOperand decodeOperand_SReg_32_XM0_XEXEC(unsigned Val) const;
130   MCOperand decodeOperand_SReg_32_XEXEC_HI(unsigned Val) const;
131   MCOperand decodeOperand_SRegOrLds_32(unsigned Val) const;
132   MCOperand decodeOperand_SReg_64(unsigned Val) const;
133   MCOperand decodeOperand_SReg_64_XEXEC(unsigned Val) const;
134   MCOperand decodeOperand_SReg_128(unsigned Val) const;
135   MCOperand decodeOperand_SReg_256(unsigned Val) const;
136   MCOperand decodeOperand_SReg_512(unsigned Val) const;
137 
138   MCOperand decodeOperand_AGPR_32(unsigned Val) const;
139   MCOperand decodeOperand_AReg_64(unsigned Val) const;
140   MCOperand decodeOperand_AReg_128(unsigned Val) const;
141   MCOperand decodeOperand_AReg_256(unsigned Val) const;
142   MCOperand decodeOperand_AReg_512(unsigned Val) const;
143   MCOperand decodeOperand_AReg_1024(unsigned Val) const;
144   MCOperand decodeOperand_AV_32(unsigned Val) const;
145   MCOperand decodeOperand_AV_64(unsigned Val) const;
146   MCOperand decodeOperand_AV_128(unsigned Val) const;
147   MCOperand decodeOperand_AVDst_128(unsigned Val) const;
148   MCOperand decodeOperand_AVDst_512(unsigned Val) const;
149 
150   enum OpWidthTy {
151     OPW32,
152     OPW64,
153     OPW96,
154     OPW128,
155     OPW160,
156     OPW256,
157     OPW512,
158     OPW1024,
159     OPW16,
160     OPWV216,
161     OPWV232,
162     OPW_LAST_,
163     OPW_FIRST_ = OPW32
164   };
165 
166   unsigned getVgprClassId(const OpWidthTy Width) const;
167   unsigned getAgprClassId(const OpWidthTy Width) const;
168   unsigned getSgprClassId(const OpWidthTy Width) const;
169   unsigned getTtmpClassId(const OpWidthTy Width) const;
170 
171   static MCOperand decodeIntImmed(unsigned Imm);
172   static MCOperand decodeFPImmed(OpWidthTy Width, unsigned Imm);
173   MCOperand decodeMandatoryLiteralConstant(unsigned Imm) const;
174   MCOperand decodeLiteralConstant() const;
175 
176   MCOperand decodeSrcOp(const OpWidthTy Width, unsigned Val,
177                         bool MandatoryLiteral = false) const;
178   MCOperand decodeDstOp(const OpWidthTy Width, unsigned Val) const;
179   MCOperand decodeSpecialReg32(unsigned Val) const;
180   MCOperand decodeSpecialReg64(unsigned Val) const;
181 
182   MCOperand decodeSDWASrc(const OpWidthTy Width, unsigned Val) const;
183   MCOperand decodeSDWASrc16(unsigned Val) const;
184   MCOperand decodeSDWASrc32(unsigned Val) const;
185   MCOperand decodeSDWAVopcDst(unsigned Val) const;
186 
187   MCOperand decodeBoolReg(unsigned Val) const;
188 
189   int getTTmpIdx(unsigned Val) const;
190 
191   const MCInstrInfo *getMCII() const { return MCII.get(); }
192 
193   bool isVI() const;
194   bool isGFX9() const;
195   bool isGFX90A() const;
196   bool isGFX9Plus() const;
197   bool isGFX10() const;
198   bool isGFX10Plus() const;
199   bool isGFX11() const;
200   bool isGFX11Plus() const;
201 
202   bool hasArchitectedFlatScratch() const;
203 };
204 
205 //===----------------------------------------------------------------------===//
206 // AMDGPUSymbolizer
207 //===----------------------------------------------------------------------===//
208 
209 class AMDGPUSymbolizer : public MCSymbolizer {
210 private:
211   void *DisInfo;
212   std::vector<uint64_t> ReferencedAddresses;
213 
214 public:
215   AMDGPUSymbolizer(MCContext &Ctx, std::unique_ptr<MCRelocationInfo> &&RelInfo,
216                    void *disInfo)
217                    : MCSymbolizer(Ctx, std::move(RelInfo)), DisInfo(disInfo) {}
218 
219   bool tryAddingSymbolicOperand(MCInst &Inst, raw_ostream &cStream,
220                                 int64_t Value, uint64_t Address, bool IsBranch,
221                                 uint64_t Offset, uint64_t OpSize,
222                                 uint64_t InstSize) override;
223 
224   void tryAddingPcLoadReferenceComment(raw_ostream &cStream,
225                                        int64_t Value,
226                                        uint64_t Address) override;
227 
228   ArrayRef<uint64_t> getReferencedAddresses() const override {
229     return ReferencedAddresses;
230   }
231 };
232 
233 } // end namespace llvm
234 
235 #endif // LLVM_LIB_TARGET_AMDGPU_DISASSEMBLER_AMDGPUDISASSEMBLER_H
236