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 #include <llvm/ADT/Triple.h> 13 14 #include <string> 15 #include <list> 16 17 namespace llvm { 18 class TargetMachine; 19 class MCCodeEmitter; 20 class MCContext; 21 class AsmPrinter; 22 } // namespace of llvm 23 24 namespace mcld { 25 26 /** \class TargetRegistry 27 * \brief TargetRegistry is an object adapter of llvm::TargetRegistry 28 */ 29 class TargetRegistry 30 { 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 /// RegisterTargetMachine - Register a TargetMachine implementation for the 58 /// given target. 59 /// 60 /// @param T - The target being registered. 61 /// @param Fn - A function to construct a TargetMachine for the target. RegisterTargetMachine(mcld::Target & T,mcld::Target::TargetMachineCtorTy Fn)62 static void RegisterTargetMachine(mcld::Target &T, mcld::Target::TargetMachineCtorTy Fn) 63 { 64 // Ignore duplicate registration. 65 if (!T.TargetMachineCtorFn) 66 T.TargetMachineCtorFn = Fn; 67 } 68 69 /// RegisterMCLinker - Register a MCLinker implementation for the given 70 /// target. 71 /// 72 /// @param T - the target being registered 73 /// @param Fn - A function to create MCLinker for the target RegisterMCLinker(mcld::Target & T,mcld::Target::MCLinkerCtorTy Fn)74 static void RegisterMCLinker(mcld::Target &T, mcld::Target::MCLinkerCtorTy Fn) 75 { 76 if (!T.MCLinkerCtorFn) 77 T.MCLinkerCtorFn = Fn; 78 } 79 80 /// RegisterEmulation - Register a emulation function for the target. 81 /// target. 82 /// 83 /// @param T - the target being registered 84 /// @param Fn - A emulation function RegisterEmulation(mcld::Target & T,mcld::Target::EmulationFnTy Fn)85 static void RegisterEmulation(mcld::Target &T, mcld::Target::EmulationFnTy Fn) 86 { 87 if (!T.EmulationFn) 88 T.EmulationFn = Fn; 89 } 90 91 /// RegisterTargetLDBackend - Register a TargetLDBackend implementation for 92 /// the given target. 93 /// 94 /// @param T - The target being registered 95 /// @param Fn - A function to create TargetLDBackend for the target RegisterTargetLDBackend(mcld::Target & T,mcld::Target::TargetLDBackendCtorTy Fn)96 static void RegisterTargetLDBackend(mcld::Target &T, mcld::Target::TargetLDBackendCtorTy Fn) 97 { 98 if (!T.TargetLDBackendCtorFn) 99 T.TargetLDBackendCtorFn = Fn; 100 } 101 102 /// RegisterTargetDiagnosticLineInfo - Register a DiagnosticLineInfo 103 /// implementation for the given target. 104 /// 105 /// @param T - The target being registered 106 /// @param Fn - A function to create DiagnosticLineInfo for the target 107 static void RegisterDiagnosticLineInfo(mcld::Target & T,mcld::Target::DiagnosticLineInfoCtorTy Fn)108 RegisterDiagnosticLineInfo(mcld::Target &T, 109 mcld::Target::DiagnosticLineInfoCtorTy Fn) 110 { 111 if (!T.DiagnosticLineInfoCtorFn) 112 T.DiagnosticLineInfoCtorFn = Fn; 113 } 114 115 /// lookupTarget - Look up MCLinker target 116 /// 117 /// @param Triple - The Triple string 118 /// @param Error - The returned error message 119 static const mcld::Target *lookupTarget(const std::string& pTriple, 120 std::string& pError); 121 122 /// lookupTarget - Look up MCLinker target by an architecture name 123 /// and a triple. If the architecture name is not empty, then the 124 /// the lookup is done mainly by architecture. Otherwise, the target 125 /// triple is used. 126 /// 127 /// @param pArch - The architecture name 128 /// @param pTriple - The target triple 129 /// @param pError - The returned error message 130 static const mcld::Target *lookupTarget(const std::string& pArchName, 131 llvm::Triple& pTriple, 132 std::string &Error); 133 }; 134 135 /// RegisterTarget - Helper function for registering a target, for use in the 136 /// target's initialization function. Usage: 137 /// 138 /// Target TheFooTarget; // The global target instance. 139 /// 140 /// extern "C" void MCLDInitializeFooTargetInfo() { 141 /// RegisterTarget<llvm::Foo> X(TheFooTarget, "foo", "Foo description"); 142 /// } 143 template<llvm::Triple::ArchType TargetArchType = llvm::Triple::UnknownArch> 144 struct RegisterTarget 145 { 146 public: RegisterTargetRegisterTarget147 RegisterTarget(mcld::Target &pTarget, const char* pName) { 148 // if we've registered one, then return immediately. 149 TargetRegistry::iterator target, ie = TargetRegistry::end(); 150 for (target = TargetRegistry::begin(); target != ie; ++target) { 151 if (0 == strcmp((*target)->name(), pName)) 152 return; 153 } 154 155 TargetRegistry::RegisterTarget(pTarget, pName, &getTripleMatchQuality); 156 } 157 getTripleMatchQualityRegisterTarget158 static unsigned int getTripleMatchQuality(const llvm::Triple& pTriple) { 159 if (pTriple.getArch() == TargetArchType) 160 return 20; 161 return 0; 162 } 163 }; 164 165 /// RegisterTargetMachine - Helper template for registering a target machine 166 /// implementation, for use in the target machine initialization 167 /// function. Usage: 168 /// 169 /// extern "C" void MCLDInitializeFooTarget() { 170 /// extern mcld::Target TheFooTarget; 171 /// RegisterTargetMachine<mcld::FooTargetMachine> X(TheFooTarget); 172 /// } 173 template<class TargetMachineImpl> 174 struct RegisterTargetMachine 175 { RegisterTargetMachineRegisterTargetMachine176 RegisterTargetMachine(mcld::Target &T) { 177 TargetRegistry::RegisterTargetMachine(T, &Allocator); 178 } 179 180 private: AllocatorRegisterTargetMachine181 static MCLDTargetMachine *Allocator(const llvm::Target& pLLVMTarget, 182 const mcld::Target& pMCLDTarget, 183 llvm::TargetMachine& pTM, 184 const std::string& pTriple) { 185 return new TargetMachineImpl(pTM, pLLVMTarget, pMCLDTarget, pTriple); 186 } 187 }; 188 189 } //end namespace mcld 190 191 #endif 192 193