aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.cpp')
-rw-r--r--lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.cpp44
1 files changed, 40 insertions, 4 deletions
diff --git a/lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.cpp b/lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.cpp
index 797904e1c976..cbf1ea7d7fb8 100644
--- a/lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.cpp
+++ b/lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.cpp
@@ -15,6 +15,7 @@
#include "BPF.h"
#include "InstPrinter/BPFInstPrinter.h"
#include "MCTargetDesc/BPFMCAsmInfo.h"
+#include "llvm/MC/MCInstrAnalysis.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
@@ -49,11 +50,13 @@ static MCSubtargetInfo *createBPFMCSubtargetInfo(const Triple &TT,
return createBPFMCSubtargetInfoImpl(TT, CPU, FS);
}
-static MCStreamer *createBPFMCStreamer(const Triple &T,
- MCContext &Ctx, MCAsmBackend &MAB,
- raw_pwrite_stream &OS, MCCodeEmitter *Emitter,
+static MCStreamer *createBPFMCStreamer(const Triple &T, MCContext &Ctx,
+ std::unique_ptr<MCAsmBackend> &&MAB,
+ raw_pwrite_stream &OS,
+ std::unique_ptr<MCCodeEmitter> &&Emitter,
bool RelaxAll) {
- return createELFStreamer(Ctx, MAB, OS, Emitter, RelaxAll);
+ return createELFStreamer(Ctx, std::move(MAB), OS, std::move(Emitter),
+ RelaxAll);
}
static MCInstPrinter *createBPFMCInstPrinter(const Triple &T,
@@ -66,6 +69,35 @@ static MCInstPrinter *createBPFMCInstPrinter(const Triple &T,
return nullptr;
}
+namespace {
+
+class BPFMCInstrAnalysis : public MCInstrAnalysis {
+public:
+ explicit BPFMCInstrAnalysis(const MCInstrInfo *Info)
+ : MCInstrAnalysis(Info) {}
+
+ bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,
+ uint64_t &Target) const override {
+ // The target is the 3rd operand of cond inst and the 1st of uncond inst.
+ int16_t Imm;
+ if (isConditionalBranch(Inst)) {
+ Imm = Inst.getOperand(2).getImm();
+ } else if (isUnconditionalBranch(Inst))
+ Imm = Inst.getOperand(0).getImm();
+ else
+ return false;
+
+ Target = Addr + Size + Imm * Size;
+ return true;
+ }
+};
+
+} // end anonymous namespace
+
+static MCInstrAnalysis *createBPFInstrAnalysis(const MCInstrInfo *Info) {
+ return new BPFMCInstrAnalysis(Info);
+}
+
extern "C" void LLVMInitializeBPFTargetMC() {
for (Target *T :
{&getTheBPFleTarget(), &getTheBPFbeTarget(), &getTheBPFTarget()}) {
@@ -87,6 +119,9 @@ extern "C" void LLVMInitializeBPFTargetMC() {
// Register the MCInstPrinter.
TargetRegistry::RegisterMCInstPrinter(*T, createBPFMCInstPrinter);
+
+ // Register the MC instruction analyzer.
+ TargetRegistry::RegisterMCInstrAnalysis(*T, createBPFInstrAnalysis);
}
// Register the MC code emitter
@@ -112,4 +147,5 @@ extern "C" void LLVMInitializeBPFTargetMC() {
TargetRegistry::RegisterMCAsmBackend(getTheBPFTarget(),
createBPFbeAsmBackend);
}
+
}