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_SUPPORT_TARGETREGISTRY_H_ 10 #define MCLD_SUPPORT_TARGETREGISTRY_H_ 11 #include "mcld/Support/Target.h" 12 13 #include <llvm/ADT/Triple.h> 14 15 #include <list> 16 #include <string> 17 18 namespace llvm { 19 class TargetMachine; 20 class MCCodeEmitter; 21 class MCContext; 22 class AsmPrinter; 23 } // namespace llvm 24 25 namespace mcld { 26 27 /** \class TargetRegistry 28 * \brief TargetRegistry is an object adapter of llvm::TargetRegistry 29 */ 30 class TargetRegistry { 31 public: 32 typedef std::list<mcld::Target*> TargetListTy; 33 typedef TargetListTy::iterator iterator; 34 35 private: 36 static TargetListTy s_TargetList; 37 38 public: begin()39 static iterator begin() { return s_TargetList.begin(); } end()40 static iterator end() { return s_TargetList.end(); } 41 size()42 static size_t size() { return s_TargetList.size(); } empty()43 static bool empty() { return s_TargetList.empty(); } 44 45 /// RegisterTarget - Register the given target. Attempts to register a 46 /// target which has already been registered will be ignored. 47 /// 48 /// Clients are responsible for ensuring that registration doesn't occur 49 /// while another thread is attempting to access the registry. Typically 50 /// this is done by initializing all targets at program startup. 51 /// 52 /// @param T - The target being registered. 53 static void RegisterTarget(Target& pTarget, 54 const char* pName, 55 Target::TripleMatchQualityFnTy pQualityFn); 56 57 /// RegisterEmulation - Register a emulation function for the target. 58 /// target. 59 /// 60 /// @param T - the target being registered 61 /// @param Fn - A emulation function RegisterEmulation(mcld::Target & T,mcld::Target::EmulationFnTy Fn)62 static void RegisterEmulation(mcld::Target& T, 63 mcld::Target::EmulationFnTy Fn) { 64 if (!T.EmulationFn) 65 T.EmulationFn = Fn; 66 } 67 68 /// RegisterTargetLDBackend - Register a TargetLDBackend implementation for 69 /// the given target. 70 /// 71 /// @param T - The target being registered 72 /// @param Fn - A function to create TargetLDBackend for the target RegisterTargetLDBackend(mcld::Target & T,mcld::Target::TargetLDBackendCtorTy Fn)73 static void RegisterTargetLDBackend(mcld::Target& T, 74 mcld::Target::TargetLDBackendCtorTy Fn) { 75 if (!T.TargetLDBackendCtorFn) 76 T.TargetLDBackendCtorFn = Fn; 77 } 78 79 /// RegisterTargetDiagnosticLineInfo - Register a DiagnosticLineInfo 80 /// implementation for the given target. 81 /// 82 /// @param T - The target being registered 83 /// @param Fn - A function to create DiagnosticLineInfo for the target RegisterDiagnosticLineInfo(mcld::Target & T,mcld::Target::DiagnosticLineInfoCtorTy Fn)84 static void RegisterDiagnosticLineInfo( 85 mcld::Target& T, 86 mcld::Target::DiagnosticLineInfoCtorTy Fn) { 87 if (!T.DiagnosticLineInfoCtorFn) 88 T.DiagnosticLineInfoCtorFn = Fn; 89 } 90 91 /// lookupTarget - Look up MCLinker target 92 /// 93 /// @param Triple - The Triple string 94 /// @param Error - The returned error message 95 static const mcld::Target* lookupTarget(const std::string& pTriple, 96 std::string& pError); 97 98 /// lookupTarget - Look up MCLinker target by an architecture name 99 /// and a triple. If the architecture name is not empty, then the 100 /// the lookup is done mainly by architecture. Otherwise, the target 101 /// triple is used. 102 /// 103 /// @param pArch - The architecture name 104 /// @param pTriple - The target triple 105 /// @param pError - The returned error message 106 static const mcld::Target* lookupTarget(const std::string& pArchName, 107 llvm::Triple& pTriple, 108 std::string& Error); 109 }; 110 111 /// RegisterTarget - Helper function for registering a target, for use in the 112 /// target's initialization function. Usage: 113 /// 114 /// Target TheFooTarget; // The global target instance. 115 /// 116 /// extern "C" void MCLDInitializeFooTargetInfo() { 117 /// RegisterTarget<llvm::Foo> X(TheFooTarget, "foo", "Foo description"); 118 /// } 119 template <llvm::Triple::ArchType TargetArchType = llvm::Triple::UnknownArch> 120 struct RegisterTarget { 121 public: RegisterTargetRegisterTarget122 RegisterTarget(mcld::Target& pTarget, const char* pName) { 123 // if we've registered one, then return immediately. 124 TargetRegistry::iterator target, ie = TargetRegistry::end(); 125 for (target = TargetRegistry::begin(); target != ie; ++target) { 126 if (strcmp((*target)->name(), pName) == 0) 127 return; 128 } 129 130 TargetRegistry::RegisterTarget(pTarget, pName, &getTripleMatchQuality); 131 } 132 getTripleMatchQualityRegisterTarget133 static unsigned int getTripleMatchQuality(const llvm::Triple& pTriple) { 134 if (pTriple.getArch() == TargetArchType) 135 return 20; 136 return 0; 137 } 138 }; 139 140 } // namespace mcld 141 142 #endif // MCLD_SUPPORT_TARGETREGISTRY_H_ 143