summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/wasm/simd/validation.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit-test/tests/wasm/simd/validation.js')
-rw-r--r--js/src/jit-test/tests/wasm/simd/validation.js368
1 files changed, 368 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/wasm/simd/validation.js b/js/src/jit-test/tests/wasm/simd/validation.js
new file mode 100644
index 0000000000..46b8df620f
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/simd/validation.js
@@ -0,0 +1,368 @@
+// |jit-test| skip-if: !wasmSimdEnabled()
+
+function testValid(code) {
+ assertEq(WebAssembly.validate(wasmTextToBinary(code)), true);
+}
+
+function testInvalid(code) {
+ assertEq(WebAssembly.validate(wasmTextToBinary(code)), false);
+}
+
+// v128 -> v128
+
+for (let op of [
+ 'i8x16.neg',
+ 'i8x16.abs',
+ 'i16x8.neg',
+ 'i16x8.abs',
+ 'i16x8.extend_low_i8x16_s',
+ 'i16x8.extend_high_i8x16_s',
+ 'i16x8.extend_low_i8x16_u',
+ 'i16x8.extend_high_i8x16_u',
+ 'i32x4.neg',
+ 'i32x4.abs',
+ 'i32x4.extend_low_i16x8_s',
+ 'i32x4.extend_high_i16x8_s',
+ 'i32x4.extend_low_i16x8_u',
+ 'i32x4.extend_high_i16x8_u',
+ 'i32x4.trunc_sat_f32x4_s',
+ 'i32x4.trunc_sat_f32x4_u',
+ 'i64x2.neg',
+ 'f32x4.abs',
+ 'f32x4.neg',
+ 'f32x4.sqrt',
+ 'f32x4.convert_i32x4_s',
+ 'f32x4.convert_i32x4_s',
+ 'f64x2.abs',
+ 'f64x2.neg',
+ 'f64x2.sqrt',
+ 'v128.not'])
+{
+ testValid(`(module
+ (func (param v128) (result v128)
+ (${op} (local.get 0))))`);
+}
+
+for (let [prefix, result, suffix] of [['i8x16', 'i32', '_s'],
+ ['i8x16', 'i32', '_u'],
+ ['i16x8', 'i32', '_s'],
+ ['i16x8', 'i32', '_u'],
+ ['i32x4', 'i32', ''],
+ ['i64x2', 'i64', ''],
+ ['f32x4', 'f32', ''],
+ ['f64x2', 'f64', '']])
+{
+ testValid(`(module
+ (func (param v128) (result ${result})
+ (${prefix}.extract_lane${suffix} 1 (local.get 0))))`);
+}
+
+// The wat parser accepts small out-of-range lane indices, but they must be
+// caught in validation.
+
+testInvalid(
+ `(module
+ (func (param v128) (result i32)
+ (i8x16.extract_lane_u 16 (local.get 0))))`);
+
+// (v128, v128) -> v128
+
+for (let op of [
+ 'i8x16.eq',
+ 'i8x16.ne',
+ 'i8x16.lt_s',
+ 'i8x16.lt_u',
+ 'i8x16.gt_s',
+ 'i8x16.gt_u',
+ 'i8x16.le_s',
+ 'i8x16.le_u',
+ 'i8x16.ge_s',
+ 'i8x16.ge_u',
+ 'i16x8.eq',
+ 'i16x8.ne',
+ 'i16x8.lt_s',
+ 'i16x8.lt_u',
+ 'i16x8.gt_s',
+ 'i16x8.gt_u',
+ 'i16x8.le_s',
+ 'i16x8.le_u',
+ 'i16x8.ge_s',
+ 'i16x8.ge_u',
+ 'i32x4.eq',
+ 'i32x4.ne',
+ 'i32x4.lt_s',
+ 'i32x4.lt_u',
+ 'i32x4.gt_s',
+ 'i32x4.gt_u',
+ 'i32x4.le_s',
+ 'i32x4.le_u',
+ 'i32x4.ge_s',
+ 'i32x4.ge_u',
+ 'f32x4.eq',
+ 'f32x4.ne',
+ 'f32x4.lt',
+ 'f32x4.gt',
+ 'f32x4.le',
+ 'f32x4.ge',
+ 'f64x2.eq',
+ 'f64x2.ne',
+ 'f64x2.lt',
+ 'f64x2.gt',
+ 'f64x2.le',
+ 'f64x2.ge',
+ 'v128.and',
+ 'v128.or',
+ 'v128.xor',
+ 'v128.andnot',
+ 'i8x16.avgr_u',
+ 'i16x8.avgr_u',
+ 'i8x16.add',
+ 'i8x16.add_sat_s',
+ 'i8x16.add_sat_u',
+ 'i8x16.sub',
+ 'i8x16.sub_sat_s',
+ 'i8x16.sub_sat_u',
+ 'i8x16.min_s',
+ 'i8x16.max_s',
+ 'i8x16.min_u',
+ 'i8x16.max_u',
+ 'i16x8.add',
+ 'i16x8.add_sat_s',
+ 'i16x8.add_sat_u',
+ 'i16x8.sub',
+ 'i16x8.sub_sat_s',
+ 'i16x8.sub_sat_u',
+ 'i16x8.mul',
+ 'i16x8.min_s',
+ 'i16x8.max_s',
+ 'i16x8.min_u',
+ 'i16x8.max_u',
+ 'i32x4.add',
+ 'i32x4.sub',
+ 'i32x4.mul',
+ 'i32x4.min_s',
+ 'i32x4.max_s',
+ 'i32x4.min_u',
+ 'i32x4.max_u',
+ 'i64x2.add',
+ 'i64x2.sub',
+ 'i64x2.mul',
+ 'f32x4.add',
+ 'f32x4.sub',
+ 'f32x4.mul',
+ 'f32x4.div',
+ 'f32x4.min',
+ 'f32x4.max',
+ 'f64x2.add',
+ 'f64x2.sub',
+ 'f64x2.mul',
+ 'f64x2.div',
+ 'f64x2.min',
+ 'f64x2.max',
+ 'i8x16.narrow_i16x8_s',
+ 'i8x16.narrow_i16x8_u',
+ 'i16x8.narrow_i32x4_s',
+ 'i16x8.narrow_i32x4_u',
+ 'i8x16.swizzle'])
+{
+ testValid(`(module
+ (func (param v128) (param v128) (result v128)
+ (${op} (local.get 0) (local.get 1))))`);
+}
+
+testValid(`(module
+ (func (param v128) (param v128) (result v128)
+ (i8x16.shuffle 0 16 1 17 2 18 3 19 4 20 5 21 6 22 7 23 (local.get 0) (local.get 1))))`);
+
+assertErrorMessage(() => testValid(
+ `(module
+ (func (param v128) (param v128) (result v128)
+ (i8x16.shuffle 0 16 1 17 2 18 3 19 4 20 5 21 6 22 7 (local.get 0) (local.get 1))))`),
+ SyntaxError,
+ /expected a u8/);
+
+// (v128, i32) -> v128
+
+for (let op of [
+ 'i8x16.shl',
+ 'i8x16.shr_s',
+ 'i8x16.shr_u',
+ 'i16x8.shl',
+ 'i16x8.shr_s',
+ 'i16x8.shr_u',
+ 'i32x4.shl',
+ 'i32x4.shr_s',
+ 'i32x4.shr_u',
+ 'i64x2.shl',
+ 'i64x2.shr_s',
+ 'i64x2.shr_u'])
+{
+ testValid(`(module
+ (func (param v128) (param i32) (result v128)
+ (${op} (local.get 0) (local.get 1))))`);
+}
+
+// v128 -> i32
+
+for (let op of [
+ 'v128.any_true',
+ 'i8x16.all_true',
+ 'i16x8.all_true',
+ 'i32x4.all_true',
+ 'i8x16.bitmask',
+ 'i16x8.bitmask',
+ 'i32x4.bitmask'])
+{
+ testValid(`(module
+ (func (param v128) (result i32)
+ (${op} (local.get 0))))`);
+}
+
+// T -> V128
+
+for (let [op, input] of [
+ ['i8x16.splat', 'i32'],
+ ['i16x8.splat', 'i32'],
+ ['i32x4.splat', 'i32'],
+ ['i64x2.splat', 'i64'],
+ ['f32x4.splat', 'f32'],
+ ['f64x2.splat', 'f64']])
+{
+ testValid(`(module
+ (func (param ${input}) (result v128)
+ (${op} (local.get 0))))`);
+}
+
+// i32 -> v128
+
+for (let op of [
+ 'v128.load',
+ 'v128.load8_splat',
+ 'v128.load16_splat',
+ 'v128.load32_splat',
+ 'v128.load64_splat',
+ 'v128.load8x8_s',
+ 'v128.load8x8_u',
+ 'v128.load16x4_s',
+ 'v128.load16x4_u',
+ 'v128.load32x2_s',
+ 'v128.load32x2_u'])
+{
+ testValid(`(module
+ (memory 1 1)
+ (func (param i32) (result v128)
+ (${op} (local.get 0))))`);
+}
+
+testValid(`(module
+ (func (result v128)
+ (v128.const i8x16 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15))
+ (func (result v128)
+ (v128.const i16x8 0 1 2 3 4 5 6 7))
+ (func (result v128)
+ (v128.const i32x4 0 1 2 3))
+ (func (result v128)
+ (v128.const i64x2 0 1))
+ (func (result v128)
+ (v128.const f32x4 0 1 2 3))
+ (func (result v128)
+ (v128.const f32x4 0.5 1.5 2.5 3.5))
+ (func (result v128)
+ (v128.const f64x2 0 1))
+ (func (result v128)
+ (v128.const f64x2 0.5 1.5)))`);
+
+assertErrorMessage(() => testValid(
+ `(module
+ (func (result v128)
+ (v128.const i8x16 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14)))`),
+ SyntaxError,
+ /expected a i8/);
+
+assertErrorMessage(() => testValid(
+ `(module
+ (func (result v128)
+ (v128.const i8x16 0 1 2 3 4 5 6 7 8 9 10 11 12 13 256 15)))`),
+ SyntaxError,
+ /invalid i8 number/);
+
+assertErrorMessage(() => testValid(
+ `(module
+ (func (result v128)
+ (v128.const i8x16 0 1 2 3 4 5 6 7 8 9 10 11 12 13 3.14 15)))`),
+ SyntaxError,
+ /expected a i8/);
+
+assertErrorMessage(() => testValid(
+ `(module
+ (func (result v128)
+ (v128.const f32x4 0.5 1.5 2.5))`),
+ SyntaxError,
+ /expected a float/);
+
+assertErrorMessage(() => testValid(
+ `(module
+ (func (result v128)
+ (v128.const i8x8 0 1 2 3 4 5 6 7)))`),
+ SyntaxError,
+ /expected one of/);
+
+// v128 -> ()
+
+testValid(`(module
+ (memory 1 1)
+ (func (param i32) (param v128)
+ (v128.store (local.get 0) (local.get 1))))`);
+
+// (v128, v128, v128) -> v128
+
+testValid(`(module
+ (func (param v128) (param v128) (param v128) (result v128)
+ (v128.bitselect (local.get 0) (local.get 1) (local.get 2))))`);
+
+// (v128, t) -> v128
+
+for (let [prefix, input] of [['i8x16', 'i32'],
+ ['i16x8', 'i32'],
+ ['i32x4', 'i32'],
+ ['i64x2', 'i64'],
+ ['f32x4', 'f32'],
+ ['f64x2', 'f64']])
+{
+ testValid(`(module
+ (func (param v128) (param ${input}) (result v128)
+ (${prefix}.replace_lane 1 (local.get 0) (local.get 1))))`);
+}
+
+testInvalid(
+ `(module
+ (func (param v128) (param i32) (result v128)
+ (i8x16.replace_lane 16 (local.get 0) (local.get 1))))`);
+
+// Global variables
+
+testValid(`(module
+ (global $g (mut v128) (v128.const f32x4 1 2 3 4)))`);
+
+testValid(`(module
+ (global $g (import "m" "g") v128)
+ (global $h (mut v128) (global.get $g)))`);
+
+testValid(`(module
+ (global $g (export "g") v128 (v128.const f32x4 1 2 3 4)))`);
+
+testValid(`(module
+ (global $g (export "g") (mut v128) (v128.const f32x4 1 2 3 4)))`);
+
+// Imports, exports, calls
+
+testValid(`(module
+ (import "m" "g" (func (param v128) (result v128)))
+ (func (export "f") (param v128) (result v128)
+ (f64x2.add (local.get 0) (v128.const f64x2 1 2))))`);
+
+testValid(`(module
+ (func $f (param v128) (result v128)
+ (i8x16.neg (local.get 0)))
+ (func $g (export "g") (param v128) (result v128)
+ (call $f (local.get 0))))`);