xref: /llvm-project/llvm/lib/Target/CSKY/CSKYTargetMachine.cpp (revision eec21ccee0950d52926a79685573db1996e3ba5b)
1e1c38dd5SZi Xuan Wu //===--- CSKYTargetMachine.cpp - Define TargetMachine for CSKY ------------===//
2e1c38dd5SZi Xuan Wu //
3e1c38dd5SZi Xuan Wu // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e1c38dd5SZi Xuan Wu // See https://llvm.org/LICENSE.txt for license information.
5e1c38dd5SZi Xuan Wu // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e1c38dd5SZi Xuan Wu //
7e1c38dd5SZi Xuan Wu //===----------------------------------------------------------------------===//
8e1c38dd5SZi Xuan Wu //
9e1c38dd5SZi Xuan Wu // Implements the info about CSKY target spec.
10e1c38dd5SZi Xuan Wu //
11e1c38dd5SZi Xuan Wu //===----------------------------------------------------------------------===//
12e1c38dd5SZi Xuan Wu 
13e1c38dd5SZi Xuan Wu #include "CSKYTargetMachine.h"
14cf78715cSZi Xuan Wu #include "CSKY.h"
15616e0ad1SFangrui Song #include "CSKYMachineFunctionInfo.h"
16cf78715cSZi Xuan Wu #include "CSKYSubtarget.h"
170365c54cSZi Xuan Wu #include "CSKYTargetObjectFile.h"
18e1c38dd5SZi Xuan Wu #include "TargetInfo/CSKYTargetInfo.h"
19989f1c72Sserge-sans-paille #include "llvm/CodeGen/MachineFrameInfo.h"
20e1c38dd5SZi Xuan Wu #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
21e1c38dd5SZi Xuan Wu #include "llvm/CodeGen/TargetPassConfig.h"
22cf78715cSZi Xuan Wu #include "llvm/CodeGen/TargetSubtargetInfo.h"
2389b57061SReid Kleckner #include "llvm/MC/TargetRegistry.h"
248c7c20f0SKrzysztof Parzyszek #include <optional>
25e1c38dd5SZi Xuan Wu 
26e1c38dd5SZi Xuan Wu using namespace llvm;
27e1c38dd5SZi Xuan Wu 
28e1c38dd5SZi Xuan Wu extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeCSKYTarget() {
29e1c38dd5SZi Xuan Wu   RegisterTargetMachine<CSKYTargetMachine> X(getTheCSKYTarget());
30065e0324SZi Xuan Wu 
31065e0324SZi Xuan Wu   PassRegistry *Registry = PassRegistry::getPassRegistry();
32065e0324SZi Xuan Wu   initializeCSKYConstantIslandsPass(*Registry);
337652a594Spaperchalice   initializeCSKYDAGToDAGISelLegacyPass(*Registry);
34e1c38dd5SZi Xuan Wu }
35e1c38dd5SZi Xuan Wu 
36e1c38dd5SZi Xuan Wu static std::string computeDataLayout(const Triple &TT) {
37e1c38dd5SZi Xuan Wu   std::string Ret;
38e1c38dd5SZi Xuan Wu 
39e1c38dd5SZi Xuan Wu   // Only support little endian for now.
40e1c38dd5SZi Xuan Wu   // TODO: Add support for big endian.
41e1c38dd5SZi Xuan Wu   Ret += "e";
42e1c38dd5SZi Xuan Wu 
43e1c38dd5SZi Xuan Wu   // CSKY is always 32-bit target with the CSKYv2 ABI as prefer now.
44e1c38dd5SZi Xuan Wu   // It's a 4-byte aligned stack with ELF mangling only.
45e1c38dd5SZi Xuan Wu   Ret += "-m:e-S32-p:32:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:32"
46e1c38dd5SZi Xuan Wu          "-v128:32:32-a:0:32-Fi32-n32";
47e1c38dd5SZi Xuan Wu 
48e1c38dd5SZi Xuan Wu   return Ret;
49e1c38dd5SZi Xuan Wu }
50e1c38dd5SZi Xuan Wu 
51e1c38dd5SZi Xuan Wu CSKYTargetMachine::CSKYTargetMachine(const Target &T, const Triple &TT,
52e1c38dd5SZi Xuan Wu                                      StringRef CPU, StringRef FS,
53e1c38dd5SZi Xuan Wu                                      const TargetOptions &Options,
54bac97427SFangrui Song                                      std::optional<Reloc::Model> RM,
558c7c20f0SKrzysztof Parzyszek                                      std::optional<CodeModel::Model> CM,
560a1aa6cdSArthur Eubanks                                      CodeGenOptLevel OL, bool JIT)
57*eec21cceSMatin Raayai     : CodeGenTargetMachineImpl(T, computeDataLayout(TT), TT, CPU, FS, Options,
58129b531cSKazu Hirata                                RM.value_or(Reloc::Static),
59e1c38dd5SZi Xuan Wu                                getEffectiveCodeModel(CM, CodeModel::Small), OL),
600365c54cSZi Xuan Wu       TLOF(std::make_unique<CSKYELFTargetObjectFile>()) {
61e1c38dd5SZi Xuan Wu   initAsmInfo();
62e1c38dd5SZi Xuan Wu }
63e1c38dd5SZi Xuan Wu 
64cf78715cSZi Xuan Wu const CSKYSubtarget *
65cf78715cSZi Xuan Wu CSKYTargetMachine::getSubtargetImpl(const Function &F) const {
66cf78715cSZi Xuan Wu   Attribute CPUAttr = F.getFnAttribute("target-cpu");
67cf78715cSZi Xuan Wu   Attribute TuneAttr = F.getFnAttribute("tune-cpu");
68cf78715cSZi Xuan Wu   Attribute FSAttr = F.getFnAttribute("target-features");
69cf78715cSZi Xuan Wu 
70cf78715cSZi Xuan Wu   std::string CPU =
71cf78715cSZi Xuan Wu       CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU;
72cf78715cSZi Xuan Wu   std::string TuneCPU =
73cf78715cSZi Xuan Wu       TuneAttr.isValid() ? TuneAttr.getValueAsString().str() : CPU;
74cf78715cSZi Xuan Wu   std::string FS =
75cf78715cSZi Xuan Wu       FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS;
76cf78715cSZi Xuan Wu 
77cf78715cSZi Xuan Wu   std::string Key = CPU + TuneCPU + FS;
78cf78715cSZi Xuan Wu   auto &I = SubtargetMap[Key];
79cf78715cSZi Xuan Wu   if (!I) {
80cf78715cSZi Xuan Wu     // This needs to be done before we create a new subtarget since any
81cf78715cSZi Xuan Wu     // creation will depend on the TM and the code generation flags on the
82cf78715cSZi Xuan Wu     // function that reside in TargetOptions.
83cf78715cSZi Xuan Wu     resetTargetOptions(F);
84cf78715cSZi Xuan Wu     I = std::make_unique<CSKYSubtarget>(TargetTriple, CPU, TuneCPU, FS, *this);
85cf78715cSZi Xuan Wu     if (I->useHardFloat() && !I->hasAnyFloatExt())
86cf78715cSZi Xuan Wu       errs() << "Hard-float can't be used with current CPU,"
87cf78715cSZi Xuan Wu                 " set to Soft-float\n";
88cf78715cSZi Xuan Wu   }
89cf78715cSZi Xuan Wu   return I.get();
90cf78715cSZi Xuan Wu }
91cf78715cSZi Xuan Wu 
92616e0ad1SFangrui Song MachineFunctionInfo *CSKYTargetMachine::createMachineFunctionInfo(
93616e0ad1SFangrui Song     BumpPtrAllocator &Allocator, const Function &F,
94616e0ad1SFangrui Song     const TargetSubtargetInfo *STI) const {
95616e0ad1SFangrui Song   return CSKYMachineFunctionInfo::create<CSKYMachineFunctionInfo>(Allocator, F,
96616e0ad1SFangrui Song                                                                   STI);
97616e0ad1SFangrui Song }
98616e0ad1SFangrui Song 
99e1c38dd5SZi Xuan Wu namespace {
100e1c38dd5SZi Xuan Wu class CSKYPassConfig : public TargetPassConfig {
101e1c38dd5SZi Xuan Wu public:
102e1c38dd5SZi Xuan Wu   CSKYPassConfig(CSKYTargetMachine &TM, PassManagerBase &PM)
103e1c38dd5SZi Xuan Wu       : TargetPassConfig(TM, PM) {}
104e1c38dd5SZi Xuan Wu 
105e1c38dd5SZi Xuan Wu   CSKYTargetMachine &getCSKYTargetMachine() const {
106e1c38dd5SZi Xuan Wu     return getTM<CSKYTargetMachine>();
107e1c38dd5SZi Xuan Wu   }
108cf78715cSZi Xuan Wu 
109ec2de749SZi Xuan Wu   void addIRPasses() override;
110cf78715cSZi Xuan Wu   bool addInstSelector() override;
111065e0324SZi Xuan Wu   void addPreEmitPass() override;
112e1c38dd5SZi Xuan Wu };
113e1c38dd5SZi Xuan Wu 
114e1c38dd5SZi Xuan Wu } // namespace
115e1c38dd5SZi Xuan Wu 
116e1c38dd5SZi Xuan Wu TargetPassConfig *CSKYTargetMachine::createPassConfig(PassManagerBase &PM) {
117e1c38dd5SZi Xuan Wu   return new CSKYPassConfig(*this, PM);
118e1c38dd5SZi Xuan Wu }
119cf78715cSZi Xuan Wu 
120ec2de749SZi Xuan Wu void CSKYPassConfig::addIRPasses() {
121fe42e72dSRishabh Bali   addPass(createAtomicExpandLegacyPass());
122ec2de749SZi Xuan Wu   TargetPassConfig::addIRPasses();
123ec2de749SZi Xuan Wu }
124ec2de749SZi Xuan Wu 
125cf78715cSZi Xuan Wu bool CSKYPassConfig::addInstSelector() {
12605f343faSZi Xuan Wu (Zeson)   addPass(createCSKYISelDag(getCSKYTargetMachine(), getOptLevel()));
127cf78715cSZi Xuan Wu 
128cf78715cSZi Xuan Wu   return false;
129cf78715cSZi Xuan Wu }
130065e0324SZi Xuan Wu 
131065e0324SZi Xuan Wu void CSKYPassConfig::addPreEmitPass() {
132065e0324SZi Xuan Wu   addPass(createCSKYConstantIslandPass());
133065e0324SZi Xuan Wu }
134