Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit 6c6dbe6

Browse files
committed
[AMDGPU] Disassembler: print label names in branch instructions
Summary: Add AMDGPUSymbolizer for finding names for labels from ELF symbol table. Reviewers: vpykhtin, artem.tamazov, tstellarAMD Subscribers: arsenm, kzhuravl, wdng, nhaehnle, yaxunl, tony-tye Differential Revision: https://reviews.llvm.org/D24802 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@282394 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent ba54dc2 commit 6c6dbe6

File tree

5 files changed

+171
-69
lines changed

5 files changed

+171
-69
lines changed

lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "llvm/MC/MCInst.h"
2929
#include "llvm/MC/MCInstrDesc.h"
3030
#include "llvm/MC/MCSubtargetInfo.h"
31+
#include "llvm/Support/ELF.h"
3132
#include "llvm/Support/Endian.h"
3233
#include "llvm/Support/Debug.h"
3334
#include "llvm/Support/TargetRegistry.h"
@@ -48,6 +49,18 @@ addOperand(MCInst &Inst, const MCOperand& Opnd) {
4849
MCDisassembler::SoftFail;
4950
}
5051

52+
static DecodeStatus decodeSoppBrTarget(MCInst &Inst, unsigned Imm,
53+
uint64_t Addr, const void *Decoder) {
54+
auto DAsm = static_cast<const AMDGPUDisassembler*>(Decoder);
55+
56+
APInt SignedOffset(18, Imm * 4, true);
57+
int64_t Offset = (SignedOffset.sext(64) + 4 + Addr).getSExtValue();
58+
59+
if (DAsm->tryAddingSymbolicOperand(Inst, Offset, Addr, true, 2, 2))
60+
return MCDisassembler::Success;
61+
return addOperand(Inst, MCOperand::createImm(Imm));
62+
}
63+
5164
#define DECODE_OPERAND2(RegClass, DecName) \
5265
static DecodeStatus Decode##RegClass##RegisterClass(MCInst &Inst, \
5366
unsigned Imm, \
@@ -431,6 +444,50 @@ MCOperand AMDGPUDisassembler::decodeSpecialReg64(unsigned Val) const {
431444
return errOperand(Val, "unknown operand encoding " + Twine(Val));
432445
}
433446

447+
//===----------------------------------------------------------------------===//
448+
// AMDGPUSymbolizer
449+
//===----------------------------------------------------------------------===//
450+
451+
// Try to find symbol name for specified label
452+
bool AMDGPUSymbolizer::tryAddingSymbolicOperand(MCInst &Inst,
453+
raw_ostream &/*cStream*/, int64_t Value,
454+
uint64_t /*Address*/, bool IsBranch,
455+
uint64_t /*Offset*/, uint64_t /*InstSize*/) {
456+
typedef std::tuple<uint64_t, StringRef, uint8_t> SymbolInfoTy;
457+
typedef std::vector<SymbolInfoTy> SectionSymbolsTy;
458+
459+
if (!IsBranch) {
460+
return false;
461+
}
462+
463+
auto *Symbols = static_cast<SectionSymbolsTy *>(DisInfo);
464+
auto Result = std::find_if(Symbols->begin(), Symbols->end(),
465+
[Value](const SymbolInfoTy& Val) {
466+
return std::get<0>(Val) == static_cast<uint64_t>(Value)
467+
&& std::get<2>(Val) == ELF::STT_NOTYPE;
468+
});
469+
if (Result != Symbols->end()) {
470+
auto *Sym = Ctx.getOrCreateSymbol(std::get<1>(*Result));
471+
const auto *Add = MCSymbolRefExpr::create(Sym, Ctx);
472+
Inst.addOperand(MCOperand::createExpr(Add));
473+
return true;
474+
}
475+
return false;
476+
}
477+
478+
//===----------------------------------------------------------------------===//
479+
// Initialization
480+
//===----------------------------------------------------------------------===//
481+
482+
static MCSymbolizer *createAMDGPUSymbolizer(const Triple &/*TT*/,
483+
LLVMOpInfoCallback /*GetOpInfo*/,
484+
LLVMSymbolLookupCallback /*SymbolLookUp*/,
485+
void *DisInfo,
486+
MCContext *Ctx,
487+
std::unique_ptr<MCRelocationInfo> &&RelInfo) {
488+
return new AMDGPUSymbolizer(*Ctx, std::move(RelInfo), DisInfo);
489+
}
490+
434491
static MCDisassembler *createAMDGPUDisassembler(const Target &T,
435492
const MCSubtargetInfo &STI,
436493
MCContext &Ctx) {
@@ -439,4 +496,5 @@ static MCDisassembler *createAMDGPUDisassembler(const Target &T,
439496

440497
extern "C" void LLVMInitializeAMDGPUDisassembler() {
441498
TargetRegistry::RegisterMCDisassembler(TheGCNTarget, createAMDGPUDisassembler);
499+
TargetRegistry::RegisterMCSymbolizer(TheGCNTarget, createAMDGPUSymbolizer);
442500
}

lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h

Lines changed: 97 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -18,76 +18,107 @@
1818

1919
#include "llvm/ADT/ArrayRef.h"
2020
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
21+
#include "llvm/MC/MCDisassembler/MCSymbolizer.h"
2122

2223
namespace llvm {
2324

24-
class MCContext;
25-
class MCInst;
26-
class MCOperand;
27-
class MCSubtargetInfo;
28-
class Twine;
29-
30-
class AMDGPUDisassembler : public MCDisassembler {
31-
private:
32-
mutable ArrayRef<uint8_t> Bytes;
33-
34-
public:
35-
AMDGPUDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) :
36-
MCDisassembler(STI, Ctx) {}
37-
38-
~AMDGPUDisassembler() {}
39-
40-
DecodeStatus getInstruction(MCInst &MI, uint64_t &Size,
41-
ArrayRef<uint8_t> Bytes, uint64_t Address,
42-
raw_ostream &WS, raw_ostream &CS) const override;
43-
44-
const char* getRegClassName(unsigned RegClassID) const;
45-
46-
MCOperand createRegOperand(unsigned int RegId) const;
47-
MCOperand createRegOperand(unsigned RegClassID, unsigned Val) const;
48-
MCOperand createSRegOperand(unsigned SRegClassID, unsigned Val) const;
49-
50-
MCOperand errOperand(unsigned V, const llvm::Twine& ErrMsg) const;
51-
52-
DecodeStatus tryDecodeInst(const uint8_t* Table,
53-
MCInst &MI,
54-
uint64_t Inst,
55-
uint64_t Address) const;
56-
57-
MCOperand decodeOperand_VGPR_32(unsigned Val) const;
58-
MCOperand decodeOperand_VS_32(unsigned Val) const;
59-
MCOperand decodeOperand_VS_64(unsigned Val) const;
60-
61-
MCOperand decodeOperand_VReg_64(unsigned Val) const;
62-
MCOperand decodeOperand_VReg_96(unsigned Val) const;
63-
MCOperand decodeOperand_VReg_128(unsigned Val) const;
64-
65-
MCOperand decodeOperand_SReg_32(unsigned Val) const;
66-
MCOperand decodeOperand_SReg_32_XM0(unsigned Val) const;
67-
MCOperand decodeOperand_SReg_64(unsigned Val) const;
68-
MCOperand decodeOperand_SReg_128(unsigned Val) const;
69-
MCOperand decodeOperand_SReg_256(unsigned Val) const;
70-
MCOperand decodeOperand_SReg_512(unsigned Val) const;
71-
72-
enum OpWidthTy {
73-
OPW32,
74-
OPW64,
75-
OPW128,
76-
OPW_LAST_,
77-
OPW_FIRST_ = OPW32
78-
};
79-
unsigned getVgprClassId(const OpWidthTy Width) const;
80-
unsigned getSgprClassId(const OpWidthTy Width) const;
81-
unsigned getTtmpClassId(const OpWidthTy Width) const;
82-
83-
static MCOperand decodeIntImmed(unsigned Imm);
84-
static MCOperand decodeFPImmed(bool Is32, unsigned Imm);
85-
MCOperand decodeLiteralConstant() const;
86-
87-
MCOperand decodeSrcOp(const OpWidthTy Width, unsigned Val) const;
88-
MCOperand decodeSpecialReg32(unsigned Val) const;
89-
MCOperand decodeSpecialReg64(unsigned Val) const;
25+
class MCContext;
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+
mutable ArrayRef<uint8_t> Bytes;
38+
39+
public:
40+
AMDGPUDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) :
41+
MCDisassembler(STI, Ctx) {}
42+
43+
~AMDGPUDisassembler() {}
44+
45+
DecodeStatus getInstruction(MCInst &MI, uint64_t &Size,
46+
ArrayRef<uint8_t> Bytes, uint64_t Address,
47+
raw_ostream &WS, raw_ostream &CS) const override;
48+
49+
const char* getRegClassName(unsigned RegClassID) const;
50+
51+
MCOperand createRegOperand(unsigned int RegId) const;
52+
MCOperand createRegOperand(unsigned RegClassID, unsigned Val) const;
53+
MCOperand createSRegOperand(unsigned SRegClassID, unsigned Val) const;
54+
55+
MCOperand errOperand(unsigned V, const llvm::Twine& ErrMsg) const;
56+
57+
DecodeStatus tryDecodeInst(const uint8_t* Table,
58+
MCInst &MI,
59+
uint64_t Inst,
60+
uint64_t Address) const;
61+
62+
MCOperand decodeOperand_VGPR_32(unsigned Val) const;
63+
MCOperand decodeOperand_VS_32(unsigned Val) const;
64+
MCOperand decodeOperand_VS_64(unsigned Val) const;
65+
66+
MCOperand decodeOperand_VReg_64(unsigned Val) const;
67+
MCOperand decodeOperand_VReg_96(unsigned Val) const;
68+
MCOperand decodeOperand_VReg_128(unsigned Val) const;
69+
70+
MCOperand decodeOperand_SReg_32(unsigned Val) const;
71+
MCOperand decodeOperand_SReg_32_XM0(unsigned Val) const;
72+
MCOperand decodeOperand_SReg_64(unsigned Val) const;
73+
MCOperand decodeOperand_SReg_128(unsigned Val) const;
74+
MCOperand decodeOperand_SReg_256(unsigned Val) const;
75+
MCOperand decodeOperand_SReg_512(unsigned Val) const;
76+
77+
enum OpWidthTy {
78+
OPW32,
79+
OPW64,
80+
OPW128,
81+
OPW_LAST_,
82+
OPW_FIRST_ = OPW32
9083
};
84+
unsigned getVgprClassId(const OpWidthTy Width) const;
85+
unsigned getSgprClassId(const OpWidthTy Width) const;
86+
unsigned getTtmpClassId(const OpWidthTy Width) const;
87+
88+
static MCOperand decodeIntImmed(unsigned Imm);
89+
static MCOperand decodeFPImmed(bool Is32, unsigned Imm);
90+
MCOperand decodeLiteralConstant() const;
91+
92+
MCOperand decodeSrcOp(const OpWidthTy Width, unsigned Val) const;
93+
MCOperand decodeSpecialReg32(unsigned Val) const;
94+
MCOperand decodeSpecialReg64(unsigned Val) const;
95+
};
96+
97+
//===----------------------------------------------------------------------===//
98+
// AMDGPUSymbolizer
99+
//===----------------------------------------------------------------------===//
100+
101+
class AMDGPUSymbolizer : public MCSymbolizer {
102+
private:
103+
void *DisInfo;
104+
105+
public:
106+
AMDGPUSymbolizer(MCContext &Ctx, std::unique_ptr<MCRelocationInfo> &&RelInfo,
107+
void *disInfo)
108+
: MCSymbolizer(Ctx, std::move(RelInfo)), DisInfo(disInfo) {}
109+
110+
bool tryAddingSymbolicOperand(MCInst &Inst, raw_ostream &cStream,
111+
int64_t Value, uint64_t Address,
112+
bool IsBranch, uint64_t Offset,
113+
uint64_t InstSize) override;
114+
115+
void tryAddingPcLoadReferenceComment(raw_ostream &cStream,
116+
int64_t Value,
117+
uint64_t Address) override {
118+
assert(false && "Implement if needed");
119+
}
120+
};
121+
91122
} // namespace llvm
92123

93124
#endif //LLVM_LIB_TARGET_AMDGPU_DISASSEMBLER_AMDGPUDISASSEMBLER_H

lib/Target/AMDGPU/SIInstrInfo.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,7 @@ def SoppBrTarget : AsmOperandClass {
291291

292292
def sopp_brtarget : Operand<OtherVT> {
293293
let EncoderMethod = "getSOPPBrEncoding";
294+
let DecoderMethod = "decodeSoppBrTarget";
294295
let OperandType = "OPERAND_PCREL";
295296
let ParserMatchClass = SoppBrTarget;
296297
}

test/MC/AMDGPU/labels-branch.s

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,19 @@ s_branch loop_start
66
// VI: s_branch loop_start ; encoding: [A,A,0x82,0xbf]
77
// VI-NEXT: ; fixup A - offset: 0, value: loop_start, kind: fixup_si_sopp_br
88
// BIN: loop_start:
9-
// BIN-NEXT: BF82FFFF
9+
// BIN-NEXT: s_branch loop_start // 000000000000: BF82FFFF
1010

1111
s_branch loop_end
1212
// VI: s_branch loop_end ; encoding: [A,A,0x82,0xbf]
1313
// VI-NEXT: ; fixup A - offset: 0, value: loop_end, kind: fixup_si_sopp_br
14-
// BIN: BF820000
14+
// BIN: s_branch loop_end // 000000000004: BF820000
1515
// BIN: loop_end:
1616
loop_end:
1717

1818
s_branch gds
1919
// VI: s_branch gds ; encoding: [A,A,0x82,0xbf]
2020
// VI-NEXT: ; fixup A - offset: 0, value: gds, kind: fixup_si_sopp_br
21-
// BIN: BF820000
21+
// BIN: s_branch gds // 000000000008: BF820000
2222
// BIN: gds:
2323
gds:
2424
s_nop 0

tools/llvm-objdump/llvm-objdump.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1228,6 +1228,18 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
12281228
std::sort(DataMappingSymsAddr.begin(), DataMappingSymsAddr.end());
12291229
std::sort(TextMappingSymsAddr.begin(), TextMappingSymsAddr.end());
12301230

1231+
if (Obj->isELF() && Obj->getArch() == Triple::amdgcn) {
1232+
// AMDGPU disassembler uses symbolizer for printing labels
1233+
std::unique_ptr<MCRelocationInfo> RelInfo(
1234+
TheTarget->createMCRelocationInfo(TripleName, Ctx));
1235+
if (RelInfo) {
1236+
std::unique_ptr<MCSymbolizer> Symbolizer(
1237+
TheTarget->createMCSymbolizer(
1238+
TripleName, nullptr, nullptr, &Symbols, &Ctx, std::move(RelInfo)));
1239+
DisAsm->setSymbolizer(std::move(Symbolizer));
1240+
}
1241+
}
1242+
12311243
// Make a list of all the relocations for this section.
12321244
std::vector<RelocationRef> Rels;
12331245
if (InlineRelocs) {

0 commit comments

Comments
 (0)