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/ADT/APInt.h" 19 #include "llvm/MC/MCDisassembler/MCDisassembler.h" 20 #include "llvm/MC/MCInstrInfo.h" 21 #include "llvm/MC/MCInst.h" 22 #include "llvm/Support/DataExtractor.h" 23 #include <memory> 24 25 namespace llvm { 26 27 class MCInst; 28 class MCOperand; 29 class MCSubtargetInfo; 30 class Twine; 31 32 // Exposes an interface expected by autogenerated code in 33 // FixedLenDecoderEmitter 34 class DecoderUInt128 { 35 private: 36 uint64_t Lo = 0; 37 uint64_t Hi = 0; 38 39 public: 40 DecoderUInt128() = default; 41 DecoderUInt128(uint64_t Lo, uint64_t Hi = 0) : Lo(Lo), Hi(Hi) {} 42 operator bool() const { return Lo || Hi; } 43 void insertBits(uint64_t SubBits, unsigned BitPosition, unsigned NumBits) { 44 assert(NumBits && NumBits <= 64); 45 assert(SubBits >> 1 >> (NumBits - 1) == 0); 46 assert(BitPosition < 128); 47 if (BitPosition < 64) { 48 Lo |= SubBits << BitPosition; 49 Hi |= SubBits >> 1 >> (63 - BitPosition); 50 } else { 51 Hi |= SubBits << (BitPosition - 64); 52 } 53 } 54 uint64_t extractBitsAsZExtValue(unsigned NumBits, 55 unsigned BitPosition) const { 56 assert(NumBits && NumBits <= 64); 57 assert(BitPosition < 128); 58 uint64_t Val; 59 if (BitPosition < 64) 60 Val = Lo >> BitPosition | Hi << 1 << (63 - BitPosition); 61 else 62 Val = Hi >> (BitPosition - 64); 63 return Val & ((uint64_t(2) << (NumBits - 1)) - 1); 64 } 65 DecoderUInt128 operator&(const DecoderUInt128 &RHS) const { 66 return DecoderUInt128(Lo & RHS.Lo, Hi & RHS.Hi); 67 } 68 DecoderUInt128 operator&(const uint64_t &RHS) const { 69 return *this & DecoderUInt128(RHS); 70 } 71 DecoderUInt128 operator~() const { return DecoderUInt128(~Lo, ~Hi); } 72 bool operator==(const DecoderUInt128 &RHS) { 73 return Lo == RHS.Lo && Hi == RHS.Hi; 74 } 75 bool operator!=(const DecoderUInt128 &RHS) { 76 return Lo != RHS.Lo || Hi != RHS.Hi; 77 } 78 bool operator!=(const int &RHS) { 79 return *this != DecoderUInt128(RHS); 80 } 81 friend raw_ostream &operator<<(raw_ostream &OS, const DecoderUInt128 &RHS) { 82 return OS << APInt(128, {RHS.Lo, RHS.Hi}); 83 } 84 }; 85 86 //===----------------------------------------------------------------------===// 87 // AMDGPUDisassembler 88 //===----------------------------------------------------------------------===// 89 90 class AMDGPUDisassembler : public MCDisassembler { 91 private: 92 std::unique_ptr<MCInstrInfo const> const MCII; 93 const MCRegisterInfo &MRI; 94 const unsigned TargetMaxInstBytes; 95 mutable ArrayRef<uint8_t> Bytes; 96 mutable uint32_t Literal; 97 mutable bool HasLiteral; 98 99 public: 100 AMDGPUDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, 101 MCInstrInfo const *MCII); 102 ~AMDGPUDisassembler() override = default; 103 104 DecodeStatus getInstruction(MCInst &MI, uint64_t &Size, 105 ArrayRef<uint8_t> Bytes, uint64_t Address, 106 raw_ostream &CS) const override; 107 108 const char* getRegClassName(unsigned RegClassID) const; 109 110 MCOperand createRegOperand(unsigned int RegId) const; 111 MCOperand createRegOperand(unsigned RegClassID, unsigned Val) const; 112 MCOperand createSRegOperand(unsigned SRegClassID, unsigned Val) const; 113 114 MCOperand errOperand(unsigned V, const Twine& ErrMsg) const; 115 116 template <typename InsnType> 117 DecodeStatus tryDecodeInst(const uint8_t *Table, MCInst &MI, InsnType Inst, 118 uint64_t Address) const { 119 assert(MI.getOpcode() == 0); 120 assert(MI.getNumOperands() == 0); 121 MCInst TmpInst; 122 HasLiteral = false; 123 const auto SavedBytes = Bytes; 124 if (decodeInstruction(Table, TmpInst, Inst, Address, this, STI)) { 125 MI = TmpInst; 126 return MCDisassembler::Success; 127 } 128 Bytes = SavedBytes; 129 return MCDisassembler::Fail; 130 } 131 132 std::optional<DecodeStatus> 133 onSymbolStart(SymbolInfoTy &Symbol, uint64_t &Size, ArrayRef<uint8_t> Bytes, 134 uint64_t Address, raw_ostream &CStream) const override; 135 136 DecodeStatus decodeKernelDescriptor(StringRef KdName, ArrayRef<uint8_t> Bytes, 137 uint64_t KdAddress) const; 138 139 DecodeStatus 140 decodeKernelDescriptorDirective(DataExtractor::Cursor &Cursor, 141 ArrayRef<uint8_t> Bytes, 142 raw_string_ostream &KdStream) const; 143 144 /// Decode as directives that handle COMPUTE_PGM_RSRC1. 145 /// \param FourByteBuffer - Bytes holding contents of COMPUTE_PGM_RSRC1. 146 /// \param KdStream - Stream to write the disassembled directives to. 147 // NOLINTNEXTLINE(readability-identifier-naming) 148 DecodeStatus decodeCOMPUTE_PGM_RSRC1(uint32_t FourByteBuffer, 149 raw_string_ostream &KdStream) const; 150 151 /// Decode as directives that handle COMPUTE_PGM_RSRC2. 152 /// \param FourByteBuffer - Bytes holding contents of COMPUTE_PGM_RSRC2. 153 /// \param KdStream - Stream to write the disassembled directives to. 154 // NOLINTNEXTLINE(readability-identifier-naming) 155 DecodeStatus decodeCOMPUTE_PGM_RSRC2(uint32_t FourByteBuffer, 156 raw_string_ostream &KdStream) const; 157 158 DecodeStatus convertEXPInst(MCInst &MI) const; 159 DecodeStatus convertVINTERPInst(MCInst &MI) const; 160 DecodeStatus convertFMAanyK(MCInst &MI, int ImmLitIdx) const; 161 DecodeStatus convertSDWAInst(MCInst &MI) const; 162 DecodeStatus convertDPP8Inst(MCInst &MI) const; 163 DecodeStatus convertMIMGInst(MCInst &MI) const; 164 DecodeStatus convertVOP3DPPInst(MCInst &MI) const; 165 DecodeStatus convertVOP3PDPPInst(MCInst &MI) const; 166 DecodeStatus convertVOPCDPPInst(MCInst &MI) const; 167 void convertMacDPPInst(MCInst &MI) const; 168 169 MCOperand decodeOperand_VGPR_32(unsigned Val) const; 170 MCOperand decodeOperand_VGPR_32_Lo128(unsigned Val) const; 171 MCOperand decodeOperand_VRegOrLds_32(unsigned Val) const; 172 173 MCOperand decodeOperand_VS_32(unsigned Val) const; 174 MCOperand decodeOperand_VS_64(unsigned Val) const; 175 MCOperand decodeOperand_VS_128(unsigned Val) const; 176 MCOperand decodeOperand_VSrc16(unsigned Val) const; 177 MCOperand decodeOperand_VSrcV216(unsigned Val) const; 178 MCOperand decodeOperand_VSrcV232(unsigned Val) const; 179 180 MCOperand decodeOperand_VReg_64(unsigned Val) const; 181 MCOperand decodeOperand_VReg_96(unsigned Val) const; 182 MCOperand decodeOperand_VReg_128(unsigned Val) const; 183 MCOperand decodeOperand_VReg_256(unsigned Val) const; 184 MCOperand decodeOperand_VReg_288(unsigned Val) const; 185 MCOperand decodeOperand_VReg_320(unsigned Val) const; 186 MCOperand decodeOperand_VReg_352(unsigned Val) const; 187 MCOperand decodeOperand_VReg_384(unsigned Val) const; 188 MCOperand decodeOperand_VReg_512(unsigned Val) const; 189 MCOperand decodeOperand_VReg_1024(unsigned Val) const; 190 191 MCOperand decodeOperand_SReg_32(unsigned Val) const; 192 MCOperand decodeOperand_SReg_32_XM0_XEXEC(unsigned Val) const; 193 MCOperand decodeOperand_SReg_32_XEXEC_HI(unsigned Val) const; 194 MCOperand decodeOperand_SRegOrLds_32(unsigned Val) const; 195 MCOperand decodeOperand_SReg_64(unsigned Val) const; 196 MCOperand decodeOperand_SReg_64_XEXEC(unsigned Val) const; 197 MCOperand decodeOperand_SReg_128(unsigned Val) const; 198 MCOperand decodeOperand_SReg_256(unsigned Val) const; 199 MCOperand decodeOperand_SReg_288(unsigned Val) const; 200 MCOperand decodeOperand_SReg_320(unsigned Val) const; 201 MCOperand decodeOperand_SReg_352(unsigned Val) const; 202 MCOperand decodeOperand_SReg_384(unsigned Val) const; 203 MCOperand decodeOperand_SReg_512(unsigned Val) const; 204 205 MCOperand decodeOperand_AGPR_32(unsigned Val) const; 206 MCOperand decodeOperand_AReg_64(unsigned Val) const; 207 MCOperand decodeOperand_AReg_128(unsigned Val) const; 208 MCOperand decodeOperand_AReg_256(unsigned Val) const; 209 MCOperand decodeOperand_AReg_288(unsigned Val) const; 210 MCOperand decodeOperand_AReg_320(unsigned Val) const; 211 MCOperand decodeOperand_AReg_352(unsigned Val) const; 212 MCOperand decodeOperand_AReg_384(unsigned Val) const; 213 MCOperand decodeOperand_AReg_512(unsigned Val) const; 214 MCOperand decodeOperand_AReg_1024(unsigned Val) const; 215 MCOperand decodeOperand_AV_32(unsigned Val) const; 216 MCOperand decodeOperand_AV_64(unsigned Val) const; 217 MCOperand decodeOperand_AV_128(unsigned Val) const; 218 MCOperand decodeOperand_AVDst_128(unsigned Val) const; 219 MCOperand decodeOperand_AVDst_512(unsigned Val) const; 220 221 enum OpWidthTy { 222 OPW32, 223 OPW64, 224 OPW96, 225 OPW128, 226 OPW160, 227 OPW256, 228 OPW288, 229 OPW320, 230 OPW352, 231 OPW384, 232 OPW512, 233 OPW1024, 234 OPW16, 235 OPWV216, 236 OPWV232, 237 OPW_LAST_, 238 OPW_FIRST_ = OPW32 239 }; 240 241 unsigned getVgprClassId(const OpWidthTy Width) const; 242 unsigned getAgprClassId(const OpWidthTy Width) const; 243 unsigned getSgprClassId(const OpWidthTy Width) const; 244 unsigned getTtmpClassId(const OpWidthTy Width) const; 245 246 static MCOperand decodeIntImmed(unsigned Imm); 247 static MCOperand decodeFPImmed(OpWidthTy Width, unsigned Imm); 248 MCOperand decodeMandatoryLiteralConstant(unsigned Imm) const; 249 MCOperand decodeLiteralConstant() const; 250 251 MCOperand decodeSrcOp(const OpWidthTy Width, unsigned Val, 252 bool MandatoryLiteral = false) const; 253 MCOperand decodeDstOp(const OpWidthTy Width, unsigned Val) const; 254 MCOperand decodeVOPDDstYOp(MCInst &Inst, unsigned Val) const; 255 MCOperand decodeSpecialReg32(unsigned Val) const; 256 MCOperand decodeSpecialReg64(unsigned Val) const; 257 258 MCOperand decodeSDWASrc(const OpWidthTy Width, unsigned Val) const; 259 MCOperand decodeSDWASrc16(unsigned Val) const; 260 MCOperand decodeSDWASrc32(unsigned Val) const; 261 MCOperand decodeSDWAVopcDst(unsigned Val) const; 262 263 MCOperand decodeBoolReg(unsigned Val) const; 264 265 int getTTmpIdx(unsigned Val) const; 266 267 const MCInstrInfo *getMCII() const { return MCII.get(); } 268 269 bool isVI() const; 270 bool isGFX9() const; 271 bool isGFX90A() const; 272 bool isGFX9Plus() const; 273 bool isGFX10() const; 274 bool isGFX10Plus() const; 275 bool isGFX11() const; 276 bool isGFX11Plus() const; 277 278 bool hasArchitectedFlatScratch() const; 279 280 bool isMacDPP(MCInst &MI) const; 281 }; 282 283 //===----------------------------------------------------------------------===// 284 // AMDGPUSymbolizer 285 //===----------------------------------------------------------------------===// 286 287 class AMDGPUSymbolizer : public MCSymbolizer { 288 private: 289 void *DisInfo; 290 std::vector<uint64_t> ReferencedAddresses; 291 292 public: 293 AMDGPUSymbolizer(MCContext &Ctx, std::unique_ptr<MCRelocationInfo> &&RelInfo, 294 void *disInfo) 295 : MCSymbolizer(Ctx, std::move(RelInfo)), DisInfo(disInfo) {} 296 297 bool tryAddingSymbolicOperand(MCInst &Inst, raw_ostream &cStream, 298 int64_t Value, uint64_t Address, bool IsBranch, 299 uint64_t Offset, uint64_t OpSize, 300 uint64_t InstSize) override; 301 302 void tryAddingPcLoadReferenceComment(raw_ostream &cStream, 303 int64_t Value, 304 uint64_t Address) override; 305 306 ArrayRef<uint64_t> getReferencedAddresses() const override { 307 return ReferencedAddresses; 308 } 309 }; 310 311 } // end namespace llvm 312 313 #endif // LLVM_LIB_TARGET_AMDGPU_DISASSEMBLER_AMDGPUDISASSEMBLER_H 314