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 15namespace llvm { 16class TargetMachine; 17class MCCodeEmitter; 18class MCContext; 19class AsmPrinter; 20} // namespace of llvm 21 22namespace mcld { 23class LLVMTargetMachine; 24class TargetRegistry; 25class SectLinker; 26class SectLinkerOption; 27class TargetLDBackend; 28class AttributeFactory; 29class InputFactory; 30class ContextFactory; 31 32//===----------------------------------------------------------------------===// 33/// Target - mcld::Target is an object adapter of llvm::Target 34/// 35class Target 36{ 37 friend class mcld::LLVMTargetMachine; 38 friend class mcld::TargetRegistry; 39public: 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 51private: 52 TargetMachineCtorTy TargetMachineCtorFn; 53 SectLinkerCtorTy SectLinkerCtorFn; 54 TargetLDBackendCtorTy TargetLDBackendCtorFn; 55 56public: 57 Target(); 58 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 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 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 99 const llvm::Target* get() const { 100 return m_pT; 101 } 102 103private: 104 const llvm::Target* m_pT; 105}; 106 107//===----------------------------------------------------------------------===// 108/// TargetRegistry - mcld::TargetRegistry is an object adapter of 109/// llvm::TargetRegistry 110/// 111class TargetRegistry 112{ 113public: 114 typedef std::list<mcld::Target*> TargetListTy; 115 typedef TargetListTy::iterator iterator; 116 117private: 118 static TargetListTy s_TargetList; 119 120public: 121 static iterator begin() { return s_TargetList.begin(); } 122 static iterator end() { return s_TargetList.end(); } 123 124 static size_t size() { return s_TargetList.size(); } 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. 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 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 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/// } 189struct RegisterTarget 190{ 191 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/// } 212template<class TargetMachineImpl> 213struct RegisterTargetMachine 214{ 215 RegisterTargetMachine(mcld::Target &T) { 216 TargetRegistry::RegisterTargetMachine(T, &Allocator); 217 } 218 219private: 220 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