xref: /llvm-project/llvm/lib/Target/AVR/AVRTargetMachine.cpp (revision 2946cd701067404b99c39fb29dc9c74bd7193eb3)
1 //===-- AVRTargetMachine.cpp - Define TargetMachine for AVR ---------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines the AVR specific subclass of TargetMachine.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "AVRTargetMachine.h"
14 
15 #include "llvm/CodeGen/Passes.h"
16 #include "llvm/CodeGen/TargetPassConfig.h"
17 #include "llvm/IR/LegacyPassManager.h"
18 #include "llvm/IR/Module.h"
19 #include "llvm/Support/TargetRegistry.h"
20 
21 #include "AVR.h"
22 #include "AVRTargetObjectFile.h"
23 #include "MCTargetDesc/AVRMCTargetDesc.h"
24 
25 namespace llvm {
26 
27 static const char *AVRDataLayout = "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8";
28 
29 /// Processes a CPU name.
30 static StringRef getCPU(StringRef CPU) {
31   if (CPU.empty() || CPU == "generic") {
32     return "avr2";
33   }
34 
35   return CPU;
36 }
37 
38 static Reloc::Model getEffectiveRelocModel(Optional<Reloc::Model> RM) {
39   return RM.hasValue() ? *RM : Reloc::Static;
40 }
41 
42 AVRTargetMachine::AVRTargetMachine(const Target &T, const Triple &TT,
43                                    StringRef CPU, StringRef FS,
44                                    const TargetOptions &Options,
45                                    Optional<Reloc::Model> RM,
46                                    Optional<CodeModel::Model> CM,
47                                    CodeGenOpt::Level OL, bool JIT)
48     : LLVMTargetMachine(T, AVRDataLayout, TT, getCPU(CPU), FS, Options,
49                         getEffectiveRelocModel(RM),
50                         getEffectiveCodeModel(CM, CodeModel::Small), OL),
51       SubTarget(TT, getCPU(CPU), FS, *this) {
52   this->TLOF = make_unique<AVRTargetObjectFile>();
53   initAsmInfo();
54 }
55 
56 namespace {
57 /// AVR Code Generator Pass Configuration Options.
58 class AVRPassConfig : public TargetPassConfig {
59 public:
60   AVRPassConfig(AVRTargetMachine &TM, PassManagerBase &PM)
61       : TargetPassConfig(TM, PM) {}
62 
63   AVRTargetMachine &getAVRTargetMachine() const {
64     return getTM<AVRTargetMachine>();
65   }
66 
67   bool addInstSelector() override;
68   void addPreSched2() override;
69   void addPreEmitPass() override;
70   void addPreRegAlloc() override;
71 };
72 } // namespace
73 
74 TargetPassConfig *AVRTargetMachine::createPassConfig(PassManagerBase &PM) {
75   return new AVRPassConfig(*this, PM);
76 }
77 
78 extern "C" void LLVMInitializeAVRTarget() {
79   // Register the target.
80   RegisterTargetMachine<AVRTargetMachine> X(getTheAVRTarget());
81 
82   auto &PR = *PassRegistry::getPassRegistry();
83   initializeAVRExpandPseudoPass(PR);
84   initializeAVRRelaxMemPass(PR);
85 }
86 
87 const AVRSubtarget *AVRTargetMachine::getSubtargetImpl() const {
88   return &SubTarget;
89 }
90 
91 const AVRSubtarget *AVRTargetMachine::getSubtargetImpl(const Function &) const {
92   return &SubTarget;
93 }
94 
95 //===----------------------------------------------------------------------===//
96 // Pass Pipeline Configuration
97 //===----------------------------------------------------------------------===//
98 
99 bool AVRPassConfig::addInstSelector() {
100   // Install an instruction selector.
101   addPass(createAVRISelDag(getAVRTargetMachine(), getOptLevel()));
102   // Create the frame analyzer pass used by the PEI pass.
103   addPass(createAVRFrameAnalyzerPass());
104 
105   return false;
106 }
107 
108 void AVRPassConfig::addPreRegAlloc() {
109   // Create the dynalloc SP save/restore pass to handle variable sized allocas.
110   addPass(createAVRDynAllocaSRPass());
111 }
112 
113 void AVRPassConfig::addPreSched2() {
114   addPass(createAVRRelaxMemPass());
115   addPass(createAVRExpandPseudoPass());
116 }
117 
118 void AVRPassConfig::addPreEmitPass() {
119   // Must run branch selection immediately preceding the asm printer.
120   addPass(&BranchRelaxationPassID);
121 }
122 
123 } // end of namespace llvm
124