summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
diff options
context:
space:
mode:
authorJF Bastien <jfb@google.com>2015-08-25 22:58:05 +0000
committerJF Bastien <jfb@google.com>2015-08-25 22:58:05 +0000
commitb6091dfe0f9237184e825e4915cf36c9e64a6c5e (patch)
treeaecba3e39b73d781f260178ae49cad5a23f16858 /llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
parente283c5529e3c0ee7134470d40c8f30a3ef5e1fd4 (diff)
downloadbcm5719-llvm-b6091dfe0f9237184e825e4915cf36c9e64a6c5e.tar.gz
bcm5719-llvm-b6091dfe0f9237184e825e4915cf36c9e64a6c5e.zip
WebAssembly: emit `(func (param t) (result t))` s-expressions
Summary: Match spec format: https://github.com/WebAssembly/spec/blob/master/ml-proto/test/fac.wasm Reviewers: sunfish Subscribers: llvm-commits, jfb Differential Revision: http://reviews.llvm.org/D12307 llvm-svn: 245986
Diffstat (limited to 'llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp')
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp61
1 files changed, 61 insertions, 0 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
index 065ef87fb35..a81e35ea4da 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
@@ -27,6 +27,7 @@
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
@@ -66,6 +67,10 @@ private:
// AsmPrinter Implementation.
//===------------------------------------------------------------------===//
+ void EmitFunctionEntryLabel() override;
+ void EmitFunctionBodyStart() override;
+ void EmitFunctionBodyEnd() override;
+
void EmitInstruction(const MachineInstr *MI) override;
};
@@ -86,6 +91,62 @@ static SmallString<32> Name(const WebAssemblyInstrInfo *TII,
static std::string toSymbol(StringRef S) { return ("$" + S).str(); }
+static const char *toType(const Type *Ty) {
+ switch (Ty->getTypeID()) {
+ default: break;
+ case Type::FloatTyID: return "f32";
+ case Type::DoubleTyID: return "f64";
+ case Type::IntegerTyID:
+ switch (Ty->getIntegerBitWidth()) {
+ case 32: return "i32";
+ case 64: return "i64";
+ default: break;
+ }
+ }
+ DEBUG(dbgs() << "Invalid type "; Ty->print(dbgs()); dbgs() << '\n');
+ llvm_unreachable("invalid type");
+ return "<invalid>";
+}
+
+void WebAssemblyAsmPrinter::EmitFunctionEntryLabel() {
+ SmallString<128> Str;
+ raw_svector_ostream OS(Str);
+
+ CurrentFnSym->redefineIfPossible();
+
+ // The function label could have already been emitted if two symbols end up
+ // conflicting due to asm renaming. Detect this and emit an error.
+ if (CurrentFnSym->isVariable())
+ report_fatal_error("'" + Twine(CurrentFnSym->getName()) +
+ "' is a protected alias");
+ if (CurrentFnSym->isDefined())
+ report_fatal_error("'" + Twine(CurrentFnSym->getName()) +
+ "' label emitted multiple times to assembly file");
+
+ OS << "(func " << toSymbol(CurrentFnSym->getName());
+ OutStreamer->EmitRawText(OS.str());
+}
+
+void WebAssemblyAsmPrinter::EmitFunctionBodyStart() {
+ SmallString<128> Str;
+ raw_svector_ostream OS(Str);
+ const Function *F = MF->getFunction();
+ for (const Argument &A : F->args())
+ OS << " (param " << toType(A.getType()) << ')';
+ const Type *Rt = F->getReturnType();
+ if (!Rt->isVoidTy())
+ OS << " (result " << toType(Rt) << ')';
+ OS << '\n';
+ OutStreamer->EmitRawText(OS.str());
+}
+
+void WebAssemblyAsmPrinter::EmitFunctionBodyEnd() {
+ SmallString<128> Str;
+ raw_svector_ostream OS(Str);
+ OS << ") ;; end func " << toSymbol(CurrentFnSym->getName()) << '\n';
+ OutStreamer->EmitRawText(OS.str());
+}
+
void WebAssemblyAsmPrinter::EmitInstruction(const MachineInstr *MI) {
DEBUG(dbgs() << "EmitInstruction: " << *MI << '\n');
SmallString<128> Str;
OpenPOWER on IntegriCloud