forked from OSchip/llvm-project
[AMDGPU] Disassembler: print label names in branch instructions
Summary: Add AMDGPUSymbolizer for finding names for labels from ELF symbol table. Initialize MCObjectFileInfo with some default values. Reviewers: vpykhtin, artem.tamazov, tstellarAMD Subscribers: arsenm, kzhuravl, wdng, nhaehnle, yaxunl, tony-tye Differential Revision: https://reviews.llvm.org/D24802 llvm-svn: 283450
This commit is contained in:
parent
488c05763c
commit
3381d7a216
|
@ -28,6 +28,7 @@
|
||||||
#include "llvm/MC/MCInst.h"
|
#include "llvm/MC/MCInst.h"
|
||||||
#include "llvm/MC/MCInstrDesc.h"
|
#include "llvm/MC/MCInstrDesc.h"
|
||||||
#include "llvm/MC/MCSubtargetInfo.h"
|
#include "llvm/MC/MCSubtargetInfo.h"
|
||||||
|
#include "llvm/Support/ELF.h"
|
||||||
#include "llvm/Support/Endian.h"
|
#include "llvm/Support/Endian.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
#include "llvm/Support/TargetRegistry.h"
|
#include "llvm/Support/TargetRegistry.h"
|
||||||
|
@ -48,6 +49,18 @@ addOperand(MCInst &Inst, const MCOperand& Opnd) {
|
||||||
MCDisassembler::SoftFail;
|
MCDisassembler::SoftFail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static DecodeStatus decodeSoppBrTarget(MCInst &Inst, unsigned Imm,
|
||||||
|
uint64_t Addr, const void *Decoder) {
|
||||||
|
auto DAsm = static_cast<const AMDGPUDisassembler*>(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) \
|
#define DECODE_OPERAND2(RegClass, DecName) \
|
||||||
static DecodeStatus Decode##RegClass##RegisterClass(MCInst &Inst, \
|
static DecodeStatus Decode##RegClass##RegisterClass(MCInst &Inst, \
|
||||||
unsigned Imm, \
|
unsigned Imm, \
|
||||||
|
@ -431,6 +444,50 @@ MCOperand AMDGPUDisassembler::decodeSpecialReg64(unsigned Val) const {
|
||||||
return errOperand(Val, "unknown operand encoding " + Twine(Val));
|
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<uint64_t, StringRef, uint8_t> SymbolInfoTy;
|
||||||
|
typedef std::vector<SymbolInfoTy> SectionSymbolsTy;
|
||||||
|
|
||||||
|
if (!IsBranch) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto *Symbols = static_cast<SectionSymbolsTy *>(DisInfo);
|
||||||
|
auto Result = std::find_if(Symbols->begin(), Symbols->end(),
|
||||||
|
[Value](const SymbolInfoTy& Val) {
|
||||||
|
return std::get<0>(Val) == static_cast<uint64_t>(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<MCRelocationInfo> &&RelInfo) {
|
||||||
|
return new AMDGPUSymbolizer(*Ctx, std::move(RelInfo), DisInfo);
|
||||||
|
}
|
||||||
|
|
||||||
static MCDisassembler *createAMDGPUDisassembler(const Target &T,
|
static MCDisassembler *createAMDGPUDisassembler(const Target &T,
|
||||||
const MCSubtargetInfo &STI,
|
const MCSubtargetInfo &STI,
|
||||||
MCContext &Ctx) {
|
MCContext &Ctx) {
|
||||||
|
@ -439,4 +496,5 @@ static MCDisassembler *createAMDGPUDisassembler(const Target &T,
|
||||||
|
|
||||||
extern "C" void LLVMInitializeAMDGPUDisassembler() {
|
extern "C" void LLVMInitializeAMDGPUDisassembler() {
|
||||||
TargetRegistry::RegisterMCDisassembler(TheGCNTarget, createAMDGPUDisassembler);
|
TargetRegistry::RegisterMCDisassembler(TheGCNTarget, createAMDGPUDisassembler);
|
||||||
|
TargetRegistry::RegisterMCSymbolizer(TheGCNTarget, createAMDGPUSymbolizer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,76 +18,107 @@
|
||||||
|
|
||||||
#include "llvm/ADT/ArrayRef.h"
|
#include "llvm/ADT/ArrayRef.h"
|
||||||
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
|
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
|
||||||
|
#include "llvm/MC/MCDisassembler/MCSymbolizer.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
class MCContext;
|
class MCContext;
|
||||||
class MCInst;
|
class MCInst;
|
||||||
class MCOperand;
|
class MCOperand;
|
||||||
class MCSubtargetInfo;
|
class MCSubtargetInfo;
|
||||||
class Twine;
|
class Twine;
|
||||||
|
|
||||||
class AMDGPUDisassembler : public MCDisassembler {
|
//===----------------------------------------------------------------------===//
|
||||||
private:
|
// AMDGPUDisassembler
|
||||||
mutable ArrayRef<uint8_t> Bytes;
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
public:
|
class AMDGPUDisassembler : public MCDisassembler {
|
||||||
AMDGPUDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) :
|
private:
|
||||||
MCDisassembler(STI, Ctx) {}
|
mutable ArrayRef<uint8_t> Bytes;
|
||||||
|
|
||||||
~AMDGPUDisassembler() {}
|
public:
|
||||||
|
AMDGPUDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) :
|
||||||
|
MCDisassembler(STI, Ctx) {}
|
||||||
|
|
||||||
DecodeStatus getInstruction(MCInst &MI, uint64_t &Size,
|
~AMDGPUDisassembler() {}
|
||||||
ArrayRef<uint8_t> Bytes, uint64_t Address,
|
|
||||||
raw_ostream &WS, raw_ostream &CS) const override;
|
|
||||||
|
|
||||||
const char* getRegClassName(unsigned RegClassID) const;
|
DecodeStatus getInstruction(MCInst &MI, uint64_t &Size,
|
||||||
|
ArrayRef<uint8_t> Bytes, uint64_t Address,
|
||||||
|
raw_ostream &WS, raw_ostream &CS) const override;
|
||||||
|
|
||||||
MCOperand createRegOperand(unsigned int RegId) const;
|
const char* getRegClassName(unsigned RegClassID) const;
|
||||||
MCOperand createRegOperand(unsigned RegClassID, unsigned Val) const;
|
|
||||||
MCOperand createSRegOperand(unsigned SRegClassID, unsigned Val) const;
|
|
||||||
|
|
||||||
MCOperand errOperand(unsigned V, const llvm::Twine& ErrMsg) const;
|
MCOperand createRegOperand(unsigned int RegId) const;
|
||||||
|
MCOperand createRegOperand(unsigned RegClassID, unsigned Val) const;
|
||||||
|
MCOperand createSRegOperand(unsigned SRegClassID, unsigned Val) const;
|
||||||
|
|
||||||
DecodeStatus tryDecodeInst(const uint8_t* Table,
|
MCOperand errOperand(unsigned V, const llvm::Twine& ErrMsg) const;
|
||||||
MCInst &MI,
|
|
||||||
uint64_t Inst,
|
|
||||||
uint64_t Address) const;
|
|
||||||
|
|
||||||
MCOperand decodeOperand_VGPR_32(unsigned Val) const;
|
DecodeStatus tryDecodeInst(const uint8_t* Table,
|
||||||
MCOperand decodeOperand_VS_32(unsigned Val) const;
|
MCInst &MI,
|
||||||
MCOperand decodeOperand_VS_64(unsigned Val) const;
|
uint64_t Inst,
|
||||||
|
uint64_t Address) const;
|
||||||
|
|
||||||
MCOperand decodeOperand_VReg_64(unsigned Val) const;
|
MCOperand decodeOperand_VGPR_32(unsigned Val) const;
|
||||||
MCOperand decodeOperand_VReg_96(unsigned Val) const;
|
MCOperand decodeOperand_VS_32(unsigned Val) const;
|
||||||
MCOperand decodeOperand_VReg_128(unsigned Val) const;
|
MCOperand decodeOperand_VS_64(unsigned Val) const;
|
||||||
|
|
||||||
MCOperand decodeOperand_SReg_32(unsigned Val) const;
|
MCOperand decodeOperand_VReg_64(unsigned Val) const;
|
||||||
MCOperand decodeOperand_SReg_32_XM0(unsigned Val) const;
|
MCOperand decodeOperand_VReg_96(unsigned Val) const;
|
||||||
MCOperand decodeOperand_SReg_64(unsigned Val) const;
|
MCOperand decodeOperand_VReg_128(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 {
|
MCOperand decodeOperand_SReg_32(unsigned Val) const;
|
||||||
OPW32,
|
MCOperand decodeOperand_SReg_32_XM0(unsigned Val) const;
|
||||||
OPW64,
|
MCOperand decodeOperand_SReg_64(unsigned Val) const;
|
||||||
OPW128,
|
MCOperand decodeOperand_SReg_128(unsigned Val) const;
|
||||||
OPW_LAST_,
|
MCOperand decodeOperand_SReg_256(unsigned Val) const;
|
||||||
OPW_FIRST_ = OPW32
|
MCOperand decodeOperand_SReg_512(unsigned Val) const;
|
||||||
};
|
|
||||||
unsigned getVgprClassId(const OpWidthTy Width) const;
|
|
||||||
unsigned getSgprClassId(const OpWidthTy Width) const;
|
|
||||||
unsigned getTtmpClassId(const OpWidthTy Width) const;
|
|
||||||
|
|
||||||
static MCOperand decodeIntImmed(unsigned Imm);
|
enum OpWidthTy {
|
||||||
static MCOperand decodeFPImmed(bool Is32, unsigned Imm);
|
OPW32,
|
||||||
MCOperand decodeLiteralConstant() const;
|
OPW64,
|
||||||
|
OPW128,
|
||||||
MCOperand decodeSrcOp(const OpWidthTy Width, unsigned Val) const;
|
OPW_LAST_,
|
||||||
MCOperand decodeSpecialReg32(unsigned Val) const;
|
OPW_FIRST_ = OPW32
|
||||||
MCOperand decodeSpecialReg64(unsigned Val) const;
|
|
||||||
};
|
};
|
||||||
|
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<MCRelocationInfo> &&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
|
} // namespace llvm
|
||||||
|
|
||||||
#endif //LLVM_LIB_TARGET_AMDGPU_DISASSEMBLER_AMDGPUDISASSEMBLER_H
|
#endif //LLVM_LIB_TARGET_AMDGPU_DISASSEMBLER_AMDGPUDISASSEMBLER_H
|
||||||
|
|
|
@ -291,6 +291,7 @@ def SoppBrTarget : AsmOperandClass {
|
||||||
|
|
||||||
def sopp_brtarget : Operand<OtherVT> {
|
def sopp_brtarget : Operand<OtherVT> {
|
||||||
let EncoderMethod = "getSOPPBrEncoding";
|
let EncoderMethod = "getSOPPBrEncoding";
|
||||||
|
let DecoderMethod = "decodeSoppBrTarget";
|
||||||
let OperandType = "OPERAND_PCREL";
|
let OperandType = "OPERAND_PCREL";
|
||||||
let ParserMatchClass = SoppBrTarget;
|
let ParserMatchClass = SoppBrTarget;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,19 +6,19 @@ s_branch loop_start
|
||||||
// VI: s_branch loop_start ; encoding: [A,A,0x82,0xbf]
|
// VI: s_branch loop_start ; encoding: [A,A,0x82,0xbf]
|
||||||
// VI-NEXT: ; fixup A - offset: 0, value: loop_start, kind: fixup_si_sopp_br
|
// VI-NEXT: ; fixup A - offset: 0, value: loop_start, kind: fixup_si_sopp_br
|
||||||
// BIN: loop_start:
|
// BIN: loop_start:
|
||||||
// BIN-NEXT: BF82FFFF
|
// BIN-NEXT: s_branch loop_start // 000000000000: BF82FFFF
|
||||||
|
|
||||||
s_branch loop_end
|
s_branch loop_end
|
||||||
// VI: s_branch loop_end ; encoding: [A,A,0x82,0xbf]
|
// VI: s_branch loop_end ; encoding: [A,A,0x82,0xbf]
|
||||||
// VI-NEXT: ; fixup A - offset: 0, value: loop_end, kind: fixup_si_sopp_br
|
// 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:
|
// BIN: loop_end:
|
||||||
loop_end:
|
loop_end:
|
||||||
|
|
||||||
s_branch gds
|
s_branch gds
|
||||||
// VI: s_branch gds ; encoding: [A,A,0x82,0xbf]
|
// VI: s_branch gds ; encoding: [A,A,0x82,0xbf]
|
||||||
// VI-NEXT: ; fixup A - offset: 0, value: gds, kind: fixup_si_sopp_br
|
// VI-NEXT: ; fixup A - offset: 0, value: gds, kind: fixup_si_sopp_br
|
||||||
// BIN: BF820000
|
// BIN: s_branch gds // 000000000008: BF820000
|
||||||
// BIN: gds:
|
// BIN: gds:
|
||||||
gds:
|
gds:
|
||||||
s_nop 0
|
s_nop 0
|
||||||
|
|
|
@ -1097,8 +1097,10 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
|
||||||
std::unique_ptr<const MCInstrInfo> MII(TheTarget->createMCInstrInfo());
|
std::unique_ptr<const MCInstrInfo> MII(TheTarget->createMCInstrInfo());
|
||||||
if (!MII)
|
if (!MII)
|
||||||
report_fatal_error("error: no instruction info for target " + TripleName);
|
report_fatal_error("error: no instruction info for target " + TripleName);
|
||||||
std::unique_ptr<const MCObjectFileInfo> MOFI(new MCObjectFileInfo);
|
MCObjectFileInfo MOFI;
|
||||||
MCContext Ctx(AsmInfo.get(), MRI.get(), MOFI.get());
|
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<MCDisassembler> DisAsm(
|
std::unique_ptr<MCDisassembler> DisAsm(
|
||||||
TheTarget->createMCDisassembler(*STI, Ctx));
|
TheTarget->createMCDisassembler(*STI, Ctx));
|
||||||
|
@ -1229,6 +1231,18 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
|
||||||
std::sort(DataMappingSymsAddr.begin(), DataMappingSymsAddr.end());
|
std::sort(DataMappingSymsAddr.begin(), DataMappingSymsAddr.end());
|
||||||
std::sort(TextMappingSymsAddr.begin(), TextMappingSymsAddr.end());
|
std::sort(TextMappingSymsAddr.begin(), TextMappingSymsAddr.end());
|
||||||
|
|
||||||
|
if (Obj->isELF() && Obj->getArch() == Triple::amdgcn) {
|
||||||
|
// AMDGPU disassembler uses symbolizer for printing labels
|
||||||
|
std::unique_ptr<MCRelocationInfo> RelInfo(
|
||||||
|
TheTarget->createMCRelocationInfo(TripleName, Ctx));
|
||||||
|
if (RelInfo) {
|
||||||
|
std::unique_ptr<MCSymbolizer> 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.
|
// Make a list of all the relocations for this section.
|
||||||
std::vector<RelocationRef> Rels;
|
std::vector<RelocationRef> Rels;
|
||||||
if (InlineRelocs) {
|
if (InlineRelocs) {
|
||||||
|
|
Loading…
Reference in New Issue