Skip to content

Commit efec139

Browse files
committed
[AMDGPU] Implement AMDGPUMCInstrAnalysis
Implement MCInstrAnalysis for AMDGPU, with default implementations save for `evaluateBranch`. Differential Revision: https://reviews.llvm.org/D58400 llvm-svn: 355373
1 parent 3d7e9c8 commit efec139

File tree

3 files changed

+75
-0
lines changed

3 files changed

+75
-0
lines changed

llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ static DecodeStatus decodeSoppBrTarget(MCInst &Inst, unsigned Imm,
7676
uint64_t Addr, const void *Decoder) {
7777
auto DAsm = static_cast<const AMDGPUDisassembler*>(Decoder);
7878

79+
// Our branches take a simm16, but we need two extra bits to account for the
80+
// factor of 4.
7981
APInt SignedOffset(18, Imm * 4, true);
8082
int64_t Offset = (SignedOffset.sext(64) + 4 + Addr).getSExtValue();
8183

llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "llvm/MC/MCAsmBackend.h"
2121
#include "llvm/MC/MCCodeEmitter.h"
2222
#include "llvm/MC/MCContext.h"
23+
#include "llvm/MC/MCInstrAnalysis.h"
2324
#include "llvm/MC/MCInstrInfo.h"
2425
#include "llvm/MC/MCObjectWriter.h"
2526
#include "llvm/MC/MCRegisterInfo.h"
@@ -103,6 +104,35 @@ static MCStreamer *createMCStreamer(const Triple &T, MCContext &Context,
103104
std::move(Emitter), RelaxAll);
104105
}
105106

107+
namespace {
108+
109+
class AMDGPUMCInstrAnalysis : public MCInstrAnalysis {
110+
public:
111+
explicit AMDGPUMCInstrAnalysis(const MCInstrInfo *Info)
112+
: MCInstrAnalysis(Info) {}
113+
114+
bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,
115+
uint64_t &Target) const override {
116+
if (Inst.getNumOperands() == 0 || !Inst.getOperand(0).isImm() ||
117+
Info->get(Inst.getOpcode()).OpInfo[0].OperandType !=
118+
MCOI::OPERAND_PCREL)
119+
return false;
120+
121+
int64_t Imm = Inst.getOperand(0).getImm();
122+
// Our branches take a simm16, but we need two extra bits to account for
123+
// the factor of 4.
124+
APInt SignedOffset(18, Imm * 4, true);
125+
Target = (SignedOffset.sext(64) + Addr + Size).getZExtValue();
126+
return true;
127+
}
128+
};
129+
130+
} // end anonymous namespace
131+
132+
static MCInstrAnalysis *createAMDGPUMCInstrAnalysis(const MCInstrInfo *Info) {
133+
return new AMDGPUMCInstrAnalysis(Info);
134+
}
135+
106136
extern "C" void LLVMInitializeAMDGPUTargetMC() {
107137

108138
TargetRegistry::RegisterMCInstrInfo(getTheGCNTarget(), createAMDGPUMCInstrInfo);
@@ -113,6 +143,7 @@ extern "C" void LLVMInitializeAMDGPUTargetMC() {
113143
TargetRegistry::RegisterMCRegInfo(*T, createAMDGPUMCRegisterInfo);
114144
TargetRegistry::RegisterMCSubtargetInfo(*T, createAMDGPUMCSubtargetInfo);
115145
TargetRegistry::RegisterMCInstPrinter(*T, createAMDGPUMCInstPrinter);
146+
TargetRegistry::RegisterMCInstrAnalysis(*T, createAMDGPUMCInstrAnalysis);
116147
TargetRegistry::RegisterMCAsmBackend(*T, createAMDGPUAsmBackend);
117148
TargetRegistry::RegisterELFStreamer(*T, createMCStreamer);
118149
}

llvm/test/MC/AMDGPU/branch-comment.s

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// RUN: llvm-mc -arch=amdgcn -mcpu=fiji -filetype=obj %s | llvm-objcopy -S -K keep_symbol - | llvm-objdump -disassemble -mcpu=fiji - | FileCheck %s --check-prefix=BIN
2+
3+
// FIXME: Immediate operands to sopp_br instructions are currently scaled by a
4+
// factor of 4, are unsigned, are always PC relative, don't accept most
5+
// expressions, and are not range checked.
6+
7+
loop_start_nosym:
8+
s_branch loop_start_nosym
9+
// BIN-NOT: loop_start_nosym:
10+
// BIN: s_branch 65535 // 000000000000: BF82FFFF <.text>
11+
12+
s_branch loop_end_nosym
13+
// BIN: s_branch 0 // 000000000004: BF820000 <.text+0x8>
14+
// BIN-NOT: loop_end_nosym:
15+
loop_end_nosym:
16+
s_nop 0
17+
18+
keep_symbol:
19+
s_nop 0
20+
21+
loop_start_sym:
22+
s_branch loop_start_sym
23+
// BIN-NOT: loop_start_sym:
24+
// BIN: s_branch 65535 // 000000000010: BF82FFFF <keep_symbol+0x4>
25+
26+
s_branch loop_end_sym
27+
// BIN: s_branch 0 // 000000000014: BF820000 <keep_symbol+0xc>
28+
// BIN-NOT: loop_end_sym:
29+
loop_end_sym:
30+
s_nop 0
31+
32+
s_branch 65535
33+
// BIN: s_branch 65535 // 00000000001C: BF82FFFF <keep_symbol+0x10>
34+
35+
s_branch 32768
36+
// BIN: s_branch 32768 // 000000000020: BF828000 <keep_symbol+0xfffffffffffe0018>
37+
38+
s_branch 32767
39+
// BIN: s_branch 32767 // 000000000024: BF827FFF <keep_symbol+0x20018>
40+
41+
s_branch 0x80000000ffff
42+
// BIN: s_branch 65535 // 000000000028: BF82FFFF <keep_symbol+0x1c>

0 commit comments

Comments
 (0)