#include "llvm/ADT/Triple.h"
#include "llvm/MC/MCCodeGenInfo.h"
#include "llvm/MC/MCELFStreamer.h"
+#include "llvm/MC/MCInstrAnalysis.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
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() {
for (Target *T : {&TheMipsTarget, &TheMipselTarget, &TheMips64Target,
&TheMips64elTarget}) {
// Register the MC subtarget info.
TargetRegistry::RegisterMCSubtargetInfo(*T, createMipsMCSubtargetInfo);
+ // Register the MC instruction analyzer.
+ TargetRegistry::RegisterMCInstrAnalysis(*T, createMipsMCInstrAnalysis);
+
// Register the MCInstPrinter.
TargetRegistry::RegisterMCInstPrinter(*T, createMipsMCInstPrinter);
--- /dev/null
+# 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