1 //===- TargetRegistry.h ---------------------------------------------------===// 2 // 3 // The MCLinker Project 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 #ifndef TARGET_REGISTRY_H 10 #define TARGET_REGISTRY_H 11 #include <llvm/Support/TargetRegistry.h> 12 #include <string> 13 #include <list> 14 15 namespace llvm { 16 class TargetMachine; 17 class MCCodeEmitter; 18 class MCContext; 19 class AsmPrinter; 20 } // namespace of llvm 21 22 namespace mcld { 23 class LLVMTargetMachine; 24 class TargetRegistry; 25 class SectLinker; 26 class SectLinkerOption; 27 class TargetLDBackend; 28 class AttributeFactory; 29 class InputFactory; 30 class ContextFactory; 31 32 //===----------------------------------------------------------------------===// 33 /// Target - mcld::Target is an object adapter of llvm::Target 34 /// 35 class Target 36 { 37 friend class mcld::LLVMTargetMachine; 38 friend class mcld::TargetRegistry; 39 public: 40 typedef mcld::LLVMTargetMachine *(*TargetMachineCtorTy)(const mcld::Target &, 41 llvm::TargetMachine &, 42 const std::string&); 43 44 typedef SectLinker *(*SectLinkerCtorTy)(const std::string& pTriple, 45 SectLinkerOption &, 46 TargetLDBackend&); 47 48 typedef TargetLDBackend *(*TargetLDBackendCtorTy)(const llvm::Target&, 49 const std::string&); 50 51 private: 52 TargetMachineCtorTy TargetMachineCtorFn; 53 SectLinkerCtorTy SectLinkerCtorFn; 54 TargetLDBackendCtorTy TargetLDBackendCtorFn; 55 56 public: 57 Target(); 58 setTarget(const llvm::Target & pTarget)59 void setTarget(const llvm::Target& pTarget) { 60 m_pT = &pTarget; 61 } 62 63 mcld::LLVMTargetMachine *createTargetMachine(const std::string &pTriple, 64 const std::string &pCPU, const std::string &pFeatures, 65 const llvm::TargetOptions &Options, 66 llvm::Reloc::Model RM = llvm::Reloc::Default, 67 llvm::CodeModel::Model CM = llvm::CodeModel::Default, 68 llvm::CodeGenOpt::Level OL = llvm::CodeGenOpt::Default) const { 69 if (TargetMachineCtorFn && m_pT) { 70 llvm::TargetMachine *tm = m_pT->createTargetMachine(pTriple, pCPU, pFeatures, Options, RM, CM, OL); 71 if (tm) 72 return TargetMachineCtorFn(*this, *tm, pTriple); 73 } 74 return 0; 75 } 76 77 /// createSectLinker - create target-specific SectLinker 78 /// 79 /// @return created SectLinker createSectLinker(const std::string & pTriple,SectLinkerOption & pOption,TargetLDBackend & pLDBackend)80 SectLinker *createSectLinker(const std::string &pTriple, 81 SectLinkerOption &pOption, 82 TargetLDBackend &pLDBackend) const { 83 if (!SectLinkerCtorFn) 84 return 0; 85 return SectLinkerCtorFn(pTriple, 86 pOption, 87 pLDBackend); 88 } 89 90 /// createLDBackend - create target-specific LDBackend 91 /// 92 /// @return created TargetLDBackend createLDBackend(const llvm::Target & T,const std::string & Triple)93 TargetLDBackend *createLDBackend(const llvm::Target& T, const std::string& Triple) const { 94 if (!TargetLDBackendCtorFn) 95 return 0; 96 return TargetLDBackendCtorFn(T, Triple); 97 } 98 get()99 const llvm::Target* get() const { 100 return m_pT; 101 } 102 103 private: 104 const llvm::Target* m_pT; 105 }; 106 107 //===----------------------------------------------------------------------===// 108 /// TargetRegistry - mcld::TargetRegistry is an object adapter of 109 /// llvm::TargetRegistry 110 /// 111 class TargetRegistry 112 { 113 public: 114 typedef std::list<mcld::Target*> TargetListTy; 115 typedef TargetListTy::iterator iterator; 116 117 private: 118 static TargetListTy s_TargetList; 119 120 public: begin()121 static iterator begin() { return s_TargetList.begin(); } end()122 static iterator end() { return s_TargetList.end(); } 123 size()124 static size_t size() { return s_TargetList.size(); } empty()125 static bool empty() { return s_TargetList.empty(); } 126 127 /// RegisterTarget - Register the given target. Attempts to register a 128 /// target which has already been registered will be ignored. 129 /// 130 /// Clients are responsible for ensuring that registration doesn't occur 131 /// while another thread is attempting to access the registry. Typically 132 /// this is done by initializing all targets at program startup. 133 /// 134 /// @param T - The target being registered. 135 static void RegisterTarget(mcld::Target &T); 136 137 /// RegisterTargetMachine - Register a TargetMachine implementation for the 138 /// given target. 139 /// 140 /// @param T - The target being registered. 141 /// @param Fn - A function to construct a TargetMachine for the target. RegisterTargetMachine(mcld::Target & T,mcld::Target::TargetMachineCtorTy Fn)142 static void RegisterTargetMachine(mcld::Target &T, mcld::Target::TargetMachineCtorTy Fn) { 143 // Ignore duplicate registration. 144 if (!T.TargetMachineCtorFn) 145 T.TargetMachineCtorFn = Fn; 146 } 147 148 /// RegisterSectLinker - Register a SectLinker implementation for the given 149 /// target. 150 /// 151 /// @param T - the target being registered 152 /// @param Fn - A function to create SectLinker for the target RegisterSectLinker(mcld::Target & T,mcld::Target::SectLinkerCtorTy Fn)153 static void RegisterSectLinker(mcld::Target &T, mcld::Target::SectLinkerCtorTy Fn) { 154 if (!T.SectLinkerCtorFn) 155 T.SectLinkerCtorFn = Fn; 156 } 157 158 /// RegisterTargetLDBackend - Register a TargetLDBackend implementation for 159 /// the given target. 160 /// 161 /// @param T - The target being registered 162 /// @param Fn - A function to create TargetLDBackend for the target RegisterTargetLDBackend(mcld::Target & T,mcld::Target::TargetLDBackendCtorTy Fn)163 static void RegisterTargetLDBackend(mcld::Target &T, mcld::Target::TargetLDBackendCtorTy Fn) { 164 if (!T.TargetLDBackendCtorFn) 165 T.TargetLDBackendCtorFn = Fn; 166 } 167 168 /// lookupTarget - Lookup a target based on a llvm::Target. 169 /// 170 /// @param T - The llvm::Target to find 171 static const mcld::Target *lookupTarget(const llvm::Target& T); 172 173 /// lookupTarget - function wrapper of llvm::TargetRegistry::lookupTarget 174 /// 175 /// @param Triple - The Triple string 176 /// @param Error - The returned error message 177 static const mcld::Target *lookupTarget(const std::string &Triple, 178 std::string &Error); 179 }; 180 181 /// RegisterTarget - Helper function for registering a target, for use in the 182 /// target's initialization function. Usage: 183 /// 184 /// Target TheFooTarget; // The global target instance. 185 /// 186 /// extern "C" void LLVMInitializeFooTargetInfo() { 187 /// RegisterTarget X(TheFooTarget, "foo", "Foo description"); 188 /// } 189 struct RegisterTarget 190 { RegisterTargetRegisterTarget191 RegisterTarget(mcld::Target &T, const char *Name) { 192 llvm::TargetRegistry::iterator TIter, TEnd = llvm::TargetRegistry::end(); 193 // lookup llvm::Target 194 for( TIter=llvm::TargetRegistry::begin(); TIter!=TEnd; ++TIter ) { 195 if( 0==strcmp(TIter->getName(), Name) ) 196 break; 197 } 198 T.setTarget(*TIter); 199 200 TargetRegistry::RegisterTarget(T); 201 } 202 }; 203 204 /// RegisterTargetMachine - Helper template for registering a target machine 205 /// implementation, for use in the target machine initialization 206 /// function. Usage: 207 /// 208 /// extern "C" void LLVMInitializeFooTarget() { 209 /// extern mcld::Target TheFooTarget; 210 /// RegisterTargetMachine<mcld::FooTargetMachine> X(TheFooTarget); 211 /// } 212 template<class TargetMachineImpl> 213 struct RegisterTargetMachine 214 { RegisterTargetMachineRegisterTargetMachine215 RegisterTargetMachine(mcld::Target &T) { 216 TargetRegistry::RegisterTargetMachine(T, &Allocator); 217 } 218 219 private: AllocatorRegisterTargetMachine220 static mcld::LLVMTargetMachine *Allocator(const mcld::Target &T, 221 llvm::TargetMachine& TM, 222 const std::string &Triple) { 223 return new TargetMachineImpl(TM, T, Triple); 224 } 225 }; 226 227 } //end namespace mcld 228 229 #endif 230 231