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