aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-04-03 21:35:55 +0000
committerChris Lattner <sabre@nondot.org>2010-04-03 21:35:55 +0000
commit91bead790518fcf5cb26019fb1ebf2372e8a5b3f (patch)
tree069591723216e18906bac6c3117502c73a56bf0b /lib
parent47b7e5dae911bc98aa76fa5d2ee506c9304f941a (diff)
add a new EmitInlineAsm function to asmprinter to handle inline asm.
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
Diffstat (limited to 'lib')
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinter.cpp24
-rw-r--r--lib/MC/MCAsmStreamer.cpp22
-rw-r--r--lib/MC/MCStreamer.cpp9
3 files changed, 49 insertions, 6 deletions
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 2cb4d01574..0d6a2e2999 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -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
//
diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp
index 7a23aecf29..b92051791a 100644
--- a/lib/MC/MCAsmStreamer.cpp
+++ b/lib/MC/MCAsmStreamer.cpp
@@ -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();
}
diff --git a/lib/MC/MCStreamer.cpp b/lib/MC/MCStreamer.cpp
index 703acc4e59..c30dde8aed 100644
--- a/lib/MC/MCStreamer.cpp
+++ b/lib/MC/MCStreamer.cpp
@@ -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();
+}