diff options
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.js | 122 |
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++; + } +} + |