[llvm-commits] [llvm] r80188 - in /llvm/trunk: include/llvm/MC/MCCodeEmitter.h include/llvm/MC/MCStreamer.h include/llvm/Target/TargetRegistry.h lib/MC/MCAsmStreamer.cpp tools/llvm-mc/llvm-mc.cpp

Daniel Dunbar daniel at zuster.org
Wed Aug 26 17:51:57 PDT 2009


Author: ddunbar
Date: Wed Aug 26 19:51:57 2009
New Revision: 80188

URL: http://llvm.org/viewvc/llvm-project?rev=80188&view=rev
Log:
Sketch TargetRegistry support for MCCodeEmitter abstract interface.
 - Of course, nothing actually can provide this interface yet.

Added:
    llvm/trunk/include/llvm/MC/MCCodeEmitter.h
Modified:
    llvm/trunk/include/llvm/MC/MCStreamer.h
    llvm/trunk/include/llvm/Target/TargetRegistry.h
    llvm/trunk/lib/MC/MCAsmStreamer.cpp
    llvm/trunk/tools/llvm-mc/llvm-mc.cpp

Added: llvm/trunk/include/llvm/MC/MCCodeEmitter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCCodeEmitter.h?rev=80188&view=auto

==============================================================================
--- llvm/trunk/include/llvm/MC/MCCodeEmitter.h (added)
+++ llvm/trunk/include/llvm/MC/MCCodeEmitter.h Wed Aug 26 19:51:57 2009
@@ -0,0 +1,32 @@
+//===-- llvm/MC/MCCodeEmitter.h - Instruction Encoding ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCCODEEMITTER_H
+#define LLVM_MC_MCCODEEMITTER_H
+
+namespace llvm {
+
+/// MCCodeEmitter - Generic instruction encoding interface.
+class MCCodeEmitter {
+  MCCodeEmitter(const MCCodeEmitter &);   // DO NOT IMPLEMENT
+  void operator=(const MCCodeEmitter &);  // DO NOT IMPLEMENT
+protected: // Can only create subclasses.
+  MCCodeEmitter();
+ 
+public:
+  virtual ~MCCodeEmitter();
+
+  /// EncodeInstruction - Encode the given \arg Inst to bytes on the output
+  /// stream \arg OS.
+  virtual void EncodeInstruction(const MCInst &Inst, raw_ostream &OS) = 0;
+};
+
+} // End llvm namespace
+
+#endif

Modified: llvm/trunk/include/llvm/MC/MCStreamer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCStreamer.h?rev=80188&r1=80187&r2=80188&view=diff

==============================================================================
--- llvm/trunk/include/llvm/MC/MCStreamer.h (original)
+++ llvm/trunk/include/llvm/MC/MCStreamer.h Wed Aug 26 19:51:57 2009
@@ -18,14 +18,15 @@
 
 namespace llvm {
   class AsmPrinter;
+  class MCAsmInfo;
+  class MCCodeEmitter;
   class MCContext;
-  class MCValue;
   class MCInst;
   class MCSection;
   class MCSymbol;
+  class MCValue;
   class StringRef;
   class raw_ostream;
-  class MCAsmInfo;
 
   /// MCStreamer - Streaming machine code generation interface.  This interface
   /// is intended to provide a programatic interface that is very similar to the
@@ -241,7 +242,8 @@
   ///
   /// \arg AP - If given, an AsmPrinter to use for printing instructions.
   MCStreamer *createAsmStreamer(MCContext &Ctx, raw_ostream &OS,
-                                const MCAsmInfo &MAI, AsmPrinter *AP = 0);
+                                const MCAsmInfo &MAI, AsmPrinter *AP = 0,
+                                MCCodeEmitter *CE = 0);
 
   // FIXME: These two may end up getting rolled into a single
   // createObjectStreamer interface, which implements the assembler backend, and

Modified: llvm/trunk/include/llvm/Target/TargetRegistry.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetRegistry.h?rev=80188&r1=80187&r2=80188&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Target/TargetRegistry.h (original)
+++ llvm/trunk/include/llvm/Target/TargetRegistry.h Wed Aug 26 19:51:57 2009
@@ -26,6 +26,7 @@
 namespace llvm {
   class AsmPrinter;
   class MCAsmParser;
+  class MCCodeEmitter;
   class Module;
   class MCAsmInfo;
   class TargetAsmParser;
@@ -57,6 +58,10 @@
                                             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.
@@ -89,7 +94,14 @@
     /// 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; }
 
@@ -99,6 +111,11 @@
     /// 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.
@@ -110,6 +127,12 @@
     /// 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.
@@ -155,6 +178,16 @@
         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.
@@ -303,6 +336,20 @@
         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;
+    }
+
     /// @}
   };
 
@@ -431,6 +478,27 @@
     }
   };
 
+  /// 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

Modified: llvm/trunk/lib/MC/MCAsmStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAsmStreamer.cpp?rev=80188&r1=80187&r2=80188&view=diff

==============================================================================
--- llvm/trunk/lib/MC/MCAsmStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCAsmStreamer.cpp Wed Aug 26 19:51:57 2009
@@ -8,7 +8,9 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/MC/MCStreamer.h"
+#include "llvm/ADT/SmallString.h"
 #include "llvm/CodeGen/AsmPrinter.h"
+#include "llvm/MC/MCCodeEmitter.h"
 #include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCInst.h"
 #include "llvm/MC/MCSectionMachO.h"
@@ -17,6 +19,7 @@
 #include "llvm/MC/MCAsmInfo.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Format.h"
 #include "llvm/Support/raw_ostream.h"
 using namespace llvm;
 
@@ -26,10 +29,12 @@
   raw_ostream &OS;
   const MCAsmInfo &MAI;
   AsmPrinter *Printer;
+  MCCodeEmitter *Emitter;
 public:
   MCAsmStreamer(MCContext &Context, raw_ostream &_OS, const MCAsmInfo &tai,
-                AsmPrinter *_AsmPrinter)
-    : MCStreamer(Context), OS(_OS), MAI(tai), Printer(_AsmPrinter) {}
+                AsmPrinter *_Printer, MCCodeEmitter *_Emitter)
+    : MCStreamer(Context), OS(_OS), MAI(tai), Printer(_Printer),
+      Emitter(_Emitter) {}
   ~MCAsmStreamer() {}
 
   /// @name MCStreamer Interface
@@ -290,6 +295,23 @@
 void MCAsmStreamer::EmitInstruction(const MCInst &Inst) {
   assert(CurSection && "Cannot emit contents before setting section!");
 
+  // Show the encoding if we have a code emitter.
+  if (Emitter) {
+    SmallString<256> Code;
+    raw_svector_ostream VecOS(Code);
+    Emitter->EncodeInstruction(Inst, VecOS);
+    VecOS.flush();
+
+    OS.indent(20);
+    OS << " # encoding: [";
+    for (unsigned i = 0, e = Code.size(); i != e; ++i) {
+      if (i + 1 != e)
+        OS << ',';
+      OS << format("%#04x", Code[i]);
+    }
+    OS << "]\n";
+  }
+
   // If we have an AsmPrinter, use that to print.
   if (Printer) {
     Printer->printMCInst(&Inst);
@@ -314,6 +336,7 @@
 }
     
 MCStreamer *llvm::createAsmStreamer(MCContext &Context, raw_ostream &OS,
-                                    const MCAsmInfo &MAI, AsmPrinter *AP) {
-  return new MCAsmStreamer(Context, OS, MAI, AP);
+                                    const MCAsmInfo &MAI, AsmPrinter *AP,
+                                    MCCodeEmitter *CE) {
+  return new MCAsmStreamer(Context, OS, MAI, AP, CE);
 }

Modified: llvm/trunk/tools/llvm-mc/llvm-mc.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mc/llvm-mc.cpp?rev=80188&r1=80187&r2=80188&view=diff

==============================================================================
--- llvm/trunk/tools/llvm-mc/llvm-mc.cpp (original)
+++ llvm/trunk/tools/llvm-mc/llvm-mc.cpp Wed Aug 26 19:51:57 2009
@@ -13,6 +13,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCCodeEmitter.h"
 #include "llvm/MC/MCSectionMachO.h"
 #include "llvm/MC/MCStreamer.h"
 #include "llvm/ADT/OwningPtr.h"
@@ -235,6 +236,7 @@
   }
 
   OwningPtr<AsmPrinter> AP;
+  OwningPtr<MCCodeEmitter> CE;
   OwningPtr<MCStreamer> Str;
 
   if (FileType == OFT_AssemblyFile) {
@@ -242,7 +244,8 @@
     assert(TAI && "Unable to create target asm info!");
 
     AP.reset(TheTarget->createAsmPrinter(*Out, *TM, TAI, true));
-    Str.reset(createAsmStreamer(Ctx, *Out, *TAI, AP.get()));
+    CE.reset(TheTarget->createCodeEmitter(*TM, TAI));
+    Str.reset(createAsmStreamer(Ctx, *Out, *TAI, AP.get(), CE.get()));
   } else {
     assert(FileType == OFT_ObjectFile && "Invalid file type!");
     Str.reset(createMachOStreamer(Ctx, *Out));





More information about the llvm-commits mailing list