Skip to content

Commit

Permalink
Add i32x4.dot_i16x8_s
Browse files Browse the repository at this point in the history
This experimental instruction is specified in
WebAssembly/simd#127 and is being implemented
to enable further investigation of its performance impact.
  • Loading branch information
tlively committed Nov 4, 2019
1 parent 0a5925a commit 565d952
Show file tree
Hide file tree
Showing 27 changed files with 845 additions and 709 deletions.
1 change: 1 addition & 0 deletions build-js.sh
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,7 @@ export_function "_BinaryenMinSVecI32x4"
export_function "_BinaryenMinUVecI32x4"
export_function "_BinaryenMaxSVecI32x4"
export_function "_BinaryenMaxUVecI32x4"
export_function "_BinaryenDotSVecI16x8ToVecI32x4"
export_function "_BinaryenNegVecI64x2"
export_function "_BinaryenAnyTrueVecI64x2"
export_function "_BinaryenAllTrueVecI64x2"
Expand Down
1 change: 1 addition & 0 deletions scripts/gen-s-parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,7 @@
("i32x4.min_u", "makeBinary(s, BinaryOp::MinUVecI32x4)"),
("i32x4.max_s", "makeBinary(s, BinaryOp::MaxSVecI32x4)"),
("i32x4.max_u", "makeBinary(s, BinaryOp::MaxUVecI32x4)"),
("i32x4.dot_i16x8_s", "makeBinary(s, BinaryOp::DotSVecI16x8ToVecI32x4)"),
("i64x2.neg", "makeUnary(s, UnaryOp::NegVecI64x2)"),
("i64x2.any_true", "makeUnary(s, UnaryOp::AnyTrueVecI64x2)"),
("i64x2.all_true", "makeUnary(s, UnaryOp::AllTrueVecI64x2)"),
Expand Down
3 changes: 3 additions & 0 deletions src/binaryen-c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -842,6 +842,9 @@ BinaryenOp BinaryenMinSVecI32x4(void) { return MinSVecI32x4; }
BinaryenOp BinaryenMinUVecI32x4(void) { return MinUVecI32x4; }
BinaryenOp BinaryenMaxSVecI32x4(void) { return MaxSVecI32x4; }
BinaryenOp BinaryenMaxUVecI32x4(void) { return MaxUVecI32x4; }
BinaryenOp BinaryenDotSVecI16x8ToVecI32x4(void) {
return DotSVecI16x8ToVecI32x4;
}
BinaryenOp BinaryenNegVecI64x2(void) { return NegVecI64x2; }
BinaryenOp BinaryenAnyTrueVecI64x2(void) { return AnyTrueVecI64x2; }
BinaryenOp BinaryenAllTrueVecI64x2(void) { return AllTrueVecI64x2; }
Expand Down
1 change: 1 addition & 0 deletions src/binaryen-c.h
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,7 @@ BINARYEN_API BinaryenOp BinaryenMinSVecI32x4(void);
BINARYEN_API BinaryenOp BinaryenMinUVecI32x4(void);
BINARYEN_API BinaryenOp BinaryenMaxSVecI32x4(void);
BINARYEN_API BinaryenOp BinaryenMaxUVecI32x4(void);
BINARYEN_API BinaryenOp BinaryenDotSVecI16x8ToVecI32x4(void);
BINARYEN_API BinaryenOp BinaryenNegVecI64x2(void);
BINARYEN_API BinaryenOp BinaryenAnyTrueVecI64x2(void);
BINARYEN_API BinaryenOp BinaryenAllTrueVecI64x2(void);
Expand Down
3 changes: 3 additions & 0 deletions src/gen-s-parser.inc
Original file line number Diff line number Diff line change
Expand Up @@ -1409,6 +1409,9 @@ switch (op[0]) {
default: goto parse_error;
}
}
case 'd':
if (strcmp(op, "i32x4.dot_i16x8_s") == 0) { return makeBinary(s, BinaryOp::DotSVecI16x8ToVecI32x4); }
goto parse_error;
case 'e': {
switch (op[7]) {
case 'q':
Expand Down
3 changes: 3 additions & 0 deletions src/ir/cost.h
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,9 @@ struct CostAnalyzer : public Visitor<CostAnalyzer, Index> {
case MaxUVecI32x4:
ret = 1;
break;
case DotSVecI16x8ToVecI32x4:
ret = 1;
break;
case AddVecI64x2:
ret = 1;
break;
Expand Down
4 changes: 4 additions & 0 deletions src/js/binaryen.js-post.js
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,7 @@ Module['MinSVecI16x8'] = Module['_BinaryenMinSVecI16x8']();
Module['MinUVecI16x8'] = Module['_BinaryenMinUVecI16x8']();
Module['MaxSVecI16x8'] = Module['_BinaryenMaxSVecI16x8']();
Module['MaxUVecI16x8'] = Module['_BinaryenMaxUVecI16x8']();
Module['DotSVecI16x8ToVecI32x4'] = Module['_BinaryenDotSVecI16x8ToVecI32x4']();
Module['NegVecI32x4'] = Module['_BinaryenNegVecI32x4']();
Module['AnyTrueVecI32x4'] = Module['_BinaryenAnyTrueVecI32x4']();
Module['AllTrueVecI32x4'] = Module['_BinaryenAllTrueVecI32x4']();
Expand Down Expand Up @@ -1676,6 +1677,9 @@ function wrapModule(module, self) {
'max_u': function(left, right) {
return Module['_BinaryenBinary'](module, Module['MaxUVecI32x4'], left, right);
},
'dot_i16x8_s': function(left, right) {
return Module['_BinaryenBinary'](module, Module['DotSVecI16x8ToVecI32x4'], left, right);
},
'trunc_sat_f32x4_s': function(value) {
return Module['_BinaryenUnary'](module, Module['TruncSatSVecF32x4ToVecI32x4'], value);
},
Expand Down
1 change: 1 addition & 0 deletions src/literal.h
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,7 @@ class Literal {
Literal minUI32x4(const Literal& other) const;
Literal maxSI32x4(const Literal& other) const;
Literal maxUI32x4(const Literal& other) const;
Literal dotSI16x8toI32x4(const Literal& other) const;
Literal negI64x2() const;
Literal anyTrueI64x2() const;
Literal allTrueI64x2() const;
Expand Down
3 changes: 3 additions & 0 deletions src/passes/Print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1222,6 +1222,9 @@ struct PrintExpressionContents
case MaxUVecI32x4:
o << "i32x4.max_u";
break;
case DotSVecI16x8ToVecI32x4:
o << "i32x4.dot_i16x8_s";
break;
case AddVecI64x2:
o << "i64x2.add";
break;
Expand Down
1 change: 1 addition & 0 deletions src/tools/fuzzing.h
Original file line number Diff line number Diff line change
Expand Up @@ -2169,6 +2169,7 @@ class TranslateToFuzzReader {
MinUVecI32x4,
MaxSVecI32x4,
MaxUVecI32x4,
DotSVecI16x8ToVecI32x4,
AddVecI64x2,
SubVecI64x2,
AddVecF32x4,
Expand Down
1 change: 1 addition & 0 deletions src/wasm-binary.h
Original file line number Diff line number Diff line change
Expand Up @@ -831,6 +831,7 @@ enum ASTNodes {
I32x4MinU = 0x81,
I32x4MaxS = 0x82,
I32x4MaxU = 0x83,
I32x4DotSVecI16x8 = 0xd9,
I64x2Neg = 0x84,
I64x2AnyTrue = 0x85,
I64x2AllTrue = 0x86,
Expand Down
2 changes: 2 additions & 0 deletions src/wasm-interpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -801,6 +801,8 @@ class ExpressionRunner : public OverriddenVisitor<SubType, Flow> {
return left.maxSI32x4(right);
case MaxUVecI32x4:
return left.maxUI32x4(right);
case DotSVecI16x8ToVecI32x4:
return left.dotSI16x8toI32x4(right);
case AddVecI64x2:
return left.addI64x2(right);
case SubVecI64x2:
Expand Down
1 change: 1 addition & 0 deletions src/wasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,7 @@ enum BinaryOp {
MinUVecI32x4,
MaxSVecI32x4,
MaxUVecI32x4,
DotSVecI16x8ToVecI32x4,
AddVecI64x2,
SubVecI64x2,
AddVecF32x4,
Expand Down
11 changes: 11 additions & 0 deletions src/wasm/literal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1829,6 +1829,17 @@ Literal Literal::maxF64x2(const Literal& other) const {
return binary<2, &Literal::getLanesF64x2, &Literal::max>(*this, other);
}

Literal Literal::dotSI16x8toI32x4(const Literal& other) const {
LaneArray<8> lhs = getLanesSI16x8();
LaneArray<8> rhs = other.getLanesSI16x8();
LaneArray<4> result;
for (size_t i = 0; i < 4; ++i) {
result[i] = Literal(lhs[i * 2].geti32() * rhs[i * 2].geti32() +
lhs[i * 2 + 1].geti32() * rhs[i * 2 + 1].geti32());
}
return Literal(result);
}

Literal Literal::bitselectV128(const Literal& left,
const Literal& right) const {
return andV128(left).orV128(notV128().andV128(right));
Expand Down
4 changes: 4 additions & 0 deletions src/wasm/wasm-binary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3939,6 +3939,10 @@ bool WasmBinaryBuilder::maybeVisitSIMDBinary(Expression*& out, uint32_t code) {
curr = allocator.alloc<Binary>();
curr->op = MaxUVecI32x4;
break;
case BinaryConsts::I32x4DotSVecI16x8:
curr = allocator.alloc<Binary>();
curr->op = DotSVecI16x8ToVecI32x4;
break;
case BinaryConsts::I64x2Add:
curr = allocator.alloc<Binary>();
curr->op = AddVecI64x2;
Expand Down
4 changes: 4 additions & 0 deletions src/wasm/wasm-stack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1459,6 +1459,10 @@ void BinaryInstWriter::visitBinary(Binary* curr) {
case MaxUVecI32x4:
o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I32x4MaxU);
break;
case DotSVecI16x8ToVecI32x4:
o << int8_t(BinaryConsts::SIMDPrefix)
<< U32LEB(BinaryConsts::I32x4DotSVecI16x8);
break;
case AddVecI64x2:
o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I64x2Add);
break;
Expand Down
1 change: 1 addition & 0 deletions src/wasm/wasm-validator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1361,6 +1361,7 @@ void FunctionValidator::visitBinary(Binary* curr) {
case MinUVecI32x4:
case MaxSVecI32x4:
case MaxUVecI32x4:
case DotSVecI16x8ToVecI32x4:
case AddVecI64x2:
case SubVecI64x2:
case AddVecF32x4:
Expand Down
1 change: 1 addition & 0 deletions test/binaryen.js/kitchen-sink.js
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,7 @@ function test_core() {
module.i32x4.min_u(module.v128.const(v128_bytes), module.v128.const(v128_bytes)),
module.i32x4.max_s(module.v128.const(v128_bytes), module.v128.const(v128_bytes)),
module.i32x4.max_u(module.v128.const(v128_bytes), module.v128.const(v128_bytes)),
module.i32x4.dot_i16x8_s(module.v128.const(v128_bytes), module.v128.const(v128_bytes)),
module.i64x2.add(module.v128.const(v128_bytes), module.v128.const(v128_bytes)),
module.i64x2.sub(module.v128.const(v128_bytes), module.v128.const(v128_bytes)),
module.f32x4.add(module.v128.const(v128_bytes), module.v128.const(v128_bytes)),
Expand Down
Loading

0 comments on commit 565d952

Please sign in to comment.