1c8fbf6ffSEugene Zelenko //===- AMDGPUDisassembler.hpp - Disassembler for AMDGPU ISA -----*- C++ -*-===//
2e1818af8STom Stellard //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e1818af8STom Stellard //
7e1818af8STom Stellard //===----------------------------------------------------------------------===//
8e1818af8STom Stellard //
9e1818af8STom Stellard /// \file
10e1818af8STom Stellard ///
11e1818af8STom Stellard /// This file contains declaration for AMDGPU ISA disassembler
12e1818af8STom Stellard //
13e1818af8STom Stellard //===----------------------------------------------------------------------===//
14e1818af8STom Stellard 
15e1818af8STom Stellard #ifndef LLVM_LIB_TARGET_AMDGPU_DISASSEMBLER_AMDGPUDISASSEMBLER_H
16e1818af8STom Stellard #define LLVM_LIB_TARGET_AMDGPU_DISASSEMBLER_AMDGPUDISASSEMBLER_H
17e1818af8STom Stellard 
18e243ead6SJoe Nash #include "llvm/ADT/APInt.h"
19e1818af8STom Stellard #include "llvm/MC/MCDisassembler/MCDisassembler.h"
20528057c1SRonak Chauhan #include "llvm/MC/MCInstrInfo.h"
21a0a406b2SJoe Nash #include "llvm/MC/MCInst.h"
22528057c1SRonak Chauhan #include "llvm/Support/DataExtractor.h"
232bc2f33bSEugene Zelenko #include <memory>
24e1818af8STom Stellard 
25e1818af8STom Stellard namespace llvm {
26e1818af8STom Stellard 
27e1818af8STom Stellard class MCInst;
28ac106addSNikolay Haustov class MCOperand;
29e1818af8STom Stellard class MCSubtargetInfo;
30ac106addSNikolay Haustov class Twine;
31e1818af8STom Stellard 
32e243ead6SJoe Nash // Exposes an interface expected by autogenerated code in
33e243ead6SJoe Nash // FixedLenDecoderEmitter
34e243ead6SJoe Nash class DecoderUInt128 {
35e243ead6SJoe Nash private:
36e243ead6SJoe Nash   uint64_t Lo = 0;
37e243ead6SJoe Nash   uint64_t Hi = 0;
38e243ead6SJoe Nash 
39e243ead6SJoe Nash public:
40e243ead6SJoe Nash   DecoderUInt128() = default;
Lo(Lo)41e243ead6SJoe Nash   DecoderUInt128(uint64_t Lo, uint64_t Hi = 0) : Lo(Lo), Hi(Hi) {}
42e243ead6SJoe Nash   operator bool() const { return Lo || Hi; }
insertBits(uint64_t SubBits,unsigned BitPosition,unsigned NumBits)43e243ead6SJoe Nash   void insertBits(uint64_t SubBits, unsigned BitPosition, unsigned NumBits) {
44e243ead6SJoe Nash     assert(NumBits && NumBits <= 64);
45e243ead6SJoe Nash     assert(SubBits >> 1 >> (NumBits - 1) == 0);
46e243ead6SJoe Nash     assert(BitPosition < 128);
47e243ead6SJoe Nash     if (BitPosition < 64) {
48e243ead6SJoe Nash       Lo |= SubBits << BitPosition;
49e243ead6SJoe Nash       Hi |= SubBits >> 1 >> (63 - BitPosition);
50e243ead6SJoe Nash     } else {
51e243ead6SJoe Nash       Hi |= SubBits << (BitPosition - 64);
52e243ead6SJoe Nash     }
53e243ead6SJoe Nash   }
extractBitsAsZExtValue(unsigned NumBits,unsigned BitPosition)54e243ead6SJoe Nash   uint64_t extractBitsAsZExtValue(unsigned NumBits,
55e243ead6SJoe Nash                                   unsigned BitPosition) const {
56e243ead6SJoe Nash     assert(NumBits && NumBits <= 64);
57e243ead6SJoe Nash     assert(BitPosition < 128);
58e243ead6SJoe Nash     uint64_t Val;
59e243ead6SJoe Nash     if (BitPosition < 64)
60e243ead6SJoe Nash       Val = Lo >> BitPosition | Hi << 1 << (63 - BitPosition);
61e243ead6SJoe Nash     else
62e243ead6SJoe Nash       Val = Hi >> (BitPosition - 64);
63e243ead6SJoe Nash     return Val & ((uint64_t(2) << (NumBits - 1)) - 1);
64e243ead6SJoe Nash   }
65e243ead6SJoe Nash   DecoderUInt128 operator&(const DecoderUInt128 &RHS) const {
66e243ead6SJoe Nash     return DecoderUInt128(Lo & RHS.Lo, Hi & RHS.Hi);
67e243ead6SJoe Nash   }
68e243ead6SJoe Nash   DecoderUInt128 operator&(const uint64_t &RHS) const {
69e243ead6SJoe Nash     return *this & DecoderUInt128(RHS);
70e243ead6SJoe Nash   }
71e243ead6SJoe Nash   DecoderUInt128 operator~() const { return DecoderUInt128(~Lo, ~Hi); }
72e243ead6SJoe Nash   bool operator==(const DecoderUInt128 &RHS) {
73e243ead6SJoe Nash     return Lo == RHS.Lo && Hi == RHS.Hi;
74e243ead6SJoe Nash   }
75e243ead6SJoe Nash   bool operator!=(const DecoderUInt128 &RHS) {
76e243ead6SJoe Nash     return Lo != RHS.Lo || Hi != RHS.Hi;
77e243ead6SJoe Nash   }
78e243ead6SJoe Nash   bool operator!=(const int &RHS) {
79e243ead6SJoe Nash     return *this != DecoderUInt128(RHS);
80e243ead6SJoe Nash   }
81e243ead6SJoe Nash   friend raw_ostream &operator<<(raw_ostream &OS, const DecoderUInt128 &RHS) {
82e243ead6SJoe Nash     return OS << APInt(128, {RHS.Lo, RHS.Hi});
83e243ead6SJoe Nash   }
84e243ead6SJoe Nash };
85e243ead6SJoe Nash 
863381d7a2SSam Kolton //===----------------------------------------------------------------------===//
873381d7a2SSam Kolton // AMDGPUDisassembler
883381d7a2SSam Kolton //===----------------------------------------------------------------------===//
893381d7a2SSam Kolton 
90e1818af8STom Stellard class AMDGPUDisassembler : public MCDisassembler {
91161a158eSNikolay Haustov private:
92cad7fa85SMatt Arsenault   std::unique_ptr<MCInstrInfo const> const MCII;
93cad7fa85SMatt Arsenault   const MCRegisterInfo &MRI;
94ca64ef20SMatt Arsenault   const unsigned TargetMaxInstBytes;
95161a158eSNikolay Haustov   mutable ArrayRef<uint8_t> Bytes;
96ce941c9cSDmitry Preobrazhensky   mutable uint32_t Literal;
97ce941c9cSDmitry Preobrazhensky   mutable bool HasLiteral;
98161a158eSNikolay Haustov 
99e1818af8STom Stellard public:
100cad7fa85SMatt Arsenault   AMDGPUDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
101ca64ef20SMatt Arsenault                      MCInstrInfo const *MCII);
1022bc2f33bSEugene Zelenko   ~AMDGPUDisassembler() override = default;
103e1818af8STom Stellard 
104e1818af8STom Stellard   DecodeStatus getInstruction(MCInst &MI, uint64_t &Size,
105e1818af8STom Stellard                               ArrayRef<uint8_t> Bytes, uint64_t Address,
1066fdd6a7bSFangrui Song                               raw_ostream &CS) const override;
107e1818af8STom Stellard 
108ac106addSNikolay Haustov   const char* getRegClassName(unsigned RegClassID) const;
109161a158eSNikolay Haustov 
110ac106addSNikolay Haustov   MCOperand createRegOperand(unsigned int RegId) const;
111ac106addSNikolay Haustov   MCOperand createRegOperand(unsigned RegClassID, unsigned Val) const;
112ac106addSNikolay Haustov   MCOperand createSRegOperand(unsigned SRegClassID, unsigned Val) const;
113161a158eSNikolay Haustov 
1142bc2f33bSEugene Zelenko   MCOperand errOperand(unsigned V, const Twine& ErrMsg) const;
115161a158eSNikolay Haustov 
116a0a406b2SJoe Nash   template <typename InsnType>
tryDecodeInst(const uint8_t * Table,MCInst & MI,InsnType Inst,uint64_t Address)117a0a406b2SJoe Nash   DecodeStatus tryDecodeInst(const uint8_t *Table, MCInst &MI, InsnType Inst,
118a0a406b2SJoe Nash                              uint64_t Address) const {
119a0a406b2SJoe Nash     assert(MI.getOpcode() == 0);
120a0a406b2SJoe Nash     assert(MI.getNumOperands() == 0);
121a0a406b2SJoe Nash     MCInst TmpInst;
122a0a406b2SJoe Nash     HasLiteral = false;
123a0a406b2SJoe Nash     const auto SavedBytes = Bytes;
124a0a406b2SJoe Nash     if (decodeInstruction(Table, TmpInst, Inst, Address, this, STI)) {
125a0a406b2SJoe Nash       MI = TmpInst;
126a0a406b2SJoe Nash       return MCDisassembler::Success;
127a0a406b2SJoe Nash     }
128a0a406b2SJoe Nash     Bytes = SavedBytes;
129a0a406b2SJoe Nash     return MCDisassembler::Fail;
130a0a406b2SJoe Nash   }
131e1818af8STom Stellard 
132528057c1SRonak Chauhan   Optional<DecodeStatus> onSymbolStart(SymbolInfoTy &Symbol, uint64_t &Size,
133528057c1SRonak Chauhan                                        ArrayRef<uint8_t> Bytes,
134528057c1SRonak Chauhan                                        uint64_t Address,
135528057c1SRonak Chauhan                                        raw_ostream &CStream) const override;
136528057c1SRonak Chauhan 
137528057c1SRonak Chauhan   DecodeStatus decodeKernelDescriptor(StringRef KdName, ArrayRef<uint8_t> Bytes,
138528057c1SRonak Chauhan                                       uint64_t KdAddress) const;
139528057c1SRonak Chauhan 
140528057c1SRonak Chauhan   DecodeStatus
141528057c1SRonak Chauhan   decodeKernelDescriptorDirective(DataExtractor::Cursor &Cursor,
142528057c1SRonak Chauhan                                   ArrayRef<uint8_t> Bytes,
143528057c1SRonak Chauhan                                   raw_string_ostream &KdStream) const;
144528057c1SRonak Chauhan 
145528057c1SRonak Chauhan   /// Decode as directives that handle COMPUTE_PGM_RSRC1.
146528057c1SRonak Chauhan   /// \param FourByteBuffer - Bytes holding contents of COMPUTE_PGM_RSRC1.
147528057c1SRonak Chauhan   /// \param KdStream       - Stream to write the disassembled directives to.
148528057c1SRonak Chauhan   // NOLINTNEXTLINE(readability-identifier-naming)
149528057c1SRonak Chauhan   DecodeStatus decodeCOMPUTE_PGM_RSRC1(uint32_t FourByteBuffer,
150528057c1SRonak Chauhan                                        raw_string_ostream &KdStream) const;
151528057c1SRonak Chauhan 
152528057c1SRonak Chauhan   /// Decode as directives that handle COMPUTE_PGM_RSRC2.
153528057c1SRonak Chauhan   /// \param FourByteBuffer - Bytes holding contents of COMPUTE_PGM_RSRC2.
154528057c1SRonak Chauhan   /// \param KdStream       - Stream to write the disassembled directives to.
155528057c1SRonak Chauhan   // NOLINTNEXTLINE(readability-identifier-naming)
156528057c1SRonak Chauhan   DecodeStatus decodeCOMPUTE_PGM_RSRC2(uint32_t FourByteBuffer,
157528057c1SRonak Chauhan                                        raw_string_ostream &KdStream) const;
158528057c1SRonak Chauhan 
1591a51ab76SJoe Nash   DecodeStatus convertEXPInst(MCInst &MI) const;
160ef1ea5acSJoe Nash   DecodeStatus convertVINTERPInst(MCInst &MI) const;
161b4b7e605SJoe Nash   DecodeStatus convertFMAanyK(MCInst &MI, int ImmLitIdx) const;
162549c89d2SSam Kolton   DecodeStatus convertSDWAInst(MCInst &MI) const;
163245b5ba3SStanislav Mekhanoshin   DecodeStatus convertDPP8Inst(MCInst &MI) const;
164cad7fa85SMatt Arsenault   DecodeStatus convertMIMGInst(MCInst &MI) const;
165*2a6532d5SDmitry Preobrazhensky   DecodeStatus convertVOP3DPPInst(MCInst &MI) const;
16640f35cefSJoe Nash   DecodeStatus convertVOP3PDPPInst(MCInst &MI) const;
167be1082c6SJoe Nash   DecodeStatus convertVOPCDPPInst(MCInst &MI) const;
168549c89d2SSam Kolton 
169ac106addSNikolay Haustov   MCOperand decodeOperand_VGPR_32(unsigned Val) const;
1706023d599SDmitry Preobrazhensky   MCOperand decodeOperand_VRegOrLds_32(unsigned Val) const;
1716023d599SDmitry Preobrazhensky 
172ac106addSNikolay Haustov   MCOperand decodeOperand_VS_32(unsigned Val) const;
173ac106addSNikolay Haustov   MCOperand decodeOperand_VS_64(unsigned Val) const;
17430fc5239SDmitry Preobrazhensky   MCOperand decodeOperand_VS_128(unsigned Val) const;
1754bd72361SMatt Arsenault   MCOperand decodeOperand_VSrc16(unsigned Val) const;
1769be7b0d4SMatt Arsenault   MCOperand decodeOperand_VSrcV216(unsigned Val) const;
177a8d9d507SStanislav Mekhanoshin   MCOperand decodeOperand_VSrcV232(unsigned Val) const;
178e1818af8STom Stellard 
179ac106addSNikolay Haustov   MCOperand decodeOperand_VReg_64(unsigned Val) const;
180ac106addSNikolay Haustov   MCOperand decodeOperand_VReg_96(unsigned Val) const;
181ac106addSNikolay Haustov   MCOperand decodeOperand_VReg_128(unsigned Val) const;
1829e77d0c6SStanislav Mekhanoshin   MCOperand decodeOperand_VReg_256(unsigned Val) const;
1839e77d0c6SStanislav Mekhanoshin   MCOperand decodeOperand_VReg_512(unsigned Val) const;
184a8d9d507SStanislav Mekhanoshin   MCOperand decodeOperand_VReg_1024(unsigned Val) const;
185161a158eSNikolay Haustov 
186ac106addSNikolay Haustov   MCOperand decodeOperand_SReg_32(unsigned Val) const;
187640c44b8SMatt Arsenault   MCOperand decodeOperand_SReg_32_XM0_XEXEC(unsigned Val) const;
188ca7b0a17SMatt Arsenault   MCOperand decodeOperand_SReg_32_XEXEC_HI(unsigned Val) const;
1896023d599SDmitry Preobrazhensky   MCOperand decodeOperand_SRegOrLds_32(unsigned Val) const;
190ac106addSNikolay Haustov   MCOperand decodeOperand_SReg_64(unsigned Val) const;
191640c44b8SMatt Arsenault   MCOperand decodeOperand_SReg_64_XEXEC(unsigned Val) const;
192ac106addSNikolay Haustov   MCOperand decodeOperand_SReg_128(unsigned Val) const;
193ac106addSNikolay Haustov   MCOperand decodeOperand_SReg_256(unsigned Val) const;
194ac106addSNikolay Haustov   MCOperand decodeOperand_SReg_512(unsigned Val) const;
195ac106addSNikolay Haustov 
1969e77d0c6SStanislav Mekhanoshin   MCOperand decodeOperand_AGPR_32(unsigned Val) const;
197a8d9d507SStanislav Mekhanoshin   MCOperand decodeOperand_AReg_64(unsigned Val) const;
1989e77d0c6SStanislav Mekhanoshin   MCOperand decodeOperand_AReg_128(unsigned Val) const;
199a8d9d507SStanislav Mekhanoshin   MCOperand decodeOperand_AReg_256(unsigned Val) const;
2009e77d0c6SStanislav Mekhanoshin   MCOperand decodeOperand_AReg_512(unsigned Val) const;
2019e77d0c6SStanislav Mekhanoshin   MCOperand decodeOperand_AReg_1024(unsigned Val) const;
2029e77d0c6SStanislav Mekhanoshin   MCOperand decodeOperand_AV_32(unsigned Val) const;
2039e77d0c6SStanislav Mekhanoshin   MCOperand decodeOperand_AV_64(unsigned Val) const;
2046e3e14f6SStanislav Mekhanoshin   MCOperand decodeOperand_AV_128(unsigned Val) const;
20532ca9bd7SDmitry Preobrazhensky   MCOperand decodeOperand_AVDst_128(unsigned Val) const;
20632ca9bd7SDmitry Preobrazhensky   MCOperand decodeOperand_AVDst_512(unsigned Val) const;
2079e77d0c6SStanislav Mekhanoshin 
208212a251cSArtem Tamazov   enum OpWidthTy {
209212a251cSArtem Tamazov     OPW32,
210212a251cSArtem Tamazov     OPW64,
211a8d9d507SStanislav Mekhanoshin     OPW96,
212212a251cSArtem Tamazov     OPW128,
213a8d9d507SStanislav Mekhanoshin     OPW160,
21427134953SDmitry Preobrazhensky     OPW256,
21527134953SDmitry Preobrazhensky     OPW512,
2169e77d0c6SStanislav Mekhanoshin     OPW1024,
2174bd72361SMatt Arsenault     OPW16,
2189be7b0d4SMatt Arsenault     OPWV216,
219a8d9d507SStanislav Mekhanoshin     OPWV232,
220212a251cSArtem Tamazov     OPW_LAST_,
221212a251cSArtem Tamazov     OPW_FIRST_ = OPW32
222212a251cSArtem Tamazov   };
2232bc2f33bSEugene Zelenko 
224212a251cSArtem Tamazov   unsigned getVgprClassId(const OpWidthTy Width) const;
2259e77d0c6SStanislav Mekhanoshin   unsigned getAgprClassId(const OpWidthTy Width) const;
226212a251cSArtem Tamazov   unsigned getSgprClassId(const OpWidthTy Width) const;
227212a251cSArtem Tamazov   unsigned getTtmpClassId(const OpWidthTy Width) const;
228ac106addSNikolay Haustov 
229ac106addSNikolay Haustov   static MCOperand decodeIntImmed(unsigned Imm);
2304bd72361SMatt Arsenault   static MCOperand decodeFPImmed(OpWidthTy Width, unsigned Imm);
231b4b7e605SJoe Nash   MCOperand decodeMandatoryLiteralConstant(unsigned Imm) const;
232ac106addSNikolay Haustov   MCOperand decodeLiteralConstant() const;
233ac106addSNikolay Haustov 
234b4b7e605SJoe Nash   MCOperand decodeSrcOp(const OpWidthTy Width, unsigned Val,
235b4b7e605SJoe Nash                         bool MandatoryLiteral = false) const;
23627134953SDmitry Preobrazhensky   MCOperand decodeDstOp(const OpWidthTy Width, unsigned Val) const;
23707b7fadaSJoe Nash   MCOperand decodeVOPDDstYOp(MCInst &Inst, unsigned Val) const;
238ac106addSNikolay Haustov   MCOperand decodeSpecialReg32(unsigned Val) const;
239ac106addSNikolay Haustov   MCOperand decodeSpecialReg64(unsigned Val) const;
240363f47a2SSam Kolton 
241549c89d2SSam Kolton   MCOperand decodeSDWASrc(const OpWidthTy Width, unsigned Val) const;
242549c89d2SSam Kolton   MCOperand decodeSDWASrc16(unsigned Val) const;
243549c89d2SSam Kolton   MCOperand decodeSDWASrc32(unsigned Val) const;
244549c89d2SSam Kolton   MCOperand decodeSDWAVopcDst(unsigned Val) const;
245ac2b0264SDmitry Preobrazhensky 
246ab4f2ea7SStanislav Mekhanoshin   MCOperand decodeBoolReg(unsigned Val) const;
247ab4f2ea7SStanislav Mekhanoshin 
248ac2b0264SDmitry Preobrazhensky   int getTTmpIdx(unsigned Val) const;
249ac2b0264SDmitry Preobrazhensky 
getMCII()250a8d9d507SStanislav Mekhanoshin   const MCInstrInfo *getMCII() const { return MCII.get(); }
251a8d9d507SStanislav Mekhanoshin 
252ac2b0264SDmitry Preobrazhensky   bool isVI() const;
253ac2b0264SDmitry Preobrazhensky   bool isGFX9() const;
254a8d9d507SStanislav Mekhanoshin   bool isGFX90A() const;
2554f87d30aSJay Foad   bool isGFX9Plus() const;
25633d806a5SStanislav Mekhanoshin   bool isGFX10() const;
2574f87d30aSJay Foad   bool isGFX10Plus() const;
258c7025940SJoe Nash   bool isGFX11() const;
259c7025940SJoe Nash   bool isGFX11Plus() const;
2606fb02596SStanislav Mekhanoshin 
2616fb02596SStanislav Mekhanoshin   bool hasArchitectedFlatScratch() const;
262e1818af8STom Stellard };
2633381d7a2SSam Kolton 
2643381d7a2SSam Kolton //===----------------------------------------------------------------------===//
2653381d7a2SSam Kolton // AMDGPUSymbolizer
2663381d7a2SSam Kolton //===----------------------------------------------------------------------===//
2673381d7a2SSam Kolton 
2683381d7a2SSam Kolton class AMDGPUSymbolizer : public MCSymbolizer {
2693381d7a2SSam Kolton private:
2703381d7a2SSam Kolton   void *DisInfo;
2718710eff6STim Renouf   std::vector<uint64_t> ReferencedAddresses;
2723381d7a2SSam Kolton 
2733381d7a2SSam Kolton public:
AMDGPUSymbolizer(MCContext & Ctx,std::unique_ptr<MCRelocationInfo> && RelInfo,void * disInfo)2743381d7a2SSam Kolton   AMDGPUSymbolizer(MCContext &Ctx, std::unique_ptr<MCRelocationInfo> &&RelInfo,
2753381d7a2SSam Kolton                    void *disInfo)
2763381d7a2SSam Kolton                    : MCSymbolizer(Ctx, std::move(RelInfo)), DisInfo(disInfo) {}
2773381d7a2SSam Kolton 
2783381d7a2SSam Kolton   bool tryAddingSymbolicOperand(MCInst &Inst, raw_ostream &cStream,
279bed9efedSMaksim Panchenko                                 int64_t Value, uint64_t Address, bool IsBranch,
280bed9efedSMaksim Panchenko                                 uint64_t Offset, uint64_t OpSize,
2813381d7a2SSam Kolton                                 uint64_t InstSize) override;
2823381d7a2SSam Kolton 
2833381d7a2SSam Kolton   void tryAddingPcLoadReferenceComment(raw_ostream &cStream,
2843381d7a2SSam Kolton                                        int64_t Value,
28592b355b1SMatt Arsenault                                        uint64_t Address) override;
2868710eff6STim Renouf 
getReferencedAddresses()2878710eff6STim Renouf   ArrayRef<uint64_t> getReferencedAddresses() const override {
2888710eff6STim Renouf     return ReferencedAddresses;
2898710eff6STim Renouf   }
2903381d7a2SSam Kolton };
2913381d7a2SSam Kolton 
2922bc2f33bSEugene Zelenko } // end namespace llvm
293e1818af8STom Stellard 
294e1818af8STom Stellard #endif // LLVM_LIB_TARGET_AMDGPU_DISASSEMBLER_AMDGPUDISASSEMBLER_H
295