summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas Lively <7121787+tlively@users.noreply.github.com>2019-10-03 18:07:02 -0700
committerGitHub <noreply@github.com>2019-10-03 18:07:02 -0700
commit3c78269032071490bc13dc5dbac02567d4d491e0 (patch)
treea00c874c18dd2e00fbb2d05aa104ee8131a7d1c5 /src
parentfc6d2df4eedfef53a0a29fed1ff3ce4707556700 (diff)
downloadbinaryen-3c78269032071490bc13dc5dbac02567d4d491e0.tar.gz
binaryen-3c78269032071490bc13dc5dbac02567d4d491e0.tar.bz2
binaryen-3c78269032071490bc13dc5dbac02567d4d491e0.zip
v8x16.swizzle (#2368)
As specified at https://github.com/WebAssembly/simd/blob/master/proposals/simd/SIMD.md#swizzling-using-variable-indices.
Diffstat (limited to 'src')
-rw-r--r--src/binaryen-c.cpp1
-rw-r--r--src/binaryen-c.h1
-rw-r--r--src/gen-s-parser.inc14
-rw-r--r--src/ir/cost.h3
-rw-r--r--src/js/binaryen.js-post.js4
-rw-r--r--src/literal.h1
-rw-r--r--src/passes/Print.cpp4
-rw-r--r--src/tools/fuzzing.h3
-rw-r--r--src/wasm-binary.h1
-rw-r--r--src/wasm-interpreter.h3
-rw-r--r--src/wasm.h3
-rw-r--r--src/wasm/literal.cpp11
-rw-r--r--src/wasm/wasm-binary.cpp4
-rw-r--r--src/wasm/wasm-stack.cpp5
-rw-r--r--src/wasm/wasm-validator.cpp3
15 files changed, 56 insertions, 5 deletions
diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp
index a4b3e9b5b..7b4ee2bc5 100644
--- a/src/binaryen-c.cpp
+++ b/src/binaryen-c.cpp
@@ -942,6 +942,7 @@ BinaryenOp BinaryenWidenLowUVecI16x8ToVecI32x4(void) {
BinaryenOp BinaryenWidenHighUVecI16x8ToVecI32x4(void) {
return WidenHighUVecI16x8ToVecI32x4;
}
+BinaryenOp BinaryenSwizzleVec8x16(void) { return SwizzleVec8x16; }
BinaryenExpressionRef BinaryenBlock(BinaryenModuleRef module,
const char* name,
diff --git a/src/binaryen-c.h b/src/binaryen-c.h
index a31df8cae..3d15a7efe 100644
--- a/src/binaryen-c.h
+++ b/src/binaryen-c.h
@@ -546,6 +546,7 @@ BINARYEN_API BinaryenOp BinaryenWidenLowSVecI16x8ToVecI32x4(void);
BINARYEN_API BinaryenOp BinaryenWidenHighSVecI16x8ToVecI32x4(void);
BINARYEN_API BinaryenOp BinaryenWidenLowUVecI16x8ToVecI32x4(void);
BINARYEN_API BinaryenOp BinaryenWidenHighUVecI16x8ToVecI32x4(void);
+BINARYEN_API BinaryenOp BinaryenSwizzleVec8x16(void);
typedef void* BinaryenExpressionRef;
diff --git a/src/gen-s-parser.inc b/src/gen-s-parser.inc
index bab468e2a..7f1958582 100644
--- a/src/gen-s-parser.inc
+++ b/src/gen-s-parser.inc
@@ -2509,9 +2509,17 @@ switch (op[0]) {
case 'l':
if (strcmp(op, "v8x16.load_splat") == 0) { return makeSIMDLoad(s, SIMDLoadOp::LoadSplatVec8x16); }
goto parse_error;
- case 's':
- if (strcmp(op, "v8x16.shuffle") == 0) { return makeSIMDShuffle(s); }
- goto parse_error;
+ case 's': {
+ switch (op[7]) {
+ case 'h':
+ if (strcmp(op, "v8x16.shuffle") == 0) { return makeSIMDShuffle(s); }
+ goto parse_error;
+ case 'w':
+ if (strcmp(op, "v8x16.swizzle") == 0) { return makeBinary(s, BinaryOp::SwizzleVec8x16); }
+ goto parse_error;
+ default: goto parse_error;
+ }
+ }
default: goto parse_error;
}
}
diff --git a/src/ir/cost.h b/src/ir/cost.h
index a4d9a0d40..a3d9f8584 100644
--- a/src/ir/cost.h
+++ b/src/ir/cost.h
@@ -666,6 +666,9 @@ struct CostAnalyzer : public Visitor<CostAnalyzer, Index> {
case NarrowUVecI32x4ToVecI16x8:
ret = 1;
break;
+ case SwizzleVec8x16:
+ ret = 1;
+ break;
case InvalidBinary:
WASM_UNREACHABLE();
}
diff --git a/src/js/binaryen.js-post.js b/src/js/binaryen.js-post.js
index 8769e1c9e..b11d2769b 100644
--- a/src/js/binaryen.js-post.js
+++ b/src/js/binaryen.js-post.js
@@ -418,6 +418,7 @@ Module['WidenLowSVecI16x8ToVecI32x4'] = Module['_BinaryenWidenLowSVecI16x8ToVecI
Module['WidenHighSVecI16x8ToVecI32x4'] = Module['_BinaryenWidenHighSVecI16x8ToVecI32x4']();
Module['WidenLowUVecI16x8ToVecI32x4'] = Module['_BinaryenWidenLowUVecI16x8ToVecI32x4']();
Module['WidenHighUVecI16x8ToVecI32x4'] = Module['_BinaryenWidenHighUVecI16x8ToVecI32x4']();
+Module['SwizzleVec8x16'] = Module['_BinaryenSwizzleVec8x16']();
// The size of a single literal in memory as used in Const creation,
// which is a little different: we don't want users to need to make
@@ -1845,6 +1846,9 @@ function wrapModule(module, self) {
return Module['_BinaryenSIMDShuffle'](module, left, right, i8sToStack(mask));
});
},
+ 'swizzle': function(left, right) {
+ return Module['_BinaryenBinary'](module, Module['SwizzleVec8x16'], left, right);
+ },
'load_splat': function(offset, align, ptr) {
return Module['_BinaryenSIMDLoad'](module, Module['LoadSplatVec8x16'], offset, align, ptr);
},
diff --git a/src/literal.h b/src/literal.h
index 98bb1aa7b..19db6a1d6 100644
--- a/src/literal.h
+++ b/src/literal.h
@@ -398,6 +398,7 @@ public:
Literal widenHighSToVecI32x4() const;
Literal widenLowUToVecI32x4() const;
Literal widenHighUToVecI32x4() const;
+ Literal swizzleVec8x16(const Literal& other) const;
private:
Literal addSatSI8(const Literal& other) const;
diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp
index b856b2000..a5b5e3c2b 100644
--- a/src/passes/Print.cpp
+++ b/src/passes/Print.cpp
@@ -1243,6 +1243,10 @@ struct PrintExpressionContents
o << "i16x8.narrow_i32x4_u";
break;
+ case SwizzleVec8x16:
+ o << "v8x16.swizzle";
+ break;
+
case InvalidBinary:
WASM_UNREACHABLE();
}
diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h
index 45ddc59b1..c4070427c 100644
--- a/src/tools/fuzzing.h
+++ b/src/tools/fuzzing.h
@@ -2174,7 +2174,8 @@ private:
NarrowSVecI16x8ToVecI8x16,
NarrowUVecI16x8ToVecI8x16,
NarrowSVecI32x4ToVecI16x8,
- NarrowUVecI32x4ToVecI16x8),
+ NarrowUVecI32x4ToVecI16x8,
+ SwizzleVec8x16),
make(v128),
make(v128)});
}
diff --git a/src/wasm-binary.h b/src/wasm-binary.h
index f299099b2..104e7b208 100644
--- a/src/wasm-binary.h
+++ b/src/wasm-binary.h
@@ -879,6 +879,7 @@ enum ASTNodes {
I32x4LoadExtUVec16x4 = 0xd5,
I64x2LoadExtSVec32x2 = 0xd6,
I64x2LoadExtUVec32x2 = 0xd7,
+ V8x16Swizzle = 0xc0,
// bulk memory opcodes
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h
index 8c429caa9..5995808a5 100644
--- a/src/wasm-interpreter.h
+++ b/src/wasm-interpreter.h
@@ -816,6 +816,9 @@ public:
case NarrowUVecI32x4ToVecI16x8:
return left.narrowUToVecI16x8(right);
+ case SwizzleVec8x16:
+ return left.swizzleVec8x16(right);
+
case InvalidBinary:
WASM_UNREACHABLE();
}
diff --git a/src/wasm.h b/src/wasm.h
index 8006bd319..d4b53f5bb 100644
--- a/src/wasm.h
+++ b/src/wasm.h
@@ -392,6 +392,9 @@ enum BinaryOp {
NarrowSVecI32x4ToVecI16x8,
NarrowUVecI32x4ToVecI16x8,
+ // SIMD Swizzle
+ SwizzleVec8x16,
+
InvalidBinary
};
diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp
index b382d1a3d..7f0c9fa6b 100644
--- a/src/wasm/literal.cpp
+++ b/src/wasm/literal.cpp
@@ -1867,4 +1867,15 @@ Literal Literal::widenHighUToVecI32x4() const {
return widen<4, &Literal::getLanesUI16x8, LaneOrder::High>(*this);
}
+Literal Literal::swizzleVec8x16(const Literal& other) const {
+ auto lanes = getLanesUI8x16();
+ auto indices = other.getLanesUI8x16();
+ LaneArray<16> result;
+ for (size_t i = 0; i < 16; ++i) {
+ size_t index = indices[i].geti32();
+ result[i] = index >= 16 ? Literal(int32_t(0)) : lanes[index];
+ }
+ return Literal(result);
+}
+
} // namespace wasm
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index 1606d74a1..8446f3c17 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -3963,6 +3963,10 @@ bool WasmBinaryBuilder::maybeVisitSIMDBinary(Expression*& out, uint32_t code) {
curr = allocator.alloc<Binary>();
curr->op = NarrowUVecI32x4ToVecI16x8;
break;
+ case BinaryConsts::V8x16Swizzle:
+ curr = allocator.alloc<Binary>();
+ curr->op = SwizzleVec8x16;
+ break;
default:
return false;
}
diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp
index 8b7ccfb2e..949bf1364 100644
--- a/src/wasm/wasm-stack.cpp
+++ b/src/wasm/wasm-stack.cpp
@@ -1484,6 +1484,11 @@ void BinaryInstWriter::visitBinary(Binary* curr) {
<< U32LEB(BinaryConsts::I16x8NarrowUI32x4);
break;
+ case SwizzleVec8x16:
+ o << int8_t(BinaryConsts::SIMDPrefix)
+ << U32LEB(BinaryConsts::V8x16Swizzle);
+ break;
+
case InvalidBinary:
WASM_UNREACHABLE();
}
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp
index 1c30d0d2a..278ec4769 100644
--- a/src/wasm/wasm-validator.cpp
+++ b/src/wasm/wasm-validator.cpp
@@ -1366,7 +1366,8 @@ void FunctionValidator::visitBinary(Binary* curr) {
case NarrowSVecI16x8ToVecI8x16:
case NarrowUVecI16x8ToVecI8x16:
case NarrowSVecI32x4ToVecI16x8:
- case NarrowUVecI32x4ToVecI16x8: {
+ case NarrowUVecI32x4ToVecI16x8:
+ case SwizzleVec8x16: {
shouldBeEqualOrFirstIsUnreachable(
curr->left->type, v128, curr, "v128 op");
shouldBeEqualOrFirstIsUnreachable(