1*9880d681SAndroid Build Coastguard Worker //===-- SparcTargetMachine.cpp - Define TargetMachine for Sparc -----------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker //
11*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
12*9880d681SAndroid Build Coastguard Worker
13*9880d681SAndroid Build Coastguard Worker #include "SparcTargetMachine.h"
14*9880d681SAndroid Build Coastguard Worker #include "SparcTargetObjectFile.h"
15*9880d681SAndroid Build Coastguard Worker #include "Sparc.h"
16*9880d681SAndroid Build Coastguard Worker #include "LeonPasses.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/Passes.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/TargetPassConfig.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/LegacyPassManager.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/TargetRegistry.h"
21*9880d681SAndroid Build Coastguard Worker using namespace llvm;
22*9880d681SAndroid Build Coastguard Worker
LLVMInitializeSparcTarget()23*9880d681SAndroid Build Coastguard Worker extern "C" void LLVMInitializeSparcTarget() {
24*9880d681SAndroid Build Coastguard Worker // Register the target.
25*9880d681SAndroid Build Coastguard Worker RegisterTargetMachine<SparcV8TargetMachine> X(TheSparcTarget);
26*9880d681SAndroid Build Coastguard Worker RegisterTargetMachine<SparcV9TargetMachine> Y(TheSparcV9Target);
27*9880d681SAndroid Build Coastguard Worker RegisterTargetMachine<SparcelTargetMachine> Z(TheSparcelTarget);
28*9880d681SAndroid Build Coastguard Worker }
29*9880d681SAndroid Build Coastguard Worker
computeDataLayout(const Triple & T,bool is64Bit)30*9880d681SAndroid Build Coastguard Worker static std::string computeDataLayout(const Triple &T, bool is64Bit) {
31*9880d681SAndroid Build Coastguard Worker // Sparc is typically big endian, but some are little.
32*9880d681SAndroid Build Coastguard Worker std::string Ret = T.getArch() == Triple::sparcel ? "e" : "E";
33*9880d681SAndroid Build Coastguard Worker Ret += "-m:e";
34*9880d681SAndroid Build Coastguard Worker
35*9880d681SAndroid Build Coastguard Worker // Some ABIs have 32bit pointers.
36*9880d681SAndroid Build Coastguard Worker if (!is64Bit)
37*9880d681SAndroid Build Coastguard Worker Ret += "-p:32:32";
38*9880d681SAndroid Build Coastguard Worker
39*9880d681SAndroid Build Coastguard Worker // Alignments for 64 bit integers.
40*9880d681SAndroid Build Coastguard Worker Ret += "-i64:64";
41*9880d681SAndroid Build Coastguard Worker
42*9880d681SAndroid Build Coastguard Worker // On SparcV9 128 floats are aligned to 128 bits, on others only to 64.
43*9880d681SAndroid Build Coastguard Worker // On SparcV9 registers can hold 64 or 32 bits, on others only 32.
44*9880d681SAndroid Build Coastguard Worker if (is64Bit)
45*9880d681SAndroid Build Coastguard Worker Ret += "-n32:64";
46*9880d681SAndroid Build Coastguard Worker else
47*9880d681SAndroid Build Coastguard Worker Ret += "-f128:64-n32";
48*9880d681SAndroid Build Coastguard Worker
49*9880d681SAndroid Build Coastguard Worker if (is64Bit)
50*9880d681SAndroid Build Coastguard Worker Ret += "-S128";
51*9880d681SAndroid Build Coastguard Worker else
52*9880d681SAndroid Build Coastguard Worker Ret += "-S64";
53*9880d681SAndroid Build Coastguard Worker
54*9880d681SAndroid Build Coastguard Worker return Ret;
55*9880d681SAndroid Build Coastguard Worker }
56*9880d681SAndroid Build Coastguard Worker
getEffectiveRelocModel(Optional<Reloc::Model> RM)57*9880d681SAndroid Build Coastguard Worker static Reloc::Model getEffectiveRelocModel(Optional<Reloc::Model> RM) {
58*9880d681SAndroid Build Coastguard Worker if (!RM.hasValue())
59*9880d681SAndroid Build Coastguard Worker return Reloc::Static;
60*9880d681SAndroid Build Coastguard Worker return *RM;
61*9880d681SAndroid Build Coastguard Worker }
62*9880d681SAndroid Build Coastguard Worker
63*9880d681SAndroid Build Coastguard Worker /// Create an ILP32 architecture model
SparcTargetMachine(const Target & T,const Triple & TT,StringRef CPU,StringRef FS,const TargetOptions & Options,Optional<Reloc::Model> RM,CodeModel::Model CM,CodeGenOpt::Level OL,bool is64bit)64*9880d681SAndroid Build Coastguard Worker SparcTargetMachine::SparcTargetMachine(const Target &T, const Triple &TT,
65*9880d681SAndroid Build Coastguard Worker StringRef CPU, StringRef FS,
66*9880d681SAndroid Build Coastguard Worker const TargetOptions &Options,
67*9880d681SAndroid Build Coastguard Worker Optional<Reloc::Model> RM,
68*9880d681SAndroid Build Coastguard Worker CodeModel::Model CM,
69*9880d681SAndroid Build Coastguard Worker CodeGenOpt::Level OL, bool is64bit)
70*9880d681SAndroid Build Coastguard Worker : LLVMTargetMachine(T, computeDataLayout(TT, is64bit), TT, CPU, FS, Options,
71*9880d681SAndroid Build Coastguard Worker getEffectiveRelocModel(RM), CM, OL),
72*9880d681SAndroid Build Coastguard Worker TLOF(make_unique<SparcELFTargetObjectFile>()),
73*9880d681SAndroid Build Coastguard Worker Subtarget(TT, CPU, FS, *this, is64bit), is64Bit(is64bit) {
74*9880d681SAndroid Build Coastguard Worker initAsmInfo();
75*9880d681SAndroid Build Coastguard Worker }
76*9880d681SAndroid Build Coastguard Worker
~SparcTargetMachine()77*9880d681SAndroid Build Coastguard Worker SparcTargetMachine::~SparcTargetMachine() {}
78*9880d681SAndroid Build Coastguard Worker
79*9880d681SAndroid Build Coastguard Worker const SparcSubtarget *
getSubtargetImpl(const Function & F) const80*9880d681SAndroid Build Coastguard Worker SparcTargetMachine::getSubtargetImpl(const Function &F) const {
81*9880d681SAndroid Build Coastguard Worker Attribute CPUAttr = F.getFnAttribute("target-cpu");
82*9880d681SAndroid Build Coastguard Worker Attribute FSAttr = F.getFnAttribute("target-features");
83*9880d681SAndroid Build Coastguard Worker
84*9880d681SAndroid Build Coastguard Worker std::string CPU = !CPUAttr.hasAttribute(Attribute::None)
85*9880d681SAndroid Build Coastguard Worker ? CPUAttr.getValueAsString().str()
86*9880d681SAndroid Build Coastguard Worker : TargetCPU;
87*9880d681SAndroid Build Coastguard Worker std::string FS = !FSAttr.hasAttribute(Attribute::None)
88*9880d681SAndroid Build Coastguard Worker ? FSAttr.getValueAsString().str()
89*9880d681SAndroid Build Coastguard Worker : TargetFS;
90*9880d681SAndroid Build Coastguard Worker
91*9880d681SAndroid Build Coastguard Worker // FIXME: This is related to the code below to reset the target options,
92*9880d681SAndroid Build Coastguard Worker // we need to know whether or not the soft float flag is set on the
93*9880d681SAndroid Build Coastguard Worker // function, so we can enable it as a subtarget feature.
94*9880d681SAndroid Build Coastguard Worker bool softFloat =
95*9880d681SAndroid Build Coastguard Worker F.hasFnAttribute("use-soft-float") &&
96*9880d681SAndroid Build Coastguard Worker F.getFnAttribute("use-soft-float").getValueAsString() == "true";
97*9880d681SAndroid Build Coastguard Worker
98*9880d681SAndroid Build Coastguard Worker if (softFloat)
99*9880d681SAndroid Build Coastguard Worker FS += FS.empty() ? "+soft-float" : ",+soft-float";
100*9880d681SAndroid Build Coastguard Worker
101*9880d681SAndroid Build Coastguard Worker auto &I = SubtargetMap[CPU + FS];
102*9880d681SAndroid Build Coastguard Worker if (!I) {
103*9880d681SAndroid Build Coastguard Worker // This needs to be done before we create a new subtarget since any
104*9880d681SAndroid Build Coastguard Worker // creation will depend on the TM and the code generation flags on the
105*9880d681SAndroid Build Coastguard Worker // function that reside in TargetOptions.
106*9880d681SAndroid Build Coastguard Worker resetTargetOptions(F);
107*9880d681SAndroid Build Coastguard Worker I = llvm::make_unique<SparcSubtarget>(TargetTriple, CPU, FS, *this,
108*9880d681SAndroid Build Coastguard Worker this->is64Bit);
109*9880d681SAndroid Build Coastguard Worker }
110*9880d681SAndroid Build Coastguard Worker return I.get();
111*9880d681SAndroid Build Coastguard Worker }
112*9880d681SAndroid Build Coastguard Worker
113*9880d681SAndroid Build Coastguard Worker namespace {
114*9880d681SAndroid Build Coastguard Worker /// Sparc Code Generator Pass Configuration Options.
115*9880d681SAndroid Build Coastguard Worker class SparcPassConfig : public TargetPassConfig {
116*9880d681SAndroid Build Coastguard Worker public:
SparcPassConfig(SparcTargetMachine * TM,PassManagerBase & PM)117*9880d681SAndroid Build Coastguard Worker SparcPassConfig(SparcTargetMachine *TM, PassManagerBase &PM)
118*9880d681SAndroid Build Coastguard Worker : TargetPassConfig(TM, PM) {}
119*9880d681SAndroid Build Coastguard Worker
getSparcTargetMachine() const120*9880d681SAndroid Build Coastguard Worker SparcTargetMachine &getSparcTargetMachine() const {
121*9880d681SAndroid Build Coastguard Worker return getTM<SparcTargetMachine>();
122*9880d681SAndroid Build Coastguard Worker }
123*9880d681SAndroid Build Coastguard Worker
124*9880d681SAndroid Build Coastguard Worker void addIRPasses() override;
125*9880d681SAndroid Build Coastguard Worker bool addInstSelector() override;
126*9880d681SAndroid Build Coastguard Worker void addPreEmitPass() override;
127*9880d681SAndroid Build Coastguard Worker };
128*9880d681SAndroid Build Coastguard Worker } // namespace
129*9880d681SAndroid Build Coastguard Worker
createPassConfig(PassManagerBase & PM)130*9880d681SAndroid Build Coastguard Worker TargetPassConfig *SparcTargetMachine::createPassConfig(PassManagerBase &PM) {
131*9880d681SAndroid Build Coastguard Worker return new SparcPassConfig(this, PM);
132*9880d681SAndroid Build Coastguard Worker }
133*9880d681SAndroid Build Coastguard Worker
addIRPasses()134*9880d681SAndroid Build Coastguard Worker void SparcPassConfig::addIRPasses() {
135*9880d681SAndroid Build Coastguard Worker addPass(createAtomicExpandPass(&getSparcTargetMachine()));
136*9880d681SAndroid Build Coastguard Worker
137*9880d681SAndroid Build Coastguard Worker TargetPassConfig::addIRPasses();
138*9880d681SAndroid Build Coastguard Worker }
139*9880d681SAndroid Build Coastguard Worker
addInstSelector()140*9880d681SAndroid Build Coastguard Worker bool SparcPassConfig::addInstSelector() {
141*9880d681SAndroid Build Coastguard Worker addPass(createSparcISelDag(getSparcTargetMachine()));
142*9880d681SAndroid Build Coastguard Worker return false;
143*9880d681SAndroid Build Coastguard Worker }
144*9880d681SAndroid Build Coastguard Worker
addPreEmitPass()145*9880d681SAndroid Build Coastguard Worker void SparcPassConfig::addPreEmitPass() {
146*9880d681SAndroid Build Coastguard Worker addPass(createSparcDelaySlotFillerPass(getSparcTargetMachine()));
147*9880d681SAndroid Build Coastguard Worker if (this->getSparcTargetMachine().getSubtargetImpl()->ignoreZeroFlag()) {
148*9880d681SAndroid Build Coastguard Worker addPass(new IgnoreZeroFlag(getSparcTargetMachine()));
149*9880d681SAndroid Build Coastguard Worker }
150*9880d681SAndroid Build Coastguard Worker if (this->getSparcTargetMachine().getSubtargetImpl()->performSDIVReplace()) {
151*9880d681SAndroid Build Coastguard Worker addPass(new ReplaceSDIV(getSparcTargetMachine()));
152*9880d681SAndroid Build Coastguard Worker }
153*9880d681SAndroid Build Coastguard Worker if (this->getSparcTargetMachine().getSubtargetImpl()->fixCallImmediates()) {
154*9880d681SAndroid Build Coastguard Worker addPass(new FixCALL(getSparcTargetMachine()));
155*9880d681SAndroid Build Coastguard Worker }
156*9880d681SAndroid Build Coastguard Worker if (this->getSparcTargetMachine().getSubtargetImpl()->fixFSMULD()) {
157*9880d681SAndroid Build Coastguard Worker addPass(new FixFSMULD(getSparcTargetMachine()));
158*9880d681SAndroid Build Coastguard Worker }
159*9880d681SAndroid Build Coastguard Worker if (this->getSparcTargetMachine().getSubtargetImpl()->replaceFMULS()) {
160*9880d681SAndroid Build Coastguard Worker addPass(new ReplaceFMULS(getSparcTargetMachine()));
161*9880d681SAndroid Build Coastguard Worker }
162*9880d681SAndroid Build Coastguard Worker if (this->getSparcTargetMachine().getSubtargetImpl()->preventRoundChange()) {
163*9880d681SAndroid Build Coastguard Worker addPass(new PreventRoundChange(getSparcTargetMachine()));
164*9880d681SAndroid Build Coastguard Worker }
165*9880d681SAndroid Build Coastguard Worker if (this->getSparcTargetMachine().getSubtargetImpl()->fixAllFDIVSQRT()) {
166*9880d681SAndroid Build Coastguard Worker addPass(new FixAllFDIVSQRT(getSparcTargetMachine()));
167*9880d681SAndroid Build Coastguard Worker }
168*9880d681SAndroid Build Coastguard Worker if (this->getSparcTargetMachine().getSubtargetImpl()->insertNOPsLoadStore()) {
169*9880d681SAndroid Build Coastguard Worker addPass(new InsertNOPsLoadStore(getSparcTargetMachine()));
170*9880d681SAndroid Build Coastguard Worker }
171*9880d681SAndroid Build Coastguard Worker if (this->getSparcTargetMachine().getSubtargetImpl()->insertNOPLoad()) {
172*9880d681SAndroid Build Coastguard Worker addPass(new InsertNOPLoad(getSparcTargetMachine()));
173*9880d681SAndroid Build Coastguard Worker }
174*9880d681SAndroid Build Coastguard Worker if (this->getSparcTargetMachine().getSubtargetImpl()->flushCacheLineSWAP()) {
175*9880d681SAndroid Build Coastguard Worker addPass(new FlushCacheLineSWAP(getSparcTargetMachine()));
176*9880d681SAndroid Build Coastguard Worker }
177*9880d681SAndroid Build Coastguard Worker if (this->getSparcTargetMachine()
178*9880d681SAndroid Build Coastguard Worker .getSubtargetImpl()
179*9880d681SAndroid Build Coastguard Worker ->insertNOPDoublePrecision()) {
180*9880d681SAndroid Build Coastguard Worker addPass(new InsertNOPDoublePrecision(getSparcTargetMachine()));
181*9880d681SAndroid Build Coastguard Worker }
182*9880d681SAndroid Build Coastguard Worker }
183*9880d681SAndroid Build Coastguard Worker
anchor()184*9880d681SAndroid Build Coastguard Worker void SparcV8TargetMachine::anchor() {}
185*9880d681SAndroid Build Coastguard Worker
SparcV8TargetMachine(const Target & T,const Triple & TT,StringRef CPU,StringRef FS,const TargetOptions & Options,Optional<Reloc::Model> RM,CodeModel::Model CM,CodeGenOpt::Level OL)186*9880d681SAndroid Build Coastguard Worker SparcV8TargetMachine::SparcV8TargetMachine(const Target &T, const Triple &TT,
187*9880d681SAndroid Build Coastguard Worker StringRef CPU, StringRef FS,
188*9880d681SAndroid Build Coastguard Worker const TargetOptions &Options,
189*9880d681SAndroid Build Coastguard Worker Optional<Reloc::Model> RM,
190*9880d681SAndroid Build Coastguard Worker CodeModel::Model CM,
191*9880d681SAndroid Build Coastguard Worker CodeGenOpt::Level OL)
192*9880d681SAndroid Build Coastguard Worker : SparcTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {}
193*9880d681SAndroid Build Coastguard Worker
anchor()194*9880d681SAndroid Build Coastguard Worker void SparcV9TargetMachine::anchor() {}
195*9880d681SAndroid Build Coastguard Worker
SparcV9TargetMachine(const Target & T,const Triple & TT,StringRef CPU,StringRef FS,const TargetOptions & Options,Optional<Reloc::Model> RM,CodeModel::Model CM,CodeGenOpt::Level OL)196*9880d681SAndroid Build Coastguard Worker SparcV9TargetMachine::SparcV9TargetMachine(const Target &T, const Triple &TT,
197*9880d681SAndroid Build Coastguard Worker StringRef CPU, StringRef FS,
198*9880d681SAndroid Build Coastguard Worker const TargetOptions &Options,
199*9880d681SAndroid Build Coastguard Worker Optional<Reloc::Model> RM,
200*9880d681SAndroid Build Coastguard Worker CodeModel::Model CM,
201*9880d681SAndroid Build Coastguard Worker CodeGenOpt::Level OL)
202*9880d681SAndroid Build Coastguard Worker : SparcTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {}
203*9880d681SAndroid Build Coastguard Worker
anchor()204*9880d681SAndroid Build Coastguard Worker void SparcelTargetMachine::anchor() {}
205*9880d681SAndroid Build Coastguard Worker
SparcelTargetMachine(const Target & T,const Triple & TT,StringRef CPU,StringRef FS,const TargetOptions & Options,Optional<Reloc::Model> RM,CodeModel::Model CM,CodeGenOpt::Level OL)206*9880d681SAndroid Build Coastguard Worker SparcelTargetMachine::SparcelTargetMachine(const Target &T, const Triple &TT,
207*9880d681SAndroid Build Coastguard Worker StringRef CPU, StringRef FS,
208*9880d681SAndroid Build Coastguard Worker const TargetOptions &Options,
209*9880d681SAndroid Build Coastguard Worker Optional<Reloc::Model> RM,
210*9880d681SAndroid Build Coastguard Worker CodeModel::Model CM,
211*9880d681SAndroid Build Coastguard Worker CodeGenOpt::Level OL)
212*9880d681SAndroid Build Coastguard Worker : SparcTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {}
213