mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
[WebAssembly] Add '.eventtype' directive support
Summary: This patch supports `.eventtype` directive printing and parsing in the same syntax with `.functype`. Reviewers: aardappel, sbc100 Subscribers: dschuff, sbc100, jgravelle-google, sunfish, llvm-commits Differential Revision: https://reviews.llvm.org/D55353 llvm-svn: 348818
This commit is contained in:
parent
08f3004e2a
commit
73b2f90c13
@ -367,6 +367,24 @@ public:
|
|||||||
CurrentState = Label;
|
CurrentState = Label;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool parseSignature(wasm::WasmSignature *Signature) {
|
||||||
|
if (expect(AsmToken::LParen, "("))
|
||||||
|
return true;
|
||||||
|
if (parseRegTypeList(Signature->Params))
|
||||||
|
return true;
|
||||||
|
if (expect(AsmToken::RParen, ")"))
|
||||||
|
return true;
|
||||||
|
if (expect(AsmToken::MinusGreater, "->"))
|
||||||
|
return true;
|
||||||
|
if (expect(AsmToken::LParen, "("))
|
||||||
|
return true;
|
||||||
|
if (parseRegTypeList(Signature->Returns))
|
||||||
|
return true;
|
||||||
|
if (expect(AsmToken::RParen, ")"))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// This function processes wasm-specific directives streamed to
|
// This function processes wasm-specific directives streamed to
|
||||||
// WebAssemblyTargetStreamer, all others go to the generic parser
|
// WebAssemblyTargetStreamer, all others go to the generic parser
|
||||||
// (see WasmAsmParser).
|
// (see WasmAsmParser).
|
||||||
@ -424,19 +442,7 @@ public:
|
|||||||
CurrentState = FunctionStart;
|
CurrentState = FunctionStart;
|
||||||
}
|
}
|
||||||
auto Signature = make_unique<wasm::WasmSignature>();
|
auto Signature = make_unique<wasm::WasmSignature>();
|
||||||
if (expect(AsmToken::LParen, "("))
|
if (parseSignature(Signature.get()))
|
||||||
return true;
|
|
||||||
if (parseRegTypeList(Signature->Params))
|
|
||||||
return true;
|
|
||||||
if (expect(AsmToken::RParen, ")"))
|
|
||||||
return true;
|
|
||||||
if (expect(AsmToken::MinusGreater, "->"))
|
|
||||||
return true;
|
|
||||||
if (expect(AsmToken::LParen, "("))
|
|
||||||
return true;
|
|
||||||
if (parseRegTypeList(Signature->Returns))
|
|
||||||
return true;
|
|
||||||
if (expect(AsmToken::RParen, ")"))
|
|
||||||
return true;
|
return true;
|
||||||
WasmSym->setSignature(Signature.get());
|
WasmSym->setSignature(Signature.get());
|
||||||
addSignature(std::move(Signature));
|
addSignature(std::move(Signature));
|
||||||
@ -446,6 +452,23 @@ public:
|
|||||||
return expect(AsmToken::EndOfStatement, "EOL");
|
return expect(AsmToken::EndOfStatement, "EOL");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (DirectiveID.getString() == ".eventtype") {
|
||||||
|
auto SymName = expectIdent();
|
||||||
|
if (SymName.empty())
|
||||||
|
return true;
|
||||||
|
auto WasmSym = cast<MCSymbolWasm>(
|
||||||
|
TOut.getStreamer().getContext().getOrCreateSymbol(SymName));
|
||||||
|
auto Signature = make_unique<wasm::WasmSignature>();
|
||||||
|
if (parseRegTypeList(Signature->Params))
|
||||||
|
return true;
|
||||||
|
WasmSym->setSignature(Signature.get());
|
||||||
|
addSignature(std::move(Signature));
|
||||||
|
WasmSym->setType(wasm::WASM_SYMBOL_TYPE_EVENT);
|
||||||
|
TOut.emitEventType(WasmSym);
|
||||||
|
// TODO: backend also calls TOut.emitIndIdx, but that is not implemented.
|
||||||
|
return expect(AsmToken::EndOfStatement, "EOL");
|
||||||
|
}
|
||||||
|
|
||||||
if (DirectiveID.getString() == ".local") {
|
if (DirectiveID.getString() == ".local") {
|
||||||
if (CurrentState != FunctionStart)
|
if (CurrentState != FunctionStart)
|
||||||
return error(".local directive should follow the start of a function",
|
return error(".local directive should follow the start of a function",
|
||||||
|
@ -61,21 +61,40 @@ void WebAssemblyTargetAsmStreamer::emitLocal(ArrayRef<wasm::ValType> Types) {
|
|||||||
|
|
||||||
void WebAssemblyTargetAsmStreamer::emitEndFunc() { OS << "\t.endfunc\n"; }
|
void WebAssemblyTargetAsmStreamer::emitEndFunc() { OS << "\t.endfunc\n"; }
|
||||||
|
|
||||||
|
void WebAssemblyTargetAsmStreamer::emitSignature(
|
||||||
|
const wasm::WasmSignature *Sig) {
|
||||||
|
OS << "(";
|
||||||
|
emitParamList(Sig);
|
||||||
|
OS << ") -> (";
|
||||||
|
emitReturnList(Sig);
|
||||||
|
OS << ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebAssemblyTargetAsmStreamer::emitParamList(
|
||||||
|
const wasm::WasmSignature *Sig) {
|
||||||
|
auto &Params = Sig->Params;
|
||||||
|
for (auto &Ty : Params) {
|
||||||
|
if (&Ty != &Params[0])
|
||||||
|
OS << ", ";
|
||||||
|
OS << WebAssembly::TypeToString(Ty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebAssemblyTargetAsmStreamer::emitReturnList(
|
||||||
|
const wasm::WasmSignature *Sig) {
|
||||||
|
auto &Returns = Sig->Returns;
|
||||||
|
for (auto &Ty : Returns) {
|
||||||
|
if (&Ty != &Returns[0])
|
||||||
|
OS << ", ";
|
||||||
|
OS << WebAssembly::TypeToString(Ty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void WebAssemblyTargetAsmStreamer::emitFunctionType(const MCSymbolWasm *Sym) {
|
void WebAssemblyTargetAsmStreamer::emitFunctionType(const MCSymbolWasm *Sym) {
|
||||||
assert(Sym->isFunction());
|
assert(Sym->isFunction());
|
||||||
OS << "\t.functype\t" << Sym->getName() << " (";
|
OS << "\t.functype\t" << Sym->getName() << " ";
|
||||||
auto &Params = Sym->getSignature()->Params;
|
emitSignature(Sym->getSignature());
|
||||||
for (auto &Ty : Params) {
|
OS << "\n";
|
||||||
if (&Ty != &Params[0]) OS << ", ";
|
|
||||||
OS << WebAssembly::TypeToString(Ty);
|
|
||||||
}
|
|
||||||
OS << ") -> (";
|
|
||||||
auto &Returns = Sym->getSignature()->Returns;
|
|
||||||
for (auto &Ty : Returns) {
|
|
||||||
if (&Ty != &Returns[0]) OS << ", ";
|
|
||||||
OS << WebAssembly::TypeToString(Ty);
|
|
||||||
}
|
|
||||||
OS << ")\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebAssemblyTargetAsmStreamer::emitGlobalType(const MCSymbolWasm *Sym) {
|
void WebAssemblyTargetAsmStreamer::emitGlobalType(const MCSymbolWasm *Sym) {
|
||||||
@ -88,17 +107,9 @@ void WebAssemblyTargetAsmStreamer::emitGlobalType(const MCSymbolWasm *Sym) {
|
|||||||
|
|
||||||
void WebAssemblyTargetAsmStreamer::emitEventType(const MCSymbolWasm *Sym) {
|
void WebAssemblyTargetAsmStreamer::emitEventType(const MCSymbolWasm *Sym) {
|
||||||
assert(Sym->isEvent());
|
assert(Sym->isEvent());
|
||||||
OS << "\t.eventtype\t" << Sym->getName();
|
OS << "\t.eventtype\t" << Sym->getName() << " ";
|
||||||
if (Sym->getSignature()->Returns.empty())
|
emitParamList(Sym->getSignature());
|
||||||
OS << ", void";
|
OS << "\n";
|
||||||
else {
|
|
||||||
assert(Sym->getSignature()->Returns.size() == 1);
|
|
||||||
OS << ", "
|
|
||||||
<< WebAssembly::TypeToString(Sym->getSignature()->Returns.front());
|
|
||||||
}
|
|
||||||
for (auto Ty : Sym->getSignature()->Params)
|
|
||||||
OS << ", " << WebAssembly::TypeToString(Ty);
|
|
||||||
OS << '\n';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebAssemblyTargetAsmStreamer::emitImportModule(const MCSymbolWasm *Sym,
|
void WebAssemblyTargetAsmStreamer::emitImportModule(const MCSymbolWasm *Sym,
|
||||||
|
@ -54,6 +54,9 @@ protected:
|
|||||||
/// This part is for ascii assembly output
|
/// This part is for ascii assembly output
|
||||||
class WebAssemblyTargetAsmStreamer final : public WebAssemblyTargetStreamer {
|
class WebAssemblyTargetAsmStreamer final : public WebAssemblyTargetStreamer {
|
||||||
formatted_raw_ostream &OS;
|
formatted_raw_ostream &OS;
|
||||||
|
void emitSignature(const wasm::WasmSignature *Sig);
|
||||||
|
void emitParamList(const wasm::WasmSignature *Sig);
|
||||||
|
void emitReturnList(const wasm::WasmSignature *Sig);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
WebAssemblyTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS);
|
WebAssemblyTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS);
|
||||||
|
@ -262,4 +262,4 @@ declare void @_ZSt9terminatev()
|
|||||||
declare %struct.Cleanup* @_ZN7CleanupD1Ev(%struct.Cleanup* returned)
|
declare %struct.Cleanup* @_ZN7CleanupD1Ev(%struct.Cleanup* returned)
|
||||||
|
|
||||||
; CHECK: __cpp_exception:
|
; CHECK: __cpp_exception:
|
||||||
; CHECK: .eventtype __cpp_exception, void, i32
|
; CHECK: .eventtype __cpp_exception i32
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
test0:
|
test0:
|
||||||
# Test all types:
|
# Test all types:
|
||||||
.functype test0 (i32, i64) -> (i32)
|
.functype test0 (i32, i64) -> (i32)
|
||||||
|
.eventtype __cpp_exception i32
|
||||||
.local f32, f64, v128, v128
|
.local f32, f64, v128, v128
|
||||||
# Explicit getlocal/setlocal:
|
# Explicit getlocal/setlocal:
|
||||||
get_local 2
|
get_local 2
|
||||||
@ -66,6 +67,7 @@ test0:
|
|||||||
# CHECK: .text
|
# CHECK: .text
|
||||||
# CHECK-LABEL: test0:
|
# CHECK-LABEL: test0:
|
||||||
# CHECK-NEXT: .functype test0 (i32, i64) -> (i32)
|
# CHECK-NEXT: .functype test0 (i32, i64) -> (i32)
|
||||||
|
# CHECK-NEXT: .eventtype __cpp_exception i32
|
||||||
# CHECK-NEXT: .local f32, f64
|
# CHECK-NEXT: .local f32, f64
|
||||||
# CHECK-NEXT: get_local 2
|
# CHECK-NEXT: get_local 2
|
||||||
# CHECK-NEXT: set_local 2
|
# CHECK-NEXT: set_local 2
|
||||||
|
Loading…
Reference in New Issue
Block a user