LLVM  12.0.0git
SparcTargetMachine.cpp
Go to the documentation of this file.
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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 //
10 //===----------------------------------------------------------------------===//
11 
12 #include "SparcTargetMachine.h"
13 #include "LeonPasses.h"
14 #include "Sparc.h"
15 #include "SparcTargetObjectFile.h"
17 #include "llvm/CodeGen/Passes.h"
21 using namespace llvm;
22 
24  // Register the target.
28 }
29 
30 static std::string computeDataLayout(const Triple &T, bool is64Bit) {
31  // Sparc is typically big endian, but some are little.
32  std::string Ret = T.getArch() == Triple::sparcel ? "e" : "E";
33  Ret += "-m:e";
34 
35  // Some ABIs have 32bit pointers.
36  if (!is64Bit)
37  Ret += "-p:32:32";
38 
39  // Alignments for 64 bit integers.
40  Ret += "-i64:64";
41 
42  // On SparcV9 128 floats are aligned to 128 bits, on others only to 64.
43  // On SparcV9 registers can hold 64 or 32 bits, on others only 32.
44  if (is64Bit)
45  Ret += "-n32:64";
46  else
47  Ret += "-f128:64-n32";
48 
49  if (is64Bit)
50  Ret += "-S128";
51  else
52  Ret += "-S64";
53 
54  return Ret;
55 }
56 
58  return RM.getValueOr(Reloc::Static);
59 }
60 
61 // Code models. Some only make sense for 64-bit code.
62 //
63 // SunCC Reloc CodeModel Constraints
64 // abs32 Static Small text+data+bss linked below 2^32 bytes
65 // abs44 Static Medium text+data+bss linked below 2^44 bytes
66 // abs64 Static Large text smaller than 2^31 bytes
67 // pic13 PIC_ Small GOT < 2^13 bytes
68 // pic32 PIC_ Medium GOT < 2^32 bytes
69 //
70 // All code models require that the text segment is smaller than 2GB.
71 static CodeModel::Model
73  bool Is64Bit, bool JIT) {
74  if (CM) {
75  if (*CM == CodeModel::Tiny)
76  report_fatal_error("Target does not support the tiny CodeModel", false);
77  if (*CM == CodeModel::Kernel)
78  report_fatal_error("Target does not support the kernel CodeModel", false);
79  return *CM;
80  }
81  if (Is64Bit) {
82  if (JIT)
83  return CodeModel::Large;
85  }
86  return CodeModel::Small;
87 }
88 
89 /// Create an ILP32 architecture model
91  const Target &T, const Triple &TT, StringRef CPU, StringRef FS,
92  const TargetOptions &Options, Optional<Reloc::Model> RM,
93  Optional<CodeModel::Model> CM, CodeGenOpt::Level OL, bool JIT, bool is64bit)
94  : LLVMTargetMachine(T, computeDataLayout(TT, is64bit), TT, CPU, FS, Options,
97  CM, getEffectiveRelocModel(RM), is64bit, JIT),
98  OL),
99  TLOF(std::make_unique<SparcELFTargetObjectFile>()),
100  Subtarget(TT, std::string(CPU), std::string(FS), *this, is64bit),
101  is64Bit(is64bit) {
102  initAsmInfo();
103 }
104 
106 
107 const SparcSubtarget *
109  Attribute CPUAttr = F.getFnAttribute("target-cpu");
110  Attribute FSAttr = F.getFnAttribute("target-features");
111 
112  std::string CPU =
113  CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU;
114  std::string FS =
115  FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS;
116 
117  // FIXME: This is related to the code below to reset the target options,
118  // we need to know whether or not the soft float flag is set on the
119  // function, so we can enable it as a subtarget feature.
120  bool softFloat =
121  F.hasFnAttribute("use-soft-float") &&
122  F.getFnAttribute("use-soft-float").getValueAsString() == "true";
123 
124  if (softFloat)
125  FS += FS.empty() ? "+soft-float" : ",+soft-float";
126 
127  auto &I = SubtargetMap[CPU + FS];
128  if (!I) {
129  // This needs to be done before we create a new subtarget since any
130  // creation will depend on the TM and the code generation flags on the
131  // function that reside in TargetOptions.
133  I = std::make_unique<SparcSubtarget>(TargetTriple, CPU, FS, *this,
134  this->is64Bit);
135  }
136  return I.get();
137 }
138 
139 namespace {
140 /// Sparc Code Generator Pass Configuration Options.
141 class SparcPassConfig : public TargetPassConfig {
142 public:
143  SparcPassConfig(SparcTargetMachine &TM, PassManagerBase &PM)
144  : TargetPassConfig(TM, PM) {}
145 
146  SparcTargetMachine &getSparcTargetMachine() const {
147  return getTM<SparcTargetMachine>();
148  }
149 
150  void addIRPasses() override;
151  bool addInstSelector() override;
152  void addPreEmitPass() override;
153 };
154 } // namespace
155 
157  return new SparcPassConfig(*this, PM);
158 }
159 
160 void SparcPassConfig::addIRPasses() {
161  addPass(createAtomicExpandPass());
162 
164 }
165 
166 bool SparcPassConfig::addInstSelector() {
167  addPass(createSparcISelDag(getSparcTargetMachine()));
168  return false;
169 }
170 
171 void SparcPassConfig::addPreEmitPass(){
173 
174  if (this->getSparcTargetMachine().getSubtargetImpl()->insertNOPLoad())
175  {
176  addPass(new InsertNOPLoad());
177  }
178  if (this->getSparcTargetMachine().getSubtargetImpl()->detectRoundChange()) {
179  addPass(new DetectRoundChange());
180  }
181  if (this->getSparcTargetMachine().getSubtargetImpl()->fixAllFDIVSQRT())
182  {
183  addPass(new FixAllFDIVSQRT());
184  }
185 }
186 
187 void SparcV8TargetMachine::anchor() { }
188 
190  StringRef CPU, StringRef FS,
191  const TargetOptions &Options,
194  CodeGenOpt::Level OL, bool JIT)
195  : SparcTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, JIT, false) {}
196 
197 void SparcV9TargetMachine::anchor() { }
198 
200  StringRef CPU, StringRef FS,
201  const TargetOptions &Options,
204  CodeGenOpt::Level OL, bool JIT)
205  : SparcTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, JIT, true) {}
206 
207 void SparcelTargetMachine::anchor() {}
208 
210  StringRef CPU, StringRef FS,
211  const TargetOptions &Options,
214  CodeGenOpt::Level OL, bool JIT)
215  : SparcTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, JIT, false) {}
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:248
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:140
This class represents lattice values for constants.
Definition: AllocatorList.h:23
FunctionPass * createSparcDelaySlotFillerPass()
createSparcDelaySlotFillerPass - Returns a pass that fills in delay slots in Sparc MachineFunctions
virtual void addIRPasses()
Add common target configurable passes that perform LLVM IR to IR transforms following machine indepen...
Triple TargetTriple
Triple string, CPU name, and target feature strings the TargetMachine instance is created with.
Definition: TargetMachine.h:96
SparcelTargetMachine(const Target &T, const Triple &TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Optional< Reloc::Model > RM, Optional< CodeModel::Model > CM, CodeGenOpt::Level OL, bool JIT)
SparcV8TargetMachine(const Target &T, const Triple &TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Optional< Reloc::Model > RM, Optional< CodeModel::Model > CM, CodeGenOpt::Level OL, bool JIT)
const SparcSubtarget * getSubtargetImpl() const
F(f)
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
Definition: BitVector.h:941
void resetTargetOptions(const Function &F) const
Reset the target options based on the function's attributes.
Target-Independent Code Generator Pass Configuration Options.
RegisterTargetMachine - Helper template for registering a target machine implementation,...
Target & getTheSparcTarget()
static CodeModel::Model getEffectiveSparcCodeModel(Optional< CodeModel::Model > CM, Reloc::Model RM, bool Is64Bit, bool JIT)
bool isValid() const
Return true if the attribute is any kind of attribute.
Definition: Attributes.h:151
static Reloc::Model getEffectiveRelocModel(Optional< Reloc::Model > RM)
Target & getTheSparcelTarget()
This class describes a target machine that is implemented with the LLVM target-independent code gener...
FunctionPass * createSparcISelDag(SparcTargetMachine &TM)
createSparcISelDag - This pass converts a legalized DAG into a SPARC-specific DAG,...
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:45
PassManagerBase - An abstract interface to allow code to add passes to a pass manager without having ...
SparcTargetMachine(const Target &T, const Triple &TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Optional< Reloc::Model > RM, Optional< CodeModel::Model > CM, CodeGenOpt::Level OL, bool JIT, bool is64bit)
Create an ILP32 architecture model.
#define LLVM_EXTERNAL_VISIBILITY
Definition: Compiler.h:131
Target - Wrapper for Target specific information.
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSparcTarget()
std::string TargetCPU
Definition: TargetMachine.h:97
Target & getTheSparcV9Target()
static std::string computeDataLayout(const Triple &T, bool is64Bit)
basic Basic Alias true
StringRef getValueAsString() const
Return the attribute's value as a string.
Definition: Attributes.cpp:275
#define I(x, y, z)
Definition: MD5.cpp:59
std::string TargetFS
Definition: TargetMachine.h:98
TargetPassConfig * createPassConfig(PassManagerBase &PM) override
Create a pass configuration object to be used by addPassToEmitX methods for generating a pipeline of ...
SparcV9TargetMachine(const Target &T, const Triple &TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Optional< Reloc::Model > RM, Optional< CodeModel::Model > CM, CodeGenOpt::Level OL, bool JIT)
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
FunctionPass * createAtomicExpandPass()
static bool is64Bit(const char *name)