[WebAssembly] Add support for data sections in the assembler.
Summary:
This is quite minimal so far, introduce them with .section,
fill them with .int8 or .asciz, end with .size
Reviewers: dschuff, sbc100, aheejin
Subscribers: jgravelle-google, sunfish, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D58660
llvm-svn: 355321
diff --git a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
index eeccc3e..9d5bb3f 100644
--- a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
+++ b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
@@ -172,6 +172,7 @@
FunctionLocals,
Instructions,
EndFunction,
+ DataSection,
} CurrentState = FileStart;
// For ensuring blocks are properly nested.
@@ -552,6 +553,17 @@
return false;
}
+ bool CheckDataSection() {
+ if (CurrentState != DataSection) {
+ auto WS = cast<MCSectionWasm>(getStreamer().getCurrentSection().first);
+ if (WS && WS->getKind().isText())
+ return error("data directive must occur in a data segment: ",
+ Lexer.getTok());
+ }
+ CurrentState = DataSection;
+ return false;
+ }
+
// This function processes wasm-specific directives streamed to
// WebAssemblyTargetStreamer, all others go to the generic parser
// (see WasmAsmParser).
@@ -650,6 +662,25 @@
return expect(AsmToken::EndOfStatement, "EOL");
}
+ if (DirectiveID.getString() == ".int8") {
+ if (CheckDataSection()) return true;
+ int64_t V;
+ if (Parser.parseAbsoluteExpression(V))
+ return error("Cannot parse int8 constant: ", Lexer.getTok());
+ // TODO: error if value doesn't fit?
+ Out.EmitIntValue(static_cast<uint64_t>(V), 1);
+ return expect(AsmToken::EndOfStatement, "EOL");
+ }
+
+ if (DirectiveID.getString() == ".asciz") {
+ if (CheckDataSection()) return true;
+ std::string S;
+ if (Parser.parseEscapedString(S))
+ return error("Cannot parse string constant: ", Lexer.getTok());
+ Out.EmitBytes(StringRef(S.c_str(), S.length() + 1));
+ return expect(AsmToken::EndOfStatement, "EOL");
+ }
+
return true; // We didn't process this directive.
}
@@ -717,9 +748,10 @@
void onEndOfFunction() {
// Automatically output a .size directive, so it becomes optional for the
// user.
+ if (!LastFunctionLabel) return;
auto TempSym = getContext().createLinkerPrivateTempSymbol();
getStreamer().EmitLabel(TempSym);
- auto Start = MCSymbolRefExpr::create(LastLabel, getContext());
+ auto Start = MCSymbolRefExpr::create(LastFunctionLabel, getContext());
auto End = MCSymbolRefExpr::create(TempSym, getContext());
auto Expr =
MCBinaryExpr::create(MCBinaryExpr::Sub, End, Start, getContext());