]> granicus.if.org Git - llvm/commitdiff
[WebAssembly] Implement WASM_STACK_POINTER.
authorDan Gohman <dan433584@gmail.com>
Tue, 5 Dec 2017 17:23:43 +0000 (17:23 +0000)
committerDan Gohman <dan433584@gmail.com>
Tue, 5 Dec 2017 17:23:43 +0000 (17:23 +0000)
Use the .stack_pointer directive to implement WASM_STACK_POINTER for
specifying a global variable to be the stack pointer.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@319797 91177308-0d34-0410-b5e6-96231b3b80d8

lib/MC/WasmObjectWriter.cpp
lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp
lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h
lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
test/CodeGen/WebAssembly/stack-alignment.ll

index 42521ac72e2c3834d3369cdb8a543bdfa2123b52..88b960e457a5366ca396a6374b1e6a403671308b 100644 (file)
@@ -287,7 +287,7 @@ private:
   void writeLinkingMetaDataSection(
       ArrayRef<WasmDataSegment> Segments, uint32_t DataSize,
       SmallVector<std::pair<StringRef, uint32_t>, 4> SymbolFlags,
-      bool HasStackPointer, uint32_t StackPointerGlobal);
+      Optional<uint32_t> StackPointerGlobal);
 
   uint32_t getProvisionalValue(const WasmRelocationEntry &RelEntry);
   void applyRelocations(ArrayRef<WasmRelocationEntry> Relocations,
@@ -929,14 +929,14 @@ void WasmObjectWriter::writeDataRelocSection() {
 void WasmObjectWriter::writeLinkingMetaDataSection(
     ArrayRef<WasmDataSegment> Segments, uint32_t DataSize,
     SmallVector<std::pair<StringRef, uint32_t>, 4> SymbolFlags,
-    bool HasStackPointer, uint32_t StackPointerGlobal) {
+    Optional<uint32_t> StackPointerGlobal) {
   SectionBookkeeping Section;
   startSection(Section, wasm::WASM_SEC_CUSTOM, "linking");
   SectionBookkeeping SubSection;
 
-  if (HasStackPointer) {
+  if (StackPointerGlobal.hasValue()) {
     startSection(SubSection, wasm::WASM_STACK_POINTER);
-    encodeULEB128(StackPointerGlobal, getStream()); // id
+    encodeULEB128(StackPointerGlobal.getValue(), getStream()); // id
     endSection(SubSection);
   }
 
@@ -1010,9 +1010,9 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm,
   SmallPtrSet<const MCSymbolWasm *, 4> IsAddressTaken;
   unsigned NumFuncImports = 0;
   SmallVector<WasmDataSegment, 4> DataSegments;
-  uint32_t StackPointerGlobal = 0;
+  Optional<StringRef> StackPointerGlobalName;
+  Optional<uint32_t> StackPointerGlobal;
   uint32_t DataSize = 0;
-  bool HasStackPointer = false;
 
   // Populate the IsAddressTaken set.
   for (const WasmRelocationEntry &RelEntry : CodeRelocations) {
@@ -1143,10 +1143,7 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm,
     if (!DataFrag.getFixups().empty())
       report_fatal_error("fixups not supported in .stack_pointer");
     const SmallVectorImpl<char> &Contents = DataFrag.getContents();
-    if (Contents.size() != 4)
-      report_fatal_error("only one entry supported in .stack_pointer");
-    HasStackPointer = true;
-    StackPointerGlobal = NumGlobalImports + *(const int32_t *)Contents.data();
+    StackPointerGlobalName = StringRef(Contents.data(), Contents.size());
   }
 
   for (MCSection &Sec : Asm) {
@@ -1255,6 +1252,10 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm,
       SymbolIndices[&WS] = Index;
       DEBUG(dbgs() << "  -> global index: " << Index << "\n");
       Globals.push_back(Global);
+
+      if (StackPointerGlobalName.hasValue() &&
+          WS.getName() == StackPointerGlobalName.getValue())
+        StackPointerGlobal = Index;
     }
 
     // If the symbol is visible outside this translation unit, export it.
@@ -1331,7 +1332,7 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm,
   writeCodeRelocSection();
   writeDataRelocSection();
   writeLinkingMetaDataSection(DataSegments, DataSize, SymbolFlags,
-                              HasStackPointer, StackPointerGlobal);
+                              StackPointerGlobal);
 
   // TODO: Translate the .comment section to the output.
   // TODO: Translate debug sections to the output.
index c82a64d58246e39c627cf98dc4db70712a2eba20..2437b017688153b2cce080977713d0fab5d6cfb0 100644 (file)
@@ -108,8 +108,8 @@ void WebAssemblyTargetAsmStreamer::emitGlobal(
   }
 }
 
-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::emitGlobal(
 }
 
 void WebAssemblyTargetELFStreamer::emitStackPointer(
-    uint32_t Index) {
+    MCSymbol *Symbol) {
   llvm_unreachable(".stack_pointer encoding not yet implemented");
 }
 
@@ -238,11 +238,11 @@ void WebAssemblyTargetWasmStreamer::emitGlobal(
   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::emitIndirectFunctionType(
 }
 
 void WebAssemblyTargetWasmStreamer::emitGlobalImport(StringRef name) {
+  llvm_unreachable(".global_import is not needed for direct wasm output");
 }
index 102d7219a1e7494f366a0ef67766f6bafa6a44ae..db908572a58d99ba455ef2da62e53cdc7d56707a 100644 (file)
@@ -40,7 +40,7 @@ public:
   /// .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 @@ public:
   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 @@ public:
   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 @@ public:
   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,
index 5f7f3d694cd4cc90cefdf6f3c5ddc7bb3d016d80..1d606d49bed408b1a82c48b5e6ac346d55a54e3a 100644 (file)
@@ -78,6 +78,10 @@ WebAssemblyTargetStreamer *WebAssemblyAsmPrinter::getTargetStreamer() {
 //===----------------------------------------------------------------------===//
 
 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()) {
index 25e9d06db411bed5de67427299845b7831c7c350..6128c8a4d235824943b762202df337d57f72e4ef 100644 (file)
@@ -147,3 +147,5 @@ entry:
   call void @somefunc(i32* %static)
   ret void
 }
+
+; CHECK: .stack_pointer __stack_pointer