summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/wasm/simd/ad-hack-simple-unops.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit-test/tests/wasm/simd/ad-hack-simple-unops.js')
-rw-r--r--js/src/jit-test/tests/wasm/simd/ad-hack-simple-unops.js122
1 files changed, 122 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/wasm/simd/ad-hack-simple-unops.js b/js/src/jit-test/tests/wasm/simd/ad-hack-simple-unops.js
new file mode 100644
index 0000000000..6e562a97a1
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/simd/ad-hack-simple-unops.js
@@ -0,0 +1,122 @@
+// |jit-test| skip-if: !wasmSimdEnabled()
+
+// Do not include this in the preamble, it must be loaded after lib/wasm.js
+load(scriptdir + "ad-hack-preamble.js")
+
+// Simple unary operators. Place parameter in memory at offset 16,
+// read the result at offset 0.
+
+function expandConstantUnopInputs(op, memtype, inputs) {
+ let s = '';
+ let ident = 0;
+ for ( let a of inputs ) {
+ let constval = `${memtype.layoutName} ${a.map(jsValueToWasmName).join(' ')}`;
+ s += `
+ (func (export "run_const${ident}")
+ (v128.store (i32.const 0)
+ (${op} (v128.const ${constval}))))
+`;
+ ident++;
+ }
+ return s;
+}
+
+function insAndMemUnop(op, memtype, resultmemtype, inputs) {
+ var ins = wasmEvalText(`
+ (module
+ (memory (export "mem") 1 1)
+
+ (func (export "run")
+ (v128.store (i32.const 0)
+ (call $doit (v128.load (i32.const 16)))))
+
+ (func $doit (param $a v128) (result v128)
+ (${op} (local.get $a)))
+
+ ${expandConstantUnopInputs(op, memtype, inputs)})`);
+ var mem = new memtype(ins.exports.mem.buffer);
+ var resultmem = !resultmemtype || memtype == resultmemtype ? mem : new resultmemtype(ins.exports.mem.buffer);
+ return [ins, mem, resultmem];
+}
+
+function ineg(bits) { return (a) => sign_extend(!a ? a : -a,bits) }
+function iabs(bits) { return (a) => zero_extend(a < 0 ? -a : a, bits) }
+function fneg(a) { return -a }
+function fabs(a) { return Math.abs(a) }
+function fsqrt(a) { return Math.fround(Math.sqrt(Math.fround(a))) }
+function dsqrt(a) { return Math.sqrt(a) }
+function bitnot(a) { return (~a) & 255 }
+function ffloor(x) { return Math.fround(Math.floor(x)) }
+function fceil(x) { return Math.fround(Math.ceil(x)) }
+function ftrunc(x) { return Math.fround(Math.sign(x)*Math.floor(Math.abs(x))) }
+function fnearest(x) { return Math.fround(Math.round(x)) }
+function dfloor(x) { return Math.floor(x) }
+function dceil(x) { return Math.ceil(x) }
+function dtrunc(x) { return Math.sign(x)*Math.floor(Math.abs(x)) }
+function dnearest(x) { return Math.round(x) }
+
+for ( let [op, memtype, rop, resultmemtype] of
+ [['i8x16.neg', Int8Array, ineg(8)],
+ ['i16x8.neg', Int16Array, ineg(16)],
+ ['i32x4.neg', Int32Array, ineg(32)],
+ ['i64x2.neg', BigInt64Array, ineg(64)],
+ ['i8x16.abs', Int8Array, iabs(8), Uint8Array],
+ ['i16x8.abs', Int16Array, iabs(16), Uint16Array],
+ ['i32x4.abs', Int32Array, iabs(32), Uint32Array],
+ ['f32x4.neg', Float32Array, fneg],
+ ['f64x2.neg', Float64Array, fneg],
+ ['f32x4.abs', Float32Array, fabs],
+ ['f64x2.abs', Float64Array, fabs],
+ ['f32x4.sqrt', Float32Array, fsqrt],
+ ['f64x2.sqrt', Float64Array, dsqrt],
+ ['f32x4.ceil', Float32Array, fceil],
+ ['f32x4.floor', Float32Array, ffloor],
+ ['f32x4.trunc', Float32Array, ftrunc],
+ ['f32x4.nearest', Float32Array, fnearest],
+ ['f64x2.ceil', Float64Array, dceil],
+ ['f64x2.floor', Float64Array, dfloor],
+ ['f64x2.trunc', Float64Array, dtrunc],
+ ['f64x2.nearest', Float64Array, dnearest],
+ ['v128.not', Uint8Array, bitnot],
+ ])
+{
+ let [ins, mem, resultmem] = insAndMemUnop(op, memtype, resultmemtype, memtype.inputs);
+ let len = 16/memtype.BYTES_PER_ELEMENT;
+ let xs = iota(len);
+ let zero = xs.map(_ => 0);
+ let bitsForF32 = memtype == Float32Array ? new Uint32Array(mem.buffer) : null;
+ let bitsForF64 = memtype == Float64Array ? new BigInt64Array(mem.buffer) : null;
+
+ function testIt(a, r) {
+ set(mem, len, a);
+ ins.exports.run();
+ assertSame(get(resultmem, 0, len), r);
+
+ // Test signalling NaN superficially by replacing QNaN inputs with SNaN
+ if (bitsForF32 != null && a.some(isNaN)) {
+ a.forEach((x, i) => { if (isNaN(x)) { bitsForF32[len+i] = 0x7FA0_0000; } });
+ ins.exports.run();
+ assertSame(get(resultmem, 0, len), r);
+ }
+ if (bitsForF64 != null && a.some(isNaN)) {
+ a.forEach((x, i) => { if (isNaN(x)) { bitsForF64[len+i] = 0x7FF4_0000_0000_0000n; } });
+ ins.exports.run();
+ assertSame(get(resultmem, 0, len), r);
+ }
+ }
+
+ function testConstIt(i,r) {
+ set(resultmem, 0, zero);
+ ins.exports["run_const" + i]();
+ assertSame(get(resultmem, 0, len), r);
+ }
+
+ let i = 0;
+ for (let a of memtype.inputs) {
+ let r = xs.map((i) => rop(a[i]));
+ testIt(a, r);
+ testConstIt(i, r);
+ i++;
+ }
+}
+