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//===----------------------------------------------------------------------===//
937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#ifndef MCLD_SUPPORT_TARGETREGISTRY_H_
1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#define MCLD_SUPPORT_TARGETREGISTRY_H_
1137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/Target.h"
1237b74a387bb3993387029859c2d9d051c41c724eStephen Hines
13f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <llvm/ADT/Triple.h>
14f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <list>
1637b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include <string>
175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace llvm {
195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass TargetMachine;
205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass MCCodeEmitter;
215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass MCContext;
225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass AsmPrinter;
2337b74a387bb3993387029859c2d9d051c41c724eStephen Hines}  // namespace llvm
245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace mcld {
2622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
27f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines/** \class TargetRegistry
28f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines *  \brief TargetRegistry is an object adapter of llvm::TargetRegistry
29f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines */
3037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesclass TargetRegistry {
3137b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  typedef std::list<mcld::Target*> TargetListTy;
335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  typedef TargetListTy::iterator iterator;
345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3537b74a387bb3993387029859c2d9d051c41c724eStephen Hines private:
365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  static TargetListTy s_TargetList;
375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3837b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
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
5722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// RegisterEmulation - Register a emulation function for the target.
5822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// target.
5922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ///
6022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// @param T - the target being registered
6122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// @param Fn - A emulation function
6237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  static void RegisterEmulation(mcld::Target& T,
6337b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                mcld::Target::EmulationFnTy Fn) {
6422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (!T.EmulationFn)
6522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      T.EmulationFn = Fn;
665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// RegisterTargetLDBackend - Register a TargetLDBackend implementation for
695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// the given target.
705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ///
715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// @param T - The target being registered
725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// @param Fn - A function to create TargetLDBackend for the target
7337b74a387bb3993387029859c2d9d051c41c724eStephen Hines  static void RegisterTargetLDBackend(mcld::Target& T,
7437b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                      mcld::Target::TargetLDBackendCtorTy Fn) {
755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (!T.TargetLDBackendCtorFn)
765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      T.TargetLDBackendCtorFn = Fn;
775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
79affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// RegisterTargetDiagnosticLineInfo - Register a DiagnosticLineInfo
80affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// implementation for the given target.
81affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  ///
82affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// @param T - The target being registered
83affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// @param Fn - A function to create DiagnosticLineInfo for the target
8437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  static void RegisterDiagnosticLineInfo(
8537b74a387bb3993387029859c2d9d051c41c724eStephen Hines      mcld::Target& T,
8637b74a387bb3993387029859c2d9d051c41c724eStephen Hines      mcld::Target::DiagnosticLineInfoCtorTy Fn) {
87affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (!T.DiagnosticLineInfoCtorFn)
88affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      T.DiagnosticLineInfoCtorFn = Fn;
89affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
90affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
91f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  /// lookupTarget - Look up MCLinker target
925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ///
935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// @param Triple - The Triple string
945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// @param Error  - The returned error message
9537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  static const mcld::Target* lookupTarget(const std::string& pTriple,
96f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines                                          std::string& pError);
97f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
98f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  /// lookupTarget - Look up MCLinker target by an architecture name
99f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  /// and a triple. If the architecture name is not empty, then the
100f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  /// the lookup is done mainly by architecture. Otherwise, the target
101f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  /// triple is used.
102f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  ///
103f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  /// @param pArch   - The architecture name
104f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  /// @param pTriple - The target triple
105f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  /// @param pError  - The returned error message
10637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  static const mcld::Target* lookupTarget(const std::string& pArchName,
107f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines                                          llvm::Triple& pTriple,
10837b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                          std::string& Error);
1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao};
1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// RegisterTarget - Helper function for registering a target, for use in the
1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// target's initialization function. Usage:
1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///
1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Target TheFooTarget; // The global target instance.
1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///
11622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// extern "C" void MCLDInitializeFooTargetInfo() {
117f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines///   RegisterTarget<llvm::Foo> X(TheFooTarget, "foo", "Foo description");
1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// }
11937b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <llvm::Triple::ArchType TargetArchType = llvm::Triple::UnknownArch>
12037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesstruct RegisterTarget {
12137b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
12237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  RegisterTarget(mcld::Target& pTarget, const char* pName) {
123f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    // if we've registered one, then return immediately.
124f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    TargetRegistry::iterator target, ie = TargetRegistry::end();
125f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    for (target = TargetRegistry::begin(); target != ie; ++target) {
12637b74a387bb3993387029859c2d9d051c41c724eStephen Hines      if (strcmp((*target)->name(), pName) == 0)
127f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines        return;
1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
12922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
130f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    TargetRegistry::RegisterTarget(pTarget, pName, &getTripleMatchQuality);
131f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  }
1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
133f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  static unsigned int getTripleMatchQuality(const llvm::Triple& pTriple) {
134f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    if (pTriple.getArch() == TargetArchType)
135f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines      return 20;
136f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    return 0;
1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao};
1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14037b74a387bb3993387029859c2d9d051c41c724eStephen Hines}  // namespace mcld
1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#endif  // MCLD_SUPPORT_TARGETREGISTRY_H_
143