diff options
author | Thomas Lively <7121787+tlively@users.noreply.github.com> | 2019-11-01 18:22:05 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-11-01 18:22:05 -0700 |
commit | 0a5925a52cc0888fb61bc7b55c78666add5025cd (patch) | |
tree | d21ff1cc88829dcacbc33b4ddd23e2d467fd8cb1 /src | |
parent | 90297e84007031ec884d829f973556d49c9b9467 (diff) | |
download | binaryen-0a5925a52cc0888fb61bc7b55c78666add5025cd.tar.gz binaryen-0a5925a52cc0888fb61bc7b55c78666add5025cd.tar.bz2 binaryen-0a5925a52cc0888fb61bc7b55c78666add5025cd.zip |
Add SIMD integer min and max instructions (#2416)
As proposed in https://github.com/WebAssembly/simd/pull/27.
Diffstat (limited to 'src')
-rw-r--r-- | src/binaryen-c.cpp | 12 | ||||
-rw-r--r-- | src/binaryen-c.h | 12 | ||||
-rw-r--r-- | src/gen-s-parser.inc | 99 | ||||
-rw-r--r-- | src/ir/cost.h | 36 | ||||
-rw-r--r-- | src/js/binaryen.js-post.js | 48 | ||||
-rw-r--r-- | src/literal.h | 16 | ||||
-rw-r--r-- | src/passes/Print.cpp | 36 | ||||
-rw-r--r-- | src/tools/fuzzing.h | 12 | ||||
-rw-r--r-- | src/wasm-binary.h | 12 | ||||
-rw-r--r-- | src/wasm-interpreter.h | 24 | ||||
-rw-r--r-- | src/wasm.h | 12 | ||||
-rw-r--r-- | src/wasm/literal.cpp | 49 | ||||
-rw-r--r-- | src/wasm/wasm-binary.cpp | 48 | ||||
-rw-r--r-- | src/wasm/wasm-stack.cpp | 36 | ||||
-rw-r--r-- | src/wasm/wasm-validator.cpp | 12 |
15 files changed, 455 insertions, 9 deletions
diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp index 018b5b861..2b9b9d2ae 100644 --- a/src/binaryen-c.cpp +++ b/src/binaryen-c.cpp @@ -808,6 +808,10 @@ BinaryenOp BinaryenSubVecI8x16(void) { return SubVecI8x16; } BinaryenOp BinaryenSubSatSVecI8x16(void) { return SubSatSVecI8x16; } BinaryenOp BinaryenSubSatUVecI8x16(void) { return SubSatUVecI8x16; } BinaryenOp BinaryenMulVecI8x16(void) { return MulVecI8x16; } +BinaryenOp BinaryenMinSVecI8x16(void) { return MinSVecI8x16; } +BinaryenOp BinaryenMinUVecI8x16(void) { return MinUVecI8x16; } +BinaryenOp BinaryenMaxSVecI8x16(void) { return MaxSVecI8x16; } +BinaryenOp BinaryenMaxUVecI8x16(void) { return MaxUVecI8x16; } BinaryenOp BinaryenNegVecI16x8(void) { return NegVecI16x8; } BinaryenOp BinaryenAnyTrueVecI16x8(void) { return AnyTrueVecI16x8; } BinaryenOp BinaryenAllTrueVecI16x8(void) { return AllTrueVecI16x8; } @@ -821,6 +825,10 @@ BinaryenOp BinaryenSubVecI16x8(void) { return SubVecI16x8; } BinaryenOp BinaryenSubSatSVecI16x8(void) { return SubSatSVecI16x8; } BinaryenOp BinaryenSubSatUVecI16x8(void) { return SubSatUVecI16x8; } BinaryenOp BinaryenMulVecI16x8(void) { return MulVecI16x8; } +BinaryenOp BinaryenMinSVecI16x8(void) { return MinSVecI16x8; } +BinaryenOp BinaryenMinUVecI16x8(void) { return MinUVecI16x8; } +BinaryenOp BinaryenMaxSVecI16x8(void) { return MaxSVecI16x8; } +BinaryenOp BinaryenMaxUVecI16x8(void) { return MaxUVecI16x8; } BinaryenOp BinaryenNegVecI32x4(void) { return NegVecI32x4; } BinaryenOp BinaryenAnyTrueVecI32x4(void) { return AnyTrueVecI32x4; } BinaryenOp BinaryenAllTrueVecI32x4(void) { return AllTrueVecI32x4; } @@ -830,6 +838,10 @@ BinaryenOp BinaryenShrUVecI32x4(void) { return ShrUVecI32x4; } BinaryenOp BinaryenAddVecI32x4(void) { return AddVecI32x4; } BinaryenOp BinaryenSubVecI32x4(void) { return SubVecI32x4; } BinaryenOp BinaryenMulVecI32x4(void) { return MulVecI32x4; } +BinaryenOp BinaryenMinSVecI32x4(void) { return MinSVecI32x4; } +BinaryenOp BinaryenMinUVecI32x4(void) { return MinUVecI32x4; } +BinaryenOp BinaryenMaxSVecI32x4(void) { return MaxSVecI32x4; } +BinaryenOp BinaryenMaxUVecI32x4(void) { return MaxUVecI32x4; } BinaryenOp BinaryenNegVecI64x2(void) { return NegVecI64x2; } BinaryenOp BinaryenAnyTrueVecI64x2(void) { return AnyTrueVecI64x2; } BinaryenOp BinaryenAllTrueVecI64x2(void) { return AllTrueVecI64x2; } diff --git a/src/binaryen-c.h b/src/binaryen-c.h index 1b7d3b10c..936cfb0f6 100644 --- a/src/binaryen-c.h +++ b/src/binaryen-c.h @@ -470,6 +470,10 @@ BINARYEN_API BinaryenOp BinaryenSubVecI8x16(void); BINARYEN_API BinaryenOp BinaryenSubSatSVecI8x16(void); BINARYEN_API BinaryenOp BinaryenSubSatUVecI8x16(void); BINARYEN_API BinaryenOp BinaryenMulVecI8x16(void); +BINARYEN_API BinaryenOp BinaryenMinSVecI8x16(void); +BINARYEN_API BinaryenOp BinaryenMinUVecI8x16(void); +BINARYEN_API BinaryenOp BinaryenMaxSVecI8x16(void); +BINARYEN_API BinaryenOp BinaryenMaxUVecI8x16(void); BINARYEN_API BinaryenOp BinaryenNegVecI16x8(void); BINARYEN_API BinaryenOp BinaryenAnyTrueVecI16x8(void); BINARYEN_API BinaryenOp BinaryenAllTrueVecI16x8(void); @@ -483,6 +487,10 @@ BINARYEN_API BinaryenOp BinaryenSubVecI16x8(void); BINARYEN_API BinaryenOp BinaryenSubSatSVecI16x8(void); BINARYEN_API BinaryenOp BinaryenSubSatUVecI16x8(void); BINARYEN_API BinaryenOp BinaryenMulVecI16x8(void); +BINARYEN_API BinaryenOp BinaryenMinSVecI16x8(void); +BINARYEN_API BinaryenOp BinaryenMinUVecI16x8(void); +BINARYEN_API BinaryenOp BinaryenMaxSVecI16x8(void); +BINARYEN_API BinaryenOp BinaryenMaxUVecI16x8(void); BINARYEN_API BinaryenOp BinaryenNegVecI32x4(void); BINARYEN_API BinaryenOp BinaryenAnyTrueVecI32x4(void); BINARYEN_API BinaryenOp BinaryenAllTrueVecI32x4(void); @@ -492,6 +500,10 @@ BINARYEN_API BinaryenOp BinaryenShrUVecI32x4(void); BINARYEN_API BinaryenOp BinaryenAddVecI32x4(void); BINARYEN_API BinaryenOp BinaryenSubVecI32x4(void); BINARYEN_API BinaryenOp BinaryenMulVecI32x4(void); +BINARYEN_API BinaryenOp BinaryenMinSVecI32x4(void); +BINARYEN_API BinaryenOp BinaryenMinUVecI32x4(void); +BINARYEN_API BinaryenOp BinaryenMaxSVecI32x4(void); +BINARYEN_API BinaryenOp BinaryenMaxUVecI32x4(void); BINARYEN_API BinaryenOp BinaryenNegVecI64x2(void); BINARYEN_API BinaryenOp BinaryenAnyTrueVecI64x2(void); BINARYEN_API BinaryenOp BinaryenAllTrueVecI64x2(void); diff --git a/src/gen-s-parser.inc b/src/gen-s-parser.inc index 85702d326..9a8d9b88c 100644 --- a/src/gen-s-parser.inc +++ b/src/gen-s-parser.inc @@ -793,9 +793,36 @@ switch (op[0]) { default: goto parse_error; } } - case 'm': - if (strcmp(op, "i16x8.mul") == 0) { return makeBinary(s, BinaryOp::MulVecI16x8); } - goto parse_error; + case 'm': { + switch (op[7]) { + case 'a': { + switch (op[10]) { + case 's': + if (strcmp(op, "i16x8.max_s") == 0) { return makeBinary(s, BinaryOp::MaxSVecI16x8); } + goto parse_error; + case 'u': + if (strcmp(op, "i16x8.max_u") == 0) { return makeBinary(s, BinaryOp::MaxUVecI16x8); } + goto parse_error; + default: goto parse_error; + } + } + case 'i': { + switch (op[10]) { + case 's': + if (strcmp(op, "i16x8.min_s") == 0) { return makeBinary(s, BinaryOp::MinSVecI16x8); } + goto parse_error; + case 'u': + if (strcmp(op, "i16x8.min_u") == 0) { return makeBinary(s, BinaryOp::MinUVecI16x8); } + goto parse_error; + default: goto parse_error; + } + } + case 'u': + if (strcmp(op, "i16x8.mul") == 0) { return makeBinary(s, BinaryOp::MulVecI16x8); } + goto parse_error; + default: goto parse_error; + } + } case 'n': { switch (op[7]) { case 'a': { @@ -1458,9 +1485,36 @@ switch (op[0]) { default: goto parse_error; } } - case 'm': - if (strcmp(op, "i32x4.mul") == 0) { return makeBinary(s, BinaryOp::MulVecI32x4); } - goto parse_error; + case 'm': { + switch (op[7]) { + case 'a': { + switch (op[10]) { + case 's': + if (strcmp(op, "i32x4.max_s") == 0) { return makeBinary(s, BinaryOp::MaxSVecI32x4); } + goto parse_error; + case 'u': + if (strcmp(op, "i32x4.max_u") == 0) { return makeBinary(s, BinaryOp::MaxUVecI32x4); } + goto parse_error; + default: goto parse_error; + } + } + case 'i': { + switch (op[10]) { + case 's': + if (strcmp(op, "i32x4.min_s") == 0) { return makeBinary(s, BinaryOp::MinSVecI32x4); } + goto parse_error; + case 'u': + if (strcmp(op, "i32x4.min_u") == 0) { return makeBinary(s, BinaryOp::MinUVecI32x4); } + goto parse_error; + default: goto parse_error; + } + } + case 'u': + if (strcmp(op, "i32x4.mul") == 0) { return makeBinary(s, BinaryOp::MulVecI32x4); } + goto parse_error; + default: goto parse_error; + } + } case 'n': { switch (op[8]) { case '\0': @@ -2268,9 +2322,36 @@ switch (op[0]) { default: goto parse_error; } } - case 'm': - if (strcmp(op, "i8x16.mul") == 0) { return makeBinary(s, BinaryOp::MulVecI8x16); } - goto parse_error; + case 'm': { + switch (op[7]) { + case 'a': { + switch (op[10]) { + case 's': + if (strcmp(op, "i8x16.max_s") == 0) { return makeBinary(s, BinaryOp::MaxSVecI8x16); } + goto parse_error; + case 'u': + if (strcmp(op, "i8x16.max_u") == 0) { return makeBinary(s, BinaryOp::MaxUVecI8x16); } + goto parse_error; + default: goto parse_error; + } + } + case 'i': { + switch (op[10]) { + case 's': + if (strcmp(op, "i8x16.min_s") == 0) { return makeBinary(s, BinaryOp::MinSVecI8x16); } + goto parse_error; + case 'u': + if (strcmp(op, "i8x16.min_u") == 0) { return makeBinary(s, BinaryOp::MinUVecI8x16); } + goto parse_error; + default: goto parse_error; + } + } + case 'u': + if (strcmp(op, "i8x16.mul") == 0) { return makeBinary(s, BinaryOp::MulVecI8x16); } + goto parse_error; + default: goto parse_error; + } + } case 'n': { switch (op[7]) { case 'a': { diff --git a/src/ir/cost.h b/src/ir/cost.h index a3d9f8584..26c120675 100644 --- a/src/ir/cost.h +++ b/src/ir/cost.h @@ -582,6 +582,18 @@ struct CostAnalyzer : public Visitor<CostAnalyzer, Index> { case MulVecI8x16: ret = 2; break; + case MinSVecI8x16: + ret = 1; + break; + case MinUVecI8x16: + ret = 1; + break; + case MaxSVecI8x16: + ret = 1; + break; + case MaxUVecI8x16: + ret = 1; + break; case AddVecI16x8: ret = 1; break; @@ -603,6 +615,18 @@ struct CostAnalyzer : public Visitor<CostAnalyzer, Index> { case MulVecI16x8: ret = 2; break; + case MinSVecI16x8: + ret = 1; + break; + case MinUVecI16x8: + ret = 1; + break; + case MaxSVecI16x8: + ret = 1; + break; + case MaxUVecI16x8: + ret = 1; + break; case AddVecI32x4: ret = 1; break; @@ -612,6 +636,18 @@ struct CostAnalyzer : public Visitor<CostAnalyzer, Index> { case MulVecI32x4: ret = 2; break; + case MinSVecI32x4: + ret = 1; + break; + case MinUVecI32x4: + ret = 1; + break; + case MaxSVecI32x4: + ret = 1; + break; + case MaxUVecI32x4: + ret = 1; + break; case AddVecI64x2: ret = 1; break; diff --git a/src/js/binaryen.js-post.js b/src/js/binaryen.js-post.js index b4cd5e482..f2d679900 100644 --- a/src/js/binaryen.js-post.js +++ b/src/js/binaryen.js-post.js @@ -336,6 +336,10 @@ Module['SubVecI8x16'] = Module['_BinaryenSubVecI8x16'](); Module['SubSatSVecI8x16'] = Module['_BinaryenSubSatSVecI8x16'](); Module['SubSatUVecI8x16'] = Module['_BinaryenSubSatUVecI8x16'](); Module['MulVecI8x16'] = Module['_BinaryenMulVecI8x16'](); +Module['MinSVecI8x16'] = Module['_BinaryenMinSVecI8x16'](); +Module['MinUVecI8x16'] = Module['_BinaryenMinUVecI8x16'](); +Module['MaxSVecI8x16'] = Module['_BinaryenMaxSVecI8x16'](); +Module['MaxUVecI8x16'] = Module['_BinaryenMaxUVecI8x16'](); Module['NegVecI16x8'] = Module['_BinaryenNegVecI16x8'](); Module['AnyTrueVecI16x8'] = Module['_BinaryenAnyTrueVecI16x8'](); Module['AllTrueVecI16x8'] = Module['_BinaryenAllTrueVecI16x8'](); @@ -349,6 +353,10 @@ Module['SubVecI16x8'] = Module['_BinaryenSubVecI16x8'](); Module['SubSatSVecI16x8'] = Module['_BinaryenSubSatSVecI16x8'](); Module['SubSatUVecI16x8'] = Module['_BinaryenSubSatUVecI16x8'](); Module['MulVecI16x8'] = Module['_BinaryenMulVecI16x8'](); +Module['MinSVecI16x8'] = Module['_BinaryenMinSVecI16x8'](); +Module['MinUVecI16x8'] = Module['_BinaryenMinUVecI16x8'](); +Module['MaxSVecI16x8'] = Module['_BinaryenMaxSVecI16x8'](); +Module['MaxUVecI16x8'] = Module['_BinaryenMaxUVecI16x8'](); Module['NegVecI32x4'] = Module['_BinaryenNegVecI32x4'](); Module['AnyTrueVecI32x4'] = Module['_BinaryenAnyTrueVecI32x4'](); Module['AllTrueVecI32x4'] = Module['_BinaryenAllTrueVecI32x4'](); @@ -358,6 +366,10 @@ Module['ShrUVecI32x4'] = Module['_BinaryenShrUVecI32x4'](); Module['AddVecI32x4'] = Module['_BinaryenAddVecI32x4'](); Module['SubVecI32x4'] = Module['_BinaryenSubVecI32x4'](); Module['MulVecI32x4'] = Module['_BinaryenMulVecI32x4'](); +Module['MinSVecI32x4'] = Module['_BinaryenMinSVecI32x4'](); +Module['MinUVecI32x4'] = Module['_BinaryenMinUVecI32x4'](); +Module['MaxSVecI32x4'] = Module['_BinaryenMaxSVecI32x4'](); +Module['MaxUVecI32x4'] = Module['_BinaryenMaxUVecI32x4'](); Module['NegVecI64x2'] = Module['_BinaryenNegVecI64x2'](); Module['AnyTrueVecI64x2'] = Module['_BinaryenAnyTrueVecI64x2'](); Module['AllTrueVecI64x2'] = Module['_BinaryenAllTrueVecI64x2'](); @@ -1445,6 +1457,18 @@ function wrapModule(module, self) { 'mul': function(left, right) { return Module['_BinaryenBinary'](module, Module['MulVecI8x16'], left, right); }, + 'min_s': function(left, right) { + return Module['_BinaryenBinary'](module, Module['MinSVecI8x16'], left, right); + }, + 'min_u': function(left, right) { + return Module['_BinaryenBinary'](module, Module['MinUVecI8x16'], left, right); + }, + 'max_s': function(left, right) { + return Module['_BinaryenBinary'](module, Module['MaxSVecI8x16'], left, right); + }, + 'max_u': function(left, right) { + return Module['_BinaryenBinary'](module, Module['MaxUVecI8x16'], left, right); + }, 'narrow_i16x8_s': function(left, right) { return Module['_BinaryenBinary'](module, Module['NarrowSVecI16x8ToVecI8x16'], left, right); }, @@ -1535,6 +1559,18 @@ function wrapModule(module, self) { 'mul': function(left, right) { return Module['_BinaryenBinary'](module, Module['MulVecI16x8'], left, right); }, + 'min_s': function(left, right) { + return Module['_BinaryenBinary'](module, Module['MinSVecI16x8'], left, right); + }, + 'min_u': function(left, right) { + return Module['_BinaryenBinary'](module, Module['MinUVecI16x8'], left, right); + }, + 'max_s': function(left, right) { + return Module['_BinaryenBinary'](module, Module['MaxSVecI16x8'], left, right); + }, + 'max_u': function(left, right) { + return Module['_BinaryenBinary'](module, Module['MaxUVecI16x8'], left, right); + }, 'narrow_i32x4_s': function(left, right) { return Module['_BinaryenBinary'](module, Module['NarrowSVecI32x4ToVecI16x8'], left, right); }, @@ -1628,6 +1664,18 @@ function wrapModule(module, self) { 'mul': function(left, right) { return Module['_BinaryenBinary'](module, Module['MulVecI32x4'], left, right); }, + 'min_s': function(left, right) { + return Module['_BinaryenBinary'](module, Module['MinSVecI32x4'], left, right); + }, + 'min_u': function(left, right) { + return Module['_BinaryenBinary'](module, Module['MinUVecI32x4'], left, right); + }, + 'max_s': function(left, right) { + return Module['_BinaryenBinary'](module, Module['MaxSVecI32x4'], left, right); + }, + 'max_u': function(left, right) { + return Module['_BinaryenBinary'](module, Module['MaxUVecI32x4'], left, right); + }, 'trunc_sat_f32x4_s': function(value) { return Module['_BinaryenUnary'](module, Module['TruncSatSVecF32x4ToVecI32x4'], value); }, diff --git a/src/literal.h b/src/literal.h index 19db6a1d6..007a2cde8 100644 --- a/src/literal.h +++ b/src/literal.h @@ -330,6 +330,10 @@ public: Literal subSaturateSI8x16(const Literal& other) const; Literal subSaturateUI8x16(const Literal& other) const; Literal mulI8x16(const Literal& other) const; + Literal minSI8x16(const Literal& other) const; + Literal minUI8x16(const Literal& other) const; + Literal maxSI8x16(const Literal& other) const; + Literal maxUI8x16(const Literal& other) const; Literal negI16x8() const; Literal anyTrueI16x8() const; Literal allTrueI16x8() const; @@ -343,6 +347,10 @@ public: Literal subSaturateSI16x8(const Literal& other) const; Literal subSaturateUI16x8(const Literal& other) const; Literal mulI16x8(const Literal& other) const; + Literal minSI16x8(const Literal& other) const; + Literal minUI16x8(const Literal& other) const; + Literal maxSI16x8(const Literal& other) const; + Literal maxUI16x8(const Literal& other) const; Literal negI32x4() const; Literal anyTrueI32x4() const; Literal allTrueI32x4() const; @@ -352,6 +360,10 @@ public: Literal addI32x4(const Literal& other) const; Literal subI32x4(const Literal& other) const; Literal mulI32x4(const Literal& other) const; + Literal minSI32x4(const Literal& other) const; + Literal minUI32x4(const Literal& other) const; + Literal maxSI32x4(const Literal& other) const; + Literal maxUI32x4(const Literal& other) const; Literal negI64x2() const; Literal anyTrueI64x2() const; Literal allTrueI64x2() const; @@ -409,6 +421,10 @@ private: Literal subSatUI8(const Literal& other) const; Literal subSatSI16(const Literal& other) const; Literal subSatUI16(const Literal& other) const; + Literal minInt(const Literal& other) const; + Literal maxInt(const Literal& other) const; + Literal minUInt(const Literal& other) const; + Literal maxUInt(const Literal& other) const; }; } // namespace wasm diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 95c6a0568..e383974d6 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -1156,6 +1156,18 @@ struct PrintExpressionContents case MulVecI8x16: o << "i8x16.mul"; break; + case MinSVecI8x16: + o << "i8x16.min_s"; + break; + case MinUVecI8x16: + o << "i8x16.min_u"; + break; + case MaxSVecI8x16: + o << "i8x16.max_s"; + break; + case MaxUVecI8x16: + o << "i8x16.max_u"; + break; case AddVecI16x8: o << "i16x8.add"; break; @@ -1177,6 +1189,18 @@ struct PrintExpressionContents case MulVecI16x8: o << "i16x8.mul"; break; + case MinSVecI16x8: + o << "i16x8.min_s"; + break; + case MinUVecI16x8: + o << "i16x8.min_u"; + break; + case MaxSVecI16x8: + o << "i16x8.max_s"; + break; + case MaxUVecI16x8: + o << "i16x8.max_u"; + break; case AddVecI32x4: o << "i32x4.add"; break; @@ -1186,6 +1210,18 @@ struct PrintExpressionContents case MulVecI32x4: o << "i32x4.mul"; break; + case MinSVecI32x4: + o << "i32x4.min_s"; + break; + case MinUVecI32x4: + o << "i32x4.min_u"; + break; + case MaxSVecI32x4: + o << "i32x4.max_s"; + break; + case MaxUVecI32x4: + o << "i32x4.max_u"; + break; case AddVecI64x2: o << "i64x2.add"; break; diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h index c4070427c..c6cce4427 100644 --- a/src/tools/fuzzing.h +++ b/src/tools/fuzzing.h @@ -2147,6 +2147,10 @@ private: SubSatSVecI8x16, SubSatUVecI8x16, MulVecI8x16, + MinSVecI8x16, + MinUVecI8x16, + MaxSVecI8x16, + MaxUVecI8x16, AddVecI16x8, AddSatSVecI16x8, AddSatUVecI16x8, @@ -2154,9 +2158,17 @@ private: SubSatSVecI16x8, SubSatUVecI16x8, MulVecI16x8, + MinSVecI16x8, + MinUVecI16x8, + MaxSVecI16x8, + MaxUVecI16x8, AddVecI32x4, SubVecI32x4, MulVecI32x4, + MinSVecI32x4, + MinUVecI32x4, + MaxSVecI32x4, + MaxUVecI32x4, AddVecI64x2, SubVecI64x2, AddVecF32x4, diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 104e7b208..2a457f5a7 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -797,6 +797,10 @@ enum ASTNodes { I8x16SubSatS = 0x5b, I8x16SubSatU = 0x5c, I8x16Mul = 0x5d, + I8x16MinS = 0x5e, + I8x16MinU = 0x5f, + I8x16MaxS = 0x60, + I8x16MaxU = 0x61, I16x8Neg = 0x62, I16x8AnyTrue = 0x63, I16x8AllTrue = 0x64, @@ -810,6 +814,10 @@ enum ASTNodes { I16x8SubSatS = 0x6c, I16x8SubSatU = 0x6d, I16x8Mul = 0x6e, + I16x8MinS = 0x6f, + I16x8MinU = 0x70, + I16x8MaxS = 0x71, + I16x8MaxU = 0x72, I32x4Neg = 0x73, I32x4AnyTrue = 0x74, I32x4AllTrue = 0x75, @@ -819,6 +827,10 @@ enum ASTNodes { I32x4Add = 0x79, I32x4Sub = 0x7c, I32x4Mul = 0x7f, + I32x4MinS = 0x80, + I32x4MinU = 0x81, + I32x4MaxS = 0x82, + I32x4MaxU = 0x83, I64x2Neg = 0x84, I64x2AnyTrue = 0x85, I64x2AllTrue = 0x86, diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 5995808a5..f8cf3ae42 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -757,6 +757,14 @@ public: return left.subSaturateUI8x16(right); case MulVecI8x16: return left.mulI8x16(right); + case MinSVecI8x16: + return left.minSI8x16(right); + case MinUVecI8x16: + return left.minUI8x16(right); + case MaxSVecI8x16: + return left.maxSI8x16(right); + case MaxUVecI8x16: + return left.maxUI8x16(right); case AddVecI16x8: return left.addI16x8(right); case AddSatSVecI16x8: @@ -771,12 +779,28 @@ public: return left.subSaturateUI16x8(right); case MulVecI16x8: return left.mulI16x8(right); + case MinSVecI16x8: + return left.minSI16x8(right); + case MinUVecI16x8: + return left.minUI16x8(right); + case MaxSVecI16x8: + return left.maxSI16x8(right); + case MaxUVecI16x8: + return left.maxUI16x8(right); case AddVecI32x4: return left.addI32x4(right); case SubVecI32x4: return left.subI32x4(right); case MulVecI32x4: return left.mulI32x4(right); + case MinSVecI32x4: + return left.minSI32x4(right); + case MinUVecI32x4: + return left.minUI32x4(right); + case MaxSVecI32x4: + return left.maxSI32x4(right); + case MaxUVecI32x4: + return left.maxUI32x4(right); case AddVecI64x2: return left.addI64x2(right); case SubVecI64x2: diff --git a/src/wasm.h b/src/wasm.h index d4b53f5bb..ca1114182 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -361,6 +361,10 @@ enum BinaryOp { SubSatSVecI8x16, SubSatUVecI8x16, MulVecI8x16, + MinSVecI8x16, + MinUVecI8x16, + MaxSVecI8x16, + MaxUVecI8x16, AddVecI16x8, AddSatSVecI16x8, AddSatUVecI16x8, @@ -368,9 +372,17 @@ enum BinaryOp { SubSatSVecI16x8, SubSatUVecI16x8, MulVecI16x8, + MinSVecI16x8, + MinUVecI16x8, + MaxSVecI16x8, + MaxUVecI16x8, AddVecI32x4, SubVecI32x4, MulVecI32x4, + MinSVecI32x4, + MinUVecI32x4, + MaxSVecI32x4, + MaxUVecI32x4, AddVecI64x2, SubVecI64x2, AddVecF32x4, diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp index 7f0c9fa6b..f4ddf69cc 100644 --- a/src/wasm/literal.cpp +++ b/src/wasm/literal.cpp @@ -847,6 +847,19 @@ Literal Literal::remU(const Literal& other) const { } } +Literal Literal::minInt(const Literal& other) const { + return geti32() < other.geti32() ? *this : other; +} +Literal Literal::maxInt(const Literal& other) const { + return geti32() > other.geti32() ? *this : other; +} +Literal Literal::minUInt(const Literal& other) const { + return uint32_t(geti32()) < uint32_t(other.geti32()) ? *this : other; +} +Literal Literal::maxUInt(const Literal& other) const { + return uint32_t(geti32()) > uint32_t(other.geti32()) ? *this : other; +} + Literal Literal::and_(const Literal& other) const { switch (type) { case Type::i32: @@ -1703,6 +1716,18 @@ Literal Literal::subSaturateUI8x16(const Literal& other) const { Literal Literal::mulI8x16(const Literal& other) const { return binary<16, &Literal::getLanesUI8x16, &Literal::mul>(*this, other); } +Literal Literal::minSI8x16(const Literal& other) const { + return binary<16, &Literal::getLanesSI8x16, &Literal::minInt>(*this, other); +} +Literal Literal::minUI8x16(const Literal& other) const { + return binary<16, &Literal::getLanesUI8x16, &Literal::minInt>(*this, other); +} +Literal Literal::maxSI8x16(const Literal& other) const { + return binary<16, &Literal::getLanesSI8x16, &Literal::maxInt>(*this, other); +} +Literal Literal::maxUI8x16(const Literal& other) const { + return binary<16, &Literal::getLanesUI8x16, &Literal::maxInt>(*this, other); +} Literal Literal::addI16x8(const Literal& other) const { return binary<8, &Literal::getLanesUI16x8, &Literal::add>(*this, other); } @@ -1728,6 +1753,18 @@ Literal Literal::subSaturateUI16x8(const Literal& other) const { Literal Literal::mulI16x8(const Literal& other) const { return binary<8, &Literal::getLanesUI16x8, &Literal::mul>(*this, other); } +Literal Literal::minSI16x8(const Literal& other) const { + return binary<8, &Literal::getLanesSI16x8, &Literal::minInt>(*this, other); +} +Literal Literal::minUI16x8(const Literal& other) const { + return binary<8, &Literal::getLanesUI16x8, &Literal::minInt>(*this, other); +} +Literal Literal::maxSI16x8(const Literal& other) const { + return binary<8, &Literal::getLanesSI16x8, &Literal::maxInt>(*this, other); +} +Literal Literal::maxUI16x8(const Literal& other) const { + return binary<8, &Literal::getLanesUI16x8, &Literal::maxInt>(*this, other); +} Literal Literal::addI32x4(const Literal& other) const { return binary<4, &Literal::getLanesI32x4, &Literal::add>(*this, other); } @@ -1737,6 +1774,18 @@ Literal Literal::subI32x4(const Literal& other) const { Literal Literal::mulI32x4(const Literal& other) const { return binary<4, &Literal::getLanesI32x4, &Literal::mul>(*this, other); } +Literal Literal::minSI32x4(const Literal& other) const { + return binary<4, &Literal::getLanesI32x4, &Literal::minInt>(*this, other); +} +Literal Literal::minUI32x4(const Literal& other) const { + return binary<4, &Literal::getLanesI32x4, &Literal::minUInt>(*this, other); +} +Literal Literal::maxSI32x4(const Literal& other) const { + return binary<4, &Literal::getLanesI32x4, &Literal::maxInt>(*this, other); +} +Literal Literal::maxUI32x4(const Literal& other) const { + return binary<4, &Literal::getLanesI32x4, &Literal::maxUInt>(*this, other); +} Literal Literal::addI64x2(const Literal& other) const { return binary<2, &Literal::getLanesI64x2, &Literal::add>(*this, other); } diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 8446f3c17..cb67d1556 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -3851,6 +3851,22 @@ bool WasmBinaryBuilder::maybeVisitSIMDBinary(Expression*& out, uint32_t code) { curr = allocator.alloc<Binary>(); curr->op = MulVecI8x16; break; + case BinaryConsts::I8x16MinS: + curr = allocator.alloc<Binary>(); + curr->op = MinSVecI8x16; + break; + case BinaryConsts::I8x16MinU: + curr = allocator.alloc<Binary>(); + curr->op = MinUVecI8x16; + break; + case BinaryConsts::I8x16MaxS: + curr = allocator.alloc<Binary>(); + curr->op = MaxSVecI8x16; + break; + case BinaryConsts::I8x16MaxU: + curr = allocator.alloc<Binary>(); + curr->op = MaxUVecI8x16; + break; case BinaryConsts::I16x8Add: curr = allocator.alloc<Binary>(); curr->op = AddVecI16x8; @@ -3879,6 +3895,22 @@ bool WasmBinaryBuilder::maybeVisitSIMDBinary(Expression*& out, uint32_t code) { curr = allocator.alloc<Binary>(); curr->op = MulVecI16x8; break; + case BinaryConsts::I16x8MinS: + curr = allocator.alloc<Binary>(); + curr->op = MinSVecI16x8; + break; + case BinaryConsts::I16x8MinU: + curr = allocator.alloc<Binary>(); + curr->op = MinUVecI16x8; + break; + case BinaryConsts::I16x8MaxS: + curr = allocator.alloc<Binary>(); + curr->op = MaxSVecI16x8; + break; + case BinaryConsts::I16x8MaxU: + curr = allocator.alloc<Binary>(); + curr->op = MaxUVecI16x8; + break; case BinaryConsts::I32x4Add: curr = allocator.alloc<Binary>(); curr->op = AddVecI32x4; @@ -3891,6 +3923,22 @@ bool WasmBinaryBuilder::maybeVisitSIMDBinary(Expression*& out, uint32_t code) { curr = allocator.alloc<Binary>(); curr->op = MulVecI32x4; break; + case BinaryConsts::I32x4MinS: + curr = allocator.alloc<Binary>(); + curr->op = MinSVecI32x4; + break; + case BinaryConsts::I32x4MinU: + curr = allocator.alloc<Binary>(); + curr->op = MinUVecI32x4; + break; + case BinaryConsts::I32x4MaxS: + curr = allocator.alloc<Binary>(); + curr->op = MaxSVecI32x4; + break; + case BinaryConsts::I32x4MaxU: + curr = allocator.alloc<Binary>(); + curr->op = MaxUVecI32x4; + break; case BinaryConsts::I64x2Add: curr = allocator.alloc<Binary>(); curr->op = AddVecI64x2; diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index 949bf1364..d4af126b7 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -1389,6 +1389,18 @@ void BinaryInstWriter::visitBinary(Binary* curr) { case MulVecI8x16: o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I8x16Mul); break; + case MinSVecI8x16: + o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I8x16MinS); + break; + case MinUVecI8x16: + o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I8x16MinU); + break; + case MaxSVecI8x16: + o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I8x16MaxS); + break; + case MaxUVecI8x16: + o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I8x16MaxU); + break; case AddVecI16x8: o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I16x8Add); break; @@ -1414,6 +1426,18 @@ void BinaryInstWriter::visitBinary(Binary* curr) { case MulVecI16x8: o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I16x8Mul); break; + case MinSVecI16x8: + o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I16x8MinS); + break; + case MinUVecI16x8: + o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I16x8MinU); + break; + case MaxSVecI16x8: + o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I16x8MaxS); + break; + case MaxUVecI16x8: + o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I16x8MaxU); + break; case AddVecI32x4: o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I32x4Add); break; @@ -1423,6 +1447,18 @@ void BinaryInstWriter::visitBinary(Binary* curr) { case MulVecI32x4: o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I32x4Mul); break; + case MinSVecI32x4: + o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I32x4MinS); + break; + case MinUVecI32x4: + o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I32x4MinU); + break; + case MaxSVecI32x4: + o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I32x4MaxS); + break; + case MaxUVecI32x4: + o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I32x4MaxU); + break; case AddVecI64x2: o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I64x2Add); break; diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 278ec4769..ed54173ed 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -1339,6 +1339,10 @@ void FunctionValidator::visitBinary(Binary* curr) { case SubSatSVecI8x16: case SubSatUVecI8x16: case MulVecI8x16: + case MinSVecI8x16: + case MinUVecI8x16: + case MaxSVecI8x16: + case MaxUVecI8x16: case AddVecI16x8: case AddSatSVecI16x8: case AddSatUVecI16x8: @@ -1346,9 +1350,17 @@ void FunctionValidator::visitBinary(Binary* curr) { case SubSatSVecI16x8: case SubSatUVecI16x8: case MulVecI16x8: + case MinSVecI16x8: + case MinUVecI16x8: + case MaxSVecI16x8: + case MaxUVecI16x8: case AddVecI32x4: case SubVecI32x4: case MulVecI32x4: + case MinSVecI32x4: + case MinUVecI32x4: + case MaxSVecI32x4: + case MaxUVecI32x4: case AddVecI64x2: case SubVecI64x2: case AddVecF32x4: |