Skip to content

Commit

Permalink
[Parser] Parse v128.const (#6275)
Browse files Browse the repository at this point in the history
  • Loading branch information
tlively authored Feb 5, 2024
1 parent ed15efe commit be13e0f
Show file tree
Hide file tree
Showing 6 changed files with 179 additions and 3 deletions.
62 changes: 62 additions & 0 deletions src/parser/contexts.h
Original file line number Diff line number Diff line change
Expand Up @@ -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{};
}
Expand Down Expand Up @@ -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_,
Expand Down
6 changes: 6 additions & 0 deletions src/parser/input-impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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()) {
Expand Down
2 changes: 2 additions & 0 deletions src/parser/input.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
5 changes: 5 additions & 0 deletions src/parser/lexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
68 changes: 67 additions & 1 deletion src/parser/parsers.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
39 changes: 37 additions & 2 deletions test/lit/wat-kitchen-sink.wast
Original file line number Diff line number Diff line change
Expand Up @@ -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)))
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit be13e0f

Please sign in to comment.