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