summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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