Home | History | Annotate | Download | only in Support
      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:
     39   static iterator begin() { return s_TargetList.begin(); }
     40   static iterator end() { return s_TargetList.end(); }
     41 
     42   static size_t size() { return s_TargetList.size(); }
     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
     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
     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
     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:
    122   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 
    133   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