summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Lively <7121787+tlively@users.noreply.github.com>2021-01-19 19:32:10 -0500
committerGitHub <noreply@github.com>2021-01-19 16:32:10 -0800
commita4d1b53ff3374a5d7843b0a879a7908334d5bb46 (patch)
tree6bc7c3fd1ca8850f5fbba27ee850b98343306656
parent0f212dfc69306688afa5057e3179aed5af3edc85 (diff)
downloadbinaryen-a4d1b53ff3374a5d7843b0a879a7908334d5bb46.tar.gz
binaryen-a4d1b53ff3374a5d7843b0a879a7908334d5bb46.tar.bz2
binaryen-a4d1b53ff3374a5d7843b0a879a7908334d5bb46.zip
Prototype additional f64x2 conversions (#3501)
As proposed in https://github.com/WebAssembly/simd/pull/383, with opcodes coordinated with the WIP V8 prototype.
-rwxr-xr-xscripts/gen-s-parser.py7
-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
-rw-r--r--test/simd.wast30
-rw-r--r--test/simd.wast.from-wast30
-rw-r--r--test/simd.wast.fromBinary30
-rw-r--r--test/simd.wast.fromBinary.noDebugInfo30
-rw-r--r--test/spec/simd.wast1
16 files changed, 303 insertions, 23 deletions
diff --git a/scripts/gen-s-parser.py b/scripts/gen-s-parser.py
index f9ff903fc..ae19596d5 100755
--- a/scripts/gen-s-parser.py
+++ b/scripts/gen-s-parser.py
@@ -516,6 +516,13 @@ instructions = [
("i16x8.extadd_pairwise_i8x16_u", "makeUnary(s, UnaryOp::ExtAddPairwiseUVecI8x16ToI16x8)"),
("i32x4.extadd_pairwise_i16x8_s", "makeUnary(s, UnaryOp::ExtAddPairwiseSVecI16x8ToI32x4)"),
("i32x4.extadd_pairwise_i16x8_u", "makeUnary(s, UnaryOp::ExtAddPairwiseUVecI16x8ToI32x4)"),
+ ("f64x2.convert_low_i32x4_s", "makeUnary(s, UnaryOp::ConvertLowSVecI32x4ToVecF64x2)"),
+ ("f64x2.convert_low_i32x4_u", "makeUnary(s, UnaryOp::ConvertLowUVecI32x4ToVecF64x2)"),
+ ("i32x4.trunc_sat_f64x2_zero_s", "makeUnary(s, UnaryOp::TruncSatZeroSVecF64x2ToVecI32x4)"),
+ ("i32x4.trunc_sat_f64x2_zero_u", "makeUnary(s, UnaryOp::TruncSatZeroUVecF64x2ToVecI32x4)"),
+ ("f32x4.demote_f64x2_zero", "makeUnary(s, UnaryOp::DemoteZeroVecF64x2ToVecF32x4)"),
+ ("f64x2.promote_low_f32x4", "makeUnary(s, UnaryOp::PromoteLowVecF32x4ToVecF64x2)"),
+
# prefetch instructions
("prefetch.t", "makePrefetch(s, PrefetchOp::PrefetchTemporal)"),
("prefetch.nt", "makePrefetch(s, PrefetchOp::PrefetchNontemporal)"),
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:
diff --git a/test/simd.wast b/test/simd.wast
index 515268859..a171c5398 100644
--- a/test/simd.wast
+++ b/test/simd.wast
@@ -1406,4 +1406,34 @@
(local.get $0)
)
)
+ (func $f64x2.convert_low_i32x4_s (param $0 v128) (result v128)
+ (f64x2.convert_low_i32x4_s
+ (local.get $0)
+ )
+ )
+ (func $f64x2.convert_low_i32x4_u (param $0 v128) (result v128)
+ (f64x2.convert_low_i32x4_u
+ (local.get $0)
+ )
+ )
+ (func $i32x4.trunc_sat_f64x2_zero_s (param $0 v128) (result v128)
+ (i32x4.trunc_sat_f64x2_zero_s
+ (local.get $0)
+ )
+ )
+ (func $i32x4.trunc_sat_f64x2_zero_u (param $0 v128) (result v128)
+ (i32x4.trunc_sat_f64x2_zero_u
+ (local.get $0)
+ )
+ )
+ (func $f32x4.demote_f64x2_zero (param $0 v128) (result v128)
+ (f32x4.demote_f64x2_zero
+ (local.get $0)
+ )
+ )
+ (func $f64x2.promote_low_f32x4 (param $0 v128) (result v128)
+ (f64x2.promote_low_f32x4
+ (local.get $0)
+ )
+ )
)
diff --git a/test/simd.wast.from-wast b/test/simd.wast.from-wast
index 158de7664..223191c18 100644
--- a/test/simd.wast.from-wast
+++ b/test/simd.wast.from-wast
@@ -1424,4 +1424,34 @@
(local.get $0)
)
)
+ (func $f64x2.convert_low_i32x4_s (param $0 v128) (result v128)
+ (f64x2.convert_low_i32x4_s
+ (local.get $0)
+ )
+ )
+ (func $f64x2.convert_low_i32x4_u (param $0 v128) (result v128)
+ (f64x2.convert_low_i32x4_u
+ (local.get $0)
+ )
+ )
+ (func $i32x4.trunc_sat_f64x2_zero_s (param $0 v128) (result v128)
+ (i32x4.trunc_sat_f64x2_zero_s
+ (local.get $0)
+ )
+ )
+ (func $i32x4.trunc_sat_f64x2_zero_u (param $0 v128) (result v128)
+ (i32x4.trunc_sat_f64x2_zero_u
+ (local.get $0)
+ )
+ )
+ (func $f32x4.demote_f64x2_zero (param $0 v128) (result v128)
+ (f32x4.demote_f64x2_zero
+ (local.get $0)
+ )
+ )
+ (func $f64x2.promote_low_f32x4 (param $0 v128) (result v128)
+ (f64x2.promote_low_f32x4
+ (local.get $0)
+ )
+ )
)
diff --git a/test/simd.wast.fromBinary b/test/simd.wast.fromBinary
index c78c23572..1c0b12493 100644
--- a/test/simd.wast.fromBinary
+++ b/test/simd.wast.fromBinary
@@ -1424,5 +1424,35 @@
(local.get $0)
)
)
+ (func $f64x2.convert_low_i32x4_s (param $0 v128) (result v128)
+ (f64x2.convert_low_i32x4_s
+ (local.get $0)
+ )
+ )
+ (func $f64x2.convert_low_i32x4_u (param $0 v128) (result v128)
+ (f64x2.convert_low_i32x4_u
+ (local.get $0)
+ )
+ )
+ (func $i32x4.trunc_sat_f64x2_zero_s (param $0 v128) (result v128)
+ (i32x4.trunc_sat_f64x2_zero_s
+ (local.get $0)
+ )
+ )
+ (func $i32x4.trunc_sat_f64x2_zero_u (param $0 v128) (result v128)
+ (i32x4.trunc_sat_f64x2_zero_u
+ (local.get $0)
+ )
+ )
+ (func $f32x4.demote_f64x2_zero (param $0 v128) (result v128)
+ (f32x4.demote_f64x2_zero
+ (local.get $0)
+ )
+ )
+ (func $f64x2.promote_low_f32x4 (param $0 v128) (result v128)
+ (f64x2.promote_low_f32x4
+ (local.get $0)
+ )
+ )
)
diff --git a/test/simd.wast.fromBinary.noDebugInfo b/test/simd.wast.fromBinary.noDebugInfo
index 8655975db..3feb5a7b4 100644
--- a/test/simd.wast.fromBinary.noDebugInfo
+++ b/test/simd.wast.fromBinary.noDebugInfo
@@ -1424,5 +1424,35 @@
(local.get $0)
)
)
+ (func $250 (param $0 v128) (result v128)
+ (f64x2.convert_low_i32x4_s
+ (local.get $0)
+ )
+ )
+ (func $251 (param $0 v128) (result v128)
+ (f64x2.convert_low_i32x4_u
+ (local.get $0)
+ )
+ )
+ (func $252 (param $0 v128) (result v128)
+ (i32x4.trunc_sat_f64x2_zero_s
+ (local.get $0)
+ )
+ )
+ (func $253 (param $0 v128) (result v128)
+ (i32x4.trunc_sat_f64x2_zero_u
+ (local.get $0)
+ )
+ )
+ (func $254 (param $0 v128) (result v128)
+ (f32x4.demote_f64x2_zero
+ (local.get $0)
+ )
+ )
+ (func $255 (param $0 v128) (result v128)
+ (f64x2.promote_low_f32x4
+ (local.get $0)
+ )
+ )
)
diff --git a/test/spec/simd.wast b/test/spec/simd.wast
index 968a3e553..87bbb96cb 100644
--- a/test/spec/simd.wast
+++ b/test/spec/simd.wast
@@ -265,6 +265,7 @@
(func (export "v128.load64_zero") (param $0 i32) (result v128) (v128.load64_zero (local.get $0)))
(func (export "v8x16.swizzle") (param $0 v128) (param $1 v128) (result v128) (v8x16.swizzle (local.get $0) (local.get $1)))
)
+;; TODO: Additional f64x2 conversions if specified
;; Basic v128 manipulation
(assert_return (invoke "v128.load" (i32.const 128)) (v128.const i8x16 87 65 83 77 83 73 77 68 71 79 69 83 70 65 83 84))