diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gen-s-parser.inc | 131 | ||||
-rw-r--r-- | src/ir/cost.h | 10 | ||||
-rw-r--r-- | src/literal.h | 1 | ||||
-rw-r--r-- | src/passes/Print.cpp | 30 | ||||
-rw-r--r-- | src/wasm-binary.h | 11 | ||||
-rw-r--r-- | src/wasm-interpreter.h | 11 | ||||
-rw-r--r-- | src/wasm.h | 18 | ||||
-rw-r--r-- | src/wasm/literal.cpp | 4 | ||||
-rw-r--r-- | src/wasm/wasm-binary.cpp | 40 | ||||
-rw-r--r-- | src/wasm/wasm-stack.cpp | 35 | ||||
-rw-r--r-- | src/wasm/wasm-validator.cpp | 6 | ||||
-rw-r--r-- | src/wasm/wasm.cpp | 5 |
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; |