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/MC/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 = 29 "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8"; 30 31 /// Processes a CPU name. 32 static StringRef getCPU(StringRef CPU) { 33 if (CPU.empty() || CPU == "generic") { 34 return "avr2"; 35 } 36 37 return CPU; 38 } 39 40 static Reloc::Model getEffectiveRelocModel(Optional<Reloc::Model> RM) { 41 return RM.value_or(Reloc::Static); 42 } 43 44 AVRTargetMachine::AVRTargetMachine(const Target &T, const Triple &TT, 45 StringRef CPU, StringRef FS, 46 const TargetOptions &Options, 47 Optional<Reloc::Model> RM, 48 Optional<CodeModel::Model> CM, 49 CodeGenOpt::Level OL, bool JIT) 50 : LLVMTargetMachine(T, AVRDataLayout, TT, getCPU(CPU), FS, Options, 51 getEffectiveRelocModel(RM), 52 getEffectiveCodeModel(CM, CodeModel::Small), OL), 53 SubTarget(TT, std::string(getCPU(CPU)), std::string(FS), *this) { 54 this->TLOF = std::make_unique<AVRTargetObjectFile>(); 55 initAsmInfo(); 56 } 57 58 namespace { 59 /// AVR Code Generator Pass Configuration Options. 60 class AVRPassConfig : public TargetPassConfig { 61 public: 62 AVRPassConfig(AVRTargetMachine &TM, PassManagerBase &PM) 63 : TargetPassConfig(TM, PM) {} 64 65 AVRTargetMachine &getAVRTargetMachine() const { 66 return getTM<AVRTargetMachine>(); 67 } 68 69 void addIRPasses() override; 70 bool addInstSelector() override; 71 void addPreSched2() override; 72 void addPreEmitPass() override; 73 }; 74 } // namespace 75 76 TargetPassConfig *AVRTargetMachine::createPassConfig(PassManagerBase &PM) { 77 return new AVRPassConfig(*this, PM); 78 } 79 80 void AVRPassConfig::addIRPasses() { 81 // Expand instructions like 82 // %result = shl i32 %n, %amount 83 // to a loop so that library calls are avoided. 84 addPass(createAVRShiftExpandPass()); 85 86 TargetPassConfig::addIRPasses(); 87 } 88 89 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAVRTarget() { 90 // Register the target. 91 RegisterTargetMachine<AVRTargetMachine> X(getTheAVRTarget()); 92 93 auto &PR = *PassRegistry::getPassRegistry(); 94 initializeAVRExpandPseudoPass(PR); 95 initializeAVRShiftExpandPass(PR); 96 } 97 98 const AVRSubtarget *AVRTargetMachine::getSubtargetImpl() const { 99 return &SubTarget; 100 } 101 102 const AVRSubtarget *AVRTargetMachine::getSubtargetImpl(const Function &) const { 103 return &SubTarget; 104 } 105 106 //===----------------------------------------------------------------------===// 107 // Pass Pipeline Configuration 108 //===----------------------------------------------------------------------===// 109 110 bool AVRPassConfig::addInstSelector() { 111 // Install an instruction selector. 112 addPass(createAVRISelDag(getAVRTargetMachine(), getOptLevel())); 113 // Create the frame analyzer pass used by the PEI pass. 114 addPass(createAVRFrameAnalyzerPass()); 115 116 return false; 117 } 118 119 void AVRPassConfig::addPreSched2() { 120 addPass(createAVRExpandPseudoPass()); 121 } 122 123 void AVRPassConfig::addPreEmitPass() { 124 // Must run branch selection immediately preceding the asm printer. 125 addPass(&BranchRelaxationPassID); 126 } 127 128 } // end of namespace llvm 129