summaryrefslogtreecommitdiff
path: root/llvm/lib/Target/WebAssembly/AsmParser
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/WebAssembly/AsmParser')
-rw-r--r--llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp45
1 files changed, 36 insertions, 9 deletions
diff --git a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
index ea99cee3eb3bf..e29d85d7588d2 100644
--- a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
+++ b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
@@ -164,6 +164,7 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
// Much like WebAssemblyAsmPrinter in the backend, we have to own these.
std::vector<std::unique_ptr<wasm::WasmSignature>> Signatures;
+ std::vector<std::unique_ptr<std::string>> Names;
// Order of labels, directives and instructions in a .s file have no
// syntactical enforcement. This class is a callback from the actual parser,
@@ -214,6 +215,11 @@ public:
SMLoc & /*EndLoc*/) override {
llvm_unreachable("ParseRegister is not implemented.");
}
+ OperandMatchResultTy tryParseRegister(unsigned & /*RegNo*/,
+ SMLoc & /*StartLoc*/,
+ SMLoc & /*EndLoc*/) override {
+ llvm_unreachable("tryParseRegister is not implemented.");
+ }
bool error(const Twine &Msg, const AsmToken &Tok) {
return Parser.Error(Tok.getLoc(), Msg + Tok.getString());
@@ -227,6 +233,12 @@ public:
Signatures.push_back(std::move(Sig));
}
+ StringRef storeName(StringRef Name) {
+ std::unique_ptr<std::string> N = std::make_unique<std::string>(Name);
+ Names.push_back(std::move(N));
+ return *Names.back();
+ }
+
std::pair<StringRef, StringRef> nestingString(NestingType NT) {
switch (NT) {
case Function:
@@ -310,6 +322,8 @@ public:
return wasm::ValType::V128;
if (Type == "exnref")
return wasm::ValType::EXNREF;
+ if (Type == "externref")
+ return wasm::ValType::EXTERNREF;
return Optional<wasm::ValType>();
}
@@ -430,7 +444,7 @@ public:
Name = StringRef(NameLoc.getPointer(), Name.size());
// WebAssembly has instructions with / in them, which AsmLexer parses
- // as seperate tokens, so if we find such tokens immediately adjacent (no
+ // as separate tokens, so if we find such tokens immediately adjacent (no
// whitespace), expand the name to include them:
for (;;) {
auto &Sep = Lexer.getTok();
@@ -688,7 +702,7 @@ public:
// WebAssemblyAsmPrinter::EmitFunctionBodyStart.
// TODO: would be good to factor this into a common function, but the
// assembler and backend really don't share any common code, and this code
- // parses the locals seperately.
+ // parses the locals separately.
auto SymName = expectIdent();
if (SymName.empty())
return true;
@@ -720,7 +734,7 @@ public:
return true;
auto ExportName = expectIdent();
auto WasmSym = cast<MCSymbolWasm>(Ctx.getOrCreateSymbol(SymName));
- WasmSym->setExportName(ExportName);
+ WasmSym->setExportName(storeName(ExportName));
TOut.emitExportName(WasmSym, ExportName);
}
@@ -732,7 +746,7 @@ public:
return true;
auto ImportModule = expectIdent();
auto WasmSym = cast<MCSymbolWasm>(Ctx.getOrCreateSymbol(SymName));
- WasmSym->setImportModule(ImportModule);
+ WasmSym->setImportModule(storeName(ImportModule));
TOut.emitImportModule(WasmSym, ImportModule);
}
@@ -744,7 +758,7 @@ public:
return true;
auto ImportName = expectIdent();
auto WasmSym = cast<MCSymbolWasm>(Ctx.getOrCreateSymbol(SymName));
- WasmSym->setImportName(ImportName);
+ WasmSym->setImportName(storeName(ImportName));
TOut.emitImportName(WasmSym, ImportName);
}
@@ -787,7 +801,7 @@ public:
return error("Cannot parse .int expression: ", Lexer.getTok());
size_t NumBits = 0;
DirectiveID.getString().drop_front(4).getAsInteger(10, NumBits);
- Out.EmitValue(Val, NumBits / 8, End);
+ Out.emitValue(Val, NumBits / 8, End);
return expect(AsmToken::EndOfStatement, "EOL");
}
@@ -796,7 +810,7 @@ public:
std::string S;
if (Parser.parseEscapedString(S))
return error("Cannot parse string constant: ", Lexer.getTok());
- Out.EmitBytes(StringRef(S.c_str(), S.length() + 1));
+ Out.emitBytes(StringRef(S.c_str(), S.length() + 1));
return expect(AsmToken::EndOfStatement, "EOL");
}
@@ -834,7 +848,17 @@ public:
if (Op0.getImm() == -1)
Op0.setImm(Align);
}
- Out.EmitInstruction(Inst, getSTI());
+ if (getSTI().getTargetTriple().isArch64Bit()) {
+ // Upgrade 32-bit loads/stores to 64-bit. These mostly differ by having
+ // an offset64 arg instead of offset32, but to the assembler matcher
+ // they're both immediates so don't get selected for.
+ auto Opc64 = WebAssembly::getWasm64Opcode(
+ static_cast<uint16_t>(Inst.getOpcode()));
+ if (Opc64 >= 0) {
+ Inst.setOpcode(Opc64);
+ }
+ }
+ Out.emitInstruction(Inst, getSTI());
if (CurrentState == EndFunction) {
onEndOfFunction();
} else {
@@ -879,6 +903,9 @@ public:
auto SecName = ".text." + SymName;
auto WS = getContext().getWasmSection(SecName, SectionKind::getText());
getStreamer().SwitchSection(WS);
+ // Also generate DWARF for this section if requested.
+ if (getContext().getGenDwarfForAssembly())
+ getContext().addGenDwarfSection(WS);
}
void onEndOfFunction() {
@@ -886,7 +913,7 @@ public:
// user.
if (!LastFunctionLabel) return;
auto TempSym = getContext().createLinkerPrivateTempSymbol();
- getStreamer().EmitLabel(TempSym);
+ getStreamer().emitLabel(TempSym);
auto Start = MCSymbolRefExpr::create(LastFunctionLabel, getContext());
auto End = MCSymbolRefExpr::create(TempSym, getContext());
auto Expr =