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_TARGET_REGISTRY_H
     10 #define MCLD_TARGET_REGISTRY_H
     11 #include <llvm/Support/TargetRegistry.h>
     12 #include <string>
     13 #include <list>
     14 
     15 namespace llvm {
     16 class TargetMachine;
     17 class MCCodeEmitter;
     18 class MCContext;
     19 class AsmPrinter;
     20 } // namespace of llvm
     21 
     22 namespace mcld {
     23 class LLVMTargetMachine;
     24 class TargetRegistry;
     25 class SectLinker;
     26 class SectLinkerOption;
     27 class TargetLDBackend;
     28 class AttributeFactory;
     29 class InputFactory;
     30 class ContextFactory;
     31 class DiagnosticLineInfo;
     32 
     33 //===----------------------------------------------------------------------===//
     34 /// Target - mcld::Target is an object adapter of llvm::Target
     35 ///
     36 class Target
     37 {
     38   friend class mcld::LLVMTargetMachine;
     39   friend class mcld::TargetRegistry;
     40 public:
     41   typedef mcld::LLVMTargetMachine *(*TargetMachineCtorTy)(const mcld::Target &,
     42                                                           llvm::TargetMachine &,
     43                                                           const std::string&);
     44 
     45   typedef SectLinker *(*SectLinkerCtorTy)(const std::string& pTriple,
     46                                           SectLinkerOption &,
     47                                           TargetLDBackend&);
     48 
     49   typedef TargetLDBackend  *(*TargetLDBackendCtorTy)(const llvm::Target&,
     50                                                      const std::string&);
     51 
     52   typedef DiagnosticLineInfo *(*DiagnosticLineInfoCtorTy)(const mcld::Target&,
     53                                                           const std::string&);
     54 
     55 public:
     56   Target();
     57 
     58   void setTarget(const llvm::Target& pTarget)
     59   { m_pT = &pTarget; }
     60 
     61   mcld::LLVMTargetMachine *createTargetMachine(const std::string &pTriple,
     62                           const std::string &pCPU, const std::string &pFeatures,
     63                           const llvm::TargetOptions &Options,
     64                           llvm::Reloc::Model RM = llvm::Reloc::Default,
     65                           llvm::CodeModel::Model CM = llvm::CodeModel::Default,
     66                           llvm::CodeGenOpt::Level OL = llvm::CodeGenOpt::Default) const
     67   {
     68     if (TargetMachineCtorFn && m_pT) {
     69       llvm::TargetMachine *tm = m_pT->createTargetMachine(pTriple, pCPU, pFeatures, Options, RM, CM, OL);
     70       if (tm)
     71         return TargetMachineCtorFn(*this, *tm, pTriple);
     72     }
     73     return NULL;
     74   }
     75 
     76   /// createSectLinker - create target-specific SectLinker
     77   ///
     78   /// @return created SectLinker
     79   SectLinker *createSectLinker(const std::string &pTriple,
     80                                SectLinkerOption &pOption,
     81                                TargetLDBackend &pLDBackend) const {
     82     if (!SectLinkerCtorFn)
     83       return NULL;
     84     return SectLinkerCtorFn(pTriple,
     85                             pOption,
     86                             pLDBackend);
     87   }
     88 
     89   /// createLDBackend - create target-specific LDBackend
     90   ///
     91   /// @return created TargetLDBackend
     92   TargetLDBackend* createLDBackend(const std::string& Triple) const
     93   {
     94     if (!TargetLDBackendCtorFn)
     95       return NULL;
     96     return TargetLDBackendCtorFn(*get(), Triple);
     97   }
     98 
     99   /// createDiagnosticLineInfo - create target-specific DiagnosticLineInfo
    100   DiagnosticLineInfo* createDiagnosticLineInfo(const mcld::Target& pTarget,
    101                                                const std::string& pTriple) const
    102   {
    103     if (!DiagnosticLineInfoCtorFn)
    104       return NULL;
    105     return DiagnosticLineInfoCtorFn(pTarget, pTriple);
    106   }
    107 
    108   const llvm::Target* get() const
    109   { return m_pT; }
    110 
    111 private:
    112   // -----  function pointers  ----- //
    113   TargetMachineCtorTy TargetMachineCtorFn;
    114   SectLinkerCtorTy SectLinkerCtorFn;
    115   TargetLDBackendCtorTy TargetLDBackendCtorFn;
    116   DiagnosticLineInfoCtorTy DiagnosticLineInfoCtorFn;
    117 
    118   // -----  adapted llvm::Target  ----- //
    119   const llvm::Target* m_pT;
    120 };
    121 
    122 //===----------------------------------------------------------------------===//
    123 /// TargetRegistry - mcld::TargetRegistry is an object adapter of
    124 /// llvm::TargetRegistry
    125 ///
    126 class TargetRegistry
    127 {
    128 public:
    129   typedef std::list<mcld::Target*> TargetListTy;
    130   typedef TargetListTy::iterator iterator;
    131 
    132 private:
    133   static TargetListTy s_TargetList;
    134 
    135 public:
    136   static iterator begin() { return s_TargetList.begin(); }
    137   static iterator end() { return s_TargetList.end(); }
    138 
    139   static size_t size() { return s_TargetList.size(); }
    140   static bool empty() { return s_TargetList.empty(); }
    141 
    142   /// RegisterTarget - Register the given target. Attempts to register a
    143   /// target which has already been registered will be ignored.
    144   ///
    145   /// Clients are responsible for ensuring that registration doesn't occur
    146   /// while another thread is attempting to access the registry. Typically
    147   /// this is done by initializing all targets at program startup.
    148   ///
    149   /// @param T - The target being registered.
    150   static void RegisterTarget(mcld::Target &T);
    151 
    152   /// RegisterTargetMachine - Register a TargetMachine implementation for the
    153   /// given target.
    154   ///
    155   /// @param T - The target being registered.
    156   /// @param Fn - A function to construct a TargetMachine for the target.
    157   static void RegisterTargetMachine(mcld::Target &T, mcld::Target::TargetMachineCtorTy Fn)
    158   {
    159     // Ignore duplicate registration.
    160     if (!T.TargetMachineCtorFn)
    161       T.TargetMachineCtorFn = Fn;
    162   }
    163 
    164   /// RegisterSectLinker - Register a SectLinker implementation for the given
    165   /// target.
    166   ///
    167   /// @param T - the target being registered
    168   /// @param Fn - A function to create SectLinker for the target
    169   static void RegisterSectLinker(mcld::Target &T, mcld::Target::SectLinkerCtorTy Fn)
    170   {
    171     if (!T.SectLinkerCtorFn)
    172       T.SectLinkerCtorFn = Fn;
    173   }
    174 
    175   /// RegisterTargetLDBackend - Register a TargetLDBackend implementation for
    176   /// the given target.
    177   ///
    178   /// @param T - The target being registered
    179   /// @param Fn - A function to create TargetLDBackend for the target
    180   static void RegisterTargetLDBackend(mcld::Target &T, mcld::Target::TargetLDBackendCtorTy Fn)
    181   {
    182     if (!T.TargetLDBackendCtorFn)
    183       T.TargetLDBackendCtorFn = Fn;
    184   }
    185 
    186   /// RegisterTargetDiagnosticLineInfo - Register a DiagnosticLineInfo
    187   /// implementation for the given target.
    188   ///
    189   /// @param T - The target being registered
    190   /// @param Fn - A function to create DiagnosticLineInfo for the target
    191   static void
    192   RegisterDiagnosticLineInfo(mcld::Target &T,
    193                              mcld::Target::DiagnosticLineInfoCtorTy Fn)
    194   {
    195     if (!T.DiagnosticLineInfoCtorFn)
    196       T.DiagnosticLineInfoCtorFn = Fn;
    197   }
    198 
    199   /// lookupTarget - Lookup a target based on a llvm::Target.
    200   ///
    201   /// @param T - The llvm::Target to find
    202   static const mcld::Target *lookupTarget(const llvm::Target& T);
    203 
    204   /// lookupTarget - function wrapper of llvm::TargetRegistry::lookupTarget
    205   ///
    206   /// @param Triple - The Triple string
    207   /// @param Error  - The returned error message
    208   static const mcld::Target *lookupTarget(const std::string &Triple,
    209                                           std::string &Error);
    210 };
    211 
    212 /// RegisterTarget - Helper function for registering a target, for use in the
    213 /// target's initialization function. Usage:
    214 ///
    215 /// Target TheFooTarget; // The global target instance.
    216 ///
    217 /// extern "C" void LLVMInitializeFooTargetInfo() {
    218 ///   RegisterTarget X(TheFooTarget, "foo", "Foo description");
    219 /// }
    220 struct RegisterTarget
    221 {
    222   RegisterTarget(mcld::Target &T, const char *Name) {
    223     llvm::TargetRegistry::iterator TIter, TEnd = llvm::TargetRegistry::end();
    224     // lookup llvm::Target
    225     for( TIter=llvm::TargetRegistry::begin(); TIter!=TEnd; ++TIter ) {
    226       if( 0==strcmp(TIter->getName(), Name) )
    227         break;
    228     }
    229     T.setTarget(*TIter);
    230 
    231     TargetRegistry::RegisterTarget(T);
    232   }
    233 };
    234 
    235 /// RegisterTargetMachine - Helper template for registering a target machine
    236 /// implementation, for use in the target machine initialization
    237 /// function. Usage:
    238 ///
    239 /// extern "C" void LLVMInitializeFooTarget() {
    240 ///   extern mcld::Target TheFooTarget;
    241 ///   RegisterTargetMachine<mcld::FooTargetMachine> X(TheFooTarget);
    242 /// }
    243 template<class TargetMachineImpl>
    244 struct RegisterTargetMachine
    245 {
    246   RegisterTargetMachine(mcld::Target &T) {
    247     TargetRegistry::RegisterTargetMachine(T, &Allocator);
    248   }
    249 
    250 private:
    251   static mcld::LLVMTargetMachine *Allocator(const mcld::Target &T,
    252                                             llvm::TargetMachine& TM,
    253                                             const std::string &Triple) {
    254     return new TargetMachineImpl(TM, T, Triple);
    255   }
    256 };
    257 
    258 } //end namespace mcld
    259 
    260 #endif
    261 
    262