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