1 //===-- BPFMCTargetDesc.cpp - BPF Target Descriptions ---------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file provides BPF specific target descriptions. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "MCTargetDesc/BPFMCTargetDesc.h" 14 #include "MCTargetDesc/BPFInstPrinter.h" 15 #include "MCTargetDesc/BPFMCAsmInfo.h" 16 #include "TargetInfo/BPFTargetInfo.h" 17 #include "llvm/MC/MCInstrAnalysis.h" 18 #include "llvm/MC/MCInstrInfo.h" 19 #include "llvm/MC/MCRegisterInfo.h" 20 #include "llvm/MC/MCSubtargetInfo.h" 21 #include "llvm/Support/Host.h" 22 #include "llvm/Support/TargetRegistry.h" 23 24 #define GET_INSTRINFO_MC_DESC 25 #include "BPFGenInstrInfo.inc" 26 27 #define GET_SUBTARGETINFO_MC_DESC 28 #include "BPFGenSubtargetInfo.inc" 29 30 #define GET_REGINFO_MC_DESC 31 #include "BPFGenRegisterInfo.inc" 32 33 using namespace llvm; 34 35 static MCInstrInfo *createBPFMCInstrInfo() { 36 MCInstrInfo *X = new MCInstrInfo(); 37 InitBPFMCInstrInfo(X); 38 return X; 39 } 40 41 static MCRegisterInfo *createBPFMCRegisterInfo(const Triple &TT) { 42 MCRegisterInfo *X = new MCRegisterInfo(); 43 InitBPFMCRegisterInfo(X, BPF::R11 /* RAReg doesn't exist */); 44 return X; 45 } 46 47 static MCSubtargetInfo *createBPFMCSubtargetInfo(const Triple &TT, 48 StringRef CPU, StringRef FS) { 49 return createBPFMCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, FS); 50 } 51 52 static MCStreamer *createBPFMCStreamer(const Triple &T, MCContext &Ctx, 53 std::unique_ptr<MCAsmBackend> &&MAB, 54 std::unique_ptr<MCObjectWriter> &&OW, 55 std::unique_ptr<MCCodeEmitter> &&Emitter, 56 bool RelaxAll) { 57 return createELFStreamer(Ctx, std::move(MAB), std::move(OW), std::move(Emitter), 58 RelaxAll); 59 } 60 61 static MCInstPrinter *createBPFMCInstPrinter(const Triple &T, 62 unsigned SyntaxVariant, 63 const MCAsmInfo &MAI, 64 const MCInstrInfo &MII, 65 const MCRegisterInfo &MRI) { 66 if (SyntaxVariant == 0) 67 return new BPFInstPrinter(MAI, MII, MRI); 68 return nullptr; 69 } 70 71 namespace { 72 73 class BPFMCInstrAnalysis : public MCInstrAnalysis { 74 public: 75 explicit BPFMCInstrAnalysis(const MCInstrInfo *Info) 76 : MCInstrAnalysis(Info) {} 77 78 bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size, 79 uint64_t &Target) const override { 80 // The target is the 3rd operand of cond inst and the 1st of uncond inst. 81 int16_t Imm; 82 if (isConditionalBranch(Inst)) { 83 Imm = Inst.getOperand(2).getImm(); 84 } else if (isUnconditionalBranch(Inst)) 85 Imm = Inst.getOperand(0).getImm(); 86 else 87 return false; 88 89 Target = Addr + Size + Imm * Size; 90 return true; 91 } 92 }; 93 94 } // end anonymous namespace 95 96 static MCInstrAnalysis *createBPFInstrAnalysis(const MCInstrInfo *Info) { 97 return new BPFMCInstrAnalysis(Info); 98 } 99 100 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeBPFTargetMC() { 101 for (Target *T : 102 {&getTheBPFleTarget(), &getTheBPFbeTarget(), &getTheBPFTarget()}) { 103 // Register the MC asm info. 104 RegisterMCAsmInfo<BPFMCAsmInfo> X(*T); 105 106 // Register the MC instruction info. 107 TargetRegistry::RegisterMCInstrInfo(*T, createBPFMCInstrInfo); 108 109 // Register the MC register info. 110 TargetRegistry::RegisterMCRegInfo(*T, createBPFMCRegisterInfo); 111 112 // Register the MC subtarget info. 113 TargetRegistry::RegisterMCSubtargetInfo(*T, 114 createBPFMCSubtargetInfo); 115 116 // Register the object streamer 117 TargetRegistry::RegisterELFStreamer(*T, createBPFMCStreamer); 118 119 // Register the MCInstPrinter. 120 TargetRegistry::RegisterMCInstPrinter(*T, createBPFMCInstPrinter); 121 122 // Register the MC instruction analyzer. 123 TargetRegistry::RegisterMCInstrAnalysis(*T, createBPFInstrAnalysis); 124 } 125 126 // Register the MC code emitter 127 TargetRegistry::RegisterMCCodeEmitter(getTheBPFleTarget(), 128 createBPFMCCodeEmitter); 129 TargetRegistry::RegisterMCCodeEmitter(getTheBPFbeTarget(), 130 createBPFbeMCCodeEmitter); 131 132 // Register the ASM Backend 133 TargetRegistry::RegisterMCAsmBackend(getTheBPFleTarget(), 134 createBPFAsmBackend); 135 TargetRegistry::RegisterMCAsmBackend(getTheBPFbeTarget(), 136 createBPFbeAsmBackend); 137 138 if (sys::IsLittleEndianHost) { 139 TargetRegistry::RegisterMCCodeEmitter(getTheBPFTarget(), 140 createBPFMCCodeEmitter); 141 TargetRegistry::RegisterMCAsmBackend(getTheBPFTarget(), 142 createBPFAsmBackend); 143 } else { 144 TargetRegistry::RegisterMCCodeEmitter(getTheBPFTarget(), 145 createBPFbeMCCodeEmitter); 146 TargetRegistry::RegisterMCAsmBackend(getTheBPFTarget(), 147 createBPFbeAsmBackend); 148 } 149 150 } 151