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