summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Gohman <dan433584@gmail.com>2017-03-30 23:58:19 +0000
committerDan Gohman <dan433584@gmail.com>2017-03-30 23:58:19 +0000
commit970d02c42dc122a4a550599aa9153965a521660b (patch)
tree585011ec096221540d87c3527856b4e5e25a2c43
parent1074cb5420f6cec1d2ea039d0f343719de7d84aa (diff)
downloadbcm5719-llvm-970d02c42dc122a4a550599aa9153965a521660b.tar.gz
bcm5719-llvm-970d02c42dc122a4a550599aa9153965a521660b.zip
[WebAssembly] Initial linking metadata support
Add support for the new relocations and linking metadata section support in https://github.com/WebAssembly/tool-conventions/blob/master/Linking.md. In particular, this allows LLVM to indicate which variable is the stack pointer, so that it can be linked with other objects. This also adds support for emitting type relocations for call_indirect instructions. Right now, this is mainly tested by using wabt and hexdump to examine the output on selected testcases. We'll add more tests as the design stablizes and more of the pieces are in place. llvm-svn: 299141
-rw-r--r--llvm/include/llvm/CodeGen/MachineModuleInfoImpls.h12
-rw-r--r--llvm/include/llvm/Support/Wasm.h18
-rw-r--r--llvm/include/llvm/Support/WasmRelocs/WebAssembly.def2
-rw-r--r--llvm/lib/MC/WasmObjectWriter.cpp146
-rw-r--r--llvm/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp15
-rw-r--r--llvm/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h2
-rw-r--r--llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp60
-rw-r--r--llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h13
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp2
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp11
10 files changed, 240 insertions, 41 deletions
diff --git a/llvm/include/llvm/CodeGen/MachineModuleInfoImpls.h b/llvm/include/llvm/CodeGen/MachineModuleInfoImpls.h
index 0dc190594c3..f28a79c5b5c 100644
--- a/llvm/include/llvm/CodeGen/MachineModuleInfoImpls.h
+++ b/llvm/include/llvm/CodeGen/MachineModuleInfoImpls.h
@@ -17,6 +17,7 @@
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/Support/Wasm.h"
namespace llvm {
class MCSymbol;
@@ -79,9 +80,10 @@ public:
/// MachineModuleInfoWasm - This is a MachineModuleInfoImpl implementation
/// for Wasm targets.
class MachineModuleInfoWasm : public MachineModuleInfoImpl {
- /// GVStubs - These stubs are used to materialize global addresses in PIC
- /// mode.
- std::vector<MVT> Globals;
+ /// WebAssembly global variables defined by CodeGen.
+ std::vector<wasm::Global> Globals;
+
+ /// The WebAssembly global variable which is the stack pointer.
unsigned StackPointerGlobal;
virtual void anchor(); // Out of line virtual method.
@@ -89,8 +91,8 @@ public:
MachineModuleInfoWasm(const MachineModuleInfo &)
: StackPointerGlobal(-1U) {}
- void addGlobal(MVT VT) { Globals.push_back(VT); }
- const std::vector<MVT> &getGlobals() const { return Globals; }
+ void addGlobal(const wasm::Global &G) { Globals.push_back(G); }
+ const std::vector<wasm::Global> &getGlobals() const { return Globals; }
bool hasStackPointerGlobal() const {
return StackPointerGlobal != -1U;
diff --git a/llvm/include/llvm/Support/Wasm.h b/llvm/include/llvm/Support/Wasm.h
index 99467ad3c63..8e6c418c818 100644
--- a/llvm/include/llvm/Support/Wasm.h
+++ b/llvm/include/llvm/Support/Wasm.h
@@ -170,6 +170,11 @@ enum class ValType {
F64 = WASM_TYPE_F64,
};
+// Linking metadata kinds.
+enum : unsigned {
+ WASM_STACK_POINTER = 0x1,
+};
+
#define WASM_RELOC(name, value) name = value,
enum : unsigned {
@@ -178,6 +183,19 @@ enum : unsigned {
#undef WASM_RELOC
+struct Global {
+ ValType Type;
+ bool Mutable;
+
+ // The initial value for this global is either the value of an imported
+ // global, in which case InitialModule and InitialName specify the global
+ // import, or a value, in which case InitialModule is empty and InitialValue
+ // holds the value.
+ StringRef InitialModule;
+ StringRef InitialName;
+ uint64_t InitialValue;
+};
+
} // end namespace wasm
} // end namespace llvm
diff --git a/llvm/include/llvm/Support/WasmRelocs/WebAssembly.def b/llvm/include/llvm/Support/WasmRelocs/WebAssembly.def
index 798f74499fa..da64e025478 100644
--- a/llvm/include/llvm/Support/WasmRelocs/WebAssembly.def
+++ b/llvm/include/llvm/Support/WasmRelocs/WebAssembly.def
@@ -9,3 +9,5 @@ WASM_RELOC(R_WEBASSEMBLY_TABLE_INDEX_I32, 2)
WASM_RELOC(R_WEBASSEMBLY_GLOBAL_ADDR_LEB, 3)
WASM_RELOC(R_WEBASSEMBLY_GLOBAL_ADDR_SLEB, 4)
WASM_RELOC(R_WEBASSEMBLY_GLOBAL_ADDR_I32, 5)
+WASM_RELOC(R_WEBASSEMBLY_TYPE_INDEX_LEB, 6)
+WASM_RELOC(R_WEBASSEMBLY_GLOBAL_INDEX_LEB, 7)
diff --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp
index 0b703f4387b..548d99fe4b9 100644
--- a/llvm/lib/MC/WasmObjectWriter.cpp
+++ b/llvm/lib/MC/WasmObjectWriter.cpp
@@ -50,16 +50,6 @@ struct SectionBookkeeping {
uint64_t ContentsOffset;
};
-// This record records information about a call_indirect which needs its
-// type index fixed up once we've computed type indices.
-struct TypeIndexFixup {
- uint64_t Offset;
- const MCSymbolWasm *Symbol;
- const MCSectionWasm *FixupSection;
- TypeIndexFixup(uint64_t O, const MCSymbolWasm *S, MCSectionWasm *F)
- : Offset(O), Symbol(S), FixupSection(F) {}
-};
-
class WasmObjectWriter : public MCObjectWriter {
/// Helper struct for containing some precomputed information on symbols.
struct WasmSymbolData {
@@ -80,7 +70,7 @@ class WasmObjectWriter : public MCObjectWriter {
std::vector<WasmRelocationEntry> DataRelocations;
// Fixups for call_indirect type indices.
- std::vector<TypeIndexFixup> TypeIndexFixups;
+ std::vector<WasmRelocationEntry> TypeIndexFixups;
// Index values to use for fixing up call_indirect type indices.
std::vector<uint32_t> TypeIndexFixupTypes;
@@ -269,8 +259,11 @@ void WasmObjectWriter::recordRelocation(MCAssembler &Asm,
if (RefA) {
if (RefA->getKind() == MCSymbolRefExpr::VK_WebAssembly_TYPEINDEX) {
- TypeIndexFixups.push_back(TypeIndexFixup(FixupOffset, SymA,
- &FixupSection));
+ assert(C == 0);
+ WasmRelocationEntry Rec(FixupOffset, SymA, C,
+ wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB,
+ &FixupSection);
+ TypeIndexFixups.push_back(Rec);
return;
}
}
@@ -358,7 +351,9 @@ struct WasmExport {
struct WasmGlobal {
wasm::ValType Type;
bool IsMutable;
- uint32_t InitialValue;
+ bool HasImport;
+ uint64_t InitialValue;
+ uint32_t ImportIndex;
};
} // end anonymous namespace
@@ -507,6 +502,29 @@ static void WriteRelocations(
}
}
+// Write out the the type relocation records that the linker will
+// need to handle.
+static void WriteTypeRelocations(
+ ArrayRef<WasmRelocationEntry> TypeIndexFixups,
+ ArrayRef<uint32_t> TypeIndexFixupTypes,
+ raw_pwrite_stream &Stream)
+{
+ for (size_t i = 0, e = TypeIndexFixups.size(); i < e; ++i) {
+ const WasmRelocationEntry &Fixup = TypeIndexFixups[i];
+ uint32_t Type = TypeIndexFixupTypes[i];
+
+ assert(Fixup.Type == wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB);
+ assert(Fixup.Addend == 0);
+
+ uint64_t Offset = Fixup.Offset +
+ Fixup.FixupSection->getSectionOffset();
+
+ encodeULEB128(Fixup.Type, Stream);
+ encodeULEB128(Offset, Stream);
+ encodeULEB128(Type, Stream);
+ }
+}
+
void WasmObjectWriter::writeObject(MCAssembler &Asm,
const MCAsmLayout &Layout) {
MCContext &Ctx = Asm.getContext();
@@ -526,6 +544,8 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm,
unsigned NumFuncImports = 0;
unsigned NumGlobalImports = 0;
SmallVector<char, 0> DataBytes;
+ uint32_t StackPointerGlobal = 0;
+ bool HasStackPointer = false;
// Populate the IsAddressTaken set.
for (WasmRelocationEntry RelEntry : CodeRelocations) {
@@ -605,15 +625,68 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm,
if (!DataFrag.getFixups().empty())
report_fatal_error("fixups not supported in .global_variables");
const SmallVectorImpl<char> &Contents = DataFrag.getContents();
- for (char p : Contents) {
+ for (const uint8_t *p = (const uint8_t *)Contents.data(),
+ *end = (const uint8_t *)Contents.data() + Contents.size();
+ p != end; ) {
WasmGlobal G;
- G.Type = wasm::ValType(p);
- G.IsMutable = true;
- G.InitialValue = 0;
+ if (end - p < 3)
+ report_fatal_error("truncated global variable encoding");
+ G.Type = wasm::ValType(int8_t(*p++));
+ G.IsMutable = bool(*p++);
+ G.HasImport = bool(*p++);
+ if (G.HasImport) {
+ G.InitialValue = 0;
+
+ WasmImport Import;
+ Import.ModuleName = (const char *)p;
+ const uint8_t *nul = (const uint8_t *)memchr(p, '\0', end - p);
+ if (!nul)
+ report_fatal_error("global module name must be nul-terminated");
+ p = nul + 1;
+ nul = (const uint8_t *)memchr(p, '\0', end - p);
+ if (!nul)
+ report_fatal_error("global base name must be nul-terminated");
+ Import.FieldName = (const char *)p;
+ p = nul + 1;
+
+ Import.Kind = wasm::WASM_EXTERNAL_GLOBAL;
+ Import.Type = int32_t(G.Type);
+
+ G.ImportIndex = NumGlobalImports;
+ ++NumGlobalImports;
+
+ Imports.push_back(Import);
+ } else {
+ unsigned n;
+ G.InitialValue = decodeSLEB128(p, &n);
+ G.ImportIndex = 0;
+ if (n > end - p)
+ report_fatal_error("global initial value must be valid SLEB128");
+ p += n;
+ }
Globals.push_back(G);
}
}
+ // In the special .stack_pointer section, we've encoded the stack pointer
+ // index.
+ MCSectionWasm *StackPtr = Ctx.getWasmSection(".stack_pointer", 0, 0);
+ if (!StackPtr->getFragmentList().empty()) {
+ if (StackPtr->getFragmentList().size() != 1)
+ report_fatal_error("only one .stack_pointer fragment supported");
+ const MCFragment &Frag = *StackPtr->begin();
+ if (Frag.hasInstructions() || Frag.getKind() != MCFragment::FT_Data)
+ report_fatal_error("only data supported in .stack_pointer");
+ const MCDataFragment &DataFrag = cast<MCDataFragment>(Frag);
+ 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();
+ }
+
// Handle defined symbols.
for (const MCSymbol &S : Asm.symbols()) {
// Ignore unnamed temporary symbols, which aren't ever exported, imported,
@@ -712,7 +785,9 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm,
WasmGlobal Global;
Global.Type = PtrType;
Global.IsMutable = false;
+ Global.HasImport = false;
Global.InitialValue = DataSection.getSectionOffset();
+ Global.ImportIndex = 0;
SymbolIndices[&WS] = Index;
Globals.push_back(Global);
}
@@ -736,7 +811,10 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm,
}
// Add types for indirect function calls.
- for (const TypeIndexFixup &Fixup : TypeIndexFixups) {
+ for (const WasmRelocationEntry &Fixup : TypeIndexFixups) {
+ assert(Fixup.Addend == 0);
+ assert(Fixup.Type == wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB);
+
WasmFunctionType F;
F.Returns = Fixup.Symbol->getReturns();
F.Params = Fixup.Symbol->getParams();
@@ -793,7 +871,7 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm,
encodeULEB128(Import.Type, getStream());
break;
case wasm::WASM_EXTERNAL_GLOBAL:
- encodeSLEB128(Import.Type, getStream());
+ encodeSLEB128(int32_t(Import.Type), getStream());
encodeULEB128(0, getStream()); // mutability
break;
default:
@@ -853,8 +931,15 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm,
writeValueType(Global.Type);
write8(Global.IsMutable);
- write8(wasm::WASM_OPCODE_I32_CONST);
- encodeSLEB128(Global.InitialValue, getStream()); // offset
+ if (Global.HasImport) {
+ assert(Global.InitialValue == 0);
+ write8(wasm::WASM_OPCODE_GET_GLOBAL);
+ encodeULEB128(Global.ImportIndex, getStream());
+ } else {
+ assert(Global.ImportIndex == 0);
+ write8(wasm::WASM_OPCODE_I32_CONST);
+ encodeSLEB128(Global.InitialValue, getStream()); // offset
+ }
write8(wasm::WASM_OPCODE_END);
}
@@ -944,7 +1029,9 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm,
uint32_t Type = TypeIndexFixupTypes[i];
unsigned Padding = PaddingFor5ByteULEB128(Type);
- const TypeIndexFixup &Fixup = TypeIndexFixups[i];
+ const WasmRelocationEntry &Fixup = TypeIndexFixups[i];
+ assert(Fixup.Addend == 0);
+ assert(Fixup.Type == wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB);
uint64_t Offset = Fixup.Offset +
Fixup.FixupSection->getSectionOffset();
@@ -1021,6 +1108,7 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm,
encodeULEB128(CodeRelocations.size(), getStream());
WriteRelocations(CodeRelocations, getStream(), SymbolIndices);
+ WriteTypeRelocations(TypeIndexFixups, TypeIndexFixupTypes, getStream());
endSection(Section);
}
@@ -1038,6 +1126,18 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm,
endSection(Section);
}
+ // === Linking Metadata Section ==============================================
+ if (HasStackPointer) {
+ startSection(Section, wasm::WASM_SEC_CUSTOM, "linking");
+
+ encodeULEB128(1, getStream()); // count
+
+ encodeULEB128(wasm::WASM_STACK_POINTER, getStream()); // type
+ encodeULEB128(StackPointerGlobal, getStream()); // id
+
+ endSection(Section);
+ }
+
// TODO: Translate the .comment section to the output.
// TODO: Translate debug sections to the output.
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());
OpenPOWER on IntegriCloud