15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- TargetRegistry.h ---------------------------------------------------===//
25460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
35460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//                     The MCLinker Project
45460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
55460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// This file is distributed under the University of Illinois Open Source
65460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// License. See LICENSE.TXT for details.
75460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
85460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
9f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#ifndef MCLD_SUPPORT_TARGETREGISTRY_H
10f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#define MCLD_SUPPORT_TARGETREGISTRY_H
11f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <mcld/Support/Target.h>
12f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <llvm/ADT/Triple.h>
13f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <string>
155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <list>
165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace llvm {
185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass TargetMachine;
195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass MCCodeEmitter;
205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass MCContext;
215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass AsmPrinter;
225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of llvm
235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace mcld {
2522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
26f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines/** \class TargetRegistry
27f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines *  \brief TargetRegistry is an object adapter of llvm::TargetRegistry
28f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines */
295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass TargetRegistry
305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaopublic:
325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  typedef std::list<mcld::Target*> TargetListTy;
335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  typedef TargetListTy::iterator iterator;
345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprivate:
365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  static TargetListTy s_TargetList;
375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaopublic:
395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  static iterator begin() { return s_TargetList.begin(); }
405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  static iterator end() { return s_TargetList.end(); }
415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  static size_t size() { return s_TargetList.size(); }
435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  static bool empty() { return s_TargetList.empty(); }
445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// RegisterTarget - Register the given target. Attempts to register a
465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// target which has already been registered will be ignored.
475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ///
485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// Clients are responsible for ensuring that registration doesn't occur
495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// while another thread is attempting to access the registry. Typically
505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// this is done by initializing all targets at program startup.
515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ///
525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// @param T - The target being registered.
53f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  static void RegisterTarget(Target& pTarget,
54f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines                             const char* pName,
55f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines                             Target::TripleMatchQualityFnTy pQualityFn);
565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// RegisterTargetMachine - Register a TargetMachine implementation for the
585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// given target.
595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ///
605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// @param T - The target being registered.
615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// @param Fn - A function to construct a TargetMachine for the target.
62affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  static void RegisterTargetMachine(mcld::Target &T, mcld::Target::TargetMachineCtorTy Fn)
63affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  {
645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // Ignore duplicate registration.
655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (!T.TargetMachineCtorFn)
665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      T.TargetMachineCtorFn = Fn;
675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// RegisterMCLinker - Register a MCLinker implementation for the given
705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// target.
715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ///
725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// @param T - the target being registered
7322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// @param Fn - A function to create MCLinker for the target
7422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  static void RegisterMCLinker(mcld::Target &T, mcld::Target::MCLinkerCtorTy Fn)
75affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  {
7622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (!T.MCLinkerCtorFn)
7722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      T.MCLinkerCtorFn = Fn;
7822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
7922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
8022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// RegisterEmulation - Register a emulation function for the target.
8122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// target.
8222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ///
8322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// @param T - the target being registered
8422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// @param Fn - A emulation function
8522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  static void RegisterEmulation(mcld::Target &T, mcld::Target::EmulationFnTy Fn)
8622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  {
8722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (!T.EmulationFn)
8822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      T.EmulationFn = Fn;
895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// RegisterTargetLDBackend - Register a TargetLDBackend implementation for
925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// the given target.
935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ///
945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// @param T - The target being registered
955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// @param Fn - A function to create TargetLDBackend for the target
96affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  static void RegisterTargetLDBackend(mcld::Target &T, mcld::Target::TargetLDBackendCtorTy Fn)
97affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  {
985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (!T.TargetLDBackendCtorFn)
995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      T.TargetLDBackendCtorFn = Fn;
1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
102affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// RegisterTargetDiagnosticLineInfo - Register a DiagnosticLineInfo
103affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// implementation for the given target.
104affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  ///
105affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// @param T - The target being registered
106affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// @param Fn - A function to create DiagnosticLineInfo for the target
107affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  static void
108affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  RegisterDiagnosticLineInfo(mcld::Target &T,
109affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                             mcld::Target::DiagnosticLineInfoCtorTy Fn)
110affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  {
111affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (!T.DiagnosticLineInfoCtorFn)
112affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      T.DiagnosticLineInfoCtorFn = Fn;
113affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
114affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
115f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  /// lookupTarget - Look up MCLinker target
1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ///
1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// @param Triple - The Triple string
1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// @param Error  - The returned error message
119f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  static const mcld::Target *lookupTarget(const std::string& pTriple,
120f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines                                          std::string& pError);
121f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
122f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  /// lookupTarget - Look up MCLinker target by an architecture name
123f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  /// and a triple. If the architecture name is not empty, then the
124f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  /// the lookup is done mainly by architecture. Otherwise, the target
125f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  /// triple is used.
126f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  ///
127f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  /// @param pArch   - The architecture name
128f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  /// @param pTriple - The target triple
129f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  /// @param pError  - The returned error message
130f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  static const mcld::Target *lookupTarget(const std::string& pArchName,
131f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines                                          llvm::Triple& pTriple,
1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                          std::string &Error);
1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao};
1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// RegisterTarget - Helper function for registering a target, for use in the
1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// target's initialization function. Usage:
1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///
1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Target TheFooTarget; // The global target instance.
1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///
14022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// extern "C" void MCLDInitializeFooTargetInfo() {
141f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines///   RegisterTarget<llvm::Foo> X(TheFooTarget, "foo", "Foo description");
1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// }
143f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinestemplate<llvm::Triple::ArchType TargetArchType = llvm::Triple::UnknownArch>
1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaostruct RegisterTarget
1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
146f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinespublic:
147f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  RegisterTarget(mcld::Target &pTarget, const char* pName) {
148f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    // if we've registered one, then return immediately.
149f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    TargetRegistry::iterator target, ie = TargetRegistry::end();
150f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    for (target = TargetRegistry::begin(); target != ie; ++target) {
151f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines      if (0 == strcmp((*target)->name(), pName))
152f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines        return;
1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
15422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
155f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    TargetRegistry::RegisterTarget(pTarget, pName, &getTripleMatchQuality);
156f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  }
1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
158f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  static unsigned int getTripleMatchQuality(const llvm::Triple& pTriple) {
159f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    if (pTriple.getArch() == TargetArchType)
160f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines      return 20;
161f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    return 0;
1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao};
1645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// RegisterTargetMachine - Helper template for registering a target machine
1665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// implementation, for use in the target machine initialization
1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// function. Usage:
1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///
16922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// extern "C" void MCLDInitializeFooTarget() {
1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///   extern mcld::Target TheFooTarget;
1715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///   RegisterTargetMachine<mcld::FooTargetMachine> X(TheFooTarget);
1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// }
1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaotemplate<class TargetMachineImpl>
1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaostruct RegisterTargetMachine
1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  RegisterTargetMachine(mcld::Target &T) {
1775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    TargetRegistry::RegisterTargetMachine(T, &Allocator);
1785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprivate:
181f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  static MCLDTargetMachine *Allocator(const llvm::Target& pLLVMTarget,
182f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines                                      const mcld::Target& pMCLDTarget,
183f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines                                      llvm::TargetMachine& pTM,
184f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines                                      const std::string& pTriple) {
185f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    return new TargetMachineImpl(pTM, pLLVMTarget, pMCLDTarget, pTriple);
1865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao};
1885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} //end namespace mcld
1905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#endif
1925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
193