Skip to content

Commit 4fea2cf

Browse files
committed
Implement i8x16.popcnt
As proposed in WebAssembly/simd#379. Since this instruction is still being evaluated for inclusion in the SIMD proposal, this PR does not add support for it to the C/JS APIs or to the fuzzer. This PR also performs a drive-by fix for unrelated instructions in c-api-kitchen-sink.c
1 parent 514a6c5 commit 4fea2cf

22 files changed

+200
-155
lines changed

scripts/gen-s-parser.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,7 @@
358358
("v128.store16_lane", "makeSIMDLoadStoreLane(s, StoreLaneVec16x8)"),
359359
("v128.store32_lane", "makeSIMDLoadStoreLane(s, StoreLaneVec32x4)"),
360360
("v128.store64_lane", "makeSIMDLoadStoreLane(s, StoreLaneVec64x2)"),
361+
("i8x16.popcnt", "makeUnary(s, UnaryOp::PopcntVecI8x16)"),
361362
("i8x16.abs", "makeUnary(s, UnaryOp::AbsVecI8x16)"),
362363
("i8x16.neg", "makeUnary(s, UnaryOp::NegVecI8x16)"),
363364
("i8x16.any_true", "makeUnary(s, UnaryOp::AnyTrueVecI8x16)"),

src/binaryen-c.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,7 @@ BINARYEN_API BinaryenOp BinaryenOrVec128(void);
485485
BINARYEN_API BinaryenOp BinaryenXorVec128(void);
486486
BINARYEN_API BinaryenOp BinaryenAndNotVec128(void);
487487
BINARYEN_API BinaryenOp BinaryenBitselectVec128(void);
488+
// TODO: Add i8x16.popcnt to C and JS APIs once merged to proposal
488489
BINARYEN_API BinaryenOp BinaryenAbsVecI8x16(void);
489490
BINARYEN_API BinaryenOp BinaryenNegVecI8x16(void);
490491
BINARYEN_API BinaryenOp BinaryenAnyTrueVecI8x16(void);

src/gen-s-parser.inc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2492,6 +2492,9 @@ switch (op[0]) {
24922492
default: goto parse_error;
24932493
}
24942494
}
2495+
case 'p':
2496+
if (strcmp(op, "i8x16.popcnt") == 0) { return makeUnary(s, UnaryOp::PopcntVecI8x16); }
2497+
goto parse_error;
24952498
case 'r':
24962499
if (strcmp(op, "i8x16.replace_lane") == 0) { return makeSIMDReplace(s, SIMDReplaceOp::ReplaceLaneVecI8x16, 16); }
24972500
goto parse_error;

src/ir/cost.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ struct CostAnalyzer : public Visitor<CostAnalyzer, Index> {
157157
case AnyTrueVecI8x16:
158158
case AllTrueVecI8x16:
159159
case BitmaskVecI8x16:
160+
case PopcntVecI8x16:
160161
case AbsVecI16x8:
161162
case NegVecI16x8:
162163
case AnyTrueVecI16x8:

src/literal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,7 @@ class Literal {
488488
Literal maxSI8x16(const Literal& other) const;
489489
Literal maxUI8x16(const Literal& other) const;
490490
Literal avgrUI8x16(const Literal& other) const;
491+
Literal popcntI8x16() const;
491492
Literal absI16x8() const;
492493
Literal negI16x8() const;
493494
Literal anyTrueI16x8() const;

src/passes/Print.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -774,6 +774,9 @@ struct PrintExpressionContents
774774
case BitmaskVecI8x16:
775775
o << "i8x16.bitmask";
776776
break;
777+
case PopcntVecI8x16:
778+
o << "i8x16.popcnt";
779+
break;
777780
case AbsVecI16x8:
778781
o << "i16x8.abs";
779782
break;

src/tools/fuzzing.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2026,6 +2026,7 @@ class TranslateToFuzzReader {
20262026
return buildUnary({SplatVecF64x2, make(Type::f64)});
20272027
case 4:
20282028
return buildUnary({pick(NotVec128,
2029+
// TODO: i8x16.popcnt once merged
20292030
NegVecI8x16,
20302031
NegVecI16x8,
20312032
NegVecI32x4,

src/wasm-binary.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,8 @@ enum ASTNodes {
823823
I8x16MaxU = 0x79,
824824
I8x16AvgrU = 0x7b,
825825

826+
I8x16Popcnt = 0x7c,
827+
826828
I16x8Abs = 0x80,
827829
I16x8Neg = 0x81,
828830
I16x8AnyTrue = 0x82,

src/wasm-interpreter.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,8 @@ class ExpressionRunner : public OverriddenVisitor<SubType, Flow> {
463463
return value.allTrueI8x16();
464464
case BitmaskVecI8x16:
465465
return value.bitmaskI8x16();
466+
case PopcntVecI8x16:
467+
return value.popcntI8x16();
466468
case AbsVecI16x8:
467469
return value.absI16x8();
468470
case NegVecI16x8:

src/wasm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ enum UnaryOp {
161161
AnyTrueVecI8x16,
162162
AllTrueVecI8x16,
163163
BitmaskVecI8x16,
164+
PopcntVecI8x16,
164165
AbsVecI16x8,
165166
NegVecI16x8,
166167
AnyTrueVecI16x8,

src/wasm/literal.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1653,6 +1653,9 @@ Literal Literal::absI32x4() const {
16531653
Literal Literal::negI8x16() const {
16541654
return unary<16, &Literal::getLanesUI8x16, &Literal::neg>(*this);
16551655
}
1656+
Literal Literal::popcntI8x16() const {
1657+
return unary<16, &Literal::getLanesUI8x16, &Literal::popCount>(*this);
1658+
}
16561659
Literal Literal::negI16x8() const {
16571660
return unary<8, &Literal::getLanesUI16x8, &Literal::neg>(*this);
16581661
}

src/wasm/wasm-binary.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4478,6 +4478,10 @@ bool WasmBinaryBuilder::maybeVisitSIMDUnary(Expression*& out, uint32_t code) {
44784478
curr = allocator.alloc<Unary>();
44794479
curr->op = NotVec128;
44804480
break;
4481+
case BinaryConsts::I8x16Popcnt:
4482+
curr = allocator.alloc<Unary>();
4483+
curr->op = PopcntVecI8x16;
4484+
break;
44814485
case BinaryConsts::I8x16Abs:
44824486
curr = allocator.alloc<Unary>();
44834487
curr->op = AbsVecI8x16;

src/wasm/wasm-stack.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -971,6 +971,10 @@ void BinaryInstWriter::visitUnary(Unary* curr) {
971971
o << int8_t(BinaryConsts::SIMDPrefix)
972972
<< U32LEB(BinaryConsts::I8x16Bitmask);
973973
break;
974+
case PopcntVecI8x16:
975+
o << int8_t(BinaryConsts::SIMDPrefix)
976+
<< U32LEB(BinaryConsts::I8x16Popcnt);
977+
break;
974978
case AbsVecI16x8:
975979
o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I16x8Abs);
976980
break;

src/wasm/wasm-validator.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1875,6 +1875,7 @@ void FunctionValidator::visitUnary(Unary* curr) {
18751875
curr->value->type, Type(Type::f64), curr, "expected f64 splat value");
18761876
break;
18771877
case NotVec128:
1878+
case PopcntVecI8x16:
18781879
case AbsVecI8x16:
18791880
case AbsVecI16x8:
18801881
case AbsVecI32x4:

src/wasm/wasm.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -826,6 +826,7 @@ void Unary::finalize() {
826826
case AbsVecI8x16:
827827
case AbsVecI16x8:
828828
case AbsVecI32x4:
829+
case PopcntVecI8x16:
829830
case NegVecI8x16:
830831
case NegVecI16x8:
831832
case NegVecI32x4:

test/example/c-api-kitchen-sink.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -580,10 +580,10 @@ void test_core() {
580580
makeBinary(module, BinaryenMaxVecF32x4(), v128),
581581
makeBinary(module, BinaryenPMinVecF32x4(), v128),
582582
makeBinary(module, BinaryenPMaxVecF32x4(), v128),
583-
makeBinary(module, BinaryenCeilVecF32x4(), v128),
584-
makeBinary(module, BinaryenFloorVecF32x4(), v128),
585-
makeBinary(module, BinaryenTruncVecF32x4(), v128),
586-
makeBinary(module, BinaryenNearestVecF32x4(), v128),
583+
makeUnary(module, BinaryenCeilVecF32x4(), v128),
584+
makeUnary(module, BinaryenFloorVecF32x4(), v128),
585+
makeUnary(module, BinaryenTruncVecF32x4(), v128),
586+
makeUnary(module, BinaryenNearestVecF32x4(), v128),
587587
makeBinary(module, BinaryenAddVecF64x2(), v128),
588588
makeBinary(module, BinaryenSubVecF64x2(), v128),
589589
makeBinary(module, BinaryenMulVecF64x2(), v128),
@@ -592,10 +592,10 @@ void test_core() {
592592
makeBinary(module, BinaryenMaxVecF64x2(), v128),
593593
makeBinary(module, BinaryenPMinVecF64x2(), v128),
594594
makeBinary(module, BinaryenPMaxVecF64x2(), v128),
595-
makeBinary(module, BinaryenCeilVecF64x2(), v128),
596-
makeBinary(module, BinaryenFloorVecF64x2(), v128),
597-
makeBinary(module, BinaryenTruncVecF64x2(), v128),
598-
makeBinary(module, BinaryenNearestVecF64x2(), v128),
595+
makeUnary(module, BinaryenCeilVecF64x2(), v128),
596+
makeUnary(module, BinaryenFloorVecF64x2(), v128),
597+
makeUnary(module, BinaryenTruncVecF64x2(), v128),
598+
makeUnary(module, BinaryenNearestVecF64x2(), v128),
599599
makeBinary(module, BinaryenNarrowSVecI16x8ToVecI8x16(), v128),
600600
makeBinary(module, BinaryenNarrowUVecI16x8ToVecI8x16(), v128),
601601
makeBinary(module, BinaryenNarrowSVecI32x4ToVecI16x8(), v128),

test/example/c-api-kitchen-sink.txt

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1235,26 +1235,22 @@ BinaryenFeatureAll: 4095
12351235
)
12361236
)
12371237
(drop
1238-
(i16x8.lt_s
1239-
(v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)
1238+
(f32x4.ceil
12401239
(v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)
12411240
)
12421241
)
12431242
(drop
1244-
(i16x8.lt_u
1245-
(v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)
1243+
(f32x4.floor
12461244
(v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)
12471245
)
12481246
)
12491247
(drop
1250-
(i16x8.gt_s
1251-
(v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)
1248+
(f32x4.trunc
12521249
(v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)
12531250
)
12541251
)
12551252
(drop
1256-
(i16x8.gt_u
1257-
(v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)
1253+
(f32x4.nearest
12581254
(v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)
12591255
)
12601256
)
@@ -1307,26 +1303,22 @@ BinaryenFeatureAll: 4095
13071303
)
13081304
)
13091305
(drop
1310-
(i16x8.ge_u
1311-
(v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)
1306+
(f64x2.ceil
13121307
(v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)
13131308
)
13141309
)
13151310
(drop
1316-
(i32x4.eq
1317-
(v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)
1311+
(f64x2.floor
13181312
(v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)
13191313
)
13201314
)
13211315
(drop
1322-
(i32x4.ne
1323-
(v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)
1316+
(f64x2.trunc
13241317
(v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)
13251318
)
13261319
)
13271320
(drop
1328-
(i32x4.lt_s
1329-
(v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)
1321+
(f64x2.nearest
13301322
(v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)
13311323
)
13321324
)

test/simd.wast

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,11 @@
508508
(local.get $1)
509509
)
510510
)
511+
(func $i8x16.popcnt (param $0 v128) (result v128)
512+
(i8x16.popcnt
513+
(local.get $0)
514+
)
515+
)
511516
(func $i8x16.abs (param $0 v128) (result v128)
512517
(i8x16.abs
513518
(local.get $0)

test/simd.wast.from-wast

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,11 @@
525525
(local.get $1)
526526
)
527527
)
528+
(func $i8x16.popcnt (param $0 v128) (result v128)
529+
(i8x16.popcnt
530+
(local.get $0)
531+
)
532+
)
528533
(func $i8x16.abs (param $0 v128) (result v128)
529534
(i8x16.abs
530535
(local.get $0)

test/simd.wast.fromBinary

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,11 @@
525525
(local.get $1)
526526
)
527527
)
528+
(func $i8x16.popcnt (param $0 v128) (result v128)
529+
(i8x16.popcnt
530+
(local.get $0)
531+
)
532+
)
528533
(func $i8x16.abs (param $0 v128) (result v128)
529534
(i8x16.abs
530535
(local.get $0)

0 commit comments

Comments
 (0)