xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/Xtensa/XtensaTargetMachine.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1bdd1243dSDimitry Andric //===- XtensaTargetMachine.cpp - Define TargetMachine for Xtensa ----------===//
2bdd1243dSDimitry Andric //
3bdd1243dSDimitry Andric //                     The LLVM Compiler Infrastructure
4bdd1243dSDimitry Andric //
5bdd1243dSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
6bdd1243dSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
7bdd1243dSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8bdd1243dSDimitry Andric //
9bdd1243dSDimitry Andric //===----------------------------------------------------------------------===//
10bdd1243dSDimitry Andric //
11bdd1243dSDimitry Andric // Implements the info about Xtensa target spec.
12bdd1243dSDimitry Andric //
13bdd1243dSDimitry Andric //===----------------------------------------------------------------------===//
14bdd1243dSDimitry Andric 
15bdd1243dSDimitry Andric #include "XtensaTargetMachine.h"
16bdd1243dSDimitry Andric #include "TargetInfo/XtensaTargetInfo.h"
17bdd1243dSDimitry Andric #include "llvm/CodeGen/Passes.h"
18bdd1243dSDimitry Andric #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
19bdd1243dSDimitry Andric #include "llvm/CodeGen/TargetPassConfig.h"
20bdd1243dSDimitry Andric #include "llvm/MC/TargetRegistry.h"
21bdd1243dSDimitry Andric #include "llvm/Transforms/Scalar.h"
22bdd1243dSDimitry Andric #include <optional>
23bdd1243dSDimitry Andric 
24bdd1243dSDimitry Andric using namespace llvm;
25bdd1243dSDimitry Andric 
26bdd1243dSDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXtensaTarget() {
27bdd1243dSDimitry Andric   // Register the target.
28bdd1243dSDimitry Andric   RegisterTargetMachine<XtensaTargetMachine> A(getTheXtensaTarget());
29bdd1243dSDimitry Andric }
30bdd1243dSDimitry Andric 
31bdd1243dSDimitry Andric static std::string computeDataLayout(const Triple &TT, StringRef CPU,
32bdd1243dSDimitry Andric                                      const TargetOptions &Options,
33bdd1243dSDimitry Andric                                      bool IsLittle) {
34bdd1243dSDimitry Andric   std::string Ret = "e-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-n32";
35bdd1243dSDimitry Andric   return Ret;
36bdd1243dSDimitry Andric }
37bdd1243dSDimitry Andric 
38bdd1243dSDimitry Andric static Reloc::Model getEffectiveRelocModel(bool JIT,
39bdd1243dSDimitry Andric                                            std::optional<Reloc::Model> RM) {
40bdd1243dSDimitry Andric   if (!RM || JIT)
41bdd1243dSDimitry Andric      return Reloc::Static;
42bdd1243dSDimitry Andric   return *RM;
43bdd1243dSDimitry Andric }
44bdd1243dSDimitry Andric 
45bdd1243dSDimitry Andric XtensaTargetMachine::XtensaTargetMachine(const Target &T, const Triple &TT,
46bdd1243dSDimitry Andric                                          StringRef CPU, StringRef FS,
47bdd1243dSDimitry Andric                                          const TargetOptions &Options,
48bdd1243dSDimitry Andric                                          std::optional<Reloc::Model> RM,
49bdd1243dSDimitry Andric                                          std::optional<CodeModel::Model> CM,
505f757f3fSDimitry Andric                                          CodeGenOptLevel OL, bool JIT,
51bdd1243dSDimitry Andric                                          bool IsLittle)
52bdd1243dSDimitry Andric     : LLVMTargetMachine(T, computeDataLayout(TT, CPU, Options, IsLittle), TT,
53bdd1243dSDimitry Andric                         CPU, FS, Options, getEffectiveRelocModel(JIT, RM),
54bdd1243dSDimitry Andric                         getEffectiveCodeModel(CM, CodeModel::Small), OL),
55bdd1243dSDimitry Andric       TLOF(std::make_unique<TargetLoweringObjectFileELF>()) {
56bdd1243dSDimitry Andric   initAsmInfo();
57bdd1243dSDimitry Andric }
58bdd1243dSDimitry Andric 
59bdd1243dSDimitry Andric XtensaTargetMachine::XtensaTargetMachine(const Target &T, const Triple &TT,
60bdd1243dSDimitry Andric                                          StringRef CPU, StringRef FS,
61bdd1243dSDimitry Andric                                          const TargetOptions &Options,
62bdd1243dSDimitry Andric                                          std::optional<Reloc::Model> RM,
63bdd1243dSDimitry Andric                                          std::optional<CodeModel::Model> CM,
645f757f3fSDimitry Andric                                          CodeGenOptLevel OL, bool JIT)
65bdd1243dSDimitry Andric     : XtensaTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, JIT, true) {}
66bdd1243dSDimitry Andric 
67*0fca6ea1SDimitry Andric const XtensaSubtarget *
68*0fca6ea1SDimitry Andric XtensaTargetMachine::getSubtargetImpl(const Function &F) const {
69*0fca6ea1SDimitry Andric   Attribute CPUAttr = F.getFnAttribute("target-cpu");
70*0fca6ea1SDimitry Andric   Attribute FSAttr = F.getFnAttribute("target-features");
71*0fca6ea1SDimitry Andric 
72*0fca6ea1SDimitry Andric   auto CPU = CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU;
73*0fca6ea1SDimitry Andric   auto FS = FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS;
74*0fca6ea1SDimitry Andric 
75*0fca6ea1SDimitry Andric   auto &I = SubtargetMap[CPU + FS];
76*0fca6ea1SDimitry Andric   if (!I) {
77*0fca6ea1SDimitry Andric     // This needs to be done before we create a new subtarget since any
78*0fca6ea1SDimitry Andric     // creation will depend on the TM and the code generation flags on the
79*0fca6ea1SDimitry Andric     // function that reside in TargetOptions.
80*0fca6ea1SDimitry Andric     resetTargetOptions(F);
81*0fca6ea1SDimitry Andric     I = std::make_unique<XtensaSubtarget>(TargetTriple, CPU, FS, *this);
82*0fca6ea1SDimitry Andric   }
83*0fca6ea1SDimitry Andric   return I.get();
84*0fca6ea1SDimitry Andric }
85*0fca6ea1SDimitry Andric 
86*0fca6ea1SDimitry Andric namespace {
87*0fca6ea1SDimitry Andric /// Xtensa Code Generator Pass Configuration Options.
88*0fca6ea1SDimitry Andric class XtensaPassConfig : public TargetPassConfig {
89*0fca6ea1SDimitry Andric public:
90*0fca6ea1SDimitry Andric   XtensaPassConfig(XtensaTargetMachine &TM, PassManagerBase &PM)
91*0fca6ea1SDimitry Andric       : TargetPassConfig(TM, PM) {}
92*0fca6ea1SDimitry Andric 
93*0fca6ea1SDimitry Andric   XtensaTargetMachine &getXtensaTargetMachine() const {
94*0fca6ea1SDimitry Andric     return getTM<XtensaTargetMachine>();
95*0fca6ea1SDimitry Andric   }
96*0fca6ea1SDimitry Andric 
97*0fca6ea1SDimitry Andric   bool addInstSelector() override;
98*0fca6ea1SDimitry Andric };
99*0fca6ea1SDimitry Andric } // end anonymous namespace
100*0fca6ea1SDimitry Andric 
101*0fca6ea1SDimitry Andric bool XtensaPassConfig::addInstSelector() {
102*0fca6ea1SDimitry Andric   addPass(createXtensaISelDag(getXtensaTargetMachine(), getOptLevel()));
103*0fca6ea1SDimitry Andric   return false;
104*0fca6ea1SDimitry Andric }
105*0fca6ea1SDimitry Andric 
106bdd1243dSDimitry Andric TargetPassConfig *XtensaTargetMachine::createPassConfig(PassManagerBase &PM) {
107*0fca6ea1SDimitry Andric   return new XtensaPassConfig(*this, PM);
108bdd1243dSDimitry Andric }
109