diff options
author | JF Bastien <jfb@google.com> | 2015-08-25 22:58:05 +0000 |
---|---|---|
committer | JF Bastien <jfb@google.com> | 2015-08-25 22:58:05 +0000 |
commit | b6091dfe0f9237184e825e4915cf36c9e64a6c5e (patch) | |
tree | aecba3e39b73d781f260178ae49cad5a23f16858 /llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp | |
parent | e283c5529e3c0ee7134470d40c8f30a3ef5e1fd4 (diff) | |
download | bcm5719-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.cpp | 61 |
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; |