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