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 #include "TargetInfo/AVRTargetInfo.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 static StringRef getCPU(StringRef CPU) { 32 if (CPU.empty() || CPU == "generic") { 33 return "avr2"; 34 } 35 36 return CPU; 37 } 38 39 static Reloc::Model getEffectiveRelocModel(Optional<Reloc::Model> RM) { 40 return RM.hasValue() ? *RM : Reloc::Static; 41 } 42 43 AVRTargetMachine::AVRTargetMachine(const Target &T, const Triple &TT, 44 StringRef CPU, StringRef FS, 45 const TargetOptions &Options, 46 Optional<Reloc::Model> RM, 47 Optional<CodeModel::Model> CM, 48 CodeGenOpt::Level OL, bool JIT) 49 : LLVMTargetMachine(T, AVRDataLayout, TT, getCPU(CPU), FS, Options, 50 getEffectiveRelocModel(RM), 51 getEffectiveCodeModel(CM, CodeModel::Small), OL), 52 SubTarget(TT, getCPU(CPU), FS, *this) { 53 this->TLOF = std::make_unique<AVRTargetObjectFile>(); 54 initAsmInfo(); 55 } 56 57 namespace { 58 /// AVR Code Generator Pass Configuration Options. 59 class AVRPassConfig : public TargetPassConfig { 60 public: 61 AVRPassConfig(AVRTargetMachine &TM, PassManagerBase &PM) 62 : TargetPassConfig(TM, PM) {} 63 64 AVRTargetMachine &getAVRTargetMachine() const { 65 return getTM<AVRTargetMachine>(); 66 } 67 68 bool addInstSelector() override; 69 void addPreSched2() override; 70 void addPreEmitPass() override; 71 void addPreRegAlloc() override; 72 }; 73 } // namespace 74 75 TargetPassConfig *AVRTargetMachine::createPassConfig(PassManagerBase &PM) { 76 return new AVRPassConfig(*this, PM); 77 } 78 79 extern "C" void LLVMInitializeAVRTarget() { 80 // Register the target. 81 RegisterTargetMachine<AVRTargetMachine> X(getTheAVRTarget()); 82 83 auto &PR = *PassRegistry::getPassRegistry(); 84 initializeAVRExpandPseudoPass(PR); 85 initializeAVRRelaxMemPass(PR); 86 } 87 88 const AVRSubtarget *AVRTargetMachine::getSubtargetImpl() const { 89 return &SubTarget; 90 } 91 92 const AVRSubtarget *AVRTargetMachine::getSubtargetImpl(const Function &) const { 93 return &SubTarget; 94 } 95 96 //===----------------------------------------------------------------------===// 97 // Pass Pipeline Configuration 98 //===----------------------------------------------------------------------===// 99 100 bool AVRPassConfig::addInstSelector() { 101 // Install an instruction selector. 102 addPass(createAVRISelDag(getAVRTargetMachine(), getOptLevel())); 103 // Create the frame analyzer pass used by the PEI pass. 104 addPass(createAVRFrameAnalyzerPass()); 105 106 return false; 107 } 108 109 void AVRPassConfig::addPreRegAlloc() { 110 // Create the dynalloc SP save/restore pass to handle variable sized allocas. 111 addPass(createAVRDynAllocaSRPass()); 112 } 113 114 void AVRPassConfig::addPreSched2() { 115 addPass(createAVRRelaxMemPass()); 116 addPass(createAVRExpandPseudoPass()); 117 } 118 119 void AVRPassConfig::addPreEmitPass() { 120 // Must run branch selection immediately preceding the asm printer. 121 addPass(&BranchRelaxationPassID); 122 } 123 124 } // end of namespace llvm 125