brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.7 KiB · 27ab57c Raw
203 lines · cpp
1//===-- SparcTargetMachine.cpp - Define TargetMachine for Sparc -----------===//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-exception6//7//===----------------------------------------------------------------------===//8//9//10//===----------------------------------------------------------------------===//11 12#include "SparcTargetMachine.h"13#include "LeonPasses.h"14#include "Sparc.h"15#include "SparcMachineFunctionInfo.h"16#include "SparcTargetObjectFile.h"17#include "TargetInfo/SparcTargetInfo.h"18#include "llvm/CodeGen/Passes.h"19#include "llvm/CodeGen/TargetPassConfig.h"20#include "llvm/MC/TargetRegistry.h"21#include "llvm/Support/Compiler.h"22#include <optional>23using namespace llvm;24 25extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSparcTarget() {26  // Register the target.27  RegisterTargetMachine<SparcV8TargetMachine> X(getTheSparcTarget());28  RegisterTargetMachine<SparcV9TargetMachine> Y(getTheSparcV9Target());29  RegisterTargetMachine<SparcelTargetMachine> Z(getTheSparcelTarget());30 31  PassRegistry &PR = *PassRegistry::getPassRegistry();32  initializeSparcAsmPrinterPass(PR);33  initializeSparcDAGToDAGISelLegacyPass(PR);34  initializeErrataWorkaroundPass(PR);35}36 37static cl::opt<bool>38    BranchRelaxation("sparc-enable-branch-relax", cl::Hidden, cl::init(true),39                     cl::desc("Relax out of range conditional branches"));40 41static Reloc::Model getEffectiveRelocModel(std::optional<Reloc::Model> RM) {42  return RM.value_or(Reloc::Static);43}44 45// Code models. Some only make sense for 64-bit code.46//47// SunCC  Reloc   CodeModel  Constraints48// abs32  Static  Small      text+data+bss linked below 2^32 bytes49// abs44  Static  Medium     text+data+bss linked below 2^44 bytes50// abs64  Static  Large      text smaller than 2^31 bytes51// pic13  PIC_    Small      GOT < 2^13 bytes52// pic32  PIC_    Medium     GOT < 2^32 bytes53//54// All code models require that the text segment is smaller than 2GB.55static CodeModel::Model56getEffectiveSparcCodeModel(std::optional<CodeModel::Model> CM, Reloc::Model RM,57                           bool Is64Bit, bool JIT) {58  if (CM) {59    if (*CM == CodeModel::Tiny)60      report_fatal_error("Target does not support the tiny CodeModel", false);61    if (*CM == CodeModel::Kernel)62      report_fatal_error("Target does not support the kernel CodeModel", false);63    return *CM;64  }65  if (Is64Bit) {66    if (JIT)67      return CodeModel::Large;68    return RM == Reloc::PIC_ ? CodeModel::Small : CodeModel::Medium;69  }70  return CodeModel::Small;71}72 73/// Create an ILP32 architecture model74SparcTargetMachine::SparcTargetMachine(const Target &T, const Triple &TT,75                                       StringRef CPU, StringRef FS,76                                       const TargetOptions &Options,77                                       std::optional<Reloc::Model> RM,78                                       std::optional<CodeModel::Model> CM,79                                       CodeGenOptLevel OL, bool JIT)80    : CodeGenTargetMachineImpl(81          T, TT.computeDataLayout(), TT, CPU, FS, Options,82          getEffectiveRelocModel(RM),83          getEffectiveSparcCodeModel(CM, getEffectiveRelocModel(RM),84                                     TT.isSPARC64(), JIT),85          OL),86      TLOF(std::make_unique<SparcELFTargetObjectFile>()) {87  initAsmInfo();88}89 90SparcTargetMachine::~SparcTargetMachine() = default;91 92const SparcSubtarget *93SparcTargetMachine::getSubtargetImpl(const Function &F) const {94  Attribute CPUAttr = F.getFnAttribute("target-cpu");95  Attribute TuneAttr = F.getFnAttribute("tune-cpu");96  Attribute FSAttr = F.getFnAttribute("target-features");97 98  std::string CPU =99      CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU;100  std::string TuneCPU =101      TuneAttr.isValid() ? TuneAttr.getValueAsString().str() : CPU;102  std::string FS =103      FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS;104 105  // FIXME: This is related to the code below to reset the target options,106  // we need to know whether or not the soft float flag is set on the107  // function, so we can enable it as a subtarget feature.108  bool softFloat = F.getFnAttribute("use-soft-float").getValueAsBool();109 110  if (softFloat)111    FS += FS.empty() ? "+soft-float" : ",+soft-float";112 113  auto &I = SubtargetMap[CPU + FS];114  if (!I) {115    // This needs to be done before we create a new subtarget since any116    // creation will depend on the TM and the code generation flags on the117    // function that reside in TargetOptions.118    resetTargetOptions(F);119    I = std::make_unique<SparcSubtarget>(CPU, TuneCPU, FS, *this);120  }121  return I.get();122}123 124MachineFunctionInfo *SparcTargetMachine::createMachineFunctionInfo(125    BumpPtrAllocator &Allocator, const Function &F,126    const TargetSubtargetInfo *STI) const {127  return SparcMachineFunctionInfo::create<SparcMachineFunctionInfo>(Allocator,128                                                                    F, STI);129}130 131namespace {132/// Sparc Code Generator Pass Configuration Options.133class SparcPassConfig : public TargetPassConfig {134public:135  SparcPassConfig(SparcTargetMachine &TM, PassManagerBase &PM)136    : TargetPassConfig(TM, PM) {}137 138  SparcTargetMachine &getSparcTargetMachine() const {139    return getTM<SparcTargetMachine>();140  }141 142  void addIRPasses() override;143  bool addInstSelector() override;144  void addPreEmitPass() override;145};146} // namespace147 148TargetPassConfig *SparcTargetMachine::createPassConfig(PassManagerBase &PM) {149  return new SparcPassConfig(*this, PM);150}151 152void SparcPassConfig::addIRPasses() {153  addPass(createAtomicExpandLegacyPass());154 155  TargetPassConfig::addIRPasses();156}157 158bool SparcPassConfig::addInstSelector() {159  addPass(createSparcISelDag(getSparcTargetMachine()));160  return false;161}162 163void SparcPassConfig::addPreEmitPass(){164  if (BranchRelaxation)165    addPass(&BranchRelaxationPassID);166 167  addPass(createSparcDelaySlotFillerPass());168  addPass(new InsertNOPLoad());169  addPass(new DetectRoundChange());170  addPass(new FixAllFDIVSQRT());171  addPass(new ErrataWorkaround());172}173 174void SparcV8TargetMachine::anchor() { }175 176SparcV8TargetMachine::SparcV8TargetMachine(const Target &T, const Triple &TT,177                                           StringRef CPU, StringRef FS,178                                           const TargetOptions &Options,179                                           std::optional<Reloc::Model> RM,180                                           std::optional<CodeModel::Model> CM,181                                           CodeGenOptLevel OL, bool JIT)182    : SparcTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, JIT) {}183 184void SparcV9TargetMachine::anchor() { }185 186SparcV9TargetMachine::SparcV9TargetMachine(const Target &T, const Triple &TT,187                                           StringRef CPU, StringRef FS,188                                           const TargetOptions &Options,189                                           std::optional<Reloc::Model> RM,190                                           std::optional<CodeModel::Model> CM,191                                           CodeGenOptLevel OL, bool JIT)192    : SparcTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, JIT) {}193 194void SparcelTargetMachine::anchor() {}195 196SparcelTargetMachine::SparcelTargetMachine(const Target &T, const Triple &TT,197                                           StringRef CPU, StringRef FS,198                                           const TargetOptions &Options,199                                           std::optional<Reloc::Model> RM,200                                           std::optional<CodeModel::Model> CM,201                                           CodeGenOptLevel OL, bool JIT)202    : SparcTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, JIT) {}203