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