summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gen-s-parser.inc94
-rw-r--r--src/ir/cost.h6
-rw-r--r--src/passes/Print.cpp18
-rw-r--r--src/wasm-binary.h7
-rw-r--r--src/wasm-interpreter.h6
-rw-r--r--src/wasm.h7
-rw-r--r--src/wasm/wasm-binary.cpp24
-rw-r--r--src/wasm/wasm-stack.cpp24
-rw-r--r--src/wasm/wasm-validator.cpp6
-rw-r--r--src/wasm/wasm.cpp6
10 files changed, 175 insertions, 23 deletions
diff --git a/src/gen-s-parser.inc b/src/gen-s-parser.inc
index bb07d81ca..1b48eca24 100644
--- a/src/gen-s-parser.inc
+++ b/src/gen-s-parser.inc
@@ -320,9 +320,17 @@ switch (op[0]) {
default: goto parse_error;
}
}
- case 'd':
- if (strcmp(op, "f32x4.div") == 0) { return makeBinary(s, BinaryOp::DivVecF32x4); }
- goto parse_error;
+ case 'd': {
+ switch (op[7]) {
+ case 'e':
+ if (strcmp(op, "f32x4.demote_f64x2_zero") == 0) { return makeUnary(s, UnaryOp::DemoteZeroVecF64x2ToVecF32x4); }
+ goto parse_error;
+ case 'i':
+ if (strcmp(op, "f32x4.div") == 0) { return makeBinary(s, BinaryOp::DivVecF32x4); }
+ goto parse_error;
+ default: goto parse_error;
+ }
+ }
case 'e': {
switch (op[7]) {
case 'q':
@@ -608,13 +616,29 @@ switch (op[0]) {
if (strcmp(op, "f64x2.ceil") == 0) { return makeUnary(s, UnaryOp::CeilVecF64x2); }
goto parse_error;
case 'o': {
- switch (op[20]) {
- case 's':
- if (strcmp(op, "f64x2.convert_i64x2_s") == 0) { return makeUnary(s, UnaryOp::ConvertSVecI64x2ToVecF64x2); }
- goto parse_error;
- case 'u':
- if (strcmp(op, "f64x2.convert_i64x2_u") == 0) { return makeUnary(s, UnaryOp::ConvertUVecI64x2ToVecF64x2); }
- goto parse_error;
+ switch (op[14]) {
+ case 'i': {
+ switch (op[20]) {
+ case 's':
+ if (strcmp(op, "f64x2.convert_i64x2_s") == 0) { return makeUnary(s, UnaryOp::ConvertSVecI64x2ToVecF64x2); }
+ goto parse_error;
+ case 'u':
+ if (strcmp(op, "f64x2.convert_i64x2_u") == 0) { return makeUnary(s, UnaryOp::ConvertUVecI64x2ToVecF64x2); }
+ goto parse_error;
+ default: goto parse_error;
+ }
+ }
+ case 'l': {
+ switch (op[24]) {
+ case 's':
+ if (strcmp(op, "f64x2.convert_low_i32x4_s") == 0) { return makeUnary(s, UnaryOp::ConvertLowSVecI32x4ToVecF64x2); }
+ goto parse_error;
+ case 'u':
+ if (strcmp(op, "f64x2.convert_low_i32x4_u") == 0) { return makeUnary(s, UnaryOp::ConvertLowUVecI32x4ToVecF64x2); }
+ goto parse_error;
+ default: goto parse_error;
+ }
+ }
default: goto parse_error;
}
}
@@ -689,12 +713,20 @@ switch (op[0]) {
}
}
case 'p': {
- switch (op[8]) {
- case 'a':
- if (strcmp(op, "f64x2.pmax") == 0) { return makeBinary(s, BinaryOp::PMaxVecF64x2); }
- goto parse_error;
- case 'i':
- if (strcmp(op, "f64x2.pmin") == 0) { return makeBinary(s, BinaryOp::PMinVecF64x2); }
+ switch (op[7]) {
+ case 'm': {
+ switch (op[8]) {
+ case 'a':
+ if (strcmp(op, "f64x2.pmax") == 0) { return makeBinary(s, BinaryOp::PMaxVecF64x2); }
+ goto parse_error;
+ case 'i':
+ if (strcmp(op, "f64x2.pmin") == 0) { return makeBinary(s, BinaryOp::PMinVecF64x2); }
+ goto parse_error;
+ default: goto parse_error;
+ }
+ }
+ case 'r':
+ if (strcmp(op, "f64x2.promote_low_f32x4") == 0) { return makeUnary(s, UnaryOp::PromoteLowVecF32x4ToVecF64x2); }
goto parse_error;
default: goto parse_error;
}
@@ -1752,13 +1784,29 @@ switch (op[0]) {
}
}
case 't': {
- switch (op[22]) {
- case 's':
- if (strcmp(op, "i32x4.trunc_sat_f32x4_s") == 0) { return makeUnary(s, UnaryOp::TruncSatSVecF32x4ToVecI32x4); }
- goto parse_error;
- case 'u':
- if (strcmp(op, "i32x4.trunc_sat_f32x4_u") == 0) { return makeUnary(s, UnaryOp::TruncSatUVecF32x4ToVecI32x4); }
- goto parse_error;
+ switch (op[17]) {
+ case '3': {
+ switch (op[22]) {
+ case 's':
+ if (strcmp(op, "i32x4.trunc_sat_f32x4_s") == 0) { return makeUnary(s, UnaryOp::TruncSatSVecF32x4ToVecI32x4); }
+ goto parse_error;
+ case 'u':
+ if (strcmp(op, "i32x4.trunc_sat_f32x4_u") == 0) { return makeUnary(s, UnaryOp::TruncSatUVecF32x4ToVecI32x4); }
+ goto parse_error;
+ default: goto parse_error;
+ }
+ }
+ case '6': {
+ switch (op[27]) {
+ case 's':
+ if (strcmp(op, "i32x4.trunc_sat_f64x2_zero_s") == 0) { return makeUnary(s, UnaryOp::TruncSatZeroSVecF64x2ToVecI32x4); }
+ goto parse_error;
+ case 'u':
+ if (strcmp(op, "i32x4.trunc_sat_f64x2_zero_u") == 0) { return makeUnary(s, UnaryOp::TruncSatZeroUVecF64x2ToVecI32x4); }
+ goto parse_error;
+ default: goto parse_error;
+ }
+ }
default: goto parse_error;
}
}
diff --git a/src/ir/cost.h b/src/ir/cost.h
index 4424f2e00..7f8e39e1b 100644
--- a/src/ir/cost.h
+++ b/src/ir/cost.h
@@ -228,6 +228,12 @@ struct CostAnalyzer : public OverriddenVisitor<CostAnalyzer, Index> {
case WidenHighSVecI32x4ToVecI64x2:
case WidenLowUVecI32x4ToVecI64x2:
case WidenHighUVecI32x4ToVecI64x2:
+ case ConvertLowSVecI32x4ToVecF64x2:
+ case ConvertLowUVecI32x4ToVecF64x2:
+ case TruncSatZeroSVecF64x2ToVecI32x4:
+ case TruncSatZeroUVecF64x2ToVecI32x4:
+ case DemoteZeroVecF64x2ToVecF32x4:
+ case PromoteLowVecF32x4ToVecF64x2:
ret = 1;
break;
case InvalidUnary:
diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp
index b6da29861..0696ea4ec 100644
--- a/src/passes/Print.cpp
+++ b/src/passes/Print.cpp
@@ -1080,6 +1080,24 @@ struct PrintExpressionContents
case WidenHighUVecI32x4ToVecI64x2:
o << "i64x2.widen_high_i32x4_u";
break;
+ case ConvertLowSVecI32x4ToVecF64x2:
+ o << "f64x2.convert_low_i32x4_s";
+ break;
+ case ConvertLowUVecI32x4ToVecF64x2:
+ o << "f64x2.convert_low_i32x4_u";
+ break;
+ case TruncSatZeroSVecF64x2ToVecI32x4:
+ o << "i32x4.trunc_sat_f64x2_zero_s";
+ break;
+ case TruncSatZeroUVecF64x2ToVecI32x4:
+ o << "i32x4.trunc_sat_f64x2_zero_u";
+ break;
+ case DemoteZeroVecF64x2ToVecF32x4:
+ o << "f32x4.demote_f64x2_zero";
+ break;
+ case PromoteLowVecF32x4ToVecF64x2:
+ o << "f64x2.promote_low_f32x4";
+ break;
case InvalidUnary:
WASM_UNREACHABLE("unvalid unary operator");
}
diff --git a/src/wasm-binary.h b/src/wasm-binary.h
index bda793216..c1d2a2b6d 100644
--- a/src/wasm-binary.h
+++ b/src/wasm-binary.h
@@ -973,6 +973,13 @@ enum ASTNodes {
I64x2ExtMulLowUI32x4 = 0xd6,
I64x2ExtMulHighUI32x4 = 0xd7,
+ F64x2ConvertLowSI32x4 = 0x53,
+ F64x2ConvertLowUI32x4 = 0x54,
+ I32x4TruncSatZeroSF64x2 = 0x55,
+ I32x4TruncSatZeroUF64x2 = 0x56,
+ F32x4DemoteZeroF64x2 = 0x57,
+ F64x2PromoteLowF32x4 = 0x69,
+
// prefetch opcodes
PrefetchT = 0xc5,
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h
index 2636b20f2..9fc9734eb 100644
--- a/src/wasm-interpreter.h
+++ b/src/wasm-interpreter.h
@@ -562,6 +562,12 @@ public:
case WidenHighSVecI32x4ToVecI64x2:
case WidenLowUVecI32x4ToVecI64x2:
case WidenHighUVecI32x4ToVecI64x2:
+ case ConvertLowSVecI32x4ToVecF64x2:
+ case ConvertLowUVecI32x4ToVecF64x2:
+ case TruncSatZeroSVecF64x2ToVecI32x4:
+ case TruncSatZeroUVecF64x2ToVecI32x4:
+ case DemoteZeroVecF64x2ToVecF32x4:
+ case PromoteLowVecF32x4ToVecF64x2:
WASM_UNREACHABLE("unimp");
case InvalidUnary:
WASM_UNREACHABLE("invalid unary op");
diff --git a/src/wasm.h b/src/wasm.h
index eeccd7be0..dd15ea7ad 100644
--- a/src/wasm.h
+++ b/src/wasm.h
@@ -216,6 +216,13 @@ enum UnaryOp {
WidenLowUVecI32x4ToVecI64x2,
WidenHighUVecI32x4ToVecI64x2,
+ ConvertLowSVecI32x4ToVecF64x2,
+ ConvertLowUVecI32x4ToVecF64x2,
+ TruncSatZeroSVecF64x2ToVecI32x4,
+ TruncSatZeroUVecF64x2ToVecI32x4,
+ DemoteZeroVecF64x2ToVecF32x4,
+ PromoteLowVecF32x4ToVecF64x2,
+
InvalidUnary
};
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index bf2e4afef..eea0a9c21 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -5037,6 +5037,30 @@ bool WasmBinaryBuilder::maybeVisitSIMDUnary(Expression*& out, uint32_t code) {
curr = allocator.alloc<Unary>();
curr->op = WidenHighUVecI32x4ToVecI64x2;
break;
+ case BinaryConsts::F64x2ConvertLowSI32x4:
+ curr = allocator.alloc<Unary>();
+ curr->op = ConvertLowSVecI32x4ToVecF64x2;
+ break;
+ case BinaryConsts::F64x2ConvertLowUI32x4:
+ curr = allocator.alloc<Unary>();
+ curr->op = ConvertLowUVecI32x4ToVecF64x2;
+ break;
+ case BinaryConsts::I32x4TruncSatZeroSF64x2:
+ curr = allocator.alloc<Unary>();
+ curr->op = TruncSatZeroSVecF64x2ToVecI32x4;
+ break;
+ case BinaryConsts::I32x4TruncSatZeroUF64x2:
+ curr = allocator.alloc<Unary>();
+ curr->op = TruncSatZeroUVecF64x2ToVecI32x4;
+ break;
+ case BinaryConsts::F32x4DemoteZeroF64x2:
+ curr = allocator.alloc<Unary>();
+ curr->op = DemoteZeroVecF64x2ToVecF32x4;
+ break;
+ case BinaryConsts::F64x2PromoteLowF32x4:
+ curr = allocator.alloc<Unary>();
+ curr->op = PromoteLowVecF32x4ToVecF64x2;
+ break;
default:
return false;
}
diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp
index c96ceabb6..b0e000719 100644
--- a/src/wasm/wasm-stack.cpp
+++ b/src/wasm/wasm-stack.cpp
@@ -1186,6 +1186,30 @@ void BinaryInstWriter::visitUnary(Unary* curr) {
o << int8_t(BinaryConsts::SIMDPrefix)
<< U32LEB(BinaryConsts::I64x2WidenHighUI32x4);
break;
+ case ConvertLowSVecI32x4ToVecF64x2:
+ o << int8_t(BinaryConsts::SIMDPrefix)
+ << U32LEB(BinaryConsts::F64x2ConvertLowSI32x4);
+ break;
+ case ConvertLowUVecI32x4ToVecF64x2:
+ o << int8_t(BinaryConsts::SIMDPrefix)
+ << U32LEB(BinaryConsts::F64x2ConvertLowUI32x4);
+ break;
+ case TruncSatZeroSVecF64x2ToVecI32x4:
+ o << int8_t(BinaryConsts::SIMDPrefix)
+ << U32LEB(BinaryConsts::I32x4TruncSatZeroSF64x2);
+ break;
+ case TruncSatZeroUVecF64x2ToVecI32x4:
+ o << int8_t(BinaryConsts::SIMDPrefix)
+ << U32LEB(BinaryConsts::I32x4TruncSatZeroUF64x2);
+ break;
+ case DemoteZeroVecF64x2ToVecF32x4:
+ o << int8_t(BinaryConsts::SIMDPrefix)
+ << U32LEB(BinaryConsts::F32x4DemoteZeroF64x2);
+ break;
+ case PromoteLowVecF32x4ToVecF64x2:
+ o << int8_t(BinaryConsts::SIMDPrefix)
+ << U32LEB(BinaryConsts::F64x2PromoteLowF32x4);
+ break;
case InvalidUnary:
WASM_UNREACHABLE("invalid unary op");
}
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp
index 064a151c3..e7055a8b0 100644
--- a/src/wasm/wasm-validator.cpp
+++ b/src/wasm/wasm-validator.cpp
@@ -1890,6 +1890,12 @@ void FunctionValidator::visitUnary(Unary* curr) {
case WidenHighSVecI32x4ToVecI64x2:
case WidenLowUVecI32x4ToVecI64x2:
case WidenHighUVecI32x4ToVecI64x2:
+ case ConvertLowSVecI32x4ToVecF64x2:
+ case ConvertLowUVecI32x4ToVecF64x2:
+ case TruncSatZeroSVecF64x2ToVecI32x4:
+ case TruncSatZeroUVecF64x2ToVecI32x4:
+ case DemoteZeroVecF64x2ToVecF32x4:
+ case PromoteLowVecF32x4ToVecF64x2:
shouldBeEqual(curr->type, Type(Type::v128), curr, "expected v128 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 55b03c228..52d2af0c6 100644
--- a/src/wasm/wasm.cpp
+++ b/src/wasm/wasm.cpp
@@ -813,6 +813,12 @@ void Unary::finalize() {
case WidenHighSVecI32x4ToVecI64x2:
case WidenLowUVecI32x4ToVecI64x2:
case WidenHighUVecI32x4ToVecI64x2:
+ case ConvertLowSVecI32x4ToVecF64x2:
+ case ConvertLowUVecI32x4ToVecF64x2:
+ case TruncSatZeroSVecF64x2ToVecI32x4:
+ case TruncSatZeroUVecF64x2ToVecI32x4:
+ case DemoteZeroVecF64x2ToVecF32x4:
+ case PromoteLowVecF32x4ToVecF64x2:
type = Type::v128;
break;
case AnyTrueVecI8x16: