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