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