blob: 07f9e7250bd9f7822911500b48a4410864bc9f08 [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.
73static CodeModel::Model getEffectiveCodeModel(Optional<CodeModel::Model> CM,
74 Reloc::Model RM, bool Is64Bit,
75 bool JIT) {
76 if (CM)
77 return *CM;
78 if (Is64Bit) {
79 if (JIT)
80 return CodeModel::Large;
81 return RM == Reloc::PIC_ ? CodeModel::Small : CodeModel::Medium;
82 }
83 return CodeModel::Small;
84}
85
Rafael Espindola38af4d62016-05-18 16:00:24 +000086/// Create an ILP32 architecture model
Rafael Espindola79e238a2017-08-03 02:16:21 +000087SparcTargetMachine::SparcTargetMachine(
88 const Target &T, const Triple &TT, StringRef CPU, StringRef FS,
89 const TargetOptions &Options, Optional<Reloc::Model> RM,
90 Optional<CodeModel::Model> CM, CodeGenOpt::Level OL, bool JIT, bool is64bit)
Matthias Braunbb8507e2017-10-12 22:57:28 +000091 : LLVMTargetMachine(
Rafael Espindola79e238a2017-08-03 02:16:21 +000092 T, computeDataLayout(TT, is64bit), TT, CPU, FS, Options,
93 getEffectiveRelocModel(RM),
94 getEffectiveCodeModel(CM, getEffectiveRelocModel(RM), is64bit, JIT),
95 OL),
Chris Dewhurst4f7cac32016-05-23 10:56:36 +000096 TLOF(make_unique<SparcELFTargetObjectFile>()),
97 Subtarget(TT, CPU, FS, *this, is64bit), is64Bit(is64bit) {
Rafael Espindola227144c2013-05-13 01:16:13 +000098 initAsmInfo();
Chris Lattner158e1f52006-02-05 05:50:24 +000099}
100
Reid Kleckner357600e2014-11-20 23:37:18 +0000101SparcTargetMachine::~SparcTargetMachine() {}
102
Fangrui Songf78650a2018-07-30 19:41:25 +0000103const SparcSubtarget *
Chris Dewhurst68388a02016-05-18 09:14:13 +0000104SparcTargetMachine::getSubtargetImpl(const Function &F) const {
105 Attribute CPUAttr = F.getFnAttribute("target-cpu");
106 Attribute FSAttr = F.getFnAttribute("target-features");
107
108 std::string CPU = !CPUAttr.hasAttribute(Attribute::None)
109 ? CPUAttr.getValueAsString().str()
110 : TargetCPU;
111 std::string FS = !FSAttr.hasAttribute(Attribute::None)
112 ? FSAttr.getValueAsString().str()
113 : TargetFS;
114
115 // FIXME: This is related to the code below to reset the target options,
116 // we need to know whether or not the soft float flag is set on the
117 // function, so we can enable it as a subtarget feature.
118 bool softFloat =
119 F.hasFnAttribute("use-soft-float") &&
120 F.getFnAttribute("use-soft-float").getValueAsString() == "true";
121
Fangrui Songf78650a2018-07-30 19:41:25 +0000122 if (softFloat)
Chris Dewhurst68388a02016-05-18 09:14:13 +0000123 FS += FS.empty() ? "+soft-float" : ",+soft-float";
124
125 auto &I = SubtargetMap[CPU + FS];
126 if (!I) {
127 // This needs to be done before we create a new subtarget since any
128 // creation will depend on the TM and the code generation flags on the
129 // function that reside in TargetOptions.
130 resetTargetOptions(F);
131 I = llvm::make_unique<SparcSubtarget>(TargetTriple, CPU, FS, *this,
132 this->is64Bit);
133 }
134 return I.get();
135}
136
Andrew Trickccb67362012-02-03 05:12:41 +0000137namespace {
138/// Sparc Code Generator Pass Configuration Options.
139class SparcPassConfig : public TargetPassConfig {
140public:
Matthias Braun5e394c32017-05-30 21:36:41 +0000141 SparcPassConfig(SparcTargetMachine &TM, PassManagerBase &PM)
James Y Knight2cc9da92016-08-12 14:48:09 +0000142 : TargetPassConfig(TM, PM) {}
Andrew Trickccb67362012-02-03 05:12:41 +0000143
144 SparcTargetMachine &getSparcTargetMachine() const {
145 return getTM<SparcTargetMachine>();
146 }
147
Robin Morissete2de06b2014-10-16 20:34:57 +0000148 void addIRPasses() override;
Craig Topperb0c941b2014-04-29 07:57:13 +0000149 bool addInstSelector() override;
Matthias Braun7e37a5f2014-12-11 21:26:47 +0000150 void addPreEmitPass() override;
Andrew Trickccb67362012-02-03 05:12:41 +0000151};
152} // namespace
153
Andrew Trickf8ea1082012-02-04 02:56:59 +0000154TargetPassConfig *SparcTargetMachine::createPassConfig(PassManagerBase &PM) {
Matthias Braun5e394c32017-05-30 21:36:41 +0000155 return new SparcPassConfig(*this, PM);
Andrew Trickccb67362012-02-03 05:12:41 +0000156}
157
Robin Morissete2de06b2014-10-16 20:34:57 +0000158void SparcPassConfig::addIRPasses() {
Francis Visoiu Mistrih8b617642017-05-18 17:21:13 +0000159 addPass(createAtomicExpandPass());
Robin Morissete2de06b2014-10-16 20:34:57 +0000160
161 TargetPassConfig::addIRPasses();
162}
163
Andrew Trickccb67362012-02-03 05:12:41 +0000164bool SparcPassConfig::addInstSelector() {
Bob Wilsonbbd38dd2012-07-02 19:48:31 +0000165 addPass(createSparcISelDag(getSparcTargetMachine()));
Chris Lattner158e1f52006-02-05 05:50:24 +0000166 return false;
167}
168
James Y Knight2cc9da92016-08-12 14:48:09 +0000169void SparcPassConfig::addPreEmitPass(){
Francis Visoiu Mistrih8b617642017-05-18 17:21:13 +0000170 addPass(createSparcDelaySlotFillerPass());
James Y Knight2cc9da92016-08-12 14:48:09 +0000171
172 if (this->getSparcTargetMachine().getSubtargetImpl()->insertNOPLoad())
173 {
Francis Visoiu Mistrih8b617642017-05-18 17:21:13 +0000174 addPass(new InsertNOPLoad());
Chris Dewhurst3202f062016-07-08 15:33:56 +0000175 }
Chris Dewhurst2c3cdd62016-10-19 14:01:06 +0000176 if (this->getSparcTargetMachine().getSubtargetImpl()->detectRoundChange()) {
Francis Visoiu Mistrih8b617642017-05-18 17:21:13 +0000177 addPass(new DetectRoundChange());
Chris Dewhurst2c3cdd62016-10-19 14:01:06 +0000178 }
James Y Knight2cc9da92016-08-12 14:48:09 +0000179 if (this->getSparcTargetMachine().getSubtargetImpl()->fixAllFDIVSQRT())
180 {
Francis Visoiu Mistrih8b617642017-05-18 17:21:13 +0000181 addPass(new FixAllFDIVSQRT());
Chris Dewhurst3202f062016-07-08 15:33:56 +0000182 }
Chris Lattner12e97302006-09-04 04:14:57 +0000183}
Chris Lattner8228b112010-02-04 06:34:01 +0000184
James Y Knight2cc9da92016-08-12 14:48:09 +0000185void SparcV8TargetMachine::anchor() { }
David Blaikiea379b1812011-12-20 02:50:00 +0000186
Daniel Sanders3e5de882015-06-11 19:41:26 +0000187SparcV8TargetMachine::SparcV8TargetMachine(const Target &T, const Triple &TT,
188 StringRef CPU, StringRef FS,
Nick Lewycky50f02cb2011-12-02 22:16:29 +0000189 const TargetOptions &Options,
Rafael Espindola8c34dd82016-05-18 22:04:49 +0000190 Optional<Reloc::Model> RM,
Rafael Espindola79e238a2017-08-03 02:16:21 +0000191 Optional<CodeModel::Model> CM,
192 CodeGenOpt::Level OL, bool JIT)
193 : SparcTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, JIT, false) {}
Chris Lattner8228b112010-02-04 06:34:01 +0000194
James Y Knight2cc9da92016-08-12 14:48:09 +0000195void SparcV9TargetMachine::anchor() { }
David Blaikiea379b1812011-12-20 02:50:00 +0000196
Daniel Sanders3e5de882015-06-11 19:41:26 +0000197SparcV9TargetMachine::SparcV9TargetMachine(const Target &T, const Triple &TT,
Douglas Katzman9160e782015-04-29 20:30:57 +0000198 StringRef CPU, StringRef FS,
Nick Lewycky50f02cb2011-12-02 22:16:29 +0000199 const TargetOptions &Options,
Rafael Espindola8c34dd82016-05-18 22:04:49 +0000200 Optional<Reloc::Model> RM,
Rafael Espindola79e238a2017-08-03 02:16:21 +0000201 Optional<CodeModel::Model> CM,
202 CodeGenOpt::Level OL, bool JIT)
203 : SparcTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, JIT, true) {}
Douglas Katzman9160e782015-04-29 20:30:57 +0000204
205void SparcelTargetMachine::anchor() {}
206
Daniel Sanders3e5de882015-06-11 19:41:26 +0000207SparcelTargetMachine::SparcelTargetMachine(const Target &T, const Triple &TT,
Douglas Katzman9160e782015-04-29 20:30:57 +0000208 StringRef CPU, StringRef FS,
209 const TargetOptions &Options,
Rafael Espindola8c34dd82016-05-18 22:04:49 +0000210 Optional<Reloc::Model> RM,
Rafael Espindola79e238a2017-08-03 02:16:21 +0000211 Optional<CodeModel::Model> CM,
212 CodeGenOpt::Level OL, bool JIT)
213 : SparcTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, JIT, false) {}