summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/binaryen-c.h4
-rw-r--r--src/gen-s-parser.inc125
-rw-r--r--src/ir/cost.h39
-rw-r--r--src/literal.h13
-rw-r--r--src/passes/Print.cpp41
-rw-r--r--src/tools/fuzzing.h3
-rw-r--r--src/wasm-binary.h14
-rw-r--r--src/wasm-interpreter.h26
-rw-r--r--src/wasm.h13
-rw-r--r--src/wasm/literal.cpp40
-rw-r--r--src/wasm/wasm-binary.cpp52
-rw-r--r--src/wasm/wasm-stack.cpp52
-rw-r--r--src/wasm/wasm-validator.cpp13
13 files changed, 421 insertions, 14 deletions
diff --git a/src/binaryen-c.h b/src/binaryen-c.h
index 83477e8d1..c84361d0e 100644
--- a/src/binaryen-c.h
+++ b/src/binaryen-c.h
@@ -485,7 +485,7 @@ BINARYEN_API BinaryenOp BinaryenOrVec128(void);
BINARYEN_API BinaryenOp BinaryenXorVec128(void);
BINARYEN_API BinaryenOp BinaryenAndNotVec128(void);
BINARYEN_API BinaryenOp BinaryenBitselectVec128(void);
-// TODO: Add i8x16.popcnt to C and JS APIs once merged to proposal
+// TODO: Add i8x16.popcnt to C and JS APIs once merged to the proposal
BINARYEN_API BinaryenOp BinaryenAbsVecI8x16(void);
BINARYEN_API BinaryenOp BinaryenNegVecI8x16(void);
BINARYEN_API BinaryenOp BinaryenAnyTrueVecI8x16(void);
@@ -526,6 +526,8 @@ BINARYEN_API BinaryenOp BinaryenMinUVecI16x8(void);
BINARYEN_API BinaryenOp BinaryenMaxSVecI16x8(void);
BINARYEN_API BinaryenOp BinaryenMaxUVecI16x8(void);
BINARYEN_API BinaryenOp BinaryenAvgrUVecI16x8(void);
+// TODO: Add i16x8.q15mulr_sat_s to C and JS APIs once merged to the proposal
+// TODO: Add extending multiplications to APIs once they are merged as well
BINARYEN_API BinaryenOp BinaryenAbsVecI32x4(void);
BINARYEN_API BinaryenOp BinaryenNegVecI32x4(void);
BINARYEN_API BinaryenOp BinaryenAnyTrueVecI32x4(void);
diff --git a/src/gen-s-parser.inc b/src/gen-s-parser.inc
index 47ea6c969..87a19fb82 100644
--- a/src/gen-s-parser.inc
+++ b/src/gen-s-parser.inc
@@ -799,13 +799,45 @@ switch (op[0]) {
if (strcmp(op, "i16x8.eq") == 0) { return makeBinary(s, BinaryOp::EqVecI16x8); }
goto parse_error;
case 'x': {
- switch (op[19]) {
- case 's':
- if (strcmp(op, "i16x8.extract_lane_s") == 0) { return makeSIMDExtract(s, SIMDExtractOp::ExtractLaneSVecI16x8, 8); }
- goto parse_error;
- case 'u':
- if (strcmp(op, "i16x8.extract_lane_u") == 0) { return makeSIMDExtract(s, SIMDExtractOp::ExtractLaneUVecI16x8, 8); }
- goto parse_error;
+ switch (op[9]) {
+ case 'm': {
+ switch (op[13]) {
+ case 'h': {
+ switch (op[24]) {
+ case 's':
+ if (strcmp(op, "i16x8.extmul_high_i8x16_s") == 0) { return makeBinary(s, BinaryOp::ExtMulHighSVecI16x8); }
+ goto parse_error;
+ case 'u':
+ if (strcmp(op, "i16x8.extmul_high_i8x16_u") == 0) { return makeBinary(s, BinaryOp::ExtMulHighUVecI16x8); }
+ goto parse_error;
+ default: goto parse_error;
+ }
+ }
+ case 'l': {
+ switch (op[23]) {
+ case 's':
+ if (strcmp(op, "i16x8.extmul_low_i8x16_s") == 0) { return makeBinary(s, BinaryOp::ExtMulLowSVecI16x8); }
+ goto parse_error;
+ case 'u':
+ if (strcmp(op, "i16x8.extmul_low_i8x16_u") == 0) { return makeBinary(s, BinaryOp::ExtMulLowUVecI16x8); }
+ goto parse_error;
+ default: goto parse_error;
+ }
+ }
+ default: goto parse_error;
+ }
+ }
+ case 'r': {
+ switch (op[19]) {
+ case 's':
+ if (strcmp(op, "i16x8.extract_lane_s") == 0) { return makeSIMDExtract(s, SIMDExtractOp::ExtractLaneSVecI16x8, 8); }
+ goto parse_error;
+ case 'u':
+ if (strcmp(op, "i16x8.extract_lane_u") == 0) { return makeSIMDExtract(s, SIMDExtractOp::ExtractLaneUVecI16x8, 8); }
+ goto parse_error;
+ default: goto parse_error;
+ }
+ }
default: goto parse_error;
}
}
@@ -934,6 +966,9 @@ switch (op[0]) {
default: goto parse_error;
}
}
+ case 'q':
+ if (strcmp(op, "i16x8.q15mulr_sat_s") == 0) { return makeBinary(s, BinaryOp::Q15MulrSatSVecI16x8); }
+ goto parse_error;
case 'r':
if (strcmp(op, "i16x8.replace_lane") == 0) { return makeSIMDReplace(s, SIMDReplaceOp::ReplaceLaneVecI16x8, 8); }
goto parse_error;
@@ -1520,9 +1555,41 @@ switch (op[0]) {
case 'q':
if (strcmp(op, "i32x4.eq") == 0) { return makeBinary(s, BinaryOp::EqVecI32x4); }
goto parse_error;
- case 'x':
- if (strcmp(op, "i32x4.extract_lane") == 0) { return makeSIMDExtract(s, SIMDExtractOp::ExtractLaneVecI32x4, 4); }
- goto parse_error;
+ case 'x': {
+ switch (op[9]) {
+ case 'm': {
+ switch (op[13]) {
+ case 'h': {
+ switch (op[24]) {
+ case 's':
+ if (strcmp(op, "i32x4.extmul_high_i16x8_s") == 0) { return makeBinary(s, BinaryOp::ExtMulHighSVecI32x4); }
+ goto parse_error;
+ case 'u':
+ if (strcmp(op, "i32x4.extmul_high_i16x8_u") == 0) { return makeBinary(s, BinaryOp::ExtMulHighUVecI32x4); }
+ goto parse_error;
+ default: goto parse_error;
+ }
+ }
+ case 'l': {
+ switch (op[23]) {
+ case 's':
+ if (strcmp(op, "i32x4.extmul_low_i16x8_s") == 0) { return makeBinary(s, BinaryOp::ExtMulLowSVecI32x4); }
+ goto parse_error;
+ case 'u':
+ if (strcmp(op, "i32x4.extmul_low_i16x8_u") == 0) { return makeBinary(s, BinaryOp::ExtMulLowUVecI32x4); }
+ goto parse_error;
+ default: goto parse_error;
+ }
+ }
+ default: goto parse_error;
+ }
+ }
+ case 'r':
+ if (strcmp(op, "i32x4.extract_lane") == 0) { return makeSIMDExtract(s, SIMDExtractOp::ExtractLaneVecI32x4, 4); }
+ goto parse_error;
+ default: goto parse_error;
+ }
+ }
default: goto parse_error;
}
}
@@ -2251,9 +2318,41 @@ switch (op[0]) {
default: goto parse_error;
}
}
- case 'e':
- if (strcmp(op, "i64x2.extract_lane") == 0) { return makeSIMDExtract(s, SIMDExtractOp::ExtractLaneVecI64x2, 2); }
- goto parse_error;
+ case 'e': {
+ switch (op[9]) {
+ case 'm': {
+ switch (op[13]) {
+ case 'h': {
+ switch (op[24]) {
+ case 's':
+ if (strcmp(op, "i64x2.extmul_high_i32x4_s") == 0) { return makeBinary(s, BinaryOp::ExtMulHighSVecI64x2); }
+ goto parse_error;
+ case 'u':
+ if (strcmp(op, "i64x2.extmul_high_i32x4_u") == 0) { return makeBinary(s, BinaryOp::ExtMulHighUVecI64x2); }
+ goto parse_error;
+ default: goto parse_error;
+ }
+ }
+ case 'l': {
+ switch (op[23]) {
+ case 's':
+ if (strcmp(op, "i64x2.extmul_low_i32x4_s") == 0) { return makeBinary(s, BinaryOp::ExtMulLowSVecI64x2); }
+ goto parse_error;
+ case 'u':
+ if (strcmp(op, "i64x2.extmul_low_i32x4_u") == 0) { return makeBinary(s, BinaryOp::ExtMulLowUVecI64x2); }
+ goto parse_error;
+ default: goto parse_error;
+ }
+ }
+ default: goto parse_error;
+ }
+ }
+ case 'r':
+ if (strcmp(op, "i64x2.extract_lane") == 0) { return makeSIMDExtract(s, SIMDExtractOp::ExtractLaneVecI64x2, 2); }
+ goto parse_error;
+ default: goto parse_error;
+ }
+ }
case 'l': {
switch (op[15]) {
case 's':
diff --git a/src/ir/cost.h b/src/ir/cost.h
index 1095ff76e..96ef02286 100644
--- a/src/ir/cost.h
+++ b/src/ir/cost.h
@@ -648,6 +648,21 @@ struct CostAnalyzer : public Visitor<CostAnalyzer, Index> {
case AvgrUVecI16x8:
ret = 1;
break;
+ case Q15MulrSatSVecI16x8:
+ ret = 1;
+ break;
+ case ExtMulLowSVecI16x8:
+ ret = 1;
+ break;
+ case ExtMulHighSVecI16x8:
+ ret = 1;
+ break;
+ case ExtMulLowUVecI16x8:
+ ret = 1;
+ break;
+ case ExtMulHighUVecI16x8:
+ ret = 1;
+ break;
case AddVecI32x4:
ret = 1;
break;
@@ -672,6 +687,18 @@ struct CostAnalyzer : public Visitor<CostAnalyzer, Index> {
case DotSVecI16x8ToVecI32x4:
ret = 1;
break;
+ case ExtMulLowSVecI32x4:
+ ret = 1;
+ break;
+ case ExtMulHighSVecI32x4:
+ ret = 1;
+ break;
+ case ExtMulLowUVecI32x4:
+ ret = 1;
+ break;
+ case ExtMulHighUVecI32x4:
+ ret = 1;
+ break;
case AddVecI64x2:
ret = 1;
break;
@@ -681,6 +708,18 @@ struct CostAnalyzer : public Visitor<CostAnalyzer, Index> {
case MulVecI64x2:
ret = 1;
break;
+ case ExtMulLowSVecI64x2:
+ ret = 1;
+ break;
+ case ExtMulHighSVecI64x2:
+ ret = 1;
+ break;
+ case ExtMulLowUVecI64x2:
+ ret = 1;
+ break;
+ case ExtMulHighUVecI64x2:
+ ret = 1;
+ break;
case AddVecF32x4:
ret = 1;
break;
diff --git a/src/literal.h b/src/literal.h
index 8ead70fc7..d94d1a6d0 100644
--- a/src/literal.h
+++ b/src/literal.h
@@ -509,6 +509,11 @@ public:
Literal maxSI16x8(const Literal& other) const;
Literal maxUI16x8(const Literal& other) const;
Literal avgrUI16x8(const Literal& other) const;
+ Literal q15MulrSatSI16x8(const Literal& other) const;
+ Literal extMulLowSI16x8(const Literal& other) const;
+ Literal extMulHighSI16x8(const Literal& other) const;
+ Literal extMulLowUI16x8(const Literal& other) const;
+ Literal extMulHighUI16x8(const Literal& other) const;
Literal absI32x4() const;
Literal negI32x4() const;
Literal anyTrueI32x4() const;
@@ -525,6 +530,10 @@ public:
Literal maxSI32x4(const Literal& other) const;
Literal maxUI32x4(const Literal& other) const;
Literal dotSI16x8toI32x4(const Literal& other) const;
+ Literal extMulLowSI32x4(const Literal& other) const;
+ Literal extMulHighSI32x4(const Literal& other) const;
+ Literal extMulLowUI32x4(const Literal& other) const;
+ Literal extMulHighUI32x4(const Literal& other) const;
Literal negI64x2() const;
Literal anyTrueI64x2() const;
Literal allTrueI64x2() const;
@@ -534,6 +543,10 @@ public:
Literal addI64x2(const Literal& other) const;
Literal subI64x2(const Literal& other) const;
Literal mulI64x2(const Literal& other) const;
+ Literal extMulLowSI64x2(const Literal& other) const;
+ Literal extMulHighSI64x2(const Literal& other) const;
+ Literal extMulLowUI64x2(const Literal& other) const;
+ Literal extMulHighUI64x2(const Literal& other) const;
Literal absF32x4() const;
Literal negF32x4() const;
Literal sqrtF32x4() const;
diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp
index c093158f3..e653e85bd 100644
--- a/src/passes/Print.cpp
+++ b/src/passes/Print.cpp
@@ -1357,6 +1357,22 @@ struct PrintExpressionContents
case AvgrUVecI16x8:
o << "i16x8.avgr_u";
break;
+ case Q15MulrSatSVecI16x8:
+ o << "i16x8.q15mulr_sat_s";
+ break;
+ case ExtMulLowSVecI16x8:
+ o << "i16x8.extmul_low_i8x16_s";
+ break;
+ case ExtMulHighSVecI16x8:
+ o << "i16x8.extmul_high_i8x16_s";
+ break;
+ case ExtMulLowUVecI16x8:
+ o << "i16x8.extmul_low_i8x16_u";
+ break;
+ case ExtMulHighUVecI16x8:
+ o << "i16x8.extmul_high_i8x16_u";
+ break;
+
case AddVecI32x4:
o << "i32x4.add";
break;
@@ -1381,6 +1397,19 @@ struct PrintExpressionContents
case DotSVecI16x8ToVecI32x4:
o << "i32x4.dot_i16x8_s";
break;
+ case ExtMulLowSVecI32x4:
+ o << "i32x4.extmul_low_i16x8_s";
+ break;
+ case ExtMulHighSVecI32x4:
+ o << "i32x4.extmul_high_i16x8_s";
+ break;
+ case ExtMulLowUVecI32x4:
+ o << "i32x4.extmul_low_i16x8_u";
+ break;
+ case ExtMulHighUVecI32x4:
+ o << "i32x4.extmul_high_i16x8_u";
+ break;
+
case AddVecI64x2:
o << "i64x2.add";
break;
@@ -1390,6 +1419,18 @@ struct PrintExpressionContents
case MulVecI64x2:
o << "i64x2.mul";
break;
+ case ExtMulLowSVecI64x2:
+ o << "i64x2.extmul_low_i32x4_s";
+ break;
+ case ExtMulHighSVecI64x2:
+ o << "i64x2.extmul_high_i32x4_s";
+ break;
+ case ExtMulLowUVecI64x2:
+ o << "i64x2.extmul_low_i32x4_u";
+ break;
+ case ExtMulHighUVecI64x2:
+ o << "i64x2.extmul_high_i32x4_u";
+ break;
case AddVecF32x4:
o << "f32x4.add";
diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h
index f4c29be55..9b3649d79 100644
--- a/src/tools/fuzzing.h
+++ b/src/tools/fuzzing.h
@@ -2448,6 +2448,9 @@ private:
MinUVecI8x16,
MaxSVecI8x16,
MaxUVecI8x16,
+ // TODO: avgr_u
+ // TODO: q15mulr_sat_s
+ // TODO: extmul
AddVecI16x8,
AddSatSVecI16x8,
AddSatUVecI16x8,
diff --git a/src/wasm-binary.h b/src/wasm-binary.h
index e1247a2d4..8d7abfd70 100644
--- a/src/wasm-binary.h
+++ b/src/wasm-binary.h
@@ -851,6 +851,7 @@ enum ASTNodes {
I16x8MaxS = 0x98,
I16x8MaxU = 0x99,
I16x8AvgrU = 0x9b,
+ I16x8Q15MulrSatS = 0x9c,
I32x4Abs = 0xa0,
I32x4Neg = 0xa1,
@@ -934,6 +935,19 @@ enum ASTNodes {
F64x2ConvertSI64x2 = 0x0102,
F64x2ConvertUI64x2 = 0x0103,
+ I16x8ExtMulLowSI8x16 = 0x9a,
+ I16x8ExtMulHighSI8x16 = 0x9d,
+ I16x8ExtMulLowUI8x16 = 0x9e,
+ I16x8ExtMulHighUI8x16 = 0x9f,
+ I32x4ExtMulLowSI16x8 = 0xbb,
+ I32x4ExtMulHighSI16x8 = 0xbd,
+ I32x4ExtMulLowUI16x8 = 0xbe,
+ I32x4ExtMulHighUI16x8 = 0xbf,
+ I64x2ExtMulLowSI32x4 = 0xd2,
+ I64x2ExtMulHighSI32x4 = 0xd3,
+ I64x2ExtMulLowUI32x4 = 0xd6,
+ I64x2ExtMulHighUI32x4 = 0xd7,
+
// bulk memory opcodes
MemoryInit = 0x08,
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h
index 932f97dd3..6f0d10565 100644
--- a/src/wasm-interpreter.h
+++ b/src/wasm-interpreter.h
@@ -878,6 +878,16 @@ public:
return left.maxUI16x8(right);
case AvgrUVecI16x8:
return left.avgrUI16x8(right);
+ case Q15MulrSatSVecI16x8:
+ return left.q15MulrSatSI16x8(right);
+ case ExtMulLowSVecI16x8:
+ return left.extMulLowSI16x8(right);
+ case ExtMulHighSVecI16x8:
+ return left.extMulHighSI16x8(right);
+ case ExtMulLowUVecI16x8:
+ return left.extMulLowUI16x8(right);
+ case ExtMulHighUVecI16x8:
+ return left.extMulHighUI16x8(right);
case AddVecI32x4:
return left.addI32x4(right);
case SubVecI32x4:
@@ -894,12 +904,28 @@ public:
return left.maxUI32x4(right);
case DotSVecI16x8ToVecI32x4:
return left.dotSI16x8toI32x4(right);
+ case ExtMulLowSVecI32x4:
+ return left.extMulLowSI32x4(right);
+ case ExtMulHighSVecI32x4:
+ return left.extMulHighSI32x4(right);
+ case ExtMulLowUVecI32x4:
+ return left.extMulLowUI32x4(right);
+ case ExtMulHighUVecI32x4:
+ return left.extMulHighUI32x4(right);
case AddVecI64x2:
return left.addI64x2(right);
case SubVecI64x2:
return left.subI64x2(right);
case MulVecI64x2:
return left.mulI64x2(right);
+ case ExtMulLowSVecI64x2:
+ return left.extMulLowSI64x2(right);
+ case ExtMulHighSVecI64x2:
+ return left.extMulHighSI64x2(right);
+ case ExtMulLowUVecI64x2:
+ return left.extMulLowUI64x2(right);
+ case ExtMulHighUVecI64x2:
+ return left.extMulHighUI64x2(right);
case AddVecF32x4:
return left.addF32x4(right);
diff --git a/src/wasm.h b/src/wasm.h
index 295088780..feaa51e40 100644
--- a/src/wasm.h
+++ b/src/wasm.h
@@ -393,6 +393,11 @@ enum BinaryOp {
MaxSVecI16x8,
MaxUVecI16x8,
AvgrUVecI16x8,
+ Q15MulrSatSVecI16x8,
+ ExtMulLowSVecI16x8,
+ ExtMulHighSVecI16x8,
+ ExtMulLowUVecI16x8,
+ ExtMulHighUVecI16x8,
AddVecI32x4,
SubVecI32x4,
MulVecI32x4,
@@ -401,9 +406,17 @@ enum BinaryOp {
MaxSVecI32x4,
MaxUVecI32x4,
DotSVecI16x8ToVecI32x4,
+ ExtMulLowSVecI32x4,
+ ExtMulHighSVecI32x4,
+ ExtMulLowUVecI32x4,
+ ExtMulHighUVecI32x4,
AddVecI64x2,
SubVecI64x2,
MulVecI64x2,
+ ExtMulLowSVecI64x2,
+ ExtMulHighSVecI64x2,
+ ExtMulLowUVecI64x2,
+ ExtMulHighUVecI64x2,
AddVecF32x4,
SubVecF32x4,
MulVecF32x4,
diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp
index f549a9ca6..6d0a0fee7 100644
--- a/src/wasm/literal.cpp
+++ b/src/wasm/literal.cpp
@@ -2100,6 +2100,9 @@ Literal Literal::maxUI16x8(const Literal& other) const {
Literal Literal::avgrUI16x8(const Literal& other) const {
return binary<8, &Literal::getLanesUI16x8, &Literal::avgrUInt>(*this, other);
}
+Literal Literal::q15MulrSatSI16x8(const Literal& other) const {
+ WASM_UNREACHABLE("TODO: implement Q15 rounding, saturating multiplication");
+}
Literal Literal::addI32x4(const Literal& other) const {
return binary<4, &Literal::getLanesI32x4, &Literal::add>(*this, other);
}
@@ -2277,6 +2280,43 @@ Literal Literal::widenHighUToVecI32x4() const {
return widen<4, &Literal::getLanesUI16x8, LaneOrder::High>(*this);
}
+Literal Literal::extMulLowSI16x8(const Literal& other) const {
+ WASM_UNREACHABLE("TODO: implement SIMD extending multiplications");
+}
+Literal Literal::extMulHighSI16x8(const Literal& other) const {
+ WASM_UNREACHABLE("TODO: implement SIMD extending multiplications");
+}
+Literal Literal::extMulLowUI16x8(const Literal& other) const {
+ WASM_UNREACHABLE("TODO: implement SIMD extending multiplications");
+}
+Literal Literal::extMulHighUI16x8(const Literal& other) const {
+ WASM_UNREACHABLE("TODO: implement SIMD extending multiplications");
+}
+Literal Literal::extMulLowSI32x4(const Literal& other) const {
+ WASM_UNREACHABLE("TODO: implement SIMD extending multiplications");
+}
+Literal Literal::extMulHighSI32x4(const Literal& other) const {
+ WASM_UNREACHABLE("TODO: implement SIMD extending multiplications");
+}
+Literal Literal::extMulLowUI32x4(const Literal& other) const {
+ WASM_UNREACHABLE("TODO: implement SIMD extending multiplications");
+}
+Literal Literal::extMulHighUI32x4(const Literal& other) const {
+ WASM_UNREACHABLE("TODO: implement SIMD extending multiplications");
+}
+Literal Literal::extMulLowSI64x2(const Literal& other) const {
+ WASM_UNREACHABLE("TODO: implement SIMD extending multiplications");
+}
+Literal Literal::extMulHighSI64x2(const Literal& other) const {
+ WASM_UNREACHABLE("TODO: implement SIMD extending multiplications");
+}
+Literal Literal::extMulLowUI64x2(const Literal& other) const {
+ WASM_UNREACHABLE("TODO: implement SIMD extending multiplications");
+}
+Literal Literal::extMulHighUI64x2(const Literal& other) const {
+ WASM_UNREACHABLE("TODO: implement SIMD extending multiplications");
+}
+
Literal Literal::swizzleVec8x16(const Literal& other) const {
auto lanes = getLanesUI8x16();
auto indices = other.getLanesUI8x16();
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index 0c56af8e0..46ce205b7 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -4303,6 +4303,26 @@ bool WasmBinaryBuilder::maybeVisitSIMDBinary(Expression*& out, uint32_t code) {
curr = allocator.alloc<Binary>();
curr->op = AvgrUVecI16x8;
break;
+ case BinaryConsts::I16x8Q15MulrSatS:
+ curr = allocator.alloc<Binary>();
+ curr->op = Q15MulrSatSVecI16x8;
+ break;
+ case BinaryConsts::I16x8ExtMulLowSI8x16:
+ curr = allocator.alloc<Binary>();
+ curr->op = ExtMulLowSVecI16x8;
+ break;
+ case BinaryConsts::I16x8ExtMulHighSI8x16:
+ curr = allocator.alloc<Binary>();
+ curr->op = ExtMulHighSVecI16x8;
+ break;
+ case BinaryConsts::I16x8ExtMulLowUI8x16:
+ curr = allocator.alloc<Binary>();
+ curr->op = ExtMulLowUVecI16x8;
+ break;
+ case BinaryConsts::I16x8ExtMulHighUI8x16:
+ curr = allocator.alloc<Binary>();
+ curr->op = ExtMulHighUVecI16x8;
+ break;
case BinaryConsts::I32x4Add:
curr = allocator.alloc<Binary>();
curr->op = AddVecI32x4;
@@ -4335,6 +4355,22 @@ bool WasmBinaryBuilder::maybeVisitSIMDBinary(Expression*& out, uint32_t code) {
curr = allocator.alloc<Binary>();
curr->op = DotSVecI16x8ToVecI32x4;
break;
+ case BinaryConsts::I32x4ExtMulLowSI16x8:
+ curr = allocator.alloc<Binary>();
+ curr->op = ExtMulLowSVecI32x4;
+ break;
+ case BinaryConsts::I32x4ExtMulHighSI16x8:
+ curr = allocator.alloc<Binary>();
+ curr->op = ExtMulHighSVecI32x4;
+ break;
+ case BinaryConsts::I32x4ExtMulLowUI16x8:
+ curr = allocator.alloc<Binary>();
+ curr->op = ExtMulLowUVecI32x4;
+ break;
+ case BinaryConsts::I32x4ExtMulHighUI16x8:
+ curr = allocator.alloc<Binary>();
+ curr->op = ExtMulHighUVecI32x4;
+ break;
case BinaryConsts::I64x2Add:
curr = allocator.alloc<Binary>();
curr->op = AddVecI64x2;
@@ -4347,6 +4383,22 @@ bool WasmBinaryBuilder::maybeVisitSIMDBinary(Expression*& out, uint32_t code) {
curr = allocator.alloc<Binary>();
curr->op = MulVecI64x2;
break;
+ case BinaryConsts::I64x2ExtMulLowSI32x4:
+ curr = allocator.alloc<Binary>();
+ curr->op = ExtMulLowSVecI64x2;
+ break;
+ case BinaryConsts::I64x2ExtMulHighSI32x4:
+ curr = allocator.alloc<Binary>();
+ curr->op = ExtMulHighSVecI64x2;
+ break;
+ case BinaryConsts::I64x2ExtMulLowUI32x4:
+ curr = allocator.alloc<Binary>();
+ curr->op = ExtMulLowUVecI64x2;
+ break;
+ case BinaryConsts::I64x2ExtMulHighUI32x4:
+ curr = allocator.alloc<Binary>();
+ curr->op = ExtMulHighUVecI64x2;
+ break;
case BinaryConsts::F32x4Add:
curr = allocator.alloc<Binary>();
curr->op = AddVecF32x4;
diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp
index 1d290f53c..7139eb502 100644
--- a/src/wasm/wasm-stack.cpp
+++ b/src/wasm/wasm-stack.cpp
@@ -1587,6 +1587,26 @@ void BinaryInstWriter::visitBinary(Binary* curr) {
case AvgrUVecI16x8:
o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I16x8AvgrU);
break;
+ case Q15MulrSatSVecI16x8:
+ o << int8_t(BinaryConsts::SIMDPrefix)
+ << U32LEB(BinaryConsts::I16x8Q15MulrSatS);
+ break;
+ case ExtMulLowSVecI16x8:
+ o << int8_t(BinaryConsts::SIMDPrefix)
+ << U32LEB(BinaryConsts::I16x8ExtMulLowSI8x16);
+ break;
+ case ExtMulHighSVecI16x8:
+ o << int8_t(BinaryConsts::SIMDPrefix)
+ << U32LEB(BinaryConsts::I16x8ExtMulHighSI8x16);
+ break;
+ case ExtMulLowUVecI16x8:
+ o << int8_t(BinaryConsts::SIMDPrefix)
+ << U32LEB(BinaryConsts::I16x8ExtMulLowUI8x16);
+ break;
+ case ExtMulHighUVecI16x8:
+ o << int8_t(BinaryConsts::SIMDPrefix)
+ << U32LEB(BinaryConsts::I16x8ExtMulHighUI8x16);
+ break;
case AddVecI32x4:
o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I32x4Add);
break;
@@ -1612,6 +1632,22 @@ void BinaryInstWriter::visitBinary(Binary* curr) {
o << int8_t(BinaryConsts::SIMDPrefix)
<< U32LEB(BinaryConsts::I32x4DotSVecI16x8);
break;
+ case ExtMulLowSVecI32x4:
+ o << int8_t(BinaryConsts::SIMDPrefix)
+ << U32LEB(BinaryConsts::I32x4ExtMulLowSI16x8);
+ break;
+ case ExtMulHighSVecI32x4:
+ o << int8_t(BinaryConsts::SIMDPrefix)
+ << U32LEB(BinaryConsts::I32x4ExtMulHighSI16x8);
+ break;
+ case ExtMulLowUVecI32x4:
+ o << int8_t(BinaryConsts::SIMDPrefix)
+ << U32LEB(BinaryConsts::I32x4ExtMulLowUI16x8);
+ break;
+ case ExtMulHighUVecI32x4:
+ o << int8_t(BinaryConsts::SIMDPrefix)
+ << U32LEB(BinaryConsts::I32x4ExtMulHighUI16x8);
+ break;
case AddVecI64x2:
o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I64x2Add);
break;
@@ -1621,6 +1657,22 @@ void BinaryInstWriter::visitBinary(Binary* curr) {
case MulVecI64x2:
o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I64x2Mul);
break;
+ case ExtMulLowSVecI64x2:
+ o << int8_t(BinaryConsts::SIMDPrefix)
+ << U32LEB(BinaryConsts::I64x2ExtMulLowSI32x4);
+ break;
+ case ExtMulHighSVecI64x2:
+ o << int8_t(BinaryConsts::SIMDPrefix)
+ << U32LEB(BinaryConsts::I64x2ExtMulHighSI32x4);
+ break;
+ case ExtMulLowUVecI64x2:
+ o << int8_t(BinaryConsts::SIMDPrefix)
+ << U32LEB(BinaryConsts::I64x2ExtMulLowUI32x4);
+ break;
+ case ExtMulHighUVecI64x2:
+ o << int8_t(BinaryConsts::SIMDPrefix)
+ << U32LEB(BinaryConsts::I64x2ExtMulHighUI32x4);
+ break;
case AddVecF32x4:
o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::F32x4Add);
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp
index e09a8fb36..38dfa8092 100644
--- a/src/wasm/wasm-validator.cpp
+++ b/src/wasm/wasm-validator.cpp
@@ -1608,6 +1608,11 @@ void FunctionValidator::visitBinary(Binary* curr) {
case MaxSVecI8x16:
case MaxUVecI8x16:
case AvgrUVecI8x16:
+ case Q15MulrSatSVecI16x8:
+ case ExtMulLowSVecI16x8:
+ case ExtMulHighSVecI16x8:
+ case ExtMulLowUVecI16x8:
+ case ExtMulHighUVecI16x8:
case AddVecI16x8:
case AddSatSVecI16x8:
case AddSatUVecI16x8:
@@ -1628,9 +1633,17 @@ void FunctionValidator::visitBinary(Binary* curr) {
case MaxSVecI32x4:
case MaxUVecI32x4:
case DotSVecI16x8ToVecI32x4:
+ case ExtMulLowSVecI32x4:
+ case ExtMulHighSVecI32x4:
+ case ExtMulLowUVecI32x4:
+ case ExtMulHighUVecI32x4:
case AddVecI64x2:
case SubVecI64x2:
case MulVecI64x2:
+ case ExtMulLowSVecI64x2:
+ case ExtMulHighSVecI64x2:
+ case ExtMulLowUVecI64x2:
+ case ExtMulHighUVecI64x2:
case AddVecF32x4:
case SubVecF32x4:
case MulVecF32x4: