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