diff options
Diffstat (limited to 'js/src/jit-test/tests/wasm/simd/ad-hack-preamble.js')
-rw-r--r-- | js/src/jit-test/tests/wasm/simd/ad-hack-preamble.js | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/wasm/simd/ad-hack-preamble.js b/js/src/jit-test/tests/wasm/simd/ad-hack-preamble.js new file mode 100644 index 0000000000..407b59476f --- /dev/null +++ b/js/src/jit-test/tests/wasm/simd/ad-hack-preamble.js @@ -0,0 +1,211 @@ +// |jit-test| skip-if: true + +// Common code for the ad-hack test cases. + +function get(arr, loc, len) { + let res = []; + for ( let i=0; i < len; i++ ) { + res.push(arr[loc+i]); + } + return res; +} + +function getUnaligned(arr, width, loc, len) { + assertEq(arr.constructor, Uint8Array); + assertEq(width <= 4, true); + let res = []; + for ( let i=0; i < len; i++ ) { + let x = 0; + for ( let j=width-1; j >=0; j-- ) + x = (x << 8) | arr[loc+i*width+j]; + res.push(x); + } + return res; +} + +function set(arr, loc, vals) { + for ( let i=0; i < vals.length; i++ ) { + if (arr instanceof BigInt64Array) { + arr[loc+i] = BigInt(vals[i]); + } else { + arr[loc+i] = vals[i]; + } + } +} + +function setUnaligned(arr, width, loc, vals) { + assertEq(arr.constructor, Uint8Array); + assertEq(width <= 4, true); + for ( let i=0; i < vals.length; i++ ) { + let x = vals[i]; + for ( let j=0 ; j < width ; j++ ) { + arr[loc+i*width + j] = x & 255; + x >>= 8; + } + } +} + +function equal(a, b) { + return a === b || isNaN(a) && isNaN(b); +} + +function upd(xs, at, val) { + let ys = Array.from(xs); + ys[at] = val; + return ys; +} + +// The following operations are not always generalized fully, they are just +// functional enough for the existing test cases to pass. + +function sign_extend(n, bits) { + if (bits < 32) { + n = Number(n); + return (n << (32 - bits)) >> (32 - bits); + } + if (typeof n == "bigint") { + if (bits == 32) + return Number(n & 0xFFFF_FFFFn) | 0; + assertEq(bits, 64); + n = (n & 0xFFFF_FFFF_FFFF_FFFFn) + if (n > 0x7FFF_FFFF_FFFF_FFFFn) + return n - 0x1_0000_0000_0000_0000n; + return n; + } + assertEq(bits, 32); + return n|0; +} + +function zero_extend(n, bits) { + if (bits < 32) { + return n & ((1 << bits) - 1); + } + if (n < 0) + n = 0x100000000 + n; + return n; +} + +function signed_saturate(z, bits) { + let min = -(1 << (bits-1)); + if (z <= min) { + return min; + } + let max = (1 << (bits-1)) - 1; + if (z > max) { + return max; + } + return z; +} + +function unsigned_saturate(z, bits) { + if (z <= 0) { + return 0; + } + let max = (1 << bits) - 1; + if (z > max) { + return max; + } + return z; +} + +function shl(count, width) { + if (width == 64) { + count = BigInt(count); + return (v) => { + v = BigInt(v); + if (v < 0) + v = (1n << 64n) + v; + let r = (v << count) & ((1n << 64n) - 1n); + if (r & (1n << 63n)) + r = -((1n << 64n) - r); + return r; + } + } else { + return (v) => { + let mask = (width == 32) ? -1 : ((1 << width) - 1); + return (v << count) & mask; + } + } +} + +function popcount(n) { + n = n - ((n >> 1) & 0x55555555) + n = (n & 0x33333333) + ((n >> 2) & 0x33333333) + return ((n + (n >> 4) & 0xF0F0F0F) * 0x1010101) >> 24 +} + +function jsValueToWasmName(x) { + if (typeof x == "number") { + if (x == 0) return 1 / x < 0 ? "-0" : "0"; + if (isNaN(x)) return "+nan"; + if (!isFinite(x)) return (x < 0 ? "-" : "+") + "inf"; + } + return x; +} + +// For each input array, a set of arrays of the proper length for v128, with +// values in range but possibly of the wrong signedness (eg, for Int8Array, 128 +// is in range but is really -128). Also a unary operator `rectify` that +// transforms the value to the proper sign and bitwidth. + +Int8Array.inputs = [iota(16).map((x) => (x+1) * (x % 3 == 0 ? -1 : 1)), + iota(16).map((x) => (x*2+3) * (x % 3 == 1 ? -1 : 1)), + [1,2,128,127,1,4,128,127,1,2,129,125,1,2,254,0], + [2,1,127,128,5,1,127,128,2,1,126,130,2,1,1,255], + iota(16).map((x) => ((x + 37) * 8 + 12) % 256), + iota(16).map((x) => ((x + 12) * 4 + 9) % 256)]; +Int8Array.rectify = (x) => sign_extend(x,8); +Int8Array.layoutName = 'i8x16'; + +Uint8Array.inputs = Int8Array.inputs; +Uint8Array.rectify = (x) => zero_extend(x,8); +Uint8Array.layoutName = 'i8x16'; + +Int16Array.inputs = [iota(8).map((x) => (x+1) * (x % 3 == 0 ? -1 : 1)), + iota(8).map((x) => (x*2+3) * (x % 3 == 1 ? -1 : 1)), + [1,2,32768,32767,1,4,32768,32767], + [2,1,32767,32768,5,1,32767,32768], + [1,2,128,127,1,4,128,127].map((x) => (x << 8) + x*2), + [2,1,127,128,1,1,128,128].map((x) => (x << 8) + x*3)]; +Int16Array.rectify = (x) => sign_extend(x,16); +Int16Array.layoutName = 'i16x8'; + +Uint16Array.inputs = Int16Array.inputs; +Uint16Array.rectify = (x) => zero_extend(x,16); +Uint16Array.layoutName = 'i16x8'; + +Int32Array.inputs = [iota(4).map((x) => (x+1) * (x % 3 == 0 ? -1 : 1)), + iota(4).map((x) => (x*2+3) * (x % 3 == 1 ? -1 : 1)), + [1,2,32768 << 16,32767 << 16], + [2,1,32767 << 16,32768 << 16], + [1,2,128,127].map((x) => (x << 24) + (x << 8) + x*3), + [2,1,127,128].map((x) => (x << 24) + (x << 8) + x*4)]; +Int32Array.rectify = (x) => sign_extend(x,32); +Int32Array.layoutName = 'i32x4'; + +Uint32Array.inputs = Int32Array.inputs; +Uint32Array.rectify = (x) => zero_extend(x,32); +Uint32Array.layoutName = 'i32x4'; + +BigInt64Array.inputs = [[1,2],[2,1],[-1,-2],[-2,-1],[2n ** 32n, 2n ** 32n - 5n], + [(2n ** 38n) / 5n, (2n ** 41n) / 7n], + [-((2n ** 38n) / 5n), (2n ** 41n) / 7n]]; +BigInt64Array.rectify = (x) => BigInt(x); +BigInt64Array.layoutName = 'i64x2'; + +Float32Array.inputs = [[1, -1, 1e10, -1e10], + [-1, -2, -1e10, 1e10], + [5.1, -1.1, -4.3, -0], + ...permute([1, -10, NaN, Infinity])]; +Float32Array.rectify = (x) => Math.fround(x); +Float32Array.layoutName = 'f32x4'; + +Float64Array.inputs = Float32Array.inputs.map((x) => x.slice(0, 2)) +Float64Array.rectify = (x) => x; +Float64Array.layoutName = 'f64x2'; + +// Tidy up all the inputs +for ( let A of [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, + Float32Array, Float64Array]) { + A.inputs = A.inputs.map((xs) => xs.map(A.rectify)); +} |