summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas Lively <7121787+tlively@users.noreply.github.com>2019-11-01 18:22:05 -0700
committerGitHub <noreply@github.com>2019-11-01 18:22:05 -0700
commit0a5925a52cc0888fb61bc7b55c78666add5025cd (patch)
treed21ff1cc88829dcacbc33b4ddd23e2d467fd8cb1 /src
parent90297e84007031ec884d829f973556d49c9b9467 (diff)
downloadbinaryen-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.cpp12
-rw-r--r--src/binaryen-c.h12
-rw-r--r--src/gen-s-parser.inc99
-rw-r--r--src/ir/cost.h36
-rw-r--r--src/js/binaryen.js-post.js48
-rw-r--r--src/literal.h16
-rw-r--r--src/passes/Print.cpp36
-rw-r--r--src/tools/fuzzing.h12
-rw-r--r--src/wasm-binary.h12
-rw-r--r--src/wasm-interpreter.h24
-rw-r--r--src/wasm.h12
-rw-r--r--src/wasm/literal.cpp49
-rw-r--r--src/wasm/wasm-binary.cpp48
-rw-r--r--src/wasm/wasm-stack.cpp36
-rw-r--r--src/wasm/wasm-validator.cpp12
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: