Skip to content

Commit be13e0f

Browse files
authored
[Parser] Parse v128.const (#6275)
1 parent ed15efe commit be13e0f

File tree

6 files changed

+179
-3
lines changed

6 files changed

+179
-3
lines changed

src/parser/contexts.h

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,20 @@ struct NullInstrParserCtx {
406406
Result<> makeI64Const(Index, uint64_t) { return Ok{}; }
407407
Result<> makeF32Const(Index, float) { return Ok{}; }
408408
Result<> makeF64Const(Index, double) { return Ok{}; }
409+
Result<> makeI8x16Const(Index, const std::array<uint8_t, 16>&) {
410+
return Ok{};
411+
}
412+
Result<> makeI16x8Const(Index, const std::array<uint16_t, 8>&) {
413+
return Ok{};
414+
}
415+
Result<> makeI32x4Const(Index, const std::array<uint32_t, 4>&) {
416+
return Ok{};
417+
}
418+
Result<> makeI64x2Const(Index, const std::array<uint64_t, 2>&) {
419+
return Ok{};
420+
}
421+
Result<> makeF32x4Const(Index, const std::array<float, 4>&) { return Ok{}; }
422+
Result<> makeF64x2Const(Index, const std::array<double, 2>&) { return Ok{}; }
409423
Result<> makeLoad(Index, Type, bool, int, bool, MemoryIdxT*, MemargT) {
410424
return Ok{};
411425
}
@@ -1542,6 +1556,54 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> {
15421556
return withLoc(pos, irBuilder.makeConst(Literal(c)));
15431557
}
15441558

1559+
Result<> makeI8x16Const(Index pos, const std::array<uint8_t, 16>& vals) {
1560+
std::array<Literal, 16> lanes;
1561+
for (size_t i = 0; i < 16; ++i) {
1562+
lanes[i] = Literal(uint32_t(vals[i]));
1563+
}
1564+
return withLoc(pos, irBuilder.makeConst(Literal(lanes)));
1565+
}
1566+
1567+
Result<> makeI16x8Const(Index pos, const std::array<uint16_t, 8>& vals) {
1568+
std::array<Literal, 8> lanes;
1569+
for (size_t i = 0; i < 8; ++i) {
1570+
lanes[i] = Literal(uint32_t(vals[i]));
1571+
}
1572+
return withLoc(pos, irBuilder.makeConst(Literal(lanes)));
1573+
}
1574+
1575+
Result<> makeI32x4Const(Index pos, const std::array<uint32_t, 4>& vals) {
1576+
std::array<Literal, 4> lanes;
1577+
for (size_t i = 0; i < 4; ++i) {
1578+
lanes[i] = Literal(vals[i]);
1579+
}
1580+
return withLoc(pos, irBuilder.makeConst(Literal(lanes)));
1581+
}
1582+
1583+
Result<> makeI64x2Const(Index pos, const std::array<uint64_t, 2>& vals) {
1584+
std::array<Literal, 2> lanes;
1585+
for (size_t i = 0; i < 2; ++i) {
1586+
lanes[i] = Literal(vals[i]);
1587+
}
1588+
return withLoc(pos, irBuilder.makeConst(Literal(lanes)));
1589+
}
1590+
1591+
Result<> makeF32x4Const(Index pos, const std::array<float, 4>& vals) {
1592+
std::array<Literal, 4> lanes;
1593+
for (size_t i = 0; i < 4; ++i) {
1594+
lanes[i] = Literal(vals[i]);
1595+
}
1596+
return withLoc(pos, irBuilder.makeConst(Literal(lanes)));
1597+
}
1598+
1599+
Result<> makeF64x2Const(Index pos, const std::array<double, 2>& vals) {
1600+
std::array<Literal, 2> lanes;
1601+
for (size_t i = 0; i < 2; ++i) {
1602+
lanes[i] = Literal(vals[i]);
1603+
}
1604+
return withLoc(pos, irBuilder.makeConst(Literal(lanes)));
1605+
}
1606+
15451607
Result<> makeLoad(Index pos,
15461608
Type type,
15471609
bool signed_,

src/parser/input-impl.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,14 @@ inline std::optional<uint32_t> ParseInput::takeI32() {
170170
return takeI<uint32_t>();
171171
}
172172

173+
inline std::optional<uint16_t> ParseInput::takeI16() {
174+
return takeI<uint16_t>();
175+
}
176+
173177
inline std::optional<uint8_t> ParseInput::takeU8() { return takeU<uint8_t>(); }
174178

179+
inline std::optional<uint8_t> ParseInput::takeI8() { return takeI<uint8_t>(); }
180+
175181
inline std::optional<double> ParseInput::takeF64() {
176182
if (auto t = peek()) {
177183
if (auto d = t->getF64()) {

src/parser/input.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,9 @@ struct ParseInput {
5454
std::optional<uint64_t> takeI64();
5555
std::optional<uint32_t> takeU32();
5656
std::optional<uint32_t> takeI32();
57+
std::optional<uint16_t> takeI16();
5758
std::optional<uint8_t> takeU8();
59+
std::optional<uint8_t> takeI8();
5860
std::optional<double> takeF64();
5961
std::optional<float> takeF32();
6062
std::optional<std::string> takeString();

src/parser/lexer.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -811,7 +811,12 @@ template std::optional<uint64_t> Token::getI<uint64_t>() const;
811811
template std::optional<uint32_t> Token::getU<uint32_t>() const;
812812
template std::optional<int32_t> Token::getS<int32_t>() const;
813813
template std::optional<uint32_t> Token::getI<uint32_t>() const;
814+
template std::optional<uint16_t> Token::getU<uint16_t>() const;
815+
template std::optional<int16_t> Token::getS<int16_t>() const;
816+
template std::optional<uint16_t> Token::getI<uint16_t>() const;
814817
template std::optional<uint8_t> Token::getU<uint8_t>() const;
818+
template std::optional<int8_t> Token::getS<int8_t>() const;
819+
template std::optional<uint8_t> Token::getI<uint8_t>() const;
815820

816821
std::optional<double> Token::getF64() const {
817822
constexpr int signif = 52;

src/parser/parsers.h

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1362,7 +1362,73 @@ template<typename Ctx> Result<> makeConst(Ctx& ctx, Index pos, Type type) {
13621362
}
13631363
return ctx.in.err("expected f64");
13641364
case Type::v128:
1365-
return ctx.in.err("unimplemented instruction");
1365+
if (ctx.in.takeKeyword("i8x16"sv)) {
1366+
std::array<uint8_t, 16> vals;
1367+
for (size_t i = 0; i < 16; ++i) {
1368+
auto val = ctx.in.takeI8();
1369+
if (!val) {
1370+
return ctx.in.err("expected i8 value");
1371+
}
1372+
vals[i] = *val;
1373+
}
1374+
return ctx.makeI8x16Const(pos, vals);
1375+
}
1376+
if (ctx.in.takeKeyword("i16x8"sv)) {
1377+
std::array<uint16_t, 8> vals;
1378+
for (size_t i = 0; i < 8; ++i) {
1379+
auto val = ctx.in.takeI16();
1380+
if (!val) {
1381+
return ctx.in.err("expected i16 value");
1382+
}
1383+
vals[i] = *val;
1384+
}
1385+
return ctx.makeI16x8Const(pos, vals);
1386+
}
1387+
if (ctx.in.takeKeyword("i32x4"sv)) {
1388+
std::array<uint32_t, 4> vals;
1389+
for (size_t i = 0; i < 4; ++i) {
1390+
auto val = ctx.in.takeI32();
1391+
if (!val) {
1392+
return ctx.in.err("expected i32 value");
1393+
}
1394+
vals[i] = *val;
1395+
}
1396+
return ctx.makeI32x4Const(pos, vals);
1397+
}
1398+
if (ctx.in.takeKeyword("i64x2"sv)) {
1399+
std::array<uint64_t, 2> vals;
1400+
for (size_t i = 0; i < 2; ++i) {
1401+
auto val = ctx.in.takeI64();
1402+
if (!val) {
1403+
return ctx.in.err("expected i64 value");
1404+
}
1405+
vals[i] = *val;
1406+
}
1407+
return ctx.makeI64x2Const(pos, vals);
1408+
}
1409+
if (ctx.in.takeKeyword("f32x4"sv)) {
1410+
std::array<float, 4> vals;
1411+
for (size_t i = 0; i < 4; ++i) {
1412+
auto val = ctx.in.takeF32();
1413+
if (!val) {
1414+
return ctx.in.err("expected f32 value");
1415+
}
1416+
vals[i] = *val;
1417+
}
1418+
return ctx.makeF32x4Const(pos, vals);
1419+
}
1420+
if (ctx.in.takeKeyword("f64x2"sv)) {
1421+
std::array<double, 2> vals;
1422+
for (size_t i = 0; i < 2; ++i) {
1423+
auto val = ctx.in.takeF64();
1424+
if (!val) {
1425+
return ctx.in.err("expected f64 value");
1426+
}
1427+
vals[i] = *val;
1428+
}
1429+
return ctx.makeF64x2Const(pos, vals);
1430+
}
1431+
return ctx.in.err("expected SIMD vector shape");
13661432
case Type::none:
13671433
case Type::unreachable:
13681434
break;

test/lit/wat-kitchen-sink.wast

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@
380380
;; CHECK: (elem $passive-2 anyref (struct.new_default $s0) (struct.new_default $s0))
381381
(elem $passive-2 anyref (item struct.new $s0) (struct.new $s0))
382382

383-
;; CHECK: (elem declare func $ref-func $table-fill $table-grow $table-set)
383+
;; CHECK: (elem declare func $ref-func $ref-is-null $table-fill $table-grow $table-set)
384384
(elem declare func 0 1 2 3)
385385

386386
(elem $declare-2 declare funcref (item ref.func 0) (ref.func 1) (item (ref.func 2)))
@@ -3302,6 +3302,41 @@
33023302
atomic.fence
33033303
)
33043304

3305+
;; CHECK: (func $simd-const (type $void)
3306+
;; CHECK-NEXT: (drop
3307+
;; CHECK-NEXT: (v128.const i32x4 0x03020100 0x07060504 0x0b0a0908 0x0f0e0d0c)
3308+
;; CHECK-NEXT: )
3309+
;; CHECK-NEXT: (drop
3310+
;; CHECK-NEXT: (v128.const i32x4 0x00010000 0x00030002 0x00050004 0x00070006)
3311+
;; CHECK-NEXT: )
3312+
;; CHECK-NEXT: (drop
3313+
;; CHECK-NEXT: (v128.const i32x4 0x00000000 0x00000001 0x00000002 0x00000003)
3314+
;; CHECK-NEXT: )
3315+
;; CHECK-NEXT: (drop
3316+
;; CHECK-NEXT: (v128.const i32x4 0x00000000 0x00000000 0x00000001 0x00000000)
3317+
;; CHECK-NEXT: )
3318+
;; CHECK-NEXT: (drop
3319+
;; CHECK-NEXT: (v128.const i32x4 0x00000000 0x3f800000 0x40000000 0x40400000)
3320+
;; CHECK-NEXT: )
3321+
;; CHECK-NEXT: (drop
3322+
;; CHECK-NEXT: (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x3ff00000)
3323+
;; CHECK-NEXT: )
3324+
;; CHECK-NEXT: )
3325+
(func $simd-const
3326+
v128.const i8x16 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
3327+
drop
3328+
v128.const i16x8 0 1 2 3 4 5 6 7
3329+
drop
3330+
v128.const i32x4 0 1 2 3
3331+
drop
3332+
v128.const i64x2 0 1
3333+
drop
3334+
v128.const f32x4 0.0 1.0 2.0 3.0
3335+
drop
3336+
v128.const f64x2 0.0 1.0
3337+
drop
3338+
)
3339+
33053340
;; CHECK: (func $simd-extract (type $33) (param $0 v128) (result i32)
33063341
;; CHECK-NEXT: (i32x4.extract_lane 3
33073342
;; CHECK-NEXT: (local.get $0)
@@ -3587,7 +3622,7 @@
35873622
;; CHECK-NEXT: (ref.func $ref-func)
35883623
;; CHECK-NEXT: )
35893624
;; CHECK-NEXT: (drop
3590-
;; CHECK-NEXT: (ref.func $ref-func)
3625+
;; CHECK-NEXT: (ref.func $ref-is-null)
35913626
;; CHECK-NEXT: )
35923627
;; CHECK-NEXT: )
35933628
(func $ref-func

0 commit comments

Comments
 (0)