Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ class WebAssemblyTargetStreamer : public MCTargetStreamer {
/// .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
Expand Down Expand Up @@ -66,7 +68,8 @@ class WebAssemblyTargetAsmStreamer final : public WebAssemblyTargetStreamer {
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,
Expand All @@ -83,7 +86,8 @@ class WebAssemblyTargetELFStreamer final : public WebAssemblyTargetStreamer {
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,
Expand All @@ -100,7 +104,8 @@ class WebAssemblyTargetWasmStreamer final : public WebAssemblyTargetStreamer {
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,
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
}

Expand Down
11 changes: 10 additions & 1 deletion llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down