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 #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:
     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   /// 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.
     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
     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
     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
     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
    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:
    147   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 
    158   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 {
    176   RegisterTargetMachine(mcld::Target &T) {
    177     TargetRegistry::RegisterTargetMachine(T, &Allocator);
    178   }
    179 
    180 private:
    181   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