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