1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 19:23:23 +01:00

[AMDGPU] Implement AMDGPUMCInstrAnalysis

Implement MCInstrAnalysis for AMDGPU, with default implementations save
for `evaluateBranch`.

Differential Revision: https://reviews.llvm.org/D58400

llvm-svn: 355373
This commit is contained in:
Scott Linder 2019-03-05 03:02:00 +00:00
parent 5012dbbadd
commit 7f3e1f67de
3 changed files with 75 additions and 0 deletions

View File

@ -76,6 +76,8 @@ static DecodeStatus decodeSoppBrTarget(MCInst &Inst, unsigned Imm,
uint64_t Addr, const void *Decoder) {
auto DAsm = static_cast<const AMDGPUDisassembler*>(Decoder);
// Our branches take a simm16, but we need two extra bits to account for the
// factor of 4.
APInt SignedOffset(18, Imm * 4, true);
int64_t Offset = (SignedOffset.sext(64) + 4 + Addr).getSExtValue();

View File

@ -20,6 +20,7 @@
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCInstrAnalysis.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCRegisterInfo.h"
@ -103,6 +104,35 @@ static MCStreamer *createMCStreamer(const Triple &T, MCContext &Context,
std::move(Emitter), RelaxAll);
}
namespace {
class AMDGPUMCInstrAnalysis : public MCInstrAnalysis {
public:
explicit AMDGPUMCInstrAnalysis(const MCInstrInfo *Info)
: MCInstrAnalysis(Info) {}
bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,
uint64_t &Target) const override {
if (Inst.getNumOperands() == 0 || !Inst.getOperand(0).isImm() ||
Info->get(Inst.getOpcode()).OpInfo[0].OperandType !=
MCOI::OPERAND_PCREL)
return false;
int64_t Imm = Inst.getOperand(0).getImm();
// Our branches take a simm16, but we need two extra bits to account for
// the factor of 4.
APInt SignedOffset(18, Imm * 4, true);
Target = (SignedOffset.sext(64) + Addr + Size).getZExtValue();
return true;
}
};
} // end anonymous namespace
static MCInstrAnalysis *createAMDGPUMCInstrAnalysis(const MCInstrInfo *Info) {
return new AMDGPUMCInstrAnalysis(Info);
}
extern "C" void LLVMInitializeAMDGPUTargetMC() {
TargetRegistry::RegisterMCInstrInfo(getTheGCNTarget(), createAMDGPUMCInstrInfo);
@ -113,6 +143,7 @@ extern "C" void LLVMInitializeAMDGPUTargetMC() {
TargetRegistry::RegisterMCRegInfo(*T, createAMDGPUMCRegisterInfo);
TargetRegistry::RegisterMCSubtargetInfo(*T, createAMDGPUMCSubtargetInfo);
TargetRegistry::RegisterMCInstPrinter(*T, createAMDGPUMCInstPrinter);
TargetRegistry::RegisterMCInstrAnalysis(*T, createAMDGPUMCInstrAnalysis);
TargetRegistry::RegisterMCAsmBackend(*T, createAMDGPUAsmBackend);
TargetRegistry::RegisterELFStreamer(*T, createMCStreamer);
}

View File

@ -0,0 +1,42 @@
// 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
// FIXME: Immediate operands to sopp_br instructions are currently scaled by a
// factor of 4, are unsigned, are always PC relative, don't accept most
// expressions, and are not range checked.
loop_start_nosym:
s_branch loop_start_nosym
// BIN-NOT: loop_start_nosym:
// BIN: s_branch 65535 // 000000000000: BF82FFFF <.text>
s_branch loop_end_nosym
// BIN: s_branch 0 // 000000000004: BF820000 <.text+0x8>
// BIN-NOT: loop_end_nosym:
loop_end_nosym:
s_nop 0
keep_symbol:
s_nop 0
loop_start_sym:
s_branch loop_start_sym
// BIN-NOT: loop_start_sym:
// BIN: s_branch 65535 // 000000000010: BF82FFFF <keep_symbol+0x4>
s_branch loop_end_sym
// BIN: s_branch 0 // 000000000014: BF820000 <keep_symbol+0xc>
// BIN-NOT: loop_end_sym:
loop_end_sym:
s_nop 0
s_branch 65535
// BIN: s_branch 65535 // 00000000001C: BF82FFFF <keep_symbol+0x10>
s_branch 32768
// BIN: s_branch 32768 // 000000000020: BF828000 <keep_symbol+0xfffffffffffe0018>
s_branch 32767
// BIN: s_branch 32767 // 000000000024: BF827FFF <keep_symbol+0x20018>
s_branch 0x80000000ffff
// BIN: s_branch 65535 // 000000000028: BF82FFFF <keep_symbol+0x1c>