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 convertFMAanyK(MCInst &MI, int ImmLitIdx) const;
105   DecodeStatus convertSDWAInst(MCInst &MI) const;
106   DecodeStatus convertDPP8Inst(MCInst &MI) const;
107   DecodeStatus convertMIMGInst(MCInst &MI) const;
108 
109   MCOperand decodeOperand_VGPR_32(unsigned Val) const;
110   MCOperand decodeOperand_VRegOrLds_32(unsigned Val) const;
111 
112   MCOperand decodeOperand_VS_32(unsigned Val) const;
113   MCOperand decodeOperand_VS_64(unsigned Val) const;
114   MCOperand decodeOperand_VS_128(unsigned Val) const;
115   MCOperand decodeOperand_VSrc16(unsigned Val) const;
116   MCOperand decodeOperand_VSrcV216(unsigned Val) const;
117   MCOperand decodeOperand_VSrcV232(unsigned Val) const;
118 
119   MCOperand decodeOperand_VReg_64(unsigned Val) const;
120   MCOperand decodeOperand_VReg_96(unsigned Val) const;
121   MCOperand decodeOperand_VReg_128(unsigned Val) const;
122   MCOperand decodeOperand_VReg_256(unsigned Val) const;
123   MCOperand decodeOperand_VReg_512(unsigned Val) const;
124   MCOperand decodeOperand_VReg_1024(unsigned Val) const;
125 
126   MCOperand decodeOperand_SReg_32(unsigned Val) const;
127   MCOperand decodeOperand_SReg_32_XM0_XEXEC(unsigned Val) const;
128   MCOperand decodeOperand_SReg_32_XEXEC_HI(unsigned Val) const;
129   MCOperand decodeOperand_SRegOrLds_32(unsigned Val) const;
130   MCOperand decodeOperand_SReg_64(unsigned Val) const;
131   MCOperand decodeOperand_SReg_64_XEXEC(unsigned Val) const;
132   MCOperand decodeOperand_SReg_128(unsigned Val) const;
133   MCOperand decodeOperand_SReg_256(unsigned Val) const;
134   MCOperand decodeOperand_SReg_512(unsigned Val) const;
135 
136   MCOperand decodeOperand_AGPR_32(unsigned Val) const;
137   MCOperand decodeOperand_AReg_64(unsigned Val) const;
138   MCOperand decodeOperand_AReg_128(unsigned Val) const;
139   MCOperand decodeOperand_AReg_256(unsigned Val) const;
140   MCOperand decodeOperand_AReg_512(unsigned Val) const;
141   MCOperand decodeOperand_AReg_1024(unsigned Val) const;
142   MCOperand decodeOperand_AV_32(unsigned Val) const;
143   MCOperand decodeOperand_AV_64(unsigned Val) const;
144   MCOperand decodeOperand_AV_128(unsigned Val) const;
145   MCOperand decodeOperand_AV_512(unsigned Val) const;
146 
147   enum OpWidthTy {
148     OPW32,
149     OPW64,
150     OPW96,
151     OPW128,
152     OPW160,
153     OPW256,
154     OPW512,
155     OPW1024,
156     OPW16,
157     OPWV216,
158     OPWV232,
159     OPW_LAST_,
160     OPW_FIRST_ = OPW32
161   };
162 
163   unsigned getVgprClassId(const OpWidthTy Width) const;
164   unsigned getAgprClassId(const OpWidthTy Width) const;
165   unsigned getSgprClassId(const OpWidthTy Width) const;
166   unsigned getTtmpClassId(const OpWidthTy Width) const;
167 
168   static MCOperand decodeIntImmed(unsigned Imm);
169   static MCOperand decodeFPImmed(OpWidthTy Width, unsigned Imm);
170   MCOperand decodeMandatoryLiteralConstant(unsigned Imm) const;
171   MCOperand decodeLiteralConstant() const;
172 
173   MCOperand decodeSrcOp(const OpWidthTy Width, unsigned Val,
174                         bool MandatoryLiteral = false) const;
175   MCOperand decodeDstOp(const OpWidthTy Width, unsigned Val) const;
176   MCOperand decodeSpecialReg32(unsigned Val) const;
177   MCOperand decodeSpecialReg64(unsigned Val) const;
178 
179   MCOperand decodeSDWASrc(const OpWidthTy Width, unsigned Val) const;
180   MCOperand decodeSDWASrc16(unsigned Val) const;
181   MCOperand decodeSDWASrc32(unsigned Val) const;
182   MCOperand decodeSDWAVopcDst(unsigned Val) const;
183 
184   MCOperand decodeBoolReg(unsigned Val) const;
185 
186   int getTTmpIdx(unsigned Val) const;
187 
188   const MCInstrInfo *getMCII() const { return MCII.get(); }
189 
190   bool isVI() const;
191   bool isGFX9() const;
192   bool isGFX90A() const;
193   bool isGFX9Plus() const;
194   bool isGFX10() const;
195   bool isGFX10Plus() const;
196 
197   bool hasArchitectedFlatScratch() const;
198 };
199 
200 //===----------------------------------------------------------------------===//
201 // AMDGPUSymbolizer
202 //===----------------------------------------------------------------------===//
203 
204 class AMDGPUSymbolizer : public MCSymbolizer {
205 private:
206   void *DisInfo;
207   std::vector<uint64_t> ReferencedAddresses;
208 
209 public:
210   AMDGPUSymbolizer(MCContext &Ctx, std::unique_ptr<MCRelocationInfo> &&RelInfo,
211                    void *disInfo)
212                    : MCSymbolizer(Ctx, std::move(RelInfo)), DisInfo(disInfo) {}
213 
214   bool tryAddingSymbolicOperand(MCInst &Inst, raw_ostream &cStream,
215                                 int64_t Value, uint64_t Address,
216                                 bool IsBranch, uint64_t Offset,
217                                 uint64_t InstSize) override;
218 
219   void tryAddingPcLoadReferenceComment(raw_ostream &cStream,
220                                        int64_t Value,
221                                        uint64_t Address) override;
222 
223   ArrayRef<uint64_t> getReferencedAddresses() const override {
224     return ReferencedAddresses;
225   }
226 };
227 
228 } // end namespace llvm
229 
230 #endif // LLVM_LIB_TARGET_AMDGPU_DISASSEMBLER_AMDGPUDISASSEMBLER_H
231