summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorWouter van Oortmerssen <aardappel@gmail.com>2019-03-04 17:18:04 +0000
committerWouter van Oortmerssen <aardappel@gmail.com>2019-03-04 17:18:04 +0000
commitf3feb6adb919770f7ad4888ecb3a5c15076e5bf6 (patch)
tree07d7f20e8baa412aabf78b4aaa5503b6d8007fc9 /llvm/lib
parentde11105d2ece076e9d8dcfb01286643e81af8922 (diff)
downloadbcm5719-llvm-f3feb6adb919770f7ad4888ecb3a5c15076e5bf6.tar.gz
bcm5719-llvm-f3feb6adb919770f7ad4888ecb3a5c15076e5bf6.zip
[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
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/MC/MCParser/WasmAsmParser.cpp31
-rw-r--r--llvm/lib/MC/WasmObjectWriter.cpp2
-rw-r--r--llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp34
3 files changed, 57 insertions, 10 deletions
diff --git a/llvm/lib/MC/MCParser/WasmAsmParser.cpp b/llvm/lib/MC/MCParser/WasmAsmParser.cpp
index a8a48d1cd69..197e9052566 100644
--- a/llvm/lib/MC/MCParser/WasmAsmParser.cpp
+++ b/llvm/lib/MC/MCParser/WasmAsmParser.cpp
@@ -130,11 +130,27 @@ public:
if (expect(AsmToken::Comma, ",") || expect(AsmToken::At, "@") ||
expect(AsmToken::EndOfStatement, "eol"))
return true;
- // This is done automatically by the assembler for text sections currently,
- // so we don't need to emit that here. This is what it would do (and may
- // be needed later for other section types):
- // auto WS = getContext().getWasmSection(Name, SectionKind::getText());
- // getStreamer().SwitchSection(WS);
+ struct SectionType {
+ const char *Name;
+ SectionKind Kind;
+ };
+ static SectionType SectionTypes[] = {
+ { ".text", SectionKind::getText() },
+ { ".rodata", SectionKind::getReadOnly() },
+ { ".data", SectionKind::getData() },
+ // TODO: add more types.
+ };
+ for (size_t I = 0; I < sizeof(SectionTypes) / sizeof(SectionType); I++) {
+ if (Name.startswith(SectionTypes[I].Name)) {
+ auto WS = getContext().getWasmSection(Name, SectionTypes[I].Kind);
+ getStreamer().SwitchSection(WS);
+ return false;
+ }
+ }
+ // Not found, just ignore this section.
+ // For code in a text section WebAssemblyAsmParser automatically adds
+ // one section per function, so they're optional to be specified with
+ // this directive.
return false;
}
@@ -153,9 +169,8 @@ public:
if (expect(AsmToken::EndOfStatement, "eol"))
return true;
// This is done automatically by the assembler for functions currently,
- // so we don't need to emit that here. This is what it would do:
- (void)Sym;
- // getStreamer().emitELFSize(Sym, Expr);
+ // so this is only currently needed for data sections:
+ getStreamer().emitELFSize(Sym, Expr);
return false;
}
diff --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp
index b985d4bf4d3..e82ed5898b4 100644
--- a/llvm/lib/MC/WasmObjectWriter.cpp
+++ b/llvm/lib/MC/WasmObjectWriter.cpp
@@ -1348,7 +1348,7 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm,
LLVM_DEBUG(dbgs() << " -> function index: " << Index << "\n");
} else if (WS.isData()) {
- if (WS.isTemporary() && !WS.getSize())
+ if (!isInSymtab(WS))
continue;
if (!WS.isDefined()) {
diff --git a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
index eeccc3e6449..9d5bb3f11e0 100644
--- a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
+++ b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
@@ -172,6 +172,7 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
FunctionLocals,
Instructions,
EndFunction,
+ DataSection,
} CurrentState = FileStart;
// For ensuring blocks are properly nested.
@@ -552,6 +553,17 @@ public:
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 @@ public:
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 @@ public:
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());
OpenPOWER on IntegriCloud