diff options
Diffstat (limited to 'llvm/lib/Target/WebAssembly')
6 files changed, 90 insertions, 13 deletions
diff --git a/llvm/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp b/llvm/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp index 0af13cffdb0..26461e2728d 100644 --- a/llvm/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp +++ b/llvm/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp @@ -242,3 +242,18 @@ const char *llvm::WebAssembly::TypeToString(MVT Ty) { llvm_unreachable("unsupported type"); } } + +const char *llvm::WebAssembly::TypeToString(wasm::ValType Type) { + switch (Type) { + case wasm::ValType::I32: + return "i32"; + case wasm::ValType::I64: + return "i64"; + case wasm::ValType::F32: + return "f32"; + case wasm::ValType::F64: + return "f64"; + default: + llvm_unreachable("unsupported type"); + } +} diff --git a/llvm/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h b/llvm/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h index d11f99c1ff3..c6158720d62 100644 --- a/llvm/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h +++ b/llvm/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h @@ -18,6 +18,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/CodeGen/MachineValueType.h" #include "llvm/MC/MCInstPrinter.h" +#include "llvm/Support/Wasm.h" namespace llvm { @@ -50,6 +51,7 @@ public: namespace WebAssembly { const char *TypeToString(MVT Ty); +const char *TypeToString(wasm::ValType Type); } // end namespace WebAssembly diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp index f3b6b100d65..ad59f2f4058 100644 --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp @@ -25,7 +25,6 @@ #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) @@ -88,13 +87,31 @@ void WebAssemblyTargetAsmStreamer::emitLocal(ArrayRef<MVT> Types) { } } -void WebAssemblyTargetAsmStreamer::emitGlobal(ArrayRef<MVT> Types) { - if (!Types.empty()) { +void WebAssemblyTargetAsmStreamer::emitGlobal( + ArrayRef<wasm::Global> Globals) { + if (!Globals.empty()) { OS << "\t.globalvar \t"; - PrintTypes(OS, Types); + + bool First = true; + for (const wasm::Global &G : Globals) { + if (First) + First = false; + else + OS << ", "; + OS << WebAssembly::TypeToString(G.Type); + if (!G.InitialModule.empty()) + OS << '=' << G.InitialModule << ':' << G.InitialName; + else + OS << '=' << G.InitialValue; + } + OS << '\n'; } } +void WebAssemblyTargetAsmStreamer::emitStackPointer(uint32_t Index) { + OS << "\t.stack_pointer\t" << Index << '\n'; +} + void WebAssemblyTargetAsmStreamer::emitEndFunc() { OS << "\t.endfunc\n"; } void WebAssemblyTargetAsmStreamer::emitIndirectFunctionType( @@ -135,10 +152,16 @@ void WebAssemblyTargetELFStreamer::emitLocal(ArrayRef<MVT> Types) { emitValueType(WebAssembly::toValType(Type)); } -void WebAssemblyTargetELFStreamer::emitGlobal(ArrayRef<MVT> Types) { +void WebAssemblyTargetELFStreamer::emitGlobal( + ArrayRef<wasm::Global> Globals) { llvm_unreachable(".globalvar encoding not yet implemented"); } +void WebAssemblyTargetELFStreamer::emitStackPointer( + uint32_t Index) { + llvm_unreachable(".stack_pointer encoding not yet implemented"); +} + void WebAssemblyTargetELFStreamer::emitEndFunc() { Streamer.EmitIntValue(WebAssembly::End, 1); } @@ -190,15 +213,36 @@ void WebAssemblyTargetWasmStreamer::emitLocal(ArrayRef<MVT> Types) { } } -void WebAssemblyTargetWasmStreamer::emitGlobal(ArrayRef<MVT> Types) { +void WebAssemblyTargetWasmStreamer::emitGlobal( + ArrayRef<wasm::Global> Globals) { // Encode the globals use by the funciton into the special .global_variables // section. This will later be decoded and turned into contents for the // Globals Section. Streamer.PushSection(); Streamer.SwitchSection(Streamer.getContext() .getWasmSection(".global_variables", 0, 0)); - for (MVT Ty : Types) - Streamer.EmitIntValue(int64_t(WebAssembly::toValType(Ty)), 1); + for (const wasm::Global &G : Globals) { + Streamer.EmitIntValue(int32_t(G.Type), 1); + Streamer.EmitIntValue(G.Mutable, 1); + if (G.InitialModule.empty()) { + Streamer.EmitIntValue(0, 1); // indicate that we have an int value + Streamer.EmitSLEB128IntValue(0); + } else { + Streamer.EmitIntValue(1, 1); // indicate that we have a module import + Streamer.EmitBytes(G.InitialModule); + Streamer.EmitIntValue(0, 1); // nul-terminate + Streamer.EmitBytes(G.InitialName); + Streamer.EmitIntValue(0, 1); // nul-terminate + } + } + Streamer.PopSection(); +} + +void WebAssemblyTargetWasmStreamer::emitStackPointer(uint32_t Index) { + Streamer.PushSection(); + Streamer.SwitchSection(Streamer.getContext() + .getWasmSection(".stack_pointer", 0, 0)); + Streamer.EmitIntValue(Index, 4); Streamer.PopSection(); } diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h index bb9a9c90c3a..68d6747298d 100644 --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h @@ -38,7 +38,9 @@ public: /// .local virtual void emitLocal(ArrayRef<MVT> Types) = 0; /// .globalvar - virtual void emitGlobal(ArrayRef<MVT> Types) = 0; + virtual void emitGlobal(ArrayRef<wasm::Global> Globals) = 0; + /// .stack_pointer + virtual void emitStackPointer(uint32_t Index) = 0; /// .endfunc virtual void emitEndFunc() = 0; /// .functype @@ -66,7 +68,8 @@ public: void emitParam(MCSymbol *Symbol, ArrayRef<MVT> Types) override; void emitResult(MCSymbol *Symbol, ArrayRef<MVT> Types) override; void emitLocal(ArrayRef<MVT> Types) override; - void emitGlobal(ArrayRef<MVT> Types) override; + void emitGlobal(ArrayRef<wasm::Global> Globals) override; + void emitStackPointer(uint32_t Index) override; void emitEndFunc() override; void emitIndirectFunctionType(StringRef name, SmallVectorImpl<MVT> &Params, @@ -83,7 +86,8 @@ public: void emitParam(MCSymbol *Symbol, ArrayRef<MVT> Types) override; void emitResult(MCSymbol *Symbol, ArrayRef<MVT> Types) override; void emitLocal(ArrayRef<MVT> Types) override; - void emitGlobal(ArrayRef<MVT> Types) override; + void emitGlobal(ArrayRef<wasm::Global> Globals) override; + void emitStackPointer(uint32_t Index) override; void emitEndFunc() override; void emitIndirectFunctionType(StringRef name, SmallVectorImpl<MVT> &Params, @@ -100,7 +104,8 @@ public: void emitParam(MCSymbol *Symbol, ArrayRef<MVT> Types) override; void emitResult(MCSymbol *Symbol, ArrayRef<MVT> Types) override; void emitLocal(ArrayRef<MVT> Types) override; - void emitGlobal(ArrayRef<MVT> Types) override; + void emitGlobal(ArrayRef<wasm::Global> Globals) override; + void emitStackPointer(uint32_t Index) override; void emitEndFunc() override; void emitIndirectFunctionType(StringRef name, SmallVectorImpl<MVT> &Params, diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp index c272eb4cbf5..d9c2dba5bac 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp @@ -97,6 +97,8 @@ void WebAssemblyAsmPrinter::EmitEndOfAsmFile(Module &M) { if (!TM.getTargetTriple().isOSBinFormatELF()) { MachineModuleInfoWasm &MMIW = MMI->getObjFileInfo<MachineModuleInfoWasm>(); getTargetStreamer()->emitGlobal(MMIW.getGlobals()); + if (MMIW.hasStackPointerGlobal()) + getTargetStreamer()->emitStackPointer(MMIW.getStackPointerGlobal()); } } diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp index 8b25285ad0d..4209bc333f2 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp @@ -192,7 +192,16 @@ void WebAssemblyFrameLowering::emitPrologue(MachineFunction &MF, auto &MMIW = MF.getMMI().getObjFileInfo<MachineModuleInfoWasm>(); if (!MMIW.hasStackPointerGlobal()) { MMIW.setStackPointerGlobal(MMIW.getGlobals().size()); - MMIW.addGlobal(MVT::i32); + + // Create the stack-pointer global. For now, just use the + // Emscripten/Binaryen ABI names. + wasm::Global G; + G.Type = wasm::ValType::I32; + G.Mutable = true; + G.InitialValue = 0; + G.InitialModule = "env"; + G.InitialName = "STACKTOP"; + MMIW.addGlobal(G); } BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::GET_GLOBAL_I32), SPReg) .addImm(MMIW.getStackPointerGlobal()); |