Add MCSubtargetInfo target registry stuff.
[oota-llvm.git] / include / llvm / Target / TargetRegistry.h
index 8d44f666c57bdbb3dba5c0fafef321f1e464ce12..2e79488ecbb21b7075ea88bb6b055f19c3fbea2b 100644 (file)
@@ -35,6 +35,7 @@ namespace llvm {
   class MCInstPrinter;
   class MCInstrInfo;
   class MCRegisterInfo;
+  class MCSubtargetInfo;
   class MCStreamer;
   class TargetAsmBackend;
   class TargetAsmLexer;
@@ -69,6 +70,7 @@ namespace llvm {
                                           StringRef TT);
     typedef MCInstrInfo *(*MCInstrInfoCtorFnTy)(void);
     typedef MCRegisterInfo *(*MCRegInfoCtorFnTy)(void);
+    typedef MCSubtargetInfo *(*MCSubtargetInfoCtorFnTy)(void);
     typedef TargetMachine *(*TargetMachineCtorTy)(const Target &T,
                                                   const std::string &TT,
                                                   const std::string &CPU,
@@ -137,6 +139,10 @@ namespace llvm {
     /// if registered.
     MCRegInfoCtorFnTy MCRegInfoCtorFn;
 
+    /// MCSubtargetInfoCtorFn - Constructor function for this target's
+    /// MCSubtargetInfo, if registered.
+    MCSubtargetInfoCtorFnTy MCSubtargetInfoCtorFn;
+
     /// TargetMachineCtorFn - Construction function for this target's
     /// TargetMachine, if registered.
     TargetMachineCtorTy TargetMachineCtorFn;
@@ -262,6 +268,14 @@ namespace llvm {
       return MCRegInfoCtorFn();
     }
 
+    /// createMCSubtargetInfo - Create a MCSubtargetInfo implementation.
+    ///
+    MCSubtargetInfo *createMCSubtargetInfo() const {
+      if (!MCSubtargetInfoCtorFn)
+        return 0;
+      return MCSubtargetInfoCtorFn();
+    }
+
     /// createTargetMachine - Create a target specific machine implementation
     /// for the specified \arg Triple.
     ///
@@ -506,6 +520,22 @@ namespace llvm {
         T.MCRegInfoCtorFn = Fn;
     }
 
+    /// RegisterMCSubtargetInfo - Register a MCSubtargetInfo 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 MCSubtargetInfo for the target.
+    static void RegisterMCSubtargetInfo(Target &T,
+                                        Target::MCSubtargetInfoCtorFnTy Fn) {
+      // Ignore duplicate registration.
+      if (!T.MCSubtargetInfoCtorFn)
+        T.MCSubtargetInfoCtorFn = Fn;
+    }
+
     /// RegisterTargetMachine - Register a TargetMachine implementation for the
     /// given target.
     ///
@@ -782,6 +812,39 @@ namespace llvm {
     }
   };
 
+  /// RegisterMCSubtargetInfo - Helper template for registering a target
+  /// subtarget info implementation.  This invokes the static "Create" method
+  /// on the class to actually do the construction.  Usage:
+  ///
+  /// extern "C" void LLVMInitializeFooTarget() {
+  ///   extern Target TheFooTarget;
+  ///   RegisterMCSubtargetInfo<FooMCSubtargetInfo> X(TheFooTarget);
+  /// }
+  template<class MCSubtargetInfoImpl>
+  struct RegisterMCSubtargetInfo {
+    RegisterMCSubtargetInfo(Target &T) {
+      TargetRegistry::RegisterMCSubtargetInfo(T, &Allocator);
+    }
+  private:
+    static MCSubtargetInfo *Allocator() {
+      return new MCSubtargetInfoImpl();
+    }
+  };
+
+  /// RegisterMCSubtargetInfoFn - Helper template for registering a target
+  /// subtarget info implementation.  This invokes the specified function to
+  /// do the construction.  Usage:
+  ///
+  /// extern "C" void LLVMInitializeFooTarget() {
+  ///   extern Target TheFooTarget;
+  ///   RegisterMCSubtargetInfoFn X(TheFooTarget, TheFunction);
+  /// }
+  struct RegisterMCSubtargetInfoFn {
+    RegisterMCSubtargetInfoFn(Target &T, Target::MCSubtargetInfoCtorFnTy Fn) {
+      TargetRegistry::RegisterMCSubtargetInfo(T, Fn);
+    }
+  };
+
   /// RegisterTargetMachine - Helper template for registering a target machine
   /// implementation, for use in the target machine initialization
   /// function. Usage: