Index: lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h =================================================================== --- lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h +++ lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h @@ -18,76 +18,107 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" +#include "llvm/MC/MCDisassembler/MCSymbolizer.h" namespace llvm { - class MCContext; - class MCInst; - class MCOperand; - class MCSubtargetInfo; - class Twine; - - class AMDGPUDisassembler : public MCDisassembler { - private: - mutable ArrayRef Bytes; - - public: - AMDGPUDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) : - MCDisassembler(STI, Ctx) {} - - ~AMDGPUDisassembler() {} - - DecodeStatus getInstruction(MCInst &MI, uint64_t &Size, - ArrayRef Bytes, uint64_t Address, - raw_ostream &WS, raw_ostream &CS) const override; - - const char* getRegClassName(unsigned RegClassID) const; - - MCOperand createRegOperand(unsigned int RegId) const; - MCOperand createRegOperand(unsigned RegClassID, unsigned Val) const; - MCOperand createSRegOperand(unsigned SRegClassID, unsigned Val) const; - - MCOperand errOperand(unsigned V, const llvm::Twine& ErrMsg) const; - - DecodeStatus tryDecodeInst(const uint8_t* Table, - MCInst &MI, - uint64_t Inst, - uint64_t Address) const; - - MCOperand decodeOperand_VGPR_32(unsigned Val) const; - MCOperand decodeOperand_VS_32(unsigned Val) const; - MCOperand decodeOperand_VS_64(unsigned Val) const; - - MCOperand decodeOperand_VReg_64(unsigned Val) const; - MCOperand decodeOperand_VReg_96(unsigned Val) const; - MCOperand decodeOperand_VReg_128(unsigned Val) const; - - MCOperand decodeOperand_SReg_32(unsigned Val) const; - MCOperand decodeOperand_SReg_32_XM0(unsigned Val) const; - MCOperand decodeOperand_SReg_64(unsigned Val) const; - MCOperand decodeOperand_SReg_128(unsigned Val) const; - MCOperand decodeOperand_SReg_256(unsigned Val) const; - MCOperand decodeOperand_SReg_512(unsigned Val) const; - - enum OpWidthTy { - OPW32, - OPW64, - OPW128, - OPW_LAST_, - OPW_FIRST_ = OPW32 - }; - unsigned getVgprClassId(const OpWidthTy Width) const; - unsigned getSgprClassId(const OpWidthTy Width) const; - unsigned getTtmpClassId(const OpWidthTy Width) const; - - static MCOperand decodeIntImmed(unsigned Imm); - static MCOperand decodeFPImmed(bool Is32, unsigned Imm); - MCOperand decodeLiteralConstant() const; - - MCOperand decodeSrcOp(const OpWidthTy Width, unsigned Val) const; - MCOperand decodeSpecialReg32(unsigned Val) const; - MCOperand decodeSpecialReg64(unsigned Val) const; +class MCContext; +class MCInst; +class MCOperand; +class MCSubtargetInfo; +class Twine; + +//===----------------------------------------------------------------------===// +// AMDGPUDisassembler +//===----------------------------------------------------------------------===// + +class AMDGPUDisassembler : public MCDisassembler { +private: + mutable ArrayRef Bytes; + +public: + AMDGPUDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) : + MCDisassembler(STI, Ctx) {} + + ~AMDGPUDisassembler() {} + + DecodeStatus getInstruction(MCInst &MI, uint64_t &Size, + ArrayRef Bytes, uint64_t Address, + raw_ostream &WS, raw_ostream &CS) const override; + + const char* getRegClassName(unsigned RegClassID) const; + + MCOperand createRegOperand(unsigned int RegId) const; + MCOperand createRegOperand(unsigned RegClassID, unsigned Val) const; + MCOperand createSRegOperand(unsigned SRegClassID, unsigned Val) const; + + MCOperand errOperand(unsigned V, const llvm::Twine& ErrMsg) const; + + DecodeStatus tryDecodeInst(const uint8_t* Table, + MCInst &MI, + uint64_t Inst, + uint64_t Address) const; + + MCOperand decodeOperand_VGPR_32(unsigned Val) const; + MCOperand decodeOperand_VS_32(unsigned Val) const; + MCOperand decodeOperand_VS_64(unsigned Val) const; + + MCOperand decodeOperand_VReg_64(unsigned Val) const; + MCOperand decodeOperand_VReg_96(unsigned Val) const; + MCOperand decodeOperand_VReg_128(unsigned Val) const; + + MCOperand decodeOperand_SReg_32(unsigned Val) const; + MCOperand decodeOperand_SReg_32_XM0(unsigned Val) const; + MCOperand decodeOperand_SReg_64(unsigned Val) const; + MCOperand decodeOperand_SReg_128(unsigned Val) const; + MCOperand decodeOperand_SReg_256(unsigned Val) const; + MCOperand decodeOperand_SReg_512(unsigned Val) const; + + enum OpWidthTy { + OPW32, + OPW64, + OPW128, + OPW_LAST_, + OPW_FIRST_ = OPW32 }; + unsigned getVgprClassId(const OpWidthTy Width) const; + unsigned getSgprClassId(const OpWidthTy Width) const; + unsigned getTtmpClassId(const OpWidthTy Width) const; + + static MCOperand decodeIntImmed(unsigned Imm); + static MCOperand decodeFPImmed(bool Is32, unsigned Imm); + MCOperand decodeLiteralConstant() const; + + MCOperand decodeSrcOp(const OpWidthTy Width, unsigned Val) const; + MCOperand decodeSpecialReg32(unsigned Val) const; + MCOperand decodeSpecialReg64(unsigned Val) const; +}; + +//===----------------------------------------------------------------------===// +// AMDGPUSymbolizer +//===----------------------------------------------------------------------===// + +class AMDGPUSymbolizer : public MCSymbolizer { +private: + void *DisInfo; + +public: + AMDGPUSymbolizer(MCContext &Ctx, std::unique_ptr &&RelInfo, + void *disInfo) + : MCSymbolizer(Ctx, std::move(RelInfo)), DisInfo(disInfo) {} + + bool tryAddingSymbolicOperand(MCInst &Inst, raw_ostream &cStream, + int64_t Value, uint64_t Address, + bool IsBranch, uint64_t Offset, + uint64_t InstSize) override; + + void tryAddingPcLoadReferenceComment(raw_ostream &cStream, + int64_t Value, + uint64_t Address) override { + assert(false && "Implement if needed"); + } +}; + } // namespace llvm #endif //LLVM_LIB_TARGET_AMDGPU_DISASSEMBLER_AMDGPUDISASSEMBLER_H Index: lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp =================================================================== --- lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp +++ lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp @@ -28,6 +28,7 @@ #include "llvm/MC/MCInst.h" #include "llvm/MC/MCInstrDesc.h" #include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/Support/ELF.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Debug.h" #include "llvm/Support/TargetRegistry.h" @@ -48,6 +49,18 @@ MCDisassembler::SoftFail; } +static DecodeStatus decodeSoppBrTarget(MCInst &Inst, unsigned Imm, + uint64_t Addr, const void *Decoder) { + auto DAsm = static_cast(Decoder); + + APInt SignedOffset(18, Imm * 4, true); + int64_t Offset = (SignedOffset.sext(64) + 4 + Addr).getSExtValue(); + + if (DAsm->tryAddingSymbolicOperand(Inst, Offset, Addr, true, 2, 2)) + return MCDisassembler::Success; + return addOperand(Inst, MCOperand::createImm(Imm)); +} + #define DECODE_OPERAND2(RegClass, DecName) \ static DecodeStatus Decode##RegClass##RegisterClass(MCInst &Inst, \ unsigned Imm, \ @@ -431,6 +444,50 @@ return errOperand(Val, "unknown operand encoding " + Twine(Val)); } +//===----------------------------------------------------------------------===// +// AMDGPUSymbolizer +//===----------------------------------------------------------------------===// + +// Try to find symbol name for specified label +bool AMDGPUSymbolizer::tryAddingSymbolicOperand(MCInst &Inst, + raw_ostream &/*cStream*/, int64_t Value, + uint64_t /*Address*/, bool IsBranch, + uint64_t /*Offset*/, uint64_t /*InstSize*/) { + typedef std::tuple SymbolInfoTy; + typedef std::vector SectionSymbolsTy; + + if (!IsBranch) { + return false; + } + + auto *Symbols = static_cast(DisInfo); + auto Result = std::find_if(Symbols->begin(), Symbols->end(), + [Value](const SymbolInfoTy& Val) { + return std::get<0>(Val) == static_cast(Value) + && std::get<2>(Val) == ELF::STT_NOTYPE; + }); + if (Result != Symbols->end()) { + auto *Sym = Ctx.getOrCreateSymbol(std::get<1>(*Result)); + const auto *Add = MCSymbolRefExpr::create(Sym, Ctx); + Inst.addOperand(MCOperand::createExpr(Add)); + return true; + } + return false; +} + +//===----------------------------------------------------------------------===// +// Initialization +//===----------------------------------------------------------------------===// + +static MCSymbolizer *createAMDGPUSymbolizer(const Triple &/*TT*/, + LLVMOpInfoCallback /*GetOpInfo*/, + LLVMSymbolLookupCallback /*SymbolLookUp*/, + void *DisInfo, + MCContext *Ctx, + std::unique_ptr &&RelInfo) { + return new AMDGPUSymbolizer(*Ctx, std::move(RelInfo), DisInfo); +} + static MCDisassembler *createAMDGPUDisassembler(const Target &T, const MCSubtargetInfo &STI, MCContext &Ctx) { @@ -439,4 +496,5 @@ extern "C" void LLVMInitializeAMDGPUDisassembler() { TargetRegistry::RegisterMCDisassembler(TheGCNTarget, createAMDGPUDisassembler); + TargetRegistry::RegisterMCSymbolizer(TheGCNTarget, createAMDGPUSymbolizer); } Index: lib/Target/AMDGPU/SIInstrInfo.td =================================================================== --- lib/Target/AMDGPU/SIInstrInfo.td +++ lib/Target/AMDGPU/SIInstrInfo.td @@ -291,6 +291,7 @@ def sopp_brtarget : Operand { let EncoderMethod = "getSOPPBrEncoding"; + let DecoderMethod = "decodeSoppBrTarget"; let OperandType = "OPERAND_PCREL"; let ParserMatchClass = SoppBrTarget; } Index: test/MC/AMDGPU/labels-branch.s =================================================================== --- test/MC/AMDGPU/labels-branch.s +++ test/MC/AMDGPU/labels-branch.s @@ -6,19 +6,19 @@ // VI: s_branch loop_start ; encoding: [A,A,0x82,0xbf] // VI-NEXT: ; fixup A - offset: 0, value: loop_start, kind: fixup_si_sopp_br // BIN: loop_start: -// BIN-NEXT: BF82FFFF +// BIN-NEXT: s_branch loop_start // 000000000000: BF82FFFF s_branch loop_end // VI: s_branch loop_end ; encoding: [A,A,0x82,0xbf] // VI-NEXT: ; fixup A - offset: 0, value: loop_end, kind: fixup_si_sopp_br -// BIN: BF820000 +// BIN: s_branch loop_end // 000000000004: BF820000 // BIN: loop_end: loop_end: s_branch gds // VI: s_branch gds ; encoding: [A,A,0x82,0xbf] // VI-NEXT: ; fixup A - offset: 0, value: gds, kind: fixup_si_sopp_br -// BIN: BF820000 +// BIN: s_branch gds // 000000000008: BF820000 // BIN: gds: gds: s_nop 0 Index: tools/llvm-objdump/llvm-objdump.cpp =================================================================== --- tools/llvm-objdump/llvm-objdump.cpp +++ tools/llvm-objdump/llvm-objdump.cpp @@ -1097,8 +1097,10 @@ std::unique_ptr MII(TheTarget->createMCInstrInfo()); if (!MII) report_fatal_error("error: no instruction info for target " + TripleName); - std::unique_ptr MOFI(new MCObjectFileInfo); - MCContext Ctx(AsmInfo.get(), MRI.get(), MOFI.get()); + MCObjectFileInfo MOFI; + MCContext Ctx(AsmInfo.get(), MRI.get(), &MOFI); + // FIXME: for now initialize MCObjectFileInfo with default values + MOFI.InitMCObjectFileInfo(Triple(TripleName), false, CodeModel::Default, Ctx); std::unique_ptr DisAsm( TheTarget->createMCDisassembler(*STI, Ctx)); @@ -1229,6 +1231,18 @@ std::sort(DataMappingSymsAddr.begin(), DataMappingSymsAddr.end()); std::sort(TextMappingSymsAddr.begin(), TextMappingSymsAddr.end()); + if (Obj->isELF() && Obj->getArch() == Triple::amdgcn) { + // AMDGPU disassembler uses symbolizer for printing labels + std::unique_ptr RelInfo( + TheTarget->createMCRelocationInfo(TripleName, Ctx)); + if (RelInfo) { + std::unique_ptr Symbolizer( + TheTarget->createMCSymbolizer( + TripleName, nullptr, nullptr, &Symbols, &Ctx, std::move(RelInfo))); + DisAsm->setSymbolizer(std::move(Symbolizer)); + } + } + // Make a list of all the relocations for this section. std::vector Rels; if (InlineRelocs) {