Sketch TargetRegistry support for MCCodeEmitter abstract interface.
[oota-llvm.git] / include / llvm / Target / TargetRegistry.h
index 93991dc687324f0614dd973c53eb9f6efddf3f29..14fbd45e991fec56fb3410d45df117f3a527e927 100644 (file)
 #define LLVM_TARGET_TARGETREGISTRY_H
 
 #include "llvm/ADT/Triple.h"
-// FIXME: We shouldn't need this header, but we need it until there is a
-// different interface to get the TargetAsmInfo.
-#include "llvm/Target/TargetMachine.h"
-// FIXME: We shouldn't need this header, but we need it until there is a
-// different interface to the target machines.
-#include "llvm/Module.h"
 #include <string>
 #include <cassert>
 
 namespace llvm {
-  class FunctionPass;
+  class AsmPrinter;
   class MCAsmParser;
+  class MCCodeEmitter;
   class Module;
+  class MCAsmInfo;
   class TargetAsmParser;
   class TargetMachine;
   class formatted_raw_ostream;
@@ -46,21 +42,27 @@ namespace llvm {
   /// will be zero initialized), and pass that instance to the TargetRegistry as
   /// part of their initialization.
   class Target {
-  private:
-    typedef unsigned (*TripleMatchQualityFnTy)(const std::string &TT);
+  public:
+    friend struct TargetRegistry;
 
-    typedef TargetMachine *(*TargetMachineCtorTy)(const Target &,
-                                                  const Module &, 
-                                                  const std::string &,
-                                                  const std::string &);
-    typedef FunctionPass *(*AsmPrinterCtorTy)(formatted_raw_ostream &,
-                                              TargetMachine &,
-                                              bool);
-    typedef TargetAsmParser *(*AsmParserCtorTy)(const Target &,
-                                                MCAsmParser &);
+    typedef unsigned (*TripleMatchQualityFnTy)(const std::string &TT);
 
-    friend struct TargetRegistry;
+    typedef const MCAsmInfo *(*AsmInfoCtorFnTy)(const Target &T,
+                                                const StringRef &TT);
+    typedef TargetMachine *(*TargetMachineCtorTy)(const Target &T,
+                                                  const std::string &TT,
+                                                  const std::string &Features);
+    typedef AsmPrinter *(*AsmPrinterCtorTy)(formatted_raw_ostream &OS,
+                                            TargetMachine &TM,
+                                            const MCAsmInfo *MAI,
+                                            bool VerboseAsm);
+    typedef TargetAsmParser *(*AsmParserCtorTy)(const Target &T,
+                                                MCAsmParser &P);
+    typedef MCCodeEmitter *(*CodeEmitterCtorTy)(const Target &T,
+                                                TargetMachine &TM,
+                                                const MCAsmInfo &MAI);
 
+  private:
     /// Next - The next registered target in the linked list, maintained by the
     /// TargetRegistry.
     Target *Next;
@@ -78,6 +80,8 @@ namespace llvm {
     /// HasJIT - Whether this target supports the JIT.
     bool HasJIT;
 
+    AsmInfoCtorFnTy AsmInfoCtorFn;
+    
     /// TargetMachineCtorFn - Construction function for this target's
     /// TargetMachine, if registered.
     TargetMachineCtorTy TargetMachineCtorFn;
@@ -90,7 +94,14 @@ namespace llvm {
     /// if registered.
     AsmParserCtorTy AsmParserCtorFn;
 
+    /// CodeEmitterCtorFn - Construction function for this target's CodeEmitter,
+    /// if registered.
+    CodeEmitterCtorTy CodeEmitterCtorFn;
+
   public:
+    /// @name Target Information
+    /// @{
+
     // getNext - Return the next registered target.
     const Target *getNext() const { return Next; }
 
@@ -100,6 +111,11 @@ namespace llvm {
     /// getShortDescription - Get a short description of the target.
     const char *getShortDescription() const { return ShortDesc; }
 
+    /// @}
+    /// @name Feature Predicates
+    /// @{
+
+    /// hasJIT - Check if this targets supports the just-in-time compilation.
     bool hasJIT() const { return HasJIT; }
 
     /// hasTargetMachine - Check if this target supports code generation.
@@ -111,30 +127,46 @@ namespace llvm {
     /// hasAsmParser - Check if this target supports .s parsing.
     bool hasAsmParser() const { return AsmParserCtorFn != 0; }
 
+    /// hasCodeEmitter - Check if this target supports instruction encoding.
+    bool hasCodeEmitter() const { return CodeEmitterCtorFn != 0; }
+
+    /// @}
+    /// @name Feature Constructors
+    /// @{
+    
+    /// createAsmInfo - Create a MCAsmInfo implementation for the specified
+    /// target triple.
+    ///
+    /// \arg Triple - This argument is used to determine the target machine
+    /// feature set; it should always be provided. Generally this should be
+    /// either the target triple from the module, or the target triple of the
+    /// host if that does not exist.
+    const MCAsmInfo *createAsmInfo(const StringRef &Triple) const {
+      if (!AsmInfoCtorFn)
+        return 0;
+      return AsmInfoCtorFn(*this, Triple);
+    }
+    
     /// createTargetMachine - Create a target specific machine implementation
-    /// for the module \arg M and \arg Triple.
+    /// for the specified \arg Triple.
     ///
-    /// \arg M - This argument is used for some machines to access the target
-    /// data.
     /// \arg Triple - This argument is used to determine the target machine
     /// feature set; it should always be provided. Generally this should be
     /// either the target triple from the module, or the target triple of the
     /// host if that does not exist.
-    TargetMachine *createTargetMachine(const Module &M,
-                                       const std::string &Triple,
+    TargetMachine *createTargetMachine(const std::string &Triple,
                                        const std::string &Features) const {
       if (!TargetMachineCtorFn)
         return 0;
-      return TargetMachineCtorFn(*this, M, Triple, Features);
+      return TargetMachineCtorFn(*this, Triple, Features);
     }
 
     /// createAsmPrinter - Create a target specific assembly printer pass.
-    FunctionPass *createAsmPrinter(formatted_raw_ostream &OS,
-                                   TargetMachine &M,
-                                   bool Verbose) const {
+    AsmPrinter *createAsmPrinter(formatted_raw_ostream &OS, TargetMachine &TM,
+                                 const MCAsmInfo *MAI, bool Verbose) const {
       if (!AsmPrinterCtorFn)
         return 0;
-      return AsmPrinterCtorFn(OS, M, Verbose);
+      return AsmPrinterCtorFn(OS, TM, MAI, Verbose);
     }
 
     /// createAsmParser - Create a target specific assembly parser.
@@ -146,11 +178,19 @@ namespace llvm {
         return 0;
       return AsmParserCtorFn(*this, Parser);
     }
+
+    /// createCodeEmitter - Create a target specific code emitter.
+    MCCodeEmitter *createCodeEmitter(TargetMachine &TM,
+                                     const MCAsmInfo *MAI) const {
+      if (!CodeEmitterCtorFn)
+        return 0;
+      return CodeEmitterCtorFn(*this, TM, *MAI);
+    }
+
+    /// @}
   };
 
   /// TargetRegistry - Generic interface to target specific features.
-  //
-  // FIXME: Provide Target* iterator.
   struct TargetRegistry {
     class iterator {
       const Target *Current;
@@ -199,24 +239,17 @@ namespace llvm {
     /// lookupTarget - Lookup a target based on a target triple.
     ///
     /// \param Triple - The triple to use for finding a target.
-    /// \param FallbackToHost - If true and no target is found for the given
-    /// \arg Triple, then the host's triple will be used.
-    /// \param RequireJIT - Require the target to support JIT compilation.
     /// \param Error - On failure, an error string describing why no target was
     /// found.
     static const Target *lookupTarget(const std::string &Triple,
-                                      bool FallbackToHost,
-                                      bool RequireJIT,
                                       std::string &Error);
 
     /// getClosestTargetForJIT - Pick the best target that is compatible with
     /// the current host.  If no close target can be found, this returns null
     /// and sets the Error string to a reason.
     ///
-    /// Mainted for compatibility through 2.6.
-    static const Target *getClosestTargetForJIT(std::string &Error) {
-      return lookupTarget("", true, true, Error);
-    }
+    /// Maintained for compatibility through 2.6.
+    static const Target *getClosestTargetForJIT(std::string &Error);
 
     /// @}
     /// @name Target Registration
@@ -242,7 +275,22 @@ namespace llvm {
                                const char *ShortDesc,
                                Target::TripleMatchQualityFnTy TQualityFn,
                                bool HasJIT = false);
-                               
+
+    /// RegisterAsmInfo - Register a MCAsmInfo implementation for the
+    /// given target.
+    /// 
+    /// Clients are responsible for ensuring that registration doesn't occur
+    /// while another thread is attempting to access the registry. Typically
+    /// this is done by initializing all targets at program startup.
+    /// 
+    /// @param T - The target being registered.
+    /// @param Fn - A function to construct a MCAsmInfo for the target.
+    static void RegisterAsmInfo(Target &T, Target::AsmInfoCtorFnTy Fn) {
+      // Ignore duplicate registration.
+      if (!T.AsmInfoCtorFn)
+        T.AsmInfoCtorFn = Fn;
+    }
+    
     /// RegisterTargetMachine - Register a TargetMachine implementation for the
     /// given target.
     /// 
@@ -288,6 +336,20 @@ namespace llvm {
         T.AsmParserCtorFn = Fn;
     }
 
+    /// RegisterCodeEmitter - Register a MCCodeEmitter implementation for the
+    /// given target.
+    /// 
+    /// Clients are responsible for ensuring that registration doesn't occur
+    /// while another thread is attempting to access the registry. Typically
+    /// this is done by initializing all targets at program startup.
+    ///
+    /// @param T - The target being registered.
+    /// @param Fn - A function to construct an AsmPrinter for the target.
+    static void RegisterCodeEmitter(Target &T, Target::CodeEmitterCtorTy Fn) {
+      if (!T.CodeEmitterCtorFn)
+        T.CodeEmitterCtorFn = Fn;
+    }
+
     /// @}
   };
 
@@ -319,6 +381,41 @@ namespace llvm {
     }
   };
 
+  /// RegisterAsmInfo - Helper template for registering a target assembly info
+  /// implementation.  This invokes the static "Create" method on the class to
+  /// actually do the construction.  Usage:
+  ///
+  /// extern "C" void LLVMInitializeFooTarget() {
+  ///   extern Target TheFooTarget;
+  ///   RegisterAsmInfo<FooMCAsmInfo> X(TheFooTarget);
+  /// }
+  template<class MCAsmInfoImpl>
+  struct RegisterAsmInfo {
+    RegisterAsmInfo(Target &T) {
+      TargetRegistry::RegisterAsmInfo(T, &Allocator);
+    }
+  private:
+    static const MCAsmInfo *Allocator(const Target &T, const StringRef &TT) {
+      return new MCAsmInfoImpl(T, TT);
+    }
+    
+  };
+
+  /// RegisterAsmInfoFn - Helper template for registering a target assembly info
+  /// implementation.  This invokes the specified function to do the
+  /// construction.  Usage:
+  ///
+  /// extern "C" void LLVMInitializeFooTarget() {
+  ///   extern Target TheFooTarget;
+  ///   RegisterAsmInfoFn X(TheFooTarget, TheFunction);
+  /// }
+  struct RegisterAsmInfoFn {
+    RegisterAsmInfoFn(Target &T, Target::AsmInfoCtorFnTy Fn) {
+      TargetRegistry::RegisterAsmInfo(T, Fn);
+    }
+  };
+
+
   /// RegisterTargetMachine - Helper template for registering a target machine
   /// implementation, for use in the target machine initialization
   /// function. Usage:
@@ -334,27 +431,12 @@ namespace llvm {
     }
 
   private:
-    static TargetMachine *Allocator(const Target &T, const Module &M,
-                                    const std::string &TT,
+    static TargetMachine *Allocator(const Target &T, const std::string &TT,
                                     const std::string &FS) {
       return new TargetMachineImpl(T, TT, FS);
     }
   };
 
-  template<class TargetMachineImpl>
-  struct RegisterTargetMachineDeprecated {
-    RegisterTargetMachineDeprecated(Target &T) {
-      TargetRegistry::RegisterTargetMachine(T, &Allocator);
-    }
-
-  private:
-    static TargetMachine *Allocator(const Target &T, const Module &M,
-                                    const std::string &TT,
-                                    const std::string &FS) {
-      return new TargetMachineImpl(T, M, FS);
-    }
-  };
-
   /// RegisterAsmPrinter - Helper template for registering a target specific
   /// assembly printer, for use in the target machine initialization
   /// function. Usage:
@@ -370,10 +452,9 @@ namespace llvm {
     }
 
   private:
-    static FunctionPass *Allocator(formatted_raw_ostream &OS,
-                                   TargetMachine &TM,
-                                   bool Verbose) {
-      return new AsmPrinterImpl(OS, TM, TM.getTargetAsmInfo(), Verbose);
+    static AsmPrinter *Allocator(formatted_raw_ostream &OS, TargetMachine &TM,
+                                 const MCAsmInfo *MAI, bool Verbose) {
+      return new AsmPrinterImpl(OS, TM, MAI, Verbose);
     }
   };
 
@@ -397,6 +478,27 @@ namespace llvm {
     }
   };
 
+  /// RegisterCodeEmitter - Helper template for registering a target specific
+  /// machine code emitter, for use in the target initialization
+  /// function. Usage:
+  ///
+  /// extern "C" void LLVMInitializeFooCodeEmitter() {
+  ///   extern Target TheFooTarget;
+  ///   RegisterCodeEmitter<FooCodeEmitter> X(TheFooTarget);
+  /// }
+  template<class CodeEmitterImpl>
+  struct RegisterCodeEmitter {
+    RegisterCodeEmitter(Target &T) {
+      TargetRegistry::RegisterCodeEmitter(T, &Allocator);
+    }
+
+  private:
+    static MCCodeEmitter *Allocator(const Target &T, TargetMachine &TM,
+                                    const MCAsmInfo &MAI) {
+      return new CodeEmitterImpl(T, TM, MAI);
+    }
+  };
+
 }
 
 #endif