1b60736ecSDimitry Andric //===--- CSKYTargetMachine.cpp - Define TargetMachine for CSKY ------------===//
2b60736ecSDimitry Andric //
3b60736ecSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4b60736ecSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5b60736ecSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6b60736ecSDimitry Andric //
7b60736ecSDimitry Andric //===----------------------------------------------------------------------===//
8b60736ecSDimitry Andric //
9b60736ecSDimitry Andric // Implements the info about CSKY target spec.
10b60736ecSDimitry Andric //
11b60736ecSDimitry Andric //===----------------------------------------------------------------------===//
12b60736ecSDimitry Andric
13b60736ecSDimitry Andric #include "CSKYTargetMachine.h"
14c0981da4SDimitry Andric #include "CSKY.h"
15e3b55780SDimitry Andric #include "CSKYMachineFunctionInfo.h"
16c0981da4SDimitry Andric #include "CSKYSubtarget.h"
17145449b1SDimitry Andric #include "CSKYTargetObjectFile.h"
18b60736ecSDimitry Andric #include "TargetInfo/CSKYTargetInfo.h"
19145449b1SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
20b60736ecSDimitry Andric #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
21b60736ecSDimitry Andric #include "llvm/CodeGen/TargetPassConfig.h"
22c0981da4SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
23c0981da4SDimitry Andric #include "llvm/MC/TargetRegistry.h"
24e3b55780SDimitry Andric #include <optional>
25b60736ecSDimitry Andric
26b60736ecSDimitry Andric using namespace llvm;
27b60736ecSDimitry Andric
LLVMInitializeCSKYTarget()28b60736ecSDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeCSKYTarget() {
29b60736ecSDimitry Andric RegisterTargetMachine<CSKYTargetMachine> X(getTheCSKYTarget());
306f8fc217SDimitry Andric
316f8fc217SDimitry Andric PassRegistry *Registry = PassRegistry::getPassRegistry();
326f8fc217SDimitry Andric initializeCSKYConstantIslandsPass(*Registry);
33ac9a064cSDimitry Andric initializeCSKYDAGToDAGISelLegacyPass(*Registry);
34b60736ecSDimitry Andric }
35b60736ecSDimitry Andric
computeDataLayout(const Triple & TT)36b60736ecSDimitry Andric static std::string computeDataLayout(const Triple &TT) {
37b60736ecSDimitry Andric std::string Ret;
38b60736ecSDimitry Andric
39b60736ecSDimitry Andric // Only support little endian for now.
40b60736ecSDimitry Andric // TODO: Add support for big endian.
41b60736ecSDimitry Andric Ret += "e";
42b60736ecSDimitry Andric
43b60736ecSDimitry Andric // CSKY is always 32-bit target with the CSKYv2 ABI as prefer now.
44b60736ecSDimitry Andric // It's a 4-byte aligned stack with ELF mangling only.
45b60736ecSDimitry Andric Ret += "-m:e-S32-p:32:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:32"
46b60736ecSDimitry Andric "-v128:32:32-a:0:32-Fi32-n32";
47b60736ecSDimitry Andric
48b60736ecSDimitry Andric return Ret;
49b60736ecSDimitry Andric }
50b60736ecSDimitry Andric
CSKYTargetMachine(const Target & T,const Triple & TT,StringRef CPU,StringRef FS,const TargetOptions & Options,std::optional<Reloc::Model> RM,std::optional<CodeModel::Model> CM,CodeGenOptLevel OL,bool JIT)51b60736ecSDimitry Andric CSKYTargetMachine::CSKYTargetMachine(const Target &T, const Triple &TT,
52b60736ecSDimitry Andric StringRef CPU, StringRef FS,
53b60736ecSDimitry Andric const TargetOptions &Options,
54e3b55780SDimitry Andric std::optional<Reloc::Model> RM,
55e3b55780SDimitry Andric std::optional<CodeModel::Model> CM,
56b1c73532SDimitry Andric CodeGenOptLevel OL, bool JIT)
57b60736ecSDimitry Andric : LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS, Options,
58145449b1SDimitry Andric RM.value_or(Reloc::Static),
59b60736ecSDimitry Andric getEffectiveCodeModel(CM, CodeModel::Small), OL),
60145449b1SDimitry Andric TLOF(std::make_unique<CSKYELFTargetObjectFile>()) {
61b60736ecSDimitry Andric initAsmInfo();
62b60736ecSDimitry Andric }
63b60736ecSDimitry Andric
64c0981da4SDimitry Andric const CSKYSubtarget *
getSubtargetImpl(const Function & F) const65c0981da4SDimitry Andric CSKYTargetMachine::getSubtargetImpl(const Function &F) const {
66c0981da4SDimitry Andric Attribute CPUAttr = F.getFnAttribute("target-cpu");
67c0981da4SDimitry Andric Attribute TuneAttr = F.getFnAttribute("tune-cpu");
68c0981da4SDimitry Andric Attribute FSAttr = F.getFnAttribute("target-features");
69c0981da4SDimitry Andric
70c0981da4SDimitry Andric std::string CPU =
71c0981da4SDimitry Andric CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU;
72c0981da4SDimitry Andric std::string TuneCPU =
73c0981da4SDimitry Andric TuneAttr.isValid() ? TuneAttr.getValueAsString().str() : CPU;
74c0981da4SDimitry Andric std::string FS =
75c0981da4SDimitry Andric FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS;
76c0981da4SDimitry Andric
77c0981da4SDimitry Andric std::string Key = CPU + TuneCPU + FS;
78c0981da4SDimitry Andric auto &I = SubtargetMap[Key];
79c0981da4SDimitry Andric if (!I) {
80c0981da4SDimitry Andric // This needs to be done before we create a new subtarget since any
81c0981da4SDimitry Andric // creation will depend on the TM and the code generation flags on the
82c0981da4SDimitry Andric // function that reside in TargetOptions.
83c0981da4SDimitry Andric resetTargetOptions(F);
84c0981da4SDimitry Andric I = std::make_unique<CSKYSubtarget>(TargetTriple, CPU, TuneCPU, FS, *this);
85c0981da4SDimitry Andric if (I->useHardFloat() && !I->hasAnyFloatExt())
86c0981da4SDimitry Andric errs() << "Hard-float can't be used with current CPU,"
87c0981da4SDimitry Andric " set to Soft-float\n";
88c0981da4SDimitry Andric }
89c0981da4SDimitry Andric return I.get();
90c0981da4SDimitry Andric }
91c0981da4SDimitry Andric
createMachineFunctionInfo(BumpPtrAllocator & Allocator,const Function & F,const TargetSubtargetInfo * STI) const92e3b55780SDimitry Andric MachineFunctionInfo *CSKYTargetMachine::createMachineFunctionInfo(
93e3b55780SDimitry Andric BumpPtrAllocator &Allocator, const Function &F,
94e3b55780SDimitry Andric const TargetSubtargetInfo *STI) const {
95e3b55780SDimitry Andric return CSKYMachineFunctionInfo::create<CSKYMachineFunctionInfo>(Allocator, F,
96e3b55780SDimitry Andric STI);
97e3b55780SDimitry Andric }
98e3b55780SDimitry Andric
99b60736ecSDimitry Andric namespace {
100b60736ecSDimitry Andric class CSKYPassConfig : public TargetPassConfig {
101b60736ecSDimitry Andric public:
CSKYPassConfig(CSKYTargetMachine & TM,PassManagerBase & PM)102b60736ecSDimitry Andric CSKYPassConfig(CSKYTargetMachine &TM, PassManagerBase &PM)
103b60736ecSDimitry Andric : TargetPassConfig(TM, PM) {}
104b60736ecSDimitry Andric
getCSKYTargetMachine() const105b60736ecSDimitry Andric CSKYTargetMachine &getCSKYTargetMachine() const {
106b60736ecSDimitry Andric return getTM<CSKYTargetMachine>();
107b60736ecSDimitry Andric }
108c0981da4SDimitry Andric
109145449b1SDimitry Andric void addIRPasses() override;
110c0981da4SDimitry Andric bool addInstSelector() override;
1116f8fc217SDimitry Andric void addPreEmitPass() override;
112b60736ecSDimitry Andric };
113b60736ecSDimitry Andric
114b60736ecSDimitry Andric } // namespace
115b60736ecSDimitry Andric
createPassConfig(PassManagerBase & PM)116b60736ecSDimitry Andric TargetPassConfig *CSKYTargetMachine::createPassConfig(PassManagerBase &PM) {
117b60736ecSDimitry Andric return new CSKYPassConfig(*this, PM);
118b60736ecSDimitry Andric }
119c0981da4SDimitry Andric
addIRPasses()120145449b1SDimitry Andric void CSKYPassConfig::addIRPasses() {
121ac9a064cSDimitry Andric addPass(createAtomicExpandLegacyPass());
122145449b1SDimitry Andric TargetPassConfig::addIRPasses();
123145449b1SDimitry Andric }
124145449b1SDimitry Andric
addInstSelector()125c0981da4SDimitry Andric bool CSKYPassConfig::addInstSelector() {
126e3b55780SDimitry Andric addPass(createCSKYISelDag(getCSKYTargetMachine(), getOptLevel()));
127c0981da4SDimitry Andric
128c0981da4SDimitry Andric return false;
129c0981da4SDimitry Andric }
1306f8fc217SDimitry Andric
addPreEmitPass()1316f8fc217SDimitry Andric void CSKYPassConfig::addPreEmitPass() {
1326f8fc217SDimitry Andric addPass(createCSKYConstantIslandPass());
1336f8fc217SDimitry Andric }
134