summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/asm.js/testZOOB.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit-test/tests/asm.js/testZOOB.js')
-rw-r--r--js/src/jit-test/tests/asm.js/testZOOB.js232
1 files changed, 232 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/asm.js/testZOOB.js b/js/src/jit-test/tests/asm.js/testZOOB.js
new file mode 100644
index 000000000..ae59611d6
--- /dev/null
+++ b/js/src/jit-test/tests/asm.js/testZOOB.js
@@ -0,0 +1,232 @@
+// |jit-test|
+load(libdir + "asm.js");
+load(libdir + "asserts.js");
+
+if (!isAsmJSCompilationAvailable())
+ quit();
+
+var ab = new ArrayBuffer(BUF_MIN);
+
+// Compute a set of interesting indices.
+indices = [0]
+for (var i of [4,1024,BUF_MIN,Math.pow(2,30),Math.pow(2,31),Math.pow(2,32),Math.pow(2,33)]) {
+ for (var j of [-2,-1,0,1,2]) {
+ for (var k of [1,-1])
+ indices.push((i+j)*k);
+ }
+}
+
+function testInt(ctor, shift, scale, disp) {
+ var arr = new ctor(ab);
+
+ var c = asmCompile('glob', 'imp', 'b',
+ USE_ASM +
+ 'var arr=new glob.' + ctor.name + '(b); ' +
+ 'function load(i) {i=i|0; return arr[((i<<' + scale + ')+' + disp + ')>>' + shift + ']|0 } ' +
+ 'function store(i,j) {i=i|0;j=j|0; arr[((i<<' + scale + ')+' + disp + ')>>' + shift + '] = j } ' +
+ 'function storeZero(i) {i=i|0; arr[((i<<' + scale + ')+' + disp + ')>>' + shift + '] = 0 } ' +
+ 'function storeNegOne(i) {i=i|0; arr[((i<<' + scale + ')+' + disp + ')>>' + shift + '] = -1 } ' +
+ 'return { load: load, store: store, storeZero: storeZero, storeNegOne: storeNegOne }');
+ var f = asmLink(c, this, null, ab);
+
+ var v = arr[0];
+ arr[0] = -1;
+ var negOne = arr[0]|0;
+ arr[0] = v;
+
+ for (var i of indices) {
+ var index = ((i<<scale)+disp)>>shift;
+ v = arr[index]|0;
+
+ // Loads
+ assertEq(f.load(i), v);
+
+ // Stores of immediates
+ arr[index] = 1;
+ f.storeZero(i);
+ assertEq(arr[index]|0, 0);
+ f.storeNegOne(i);
+ assertEq(arr[index]|0, index>>>0 < arr.length ? negOne : 0);
+
+ // Stores
+ arr[index] = ~v;
+ f.store(i, v);
+ assertEq(arr[index]|0, v);
+ }
+}
+
+function testFloat(ctor, shift, scale, disp, coercion) {
+ var arr = new ctor(ab);
+
+ var c = asmCompile('glob', 'imp', 'b',
+ USE_ASM +
+ 'var arr=new glob.' + ctor.name + '(b); ' +
+ 'var toF = glob.Math.fround; ' +
+ 'function load(i) {i=i|0; return ' + coercion + '(arr[((i<<' + scale + ')+' + disp + ')>>' + shift + ']) } ' +
+ 'function store(i,j) {i=i|0;j=+j; arr[((i<<' + scale + ')+' + disp + ')>>' + shift + '] = j } ' +
+ 'return { load: load, store: store }');
+ var f = asmLink(c, this, null, ab);
+
+ for (var i of indices) {
+ var index = ((i<<scale)+disp)>>shift;
+ var v = +arr[index];
+
+ // Loads
+ assertEq(f.load(i), v);
+
+ // Stores
+ arr[index] = ~v;
+ f.store(i, v);
+ assertEq(+arr[index], v);
+ }
+}
+
+function testFloat32(ctor, shift, scale, disp) {
+ testFloat(ctor, shift, scale, disp, "toF");
+}
+function testFloat64(ctor, shift, scale, disp) {
+ testFloat(ctor, shift, scale, disp, "+");
+}
+
+function assertEqX4(observed, expected) {
+ assertEq(observed.x, expected.x);
+ assertEq(observed.y, expected.y);
+ assertEq(observed.z, expected.z);
+ assertEq(observed.w, expected.w);
+}
+
+function testSimdX4(ctor, shift, scale, disp, simdName, simdCtor) {
+ var arr = new ctor(ab);
+
+ var c = asmCompile('glob', 'imp', 'b',
+ USE_ASM +
+ 'var arr=new glob.' + ctor.name + '(b); ' +
+ 'var SIMD_' + simdName + ' = glob.SIMD.' + simdName + '; ' +
+ 'var SIMD_' + simdName + '_check = SIMD_' + simdName + '.check; ' +
+ 'var SIMD_' + simdName + '_load = SIMD_' + simdName + '.load; ' +
+ 'var SIMD_' + simdName + '_load2 = SIMD_' + simdName + '.load2; ' +
+ 'var SIMD_' + simdName + '_load1 = SIMD_' + simdName + '.load1; ' +
+ 'var SIMD_' + simdName + '_store = SIMD_' + simdName + '.store; ' +
+ 'var SIMD_' + simdName + '_store2 = SIMD_' + simdName + '.store2; ' +
+ 'var SIMD_' + simdName + '_store1 = SIMD_' + simdName + '.store1; ' +
+ 'function load(i) {i=i|0; return SIMD_' + simdName + '_check(SIMD_' + simdName + '_load(arr, ((i<<' + scale + ')+' + disp + ')>>' + shift + ')) } ' +
+ 'function load2(i) {i=i|0; return SIMD_' + simdName + '_check(SIMD_' + simdName + '_load2(arr, ((i<<' + scale + ')+' + disp + ')>>' + shift + ')) } ' +
+ 'function load1(i) {i=i|0; return SIMD_' + simdName + '_check(SIMD_' + simdName + '_load1(arr, ((i<<' + scale + ')+' + disp + ')>>' + shift + ')) } ' +
+ 'function store(i,j) {i=i|0;j=SIMD_' + simdName + '_check(j); SIMD_' + simdName + '_store(arr, ((i<<' + scale + ')+' + disp + ')>>' + shift + ', j) } ' +
+ 'function store2(i,j) {i=i|0;j=SIMD_' + simdName + '_check(j); SIMD_' + simdName + '_store2(arr, ((i<<' + scale + ')+' + disp + ')>>' + shift + ', j) } ' +
+ 'function store1(i,j) {i=i|0;j=SIMD_' + simdName + '_check(j); SIMD_' + simdName + '_store1(arr, ((i<<' + scale + ')+' + disp + ')>>' + shift + ', j) } ' +
+ 'return { load: load, load2: load2, load1: load1, store: store, store2 : store2, store1 : store1 }');
+ var f = asmLink(c, this, null, ab);
+
+ const RuntimeError = WebAssembly.RuntimeError;
+
+ for (var i of indices) {
+ var index = ((i<<scale)+disp)>>shift;
+
+ var v, v2, v1;
+ var t = false, t2 = false, t1 = false;
+ try { v = simdCtor.load(arr, index); }
+ catch (e) {
+ assertEq(e instanceof RangeError, true);
+ t = true;
+ }
+ try { v2 = simdCtor.load2(arr, index); }
+ catch (e) {
+ assertEq(e instanceof RangeError, true);
+ t2 = true;
+ }
+ try { v1 = simdCtor.load1(arr, index); }
+ catch (e) {
+ assertEq(e instanceof RangeError, true);
+ t1 = true;
+ }
+
+ // Loads
+ var l, l2, l1;
+ var r = false, r2 = false, r1 = false;
+ try { l = f.load(i); }
+ catch (e) {
+ assertEq(e instanceof RuntimeError, true);
+ r = true;
+ }
+ try { l2 = f.load2(i); }
+ catch (e) {
+ assertEq(e instanceof RuntimeError, true);
+ r2 = true;
+ }
+ try { l1 = f.load1(i); }
+ catch (e) {
+ assertEq(e instanceof RuntimeError, true);
+ r1 = true;
+ }
+ assertEq(t, r);
+ assertEq(t2, r2);
+ assertEq(t1, r1);
+ if (!t) assertEqX4(v, l);
+ if (!t2) assertEqX4(v2, l2);
+ if (!t1) assertEqX4(v1, l1);
+
+ // Stores
+ if (!t) {
+ simdCtor.store(arr, index, simdCtor.neg(v));
+ f.store(i, v);
+ assertEqX4(simdCtor.load(arr, index), v);
+ } else
+ assertThrowsInstanceOf(() => f.store(i, simdCtor()), RuntimeError);
+ if (!t2) {
+ simdCtor.store2(arr, index, simdCtor.neg(v2));
+ f.store2(i, v2);
+ assertEqX4(simdCtor.load2(arr, index), v2);
+ } else
+ assertThrowsInstanceOf(() => f.store2(i, simdCtor()), RuntimeError);
+ if (!t1) {
+ simdCtor.store1(arr, index, simdCtor.neg(v1));
+ f.store1(i, v1);
+ assertEqX4(simdCtor.load1(arr, index), v1);
+ } else
+ assertThrowsInstanceOf(() => f.store1(i, simdCtor()), RuntimeError);
+ }
+}
+
+function testFloat32x4(ctor, shift, scale, disp) {
+ testSimdX4(ctor, shift, scale, disp, 'Float32x4', SIMD.Float32x4);
+}
+function testInt32x4(ctor, shift, scale, disp) {
+ testSimdX4(ctor, shift, scale, disp, 'Int32x4', SIMD.Int32x4);
+}
+
+function test(tester, ctor, shift) {
+ var arr = new ctor(ab);
+ for (var i = 0; i < arr.length; i++)
+ arr[i] = Math.imul(i, Math.imul((i & 1), 2) - 1);
+ for (scale of [0,1,2,3]) {
+ for (disp of [0,1,2,8,Math.pow(2,30),Math.pow(2,31)-1,Math.pow(2,31),Math.pow(2,32)-1])
+ tester(ctor, shift, scale, disp);
+ }
+ for (var i = 0; i < arr.length; i++) {
+ var v = arr[i];
+ arr[i] = Math.imul(i, Math.imul((i & 1), 2) - 1);
+ assertEq(arr[i], v);
+ }
+}
+
+test(testInt, Int8Array, 0);
+test(testInt, Uint8Array, 0);
+test(testInt, Int16Array, 1);
+test(testInt, Uint16Array, 1);
+test(testInt, Int32Array, 2);
+test(testInt, Uint32Array, 2);
+test(testFloat32, Float32Array, 2);
+test(testFloat64, Float64Array, 3);
+if (typeof SIMD !== 'undefined' && isSimdAvailable()) {
+ // Avoid pathological --ion-eager compile times due to bails in loops
+ setJitCompilerOption('ion.warmup.trigger', 1000000);
+
+ // Use a fresh ArrayBuffer so prepareForAsmJS can allocated a guard page
+ // which SIMD.js needs. Since the original ArrayBuffer was prepared for
+ // asm.js that didn't use SIMD.js, it has no guard page (on 32-bit).
+ ab = new ArrayBuffer(BUF_MIN);
+
+ test(testInt32x4, Uint8Array, 0);
+ test(testFloat32x4, Uint8Array, 0);
+}