xref: /aosp_15_r20/external/llvm/lib/Target/Sparc/SparcTargetMachine.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
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