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"
15cf78715cSZi Xuan Wu #include "CSKYSubtarget.h"
160365c54cSZi Xuan Wu #include "CSKYTargetObjectFile.h"
17e1c38dd5SZi Xuan Wu #include "TargetInfo/CSKYTargetInfo.h"
18989f1c72Sserge-sans-paille #include "llvm/CodeGen/MachineFrameInfo.h"
19e1c38dd5SZi Xuan Wu #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
20e1c38dd5SZi Xuan Wu #include "llvm/CodeGen/TargetPassConfig.h"
21cf78715cSZi Xuan Wu #include "llvm/CodeGen/TargetSubtargetInfo.h"
2289b57061SReid Kleckner #include "llvm/MC/TargetRegistry.h"
23e1c38dd5SZi Xuan Wu 
24e1c38dd5SZi Xuan Wu using namespace llvm;
25e1c38dd5SZi Xuan Wu 
LLVMInitializeCSKYTarget()26e1c38dd5SZi Xuan Wu extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeCSKYTarget() {
27e1c38dd5SZi Xuan Wu   RegisterTargetMachine<CSKYTargetMachine> X(getTheCSKYTarget());
28065e0324SZi Xuan Wu 
29065e0324SZi Xuan Wu   PassRegistry *Registry = PassRegistry::getPassRegistry();
30065e0324SZi Xuan Wu   initializeCSKYConstantIslandsPass(*Registry);
31e1c38dd5SZi Xuan Wu }
32e1c38dd5SZi Xuan Wu 
computeDataLayout(const Triple & TT)33e1c38dd5SZi Xuan Wu static std::string computeDataLayout(const Triple &TT) {
34e1c38dd5SZi Xuan Wu   std::string Ret;
35e1c38dd5SZi Xuan Wu 
36e1c38dd5SZi Xuan Wu   // Only support little endian for now.
37e1c38dd5SZi Xuan Wu   // TODO: Add support for big endian.
38e1c38dd5SZi Xuan Wu   Ret += "e";
39e1c38dd5SZi Xuan Wu 
40e1c38dd5SZi Xuan Wu   // CSKY is always 32-bit target with the CSKYv2 ABI as prefer now.
41e1c38dd5SZi Xuan Wu   // It's a 4-byte aligned stack with ELF mangling only.
42e1c38dd5SZi Xuan Wu   Ret += "-m:e-S32-p:32:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:32"
43e1c38dd5SZi Xuan Wu          "-v128:32:32-a:0:32-Fi32-n32";
44e1c38dd5SZi Xuan Wu 
45e1c38dd5SZi Xuan Wu   return Ret;
46e1c38dd5SZi Xuan Wu }
47e1c38dd5SZi Xuan Wu 
CSKYTargetMachine(const Target & T,const Triple & TT,StringRef CPU,StringRef FS,const TargetOptions & Options,Optional<Reloc::Model> RM,Optional<CodeModel::Model> CM,CodeGenOpt::Level OL,bool JIT)48e1c38dd5SZi Xuan Wu CSKYTargetMachine::CSKYTargetMachine(const Target &T, const Triple &TT,
49e1c38dd5SZi Xuan Wu                                      StringRef CPU, StringRef FS,
50e1c38dd5SZi Xuan Wu                                      const TargetOptions &Options,
51e1c38dd5SZi Xuan Wu                                      Optional<Reloc::Model> RM,
52e1c38dd5SZi Xuan Wu                                      Optional<CodeModel::Model> CM,
53e1c38dd5SZi Xuan Wu                                      CodeGenOpt::Level OL, bool JIT)
54e1c38dd5SZi Xuan Wu     : LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS, Options,
55*129b531cSKazu Hirata                         RM.value_or(Reloc::Static),
56e1c38dd5SZi Xuan Wu                         getEffectiveCodeModel(CM, CodeModel::Small), OL),
570365c54cSZi Xuan Wu       TLOF(std::make_unique<CSKYELFTargetObjectFile>()) {
58e1c38dd5SZi Xuan Wu   initAsmInfo();
59e1c38dd5SZi Xuan Wu }
60e1c38dd5SZi Xuan Wu 
61cf78715cSZi Xuan Wu const CSKYSubtarget *
getSubtargetImpl(const Function & F) const62cf78715cSZi Xuan Wu CSKYTargetMachine::getSubtargetImpl(const Function &F) const {
63cf78715cSZi Xuan Wu   Attribute CPUAttr = F.getFnAttribute("target-cpu");
64cf78715cSZi Xuan Wu   Attribute TuneAttr = F.getFnAttribute("tune-cpu");
65cf78715cSZi Xuan Wu   Attribute FSAttr = F.getFnAttribute("target-features");
66cf78715cSZi Xuan Wu 
67cf78715cSZi Xuan Wu   std::string CPU =
68cf78715cSZi Xuan Wu       CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU;
69cf78715cSZi Xuan Wu   std::string TuneCPU =
70cf78715cSZi Xuan Wu       TuneAttr.isValid() ? TuneAttr.getValueAsString().str() : CPU;
71cf78715cSZi Xuan Wu   std::string FS =
72cf78715cSZi Xuan Wu       FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS;
73cf78715cSZi Xuan Wu 
74cf78715cSZi Xuan Wu   std::string Key = CPU + TuneCPU + FS;
75cf78715cSZi Xuan Wu   auto &I = SubtargetMap[Key];
76cf78715cSZi Xuan Wu   if (!I) {
77cf78715cSZi Xuan Wu     // This needs to be done before we create a new subtarget since any
78cf78715cSZi Xuan Wu     // creation will depend on the TM and the code generation flags on the
79cf78715cSZi Xuan Wu     // function that reside in TargetOptions.
80cf78715cSZi Xuan Wu     resetTargetOptions(F);
81cf78715cSZi Xuan Wu     I = std::make_unique<CSKYSubtarget>(TargetTriple, CPU, TuneCPU, FS, *this);
82cf78715cSZi Xuan Wu     if (I->useHardFloat() && !I->hasAnyFloatExt())
83cf78715cSZi Xuan Wu       errs() << "Hard-float can't be used with current CPU,"
84cf78715cSZi Xuan Wu                 " set to Soft-float\n";
85cf78715cSZi Xuan Wu   }
86cf78715cSZi Xuan Wu   return I.get();
87cf78715cSZi Xuan Wu }
88cf78715cSZi Xuan Wu 
89e1c38dd5SZi Xuan Wu namespace {
90e1c38dd5SZi Xuan Wu class CSKYPassConfig : public TargetPassConfig {
91e1c38dd5SZi Xuan Wu public:
CSKYPassConfig(CSKYTargetMachine & TM,PassManagerBase & PM)92e1c38dd5SZi Xuan Wu   CSKYPassConfig(CSKYTargetMachine &TM, PassManagerBase &PM)
93e1c38dd5SZi Xuan Wu       : TargetPassConfig(TM, PM) {}
94e1c38dd5SZi Xuan Wu 
getCSKYTargetMachine() const95e1c38dd5SZi Xuan Wu   CSKYTargetMachine &getCSKYTargetMachine() const {
96e1c38dd5SZi Xuan Wu     return getTM<CSKYTargetMachine>();
97e1c38dd5SZi Xuan Wu   }
98cf78715cSZi Xuan Wu 
99ec2de749SZi Xuan Wu   void addIRPasses() override;
100cf78715cSZi Xuan Wu   bool addInstSelector() override;
101065e0324SZi Xuan Wu   void addPreEmitPass() override;
102e1c38dd5SZi Xuan Wu };
103e1c38dd5SZi Xuan Wu 
104e1c38dd5SZi Xuan Wu } // namespace
105e1c38dd5SZi Xuan Wu 
createPassConfig(PassManagerBase & PM)106e1c38dd5SZi Xuan Wu TargetPassConfig *CSKYTargetMachine::createPassConfig(PassManagerBase &PM) {
107e1c38dd5SZi Xuan Wu   return new CSKYPassConfig(*this, PM);
108e1c38dd5SZi Xuan Wu }
109cf78715cSZi Xuan Wu 
addIRPasses()110ec2de749SZi Xuan Wu void CSKYPassConfig::addIRPasses() {
111ec2de749SZi Xuan Wu   addPass(createAtomicExpandPass());
112ec2de749SZi Xuan Wu   TargetPassConfig::addIRPasses();
113ec2de749SZi Xuan Wu }
114ec2de749SZi Xuan Wu 
addInstSelector()115cf78715cSZi Xuan Wu bool CSKYPassConfig::addInstSelector() {
116cf78715cSZi Xuan Wu   addPass(createCSKYISelDag(getCSKYTargetMachine()));
117cf78715cSZi Xuan Wu 
118cf78715cSZi Xuan Wu   return false;
119cf78715cSZi Xuan Wu }
120065e0324SZi Xuan Wu 
addPreEmitPass()121065e0324SZi Xuan Wu void CSKYPassConfig::addPreEmitPass() {
122065e0324SZi Xuan Wu   addPass(createCSKYConstantIslandPass());
123065e0324SZi Xuan Wu }
124