summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gen-s-parser.inc131
-rw-r--r--src/ir/cost.h10
-rw-r--r--src/literal.h1
-rw-r--r--src/passes/Print.cpp30
-rw-r--r--src/wasm-binary.h11
-rw-r--r--src/wasm-interpreter.h11
-rw-r--r--src/wasm.h18
-rw-r--r--src/wasm/literal.cpp4
-rw-r--r--src/wasm/wasm-binary.cpp40
-rw-r--r--src/wasm/wasm-stack.cpp35
-rw-r--r--src/wasm/wasm-validator.cpp6
-rw-r--r--src/wasm/wasm.cpp5
12 files changed, 267 insertions, 35 deletions
diff --git a/src/gen-s-parser.inc b/src/gen-s-parser.inc
index 8afcea917..d4e1afe38 100644
--- a/src/gen-s-parser.inc
+++ b/src/gen-s-parser.inc
@@ -2312,38 +2312,49 @@ switch (op[0]) {
default: goto parse_error;
}
}
+ case 'b':
+ if (strcmp(op, "i64x2.bitmask") == 0) { return makeUnary(s, UnaryOp::BitmaskVecI64x2); }
+ 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;
+ switch (op[7]) {
+ case 'q':
+ if (strcmp(op, "i64x2.eq") == 0) { return makeBinary(s, BinaryOp::EqVecI64x2); }
+ goto parse_error;
+ case 'x': {
+ 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 'r':
- if (strcmp(op, "i64x2.extract_lane") == 0) { return makeSIMDExtract(s, SIMDExtractOp::ExtractLaneVecI64x2, 2); }
- goto parse_error;
default: goto parse_error;
}
}
@@ -2408,6 +2419,33 @@ switch (op[0]) {
default: goto parse_error;
}
}
+ case 'w': {
+ switch (op[12]) {
+ case 'h': {
+ switch (op[23]) {
+ case 's':
+ if (strcmp(op, "i64x2.widen_high_i32x4_s") == 0) { return makeUnary(s, UnaryOp::WidenHighSVecI32x4ToVecI64x2); }
+ goto parse_error;
+ case 'u':
+ if (strcmp(op, "i64x2.widen_high_i32x4_u") == 0) { return makeUnary(s, UnaryOp::WidenHighUVecI32x4ToVecI64x2); }
+ goto parse_error;
+ default: goto parse_error;
+ }
+ }
+ case 'l': {
+ switch (op[22]) {
+ case 's':
+ if (strcmp(op, "i64x2.widen_low_i32x4_s") == 0) { return makeUnary(s, UnaryOp::WidenLowSVecI32x4ToVecI64x2); }
+ goto parse_error;
+ case 'u':
+ if (strcmp(op, "i64x2.widen_low_i32x4_u") == 0) { return makeUnary(s, UnaryOp::WidenLowUVecI32x4ToVecI64x2); }
+ goto parse_error;
+ default: goto parse_error;
+ }
+ }
+ default: goto parse_error;
+ }
+ }
default: goto parse_error;
}
}
@@ -2962,18 +3000,42 @@ switch (op[0]) {
default: goto parse_error;
}
}
- case '6':
- if (strcmp(op, "v16x8.load_splat") == 0) { return makeSIMDLoad(s, SIMDLoadOp::LoadSplatVec16x8); }
+ case '6': {
+ switch (op[6]) {
+ case 'l':
+ if (strcmp(op, "v16x8.load_splat") == 0) { return makeSIMDLoad(s, SIMDLoadOp::LoadSplatVec16x8); }
+ goto parse_error;
+ case 's':
+ if (strcmp(op, "v16x8.signselect") == 0) { return makeSIMDTernary(s, SIMDTernaryOp::SignSelectVec16x8); }
+ goto parse_error;
+ default: goto parse_error;
+ }
+ }
+ default: goto parse_error;
+ }
+ }
+ case '3': {
+ switch (op[6]) {
+ case 'l':
+ if (strcmp(op, "v32x4.load_splat") == 0) { return makeSIMDLoad(s, SIMDLoadOp::LoadSplatVec32x4); }
+ goto parse_error;
+ case 's':
+ if (strcmp(op, "v32x4.signselect") == 0) { return makeSIMDTernary(s, SIMDTernaryOp::SignSelectVec32x4); }
+ goto parse_error;
+ default: goto parse_error;
+ }
+ }
+ case '6': {
+ switch (op[6]) {
+ case 'l':
+ if (strcmp(op, "v64x2.load_splat") == 0) { return makeSIMDLoad(s, SIMDLoadOp::LoadSplatVec64x2); }
+ goto parse_error;
+ case 's':
+ if (strcmp(op, "v64x2.signselect") == 0) { return makeSIMDTernary(s, SIMDTernaryOp::SignSelectVec64x2); }
goto parse_error;
default: goto parse_error;
}
}
- case '3':
- if (strcmp(op, "v32x4.load_splat") == 0) { return makeSIMDLoad(s, SIMDLoadOp::LoadSplatVec32x4); }
- goto parse_error;
- case '6':
- if (strcmp(op, "v64x2.load_splat") == 0) { return makeSIMDLoad(s, SIMDLoadOp::LoadSplatVec64x2); }
- goto parse_error;
case '8': {
switch (op[6]) {
case 'l':
@@ -2984,6 +3046,9 @@ switch (op[0]) {
case 'h':
if (strcmp(op, "v8x16.shuffle") == 0) { return makeSIMDShuffle(s); }
goto parse_error;
+ case 'i':
+ if (strcmp(op, "v8x16.signselect") == 0) { return makeSIMDTernary(s, SIMDTernaryOp::SignSelectVec8x16); }
+ goto parse_error;
case 'w':
if (strcmp(op, "v8x16.swizzle") == 0) { return makeBinary(s, BinaryOp::SwizzleVec8x16); }
goto parse_error;
diff --git a/src/ir/cost.h b/src/ir/cost.h
index 66a316bf6..c5b77ea01 100644
--- a/src/ir/cost.h
+++ b/src/ir/cost.h
@@ -191,6 +191,7 @@ struct CostAnalyzer : public OverriddenVisitor<CostAnalyzer, Index> {
case NegVecI64x2:
case AnyTrueVecI64x2:
case AllTrueVecI64x2:
+ case BitmaskVecI64x2:
case AbsVecF32x4:
case NegVecF32x4:
case SqrtVecF32x4:
@@ -221,6 +222,10 @@ struct CostAnalyzer : public OverriddenVisitor<CostAnalyzer, Index> {
case WidenHighSVecI16x8ToVecI32x4:
case WidenLowUVecI16x8ToVecI32x4:
case WidenHighUVecI16x8ToVecI32x4:
+ case WidenLowSVecI32x4ToVecI64x2:
+ case WidenHighSVecI32x4ToVecI64x2:
+ case WidenLowUVecI32x4ToVecI64x2:
+ case WidenHighUVecI32x4ToVecI64x2:
ret = 1;
break;
case InvalidUnary:
@@ -363,6 +368,7 @@ struct CostAnalyzer : public OverriddenVisitor<CostAnalyzer, Index> {
case GtUVecI32x4:
case GeSVecI32x4:
case GeUVecI32x4:
+ case EqVecI64x2:
case EqVecF32x4:
case NeVecF32x4:
case LtVecF32x4:
@@ -508,6 +514,10 @@ struct CostAnalyzer : public OverriddenVisitor<CostAnalyzer, Index> {
Index ret = 0;
switch (curr->op) {
case Bitselect:
+ case SignSelectVec8x16:
+ case SignSelectVec16x8:
+ case SignSelectVec32x4:
+ case SignSelectVec64x2:
ret = 1;
break;
case QFMAF32x4:
diff --git a/src/literal.h b/src/literal.h
index 80a7cea7a..8a1829d10 100644
--- a/src/literal.h
+++ b/src/literal.h
@@ -480,6 +480,7 @@ public:
Literal leUI32x4(const Literal& other) const;
Literal geSI32x4(const Literal& other) const;
Literal geUI32x4(const Literal& other) const;
+ Literal eqI64x2(const Literal& other) const;
Literal eqF32x4(const Literal& other) const;
Literal neF32x4(const Literal& other) const;
Literal ltF32x4(const Literal& other) const;
diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp
index 4007b6daa..b61a72720 100644
--- a/src/passes/Print.cpp
+++ b/src/passes/Print.cpp
@@ -533,6 +533,18 @@ struct PrintExpressionContents
case QFMSF64x2:
o << "f64x2.qfms";
break;
+ case SignSelectVec8x16:
+ o << "v8x16.signselect";
+ break;
+ case SignSelectVec16x8:
+ o << "v16x8.signselect";
+ break;
+ case SignSelectVec32x4:
+ o << "v32x4.signselect";
+ break;
+ case SignSelectVec64x2:
+ o << "v64x2.signselect";
+ break;
}
}
void visitSIMDShift(SIMDShift* curr) {
@@ -941,6 +953,9 @@ struct PrintExpressionContents
case AllTrueVecI64x2:
o << "i64x2.all_true";
break;
+ case BitmaskVecI64x2:
+ o << "i64x2.bitmask";
+ break;
case AbsVecF32x4:
o << "f32x4.abs";
break;
@@ -1031,6 +1046,18 @@ struct PrintExpressionContents
case WidenHighUVecI16x8ToVecI32x4:
o << "i32x4.widen_high_i16x8_u";
break;
+ case WidenLowSVecI32x4ToVecI64x2:
+ o << "i64x2.widen_low_i32x4_s";
+ break;
+ case WidenHighSVecI32x4ToVecI64x2:
+ o << "i64x2.widen_high_i32x4_s";
+ break;
+ case WidenLowUVecI32x4ToVecI64x2:
+ o << "i64x2.widen_low_i32x4_u";
+ break;
+ case WidenHighUVecI32x4ToVecI64x2:
+ o << "i64x2.widen_high_i32x4_u";
+ break;
case InvalidUnary:
WASM_UNREACHABLE("unvalid unary operator");
}
@@ -1360,6 +1387,9 @@ struct PrintExpressionContents
case GeUVecI32x4:
o << "i32x4.ge_u";
break;
+ case EqVecI64x2:
+ o << "i64x2.eq";
+ break;
case EqVecF32x4:
o << "f32x4.eq";
break;
diff --git a/src/wasm-binary.h b/src/wasm-binary.h
index dffc1507c..1d250aa2b 100644
--- a/src/wasm-binary.h
+++ b/src/wasm-binary.h
@@ -782,6 +782,7 @@ enum ASTNodes {
I32x4LeU = 0x3e,
I32x4GeS = 0x3f,
I32x4GeU = 0x40,
+ I64x2Eq = 0xc0,
F32x4Eq = 0x41,
F32x4Ne = 0x42,
F32x4Lt = 0x43,
@@ -802,6 +803,11 @@ enum ASTNodes {
V128Xor = 0x51,
V128Bitselect = 0x52,
+ V8x16SignSelect = 0x7d,
+ V16x8SignSelect = 0x7e,
+ V32x4SignSelect = 0x7f,
+ V64x2SignSelect = 0x94,
+
V128Load8Lane = 0x58,
V128Load16Lane = 0x59,
V128Load32Lane = 0x5a,
@@ -885,6 +891,11 @@ enum ASTNodes {
I32x4MaxU = 0xb9,
I32x4DotSVecI16x8 = 0xba,
+ I64x2Bitmask = 0xc4,
+ I64x2WidenLowSI32x4 = 0xc7,
+ I64x2WidenHighSI32x4 = 0xc8,
+ I64x2WidenLowUI32x4 = 0xc9,
+ I64x2WidenHighUI32x4 = 0xca,
I64x2Neg = 0xc1,
I64x2AnyTrue = 0xc2,
I64x2AllTrue = 0xc3,
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h
index e4c20082e..dbc14de5f 100644
--- a/src/wasm-interpreter.h
+++ b/src/wasm-interpreter.h
@@ -491,6 +491,8 @@ public:
return value.anyTrueI64x2();
case AllTrueVecI64x2:
return value.allTrueI64x2();
+ case BitmaskVecI64x2:
+ WASM_UNREACHABLE("unimp");
case AbsVecF32x4:
return value.absF32x4();
case NegVecF32x4:
@@ -551,6 +553,11 @@ public:
return value.widenLowUToVecI32x4();
case WidenHighUVecI16x8ToVecI32x4:
return value.widenHighUToVecI32x4();
+ case WidenLowSVecI32x4ToVecI64x2:
+ case WidenHighSVecI32x4ToVecI64x2:
+ case WidenLowUVecI32x4ToVecI64x2:
+ case WidenHighUVecI32x4ToVecI64x2:
+ WASM_UNREACHABLE("unimp");
case InvalidUnary:
WASM_UNREACHABLE("invalid unary op");
}
@@ -796,6 +803,8 @@ public:
return left.geSI32x4(right);
case GeUVecI32x4:
return left.geUI32x4(right);
+ case EqVecI64x2:
+ return left.eqI64x2(right);
case EqVecF32x4:
return left.eqF32x4(right);
case NeVecF32x4:
@@ -1067,7 +1076,7 @@ public:
case Bitselect:
return c.bitselectV128(a, b);
default:
- // TODO: implement qfma/qfms
+ // TODO: implement qfma/qfms and signselect
WASM_UNREACHABLE("not implemented");
}
}
diff --git a/src/wasm.h b/src/wasm.h
index 0c6566407..bc39eae7b 100644
--- a/src/wasm.h
+++ b/src/wasm.h
@@ -175,6 +175,7 @@ enum UnaryOp {
NegVecI64x2,
AnyTrueVecI64x2,
AllTrueVecI64x2,
+ BitmaskVecI64x2,
AbsVecF32x4,
NegVecF32x4,
SqrtVecF32x4,
@@ -207,6 +208,10 @@ enum UnaryOp {
WidenHighSVecI16x8ToVecI32x4,
WidenLowUVecI16x8ToVecI32x4,
WidenHighUVecI16x8ToVecI32x4,
+ WidenLowSVecI32x4ToVecI64x2,
+ WidenHighSVecI32x4ToVecI64x2,
+ WidenLowUVecI32x4ToVecI64x2,
+ WidenHighUVecI32x4ToVecI64x2,
InvalidUnary
};
@@ -351,6 +356,7 @@ enum BinaryOp {
LeUVecI32x4,
GeSVecI32x4,
GeUVecI32x4,
+ EqVecI64x2,
EqVecF32x4,
NeVecF32x4,
LtVecF32x4,
@@ -509,7 +515,17 @@ enum SIMDLoadStoreLaneOp {
StoreLaneVec64x2,
};
-enum SIMDTernaryOp { Bitselect, QFMAF32x4, QFMSF32x4, QFMAF64x2, QFMSF64x2 };
+enum SIMDTernaryOp {
+ Bitselect,
+ QFMAF32x4,
+ QFMSF32x4,
+ QFMAF64x2,
+ QFMSF64x2,
+ SignSelectVec8x16,
+ SignSelectVec16x8,
+ SignSelectVec32x4,
+ SignSelectVec64x2
+};
//
// Expressions
diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp
index c19efa225..9bdf886b3 100644
--- a/src/wasm/literal.cpp
+++ b/src/wasm/literal.cpp
@@ -1986,6 +1986,10 @@ Literal Literal::geSI32x4(const Literal& other) const {
Literal Literal::geUI32x4(const Literal& other) const {
return compare<4, &Literal::getLanesI32x4, &Literal::geU>(*this, other);
}
+Literal Literal::eqI64x2(const Literal& other) const {
+ return compare<2, &Literal::getLanesI64x2, &Literal::eq, int64_t>(*this,
+ other);
+}
Literal Literal::eqF32x4(const Literal& other) const {
return compare<4, &Literal::getLanesF32x4, &Literal::eq>(*this, other);
}
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index 1b3d50a41..796ba4b4e 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -4371,6 +4371,10 @@ bool WasmBinaryBuilder::maybeVisitSIMDBinary(Expression*& out, uint32_t code) {
curr = allocator.alloc<Binary>();
curr->op = GeUVecI32x4;
break;
+ case BinaryConsts::I64x2Eq:
+ curr = allocator.alloc<Binary>();
+ curr->op = EqVecI64x2;
+ break;
case BinaryConsts::F32x4Eq:
curr = allocator.alloc<Binary>();
curr->op = EqVecF32x4;
@@ -4828,6 +4832,10 @@ bool WasmBinaryBuilder::maybeVisitSIMDUnary(Expression*& out, uint32_t code) {
curr = allocator.alloc<Unary>();
curr->op = AllTrueVecI64x2;
break;
+ case BinaryConsts::I64x2Bitmask:
+ curr = allocator.alloc<Unary>();
+ curr->op = BitmaskVecI64x2;
+ break;
case BinaryConsts::F32x4Abs:
curr = allocator.alloc<Unary>();
curr->op = AbsVecF32x4;
@@ -4948,6 +4956,22 @@ bool WasmBinaryBuilder::maybeVisitSIMDUnary(Expression*& out, uint32_t code) {
curr = allocator.alloc<Unary>();
curr->op = WidenHighUVecI16x8ToVecI32x4;
break;
+ case BinaryConsts::I64x2WidenLowSI32x4:
+ curr = allocator.alloc<Unary>();
+ curr->op = WidenLowSVecI32x4ToVecI64x2;
+ break;
+ case BinaryConsts::I64x2WidenHighSI32x4:
+ curr = allocator.alloc<Unary>();
+ curr->op = WidenHighSVecI32x4ToVecI64x2;
+ break;
+ case BinaryConsts::I64x2WidenLowUI32x4:
+ curr = allocator.alloc<Unary>();
+ curr->op = WidenLowUVecI32x4ToVecI64x2;
+ break;
+ case BinaryConsts::I64x2WidenHighUI32x4:
+ curr = allocator.alloc<Unary>();
+ curr->op = WidenHighUVecI32x4ToVecI64x2;
+ break;
default:
return false;
}
@@ -5101,6 +5125,22 @@ bool WasmBinaryBuilder::maybeVisitSIMDTernary(Expression*& out, uint32_t code) {
curr = allocator.alloc<SIMDTernary>();
curr->op = Bitselect;
break;
+ case BinaryConsts::V8x16SignSelect:
+ curr = allocator.alloc<SIMDTernary>();
+ curr->op = SignSelectVec8x16;
+ break;
+ case BinaryConsts::V16x8SignSelect:
+ curr = allocator.alloc<SIMDTernary>();
+ curr->op = SignSelectVec16x8;
+ break;
+ case BinaryConsts::V32x4SignSelect:
+ curr = allocator.alloc<SIMDTernary>();
+ curr->op = SignSelectVec32x4;
+ break;
+ case BinaryConsts::V64x2SignSelect:
+ curr = allocator.alloc<SIMDTernary>();
+ curr->op = SignSelectVec64x2;
+ break;
case BinaryConsts::F32x4QFMA:
curr = allocator.alloc<SIMDTernary>();
curr->op = QFMAF32x4;
diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp
index 741aef5ce..3a24d0cc0 100644
--- a/src/wasm/wasm-stack.cpp
+++ b/src/wasm/wasm-stack.cpp
@@ -560,6 +560,18 @@ void BinaryInstWriter::visitSIMDTernary(SIMDTernary* curr) {
case QFMSF64x2:
o << U32LEB(BinaryConsts::F64x2QFMS);
break;
+ case SignSelectVec8x16:
+ o << U32LEB(BinaryConsts::V8x16SignSelect);
+ break;
+ case SignSelectVec16x8:
+ o << U32LEB(BinaryConsts::V16x8SignSelect);
+ break;
+ case SignSelectVec32x4:
+ o << U32LEB(BinaryConsts::V32x4SignSelect);
+ break;
+ case SignSelectVec64x2:
+ o << U32LEB(BinaryConsts::V64x2SignSelect);
+ break;
}
}
@@ -1024,6 +1036,10 @@ void BinaryInstWriter::visitUnary(Unary* curr) {
o << int8_t(BinaryConsts::SIMDPrefix)
<< U32LEB(BinaryConsts::I64x2AllTrue);
break;
+ case BitmaskVecI64x2:
+ o << int8_t(BinaryConsts::SIMDPrefix)
+ << U32LEB(BinaryConsts::I64x2Bitmask);
+ break;
case AbsVecF32x4:
o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::F32x4Abs);
break;
@@ -1132,6 +1148,22 @@ void BinaryInstWriter::visitUnary(Unary* curr) {
o << int8_t(BinaryConsts::SIMDPrefix)
<< U32LEB(BinaryConsts::I32x4WidenHighUI16x8);
break;
+ case WidenLowSVecI32x4ToVecI64x2:
+ o << int8_t(BinaryConsts::SIMDPrefix)
+ << U32LEB(BinaryConsts::I64x2WidenLowSI32x4);
+ break;
+ case WidenHighSVecI32x4ToVecI64x2:
+ o << int8_t(BinaryConsts::SIMDPrefix)
+ << U32LEB(BinaryConsts::I64x2WidenHighSI32x4);
+ break;
+ case WidenLowUVecI32x4ToVecI64x2:
+ o << int8_t(BinaryConsts::SIMDPrefix)
+ << U32LEB(BinaryConsts::I64x2WidenLowUI32x4);
+ break;
+ case WidenHighUVecI32x4ToVecI64x2:
+ o << int8_t(BinaryConsts::SIMDPrefix)
+ << U32LEB(BinaryConsts::I64x2WidenHighUI32x4);
+ break;
case InvalidUnary:
WASM_UNREACHABLE("invalid unary op");
}
@@ -1461,6 +1493,9 @@ void BinaryInstWriter::visitBinary(Binary* curr) {
case GeUVecI32x4:
o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I32x4GeU);
break;
+ case EqVecI64x2:
+ o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I64x2Eq);
+ break;
case EqVecF32x4:
o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::F32x4Eq);
break;
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp
index 56cf9c114..b294c953c 100644
--- a/src/wasm/wasm-validator.cpp
+++ b/src/wasm/wasm-validator.cpp
@@ -1534,6 +1534,7 @@ void FunctionValidator::visitBinary(Binary* curr) {
case GtUVecI32x4:
case GeSVecI32x4:
case GeUVecI32x4:
+ case EqVecI64x2:
case EqVecF32x4:
case NeVecF32x4:
case LtVecF32x4:
@@ -1880,6 +1881,10 @@ void FunctionValidator::visitUnary(Unary* curr) {
case WidenHighSVecI16x8ToVecI32x4:
case WidenLowUVecI16x8ToVecI32x4:
case WidenHighUVecI16x8ToVecI32x4:
+ case WidenLowSVecI32x4ToVecI64x2:
+ case WidenHighSVecI32x4ToVecI64x2:
+ case WidenLowUVecI32x4ToVecI64x2:
+ case WidenHighUVecI32x4ToVecI64x2:
shouldBeEqual(curr->type, Type(Type::v128), curr, "expected v128 type");
shouldBeEqual(
curr->value->type, Type(Type::v128), curr, "expected v128 operand");
@@ -1895,6 +1900,7 @@ void FunctionValidator::visitUnary(Unary* curr) {
case BitmaskVecI8x16:
case BitmaskVecI16x8:
case BitmaskVecI32x4:
+ case BitmaskVecI64x2:
shouldBeEqual(curr->type, Type(Type::i32), curr, "expected i32 type");
shouldBeEqual(
curr->value->type, Type(Type::v128), curr, "expected v128 operand");
diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp
index 93a14aecc..8e6550c27 100644
--- a/src/wasm/wasm.cpp
+++ b/src/wasm/wasm.cpp
@@ -869,6 +869,10 @@ void Unary::finalize() {
case WidenHighSVecI16x8ToVecI32x4:
case WidenLowUVecI16x8ToVecI32x4:
case WidenHighUVecI16x8ToVecI32x4:
+ case WidenLowSVecI32x4ToVecI64x2:
+ case WidenHighSVecI32x4ToVecI64x2:
+ case WidenLowUVecI32x4ToVecI64x2:
+ case WidenHighUVecI32x4ToVecI64x2:
type = Type::v128;
break;
case AnyTrueVecI8x16:
@@ -882,6 +886,7 @@ void Unary::finalize() {
case BitmaskVecI8x16:
case BitmaskVecI16x8:
case BitmaskVecI32x4:
+ case BitmaskVecI64x2:
type = Type::i32;
break;