1 //===-- BPFSubtarget.cpp - BPF Subtarget Information ----------------------===// 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 implements the BPF specific subclass of TargetSubtargetInfo. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "BPFSubtarget.h" 14 #include "BPF.h" 15 #include "BPFTargetMachine.h" 16 #include "GISel/BPFCallLowering.h" 17 #include "GISel/BPFLegalizerInfo.h" 18 #include "GISel/BPFRegisterBankInfo.h" 19 #include "llvm/MC/TargetRegistry.h" 20 #include "llvm/TargetParser/Host.h" 21 22 using namespace llvm; 23 24 #define DEBUG_TYPE "bpf-subtarget" 25 26 #define GET_SUBTARGETINFO_TARGET_DESC 27 #define GET_SUBTARGETINFO_CTOR 28 #include "BPFGenSubtargetInfo.inc" 29 30 static cl::opt<bool> Disable_ldsx("disable-ldsx", cl::Hidden, cl::init(false), 31 cl::desc("Disable ldsx insns")); 32 static cl::opt<bool> Disable_movsx("disable-movsx", cl::Hidden, cl::init(false), 33 cl::desc("Disable movsx insns")); 34 static cl::opt<bool> Disable_bswap("disable-bswap", cl::Hidden, cl::init(false), 35 cl::desc("Disable bswap insns")); 36 static cl::opt<bool> Disable_sdiv_smod("disable-sdiv-smod", cl::Hidden, 37 cl::init(false), cl::desc("Disable sdiv/smod insns")); 38 static cl::opt<bool> Disable_gotol("disable-gotol", cl::Hidden, cl::init(false), 39 cl::desc("Disable gotol insn")); 40 static cl::opt<bool> 41 Disable_StoreImm("disable-storeimm", cl::Hidden, cl::init(false), 42 cl::desc("Disable BPF_ST (immediate store) insn")); 43 44 void BPFSubtarget::anchor() {} 45 46 BPFSubtarget &BPFSubtarget::initializeSubtargetDependencies(StringRef CPU, 47 StringRef FS) { 48 initializeEnvironment(); 49 initSubtargetFeatures(CPU, FS); 50 ParseSubtargetFeatures(CPU, /*TuneCPU*/ CPU, FS); 51 return *this; 52 } 53 54 void BPFSubtarget::initializeEnvironment() { 55 HasJmpExt = false; 56 HasJmp32 = false; 57 HasAlu32 = false; 58 UseDwarfRIS = false; 59 HasLdsx = false; 60 HasMovsx = false; 61 HasBswap = false; 62 HasSdivSmod = false; 63 HasGotol = false; 64 HasStoreImm = false; 65 } 66 67 void BPFSubtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) { 68 if (CPU == "probe") 69 CPU = sys::detail::getHostCPUNameForBPF(); 70 if (CPU == "generic" || CPU == "v1") 71 return; 72 if (CPU == "v2") { 73 HasJmpExt = true; 74 return; 75 } 76 if (CPU == "v3") { 77 HasJmpExt = true; 78 HasJmp32 = true; 79 HasAlu32 = true; 80 return; 81 } 82 if (CPU == "v4") { 83 HasJmpExt = true; 84 HasJmp32 = true; 85 HasAlu32 = true; 86 HasLdsx = !Disable_ldsx; 87 HasMovsx = !Disable_movsx; 88 HasBswap = !Disable_bswap; 89 HasSdivSmod = !Disable_sdiv_smod; 90 HasGotol = !Disable_gotol; 91 HasStoreImm = !Disable_StoreImm; 92 return; 93 } 94 } 95 96 BPFSubtarget::BPFSubtarget(const Triple &TT, const std::string &CPU, 97 const std::string &FS, const TargetMachine &TM) 98 : BPFGenSubtargetInfo(TT, CPU, /*TuneCPU*/ CPU, FS), 99 FrameLowering(initializeSubtargetDependencies(CPU, FS)), 100 TLInfo(TM, *this) { 101 IsLittleEndian = TT.isLittleEndian(); 102 103 CallLoweringInfo.reset(new BPFCallLowering(*getTargetLowering())); 104 Legalizer.reset(new BPFLegalizerInfo(*this)); 105 auto *RBI = new BPFRegisterBankInfo(*getRegisterInfo()); 106 RegBankInfo.reset(RBI); 107 108 InstSelector.reset(createBPFInstructionSelector( 109 *static_cast<const BPFTargetMachine *>(&TM), *this, *RBI)); 110 } 111 112 const CallLowering *BPFSubtarget::getCallLowering() const { 113 return CallLoweringInfo.get(); 114 } 115 116 InstructionSelector *BPFSubtarget::getInstructionSelector() const { 117 return InstSelector.get(); 118 } 119 120 const LegalizerInfo *BPFSubtarget::getLegalizerInfo() const { 121 return Legalizer.get(); 122 } 123 124 const RegisterBankInfo *BPFSubtarget::getRegBankInfo() const { 125 return RegBankInfo.get(); 126 } 127