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