• 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_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