diff options
-rw-r--r-- | src/parser/contexts.h | 62 | ||||
-rw-r--r-- | src/parser/input-impl.h | 6 | ||||
-rw-r--r-- | src/parser/input.h | 2 | ||||
-rw-r--r-- | src/parser/lexer.cpp | 5 | ||||
-rw-r--r-- | src/parser/parsers.h | 68 | ||||
-rw-r--r-- | test/lit/wat-kitchen-sink.wast | 39 |
6 files changed, 179 insertions, 3 deletions
diff --git a/src/parser/contexts.h b/src/parser/contexts.h index 507a54342..c14a555c5 100644 --- a/src/parser/contexts.h +++ b/src/parser/contexts.h @@ -406,6 +406,20 @@ struct NullInstrParserCtx { Result<> makeI64Const(Index, uint64_t) { return Ok{}; } Result<> makeF32Const(Index, float) { return Ok{}; } Result<> makeF64Const(Index, double) { return Ok{}; } + Result<> makeI8x16Const(Index, const std::array<uint8_t, 16>&) { + return Ok{}; + } + Result<> makeI16x8Const(Index, const std::array<uint16_t, 8>&) { + return Ok{}; + } + Result<> makeI32x4Const(Index, const std::array<uint32_t, 4>&) { + return Ok{}; + } + Result<> makeI64x2Const(Index, const std::array<uint64_t, 2>&) { + return Ok{}; + } + Result<> makeF32x4Const(Index, const std::array<float, 4>&) { return Ok{}; } + Result<> makeF64x2Const(Index, const std::array<double, 2>&) { return Ok{}; } Result<> makeLoad(Index, Type, bool, int, bool, MemoryIdxT*, MemargT) { return Ok{}; } @@ -1542,6 +1556,54 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> { return withLoc(pos, irBuilder.makeConst(Literal(c))); } + Result<> makeI8x16Const(Index pos, const std::array<uint8_t, 16>& vals) { + std::array<Literal, 16> lanes; + for (size_t i = 0; i < 16; ++i) { + lanes[i] = Literal(uint32_t(vals[i])); + } + return withLoc(pos, irBuilder.makeConst(Literal(lanes))); + } + + Result<> makeI16x8Const(Index pos, const std::array<uint16_t, 8>& vals) { + std::array<Literal, 8> lanes; + for (size_t i = 0; i < 8; ++i) { + lanes[i] = Literal(uint32_t(vals[i])); + } + return withLoc(pos, irBuilder.makeConst(Literal(lanes))); + } + + Result<> makeI32x4Const(Index pos, const std::array<uint32_t, 4>& vals) { + std::array<Literal, 4> lanes; + for (size_t i = 0; i < 4; ++i) { + lanes[i] = Literal(vals[i]); + } + return withLoc(pos, irBuilder.makeConst(Literal(lanes))); + } + + Result<> makeI64x2Const(Index pos, const std::array<uint64_t, 2>& vals) { + std::array<Literal, 2> lanes; + for (size_t i = 0; i < 2; ++i) { + lanes[i] = Literal(vals[i]); + } + return withLoc(pos, irBuilder.makeConst(Literal(lanes))); + } + + Result<> makeF32x4Const(Index pos, const std::array<float, 4>& vals) { + std::array<Literal, 4> lanes; + for (size_t i = 0; i < 4; ++i) { + lanes[i] = Literal(vals[i]); + } + return withLoc(pos, irBuilder.makeConst(Literal(lanes))); + } + + Result<> makeF64x2Const(Index pos, const std::array<double, 2>& vals) { + std::array<Literal, 2> lanes; + for (size_t i = 0; i < 2; ++i) { + lanes[i] = Literal(vals[i]); + } + return withLoc(pos, irBuilder.makeConst(Literal(lanes))); + } + Result<> makeLoad(Index pos, Type type, bool signed_, diff --git a/src/parser/input-impl.h b/src/parser/input-impl.h index 3ffce07f8..e3cf52015 100644 --- a/src/parser/input-impl.h +++ b/src/parser/input-impl.h @@ -170,8 +170,14 @@ inline std::optional<uint32_t> ParseInput::takeI32() { return takeI<uint32_t>(); } +inline std::optional<uint16_t> ParseInput::takeI16() { + return takeI<uint16_t>(); +} + inline std::optional<uint8_t> ParseInput::takeU8() { return takeU<uint8_t>(); } +inline std::optional<uint8_t> ParseInput::takeI8() { return takeI<uint8_t>(); } + inline std::optional<double> ParseInput::takeF64() { if (auto t = peek()) { if (auto d = t->getF64()) { diff --git a/src/parser/input.h b/src/parser/input.h index d4fdde1bd..6086ed1a5 100644 --- a/src/parser/input.h +++ b/src/parser/input.h @@ -54,7 +54,9 @@ struct ParseInput { std::optional<uint64_t> takeI64(); std::optional<uint32_t> takeU32(); std::optional<uint32_t> takeI32(); + std::optional<uint16_t> takeI16(); std::optional<uint8_t> takeU8(); + std::optional<uint8_t> takeI8(); std::optional<double> takeF64(); std::optional<float> takeF32(); std::optional<std::string> takeString(); diff --git a/src/parser/lexer.cpp b/src/parser/lexer.cpp index 288660c76..2625bf8fd 100644 --- a/src/parser/lexer.cpp +++ b/src/parser/lexer.cpp @@ -811,7 +811,12 @@ template std::optional<uint64_t> Token::getI<uint64_t>() const; template std::optional<uint32_t> Token::getU<uint32_t>() const; template std::optional<int32_t> Token::getS<int32_t>() const; template std::optional<uint32_t> Token::getI<uint32_t>() const; +template std::optional<uint16_t> Token::getU<uint16_t>() const; +template std::optional<int16_t> Token::getS<int16_t>() const; +template std::optional<uint16_t> Token::getI<uint16_t>() const; template std::optional<uint8_t> Token::getU<uint8_t>() const; +template std::optional<int8_t> Token::getS<int8_t>() const; +template std::optional<uint8_t> Token::getI<uint8_t>() const; std::optional<double> Token::getF64() const { constexpr int signif = 52; diff --git a/src/parser/parsers.h b/src/parser/parsers.h index d62645441..db4c716f1 100644 --- a/src/parser/parsers.h +++ b/src/parser/parsers.h @@ -1362,7 +1362,73 @@ template<typename Ctx> Result<> makeConst(Ctx& ctx, Index pos, Type type) { } return ctx.in.err("expected f64"); case Type::v128: - return ctx.in.err("unimplemented instruction"); + if (ctx.in.takeKeyword("i8x16"sv)) { + std::array<uint8_t, 16> vals; + for (size_t i = 0; i < 16; ++i) { + auto val = ctx.in.takeI8(); + if (!val) { + return ctx.in.err("expected i8 value"); + } + vals[i] = *val; + } + return ctx.makeI8x16Const(pos, vals); + } + if (ctx.in.takeKeyword("i16x8"sv)) { + std::array<uint16_t, 8> vals; + for (size_t i = 0; i < 8; ++i) { + auto val = ctx.in.takeI16(); + if (!val) { + return ctx.in.err("expected i16 value"); + } + vals[i] = *val; + } + return ctx.makeI16x8Const(pos, vals); + } + if (ctx.in.takeKeyword("i32x4"sv)) { + std::array<uint32_t, 4> vals; + for (size_t i = 0; i < 4; ++i) { + auto val = ctx.in.takeI32(); + if (!val) { + return ctx.in.err("expected i32 value"); + } + vals[i] = *val; + } + return ctx.makeI32x4Const(pos, vals); + } + if (ctx.in.takeKeyword("i64x2"sv)) { + std::array<uint64_t, 2> vals; + for (size_t i = 0; i < 2; ++i) { + auto val = ctx.in.takeI64(); + if (!val) { + return ctx.in.err("expected i64 value"); + } + vals[i] = *val; + } + return ctx.makeI64x2Const(pos, vals); + } + if (ctx.in.takeKeyword("f32x4"sv)) { + std::array<float, 4> vals; + for (size_t i = 0; i < 4; ++i) { + auto val = ctx.in.takeF32(); + if (!val) { + return ctx.in.err("expected f32 value"); + } + vals[i] = *val; + } + return ctx.makeF32x4Const(pos, vals); + } + if (ctx.in.takeKeyword("f64x2"sv)) { + std::array<double, 2> vals; + for (size_t i = 0; i < 2; ++i) { + auto val = ctx.in.takeF64(); + if (!val) { + return ctx.in.err("expected f64 value"); + } + vals[i] = *val; + } + return ctx.makeF64x2Const(pos, vals); + } + return ctx.in.err("expected SIMD vector shape"); case Type::none: case Type::unreachable: break; diff --git a/test/lit/wat-kitchen-sink.wast b/test/lit/wat-kitchen-sink.wast index 4e4c3639c..1ab8e7516 100644 --- a/test/lit/wat-kitchen-sink.wast +++ b/test/lit/wat-kitchen-sink.wast @@ -380,7 +380,7 @@ ;; CHECK: (elem $passive-2 anyref (struct.new_default $s0) (struct.new_default $s0)) (elem $passive-2 anyref (item struct.new $s0) (struct.new $s0)) - ;; CHECK: (elem declare func $ref-func $table-fill $table-grow $table-set) + ;; CHECK: (elem declare func $ref-func $ref-is-null $table-fill $table-grow $table-set) (elem declare func 0 1 2 3) (elem $declare-2 declare funcref (item ref.func 0) (ref.func 1) (item (ref.func 2))) @@ -3302,6 +3302,41 @@ atomic.fence ) + ;; CHECK: (func $simd-const (type $void) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (v128.const i32x4 0x03020100 0x07060504 0x0b0a0908 0x0f0e0d0c) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (v128.const i32x4 0x00010000 0x00030002 0x00050004 0x00070006) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (v128.const i32x4 0x00000000 0x00000001 0x00000002 0x00000003) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (v128.const i32x4 0x00000000 0x00000000 0x00000001 0x00000000) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (v128.const i32x4 0x00000000 0x3f800000 0x40000000 0x40400000) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x3ff00000) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $simd-const + v128.const i8x16 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + drop + v128.const i16x8 0 1 2 3 4 5 6 7 + drop + v128.const i32x4 0 1 2 3 + drop + v128.const i64x2 0 1 + drop + v128.const f32x4 0.0 1.0 2.0 3.0 + drop + v128.const f64x2 0.0 1.0 + drop + ) + ;; CHECK: (func $simd-extract (type $33) (param $0 v128) (result i32) ;; CHECK-NEXT: (i32x4.extract_lane 3 ;; CHECK-NEXT: (local.get $0) @@ -3587,7 +3622,7 @@ ;; CHECK-NEXT: (ref.func $ref-func) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (ref.func $ref-func) + ;; CHECK-NEXT: (ref.func $ref-is-null) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $ref-func |