[WebAssembly] Implement WASM_STACK_POINTER.

Use the .stack_pointer directive to implement WASM_STACK_POINTER for
specifying a global variable to be the stack pointer.

llvm-svn: 319797
diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp
index c82a64d..2437b01 100644
--- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp
+++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp
@@ -108,8 +108,8 @@
   }
 }
 
-void WebAssemblyTargetAsmStreamer::emitStackPointer(uint32_t Index) {
-  OS << "\t.stack_pointer\t" << Index << '\n';
+void WebAssemblyTargetAsmStreamer::emitStackPointer(MCSymbol *Symbol) {
+  OS << "\t.stack_pointer\t" << Symbol->getName() << '\n';
 }
 
 void WebAssemblyTargetAsmStreamer::emitEndFunc() { OS << "\t.endfunc\n"; }
@@ -158,7 +158,7 @@
 }
 
 void WebAssemblyTargetELFStreamer::emitStackPointer(
-    uint32_t Index) {
+    MCSymbol *Symbol) {
   llvm_unreachable(".stack_pointer encoding not yet implemented");
 }
 
@@ -238,11 +238,11 @@
   Streamer.PopSection();
 }
 
-void WebAssemblyTargetWasmStreamer::emitStackPointer(uint32_t Index) {
+void WebAssemblyTargetWasmStreamer::emitStackPointer(MCSymbol *Symbol) {
   Streamer.PushSection();
   Streamer.SwitchSection(Streamer.getContext().getWasmSection(
       ".stack_pointer", SectionKind::getMetadata()));
-  Streamer.EmitIntValue(Index, 4);
+  Streamer.EmitBytes(Symbol->getName());
   Streamer.PopSection();
 }
 
@@ -277,4 +277,5 @@
 }
 
 void WebAssemblyTargetWasmStreamer::emitGlobalImport(StringRef name) {
+  llvm_unreachable(".global_import is not needed for direct wasm output");
 }
diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h
index 102d721..db90857 100644
--- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h
+++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h
@@ -40,7 +40,7 @@
   /// .globalvar
   virtual void emitGlobal(ArrayRef<wasm::Global> Globals) = 0;
   /// .stack_pointer
-  virtual void emitStackPointer(uint32_t Index) = 0;
+  virtual void emitStackPointer(MCSymbol *Symbol) = 0;
   /// .endfunc
   virtual void emitEndFunc() = 0;
   /// .functype
@@ -67,7 +67,7 @@
   void emitResult(MCSymbol *Symbol, ArrayRef<MVT> Types) override;
   void emitLocal(ArrayRef<MVT> Types) override;
   void emitGlobal(ArrayRef<wasm::Global> Globals) override;
-  void emitStackPointer(uint32_t Index) override;
+  void emitStackPointer(MCSymbol *Symbol) override;
   void emitEndFunc() override;
   void emitIndirectFunctionType(MCSymbol *Symbol,
                                 SmallVectorImpl<MVT> &Params,
@@ -85,7 +85,7 @@
   void emitResult(MCSymbol *Symbol, ArrayRef<MVT> Types) override;
   void emitLocal(ArrayRef<MVT> Types) override;
   void emitGlobal(ArrayRef<wasm::Global> Globals) override;
-  void emitStackPointer(uint32_t Index) override;
+  void emitStackPointer(MCSymbol *Symbol) override;
   void emitEndFunc() override;
   void emitIndirectFunctionType(MCSymbol *Symbol,
                                 SmallVectorImpl<MVT> &Params,
@@ -103,7 +103,7 @@
   void emitResult(MCSymbol *Symbol, ArrayRef<MVT> Types) override;
   void emitLocal(ArrayRef<MVT> Types) override;
   void emitGlobal(ArrayRef<wasm::Global> Globals) override;
-  void emitStackPointer(uint32_t Index) override;
+  void emitStackPointer(MCSymbol *Symbol) override;
   void emitEndFunc() override;
   void emitIndirectFunctionType(MCSymbol *Symbol,
                                 SmallVectorImpl<MVT> &Params,
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
index 5f7f3d6..1d606d4 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
@@ -78,6 +78,10 @@
 //===----------------------------------------------------------------------===//
 
 void WebAssemblyAsmPrinter::EmitEndOfAsmFile(Module &M) {
+  // Declare the stack pointer.
+  getTargetStreamer()->emitStackPointer(
+      GetExternalSymbolSymbol("__stack_pointer"));
+
   for (const auto &F : M) {
     // Emit function type info for all undefined functions
     if (F.isDeclarationForLinker() && !F.isIntrinsic()) {