• 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 class LLVMTargetMachine;
24 class TargetRegistry;
25 class SectLinker;
26 class SectLinkerOption;
27 class TargetLDBackend;
28 class AttributeFactory;
29 class InputFactory;
30 class ContextFactory;
31 class DiagnosticLineInfo;
32 
33 //===----------------------------------------------------------------------===//
34 /// Target - mcld::Target is an object adapter of llvm::Target
35 ///
36 class Target
37 {
38   friend class mcld::LLVMTargetMachine;
39   friend class mcld::TargetRegistry;
40 public:
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 
55 public:
56   Target();
57 
setTarget(const llvm::Target & pTarget)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
createSectLinker(const std::string & pTriple,SectLinkerOption & pOption,TargetLDBackend & pLDBackend)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
createLDBackend(const std::string & Triple)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
createDiagnosticLineInfo(const mcld::Target & pTarget,const std::string & pTriple)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 
get()108   const llvm::Target* get() const
109   { return m_pT; }
110 
111 private:
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 ///
126 class TargetRegistry
127 {
128 public:
129   typedef std::list<mcld::Target*> TargetListTy;
130   typedef TargetListTy::iterator iterator;
131 
132 private:
133   static TargetListTy s_TargetList;
134 
135 public:
begin()136   static iterator begin() { return s_TargetList.begin(); }
end()137   static iterator end() { return s_TargetList.end(); }
138 
size()139   static size_t size() { return s_TargetList.size(); }
empty()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.
RegisterTargetMachine(mcld::Target & T,mcld::Target::TargetMachineCtorTy Fn)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
RegisterSectLinker(mcld::Target & T,mcld::Target::SectLinkerCtorTy Fn)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
RegisterTargetLDBackend(mcld::Target & T,mcld::Target::TargetLDBackendCtorTy Fn)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
RegisterDiagnosticLineInfo(mcld::Target & T,mcld::Target::DiagnosticLineInfoCtorTy Fn)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 /// }
220 struct RegisterTarget
221 {
RegisterTargetRegisterTarget222   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 /// }
243 template<class TargetMachineImpl>
244 struct RegisterTargetMachine
245 {
RegisterTargetMachineRegisterTargetMachine246   RegisterTargetMachine(mcld::Target &T) {
247     TargetRegistry::RegisterTargetMachine(T, &Allocator);
248   }
249 
250 private:
AllocatorRegisterTargetMachine251   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