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