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 26namespace llvm { 27 28static 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. 31static StringRef getCPU(StringRef CPU) { 32 if (CPU.empty() || CPU == "generic") { 33 return "avr2"; 34 } 35 36 return CPU; 37} 38 39static Reloc::Model getEffectiveRelocModel(Optional<Reloc::Model> RM) { 40 return RM.hasValue() ? *RM : Reloc::Static; 41} 42 43AVRTargetMachine::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 57namespace { 58/// AVR Code Generator Pass Configuration Options. 59class AVRPassConfig : public TargetPassConfig { 60public: 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 75TargetPassConfig *AVRTargetMachine::createPassConfig(PassManagerBase &PM) { 76 return new AVRPassConfig(*this, PM); 77} 78 79extern "C" LLVM_EXTERNAL_VISIBILITY 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 88const AVRSubtarget *AVRTargetMachine::getSubtargetImpl() const { 89 return &SubTarget; 90} 91 92const AVRSubtarget *AVRTargetMachine::getSubtargetImpl(const Function &) const { 93 return &SubTarget; 94} 95 96//===----------------------------------------------------------------------===// 97// Pass Pipeline Configuration 98//===----------------------------------------------------------------------===// 99 100bool 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 109void AVRPassConfig::addPreRegAlloc() { 110 // Create the dynalloc SP save/restore pass to handle variable sized allocas. 111 addPass(createAVRDynAllocaSRPass()); 112} 113 114void AVRPassConfig::addPreSched2() { 115 addPass(createAVRRelaxMemPass()); 116 addPass(createAVRExpandPseudoPass()); 117} 118 119void AVRPassConfig::addPreEmitPass() { 120 // Must run branch selection immediately preceding the asm printer. 121 addPass(&BranchRelaxationPassID); 122} 123 124} // end of namespace llvm 125