diff options
author | Thomas Lively <tlively@google.com> | 2022-10-18 21:49:06 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-19 02:49:06 +0000 |
commit | ded21cf0c1c09dd4e025406c759e3d4bb08d31cc (patch) | |
tree | 0f7e35e763a292d143668c2a7ae34f431ba048a1 /src | |
parent | 2e82e3ea352b9f4c2432252797c47516b9770eb2 (diff) | |
download | binaryen-ded21cf0c1c09dd4e025406c759e3d4bb08d31cc.tar.gz binaryen-ded21cf0c1c09dd4e025406c759e3d4bb08d31cc.tar.bz2 binaryen-ded21cf0c1c09dd4e025406c759e3d4bb08d31cc.zip |
[Parser] Parse SIMD lane manipulation instructions (#5156)
Including all `SIMDExtract`, `SIMDReplace`, `SIMDShuffle` expressions.
Diffstat (limited to 'src')
-rw-r--r-- | src/wasm/wat-parser.cpp | 63 |
1 files changed, 58 insertions, 5 deletions
diff --git a/src/wasm/wat-parser.cpp b/src/wasm/wat-parser.cpp index 0114d9477..10ca62de1 100644 --- a/src/wasm/wat-parser.cpp +++ b/src/wasm/wat-parser.cpp @@ -218,6 +218,18 @@ struct ParseInput { return {}; } + std::optional<uint8_t> takeU8() { + if (auto t = peek()) { + if (auto n = t->getU32()) { + if (n <= std::numeric_limits<uint8_t>::max()) { + ++lexer; + return uint8_t(*n); + } + } + } + return {}; + } + std::optional<double> takeF64() { if (auto t = peek()) { if (auto d = t->getF64()) { @@ -591,6 +603,9 @@ struct NullInstrParserCtx { InstrT makeGlobalGet(Index, GlobalT) { return Ok{}; } InstrT makeGlobalSet(Index, GlobalT) { return Ok{}; } + InstrT makeSIMDExtract(Index, SIMDExtractOp, uint8_t) { return Ok{}; } + InstrT makeSIMDReplace(Index, SIMDReplaceOp, uint8_t) { return Ok{}; } + InstrT makeSIMDShuffle(Index, const std::array<uint8_t, 16>&) { return Ok{}; } template<typename HeapTypeT> InstrT makeRefNull(Index, HeapTypeT) { return {}; @@ -1328,6 +1343,28 @@ struct ParseDefsCtx : InstrParserCtx<ParseDefsCtx> { CHECK_ERR(val); return push(pos, builder.makeGlobalSet(global, *val)); } + + Result<> makeSIMDExtract(Index pos, SIMDExtractOp op, uint8_t lane) { + auto val = pop(pos); + CHECK_ERR(val); + return push(pos, builder.makeSIMDExtract(op, *val, lane)); + } + + Result<> makeSIMDReplace(Index pos, SIMDReplaceOp op, uint8_t lane) { + auto val = pop(pos); + CHECK_ERR(val); + auto vec = pop(pos); + CHECK_ERR(vec); + return push(pos, builder.makeSIMDReplace(op, *vec, lane, *val)); + } + + Result<> makeSIMDShuffle(Index pos, const std::array<uint8_t, 16>& lanes) { + auto rhs = pop(pos); + CHECK_ERR(rhs); + auto lhs = pop(pos); + CHECK_ERR(lhs); + return push(pos, builder.makeSIMDShuffle(*lhs, *rhs, lanes)); + } }; // ================ @@ -1874,7 +1911,7 @@ template<typename Ctx> Result<typename Ctx::InstrsT> instrs(Ctx& ctx) { } if (ctx.in.getPos() != *end) { - return ctx.in.err(start, "expected end of instruction"); + return ctx.in.err("expected end of instruction"); } } else { WASM_UNREACHABLE("expected paren"); @@ -2068,19 +2105,35 @@ Result<typename Ctx::InstrT> makeAtomicFence(Ctx& ctx, Index pos) { template<typename Ctx> Result<typename Ctx::InstrT> -makeSIMDExtract(Ctx& ctx, Index pos, SIMDExtractOp op, size_t lanes) { - return ctx.in.err("unimplemented instruction"); +makeSIMDExtract(Ctx& ctx, Index pos, SIMDExtractOp op, size_t) { + auto lane = ctx.in.takeU8(); + if (!lane) { + return ctx.in.err("expected lane index"); + } + return ctx.makeSIMDExtract(pos, op, *lane); } template<typename Ctx> Result<typename Ctx::InstrT> makeSIMDReplace(Ctx& ctx, Index pos, SIMDReplaceOp op, size_t lanes) { - return ctx.in.err("unimplemented instruction"); + auto lane = ctx.in.takeU8(); + if (!lane) { + return ctx.in.err("expected lane index"); + } + return ctx.makeSIMDReplace(pos, op, *lane); } template<typename Ctx> Result<typename Ctx::InstrT> makeSIMDShuffle(Ctx& ctx, Index pos) { - return ctx.in.err("unimplemented instruction"); + std::array<uint8_t, 16> lanes; + for (int i = 0; i < 16; ++i) { + auto lane = ctx.in.takeU8(); + if (!lane) { + return ctx.in.err("expected lane index"); + } + lanes[i] = *lane; + } + return ctx.makeSIMDShuffle(pos, lanes); } template<typename Ctx> |