blob: 5b467235f809d20743692fc1d81b577d9e3e70d5 [file] [log] [blame]
Chris Lattner158e1f52006-02-05 05:50:24 +00001//===-- SparcTargetMachine.cpp - Define TargetMachine for Sparc -----------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattnerf3ebc3f2007-12-29 20:36:04 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Chris Lattner158e1f52006-02-05 05:50:24 +00007//
8//===----------------------------------------------------------------------===//
9//
10//
11//===----------------------------------------------------------------------===//
12
13#include "SparcTargetMachine.h"
Chris Dewhurst4f7cac32016-05-23 10:56:36 +000014#include "LeonPasses.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000015#include "Sparc.h"
16#include "SparcTargetObjectFile.h"
Andrew Trickccb67362012-02-03 05:12:41 +000017#include "llvm/CodeGen/Passes.h"
Matthias Braun31d19d42016-05-10 03:21:59 +000018#include "llvm/CodeGen/TargetPassConfig.h"
Chandler Carruth30d69c22015-02-13 10:01:29 +000019#include "llvm/IR/LegacyPassManager.h"
Evan Cheng2bb40352011-08-24 18:08:43 +000020#include "llvm/Support/TargetRegistry.h"
Chris Lattner158e1f52006-02-05 05:50:24 +000021using namespace llvm;
22
Daniel Dunbar5680b4f2009-07-25 06:49:55 +000023extern "C" void LLVMInitializeSparcTarget() {
24 // Register the target.
Mehdi Aminif42454b2016-10-09 23:00:34 +000025 RegisterTargetMachine<SparcV8TargetMachine> X(getTheSparcTarget());
26 RegisterTargetMachine<SparcV9TargetMachine> Y(getTheSparcV9Target());
27 RegisterTargetMachine<SparcelTargetMachine> Z(getTheSparcelTarget());
Jim Laskeyae92ce82006-09-07 23:39:26 +000028}
29
Douglas Katzman9160e782015-04-29 20:30:57 +000030static 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";
Eric Christopher8b770652015-01-26 19:03:15 +000034
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
Rafael Espindola8c34dd82016-05-18 22:04:49 +000057static Reloc::Model getEffectiveRelocModel(Optional<Reloc::Model> RM) {
58 if (!RM.hasValue())
59 return Reloc::Static;
60 return *RM;
61}
62
Rafael Espindola79e238a2017-08-03 02:16:21 +000063// Code models. Some only make sense for 64-bit code.
64//
65// SunCC Reloc CodeModel Constraints
66// abs32 Static Small text+data+bss linked below 2^32 bytes
67// abs44 Static Medium text+data+bss linked below 2^44 bytes
68// abs64 Static Large text smaller than 2^31 bytes
69// pic13 PIC_ Small GOT < 2^13 bytes
70// pic32 PIC_ Medium GOT < 2^32 bytes
71//
72// All code models require that the text segment is smaller than 2GB.
David Greenca29c272018-12-07 12:10:23 +000073static CodeModel::Model
74getEffectiveSparcCodeModel(Optional<CodeModel::Model> CM, Reloc::Model RM,
75 bool Is64Bit, bool JIT) {
76 if (CM) {
77 if (*CM == CodeModel::Tiny)
78 report_fatal_error("Target does not support the tiny CodeModel");
79 if (*CM == CodeModel::Kernel)
80 report_fatal_error("Target does not support the kernel CodeModel");
Rafael Espindola79e238a2017-08-03 02:16:21 +000081 return *CM;
David Greenca29c272018-12-07 12:10:23 +000082 }
Rafael Espindola79e238a2017-08-03 02:16:21 +000083 if (Is64Bit) {
84 if (JIT)
85 return CodeModel::Large;
86 return RM == Reloc::PIC_ ? CodeModel::Small : CodeModel::Medium;
87 }
88 return CodeModel::Small;
89}
90
Rafael Espindola38af4d62016-05-18 16:00:24 +000091/// Create an ILP32 architecture model
Rafael Espindola79e238a2017-08-03 02:16:21 +000092SparcTargetMachine::SparcTargetMachine(
93 const Target &T, const Triple &TT, StringRef CPU, StringRef FS,
94 const TargetOptions &Options, Optional<Reloc::Model> RM,
95 Optional<CodeModel::Model> CM, CodeGenOpt::Level OL, bool JIT, bool is64bit)
David Greenca29c272018-12-07 12:10:23 +000096 : LLVMTargetMachine(T, computeDataLayout(TT, is64bit), TT, CPU, FS, Options,
97 getEffectiveRelocModel(RM),
98 getEffectiveSparcCodeModel(
99 CM, getEffectiveRelocModel(RM), is64bit, JIT),
100 OL),
Chris Dewhurst4f7cac32016-05-23 10:56:36 +0000101 TLOF(make_unique<SparcELFTargetObjectFile>()),
102 Subtarget(TT, CPU, FS, *this, is64bit), is64Bit(is64bit) {
Rafael Espindola227144c2013-05-13 01:16:13 +0000103 initAsmInfo();
Chris Lattner158e1f52006-02-05 05:50:24 +0000104}
105
Reid Kleckner357600e2014-11-20 23:37:18 +0000106SparcTargetMachine::~SparcTargetMachine() {}
107
Fangrui Songf78650a2018-07-30 19:41:25 +0000108const SparcSubtarget *
Chris Dewhurst68388a02016-05-18 09:14:13 +0000109SparcTargetMachine::getSubtargetImpl(const Function &F) const {
110 Attribute CPUAttr = F.getFnAttribute("target-cpu");
111 Attribute FSAttr = F.getFnAttribute("target-features");
112
113 std::string CPU = !CPUAttr.hasAttribute(Attribute::None)
114 ? CPUAttr.getValueAsString().str()
115 : TargetCPU;
116 std::string FS = !FSAttr.hasAttribute(Attribute::None)
117 ? FSAttr.getValueAsString().str()
118 : TargetFS;
119
120 // FIXME: This is related to the code below to reset the target options,
121 // we need to know whether or not the soft float flag is set on the
122 // function, so we can enable it as a subtarget feature.
123 bool softFloat =
124 F.hasFnAttribute("use-soft-float") &&
125 F.getFnAttribute("use-soft-float").getValueAsString() == "true";
126
Fangrui Songf78650a2018-07-30 19:41:25 +0000127 if (softFloat)
Chris Dewhurst68388a02016-05-18 09:14:13 +0000128 FS += FS.empty() ? "+soft-float" : ",+soft-float";
129
130 auto &I = SubtargetMap[CPU + FS];
131 if (!I) {
132 // This needs to be done before we create a new subtarget since any
133 // creation will depend on the TM and the code generation flags on the
134 // function that reside in TargetOptions.
135 resetTargetOptions(F);
136 I = llvm::make_unique<SparcSubtarget>(TargetTriple, CPU, FS, *this,
137 this->is64Bit);
138 }
139 return I.get();
140}
141
Andrew Trickccb67362012-02-03 05:12:41 +0000142namespace {
143/// Sparc Code Generator Pass Configuration Options.
144class SparcPassConfig : public TargetPassConfig {
145public:
Matthias Braun5e394c32017-05-30 21:36:41 +0000146 SparcPassConfig(SparcTargetMachine &TM, PassManagerBase &PM)
James Y Knight2cc9da92016-08-12 14:48:09 +0000147 : TargetPassConfig(TM, PM) {}
Andrew Trickccb67362012-02-03 05:12:41 +0000148
149 SparcTargetMachine &getSparcTargetMachine() const {
150 return getTM<SparcTargetMachine>();
151 }
152
Robin Morissete2de06b2014-10-16 20:34:57 +0000153 void addIRPasses() override;
Craig Topperb0c941b2014-04-29 07:57:13 +0000154 bool addInstSelector() override;
Matthias Braun7e37a5f2014-12-11 21:26:47 +0000155 void addPreEmitPass() override;
Andrew Trickccb67362012-02-03 05:12:41 +0000156};
157} // namespace
158
Andrew Trickf8ea1082012-02-04 02:56:59 +0000159TargetPassConfig *SparcTargetMachine::createPassConfig(PassManagerBase &PM) {
Matthias Braun5e394c32017-05-30 21:36:41 +0000160 return new SparcPassConfig(*this, PM);
Andrew Trickccb67362012-02-03 05:12:41 +0000161}
162
Robin Morissete2de06b2014-10-16 20:34:57 +0000163void SparcPassConfig::addIRPasses() {
Francis Visoiu Mistrih8b617642017-05-18 17:21:13 +0000164 addPass(createAtomicExpandPass());
Robin Morissete2de06b2014-10-16 20:34:57 +0000165
166 TargetPassConfig::addIRPasses();
167}
168
Andrew Trickccb67362012-02-03 05:12:41 +0000169bool SparcPassConfig::addInstSelector() {
Bob Wilsonbbd38dd2012-07-02 19:48:31 +0000170 addPass(createSparcISelDag(getSparcTargetMachine()));
Chris Lattner158e1f52006-02-05 05:50:24 +0000171 return false;
172}
173
James Y Knight2cc9da92016-08-12 14:48:09 +0000174void SparcPassConfig::addPreEmitPass(){
Francis Visoiu Mistrih8b617642017-05-18 17:21:13 +0000175 addPass(createSparcDelaySlotFillerPass());
James Y Knight2cc9da92016-08-12 14:48:09 +0000176
177 if (this->getSparcTargetMachine().getSubtargetImpl()->insertNOPLoad())
178 {
Francis Visoiu Mistrih8b617642017-05-18 17:21:13 +0000179 addPass(new InsertNOPLoad());
Chris Dewhurst3202f062016-07-08 15:33:56 +0000180 }
Chris Dewhurst2c3cdd62016-10-19 14:01:06 +0000181 if (this->getSparcTargetMachine().getSubtargetImpl()->detectRoundChange()) {
Francis Visoiu Mistrih8b617642017-05-18 17:21:13 +0000182 addPass(new DetectRoundChange());
Chris Dewhurst2c3cdd62016-10-19 14:01:06 +0000183 }
James Y Knight2cc9da92016-08-12 14:48:09 +0000184 if (this->getSparcTargetMachine().getSubtargetImpl()->fixAllFDIVSQRT())
185 {
Francis Visoiu Mistrih8b617642017-05-18 17:21:13 +0000186 addPass(new FixAllFDIVSQRT());
Chris Dewhurst3202f062016-07-08 15:33:56 +0000187 }
Chris Lattner12e97302006-09-04 04:14:57 +0000188}
Chris Lattner8228b112010-02-04 06:34:01 +0000189
James Y Knight2cc9da92016-08-12 14:48:09 +0000190void SparcV8TargetMachine::anchor() { }
David Blaikiea379b1812011-12-20 02:50:00 +0000191
Daniel Sanders3e5de882015-06-11 19:41:26 +0000192SparcV8TargetMachine::SparcV8TargetMachine(const Target &T, const Triple &TT,
193 StringRef CPU, StringRef FS,
Nick Lewycky50f02cb2011-12-02 22:16:29 +0000194 const TargetOptions &Options,
Rafael Espindola8c34dd82016-05-18 22:04:49 +0000195 Optional<Reloc::Model> RM,
Rafael Espindola79e238a2017-08-03 02:16:21 +0000196 Optional<CodeModel::Model> CM,
197 CodeGenOpt::Level OL, bool JIT)
198 : SparcTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, JIT, false) {}
Chris Lattner8228b112010-02-04 06:34:01 +0000199
James Y Knight2cc9da92016-08-12 14:48:09 +0000200void SparcV9TargetMachine::anchor() { }
David Blaikiea379b1812011-12-20 02:50:00 +0000201
Daniel Sanders3e5de882015-06-11 19:41:26 +0000202SparcV9TargetMachine::SparcV9TargetMachine(const Target &T, const Triple &TT,
Douglas Katzman9160e782015-04-29 20:30:57 +0000203 StringRef CPU, StringRef FS,
Nick Lewycky50f02cb2011-12-02 22:16:29 +0000204 const TargetOptions &Options,
Rafael Espindola8c34dd82016-05-18 22:04:49 +0000205 Optional<Reloc::Model> RM,
Rafael Espindola79e238a2017-08-03 02:16:21 +0000206 Optional<CodeModel::Model> CM,
207 CodeGenOpt::Level OL, bool JIT)
208 : SparcTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, JIT, true) {}
Douglas Katzman9160e782015-04-29 20:30:57 +0000209
210void SparcelTargetMachine::anchor() {}
211
Daniel Sanders3e5de882015-06-11 19:41:26 +0000212SparcelTargetMachine::SparcelTargetMachine(const Target &T, const Triple &TT,
Douglas Katzman9160e782015-04-29 20:30:57 +0000213 StringRef CPU, StringRef FS,
214 const TargetOptions &Options,
Rafael Espindola8c34dd82016-05-18 22:04:49 +0000215 Optional<Reloc::Model> RM,
Rafael Espindola79e238a2017-08-03 02:16:21 +0000216 Optional<CodeModel::Model> CM,
217 CodeGenOpt::Level OL, bool JIT)
218 : SparcTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, JIT, false) {}