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