add a new EmitInlineAsm function to asmprinter to handle inline asm.
authorChris Lattner <sabre@nondot.org>
Sat, 3 Apr 2010 21:35:55 +0000 (21:35 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 3 Apr 2010 21:35:55 +0000 (21:35 +0000)
If we have an MCAsmStreamer, we continue to emit asm textually,
otherwise we (currently) emit an error to errs and ignore it.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@100289 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/AsmPrinter.h
include/llvm/MC/MCStreamer.h
lib/CodeGen/AsmPrinter/AsmPrinter.cpp
lib/MC/MCAsmStreamer.cpp
lib/MC/MCStreamer.cpp

index a405932beadbf17c6f87a71cdca2ec2e982f15ed..51f55109c9c5f50084e7d87e8e5bb03fefffd9a6 100644 (file)
@@ -354,9 +354,12 @@ namespace llvm {
     /// isBlockOnlyReachableByFallthough - Return true if the basic block has
     /// exactly one predecessor and the control transfer mechanism between
     /// the predecessor and this block is a fall-through.
-    virtual bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const;
+    virtual bool
+    isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const;
 
   private:
+    /// EmitInlineAsm - Emit a blob of inline asm to the output streamer.
+    void EmitInlineAsm(StringRef Str);
 
     /// processDebugLoc - Processes the debug information of each machine
     /// instruction's DebugLoc. 
index bdcfdb2debee8455f105b70f2d0b090aae951ebb..d42342c145ed9967c2d82fa54a01601b3dfe6cc6 100644 (file)
@@ -62,9 +62,13 @@ class TargetAsmBackend;
     /// @name Assembly File Formatting.
     /// @{
     
-    /// isVerboseAsm - Return true if this streamer supports verbose assembly at
-    /// all.
+    /// isVerboseAsm - Return true if this streamer supports verbose assembly
+    /// and if it is enabled.
     virtual bool isVerboseAsm() const { return false; }
+    
+    /// hasRawTextSupport - Return true if this asm streamer supports emitting
+    /// unformatted text to the .s file with EmitRawText.
+    virtual bool hasRawTextSupport() const { return false; }
 
     /// AddComment - Add a comment that can be emitted to the generated .s
     /// file if applicable as a QoI issue to make the output of the compiler
@@ -278,6 +282,11 @@ class TargetAsmBackend;
     /// section.
     virtual void EmitInstruction(const MCInst &Inst) = 0;
 
+    /// EmitRawText - If this file is backed by a assembly streamer, this dumps
+    /// the specified string in the output .s file.  This capability is
+    /// indicated by the hasRawTextSupport() predicate.  By default this aborts.
+    virtual void EmitRawText(StringRef String);
+    
     /// Finish - Finish emission of machine code and flush any output.
     virtual void Finish() = 0;
   };
index 2cb4d01574a9de003ed6090cc27cbbae8dbe3be9..0d6a2e2999b9a5d1594a0e0573de15617c29a2ce 100644 (file)
@@ -125,14 +125,12 @@ bool AsmPrinter::doInitialization(Module &M) {
   for (GCModuleInfo::iterator I = MI->begin(), E = MI->end(); I != E; ++I)
     if (GCMetadataPrinter *MP = GetOrCreateGCPrinter(*I))
       MP->beginAssembly(O, *this, *MAI);
-  
+
+  // Emit module-level inline asm if it exists.
   if (!M.getModuleInlineAsm().empty()) {
     OutStreamer.AddComment("Start of file scope inline assembly");
     OutStreamer.AddBlankLine();
-    O << M.getModuleInlineAsm();
-    
-    if (*M.getModuleInlineAsm().rbegin() != '\n')
-      OutStreamer.AddBlankLine();
+    EmitInlineAsm(M.getModuleInlineAsm());
     OutStreamer.AddComment("End of file scope inline assembly");
     OutStreamer.AddBlankLine();
   }
@@ -879,6 +877,22 @@ void AsmPrinter::EmitXXStructorList(Constant *List) {
     }
 }
 
+/// EmitInlineAsm - Emit a blob of inline asm to the output streamer.
+void AsmPrinter::EmitInlineAsm(StringRef Str) {
+  assert(!Str.empty() && "Can't emit empty inline asm block");
+  
+  // If the output streamer is actually a .s file, just emit the blob textually.
+  // This is useful in case the asm parser doesn't handle something but the
+  // system assembler does.
+  if (OutStreamer.hasRawTextSupport()) {
+    OutStreamer.EmitRawText(Str);
+    return;
+  }
+  
+  errs() << "Inline asm not supported by this streamer!\n";
+}
+
+
 //===--------------------------------------------------------------------===//
 // Emission and print routines
 //
index 7a23aecf2970a225f1ae36f1c85e9565381b9918..b92051791a0bd31196b1c96f006a8286c7913721 100644 (file)
@@ -68,6 +68,9 @@ public:
   /// isVerboseAsm - Return true if this streamer supports verbose assembly at
   /// all.
   virtual bool isVerboseAsm() const { return IsVerboseAsm; }
+  
+  /// hasRawTextSupport - We support EmitRawText.
+  virtual bool hasRawTextSupport() const { return true; }
 
   /// AddComment - Add a comment that can be emitted to the generated .s
   /// file if applicable as a QoI issue to make the output of the compiler
@@ -145,6 +148,11 @@ public:
 
   virtual void EmitInstruction(const MCInst &Inst);
   
+  /// EmitRawText - If this file is backed by a assembly streamer, this dumps
+  /// the specified string in the output .s file.  This capability is
+  /// indicated by the hasRawTextSupport() predicate.
+  virtual void EmitRawText(StringRef String);
+  
   virtual void Finish();
   
   /// @}
@@ -195,7 +203,6 @@ void MCAsmStreamer::EmitCommentsAndEOL() {
   CommentStream.resync();
 }
 
-
 static inline int64_t truncateToSize(int64_t Value, unsigned Bytes) {
   assert(Bytes && "Invalid size!");
   return Value & ((uint64_t) (int64_t) -1 >> (64 - Bytes * 8));
@@ -634,6 +641,19 @@ void MCAsmStreamer::EmitInstruction(const MCInst &Inst) {
   EmitEOL();
 }
 
+/// EmitRawText - If this file is backed by a assembly streamer, this dumps
+/// the specified string in the output .s file.  This capability is
+/// indicated by the hasRawTextSupport() predicate.
+void MCAsmStreamer::EmitRawText(StringRef String) {
+  if (!CommentToEmit.empty() || CommentStream.GetNumBytesInBuffer() != 0)
+    EmitCommentsAndEOL();
+  
+  OS << String;
+  
+  if (!String.empty() && String.back() != '\n')
+    OS << '\n';
+}
+
 void MCAsmStreamer::Finish() {
   OS.flush();
 }
index 703acc4e59911775b837ed9b6fe96ef92f63e8cb..c30dde8aed438749cafb2ae768f1f824c78db7cf 100644 (file)
@@ -44,3 +44,12 @@ void MCStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue,
   for (uint64_t i = 0, e = NumBytes; i != e; ++i)
     EmitValue(E, 1, AddrSpace);
 }
+
+/// EmitRawText - If this file is backed by a assembly streamer, this dumps
+/// the specified string in the output .s file.  This capability is
+/// indicated by the hasRawTextSupport() predicate.
+void MCStreamer::EmitRawText(StringRef String) {
+  errs() << "EmitRawText called on an MCStreamer that doesn't support it, "
+  " something must not be fully mc'ized\n";
+  abort();
+}