[llvm-commits] [llvm] r100491 - in /llvm/trunk: lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp tools/llc/llc.cpp

Chris Lattner sabre at nondot.org
Mon Apr 5 16:11:25 PDT 2010


Author: lattner
Date: Mon Apr  5 18:11:24 2010
New Revision: 100491

URL: http://llvm.org/viewvc/llvm-project?rev=100491&view=rev
Log:
add .o file writing for inline asm in llc.  Here's a silly
demo:

$ clang asm.c -S -o - -emit-llvm | llc -filetype=obj -o t.o
<inline asm>:1:2: error: unrecognized instruction
	abc incl    %eax
	^
LLVM ERROR: Error parsing inline asm

Only problem seems to be that the parser finalizes OutStreamer 
at the end of the first inline asm, which isn't what we want.
For example:

$ cat asm.c
int foo(int X) {
 __asm__ ("incl    %0" : "+r" (X));
 return X;
}
$ clang asm.c -S -o - -emit-llvm | llc
...
	subq	$8, %rsp
	movl	%edi, (%rsp)
	movl	%edi, %eax
	## InlineAsm Start
	incl    %eax
	## InlineAsm End
	movl	%eax, (%rsp)
	movl	%eax, 4(%rsp)
	addq	$8, %rsp
	ret
$ clang asm.c -S -o - -emit-llvm | llc -filetype=obj -o t.o
$ otool -tv t.o
t.o:
(__TEXT,__text) section
_foo:
0000000000000000	subq	$0x08,%rsp
0000000000000004	movl	%edi,(%rsp)
0000000000000007	movl	%edi,%eax
0000000000000009	incl	%eax
$ 

don't stop at inc!


Modified:
    llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
    llvm/trunk/tools/llc/llc.cpp

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp?rev=100491&r1=100490&r2=100491&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp Mon Apr  5 18:11:24 2010
@@ -18,9 +18,16 @@
 #include "llvm/MC/MCAsmInfo.h"
 #include "llvm/MC/MCStreamer.h"
 #include "llvm/MC/MCSymbol.h"
+#include "llvm/MC/MCParser/AsmParser.h"
+#include "llvm/Target/TargetAsmParser.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetRegistry.h"
+#include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/SourceMgr.h"
 #include "llvm/Support/raw_ostream.h"
 using namespace llvm;
 
@@ -28,6 +35,11 @@
 void AsmPrinter::EmitInlineAsm(StringRef Str) const {
   assert(!Str.empty() && "Can't emit empty inline asm block");
   
+  // Remember if the buffer is nul terminated or not so we can avoid a copy.
+  bool isNullTerminated = Str.back() == 0;
+  if (isNullTerminated)
+    Str = Str.substr(0, Str.size()-1);
+  
   // 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.
@@ -36,7 +48,27 @@
     return;
   }
   
-  errs() << "Inline asm not supported by this streamer!\n";
+  SourceMgr SrcMgr;
+  MemoryBuffer *Buffer;
+  if (isNullTerminated)
+    Buffer = MemoryBuffer::getMemBuffer(Str, "<inline asm>");
+  else
+    Buffer = MemoryBuffer::getMemBufferCopy(Str, "<inline asm>");
+
+  // Tell SrcMgr about this buffer, it takes ownership of the buffer.
+  SrcMgr.AddNewSourceBuffer(Buffer, SMLoc());
+  
+  AsmParser Parser(SrcMgr, OutContext, OutStreamer, *MAI);
+  OwningPtr<TargetAsmParser> TAP(TM.getTarget().createAsmParser(Parser));
+  if (!TAP)
+    llvm_report_error("Inline asm not supported by this streamer because"
+                      " we don't have an asm parser for this target\n");
+  Parser.setTargetParser(*TAP.get());
+
+  // Don't implicitly switch to the text section before the asm.
+  int Res = Parser.Run(/*NoInitialTextSection*/ true);
+  if (Res)
+    llvm_report_error("Error parsing inline asm\n");
 }
 
 
@@ -249,8 +281,7 @@
     }
     }
   }
-  OS << "\n";
-  
+  OS << '\n' << (char)0;  // null terminate string.
   EmitInlineAsm(OS.str());
   
   // Emit the #NOAPP end marker.  This has to happen even if verbose-asm isn't

Modified: llvm/trunk/tools/llc/llc.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llc/llc.cpp?rev=100491&r1=100490&r2=100491&view=diff
==============================================================================
--- llvm/trunk/tools/llc/llc.cpp (original)
+++ llvm/trunk/tools/llc/llc.cpp Mon Apr  5 18:11:24 2010
@@ -214,6 +214,7 @@
   // Initialize targets first, so that --version shows registered targets.
   InitializeAllTargets();
   InitializeAllAsmPrinters();
+  InitializeAllAsmParsers();
 
   cl::ParseCommandLineOptions(argc, argv, "llvm system compiler\n");
   





More information about the llvm-commits mailing list