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