diff options
author | Dan Gohman <dan433584@gmail.com> | 2017-02-24 23:18:00 +0000 |
---|---|---|
committer | Dan Gohman <dan433584@gmail.com> | 2017-02-24 23:18:00 +0000 |
commit | d934cb8806dbddcbdf70fadf9b125af626fbcac3 (patch) | |
tree | 9791d4ffccafec115dbadb7e1f9cce94963dbc1c /llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp | |
parent | fb34a35c4eb11d30d9ba225c9daf84cf63f100fb (diff) | |
download | bcm5719-llvm-d934cb8806dbddcbdf70fadf9b125af626fbcac3.tar.gz bcm5719-llvm-d934cb8806dbddcbdf70fadf9b125af626fbcac3.zip |
[WebAssembly] Basic support for Wasm object file encoding.
With the "wasm32-unknown-unknown-wasm" triple, this allows writing out
simple wasm object files, and is another step in a larger series toward
migrating from ELF to general wasm object support. Note that this code
and the binary format itself is still experimental.
llvm-svn: 296190
Diffstat (limited to 'llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp')
-rw-r--r-- | llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp | 80 |
1 files changed, 64 insertions, 16 deletions
diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp index b8a0f589d7f..c198a262241 100644 --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp @@ -22,8 +22,10 @@ #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/MCSymbolELF.h" #include "llvm/MC/MCSymbolWasm.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FormattedStream.h" +#include "llvm/Support/Wasm.h" using namespace llvm; WebAssemblyTargetStreamer::WebAssemblyTargetStreamer(MCStreamer &S) @@ -51,14 +53,28 @@ static void PrintTypes(formatted_raw_ostream &OS, ArrayRef<MVT> Types) { OS << '\n'; } -void WebAssemblyTargetAsmStreamer::emitParam(ArrayRef<MVT> Types) { - OS << "\t.param \t"; - PrintTypes(OS, Types); +void WebAssemblyTargetAsmStreamer::emitParam(MCSymbol *Symbol, + ArrayRef<MVT> Types) { + if (!Types.empty()) { + OS << "\t.param \t"; + + // FIXME: Currently this applies to the "current" function; it may + // be cleaner to specify an explicit symbol as part of the directive. + + PrintTypes(OS, Types); + } } -void WebAssemblyTargetAsmStreamer::emitResult(ArrayRef<MVT> Types) { - OS << "\t.result \t"; - PrintTypes(OS, Types); +void WebAssemblyTargetAsmStreamer::emitResult(MCSymbol *Symbol, + ArrayRef<MVT> Types) { + if (!Types.empty()) { + OS << "\t.result \t"; + + // FIXME: Currently this applies to the "current" function; it may + // be cleaner to specify an explicit symbol as part of the directive. + + PrintTypes(OS, Types); + } } void WebAssemblyTargetAsmStreamer::emitLocal(ArrayRef<MVT> Types) { @@ -92,11 +108,13 @@ void WebAssemblyTargetAsmStreamer::emitIndIdx(const MCExpr *Value) { OS << "\t.indidx \t" << *Value << '\n'; } -void WebAssemblyTargetELFStreamer::emitParam(ArrayRef<MVT> Types) { +void WebAssemblyTargetELFStreamer::emitParam(MCSymbol *Symbol, + ArrayRef<MVT> Types) { // Nothing to emit; params are declared as part of the function signature. } -void WebAssemblyTargetELFStreamer::emitResult(ArrayRef<MVT> Types) { +void WebAssemblyTargetELFStreamer::emitResult(MCSymbol *Symbol, + ArrayRef<MVT> Types) { // Nothing to emit; results are declared as part of the function signature. } @@ -123,22 +141,52 @@ void WebAssemblyTargetELFStreamer::emitIndirectFunctionType( void WebAssemblyTargetELFStreamer::emitGlobalImport(StringRef name) { } -void WebAssemblyTargetWasmStreamer::emitParam(ArrayRef<MVT> Types) { - // Nothing to emit; params are declared as part of the function signature. +static unsigned MVT2WasmType(MVT Ty) { + switch (Ty.SimpleTy) { + case MVT::i32: return wasm::WASM_TYPE_I32; + case MVT::i64: return wasm::WASM_TYPE_I64; + case MVT::f32: return wasm::WASM_TYPE_F32; + case MVT::f64: return wasm::WASM_TYPE_F64; + default: llvm_unreachable("unsupported type"); + } } -void WebAssemblyTargetWasmStreamer::emitResult(ArrayRef<MVT> Types) { - // Nothing to emit; results are declared as part of the function signature. +void WebAssemblyTargetWasmStreamer::emitParam(MCSymbol *Symbol, + ArrayRef<MVT> Types) { + SmallVector<unsigned, 4> Params; + for (MVT Ty : Types) + Params.push_back(MVT2WasmType(Ty)); + + cast<MCSymbolWasm>(Symbol)->setParams(std::move(Params)); +} + +void WebAssemblyTargetWasmStreamer::emitResult(MCSymbol *Symbol, + ArrayRef<MVT> Types) { + SmallVector<unsigned, 4> Returns; + for (MVT Ty : Types) + Returns.push_back(MVT2WasmType(Ty)); + + cast<MCSymbolWasm>(Symbol)->setReturns(std::move(Returns)); } void WebAssemblyTargetWasmStreamer::emitLocal(ArrayRef<MVT> Types) { - Streamer.EmitULEB128IntValue(Types.size()); - for (MVT Type : Types) - Streamer.EmitIntValue(int64_t(WebAssembly::toValType(Type)), 1); + SmallVector<std::pair<MVT, uint32_t>, 4> Grouped; + for (MVT Type : Types) { + if (Grouped.empty() || Grouped.back().first != Type) + Grouped.push_back(std::make_pair(Type, 1)); + else + ++Grouped.back().second; + } + + Streamer.EmitULEB128IntValue(Grouped.size()); + for (auto Pair : Grouped) { + Streamer.EmitULEB128IntValue(Pair.second); + Streamer.EmitULEB128IntValue(uint64_t(WebAssembly::toValType(Pair.first))); + } } void WebAssemblyTargetWasmStreamer::emitEndFunc() { - Streamer.EmitIntValue(WebAssembly::End, 1); + llvm_unreachable(".end_func is not needed for direct wasm output"); } void WebAssemblyTargetWasmStreamer::emitIndIdx(const MCExpr *Value) { |