mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-20 03:23:01 +02:00
[MC][mips] Add MipsMCInstrAnalysis class and register it as MC instruction analyzer
The `MipsMCInstrAnalysis` class overrides the `evaluateBranch` method and calculates target addresses for branch and calls instructions. That allows llvm-objdump to print functions' names in branch instructions in the disassemble mode. Differential Revision: http://reviews.llvm.org/D18209 llvm-svn: 264309
This commit is contained in:
parent
d336a67dfe
commit
64d083c81a
@ -20,6 +20,7 @@
|
|||||||
#include "llvm/ADT/Triple.h"
|
#include "llvm/ADT/Triple.h"
|
||||||
#include "llvm/MC/MCCodeGenInfo.h"
|
#include "llvm/MC/MCCodeGenInfo.h"
|
||||||
#include "llvm/MC/MCELFStreamer.h"
|
#include "llvm/MC/MCELFStreamer.h"
|
||||||
|
#include "llvm/MC/MCInstrAnalysis.h"
|
||||||
#include "llvm/MC/MCInstrInfo.h"
|
#include "llvm/MC/MCInstrInfo.h"
|
||||||
#include "llvm/MC/MCRegisterInfo.h"
|
#include "llvm/MC/MCRegisterInfo.h"
|
||||||
#include "llvm/MC/MCSubtargetInfo.h"
|
#include "llvm/MC/MCSubtargetInfo.h"
|
||||||
@ -129,6 +130,38 @@ createMipsObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) {
|
|||||||
return new MipsTargetELFStreamer(S, STI);
|
return new MipsTargetELFStreamer(S, STI);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class MipsMCInstrAnalysis : public MCInstrAnalysis {
|
||||||
|
public:
|
||||||
|
MipsMCInstrAnalysis(const MCInstrInfo *Info) : MCInstrAnalysis(Info) {}
|
||||||
|
|
||||||
|
bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,
|
||||||
|
uint64_t &Target) const override {
|
||||||
|
unsigned NumOps = Inst.getNumOperands();
|
||||||
|
if (NumOps == 0)
|
||||||
|
return false;
|
||||||
|
switch (Info->get(Inst.getOpcode()).OpInfo[NumOps - 1].OperandType) {
|
||||||
|
case MCOI::OPERAND_UNKNOWN:
|
||||||
|
case MCOI::OPERAND_IMMEDIATE:
|
||||||
|
// jal, bal ...
|
||||||
|
Target = Inst.getOperand(NumOps - 1).getImm();
|
||||||
|
return true;
|
||||||
|
case MCOI::OPERAND_PCREL:
|
||||||
|
// b, j, beq ...
|
||||||
|
Target = Addr + Inst.getOperand(NumOps - 1).getImm();
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static MCInstrAnalysis *createMipsMCInstrAnalysis(const MCInstrInfo *Info) {
|
||||||
|
return new MipsMCInstrAnalysis(Info);
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" void LLVMInitializeMipsTargetMC() {
|
extern "C" void LLVMInitializeMipsTargetMC() {
|
||||||
for (Target *T : {&TheMipsTarget, &TheMipselTarget, &TheMips64Target,
|
for (Target *T : {&TheMipsTarget, &TheMipselTarget, &TheMips64Target,
|
||||||
&TheMips64elTarget}) {
|
&TheMips64elTarget}) {
|
||||||
@ -156,6 +189,9 @@ extern "C" void LLVMInitializeMipsTargetMC() {
|
|||||||
// Register the MC subtarget info.
|
// Register the MC subtarget info.
|
||||||
TargetRegistry::RegisterMCSubtargetInfo(*T, createMipsMCSubtargetInfo);
|
TargetRegistry::RegisterMCSubtargetInfo(*T, createMipsMCSubtargetInfo);
|
||||||
|
|
||||||
|
// Register the MC instruction analyzer.
|
||||||
|
TargetRegistry::RegisterMCInstrAnalysis(*T, createMipsMCInstrAnalysis);
|
||||||
|
|
||||||
// Register the MCInstPrinter.
|
// Register the MCInstPrinter.
|
||||||
TargetRegistry::RegisterMCInstPrinter(*T, createMipsMCInstPrinter);
|
TargetRegistry::RegisterMCInstPrinter(*T, createMipsMCInstPrinter);
|
||||||
|
|
||||||
|
36
test/MC/Mips/instr-analysis.s
Normal file
36
test/MC/Mips/instr-analysis.s
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o - \
|
||||||
|
# RUN: | llvm-objdump -d - | FileCheck %s
|
||||||
|
|
||||||
|
# CHECK: foo:
|
||||||
|
# CHECK-NEXT: 0: 0c 00 00 02 jal 8 <loc1>
|
||||||
|
# CHECK-NEXT: 4: 00 00 00 00 nop
|
||||||
|
#
|
||||||
|
# CHECK: loc1:
|
||||||
|
# CHECK-NEXT: 8: 0c 00 00 06 jal 24 <loc3>
|
||||||
|
# CHECK-NEXT: c: 00 00 00 00 nop
|
||||||
|
#
|
||||||
|
# CHECK: loc2:
|
||||||
|
# CHECK-NEXT: 10: 10 00 ff fd b -8 <loc1>
|
||||||
|
# CHECK-NEXT: 14: 00 00 00 00 nop
|
||||||
|
#
|
||||||
|
# CHECK: loc3:
|
||||||
|
# CHECK-NEXT: 18: 10 43 ff fd beq $2, $3, -8 <loc2>
|
||||||
|
# CHECK-NEXT: 1c: 00 00 00 00 nop
|
||||||
|
# CHECK-NEXT: 20: 04 11 ff f9 bal -24 <loc1>
|
||||||
|
# CHECK-NEXT: 24: 00 00 00 00 nop
|
||||||
|
# CHECK-NEXT: 28: 08 00 00 04 j 16 <loc2>
|
||||||
|
|
||||||
|
.text
|
||||||
|
.globl foo
|
||||||
|
.ent foo
|
||||||
|
foo:
|
||||||
|
jal loc1
|
||||||
|
loc1:
|
||||||
|
jal loc3
|
||||||
|
loc2:
|
||||||
|
b loc1
|
||||||
|
loc3:
|
||||||
|
beq $2, $3, loc2
|
||||||
|
bal loc1
|
||||||
|
j loc2
|
||||||
|
.end foo
|
Loading…
Reference in New Issue
Block a user