summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Lively <7121787+tlively@users.noreply.github.com>2021-07-13 13:44:01 -0700
committerGitHub <noreply@github.com>2021-07-13 20:44:01 +0000
commitaafd1bf1be09d6368127f9878ab1779cc258f526 (patch)
tree85f9565e7dcacff3d67bc45545fa906c31f19db1
parentb217effd56b644c08f6ce4b86533c133b564af6d (diff)
downloadbinaryen-aafd1bf1be09d6368127f9878ab1779cc258f526.tar.gz
binaryen-aafd1bf1be09d6368127f9878ab1779cc258f526.tar.bz2
binaryen-aafd1bf1be09d6368127f9878ab1779cc258f526.zip
Implement interpretation of i64x2.bitmask (#3982)
Like a few other SIMD operations, this i64x2.bitmask had not been implemented in the interpreter yet. Unlike the others, i64x2.bitmask has type i32 rather than type v128, so Precompute was not skipping it, leading to a crash, as in https://github.com/emscripten-core/emscripten/issues/14629. Fix the problem by implementing i64x2.bitmask in the interpreter.
-rw-r--r--src/literal.h1
-rw-r--r--src/wasm-interpreter.h2
-rw-r--r--src/wasm/literal.cpp10
-rw-r--r--test/spec/simd.wast3
4 files changed, 14 insertions, 2 deletions
diff --git a/src/literal.h b/src/literal.h
index 1dd013c4c..965ec157c 100644
--- a/src/literal.h
+++ b/src/literal.h
@@ -570,6 +570,7 @@ public:
Literal extMulHighUI32x4(const Literal& other) const;
Literal absI64x2() const;
Literal negI64x2() const;
+ Literal bitmaskI64x2() const;
Literal allTrueI64x2() const;
Literal shlI64x2(const Literal& other) const;
Literal shrSI64x2(const Literal& other) const;
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h
index 77b055fd1..8870e24dd 100644
--- a/src/wasm-interpreter.h
+++ b/src/wasm-interpreter.h
@@ -500,7 +500,7 @@ public:
case AllTrueVecI64x2:
return value.allTrueI64x2();
case BitmaskVecI64x2:
- WASM_UNREACHABLE("unimp");
+ return value.bitmaskI64x2();
case AbsVecF32x4:
return value.absF32x4();
case NegVecF32x4:
diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp
index 151ea83e5..c3a2ddf7a 100644
--- a/src/wasm/literal.cpp
+++ b/src/wasm/literal.cpp
@@ -1868,6 +1868,16 @@ Literal Literal::bitmaskI32x4() const {
Literal Literal::allTrueI64x2() const {
return all_true<2, &Literal::getLanesI64x2>(*this);
}
+Literal Literal::bitmaskI64x2() const {
+ uint32_t result = 0;
+ LaneArray<2> lanes = getLanesI64x2();
+ for (size_t i = 0; i < 2; ++i) {
+ if (lanes[i].geti64() & (1ll << 63)) {
+ result = result | (1 << i);
+ }
+ }
+ return Literal(result);
+}
template<int Lanes,
LaneArray<Lanes> (Literal::*IntoLanes)() const,
diff --git a/test/spec/simd.wast b/test/spec/simd.wast
index 4876a032d..0eda03fc5 100644
--- a/test/spec/simd.wast
+++ b/test/spec/simd.wast
@@ -824,7 +824,8 @@
;; i64x2 arithmetic
(assert_return (invoke "i64x2.neg" (v128.const i64x2 0x8000000000000000 42)) (v128.const i64x2 0x8000000000000000 -42))
-;; TODO: test i64x2.bitmask
+(assert_return (invoke "i64x2.bitmask" (v128.const i64x2 0x8000000000000000 42)) (i32.const 1))
+(assert_return (invoke "i64x2.bitmask" (v128.const i64x2 1 -1)) (i32.const 2))
(assert_return (invoke "i64x2.shl" (v128.const i64x2 1 0x8000000000000000) (i32.const 1)) (v128.const i64x2 2 0))
(assert_return (invoke "i64x2.shl" (v128.const i64x2 1 0x8000000000000000) (i32.const 64)) (v128.const i64x2 1 0x8000000000000000))
(assert_return (invoke "i64x2.shr_s" (v128.const i64x2 1 0x8000000000000000) (i32.const 1)) (v128.const i64x2 0 0xc000000000000000))