10b57cec5SDimitry Andric //===- AMDGPUDisassembler.hpp - Disassembler for AMDGPU ISA -----*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric /// \file 100b57cec5SDimitry Andric /// 110b57cec5SDimitry Andric /// This file contains declaration for AMDGPU ISA disassembler 120b57cec5SDimitry Andric // 130b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 140b57cec5SDimitry Andric 150b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_AMDGPU_DISASSEMBLER_AMDGPUDISASSEMBLER_H 160b57cec5SDimitry Andric #define LLVM_LIB_TARGET_AMDGPU_DISASSEMBLER_AMDGPUDISASSEMBLER_H 170b57cec5SDimitry Andric 18*0fca6ea1SDimitry Andric #include "SIDefines.h" 1981ad6265SDimitry Andric #include "llvm/ADT/APInt.h" 2006c3fb27SDimitry Andric #include "llvm/ADT/SmallString.h" 210b57cec5SDimitry Andric #include "llvm/MC/MCDisassembler/MCDisassembler.h" 2281ad6265SDimitry Andric #include "llvm/MC/MCInst.h" 2306c3fb27SDimitry Andric #include "llvm/MC/MCInstrInfo.h" 24e8d8bef9SDimitry Andric #include "llvm/Support/DataExtractor.h" 250b57cec5SDimitry Andric #include <memory> 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric namespace llvm { 280b57cec5SDimitry Andric 2906c3fb27SDimitry Andric class MCAsmInfo; 300b57cec5SDimitry Andric class MCInst; 310b57cec5SDimitry Andric class MCOperand; 320b57cec5SDimitry Andric class MCSubtargetInfo; 330b57cec5SDimitry Andric class Twine; 340b57cec5SDimitry Andric 3581ad6265SDimitry Andric // Exposes an interface expected by autogenerated code in 3681ad6265SDimitry Andric // FixedLenDecoderEmitter 3781ad6265SDimitry Andric class DecoderUInt128 { 3881ad6265SDimitry Andric private: 3981ad6265SDimitry Andric uint64_t Lo = 0; 4081ad6265SDimitry Andric uint64_t Hi = 0; 4181ad6265SDimitry Andric 4281ad6265SDimitry Andric public: 4381ad6265SDimitry Andric DecoderUInt128() = default; Lo(Lo)4481ad6265SDimitry Andric DecoderUInt128(uint64_t Lo, uint64_t Hi = 0) : Lo(Lo), Hi(Hi) {} 4581ad6265SDimitry Andric operator bool() const { return Lo || Hi; } insertBits(uint64_t SubBits,unsigned BitPosition,unsigned NumBits)4681ad6265SDimitry Andric void insertBits(uint64_t SubBits, unsigned BitPosition, unsigned NumBits) { 4781ad6265SDimitry Andric assert(NumBits && NumBits <= 64); 4881ad6265SDimitry Andric assert(SubBits >> 1 >> (NumBits - 1) == 0); 4981ad6265SDimitry Andric assert(BitPosition < 128); 5081ad6265SDimitry Andric if (BitPosition < 64) { 5181ad6265SDimitry Andric Lo |= SubBits << BitPosition; 5281ad6265SDimitry Andric Hi |= SubBits >> 1 >> (63 - BitPosition); 5381ad6265SDimitry Andric } else { 5481ad6265SDimitry Andric Hi |= SubBits << (BitPosition - 64); 5581ad6265SDimitry Andric } 5681ad6265SDimitry Andric } extractBitsAsZExtValue(unsigned NumBits,unsigned BitPosition)5781ad6265SDimitry Andric uint64_t extractBitsAsZExtValue(unsigned NumBits, 5881ad6265SDimitry Andric unsigned BitPosition) const { 5981ad6265SDimitry Andric assert(NumBits && NumBits <= 64); 6081ad6265SDimitry Andric assert(BitPosition < 128); 6181ad6265SDimitry Andric uint64_t Val; 6281ad6265SDimitry Andric if (BitPosition < 64) 6381ad6265SDimitry Andric Val = Lo >> BitPosition | Hi << 1 << (63 - BitPosition); 6481ad6265SDimitry Andric else 6581ad6265SDimitry Andric Val = Hi >> (BitPosition - 64); 6681ad6265SDimitry Andric return Val & ((uint64_t(2) << (NumBits - 1)) - 1); 6781ad6265SDimitry Andric } 6881ad6265SDimitry Andric DecoderUInt128 operator&(const DecoderUInt128 &RHS) const { 6981ad6265SDimitry Andric return DecoderUInt128(Lo & RHS.Lo, Hi & RHS.Hi); 7081ad6265SDimitry Andric } 7181ad6265SDimitry Andric DecoderUInt128 operator&(const uint64_t &RHS) const { 7281ad6265SDimitry Andric return *this & DecoderUInt128(RHS); 7381ad6265SDimitry Andric } 7481ad6265SDimitry Andric DecoderUInt128 operator~() const { return DecoderUInt128(~Lo, ~Hi); } 7581ad6265SDimitry Andric bool operator==(const DecoderUInt128 &RHS) { 7681ad6265SDimitry Andric return Lo == RHS.Lo && Hi == RHS.Hi; 7781ad6265SDimitry Andric } 7881ad6265SDimitry Andric bool operator!=(const DecoderUInt128 &RHS) { 7981ad6265SDimitry Andric return Lo != RHS.Lo || Hi != RHS.Hi; 8081ad6265SDimitry Andric } 8181ad6265SDimitry Andric bool operator!=(const int &RHS) { 8281ad6265SDimitry Andric return *this != DecoderUInt128(RHS); 8381ad6265SDimitry Andric } 8481ad6265SDimitry Andric friend raw_ostream &operator<<(raw_ostream &OS, const DecoderUInt128 &RHS) { 8581ad6265SDimitry Andric return OS << APInt(128, {RHS.Lo, RHS.Hi}); 8681ad6265SDimitry Andric } 8781ad6265SDimitry Andric }; 8881ad6265SDimitry Andric 890b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 900b57cec5SDimitry Andric // AMDGPUDisassembler 910b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 920b57cec5SDimitry Andric 930b57cec5SDimitry Andric class AMDGPUDisassembler : public MCDisassembler { 940b57cec5SDimitry Andric private: 950b57cec5SDimitry Andric std::unique_ptr<MCInstrInfo const> const MCII; 960b57cec5SDimitry Andric const MCRegisterInfo &MRI; 9706c3fb27SDimitry Andric const MCAsmInfo &MAI; 980b57cec5SDimitry Andric const unsigned TargetMaxInstBytes; 990b57cec5SDimitry Andric mutable ArrayRef<uint8_t> Bytes; 1000b57cec5SDimitry Andric mutable uint32_t Literal; 1015f757f3fSDimitry Andric mutable uint64_t Literal64; 1020b57cec5SDimitry Andric mutable bool HasLiteral; 10306c3fb27SDimitry Andric mutable std::optional<bool> EnableWavefrontSize32; 104*0fca6ea1SDimitry Andric unsigned CodeObjectVersion; 105*0fca6ea1SDimitry Andric const MCExpr *UCVersionW64Expr; 106*0fca6ea1SDimitry Andric const MCExpr *UCVersionW32Expr; 107*0fca6ea1SDimitry Andric const MCExpr *UCVersionMDPExpr; 108*0fca6ea1SDimitry Andric 109*0fca6ea1SDimitry Andric const MCExpr *createConstantSymbolExpr(StringRef Id, int64_t Val); 1100b57cec5SDimitry Andric 1110b57cec5SDimitry Andric public: 1120b57cec5SDimitry Andric AMDGPUDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, 1130b57cec5SDimitry Andric MCInstrInfo const *MCII); 1140b57cec5SDimitry Andric ~AMDGPUDisassembler() override = default; 1150b57cec5SDimitry Andric 116*0fca6ea1SDimitry Andric void setABIVersion(unsigned Version) override; 117*0fca6ea1SDimitry Andric 1180b57cec5SDimitry Andric DecodeStatus getInstruction(MCInst &MI, uint64_t &Size, 1190b57cec5SDimitry Andric ArrayRef<uint8_t> Bytes, uint64_t Address, 120480093f4SDimitry Andric raw_ostream &CS) const override; 1210b57cec5SDimitry Andric 1220b57cec5SDimitry Andric const char* getRegClassName(unsigned RegClassID) const; 1230b57cec5SDimitry Andric 1240b57cec5SDimitry Andric MCOperand createRegOperand(unsigned int RegId) const; 1250b57cec5SDimitry Andric MCOperand createRegOperand(unsigned RegClassID, unsigned Val) const; 1260b57cec5SDimitry Andric MCOperand createSRegOperand(unsigned SRegClassID, unsigned Val) const; 1275f757f3fSDimitry Andric MCOperand createVGPR16Operand(unsigned RegIdx, bool IsHi) const; 1280b57cec5SDimitry Andric 1290b57cec5SDimitry Andric MCOperand errOperand(unsigned V, const Twine& ErrMsg) const; 1300b57cec5SDimitry Andric 13181ad6265SDimitry Andric template <typename InsnType> tryDecodeInst(const uint8_t * Table,MCInst & MI,InsnType Inst,uint64_t Address,raw_ostream & Comments)13281ad6265SDimitry Andric DecodeStatus tryDecodeInst(const uint8_t *Table, MCInst &MI, InsnType Inst, 13306c3fb27SDimitry Andric uint64_t Address, raw_ostream &Comments) const { 13481ad6265SDimitry Andric assert(MI.getOpcode() == 0); 13581ad6265SDimitry Andric assert(MI.getNumOperands() == 0); 13681ad6265SDimitry Andric MCInst TmpInst; 13781ad6265SDimitry Andric HasLiteral = false; 13881ad6265SDimitry Andric const auto SavedBytes = Bytes; 13906c3fb27SDimitry Andric 14006c3fb27SDimitry Andric SmallString<64> LocalComments; 14106c3fb27SDimitry Andric raw_svector_ostream LocalCommentStream(LocalComments); 14206c3fb27SDimitry Andric CommentStream = &LocalCommentStream; 14306c3fb27SDimitry Andric 14406c3fb27SDimitry Andric DecodeStatus Res = 14506c3fb27SDimitry Andric decodeInstruction(Table, TmpInst, Inst, Address, this, STI); 14606c3fb27SDimitry Andric 14706c3fb27SDimitry Andric CommentStream = nullptr; 14806c3fb27SDimitry Andric 14906c3fb27SDimitry Andric if (Res != Fail) { 15081ad6265SDimitry Andric MI = TmpInst; 15106c3fb27SDimitry Andric Comments << LocalComments; 15281ad6265SDimitry Andric return MCDisassembler::Success; 15381ad6265SDimitry Andric } 15481ad6265SDimitry Andric Bytes = SavedBytes; 15581ad6265SDimitry Andric return MCDisassembler::Fail; 15681ad6265SDimitry Andric } 1570b57cec5SDimitry Andric 1585f757f3fSDimitry Andric template <typename InsnType> tryDecodeInst(const uint8_t * Table1,const uint8_t * Table2,MCInst & MI,InsnType Inst,uint64_t Address,raw_ostream & Comments)1595f757f3fSDimitry Andric DecodeStatus tryDecodeInst(const uint8_t *Table1, const uint8_t *Table2, 1605f757f3fSDimitry Andric MCInst &MI, InsnType Inst, uint64_t Address, 1615f757f3fSDimitry Andric raw_ostream &Comments) const { 1625f757f3fSDimitry Andric for (const uint8_t *T : {Table1, Table2}) { 1635f757f3fSDimitry Andric if (DecodeStatus Res = tryDecodeInst(T, MI, Inst, Address, Comments)) 1645f757f3fSDimitry Andric return Res; 1655f757f3fSDimitry Andric } 1665f757f3fSDimitry Andric return MCDisassembler::Fail; 1675f757f3fSDimitry Andric } 1685f757f3fSDimitry Andric 169*0fca6ea1SDimitry Andric Expected<bool> onSymbolStart(SymbolInfoTy &Symbol, uint64_t &Size, 170*0fca6ea1SDimitry Andric ArrayRef<uint8_t> Bytes, 171*0fca6ea1SDimitry Andric uint64_t Address) const override; 172e8d8bef9SDimitry Andric 173*0fca6ea1SDimitry Andric Expected<bool> decodeKernelDescriptor(StringRef KdName, 174*0fca6ea1SDimitry Andric ArrayRef<uint8_t> Bytes, 175e8d8bef9SDimitry Andric uint64_t KdAddress) const; 176e8d8bef9SDimitry Andric 177*0fca6ea1SDimitry Andric Expected<bool> 178e8d8bef9SDimitry Andric decodeKernelDescriptorDirective(DataExtractor::Cursor &Cursor, 179e8d8bef9SDimitry Andric ArrayRef<uint8_t> Bytes, 180e8d8bef9SDimitry Andric raw_string_ostream &KdStream) const; 181e8d8bef9SDimitry Andric 182e8d8bef9SDimitry Andric /// Decode as directives that handle COMPUTE_PGM_RSRC1. 183e8d8bef9SDimitry Andric /// \param FourByteBuffer - Bytes holding contents of COMPUTE_PGM_RSRC1. 184e8d8bef9SDimitry Andric /// \param KdStream - Stream to write the disassembled directives to. 185e8d8bef9SDimitry Andric // NOLINTNEXTLINE(readability-identifier-naming) 186*0fca6ea1SDimitry Andric Expected<bool> decodeCOMPUTE_PGM_RSRC1(uint32_t FourByteBuffer, 187e8d8bef9SDimitry Andric raw_string_ostream &KdStream) const; 188e8d8bef9SDimitry Andric 189e8d8bef9SDimitry Andric /// Decode as directives that handle COMPUTE_PGM_RSRC2. 190e8d8bef9SDimitry Andric /// \param FourByteBuffer - Bytes holding contents of COMPUTE_PGM_RSRC2. 191e8d8bef9SDimitry Andric /// \param KdStream - Stream to write the disassembled directives to. 192e8d8bef9SDimitry Andric // NOLINTNEXTLINE(readability-identifier-naming) 193*0fca6ea1SDimitry Andric Expected<bool> decodeCOMPUTE_PGM_RSRC2(uint32_t FourByteBuffer, 194e8d8bef9SDimitry Andric raw_string_ostream &KdStream) const; 195e8d8bef9SDimitry Andric 19606c3fb27SDimitry Andric /// Decode as directives that handle COMPUTE_PGM_RSRC3. 19706c3fb27SDimitry Andric /// \param FourByteBuffer - Bytes holding contents of COMPUTE_PGM_RSRC3. 19806c3fb27SDimitry Andric /// \param KdStream - Stream to write the disassembled directives to. 19906c3fb27SDimitry Andric // NOLINTNEXTLINE(readability-identifier-naming) 200*0fca6ea1SDimitry Andric Expected<bool> decodeCOMPUTE_PGM_RSRC3(uint32_t FourByteBuffer, 20106c3fb27SDimitry Andric raw_string_ostream &KdStream) const; 20206c3fb27SDimitry Andric 203*0fca6ea1SDimitry Andric void convertEXPInst(MCInst &MI) const; 204*0fca6ea1SDimitry Andric void convertVINTERPInst(MCInst &MI) const; 205*0fca6ea1SDimitry Andric void convertFMAanyK(MCInst &MI, int ImmLitIdx) const; 206*0fca6ea1SDimitry Andric void convertSDWAInst(MCInst &MI) const; 207*0fca6ea1SDimitry Andric void convertDPP8Inst(MCInst &MI) const; 208*0fca6ea1SDimitry Andric void convertMIMGInst(MCInst &MI) const; 209*0fca6ea1SDimitry Andric void convertVOP3DPPInst(MCInst &MI) const; 210*0fca6ea1SDimitry Andric void convertVOP3PDPPInst(MCInst &MI) const; 211*0fca6ea1SDimitry Andric void convertVOPCDPPInst(MCInst &MI) const; 212bdd1243dSDimitry Andric void convertMacDPPInst(MCInst &MI) const; 213*0fca6ea1SDimitry Andric void convertTrue16OpSel(MCInst &MI) const; 2140b57cec5SDimitry Andric 2150b57cec5SDimitry Andric enum OpWidthTy { 2160b57cec5SDimitry Andric OPW32, 2170b57cec5SDimitry Andric OPW64, 218fe6060f1SDimitry Andric OPW96, 2190b57cec5SDimitry Andric OPW128, 220fe6060f1SDimitry Andric OPW160, 2210b57cec5SDimitry Andric OPW256, 222bdd1243dSDimitry Andric OPW288, 223bdd1243dSDimitry Andric OPW320, 224bdd1243dSDimitry Andric OPW352, 225bdd1243dSDimitry Andric OPW384, 2260b57cec5SDimitry Andric OPW512, 2270b57cec5SDimitry Andric OPW1024, 2280b57cec5SDimitry Andric OPW16, 2290b57cec5SDimitry Andric OPWV216, 230fe6060f1SDimitry Andric OPWV232, 2310b57cec5SDimitry Andric OPW_LAST_, 2320b57cec5SDimitry Andric OPW_FIRST_ = OPW32 2330b57cec5SDimitry Andric }; 2340b57cec5SDimitry Andric 2350b57cec5SDimitry Andric unsigned getVgprClassId(const OpWidthTy Width) const; 2360b57cec5SDimitry Andric unsigned getAgprClassId(const OpWidthTy Width) const; 2370b57cec5SDimitry Andric unsigned getSgprClassId(const OpWidthTy Width) const; 2380b57cec5SDimitry Andric unsigned getTtmpClassId(const OpWidthTy Width) const; 2390b57cec5SDimitry Andric 2400b57cec5SDimitry Andric static MCOperand decodeIntImmed(unsigned Imm); 241*0fca6ea1SDimitry Andric static MCOperand decodeFPImmed(unsigned ImmWidth, unsigned Imm, 242*0fca6ea1SDimitry Andric AMDGPU::OperandSemantics Sema); 24306c3fb27SDimitry Andric 244349cc55cSDimitry Andric MCOperand decodeMandatoryLiteralConstant(unsigned Imm) const; 2455f757f3fSDimitry Andric MCOperand decodeLiteralConstant(bool ExtendFP64) const; 2460b57cec5SDimitry Andric 247*0fca6ea1SDimitry Andric MCOperand decodeSrcOp( 248*0fca6ea1SDimitry Andric const OpWidthTy Width, unsigned Val, bool MandatoryLiteral = false, 249*0fca6ea1SDimitry Andric unsigned ImmWidth = 0, 250*0fca6ea1SDimitry Andric AMDGPU::OperandSemantics Sema = AMDGPU::OperandSemantics::INT) const; 2515f757f3fSDimitry Andric 252*0fca6ea1SDimitry Andric MCOperand decodeNonVGPRSrcOp( 253*0fca6ea1SDimitry Andric const OpWidthTy Width, unsigned Val, bool MandatoryLiteral = false, 254*0fca6ea1SDimitry Andric unsigned ImmWidth = 0, 255*0fca6ea1SDimitry Andric AMDGPU::OperandSemantics Sema = AMDGPU::OperandSemantics::INT) const; 25606c3fb27SDimitry Andric 25781ad6265SDimitry Andric MCOperand decodeVOPDDstYOp(MCInst &Inst, unsigned Val) const; 2580b57cec5SDimitry Andric MCOperand decodeSpecialReg32(unsigned Val) const; 2590b57cec5SDimitry Andric MCOperand decodeSpecialReg64(unsigned Val) const; 2600b57cec5SDimitry Andric 26106c3fb27SDimitry Andric MCOperand decodeSDWASrc(const OpWidthTy Width, unsigned Val, 262*0fca6ea1SDimitry Andric unsigned ImmWidth, 263*0fca6ea1SDimitry Andric AMDGPU::OperandSemantics Sema) const; 2640b57cec5SDimitry Andric MCOperand decodeSDWASrc16(unsigned Val) const; 2650b57cec5SDimitry Andric MCOperand decodeSDWASrc32(unsigned Val) const; 2660b57cec5SDimitry Andric MCOperand decodeSDWAVopcDst(unsigned Val) const; 2670b57cec5SDimitry Andric 2680b57cec5SDimitry Andric MCOperand decodeBoolReg(unsigned Val) const; 2695f757f3fSDimitry Andric MCOperand decodeSplitBarrier(unsigned Val) const; 270*0fca6ea1SDimitry Andric MCOperand decodeDpp8FI(unsigned Val) const; 271*0fca6ea1SDimitry Andric 272*0fca6ea1SDimitry Andric MCOperand decodeVersionImm(unsigned Imm) const; 2730b57cec5SDimitry Andric 2740b57cec5SDimitry Andric int getTTmpIdx(unsigned Val) const; 2750b57cec5SDimitry Andric getMCII()276fe6060f1SDimitry Andric const MCInstrInfo *getMCII() const { return MCII.get(); } 277fe6060f1SDimitry Andric 2780b57cec5SDimitry Andric bool isVI() const; 2790b57cec5SDimitry Andric bool isGFX9() const; 280fe6060f1SDimitry Andric bool isGFX90A() const; 281e8d8bef9SDimitry Andric bool isGFX9Plus() const; 2820b57cec5SDimitry Andric bool isGFX10() const; 283e8d8bef9SDimitry Andric bool isGFX10Plus() const; 28481ad6265SDimitry Andric bool isGFX11() const; 28581ad6265SDimitry Andric bool isGFX11Plus() const; 286*0fca6ea1SDimitry Andric bool isGFX12() const; 2875f757f3fSDimitry Andric bool isGFX12Plus() const; 288fe6060f1SDimitry Andric 289fe6060f1SDimitry Andric bool hasArchitectedFlatScratch() const; 2905f757f3fSDimitry Andric bool hasKernargPreload() const; 291bdd1243dSDimitry Andric 292bdd1243dSDimitry Andric bool isMacDPP(MCInst &MI) const; 2930b57cec5SDimitry Andric }; 2940b57cec5SDimitry Andric 2950b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 2960b57cec5SDimitry Andric // AMDGPUSymbolizer 2970b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 2980b57cec5SDimitry Andric 2990b57cec5SDimitry Andric class AMDGPUSymbolizer : public MCSymbolizer { 3000b57cec5SDimitry Andric private: 3010b57cec5SDimitry Andric void *DisInfo; 302fe6060f1SDimitry Andric std::vector<uint64_t> ReferencedAddresses; 3030b57cec5SDimitry Andric 3040b57cec5SDimitry Andric public: AMDGPUSymbolizer(MCContext & Ctx,std::unique_ptr<MCRelocationInfo> && RelInfo,void * disInfo)3050b57cec5SDimitry Andric AMDGPUSymbolizer(MCContext &Ctx, std::unique_ptr<MCRelocationInfo> &&RelInfo, 3060b57cec5SDimitry Andric void *disInfo) 3070b57cec5SDimitry Andric : MCSymbolizer(Ctx, std::move(RelInfo)), DisInfo(disInfo) {} 3080b57cec5SDimitry Andric 3090b57cec5SDimitry Andric bool tryAddingSymbolicOperand(MCInst &Inst, raw_ostream &cStream, 31081ad6265SDimitry Andric int64_t Value, uint64_t Address, bool IsBranch, 31181ad6265SDimitry Andric uint64_t Offset, uint64_t OpSize, 3120b57cec5SDimitry Andric uint64_t InstSize) override; 3130b57cec5SDimitry Andric 3140b57cec5SDimitry Andric void tryAddingPcLoadReferenceComment(raw_ostream &cStream, 3150b57cec5SDimitry Andric int64_t Value, 3160b57cec5SDimitry Andric uint64_t Address) override; 317fe6060f1SDimitry Andric getReferencedAddresses()318fe6060f1SDimitry Andric ArrayRef<uint64_t> getReferencedAddresses() const override { 319fe6060f1SDimitry Andric return ReferencedAddresses; 320fe6060f1SDimitry Andric } 3210b57cec5SDimitry Andric }; 3220b57cec5SDimitry Andric 3230b57cec5SDimitry Andric } // end namespace llvm 3240b57cec5SDimitry Andric 3250b57cec5SDimitry Andric #endif // LLVM_LIB_TARGET_AMDGPU_DISASSEMBLER_AMDGPUDISASSEMBLER_H 326