TargetRegistry.h revision 67e37f1be98c926645219cfb47fab9e90d8c725c
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 MCLD_TARGET_REGISTRY_H 10#define MCLD_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; 31class DiagnosticLineInfo; 32 33//===----------------------------------------------------------------------===// 34/// Target - mcld::Target is an object adapter of llvm::Target 35/// 36class Target 37{ 38 friend class mcld::LLVMTargetMachine; 39 friend class mcld::TargetRegistry; 40public: 41 typedef mcld::LLVMTargetMachine *(*TargetMachineCtorTy)(const mcld::Target &, 42 llvm::TargetMachine &, 43 const std::string&); 44 45 typedef SectLinker *(*SectLinkerCtorTy)(const std::string& pTriple, 46 SectLinkerOption &, 47 TargetLDBackend&); 48 49 typedef TargetLDBackend *(*TargetLDBackendCtorTy)(const llvm::Target&, 50 const std::string&); 51 52 typedef DiagnosticLineInfo *(*DiagnosticLineInfoCtorTy)(const mcld::Target&, 53 const std::string&); 54 55public: 56 Target(); 57 58 void setTarget(const llvm::Target& pTarget) 59 { m_pT = &pTarget; } 60 61 mcld::LLVMTargetMachine *createTargetMachine(const std::string &pTriple, 62 const std::string &pCPU, const std::string &pFeatures, 63 const llvm::TargetOptions &Options, 64 llvm::Reloc::Model RM = llvm::Reloc::Default, 65 llvm::CodeModel::Model CM = llvm::CodeModel::Default, 66 llvm::CodeGenOpt::Level OL = llvm::CodeGenOpt::Default) const 67 { 68 if (TargetMachineCtorFn && m_pT) { 69 llvm::TargetMachine *tm = m_pT->createTargetMachine(pTriple, pCPU, pFeatures, Options, RM, CM, OL); 70 if (tm) 71 return TargetMachineCtorFn(*this, *tm, pTriple); 72 } 73 return NULL; 74 } 75 76 /// createSectLinker - create target-specific SectLinker 77 /// 78 /// @return created SectLinker 79 SectLinker *createSectLinker(const std::string &pTriple, 80 SectLinkerOption &pOption, 81 TargetLDBackend &pLDBackend) const { 82 if (!SectLinkerCtorFn) 83 return NULL; 84 return SectLinkerCtorFn(pTriple, 85 pOption, 86 pLDBackend); 87 } 88 89 /// createLDBackend - create target-specific LDBackend 90 /// 91 /// @return created TargetLDBackend 92 TargetLDBackend* createLDBackend(const std::string& Triple) const 93 { 94 if (!TargetLDBackendCtorFn) 95 return NULL; 96 return TargetLDBackendCtorFn(*get(), Triple); 97 } 98 99 /// createDiagnosticLineInfo - create target-specific DiagnosticLineInfo 100 DiagnosticLineInfo* createDiagnosticLineInfo(const mcld::Target& pTarget, 101 const std::string& pTriple) const 102 { 103 if (!DiagnosticLineInfoCtorFn) 104 return NULL; 105 return DiagnosticLineInfoCtorFn(pTarget, pTriple); 106 } 107 108 const llvm::Target* get() const 109 { return m_pT; } 110 111private: 112 // ----- function pointers ----- // 113 TargetMachineCtorTy TargetMachineCtorFn; 114 SectLinkerCtorTy SectLinkerCtorFn; 115 TargetLDBackendCtorTy TargetLDBackendCtorFn; 116 DiagnosticLineInfoCtorTy DiagnosticLineInfoCtorFn; 117 118 // ----- adapted llvm::Target ----- // 119 const llvm::Target* m_pT; 120}; 121 122//===----------------------------------------------------------------------===// 123/// TargetRegistry - mcld::TargetRegistry is an object adapter of 124/// llvm::TargetRegistry 125/// 126class TargetRegistry 127{ 128public: 129 typedef std::list<mcld::Target*> TargetListTy; 130 typedef TargetListTy::iterator iterator; 131 132private: 133 static TargetListTy s_TargetList; 134 135public: 136 static iterator begin() { return s_TargetList.begin(); } 137 static iterator end() { return s_TargetList.end(); } 138 139 static size_t size() { return s_TargetList.size(); } 140 static bool empty() { return s_TargetList.empty(); } 141 142 /// RegisterTarget - Register the given target. Attempts to register a 143 /// target which has already been registered will be ignored. 144 /// 145 /// Clients are responsible for ensuring that registration doesn't occur 146 /// while another thread is attempting to access the registry. Typically 147 /// this is done by initializing all targets at program startup. 148 /// 149 /// @param T - The target being registered. 150 static void RegisterTarget(mcld::Target &T); 151 152 /// RegisterTargetMachine - Register a TargetMachine implementation for the 153 /// given target. 154 /// 155 /// @param T - The target being registered. 156 /// @param Fn - A function to construct a TargetMachine for the target. 157 static void RegisterTargetMachine(mcld::Target &T, mcld::Target::TargetMachineCtorTy Fn) 158 { 159 // Ignore duplicate registration. 160 if (!T.TargetMachineCtorFn) 161 T.TargetMachineCtorFn = Fn; 162 } 163 164 /// RegisterSectLinker - Register a SectLinker implementation for the given 165 /// target. 166 /// 167 /// @param T - the target being registered 168 /// @param Fn - A function to create SectLinker for the target 169 static void RegisterSectLinker(mcld::Target &T, mcld::Target::SectLinkerCtorTy Fn) 170 { 171 if (!T.SectLinkerCtorFn) 172 T.SectLinkerCtorFn = Fn; 173 } 174 175 /// RegisterTargetLDBackend - Register a TargetLDBackend implementation for 176 /// the given target. 177 /// 178 /// @param T - The target being registered 179 /// @param Fn - A function to create TargetLDBackend for the target 180 static void RegisterTargetLDBackend(mcld::Target &T, mcld::Target::TargetLDBackendCtorTy Fn) 181 { 182 if (!T.TargetLDBackendCtorFn) 183 T.TargetLDBackendCtorFn = Fn; 184 } 185 186 /// RegisterTargetDiagnosticLineInfo - Register a DiagnosticLineInfo 187 /// implementation for the given target. 188 /// 189 /// @param T - The target being registered 190 /// @param Fn - A function to create DiagnosticLineInfo for the target 191 static void 192 RegisterDiagnosticLineInfo(mcld::Target &T, 193 mcld::Target::DiagnosticLineInfoCtorTy Fn) 194 { 195 if (!T.DiagnosticLineInfoCtorFn) 196 T.DiagnosticLineInfoCtorFn = Fn; 197 } 198 199 /// lookupTarget - Lookup a target based on a llvm::Target. 200 /// 201 /// @param T - The llvm::Target to find 202 static const mcld::Target *lookupTarget(const llvm::Target& T); 203 204 /// lookupTarget - function wrapper of llvm::TargetRegistry::lookupTarget 205 /// 206 /// @param Triple - The Triple string 207 /// @param Error - The returned error message 208 static const mcld::Target *lookupTarget(const std::string &Triple, 209 std::string &Error); 210}; 211 212/// RegisterTarget - Helper function for registering a target, for use in the 213/// target's initialization function. Usage: 214/// 215/// Target TheFooTarget; // The global target instance. 216/// 217/// extern "C" void LLVMInitializeFooTargetInfo() { 218/// RegisterTarget X(TheFooTarget, "foo", "Foo description"); 219/// } 220struct RegisterTarget 221{ 222 RegisterTarget(mcld::Target &T, const char *Name) { 223 llvm::TargetRegistry::iterator TIter, TEnd = llvm::TargetRegistry::end(); 224 // lookup llvm::Target 225 for( TIter=llvm::TargetRegistry::begin(); TIter!=TEnd; ++TIter ) { 226 if( 0==strcmp(TIter->getName(), Name) ) 227 break; 228 } 229 T.setTarget(*TIter); 230 231 TargetRegistry::RegisterTarget(T); 232 } 233}; 234 235/// RegisterTargetMachine - Helper template for registering a target machine 236/// implementation, for use in the target machine initialization 237/// function. Usage: 238/// 239/// extern "C" void LLVMInitializeFooTarget() { 240/// extern mcld::Target TheFooTarget; 241/// RegisterTargetMachine<mcld::FooTargetMachine> X(TheFooTarget); 242/// } 243template<class TargetMachineImpl> 244struct RegisterTargetMachine 245{ 246 RegisterTargetMachine(mcld::Target &T) { 247 TargetRegistry::RegisterTargetMachine(T, &Allocator); 248 } 249 250private: 251 static mcld::LLVMTargetMachine *Allocator(const mcld::Target &T, 252 llvm::TargetMachine& TM, 253 const std::string &Triple) { 254 return new TargetMachineImpl(TM, T, Triple); 255 } 256}; 257 258} //end namespace mcld 259 260#endif 261 262