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 
13 #include <llvm/ADT/Triple.h>
14 
15 #include <list>
16 #include <string>
17 
18 namespace llvm {
19 class TargetMachine;
20 class MCCodeEmitter;
21 class MCContext;
22 class AsmPrinter;
23 }  // namespace llvm
24 
25 namespace mcld {
26 
27 /** \class TargetRegistry
28  *  \brief TargetRegistry is an object adapter of llvm::TargetRegistry
29  */
30 class TargetRegistry {
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   /// RegisterEmulation - Register a emulation function for the target.
58   /// target.
59   ///
60   /// @param T - the target being registered
61   /// @param Fn - A emulation function
RegisterEmulation(mcld::Target & T,mcld::Target::EmulationFnTy Fn)62   static void RegisterEmulation(mcld::Target& T,
63                                 mcld::Target::EmulationFnTy Fn) {
64     if (!T.EmulationFn)
65       T.EmulationFn = Fn;
66   }
67 
68   /// RegisterTargetLDBackend - Register a TargetLDBackend implementation for
69   /// the given target.
70   ///
71   /// @param T - The target being registered
72   /// @param Fn - A function to create TargetLDBackend for the target
RegisterTargetLDBackend(mcld::Target & T,mcld::Target::TargetLDBackendCtorTy Fn)73   static void RegisterTargetLDBackend(mcld::Target& T,
74                                       mcld::Target::TargetLDBackendCtorTy Fn) {
75     if (!T.TargetLDBackendCtorFn)
76       T.TargetLDBackendCtorFn = Fn;
77   }
78 
79   /// RegisterTargetDiagnosticLineInfo - Register a DiagnosticLineInfo
80   /// implementation for the given target.
81   ///
82   /// @param T - The target being registered
83   /// @param Fn - A function to create DiagnosticLineInfo for the target
RegisterDiagnosticLineInfo(mcld::Target & T,mcld::Target::DiagnosticLineInfoCtorTy Fn)84   static void RegisterDiagnosticLineInfo(
85       mcld::Target& T,
86       mcld::Target::DiagnosticLineInfoCtorTy Fn) {
87     if (!T.DiagnosticLineInfoCtorFn)
88       T.DiagnosticLineInfoCtorFn = Fn;
89   }
90 
91   /// lookupTarget - Look up MCLinker target
92   ///
93   /// @param Triple - The Triple string
94   /// @param Error  - The returned error message
95   static const mcld::Target* lookupTarget(const std::string& pTriple,
96                                           std::string& pError);
97 
98   /// lookupTarget - Look up MCLinker target by an architecture name
99   /// and a triple. If the architecture name is not empty, then the
100   /// the lookup is done mainly by architecture. Otherwise, the target
101   /// triple is used.
102   ///
103   /// @param pArch   - The architecture name
104   /// @param pTriple - The target triple
105   /// @param pError  - The returned error message
106   static const mcld::Target* lookupTarget(const std::string& pArchName,
107                                           llvm::Triple& pTriple,
108                                           std::string& Error);
109 };
110 
111 /// RegisterTarget - Helper function for registering a target, for use in the
112 /// target's initialization function. Usage:
113 ///
114 /// Target TheFooTarget; // The global target instance.
115 ///
116 /// extern "C" void MCLDInitializeFooTargetInfo() {
117 ///   RegisterTarget<llvm::Foo> X(TheFooTarget, "foo", "Foo description");
118 /// }
119 template <llvm::Triple::ArchType TargetArchType = llvm::Triple::UnknownArch>
120 struct RegisterTarget {
121  public:
RegisterTargetRegisterTarget122   RegisterTarget(mcld::Target& pTarget, const char* pName) {
123     // if we've registered one, then return immediately.
124     TargetRegistry::iterator target, ie = TargetRegistry::end();
125     for (target = TargetRegistry::begin(); target != ie; ++target) {
126       if (strcmp((*target)->name(), pName) == 0)
127         return;
128     }
129 
130     TargetRegistry::RegisterTarget(pTarget, pName, &getTripleMatchQuality);
131   }
132 
getTripleMatchQualityRegisterTarget133   static unsigned int getTripleMatchQuality(const llvm::Triple& pTriple) {
134     if (pTriple.getArch() == TargetArchType)
135       return 20;
136     return 0;
137   }
138 };
139 
140 }  // namespace mcld
141 
142 #endif  // MCLD_SUPPORT_TARGETREGISTRY_H_
143