From dc7e5b48a9ec6f7d35960343fc2686667b2c924b Mon Sep 17 00:00:00 2001 From: ProgramFOX Date: Tue, 7 Jul 2015 15:17:55 +0200 Subject: [PATCH] Bug 1124291 - SIMD (interpreter): Added test cases for int8x16 and int16x8. r=benj --- js/src/tests/ecma_7/SIMD/binary-operations.js | 150 ++++++++ js/src/tests/ecma_7/SIMD/check.js | 26 ++ js/src/tests/ecma_7/SIMD/comparisons.js | 116 +++++- js/src/tests/ecma_7/SIMD/constructors.js | 44 ++- js/src/tests/ecma_7/SIMD/conversions.js | 352 ++++++++++++++++++ js/src/tests/ecma_7/SIMD/int16x8bool.js | 24 ++ js/src/tests/ecma_7/SIMD/int8x16bool.js | 32 ++ js/src/tests/ecma_7/SIMD/load.js | 32 +- js/src/tests/ecma_7/SIMD/replaceLane.js | 76 +++- js/src/tests/ecma_7/SIMD/select-bitselect.js | 102 ++++- js/src/tests/ecma_7/SIMD/shell.js | 99 ++++- js/src/tests/ecma_7/SIMD/shifts.js | 80 +++- js/src/tests/ecma_7/SIMD/signmask.js | 30 ++ js/src/tests/ecma_7/SIMD/splat.js | 22 ++ js/src/tests/ecma_7/SIMD/store.js | 55 ++- js/src/tests/ecma_7/SIMD/swizzle-shuffle.js | 305 ++++++++++++--- js/src/tests/ecma_7/SIMD/typedobjects.js | 257 ++++++++++++- js/src/tests/ecma_7/SIMD/unary-operations.js | 48 +++ 18 files changed, 1713 insertions(+), 137 deletions(-) create mode 100644 js/src/tests/ecma_7/SIMD/int16x8bool.js create mode 100644 js/src/tests/ecma_7/SIMD/int8x16bool.js diff --git a/js/src/tests/ecma_7/SIMD/binary-operations.js b/js/src/tests/ecma_7/SIMD/binary-operations.js index ea2eb5c9ea1..b6d6077618d 100644 --- a/js/src/tests/ecma_7/SIMD/binary-operations.js +++ b/js/src/tests/ecma_7/SIMD/binary-operations.js @@ -1,5 +1,7 @@ // |reftest| skip-if(!this.hasOwnProperty("SIMD")) var float32x4 = SIMD.float32x4; +var int8x16 = SIMD.int8x16; +var int16x8 = SIMD.int16x8; var int32x4 = SIMD.int32x4; @@ -136,6 +138,140 @@ function testFloat32x4xor() { } } +var i8x16vals = [ + [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], + [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160]], + [[INT8_MAX, INT8_MIN, INT8_MAX, INT8_MIN, INT8_MAX, INT8_MIN, INT8_MAX, INT8_MIN, -2, -3, -4, -5, -6, -7, -8, -9], + [1, 1, -1, -1, INT8_MAX, INT8_MAX, INT8_MIN, INT8_MIN, 8, 9, 10, 11, 12, 13, 14, 15]] +]; + +function testInt8x16add() { + function addi(a, b) { + return (a + b) << 24 >> 24; + } + + for (var [v,w] of i8x16vals) { + testBinaryFunc(int8x16(...v), int8x16(...w), int8x16.add, addi); + } +} + +function testInt8x16and() { + function andi(a, b) { + return (a & b) << 24 >> 24; + } + + for (var [v,w] of i8x16vals) { + testBinaryFunc(int8x16(...v), int8x16(...w), int8x16.and, andi); + } +} + +function testInt8x16mul() { + function muli(x, y) { + return (x * y) << 24 >> 24; + } + + for (var [v,w] of i8x16vals) { + testBinaryFunc(int8x16(...v), int8x16(...w), int8x16.mul, muli); + } +} + +function testInt8x16or() { + function ori(a, b) { + return (a | b) << 24 >> 24; + } + + for (var [v,w] of i8x16vals) { + testBinaryFunc(int8x16(...v), int8x16(...w), int8x16.or, ori); + } +} + +function testInt8x16sub() { + function subi(a, b) { + return (a - b) << 24 >> 24; + } + + for (var [v,w] of i8x16vals) { + testBinaryFunc(int8x16(...v), int8x16(...w), int8x16.sub, subi); + } +} + +function testInt8x16xor() { + function xori(a, b) { + return (a ^ b) << 24 >> 24; + } + + for (var [v,w] of i8x16vals) { + testBinaryFunc(int8x16(...v), int8x16(...w), int8x16.xor, xori); + } +} + +var i16x8vals = [ + [[1, 2, 3, 4, 5, 6, 7, 8], + [10, 20, 30, 40, 50, 60, 70, 80]], + [[INT16_MAX, INT16_MIN, INT16_MAX, INT16_MIN, INT16_MAX, INT16_MIN, INT16_MAX, INT16_MIN], + [1, 1, -1, -1, INT16_MAX, INT16_MAX, INT16_MIN, INT16_MIN]] +]; + +function testInt16x8add() { + function addi(a, b) { + return (a + b) << 16 >> 16; + } + + for (var [v,w] of i16x8vals) { + testBinaryFunc(int16x8(...v), int16x8(...w), int16x8.add, addi); + } +} + +function testInt16x8and() { + function andi(a, b) { + return (a & b) << 16 >> 16; + } + + for (var [v,w] of i16x8vals) { + testBinaryFunc(int16x8(...v), int16x8(...w), int16x8.and, andi); + } +} + +function testInt16x8mul() { + function muli(x, y) { + return (x * y) << 16 >> 16; + } + + for (var [v,w] of i16x8vals) { + testBinaryFunc(int16x8(...v), int16x8(...w), int16x8.mul, muli); + } +} + +function testInt16x8or() { + function ori(a, b) { + return (a | b) << 16 >> 16; + } + + for (var [v,w] of i16x8vals) { + testBinaryFunc(int16x8(...v), int16x8(...w), int16x8.or, ori); + } +} + +function testInt16x8sub() { + function subi(a, b) { + return (a - b) << 16 >> 16; + } + + for (var [v,w] of i16x8vals) { + testBinaryFunc(int16x8(...v), int16x8(...w), int16x8.sub, subi); + } +} + +function testInt16x8xor() { + function xori(a, b) { + return (a ^ b) << 16 >> 16; + } + + for (var [v,w] of i16x8vals) { + testBinaryFunc(int16x8(...v), int16x8(...w), int16x8.xor, xori); + } +} + function testInt32x4add() { function addi(a, b) { return (a + b) | 0; @@ -235,6 +371,20 @@ function test() { testFloat32x4sub(); testFloat32x4xor(); + testInt8x16add(); + testInt8x16and(); + testInt8x16mul(); + testInt8x16or(); + testInt8x16sub(); + testInt8x16xor(); + + testInt16x8add(); + testInt16x8and(); + testInt16x8mul(); + testInt16x8or(); + testInt16x8sub(); + testInt16x8xor(); + testInt32x4add(); testInt32x4and(); testInt32x4mul(); diff --git a/js/src/tests/ecma_7/SIMD/check.js b/js/src/tests/ecma_7/SIMD/check.js index 23a7b11b2e8..dce8464cd13 100644 --- a/js/src/tests/ecma_7/SIMD/check.js +++ b/js/src/tests/ecma_7/SIMD/check.js @@ -3,6 +3,8 @@ function test() { var i4 = SIMD.int32x4(1,2,3,4); + var i8 = SIMD.int16x8(1,2,3,4,5,6,7,8); + var i16 = SIMD.int8x16(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16); var f4 = SIMD.float32x4(NaN, -0, Infinity, 13.37); var f2 = SIMD.float64x2(-0, 13.37); @@ -10,12 +12,34 @@ function test() { assertEqX4(ci4, simdToArray(i4)); assertThrowsInstanceOf(() => SIMD.int32x4.check(f4), TypeError); assertThrowsInstanceOf(() => SIMD.int32x4.check(f2), TypeError); + assertThrowsInstanceOf(() => SIMD.int32x4.check(i8), TypeError); + assertThrowsInstanceOf(() => SIMD.int32x4.check(i16), TypeError); assertThrowsInstanceOf(() => SIMD.int32x4.check("i swear i'm a vector"), TypeError); assertThrowsInstanceOf(() => SIMD.int32x4.check({}), TypeError); + var ci8 = SIMD.int16x8.check(i8); + assertEqX8(ci8, simdToArray(i8)); + assertThrowsInstanceOf(() => SIMD.int16x8.check(i4), TypeError); + assertThrowsInstanceOf(() => SIMD.int16x8.check(i16), TypeError); + assertThrowsInstanceOf(() => SIMD.int16x8.check(f4), TypeError); + assertThrowsInstanceOf(() => SIMD.int16x8.check(f2), TypeError); + assertThrowsInstanceOf(() => SIMD.int16x8.check("i swear i'm a vector"), TypeError); + assertThrowsInstanceOf(() => SIMD.int16x8.check({}), TypeError); + + var ci16 = SIMD.int8x16.check(i16); + assertEqX16(ci16, simdToArray(i16)); + assertThrowsInstanceOf(() => SIMD.int8x16.check(i4), TypeError); + assertThrowsInstanceOf(() => SIMD.int8x16.check(i8), TypeError); + assertThrowsInstanceOf(() => SIMD.int8x16.check(f4), TypeError); + assertThrowsInstanceOf(() => SIMD.int8x16.check(f2), TypeError); + assertThrowsInstanceOf(() => SIMD.int8x16.check("i swear i'm a vector"), TypeError); + assertThrowsInstanceOf(() => SIMD.int8x16.check({}), TypeError); + var cf4 = SIMD.float32x4.check(f4); assertEqX4(cf4, simdToArray(f4)); assertThrowsInstanceOf(() => SIMD.float32x4.check(i4), TypeError); + assertThrowsInstanceOf(() => SIMD.float32x4.check(i8), TypeError); + assertThrowsInstanceOf(() => SIMD.float32x4.check(i16), TypeError); assertThrowsInstanceOf(() => SIMD.float32x4.check(f2), TypeError); assertThrowsInstanceOf(() => SIMD.float32x4.check("i swear i'm a vector"), TypeError); assertThrowsInstanceOf(() => SIMD.float32x4.check({}), TypeError); @@ -24,6 +48,8 @@ function test() { assertEqX2(cf2, simdToArray(f2)); assertThrowsInstanceOf(() => SIMD.float64x2.check(f4), TypeError); assertThrowsInstanceOf(() => SIMD.float64x2.check(i4), TypeError); + assertThrowsInstanceOf(() => SIMD.float64x2.check(i8), TypeError); + assertThrowsInstanceOf(() => SIMD.float64x2.check(i16), TypeError); assertThrowsInstanceOf(() => SIMD.float64x2.check("i swear i'm a vector"), TypeError); assertThrowsInstanceOf(() => SIMD.float64x2.check({}), TypeError); diff --git a/js/src/tests/ecma_7/SIMD/comparisons.js b/js/src/tests/ecma_7/SIMD/comparisons.js index 19369867de1..9c79db18ea4 100644 --- a/js/src/tests/ecma_7/SIMD/comparisons.js +++ b/js/src/tests/ecma_7/SIMD/comparisons.js @@ -7,6 +7,8 @@ var float32x4 = SIMD.float32x4; var float64x2 = SIMD.float64x2; +var int8x16 = SIMD.int8x16; +var int16x8 = SIMD.int16x8; var int32x4 = SIMD.int32x4; var fround = Math.fround; @@ -16,60 +18,98 @@ function boolToSimdLogical(b) { } function testEqualFloat32x4(v, w) { - testBinaryCompare(v, w, float32x4.equal, (x, y) => boolToSimdLogical(fround(x) == fround(y))); + testBinaryCompare(v, w, float32x4.equal, (x, y) => boolToSimdLogical(fround(x) == fround(y)), int32x4); } function testNotEqualFloat32x4(v, w) { - testBinaryCompare(v, w, float32x4.notEqual, (x, y) => boolToSimdLogical(fround(x) != fround(y))); + testBinaryCompare(v, w, float32x4.notEqual, (x, y) => boolToSimdLogical(fround(x) != fround(y)), int32x4); } function testLessThanFloat32x4(v, w) { - testBinaryCompare(v, w, float32x4.lessThan, (x, y) => boolToSimdLogical(fround(x) < fround(y))); + testBinaryCompare(v, w, float32x4.lessThan, (x, y) => boolToSimdLogical(fround(x) < fround(y)), int32x4); } function testLessThanOrEqualFloat32x4(v, w) { - testBinaryCompare(v, w, float32x4.lessThanOrEqual, (x, y) => boolToSimdLogical(fround(x) <= fround(y))); + testBinaryCompare(v, w, float32x4.lessThanOrEqual, (x, y) => boolToSimdLogical(fround(x) <= fround(y)), int32x4); } function testGreaterThanFloat32x4(v, w) { - testBinaryCompare(v, w, float32x4.greaterThan, (x, y) => boolToSimdLogical(fround(x) > fround(y))); + testBinaryCompare(v, w, float32x4.greaterThan, (x, y) => boolToSimdLogical(fround(x) > fround(y)), int32x4); } function testGreaterThanOrEqualFloat32x4(v, w) { - testBinaryCompare(v, w, float32x4.greaterThanOrEqual, (x, y) => boolToSimdLogical(fround(x) >= fround(y))); + testBinaryCompare(v, w, float32x4.greaterThanOrEqual, (x, y) => boolToSimdLogical(fround(x) >= fround(y)), int32x4); } function testEqualFloat64x2(v, w) { - testBinaryCompare(v, w, float64x2.equal, (x, y) => boolToSimdLogical(x == y)); + testBinaryCompare(v, w, float64x2.equal, (x, y) => boolToSimdLogical(x == y), int32x4); } function testNotEqualFloat64x2(v, w) { - testBinaryCompare(v, w, float64x2.notEqual, (x, y) => boolToSimdLogical(x != y)); + testBinaryCompare(v, w, float64x2.notEqual, (x, y) => boolToSimdLogical(x != y), int32x4); } function testLessThanFloat64x2(v, w) { - testBinaryCompare(v, w, float64x2.lessThan, (x, y) => boolToSimdLogical(x < y)); + testBinaryCompare(v, w, float64x2.lessThan, (x, y) => boolToSimdLogical(x < y), int32x4); } function testLessThanOrEqualFloat64x2(v, w) { - testBinaryCompare(v, w, float64x2.lessThanOrEqual, (x, y) => boolToSimdLogical(x <= y)); + testBinaryCompare(v, w, float64x2.lessThanOrEqual, (x, y) => boolToSimdLogical(x <= y), int32x4); } function testGreaterThanFloat64x2(v, w) { - testBinaryCompare(v, w, float64x2.greaterThan, (x, y) => boolToSimdLogical(x > y)); + testBinaryCompare(v, w, float64x2.greaterThan, (x, y) => boolToSimdLogical(x > y), int32x4); } function testGreaterThanOrEqualFloat64x2(v, w) { - testBinaryCompare(v, w, float64x2.greaterThanOrEqual, (x, y) => boolToSimdLogical(x >= y)); + testBinaryCompare(v, w, float64x2.greaterThanOrEqual, (x, y) => boolToSimdLogical(x >= y), int32x4); +} + +function testEqualInt8x16(v, w) { + testBinaryCompare(v, w, int8x16.equal, (x, y) => boolToSimdLogical(x == y), int8x16); +} +function testNotEqualInt8x16(v, w) { + testBinaryCompare(v, w, int8x16.notEqual, (x, y) => boolToSimdLogical(x != y), int8x16); +} +function testLessThanInt8x16(v, w) { + testBinaryCompare(v, w, int8x16.lessThan, (x, y) => boolToSimdLogical(x < y), int8x16); +} +function testLessThanOrEqualInt8x16(v, w) { + testBinaryCompare(v, w, int8x16.lessThanOrEqual, (x, y) => boolToSimdLogical(x <= y), int8x16); +} +function testGreaterThanInt8x16(v, w) { + testBinaryCompare(v, w, int8x16.greaterThan, (x, y) => boolToSimdLogical(x > y), int8x16); +} +function testGreaterThanOrEqualInt8x16(v, w) { + testBinaryCompare(v, w, int8x16.greaterThanOrEqual, (x, y) => boolToSimdLogical(x >= y), int8x16); +} + +function testEqualInt16x8(v, w) { + testBinaryCompare(v, w, int16x8.equal, (x, y) => boolToSimdLogical(x == y), int16x8); +} +function testNotEqualInt16x8(v, w) { + testBinaryCompare(v, w, int16x8.notEqual, (x, y) => boolToSimdLogical(x != y), int16x8); +} +function testLessThanInt16x8(v, w) { + testBinaryCompare(v, w, int16x8.lessThan, (x, y) => boolToSimdLogical(x < y), int16x8); +} +function testLessThanOrEqualInt16x8(v, w) { + testBinaryCompare(v, w, int16x8.lessThanOrEqual, (x, y) => boolToSimdLogical(x <= y), int16x8); +} +function testGreaterThanInt16x8(v, w) { + testBinaryCompare(v, w, int16x8.greaterThan, (x, y) => boolToSimdLogical(x > y), int16x8); +} +function testGreaterThanOrEqualInt16x8(v, w) { + testBinaryCompare(v, w, int16x8.greaterThanOrEqual, (x, y) => boolToSimdLogical(x >= y), int16x8); } function testEqualInt32x4(v, w) { - testBinaryCompare(v, w, int32x4.equal, (x, y) => boolToSimdLogical(x == y)); + testBinaryCompare(v, w, int32x4.equal, (x, y) => boolToSimdLogical(x == y), int32x4); } function testNotEqualInt32x4(v, w) { - testBinaryCompare(v, w, int32x4.notEqual, (x, y) => boolToSimdLogical(x != y)); + testBinaryCompare(v, w, int32x4.notEqual, (x, y) => boolToSimdLogical(x != y), int32x4); } function testLessThanInt32x4(v, w) { - testBinaryCompare(v, w, int32x4.lessThan, (x, y) => boolToSimdLogical(x < y)); + testBinaryCompare(v, w, int32x4.lessThan, (x, y) => boolToSimdLogical(x < y), int32x4); } function testLessThanOrEqualInt32x4(v, w) { - testBinaryCompare(v, w, int32x4.lessThanOrEqual, (x, y) => boolToSimdLogical(x <= y)); + testBinaryCompare(v, w, int32x4.lessThanOrEqual, (x, y) => boolToSimdLogical(x <= y), int32x4); } function testGreaterThanInt32x4(v, w) { - testBinaryCompare(v, w, int32x4.greaterThan, (x, y) => boolToSimdLogical(x > y)); + testBinaryCompare(v, w, int32x4.greaterThan, (x, y) => boolToSimdLogical(x > y), int32x4); } function testGreaterThanOrEqualInt32x4(v, w) { - testBinaryCompare(v, w, int32x4.greaterThanOrEqual, (x, y) => boolToSimdLogical(x >= y)); + testBinaryCompare(v, w, int32x4.greaterThanOrEqual, (x, y) => boolToSimdLogical(x >= y), int32x4); } function test() { @@ -121,6 +161,46 @@ function test() { } } + var int8x16val = [ + int8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), + int8x16(-1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16), + int8x16(-1, 2, -3, 4, -5, 6, -7, 8, -9, 10, -11, 12, -13, 14, -15, 16), + int8x16(1, -2, 3, -4, 5, -6, 7, -8, 9, -10, 11, -12, 13, -14, 15, -16), + int8x16(INT8_MAX, INT8_MAX, INT8_MIN, INT8_MIN, INT8_MIN + 1, INT8_MAX - 1, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16), + int8x16(INT8_MAX, INT8_MIN, INT8_MAX, INT8_MIN, INT8_MAX - 1, INT8_MIN + 1, 7, 8, 9, 10, 11, 12, 13, 14, 15, -16) + ]; + + for (v of int8x16val) { + for (w of int8x16val) { + testEqualInt8x16(v, w); + testNotEqualInt8x16(v, w); + testLessThanInt8x16(v, w); + testLessThanOrEqualInt8x16(v, w); + testGreaterThanInt8x16(v, w); + testGreaterThanOrEqualInt8x16(v, w); + } + } + + var int16x8val = [ + int16x8(1, 2, 3, 4, 5, 6, 7, 8), + int16x8(-1, -2, -3, -4, -5, -6, -7, -8), + int16x8(-1, 2, -3, 4, -5, 6, -7, 8), + int16x8(1, -2, 3, -4, 5, -6, 7, -8), + int16x8(INT16_MAX, INT16_MAX, INT16_MIN, INT16_MIN, INT16_MIN + 1, INT16_MAX - 1, -7, -8), + int16x8(INT16_MAX, INT16_MIN, INT16_MAX, INT16_MIN, INT16_MAX - 1, INT16_MIN + 1, 7, -8) + ]; + + for (v of int16x8val) { + for (w of int16x8val) { + testEqualInt16x8(v, w); + testNotEqualInt16x8(v, w); + testLessThanInt16x8(v, w); + testLessThanOrEqualInt16x8(v, w); + testGreaterThanInt16x8(v, w); + testGreaterThanOrEqualInt16x8(v, w); + } + } + var int32x4val = [ int32x4(1, 2, 3, 4), int32x4(-1, -2, -3, -4), diff --git a/js/src/tests/ecma_7/SIMD/constructors.js b/js/src/tests/ecma_7/SIMD/constructors.js index a48e57f6473..4d75f2035ca 100644 --- a/js/src/tests/ecma_7/SIMD/constructors.js +++ b/js/src/tests/ecma_7/SIMD/constructors.js @@ -2,8 +2,48 @@ var float64x2 = SIMD.float64x2; var float32x4 = SIMD.float32x4; +var int8x16 = SIMD.int8x16; +var int16x8 = SIMD.int16x8; var int32x4 = SIMD.int32x4; +function TestInt8x16Ctor() { + // Constructors. + assertEqX16(int8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]); + assertEqX16(int8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15), [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0]); + assertEqX16(int8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14), [1,2,3,4,5,6,7,8,9,10,11,12,13,14,0,0]); + assertEqX16(int8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13), [1,2,3,4,5,6,7,8,9,10,11,12,13,0,0,0]); + assertEqX16(int8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12), [1,2,3,4,5,6,7,8,9,10,11,12,0,0,0,0]); + assertEqX16(int8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11), [1,2,3,4,5,6,7,8,9,10,11,0,0,0,0,0]); + assertEqX16(int8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), [1,2,3,4,5,6,7,8,9,10,0,0,0,0,0,0]); + assertEqX16(int8x16(1, 2, 3, 4, 5, 6, 7, 8, 9), [1,2,3,4,5,6,7,8,9,0,0,0,0,0,0,0]); + assertEqX16(int8x16(1, 2, 3, 4, 5, 6, 7, 8), [1,2,3,4,5,6,7,8,0,0,0,0,0,0,0,0]); + assertEqX16(int8x16(1, 2, 3, 4, 5, 6, 7), [1,2,3,4,5,6,7,0,0,0,0,0,0,0,0,0]); + assertEqX16(int8x16(1, 2, 3, 4, 5, 6), [1,2,3,4,5,6,0,0,0,0,0,0,0,0,0,0]); + assertEqX16(int8x16(1, 2, 3, 4, 5), [1,2,3,4,5,0,0,0,0,0,0,0,0,0,0,0]); + assertEqX16(int8x16(1, 2, 3, 4), [1,2,3,4,0,0,0,0,0,0,0,0,0,0,0,0]); + assertEqX16(int8x16(1, 2, 3), [1,2,3,0,0,0,0,0,0,0,0,0,0,0,0,0]); + assertEqX16(int8x16(1, 2), [1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0]); + assertEqX16(int8x16(1), [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]); + assertEqX16(int8x16(), [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]); + assertEqX16(int8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17), [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]); + assertEqX16(int8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18), [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]); +} + +function TestInt16x8Ctor() { + // Constructors. + assertEqX8(int16x8(1, 2, 3, 4, 5, 6, 7, 8), [1,2,3,4,5,6,7,8]); + assertEqX8(int16x8(1, 2, 3, 4, 5, 6, 7), [1,2,3,4,5,6,7,0]); + assertEqX8(int16x8(1, 2, 3, 4, 5, 6), [1,2,3,4,5,6,0,0]); + assertEqX8(int16x8(1, 2, 3, 4, 5), [1,2,3,4,5,0,0,0]); + assertEqX8(int16x8(1, 2, 3, 4), [1,2,3,4,0,0,0,0]); + assertEqX8(int16x8(1, 2, 3), [1,2,3,0,0,0,0,0]); + assertEqX8(int16x8(1, 2), [1,2,0,0,0,0,0,0]); + assertEqX8(int16x8(1), [1,0,0,0,0,0,0,0]); + assertEqX8(int16x8(), [0,0,0,0,0,0,0,0]); + assertEqX8(int16x8(1, 2, 3, 4, 5, 6, 7, 8, 9), [1,2,3,4,5,6,7,8]); + assertEqX8(int16x8(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), [1,2,3,4,5,6,7,8]); +} + function TestInt32x4Ctor() { // Constructors. assertEqX4(int32x4(1, 2, 3, 4), [1,2,3,4]); @@ -38,8 +78,10 @@ function TestFloat64x2Ctor() { function test() { TestFloat32x4Ctor(); - TestInt32x4Ctor(); TestFloat64x2Ctor(); + TestInt8x16Ctor(); + TestInt16x8Ctor(); + TestInt32x4Ctor(); if (typeof reportCompare === "function") reportCompare(true, true); } diff --git a/js/src/tests/ecma_7/SIMD/conversions.js b/js/src/tests/ecma_7/SIMD/conversions.js index 14a486a1f5d..45a82b3ce72 100644 --- a/js/src/tests/ecma_7/SIMD/conversions.js +++ b/js/src/tests/ecma_7/SIMD/conversions.js @@ -1,6 +1,8 @@ // |reftest| skip-if(!this.hasOwnProperty("SIMD")) var float32x4 = SIMD.float32x4; var float64x2 = SIMD.float64x2; +var int8x16 = SIMD.int8x16; +var int16x8 = SIMD.int16x8; var int32x4 = SIMD.int32x4; function testFloat32x4FromFloat64x2() { @@ -75,6 +77,61 @@ function testFloat32x4FromFloat64x2Bits() { } } +function testFloat32x4FromInt8x16Bits() { + function expected(v) { + var i8 = new Int8Array(16); + var f32 = new Float32Array(i8.buffer); + i8[0] = v.s0; + i8[1] = v.s1; + i8[2] = v.s2; + i8[3] = v.s3; + i8[4] = v.s4; + i8[5] = v.s5; + i8[6] = v.s6; + i8[7] = v.s7; + i8[8] = v.s8; + i8[9] = v.s9; + i8[10] = v.s10; + i8[11] = v.s11; + i8[12] = v.s12; + i8[13] = v.s13; + i8[14] = v.s14; + i8[15] = v.s15; + return [f32[0], f32[1], f32[2], f32[3]]; + } + + var vals = [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], + [INT8_MIN, INT8_MAX, INT8_MIN, INT8_MAX, INT8_MIN, INT8_MAX, INT8_MIN, INT8_MAX, + INT8_MAX, INT8_MIN, INT8_MAX, INT8_MIN, INT8_MAX, INT8_MIN, INT8_MAX, INT8_MIN]]; + for (var v of vals) { + var i = int8x16(...v); + assertEqX4(float32x4.fromInt8x16Bits(i), expected(i)); + } +} + +function testFloat32x4FromInt16x8Bits() { + function expected(v) { + var i16 = new Int16Array(8); + var f32 = new Float32Array(i16.buffer); + i16[0] = v.s0; + i16[1] = v.s1; + i16[2] = v.s2; + i16[3] = v.s3; + i16[4] = v.s4; + i16[5] = v.s5; + i16[6] = v.s6; + i16[7] = v.s7; + return [f32[0], f32[1], f32[2], f32[3]]; + } + + var vals = [[1, 2, 3, 4, 5, 6, 7, 8], + [INT16_MIN, INT16_MAX, INT16_MIN, INT16_MAX, INT16_MIN, INT16_MAX, INT16_MIN, INT16_MAX]]; + for (var v of vals) { + var i = int16x8(...v); + assertEqX4(float32x4.fromInt16x8Bits(i), expected(i)); + } +} + function testFloat32x4FromInt32x4() { function expected(v) { return v.map(Math.fround); @@ -167,6 +224,63 @@ function testFloat64x2FromFloat32x4Bits() { } } +function testFloat64x2FromInt8x16Bits() { + function expected(v) { + var i8 = Int8Array(16); + var f64 = Float64Array(i8.buffer); + i8[0] = v.s0; + i8[1] = v.s1; + i8[2] = v.s2; + i8[3] = v.s3; + i8[4] = v.s4; + i8[5] = v.s5; + i8[6] = v.s6; + i8[7] = v.s7; + i8[8] = v.s8; + i8[9] = v.s9; + i8[10] = v.s10; + i8[11] = v.s11; + i8[12] = v.s12; + i8[13] = v.s13; + i8[14] = v.s14; + i8[15] = v.s15; + return [f64[0], f64[1]]; + } + + var vals = [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], + [INT8_MIN, INT8_MAX, INT8_MIN, INT8_MAX, INT8_MIN, INT8_MAX, INT8_MIN, INT8_MAX, + INT8_MAX, INT8_MIN, INT8_MAX, INT8_MIN, INT8_MAX, INT8_MIN, INT8_MAX, INT8_MIN]]; + + for (var v of vals) { + var f = int8x16(...v); + assertEqX2(float64x2.fromInt8x16Bits(f), expected(f)); + } +} + +function testFloat64x2FromInt16x8Bits() { + function expected(v) { + var i16 = Int16Array(8); + var f64 = Float64Array(i16.buffer); + i16[0] = v.s0; + i16[1] = v.s1; + i16[2] = v.s2; + i16[3] = v.s3; + i16[4] = v.s4; + i16[5] = v.s5; + i16[6] = v.s6; + i16[7] = v.s7; + return [f64[0], f64[1]]; + } + + var vals = [[1, 2, 3, 4, 5, 6, 7, 8], + [INT16_MIN, INT16_MAX, INT16_MIN, INT16_MAX, INT16_MIN, INT16_MAX, INT16_MIN, INT16_MAX]]; + + for (var v of vals) { + var f = int16x8(...v); + assertEqX2(float64x2.fromInt16x8Bits(f), expected(f)); + } +} + function testFloat64x2FromInt32x4() { function expected(v) { return v.slice(0, 2); @@ -285,21 +399,259 @@ function testInt32x4FromFloat64x2Bits() { } } +function testInt32x4FromInt8x16Bits() { + function expected(v) { + var i8 = Int8Array(16); + var i32 = Int32Array(i8.buffer); + i8[0] = v.s0; + i8[1] = v.s1; + i8[2] = v.s2; + i8[3] = v.s3; + i8[4] = v.s4; + i8[5] = v.s5; + i8[6] = v.s6; + i8[7] = v.s7; + i8[8] = v.s8; + i8[9] = v.s9; + i8[10] = v.s10; + i8[11] = v.s11; + i8[12] = v.s12; + i8[13] = v.s13; + i8[14] = v.s14; + i8[15] = v.s15; + return [i32[0], i32[1], i32[2], i32[3]]; + } + + var vals = [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], + [INT8_MIN, INT8_MAX, INT8_MIN, INT8_MAX, INT8_MIN, INT8_MAX, INT8_MIN, INT8_MAX, + INT8_MAX, INT8_MIN, INT8_MAX, INT8_MIN, INT8_MAX, INT8_MIN, INT8_MAX, INT8_MIN]]; + + for (var v of vals) { + var i = int8x16(...v); + assertEqX4(int32x4.fromInt8x16Bits(i), expected(i)); + } +} + +function testInt32x4FromInt16x8Bits() { + function expected(v) { + var i16 = Int16Array(8); + var i32 = Int32Array(i16.buffer); + i16[0] = v.s0; + i16[1] = v.s1; + i16[2] = v.s2; + i16[3] = v.s3; + i16[4] = v.s4; + i16[5] = v.s5; + i16[6] = v.s6; + i16[7] = v.s7; + return [i32[0], i32[1], i32[2], i32[3]]; + } + + var vals = [[1, 2, 3, 4, 5, 6, 7, 8], + [INT16_MIN, INT16_MAX, INT16_MIN, INT16_MAX, INT16_MIN, INT16_MAX, INT16_MIN, INT16_MAX]]; + + for (var v of vals) { + var i = int16x8(...v); + assertEqX4(int32x4.fromInt16x8Bits(i), expected(i)); + } +} + +function testInt8x16FromFloat32x4Bits() { + function expected(v) { + var f32 = Float32Array(4); + var i8 = Int8Array(f32.buffer); + f32[0] = v.x; + f32[1] = v.y; + f32[2] = v.z; + f32[3] = v.w; + return [i8[0], i8[1], i8[2], i8[3], i8[4], i8[5], i8[6], i8[7], + i8[8], i8[9], i8[10], i8[11], i8[12], i8[13], i8[14], i8[15]]; + } + + var vals = [[1, -2, 3, -4], [Infinity, -Infinity, NaN, -0]]; + + for (var v of vals) { + var f = float32x4(...v); + assertEqX16(int8x16.fromFloat32x4Bits(f), expected(f)); + } +} + +function testInt8x16FromFloat64x2Bits() { + function expected(v) { + var f64 = Float64Array(2); + var i8 = Int8Array(f64.buffer); + f64[0] = v.x; + f64[1] = v.y; + return [i8[0], i8[1], i8[2], i8[3], i8[4], i8[5], i8[6], i8[7], + i8[8], i8[9], i8[10], i8[11], i8[12], i8[13], i8[14], i8[15]]; + } + var vals = [[1, -2], [-3, 4], [Infinity, -Infinity], [NaN, -0]]; + + for (var v of vals) { + var f = float64x2(...v); + assertEqX16(int8x16.fromFloat64x2Bits(f), expected(f)); + } +} + +function testInt8x16FromInt16x8Bits() { + function expected(v) { + var i16 = Int16Array(8); + var i8 = Int8Array(i16.buffer); + i16[0] = v.s0; + i16[1] = v.s1; + i16[2] = v.s2; + i16[3] = v.s3; + i16[4] = v.s4; + i16[5] = v.s5; + i16[6] = v.s6; + i16[7] = v.s7; + return [i8[0], i8[1], i8[2], i8[3], i8[4], i8[5], i8[6], i8[7], + i8[8], i8[9], i8[10], i8[11], i8[12], i8[13], i8[14], i8[15]]; + } + + var vals = [[0, 1, -2, 3, INT8_MIN, INT8_MAX, INT16_MIN, INT16_MAX]]; + for (var v of vals) { + var i = int16x8(...v); + assertEqX16(int8x16.fromInt16x8Bits(i), expected(i)); + } +} + +function testInt8x16FromInt32x4Bits() { + function expected(v) { + var i32 = Int32Array(4); + var i8 = Int8Array(i32.buffer); + i32[0] = v.x; + i32[1] = v.y; + i32[2] = v.z; + i32[3] = v.w; + return [i8[0], i8[1], i8[2], i8[3], i8[4], i8[5], i8[6], i8[7], + i8[8], i8[9], i8[10], i8[11], i8[12], i8[13], i8[14], i8[15]]; + } + + var vals = [[0, 1, -2, 3], [INT8_MIN, INT8_MAX, INT32_MIN, INT32_MAX]]; + for (var v of vals) { + var i = int32x4(...v); + assertEqX16(int8x16.fromInt32x4Bits(i), expected(i)); + } +} + +function testInt16x8FromFloat32x4Bits() { + function expected(v) { + var f32 = Float32Array(4); + var i16 = Int16Array(f32.buffer); + f32[0] = v.x; + f32[1] = v.y; + f32[2] = v.z; + f32[3] = v.w; + return [i16[0], i16[1], i16[2], i16[3], i16[4], i16[5], i16[6], i16[7]]; + } + + var vals = [[1, -2, 3, -4], [Infinity, -Infinity, NaN, -0]]; + + for (var v of vals) { + var f = float32x4(...v); + assertEqX8(int16x8.fromFloat32x4Bits(f), expected(f)); + } +} + +function testInt16x8FromFloat64x2Bits() { + function expected(v) { + var f64 = Float64Array(2); + var i16 = Int16Array(f64.buffer); + f64[0] = v.x; + f64[1] = v.y; + return [i16[0], i16[1], i16[2], i16[3], i16[4], i16[5], i16[6], i16[7]]; + } + + var vals = [[1, -2], [-3, 4], [Infinity, -Infinity], [NaN, -0]]; + + for (var v of vals) { + var f = float64x2(...v); + assertEqX8(int16x8.fromFloat64x2Bits(f), expected(f)); + } +} + +function testInt16x8FromInt8x16Bits() { + function expected(v) { + var i8 = Int8Array(16); + var i16 = Int16Array(i8.buffer); + i8[0] = v.s0; + i8[1] = v.s1; + i8[2] = v.s2; + i8[3] = v.s3; + i8[4] = v.s4; + i8[5] = v.s5; + i8[6] = v.s6; + i8[7] = v.s7; + i8[8] = v.s8; + i8[9] = v.s9; + i8[10] = v.s10; + i8[11] = v.s11; + i8[12] = v.s12; + i8[13] = v.s13; + i8[14] = v.s14; + i8[15] = v.s15; + return [i16[0], i16[1], i16[2], i16[3], i16[4], i16[5], i16[6], i16[7]]; + } + + var vals = [[0, 1, -2, 3, -4, 5, INT8_MIN, INT8_MAX, -6, 7, -8, 9, -10, 11, -12, 13]]; + + for (var v of vals) { + var i = int8x16(...v); + assertEqX8(int16x8.fromInt8x16Bits(i), expected(i)); + } +} + +function testInt16x8FromInt32x4Bits() { + function expected(v) { + var i32 = Int32Array(4); + var i16 = Int16Array(i32.buffer); + i32[0] = v.x; + i32[1] = v.y; + i32[2] = v.z; + i32[3] = v.w; + return [i16[0], i16[1], i16[2], i16[3], i16[4], i16[5], i16[6], i16[7]]; + } + + var vals = [[1, -2, -3, 4], [INT16_MAX, INT16_MIN, INT32_MAX, INT32_MIN]]; + + for (var v of vals) { + var i = int32x4(...v); + assertEqX8(int16x8.fromInt32x4Bits(i), expected(i)); + } +} + function test() { testFloat32x4FromFloat64x2(); testFloat32x4FromFloat64x2Bits(); + testFloat32x4FromInt8x16Bits(); + testFloat32x4FromInt16x8Bits(); testFloat32x4FromInt32x4(); testFloat32x4FromInt32x4Bits(); testFloat64x2FromFloat32x4(); testFloat64x2FromFloat32x4Bits(); + testFloat64x2FromInt8x16Bits(); + testFloat64x2FromInt16x8Bits(); testFloat64x2FromInt32x4(); testFloat64x2FromInt32x4Bits(); + testInt8x16FromFloat32x4Bits(); + testInt8x16FromFloat64x2Bits(); + testInt8x16FromInt16x8Bits(); + testInt8x16FromInt32x4Bits(); + + testInt16x8FromFloat32x4Bits(); + testInt16x8FromFloat64x2Bits(); + testInt16x8FromInt8x16Bits(); + testInt16x8FromInt32x4Bits(); + testInt32x4FromFloat32x4(); testInt32x4FromFloat32x4Bits(); testInt32x4FromFloat64x2(); testInt32x4FromFloat64x2Bits(); + testInt32x4FromInt8x16Bits(); + testInt32x4FromInt16x8Bits(); if (typeof reportCompare === "function") { reportCompare(true, true); diff --git a/js/src/tests/ecma_7/SIMD/int16x8bool.js b/js/src/tests/ecma_7/SIMD/int16x8bool.js new file mode 100644 index 00000000000..af7c5930be2 --- /dev/null +++ b/js/src/tests/ecma_7/SIMD/int16x8bool.js @@ -0,0 +1,24 @@ +// |reftest| skip-if(!this.hasOwnProperty("SIMD")) +var int16x8 = SIMD.int16x8; + +/* + * Any copyright is dedicated to the Public Domain. + * https://creativecommons.org/publicdomain/zero/1.0/ + */ + +function test() { + var a = int16x8.bool(true, false, true, false, true, true, false, false); + assertEq(a.s0, -1); + assertEq(a.s1, 0); + assertEq(a.s2, -1); + assertEq(a.s3, 0); + assertEq(a.s4, -1); + assertEq(a.s5, -1); + assertEq(a.s6, 0); + assertEq(a.s7, 0); + + if (typeof reportCompare === "function") + reportCompare(true, true); +} + +test(); diff --git a/js/src/tests/ecma_7/SIMD/int8x16bool.js b/js/src/tests/ecma_7/SIMD/int8x16bool.js new file mode 100644 index 00000000000..3d0f4bd743d --- /dev/null +++ b/js/src/tests/ecma_7/SIMD/int8x16bool.js @@ -0,0 +1,32 @@ +// |reftest| skip-if(!this.hasOwnProperty("SIMD")) +var int8x16 = SIMD.int8x16; + +/* + * Any copyright is dedicated to the Public Domain. + * https://creativecommons.org/publicdomain/zero/1.0/ + */ + +function test() { + var a = int8x16.bool(true, false, true, false, true, true, false, false, true, true, true, false, false, false, true, true); + assertEq(a.s0, -1); + assertEq(a.s1, 0); + assertEq(a.s2, -1); + assertEq(a.s3, 0); + assertEq(a.s4, -1); + assertEq(a.s5, -1); + assertEq(a.s6, 0); + assertEq(a.s7, 0); + assertEq(a.s8, -1); + assertEq(a.s9, -1); + assertEq(a.s10, -1); + assertEq(a.s11, 0); + assertEq(a.s12, 0); + assertEq(a.s13, 0); + assertEq(a.s14, -1); + assertEq(a.s15, -1); + + if (typeof reportCompare === "function") + reportCompare(true, true); +} + +test(); diff --git a/js/src/tests/ecma_7/SIMD/load.js b/js/src/tests/ecma_7/SIMD/load.js index 0289b67d188..26d4ed48b19 100644 --- a/js/src/tests/ecma_7/SIMD/load.js +++ b/js/src/tests/ecma_7/SIMD/load.js @@ -6,6 +6,8 @@ */ // Our array for int32x4 and float32x4 will have 16 elements +const SIZE_8_ARRAY = 64; +const SIZE_16_ARRAY = 32; const SIZE_32_ARRAY = 16; const SIZE_64_ARRAY = 8; @@ -26,6 +28,14 @@ function MakeComparator(kind, arr, shared) { // Typed array constructor corresponding to the SIMD kind. var typedArrayCtor; switch (kind) { + case 'int8x16': + sizeOfLaneElem = 1; + typedArrayCtor = Int8Array; + break; + case 'int16x8': + sizeOfLaneElem = 2; + typedArrayCtor = Int16Array; + break; case 'int32x4': sizeOfLaneElem = 4; typedArrayCtor = Int32Array; @@ -59,23 +69,25 @@ function MakeComparator(kind, arr, shared) { return new typedArrayCtor(new Uint8Array(asArray).buffer); } - var assertFunc = (lanes == 2) ? assertEqX2 : assertEqX4; + var assertFunc = getAssertFuncFromLength(lanes); var type = SIMD[kind]; return { load1: function(index) { + if (lanes >= 8) // int8x16 and int16x8 only support load, no load1/load2/etc. + return var v = type.load1(arr, index); assertFunc(v, slice(index, 1)); }, load2: function(index) { - if (lanes < 4) + if (lanes !== 4) return; var v = type.load2(arr, index); assertFunc(v, slice(index, 2)); }, load3: function(index) { - if (lanes < 4) + if (lanes !== 4) return; var v = type.load3(arr, index); assertFunc(v, slice(index, 3)); @@ -83,7 +95,7 @@ function MakeComparator(kind, arr, shared) { load: function(index) { var v = type.load(arr, index); - assertFunc(v, slice(index, 4)); + assertFunc(v, slice(index, lanes)); } } } @@ -114,7 +126,7 @@ function testLoad(kind, TA) { var C = MakeComparator(kind, ta); var bpe = ta.BYTES_PER_ELEMENT; - var lastValidArgLoad1 = (SIZE_BYTES - (lanes == 4 ? 4 : 8)) / bpe | 0; + var lastValidArgLoad1 = (SIZE_BYTES - (16 / lanes)) / bpe | 0; var lastValidArgLoad2 = (SIZE_BYTES - 8) / bpe | 0; var lastValidArgLoad3 = (SIZE_BYTES - 12) / bpe | 0; var lastValidArgLoad = (SIZE_BYTES - 16) / bpe | 0; @@ -124,14 +136,12 @@ function testLoad(kind, TA) { C.load(2); C.load(3); C.load(lastValidArgLoad); - assertThrowsInstanceOf(() => SIMD[kind].load(ta, lastValidArgLoad + 1), RangeError); C.load1(0); C.load1(1); C.load1(2); C.load1(3); C.load1(lastValidArgLoad1); - assertThrowsInstanceOf(() => SIMD[kind].load1(ta, lastValidArgLoad1 + 1), RangeError); C.load2(0); C.load2(1); @@ -145,7 +155,11 @@ function testLoad(kind, TA) { C.load3(3); C.load3(lastValidArgLoad3); - if (lanes >= 4) { + assertThrowsInstanceOf(() => SIMD[kind].load(ta, lastValidArgLoad + 1), RangeError); + if (lanes <= 4) { + assertThrowsInstanceOf(() => SIMD[kind].load1(ta, lastValidArgLoad1 + 1), RangeError); + } + if (lanes == 4) { assertThrowsInstanceOf(() => SIMD[kind].load2(ta, lastValidArgLoad2 + 1), RangeError); assertThrowsInstanceOf(() => SIMD[kind].load3(ta, lastValidArgLoad3 + 1), RangeError); } @@ -209,6 +223,8 @@ function testSharedArrayBufferCompat() { testLoad('float32x4', new Float32Array(SIZE_32_ARRAY)); testLoad('float64x2', new Float64Array(SIZE_64_ARRAY)); +testLoad('int8x16', new Int8Array(SIZE_8_ARRAY)); +testLoad('int16x8', new Int16Array(SIZE_16_ARRAY)); testLoad('int32x4', new Int32Array(SIZE_32_ARRAY)); testSharedArrayBufferCompat(); diff --git a/js/src/tests/ecma_7/SIMD/replaceLane.js b/js/src/tests/ecma_7/SIMD/replaceLane.js index 4ef5d22b8b0..fd02caa361a 100644 --- a/js/src/tests/ecma_7/SIMD/replaceLane.js +++ b/js/src/tests/ecma_7/SIMD/replaceLane.js @@ -1,25 +1,33 @@ // |reftest| skip-if(!this.hasOwnProperty("SIMD")) var float32x4 = SIMD.float32x4; +var int8x16 = SIMD.int8x16; +var int16x8 = SIMD.int16x8; var int32x4 = SIMD.int32x4; var float64x2 = SIMD.float64x2; +function replaceLaneN(laneIndex, arr, value) { + var copy = arr.slice(); + assertEq(laneIndex <= arr.length, true); + copy[laneIndex] = value; + return copy; +} -function replaceLane0(arr, x) { - if (arr.length == 2) - return [x, arr[1]]; - return [x, arr[1], arr[2], arr[3]]; -} -function replaceLane1(arr, x) { - if (arr.length == 2) - return [arr[0], x]; - return [arr[0], x, arr[2], arr[3]]; -} -function replaceLane2(arr, x) { - return [arr[0], arr[1], x, arr[3]]; -} -function replaceLane3(arr, x) { - return [arr[0], arr[1], arr[2], x]; -} +var replaceLane0 = replaceLaneN.bind(null, 0); +var replaceLane1 = replaceLaneN.bind(null, 1); +var replaceLane2 = replaceLaneN.bind(null, 2); +var replaceLane3 = replaceLaneN.bind(null, 3); +var replaceLane4 = replaceLaneN.bind(null, 4); +var replaceLane5 = replaceLaneN.bind(null, 5); +var replaceLane6 = replaceLaneN.bind(null, 6); +var replaceLane7 = replaceLaneN.bind(null, 7); +var replaceLane8 = replaceLaneN.bind(null, 8); +var replaceLane9 = replaceLaneN.bind(null, 9); +var replaceLane10 = replaceLaneN.bind(null, 10); +var replaceLane11 = replaceLaneN.bind(null, 11); +var replaceLane12 = replaceLaneN.bind(null, 12); +var replaceLane13 = replaceLaneN.bind(null, 13); +var replaceLane14 = replaceLaneN.bind(null, 14); +var replaceLane15 = replaceLaneN.bind(null, 15); function testReplaceLane(vec, scalar, simdFunc, func) { var varr = simdToArray(vec); @@ -39,6 +47,22 @@ function test() { continue; testReplaceLane(vec, s, (x,y) => SIMD[type].replaceLane(x, 2, y), replaceLane2); testReplaceLane(vec, s, (x,y) => SIMD[type].replaceLane(x, 3, y), replaceLane3); + if (length <= 4) + continue; + testReplaceLane(vec, s, (x,y) => SIMD[type].replaceLane(x, 4, y), replaceLane4); + testReplaceLane(vec, s, (x,y) => SIMD[type].replaceLane(x, 5, y), replaceLane5); + testReplaceLane(vec, s, (x,y) => SIMD[type].replaceLane(x, 6, y), replaceLane6); + testReplaceLane(vec, s, (x,y) => SIMD[type].replaceLane(x, 7, y), replaceLane7); + if (length <= 8) + continue; + testReplaceLane(vec, s, (x,y) => SIMD[type].replaceLane(x, 8, y), replaceLane8); + testReplaceLane(vec, s, (x,y) => SIMD[type].replaceLane(x, 9, y), replaceLane9); + testReplaceLane(vec, s, (x,y) => SIMD[type].replaceLane(x, 10, y), replaceLane10); + testReplaceLane(vec, s, (x,y) => SIMD[type].replaceLane(x, 11, y), replaceLane11); + testReplaceLane(vec, s, (x,y) => SIMD[type].replaceLane(x, 12, y), replaceLane12); + testReplaceLane(vec, s, (x,y) => SIMD[type].replaceLane(x, 13, y), replaceLane13); + testReplaceLane(vec, s, (x,y) => SIMD[type].replaceLane(x, 14, y), replaceLane14); + testReplaceLane(vec, s, (x,y) => SIMD[type].replaceLane(x, 15, y), replaceLane15); } } @@ -74,6 +98,26 @@ function test() { assertThrowsInstanceOf(() => float64x2.replaceLane(v, 2, good), TypeError); assertThrowsInstanceOf(() => float64x2.replaceLane(v, 1.1, good), TypeError); + var int8x16inputs = [[int8x16(0, 1, 2, 3, 4, 5, 6, 7, -1, -2, -3, -4, -5, -6, INT8_MIN, INT8_MAX), 17]]; + testType('int8x16', int8x16inputs); + + var v = int8x16inputs[0][0]; + assertEqX16(int8x16.replaceLane(v, 0), replaceLane0(simdToArray(v), 0)); + assertEqX16(int8x16.replaceLane(v, 0, good), replaceLane0(simdToArray(v), good | 0)); + assertThrowsInstanceOf(() => int8x16.replaceLane(v, 0, bad), TestError); + assertThrowsInstanceOf(() => int8x16.replaceLane(v, 16, good), TypeError); + assertThrowsInstanceOf(() => int8x16.replaceLane(v, 1.1, good), TypeError); + + var int16x8inputs = [[int16x8(0, 1, 2, 3, -1, -2, INT16_MIN, INT16_MAX), 9]]; + testType('int16x8', int16x8inputs); + + var v = int16x8inputs[0][0]; + assertEqX8(int16x8.replaceLane(v, 0), replaceLane0(simdToArray(v), 0)); + assertEqX8(int16x8.replaceLane(v, 0, good), replaceLane0(simdToArray(v), good | 0)); + assertThrowsInstanceOf(() => int16x8.replaceLane(v, 0, bad), TestError); + assertThrowsInstanceOf(() => int16x8.replaceLane(v, 8, good), TypeError); + assertThrowsInstanceOf(() => int16x8.replaceLane(v, 1.1, good), TypeError); + var int32x4inputs = [ [int32x4(1, 2, 3, 4), 5], [int32x4(INT32_MIN, INT32_MAX, 3, 4), INT32_MIN], diff --git a/js/src/tests/ecma_7/SIMD/select-bitselect.js b/js/src/tests/ecma_7/SIMD/select-bitselect.js index 81a0aadf359..17ac04f0a90 100644 --- a/js/src/tests/ecma_7/SIMD/select-bitselect.js +++ b/js/src/tests/ecma_7/SIMD/select-bitselect.js @@ -7,8 +7,29 @@ var float32x4 = SIMD.float32x4; var float64x2 = SIMD.float64x2; +var int8x16 = SIMD.int8x16; +var int16x8 = SIMD.int16x8; var int32x4 = SIMD.int32x4; +function getMask(i, maskLength) { + var args = []; + for (var j = 0; j < maskLength; j++) args.push(!!((i >> j) & 1)); + if (maskLength == 4) + return int32x4.bool(...args); + else if (maskLength == 8) + return int16x8.bool(...args); + else if (maskLength == 16) + return int8x16.bool(...args); + else + throw new Error("Invalid mask length."); +} + +function selectMaskType(type) { + if (type == int32x4 || type == float32x4 || type == float64x2) + return int32x4; + return type; +} + function select(mask, ifTrue, ifFalse) { var m = simdToArray(mask); var tv = simdToArray(ifTrue); @@ -20,24 +41,32 @@ function select(mask, ifTrue, ifFalse) { /** * Tests type.select on all input pairs, for all possible masks. As the mask - * has 4 lanes and 2 possible values (true or false), there are 16 possible - * masks. + * has 4 lanes (for int32x4) and 2 possible values (true or false), there are 16 possible + * masks. For int8x16, the mask has 16 lanes and 2 possible values, so there are 256 + * possible masks. For int16x8, the mask has 8 lanes and 2 possible values, so there + * are 64 possible masks. */ function testSelect(type, inputs) { var x, y; - for (var i = 0; i < 16; i++) { - var mask = int32x4.bool(!!(i & 1), !!((i >> 1) & 1), !!((i >> 2) & 1), !!((i >> 3) & 1)); + var maskLength = simdLengthType(type); + maskLength = maskLength != 2 ? maskLength : 4; + for (var i = 0; i < Math.pow(maskLength, 2); i++) { + var mask = getMask(i, maskLength); for ([x, y] of inputs) assertEqVec(type.select(mask, x, y), select(mask, x, y)); } } -function int32x4FromTypeBits(type, vec) { +function intFromTypeBits(type, vec) { switch (type) { case float32x4: return int32x4.fromFloat32x4Bits(vec); case float64x2: return int32x4.fromFloat64x2Bits(vec); + case int8x16: + return vec; + case int16x8: + return vec; case int32x4: return vec; default: @@ -46,17 +75,20 @@ function int32x4FromTypeBits(type, vec) { } function bitselect(type, mask, ifTrue, ifFalse) { - var tv = int32x4FromTypeBits(type, ifTrue); - var fv = int32x4FromTypeBits(type, ifFalse); - var tr = int32x4.and(mask, tv); - var fr = int32x4.and(int32x4.not(mask), fv); - var orApplied = int32x4.or(tr, fr); - var converted = type == int32x4 ? orApplied : type.fromInt32x4Bits(orApplied); + var maskType = selectMaskType(type); + var tv = intFromTypeBits(type, ifTrue); + var fv = intFromTypeBits(type, ifFalse); + var tr = maskType.and(mask, tv); + var fr = maskType.and(maskType.not(mask), fv); + var orApplied = maskType.or(tr, fr); + var converted = type == maskType ? orApplied : type.fromInt32x4Bits(orApplied); return simdToArray(converted); } function findCorrespondingScalarTypedArray(type) { switch (type) { + case int8x16: return Int8Array; + case int16x8: return Int16Array; case int32x4: return Int32Array; case float32x4: return Float32Array; case float64x2: return Float64Array; @@ -70,9 +102,11 @@ function findCorrespondingScalarTypedArray(type) { */ function testBitSelectSimple(type, inputs) { var x, y; + var maskLength = simdLengthType(type); + maskLength = maskLength != 2 ? maskLength : 4; var ScalarTypedArray = findCorrespondingScalarTypedArray(type); - for (var i = 0; i < 16; i++) { - var mask = int32x4.bool(!!(i & 1), !!((i >> 1) & 1), !!((i >> 2) & 1), !!((i >> 3) & 1)); + for (var i = 0; i < Math.pow(maskLength, 2); i++) { + var mask = getMask(i, maskLength); for ([x, y] of inputs) assertEqVec(type.bitselect(mask, x, y), bitselect(type, mask, x, y)); } @@ -83,12 +117,30 @@ function testBitSelectSimple(type, inputs) { * bitselect(mask, x, y) !== select(mask, x, y) */ function testBitSelectComplex(type, inputs) { - var x, y; - var masks = [ + var masks8 = [ + int8x16(0x42, 42, INT8_MAX, INT8_MIN, INT8_MAX + 1, INT8_MIN - 1, 13, 37, -42, 125, -125, -1, 1, 0xA, 0xB, 0xC) + ] + var masks16 = [ + int16x8(0x42, 42, INT16_MAX, INT16_MIN, INT16_MAX + 1, INT16_MIN - 1, 13, 37), + int16x8(-42, 125, -125, -1, 1, 0xA, 0xB, 0xC) + ] + var masks32 = [ int32x4(1337, 0x1337, 0x42, 42), int32x4(0x00FF1CE, 0xBAADF00D, 0xDEADBEEF, 0xCAFED00D), int32x4(0xD15EA5E, 0xDEADC0DE, 0xFACEB00C, 0x4B1D4B1D) ]; + var masks = []; + var maskType = selectMaskType(type); + if (maskType == SIMD.int8x16) + masks = masks8; + else if (maskType == SIMD.int16x8) + masks = masks16; + else if (maskType == SIMD.int32x4) + masks = masks32; + else + throw new Error("Unknown mask type."); + + var x, y; var ScalarTypedArray = findCorrespondingScalarTypedArray(type); for (var mask of masks) { for ([x, y] of inputs) @@ -98,6 +150,26 @@ function testBitSelectComplex(type, inputs) { function test() { var inputs = [ + [int8x16(0,4,9,16,25,36,49,64,81,121,-4,-9,-16,-25,-36,-49), int8x16(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)], + [int8x16(-1, 2, INT8_MAX, INT8_MIN, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), + int8x16(INT8_MAX, -4, INT8_MIN, 42, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)] + ]; + + testSelect(int8x16, inputs); + testBitSelectSimple(int8x16, inputs); + testBitSelectComplex(int8x16, inputs); + + inputs = [ + [int16x8(0,4,9,16,25,36,49,64), int16x8(1,2,3,4,5,6,7,8)], + [int16x8(-1, 2, INT16_MAX, INT16_MIN, 5, 6, 7, 8), + int16x8(INT16_MAX, -4, INT16_MIN, 42, 5, 6, 7, 8)] + ]; + + testSelect(int16x8, inputs); + testBitSelectSimple(int16x8, inputs); + testBitSelectComplex(int16x8, inputs); + + inputs = [ [int32x4(0,4,9,16), int32x4(1,2,3,4)], [int32x4(-1, 2, INT32_MAX, INT32_MIN), int32x4(INT32_MAX, -4, INT32_MIN, 42)] ]; diff --git a/js/src/tests/ecma_7/SIMD/shell.js b/js/src/tests/ecma_7/SIMD/shell.js index 50433db843c..495a6168e86 100644 --- a/js/src/tests/ecma_7/SIMD/shell.js +++ b/js/src/tests/ecma_7/SIMD/shell.js @@ -51,9 +51,53 @@ function assertEqX4(v, arr) { } } +function assertEqX8(v, arr) { + try { + assertEq(v.s0, arr[0]); + assertEq(v.s1, arr[1]); + assertEq(v.s2, arr[2]); + assertEq(v.s3, arr[3]); + assertEq(v.s4, arr[4]); + assertEq(v.s5, arr[5]); + assertEq(v.s6, arr[6]); + assertEq(v.s7, arr[7]); + } catch (e) { + print("stack trace:", e.stack); + throw e; + } +} + +function assertEqX16(v, arr) { + try { + assertEq(v.s0, arr[0]); + assertEq(v.s1, arr[1]); + assertEq(v.s2, arr[2]); + assertEq(v.s3, arr[3]); + assertEq(v.s4, arr[4]); + assertEq(v.s5, arr[5]); + assertEq(v.s6, arr[6]); + assertEq(v.s7, arr[7]); + assertEq(v.s8, arr[8]); + assertEq(v.s9, arr[9]); + assertEq(v.s10, arr[10]); + assertEq(v.s11, arr[11]); + assertEq(v.s12, arr[12]); + assertEq(v.s13, arr[13]); + assertEq(v.s14, arr[14]); + assertEq(v.s15, arr[15]); + } catch (e) { + print("stack trace:", e.stack); + throw e; + } +} + function simdLength(v) { var pt = Object.getPrototypeOf(v); - if (pt === SIMD.int32x4.prototype || pt === SIMD.float32x4.prototype) { + if (pt == SIMD.int8x16.prototype) { + return 16; + } else if (pt == SIMD.int16x8.prototype) { + return 8; + } else if (pt === SIMD.int32x4.prototype || pt === SIMD.float32x4.prototype) { return 4; } else if (pt === SIMD.float64x2.prototype) { return 2; @@ -62,26 +106,58 @@ function simdLength(v) { } } -function assertEqVec(v, arr) { - var lanes = simdLength(v); - if (lanes == 4) - assertEqX4(v, arr); - else if (lanes == 2) - assertEqX2(v, arr); +function simdLengthType(t) { + if (t == SIMD.int8x16) + return 16; + else if (t == SIMD.int16x8) + return 8; + else if (t == SIMD.int32x4 || t == SIMD.float32x4) + return 4; + else if (t == SIMD.float64x2) + return 2; else throw new TypeError("Unknown SIMD kind."); } +function getAssertFuncFromLength(l) { + if (l == 2) + return assertEqX2; + else if (l == 4) + return assertEqX4; + else if (l == 8) + return assertEqX8; + else if (l == 16) + return assertEqX16; + else + throw new TypeError("Unknown SIMD kind."); +} + +function assertEqVec(v, arr) { + var lanes = simdLength(v); + var assertFunc = getAssertFuncFromLength(lanes); + assertFunc(v, arr); +} + function simdToArray(v) { var lanes = simdLength(v); if (lanes == 4) return [v.x, v.y, v.z, v.w]; else if (lanes == 2) return [v.x, v.y]; + else if (lanes == 8) + return [v.s0, v.s1, v.s2, v.s3, v.s4, v.s5, v.s6, v.s7] + else if (lanes == 16) + return [v.s0, v.s1, v.s2, v.s3, v.s4, v.s5, v.s6, v.s7, v.s8, v.s9, v.s10, v.s11, v.s12, v.s13, v.s14, v.s15]; else throw new TypeError("Unknown SIMD kind."); } +const INT8_MAX = Math.pow(2, 7) -1; +const INT8_MIN = -Math.pow(2, 7); +assertEq((INT8_MAX + 1) << 24 >> 24, INT8_MIN); +const INT16_MAX = Math.pow(2, 15) - 1; +const INT16_MIN = -Math.pow(2, 15); +assertEq((INT16_MAX + 1) << 16 >> 16, INT16_MIN); const INT32_MAX = Math.pow(2, 31) - 1; const INT32_MIN = -Math.pow(2, 31); assertEq(INT32_MAX + 1 | 0, INT32_MIN); @@ -107,15 +183,16 @@ function testBinaryFunc(v, w, simdFunc, func) { assertEq(observed[i], expected[i]); } -function testBinaryCompare(v, w, simdFunc, func) { +function testBinaryCompare(v, w, simdFunc, func, outType) { var varr = simdToArray(v); var warr = simdToArray(w); var inLanes = simdLength(v); var observed = simdToArray(simdFunc(v, w)); - assertEq(observed.length, 4); - for (var i = 0; i < 4; i++) { - var j = ((i * inLanes) / 4) | 0; + var outTypeLen = simdLengthType(outType); + assertEq(observed.length, outTypeLen); + for (var i = 0; i < outTypeLen; i++) { + var j = ((i * inLanes) / outTypeLen) | 0; assertEq(observed[i], func(varr[j], warr[j])); } } diff --git a/js/src/tests/ecma_7/SIMD/shifts.js b/js/src/tests/ecma_7/SIMD/shifts.js index 0555153bb2d..76b9281a206 100644 --- a/js/src/tests/ecma_7/SIMD/shifts.js +++ b/js/src/tests/ecma_7/SIMD/shifts.js @@ -5,15 +5,37 @@ * https://creativecommons.org/publicdomain/zero/1.0/ */ +var int8x16 = SIMD.int8x16; +var int16x8 = SIMD.int16x8; var int32x4 = SIMD.int32x4; -function lsh(a, b) { +function lsh8(a, b) { + return (b >>> 0) >= 8 ? 0 : (a << b) << 24 >> 24; +} +function rsh8(a, b) { + return (a >> Math.min(b >>> 0, 7)) << 24 >> 24; +} +function ursh8(a, b) { + return (b >>> 0) >= 8 ? 0 : (a >>> b) << 24 >> 24; +} + +function lsh16(a, b) { + return (b >>> 0) >= 16 ? 0 : (a << b) << 16 >> 16; +} +function rsh16(a, b) { + return (a >> Math.min(b >>> 0, 15)) << 16 >> 16; +} +function ursh16(a, b) { + return (b >>> 0) >= 16 ? 0 : (a >>> b) << 16 >> 16; +} + +function lsh32(a, b) { return (b >>> 0) >= 32 ? 0 : (a << b) | 0; } -function rsh(a, b) { +function rsh32(a, b) { return (a >> Math.min(b >>> 0, 31)) | 0; } -function ursh(a, b) { +function ursh32(a, b) { return (b >>> 0) >= 32 ? 0 : (a >>> b) | 0; } @@ -23,22 +45,62 @@ function test() { var good = {valueOf: () => 21}; var bad = {valueOf: () => {throw new TestError(); }}; + for (var v of [ + int8x16(-1, 2, -3, 4, -5, 6, -7, 8, -9, 10, -11, 12, -13, 14, -15, 16), + int8x16(INT8_MAX, INT8_MIN, INT8_MAX - 1, INT8_MIN + 1) + ]) + { + for (var bits = -2; bits < 12; bits++) { + testBinaryScalarFunc(v, bits, int8x16.shiftLeftByScalar, lsh8); + testBinaryScalarFunc(v, bits, int8x16.shiftRightArithmeticByScalar, rsh8); + testBinaryScalarFunc(v, bits, int8x16.shiftRightLogicalByScalar, ursh8); + } + // Test that the shift count is coerced to an int32. + testBinaryScalarFunc(v, undefined, int8x16.shiftLeftByScalar, lsh8); + testBinaryScalarFunc(v, 3.5, int8x16.shiftLeftByScalar, lsh8); + testBinaryScalarFunc(v, good, int8x16.shiftLeftByScalar, lsh8); + } + for (var v of [ + int16x8(-1, 2, -3, 4, -5, 6, -7, 8), + int16x8(INT16_MAX, INT16_MIN, INT16_MAX - 1, INT16_MIN + 1) + ]) + { + for (var bits = -2; bits < 20; bits++) { + testBinaryScalarFunc(v, bits, int16x8.shiftLeftByScalar, lsh16); + testBinaryScalarFunc(v, bits, int16x8.shiftRightArithmeticByScalar, rsh16); + testBinaryScalarFunc(v, bits, int16x8.shiftRightLogicalByScalar, ursh16); + } + // Test that the shift count is coerced to an int32. + testBinaryScalarFunc(v, undefined, int16x8.shiftLeftByScalar, lsh16); + testBinaryScalarFunc(v, 3.5, int16x8.shiftLeftByScalar, lsh16); + testBinaryScalarFunc(v, good, int16x8.shiftLeftByScalar, lsh16); + } for (var v of [ int32x4(-1, 2, -3, 4), int32x4(INT32_MAX, INT32_MIN, INT32_MAX - 1, INT32_MIN + 1) ]) { for (var bits = -2; bits < 36; bits++) { - testBinaryScalarFunc(v, bits, int32x4.shiftLeftByScalar, lsh); - testBinaryScalarFunc(v, bits, int32x4.shiftRightArithmeticByScalar, rsh); - testBinaryScalarFunc(v, bits, int32x4.shiftRightLogicalByScalar, ursh); + testBinaryScalarFunc(v, bits, int32x4.shiftLeftByScalar, lsh32); + testBinaryScalarFunc(v, bits, int32x4.shiftRightArithmeticByScalar, rsh32); + testBinaryScalarFunc(v, bits, int32x4.shiftRightLogicalByScalar, ursh32); } // Test that the shift count is coerced to an int32. - testBinaryScalarFunc(v, undefined, int32x4.shiftLeftByScalar, lsh); - testBinaryScalarFunc(v, 3.5, int32x4.shiftLeftByScalar, lsh); - testBinaryScalarFunc(v, good, int32x4.shiftLeftByScalar, lsh); + testBinaryScalarFunc(v, undefined, int32x4.shiftLeftByScalar, lsh32); + testBinaryScalarFunc(v, 3.5, int32x4.shiftLeftByScalar, lsh32); + testBinaryScalarFunc(v, good, int32x4.shiftLeftByScalar, lsh32); } + var v = SIMD.int8x16(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16); + assertThrowsInstanceOf(() => SIMD.int8x16.shiftLeftByScalar(v, bad), TestError); + assertThrowsInstanceOf(() => SIMD.int8x16.shiftRightArithmeticByScalar(v, bad), TestError); + assertThrowsInstanceOf(() => SIMD.int8x16.shiftRightLogicalByScalar(v, bad), TestError); + + var v = SIMD.int16x8(1,2,3,4,5,6,7,8); + assertThrowsInstanceOf(() => SIMD.int16x8.shiftLeftByScalar(v, bad), TestError); + assertThrowsInstanceOf(() => SIMD.int16x8.shiftRightArithmeticByScalar(v, bad), TestError); + assertThrowsInstanceOf(() => SIMD.int16x8.shiftRightLogicalByScalar(v, bad), TestError); + var v = SIMD.int32x4(1,2,3,4); assertThrowsInstanceOf(() => SIMD.int32x4.shiftLeftByScalar(v, bad), TestError); assertThrowsInstanceOf(() => SIMD.int32x4.shiftRightArithmeticByScalar(v, bad), TestError); diff --git a/js/src/tests/ecma_7/SIMD/signmask.js b/js/src/tests/ecma_7/SIMD/signmask.js index 88adbc43dfb..98541a5f34c 100644 --- a/js/src/tests/ecma_7/SIMD/signmask.js +++ b/js/src/tests/ecma_7/SIMD/signmask.js @@ -1,6 +1,8 @@ // |reftest| skip-if(!this.hasOwnProperty("SIMD")) var float32x4 = SIMD.float32x4; +var int8x16 = SIMD.int8x16; +var int16x8 = SIMD.int16x8; var int32x4 = SIMD.int32x4; function test_float32x4() { @@ -16,6 +18,32 @@ function test_float32x4() { reportCompare(true, true); } +function test_int8x16() { + var v, w; + for ([v, w] of [[int8x16(-1, 20, 30, 4, -5, 6, 70, -80, 9, 100, -11, 12, 13, -14, 15, -16), 0b1010010010010001], + [int8x16(10, 2, 30.2, -4, -5.2, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), 0b11000], + [int8x16(0, INT8_MIN, INT8_MAX, -0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), 0b10]]) + { + assertEq(v.signMask, w); + } + + if (typeof reportCompare === "function") + reportCompare(true, true); +} + +function test_int16x8() { + var v, w; + for ([v, w] of [[int16x8(-1, 20, 30, 4, -5, 6, 70, -80), 0b10010001], + [int16x8(10, 2, 30.2, -4, -5.2, 6, 7, 8), 0b11000], + [int16x8(0, INT16_MIN, INT16_MAX, -0, 5, 6, 7, 8), 0b10]]) + { + assertEq(v.signMask, w); + } + + if (typeof reportCompare === "function") + reportCompare(true, true); +} + function test_int32x4() { var v, w; for ([v, w] of [[int32x4(-1, 20, 30, 4), 0b0001], @@ -30,4 +58,6 @@ function test_int32x4() { } test_float32x4(); +test_int8x16(); +test_int16x8(); test_int32x4(); diff --git a/js/src/tests/ecma_7/SIMD/splat.js b/js/src/tests/ecma_7/SIMD/splat.js index dd3c3fbd084..713a3e913e0 100644 --- a/js/src/tests/ecma_7/SIMD/splat.js +++ b/js/src/tests/ecma_7/SIMD/splat.js @@ -2,8 +2,22 @@ var float64x2 = SIMD.float64x2; var float32x4 = SIMD.float32x4; +var int8x16 = SIMD.int8x16; +var int16x8 = SIMD.int16x8; var int32x4 = SIMD.int32x4; +function TestSplatX16(type, inputs, coerceFunc) { + for (var x of inputs) { + assertEqX16(SIMD[type].splat(x), [x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x].map(coerceFunc)); + } +} + +function TestSplatX8(type, inputs, coerceFunc) { + for (var x of inputs) { + assertEqX8(SIMD[type].splat(x), [x, x, x, x, x, x, x, x].map(coerceFunc)); + } +} + function TestSplatX4(type, inputs, coerceFunc) { for (var x of inputs) { assertEqX4(SIMD[type].splat(x), [x, x, x, x].map(coerceFunc)); @@ -22,6 +36,14 @@ function test() { var good = {valueOf: () => 19.89}; var bad = {valueOf: () => { throw new TestError(); }}; + TestSplatX16('int8x16', [0, 1, 2, -1, -2, 3, -3, 4, -4, 5, -5, 6, INT8_MIN, INT8_MAX, INT8_MIN - 1, INT8_MAX + 1], (x) => x << 24 >> 24); + assertEqX16(int8x16.splat(), [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + assertThrowsInstanceOf(() => SIMD.int8x16.splat(bad), TestError); + + TestSplatX8('int16x8', [0, 1, 2, -1, INT16_MIN, INT16_MAX, INT16_MIN - 1, INT16_MAX + 1], (x) => x << 16 >> 16); + assertEqX8(int16x8.splat(), [0, 0, 0, 0, 0, 0, 0, 0]); + assertThrowsInstanceOf(() => SIMD.int16x8.splat(bad), TestError); + TestSplatX4('int32x4', [0, undefined, 3.5, 42, -1337, INT32_MAX, INT32_MAX + 1, good], (x) => x | 0); assertEqX4(SIMD.int32x4.splat(), [0, 0, 0, 0]); assertThrowsInstanceOf(() => SIMD.int32x4.splat(bad), TestError); diff --git a/js/src/tests/ecma_7/SIMD/store.js b/js/src/tests/ecma_7/SIMD/store.js index e94f8cad635..a1afbdbd501 100644 --- a/js/src/tests/ecma_7/SIMD/store.js +++ b/js/src/tests/ecma_7/SIMD/store.js @@ -27,15 +27,18 @@ function assertChanged(ta, from, expected) { } function testStore(ta, kind, i, v) { - reset(ta); - SIMD[kind].store1(ta, i, v); - assertChanged(ta, i, [v.x]); - reset(ta); SIMD[kind].store(ta, i, v); assertChanged(ta, i, simdToArray(v)); - if (simdLength(v) > 2) { + var length = simdLength(v); + if (length >= 8) // int8x16 and int16x8 only support store, and not store1/store2/etc. + return; + + reset(ta); + SIMD[kind].store1(ta, i, v); + assertChanged(ta, i, [v.x]); + if (length > 2) { reset(ta); SIMD[kind].store2(ta, i, v); assertChanged(ta, i, [v.x, v.y]); @@ -46,6 +49,34 @@ function testStore(ta, kind, i, v) { } } +function testStoreInt8x16() { + var I8 = new Int8Array(32); + + var v = SIMD.int8x16(0, 1, INT8_MAX, INT8_MIN, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + testStore(I8, 'int8x16', 0, v); + testStore(I8, 'int8x16', 1, v); + testStore(I8, 'int8x16', 2, v); + testStore(I8, 'int8x16', 16, v); + + assertThrowsInstanceOf(() => SIMD.int8x16.store(I8), TypeError); + assertThrowsInstanceOf(() => SIMD.int8x16.store(I8, 0), TypeError); + assertThrowsInstanceOf(() => SIMD.int16x8.store(I8, 0, v), TypeError); +} + +function testStoreInt16x8() { + var I16 = new Int16Array(32); + + var v = SIMD.int16x8(0, 1, INT16_MAX, INT16_MIN, 4, 5, 6, 7); + testStore(I16, 'int16x8', 0, v); + testStore(I16, 'int16x8', 1, v); + testStore(I16, 'int16x8', 2, v); + testStore(I16, 'int16x8', 24, v); + + assertThrowsInstanceOf(() => SIMD.int16x8.store(I16), TypeError); + assertThrowsInstanceOf(() => SIMD.int16x8.store(I16, 0), TypeError); + assertThrowsInstanceOf(() => SIMD.int8x16.store(I16, 0, v), TypeError); +} + function testStoreInt32x4() { var I32 = new Int32Array(16); @@ -110,9 +141,13 @@ function testSharedArrayBufferCompat() { var I32 = new SharedInt32Array(16); var TA = I32; + var I8 = new SharedInt8Array(TA.buffer); + var I16 = new SharedInt16Array(TA.buffer); var F32 = new SharedFloat32Array(TA.buffer); var F64 = new SharedFloat64Array(TA.buffer); + var int8x16 = SIMD.int8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); + var int16x8 = SIMD.int16x8(1, 2, 3, 4, 5, 6, 7, 8); var int32x4 = SIMD.int32x4(1, 2, 3, 4); var float32x4 = SIMD.float32x4(1, 2, 3, 4); var float64x2 = SIMD.float64x2(1, 2); @@ -128,6 +163,12 @@ function testSharedArrayBufferCompat() { new SharedFloat64Array(TA.buffer) ]) { + SIMD.int8x16.store(ta, 0, int8x16); + for (var i = 0; i < 16; i++) assertEq(I8[i], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16][i]); + + SIMD.int16x8.store(ta, 0, int16x8); + for (var i = 0; i < 8; i++) assertEq(I16[i], [1, 2, 3, 4, 5, 6, 7, 8][i]); + SIMD.int32x4.store(ta, 0, int32x4); for (var i = 0; i < 4; i++) assertEq(I32[i], [1, 2, 3, 4][i]); @@ -137,12 +178,16 @@ function testSharedArrayBufferCompat() { SIMD.float64x2.store(ta, 0, float64x2); for (var i = 0; i < 2; i++) assertEq(F64[i], [1, 2][i]); + assertThrowsInstanceOf(() => SIMD.int8x16.store(ta, 1024, int8x16), RangeError); + assertThrowsInstanceOf(() => SIMD.int16x8.store(ta, 1024, int16x8), RangeError); assertThrowsInstanceOf(() => SIMD.int32x4.store(ta, 1024, int32x4), RangeError); assertThrowsInstanceOf(() => SIMD.float32x4.store(ta, 1024, float32x4), RangeError); assertThrowsInstanceOf(() => SIMD.float64x2.store(ta, 1024, float64x2), RangeError); } } +testStoreInt8x16(); +testStoreInt16x8(); testStoreInt32x4(); testStoreFloat32x4(); testStoreFloat64x2(); diff --git a/js/src/tests/ecma_7/SIMD/swizzle-shuffle.js b/js/src/tests/ecma_7/SIMD/swizzle-shuffle.js index 9f2e9cb78a0..ad7f2791002 100644 --- a/js/src/tests/ecma_7/SIMD/swizzle-shuffle.js +++ b/js/src/tests/ecma_7/SIMD/swizzle-shuffle.js @@ -7,6 +7,8 @@ var float32x4 = SIMD.float32x4; var float64x2 = SIMD.float64x2; +var int8x16 = SIMD.int8x16; +var int16x8 = SIMD.int16x8; var int32x4 = SIMD.int32x4; function swizzle2(arr, x, y) { @@ -17,8 +19,22 @@ function swizzle4(arr, x, y, z, w) { return [arr[x], arr[y], arr[z], arr[w]]; } +function swizzle8(arr, s0, s1, s2, s3, s4, s5, s6, s7) { + return [arr[s0], arr[s1], arr[s2], arr[s3], arr[s4], arr[s5], arr[s6], arr[s7]]; +} + +function swizzle16(arr, s0, s1, s2, s3, s4, s5, s6, s7, + s8, s9, s10, s11, s12, s13, s14, s15) { + return [arr[s0], arr[s1], arr[s2], arr[s3], arr[s4], arr[s5], arr[s6], arr[s7], + arr[s8], arr[s9], arr[s10], arr[s11], arr[s12], arr[s13], arr[s14], arr[s15]]; +} + function getNumberOfLanesFromType(type) { switch (type) { + case int8x16: + return 16; + case int16x8: + return 8; case float32x4: case int32x4: return 4; @@ -30,7 +46,21 @@ function getNumberOfLanesFromType(type) { function testSwizzleForType(type) { var lanes = getNumberOfLanesFromType(type); - var v = lanes == 4 ? type(1, 2, 3, 4) : type(1, 2); + var v; + switch (lanes) { + case 2: + v = type(1, 2); + break; + case 4: + v = type(1, 2, 3, 4); + break; + case 8: + v = type(1, 2, 3, 4, 5, 6, 7, 8); + break; + case 16: + v = type(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); + break; + } assertThrowsInstanceOf(() => type.swizzle() , TypeError); assertThrowsInstanceOf(() => type.swizzle(v, 0) , TypeError); @@ -38,37 +68,39 @@ function testSwizzleForType(type) { assertThrowsInstanceOf(() => type.swizzle(0, 1, 2, 3, v) , TypeError); // Test all possible swizzles. - if (lanes == 4) { - var x, y, z, w; - for (var i = 0; i < Math.pow(4, 4); i++) { - [x, y, z, w] = [i & 3, (i >> 2) & 3, (i >> 4) & 3, (i >> 6) & 3]; - assertEqVec(type.swizzle(v, x, y, z, w), swizzle4(simdToArray(v), x, y, z, w)); - } - } else { - assertEq(lanes, 2); + if (lanes == 2) { var x, y; for (var i = 0; i < Math.pow(2, 2); i++) { [x, y] = [x & 1, (y >> 1) & 1]; assertEqVec(type.swizzle(v, x, y), swizzle2(simdToArray(v), x, y)); } + } else if (lanes == 4) { + var x, y, z, w; + for (var i = 0; i < Math.pow(4, 4); i++) { + [x, y, z, w] = [i & 3, (i >> 2) & 3, (i >> 4) & 3, (i >> 6) & 3]; + assertEqVec(type.swizzle(v, x, y, z, w), swizzle4(simdToArray(v), x, y, z, w)); + } + } else if (lanes == 8) { + var vals = [[1, 2, 1, 2, 1, 2, 1, 2], [1, 1, 1, 1, 1, 1, 1, 1], [0, 1, 2, 3, 4, 5, 6, 7], + [7, 6, 5, 4, 3, 2, 1, 0], [5, 3, 2, 6, 1, 7, 4, 0]]; + for (var t of vals) { + assertEqVec(type.swizzle(v, ...t), swizzle8(simdToArray(v), ...t)); + } + } else { + assertEq(lanes, 16); + + var vals = [[11, 2, 11, 2, 11, 2, 11, 2, 11, 2, 11, 2, 11, 2, 11, 2], + [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], + [15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0], + [5, 14, 3, 2, 6, 9, 1, 10, 7, 11, 4, 0, 13, 15, 8, 12]]; + for (var t of vals) { + assertEqVec(type.swizzle(v, ...t), swizzle16(simdToArray(v), ...t)); + } } // Test that we throw if an lane argument isn't an int32 or isn't in bounds. - if (lanes == 4) { - assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0.5), TypeError); - assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, {}), TypeError); - assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, {valueOf: function(){return 42}}), TypeError); - assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, "one"), TypeError); - assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, null), TypeError); - assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, undefined), TypeError); - assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, true), TypeError); - - // In bounds is [0, 3] - assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, -1), TypeError); - assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 4), TypeError); - } else { - assertEq(lanes, 2); - + if (lanes == 2) { assertThrowsInstanceOf(() => type.swizzle(v, 0, 0.5), TypeError); assertThrowsInstanceOf(() => type.swizzle(v, 0, {}), TypeError); assertThrowsInstanceOf(() => type.swizzle(v, 0, {valueOf: function(){return 42}}), TypeError); @@ -80,9 +112,67 @@ function testSwizzleForType(type) { // In bounds is [0, 1] assertThrowsInstanceOf(() => type.swizzle(v, 0, -1), TypeError); assertThrowsInstanceOf(() => type.swizzle(v, 0, 2), TypeError); + } else if (lanes == 4) { + assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0.5), TypeError); + assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, {}), TypeError); + assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, {valueOf: function(){return 42}}), TypeError); + assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, "one"), TypeError); + assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, null), TypeError); + assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, undefined), TypeError); + assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, true), TypeError); + + // In bounds is [0, 3] + assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, -1), TypeError); + assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 4), TypeError); + } else if (lanes == 8) { + assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0.5), TypeError); + assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, {}), TypeError); + assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, {valueOf: function(){return 42}}), TypeError); + assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, "one"), TypeError); + assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, null), TypeError); + assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, undefined), TypeError); + assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, true), TypeError); + + // In bounds is [0, 7] + assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, -1), TypeError); + assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 8), TypeError); + } else { + assertEq(lanes, 16); + + assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.5), TypeError); + assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}), TypeError); + assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {valueOf: function(){return 42}}), TypeError); + assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "one"), TypeError); + assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, null), TypeError); + assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, undefined), TypeError); + assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, true), TypeError); + + // In bounds is [0, 15] + assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1), TypeError); + assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16), TypeError); } } +function testSwizzleInt8x16() { + var v = int16x8(1, 2, 3, 4, 5, 6, 7, 8); + + assertThrowsInstanceOf(function() { + int8x16.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + }, TypeError); + + testSwizzleForType(int8x16); +} + +function testSwizzleInt16x8() { + var v = int8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); + + assertThrowsInstanceOf(function() { + int16x8.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0); + }, TypeError); + + testSwizzleForType(int16x8); +} + function testSwizzleInt32x4() { var v = int32x4(1, 2, 3, 4); @@ -124,16 +214,53 @@ function shuffle4(lhsa, rhsa, x, y, z, w) { (w < 4 ? lhsa : rhsa)[w % 4]]; } +function shuffle8(lhsa, rhsa, s0, s1, s2, s3, s4, s5, s6, s7, s8) { + return [(s0 < 8 ? lhsa : rhsa)[s0 % 8], + (s1 < 8 ? lhsa : rhsa)[s1 % 8], + (s2 < 8 ? lhsa : rhsa)[s2 % 8], + (s3 < 8 ? lhsa : rhsa)[s3 % 8], + (s4 < 8 ? lhsa : rhsa)[s4 % 8], + (s5 < 8 ? lhsa : rhsa)[s5 % 8], + (s6 < 8 ? lhsa : rhsa)[s6 % 8], + (s7 < 8 ? lhsa : rhsa)[s7 % 8]]; +} + +function shuffle16(lhsa, rhsa, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15) { + return [(s0 < 16 ? lhsa : rhsa)[s0 % 16], + (s1 < 16 ? lhsa : rhsa)[s1 % 16], + (s2 < 16 ? lhsa : rhsa)[s2 % 16], + (s3 < 16 ? lhsa : rhsa)[s3 % 16], + (s4 < 16 ? lhsa : rhsa)[s4 % 16], + (s5 < 16 ? lhsa : rhsa)[s5 % 16], + (s6 < 16 ? lhsa : rhsa)[s6 % 16], + (s7 < 16 ? lhsa : rhsa)[s7 % 16], + (s8 < 16 ? lhsa : rhsa)[s8 % 16], + (s9 < 16 ? lhsa : rhsa)[s9 % 16], + (s10 < 16 ? lhsa : rhsa)[s10 % 16], + (s11 < 16 ? lhsa : rhsa)[s11 % 16], + (s12 < 16 ? lhsa : rhsa)[s12 % 16], + (s13 < 16 ? lhsa : rhsa)[s13 % 16], + (s14 < 16 ? lhsa : rhsa)[s14 % 16], + (s15 < 16 ? lhsa : rhsa)[s15 % 16]]; +} + function testShuffleForType(type) { var lanes = getNumberOfLanesFromType(type); var lhs, rhs; - if (lanes == 4) { - lhs = type(1, 2, 3, 4); - rhs = type(5, 6, 7, 8); - } else { - assertEq(lanes, 2); + if (lanes == 2) { lhs = type(1, 2); rhs = type(3, 4); + } else if (lanes == 4) { + lhs = type(1, 2, 3, 4); + rhs = type(5, 6, 7, 8); + } else if (lanes == 8) { + lhs = type(1, 2, 3, 4, 5, 6, 7, 8); + rhs = type(9, 10, 11, 12, 13, 14, 15, 16); + } else { + assertEq(lanes, 16); + + lhs = type(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); + rhs = type(17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32); } assertThrowsInstanceOf(() => type.shuffle(lhs) , TypeError); @@ -144,39 +271,49 @@ function testShuffleForType(type) { // Test all possible shuffles. var x, y, z, w; - if (lanes == 4) { - var x, y, z, w; - for (var i = 0; i < Math.pow(8, 4); i++) { - [x, y, z, w] = [i & 7, (i >> 3) & 7, (i >> 6) & 7, (i >> 9) & 7]; - assertEqVec(type.shuffle(lhs, rhs, x, y, z, w), - shuffle4(simdToArray(lhs), simdToArray(rhs), x, y, z, w)); - } - } else { - assertEq(lanes, 2); + if (lanes == 2) { var x, y; for (var i = 0; i < Math.pow(4, 2); i++) { [x, y] = [i & 3, (i >> 3) & 3]; assertEqVec(type.shuffle(lhs, rhs, x, y), shuffle2(simdToArray(lhs), simdToArray(rhs), x, y)); } + } else if (lanes == 4) { + var x, y, z, w; + for (var i = 0; i < Math.pow(8, 4); i++) { + [x, y, z, w] = [i & 7, (i >> 3) & 7, (i >> 6) & 7, (i >> 9) & 7]; + assertEqVec(type.shuffle(lhs, rhs, x, y, z, w), + shuffle4(simdToArray(lhs), simdToArray(rhs), x, y, z, w)); + } + } else if (lanes == 8) { + var s0, s1, s2, s3, s4, s5, s6, s7; + var vals = [[15, 8, 15, 8, 15, 8, 15, 8], [9, 7, 9, 7, 9, 7, 9, 7], + [7, 3, 8, 9, 2, 15, 14, 6], [2, 2, 2, 2, 2, 2, 2, 2], + [8, 8, 8, 8, 8, 8, 8, 8], [11, 11, 11, 11, 11, 11, 11, 11]]; + for (var t of vals) { + [s0, s1, s2, s3, s4, s5, s6, s7] = t; + assertEqVec(type.shuffle(lhs, rhs, s0, s1, s2, s3, s4, s5, s6, s7), + shuffle8(simdToArray(lhs), simdToArray(rhs), s0, s1, s2, s3, s4, s5, s6, s7)); + } + } else { + assertEq(lanes, 16); + + var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15; + var vals = [[30, 16, 30, 16, 30, 16, 30, 16, 30, 16, 30, 16, 30, 16, 30, 16], + [19, 17, 19, 17, 19, 17, 19, 17, 19, 17, 19, 17, 19, 17, 19, 17], + [7, 3, 8, 18, 9, 21, 2, 15, 14, 6, 16, 22, 29, 31, 30, 1], + [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2], + [16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16], + [21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21]]; + for (var t of vals) { + [s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15] = t; + assertEqVec(type.shuffle(lhs, rhs, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15), + shuffle16(simdToArray(lhs), simdToArray(rhs), s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15)); + } } // Test that we throw if an lane argument isn't an int32 or isn't in bounds. - if (lanes == 4) { - assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, 0.5), TypeError); - assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, {}), TypeError); - assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, {valueOf: function(){return 42}}), TypeError); - assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, "one"), TypeError); - assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, null), TypeError); - assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, undefined), TypeError); - assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, true), TypeError); - - // In bounds is [0, 7] - assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, -1), TypeError); - assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, 8), TypeError); - } else { - assertEq(lanes, 2); - + if (lanes == 2) { assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0.5), TypeError); assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, {}), TypeError); assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, {valueOf: function(){return 42}}), TypeError); @@ -188,9 +325,67 @@ function testShuffleForType(type) { // In bounds is [0, 3] assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, -1), TypeError); assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 4), TypeError); + } else if (lanes == 4) { + assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, 0.5), TypeError); + assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, {}), TypeError); + assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, {valueOf: function(){return 42}}), TypeError); + assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, "one"), TypeError); + assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, null), TypeError); + assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, undefined), TypeError); + assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, true), TypeError); + + // In bounds is [0, 7] + assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, -1), TypeError); + assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, 8), TypeError); + } else if (lanes == 8) { + assertThrowsInstanceOf(() => type.swizzle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, 0.5), TypeError); + assertThrowsInstanceOf(() => type.swizzle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, {}), TypeError); + assertThrowsInstanceOf(() => type.swizzle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, {valueOf: function(){return 42}}), TypeError); + assertThrowsInstanceOf(() => type.swizzle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, "one"), TypeError); + assertThrowsInstanceOf(() => type.swizzle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, null), TypeError); + assertThrowsInstanceOf(() => type.swizzle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, undefined), TypeError); + assertThrowsInstanceOf(() => type.swizzle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, true), TypeError); + + // In bounds is [0, 15] + assertThrowsInstanceOf(() => type.swizzle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, -1), TypeError); + assertThrowsInstanceOf(() => type.swizzle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, 16), TypeError); + } else { + assertEq(lanes, 16); + + assertThrowsInstanceOf(() => type.swizzle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.5), TypeError); + assertThrowsInstanceOf(() => type.swizzle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}), TypeError); + assertThrowsInstanceOf(() => type.swizzle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {valueOf: function(){return 42}}), TypeError); + assertThrowsInstanceOf(() => type.swizzle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "one"), TypeError); + assertThrowsInstanceOf(() => type.swizzle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, null), TypeError); + assertThrowsInstanceOf(() => type.swizzle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, undefined), TypeError); + assertThrowsInstanceOf(() => type.swizzle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, true), TypeError); + + // In bounds is [0, 31] + assertThrowsInstanceOf(() => type.swizzle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1), TypeError); + assertThrowsInstanceOf(() => type.swizzle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32), TypeError); } } +function testShuffleInt8x16() { + var v = int16x8(1, 2, 3, 4, 5, 6, 7, 8); + + assertThrowsInstanceOf(function() { + int8x16.shuffle(v, v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + }, TypeError); + + testShuffleForType(int8x16); +} + +function testShuffleInt16x8() { + var v = int8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); + + assertThrowsInstanceOf(function() { + int16x8.shuffle(v, v, 0, 0, 0, 0, 0, 0, 0, 0); + }, TypeError); + + testShuffleForType(int16x8); +} + function testShuffleInt32x4() { var v = int32x4(1, 2, 3, 4); @@ -221,9 +416,13 @@ function testShuffleFloat64x2() { testShuffleForType(float64x2); } +testSwizzleInt8x16(); +testSwizzleInt16x8(); testSwizzleInt32x4(); testSwizzleFloat32x4(); testSwizzleFloat64x2(); +testShuffleInt8x16(); +testShuffleInt16x8(); testShuffleInt32x4(); testShuffleFloat32x4(); testShuffleFloat64x2(); diff --git a/js/src/tests/ecma_7/SIMD/typedobjects.js b/js/src/tests/ecma_7/SIMD/typedobjects.js index 42b1ae7f484..8e58d532a59 100644 --- a/js/src/tests/ecma_7/SIMD/typedobjects.js +++ b/js/src/tests/ecma_7/SIMD/typedobjects.js @@ -1,10 +1,12 @@ // |reftest| skip-if(!this.hasOwnProperty("SIMD")) var float32x4 = SIMD.float32x4; var float64x2 = SIMD.float64x2; +var int8x16 = SIMD.int8x16; +var int16x8 = SIMD.int16x8; var int32x4 = SIMD.int32x4; var {StructType, Handle} = TypedObject; -var {float32, float64, int32, uint8} = TypedObject; +var {float32, float64, int8, int16, int32, uint8} = TypedObject; function testFloat32x4Alignment() { assertEq(float32x4.byteLength, 16); @@ -230,6 +232,247 @@ function testFloat64x2Setters() { }, TypeError, "Setting float64x2 from a number"); } +function testInt8x16Alignment() { + assertEq(int8x16.byteLength, 16); + assertEq(int8x16.byteAlignment, 16); + + var Compound = new StructType({c: uint8, d: uint8, f: int8x16}); + assertEq(Compound.fieldOffsets.c, 0); + assertEq(Compound.fieldOffsets.d, 1); + assertEq(Compound.fieldOffsets.f, 16); +} + +function testInt8x16Getters() { + // Create a int8x16 and check that the getters work: + var f = int8x16(11, 22, 33, 44, 55, 66, 77, 88, 99, 10, 20, 30, 40, 50, 60, 70); + assertEq(f.s0, 11); + assertEq(f.s1, 22); + assertEq(f.s2, 33); + assertEq(f.s3, 44); + assertEq(f.s4, 55); + assertEq(f.s5, 66); + assertEq(f.s6, 77); + assertEq(f.s7, 88); + assertEq(f.s8, 99); + assertEq(f.s9, 10); + assertEq(f.s10, 20); + assertEq(f.s11, 30); + assertEq(f.s12, 40); + assertEq(f.s13, 50); + assertEq(f.s14, 60); + assertEq(f.s15, 70); + + // Test that the getters work when called reflectively: + var g = f.__lookupGetter__("s0"); + assertEq(g.call(f), 11); + + // Test that getters cannot be applied to various incorrect things: + assertThrowsInstanceOf(function() { + g.call({}) + }, TypeError, "Getter applicable to random objects"); + assertThrowsInstanceOf(function() { + g.call(0xDEADBEEF) + }, TypeError, "Getter applicable to integers"); + assertThrowsInstanceOf(function() { + var T = new StructType({s0: int8, s1: int8, s2: int8, s3: int8, s4: int8, s5: int8, s6: int8, s7: int8, + s8: int8, s9: int8, s10: int8, s11: int8, s12: int8, s13: int8, s14: int8, s15: int8}); + var v = new T({s0: 11, s1: 22, s2: 33, s3: 44, s4: 55, s5: 66, s6: 77, s7: 88, + s8: 99, s9: 10, s10: 20, s11: 30, s12: 40, s13: 50, s14: 60, s15: 70}); + g.call(v) + }, TypeError, "Getter applicable to structs"); + assertThrowsInstanceOf(function() { + var t = new int16x8(1, 2, 3, 4, 5, 6, 7, 8); + g.call(t) + }, TypeError, "Getter applicable to int16x8"); +} + +function testInt8x16Handles() { + var Array = int8x16.array(3); + var array = new Array([int8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), + int8x16(17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32), + int8x16(33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48)]); + + // Test that trying to create handle into the interior of a + // int8x16 fails. + + assertThrowsInstanceOf(function() { + var h = int8.handle(array, 1, "s3"); + }, TypeError, "Creating a int8 handle to prop via ctor"); + + assertThrowsInstanceOf(function() { + var h = int8.handle(); + Handle.move(h, array, 1, "s3"); + }, TypeError, "Creating a int8 handle to prop via move"); + + assertThrowsInstanceOf(function() { + var h = int8.handle(array, 1, 0); + }, TypeError, "Creating a int8 handle to elem via ctor"); + + assertThrowsInstanceOf(function() { + var h = int8.handle(); + Handle.move(h, array, 1, 0); + }, TypeError, "Creating a int8 handle to elem via move"); +} + +function testInt8x16Reify() { + var Array = int8x16.array(3); + var array = new Array([int8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), + int8x16(17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32), + int8x16(33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48)]); + + // Test that reading array[1] produces a *copy* of int8x16, not an + // alias into the array. + + var f = array[1]; + assertEq(f.s3, 20); + assertEq(array[1].s3, 20); + array[1] = int8x16(49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64); + assertEq(f.s3, 20); + assertEq(array[1].s3, 52); +} + +function testInt8x16Setters() { + var Array = int8x16.array(3); + var array = new Array([int8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), + int8x16(17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32), + int8x16(33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48)]); + assertEq(array[1].s3, 20); + + // Test that we are allowed to write int8x16 values into array, + // but not other things. + + array[1] = int8x16(49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64); + assertEq(array[1].s3, 52); + + assertThrowsInstanceOf(function() { + array[1] = {s0: 49, s1: 50, s2: 51, s3: 52, s4: 53, s5: 54, s6: 55, s7: 56, + s8: 57, s9: 58, s10: 59, s11: 60, s12: 61, s13: 62, s14: 63, s15: 64}; + }, TypeError, "Setting int8x16 from an object"); + + assertThrowsInstanceOf(function() { + array[1] = [49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64]; + }, TypeError, "Setting int8x16 from an array"); + + assertThrowsInstanceOf(function() { + array[1] = 52; + }, TypeError, "Setting int8x16 from a number"); +} + +function testInt16x8Alignment() { + assertEq(int16x8.byteLength, 16); + assertEq(int16x8.byteAlignment, 16); + + var Compound = new StructType({c: uint8, d: uint8, f: int16x8}); + assertEq(Compound.fieldOffsets.c, 0); + assertEq(Compound.fieldOffsets.d, 1); + assertEq(Compound.fieldOffsets.f, 16); +} + +function testInt16x8Getters() { + // Create a int16x8 and check that the getters work: + var f = int16x8(11, 22, 33, 44, 55, 66, 77, 88); + assertEq(f.s0, 11); + assertEq(f.s1, 22); + assertEq(f.s2, 33); + assertEq(f.s3, 44); + assertEq(f.s4, 55); + assertEq(f.s5, 66); + assertEq(f.s6, 77); + assertEq(f.s7, 88); + + // Test that the getters work when called reflectively: + var g = f.__lookupGetter__("s0"); + assertEq(g.call(f), 11); + + // Test that getters cannot be applied to various incorrect things: + assertThrowsInstanceOf(function() { + g.call({}) + }, TypeError, "Getter applicable to random objects"); + assertThrowsInstanceOf(function() { + g.call(0xDEADBEEF) + }, TypeError, "Getter applicable to integers"); + assertThrowsInstanceOf(function() { + var T = new StructType({s0: int16, s1: int16, s2: int16, s3: int16, s4: int16, s5: int16, s6: int16, s7: int16}); + var v = new T({s0: 11, s1: 22, s2: 33, s3: 44, s4: 55, s5: 66, s6: 77, s7: 88}); + g.call(v) + }, TypeError, "Getter applicable to structs"); + assertThrowsInstanceOf(function() { + var t = new int16x8(1, 2, 3, 4, 5, 6, 7, 8); + g.call(t) + }, TypeError, "Getter applicable to int16x8"); +} + +function testInt16x8Handles() { + var Array = int16x8.array(3); + var array = new Array([int16x8(1, 2, 3, 4, 5, 6, 7, 8), + int16x8(9, 10, 11, 12, 13, 14, 15, 16), + int16x8(17, 18, 19, 20, 21, 22, 23, 24)]); + + // Test that trying to create handle into the interior of a + // int16x8 fails. + + assertThrowsInstanceOf(function() { + var h = int16.handle(array, 1, "s3"); + }, TypeError, "Creating a int16 handle to prop via ctor"); + + assertThrowsInstanceOf(function() { + var h = int16.handle(); + Handle.move(h, array, 1, "s3"); + }, TypeError, "Creating a int16 handle to prop via move"); + + assertThrowsInstanceOf(function() { + var h = int16.handle(array, 1, 0); + }, TypeError, "Creating a int16 handle to elem via ctor"); + + assertThrowsInstanceOf(function() { + var h = int16.handle(); + Handle.move(h, array, 1, 0); + }, TypeError, "Creating a int16 handle to elem via move"); +} + +function testInt16x8Reify() { + var Array = int16x8.array(3); + var array = new Array([int16x8(1, 2, 3, 4, 5, 6, 7, 8), + int16x8(9, 10, 11, 12, 13, 14, 15, 16), + int16x8(17, 18, 19, 20, 21, 22, 23, 24)]); + + // Test that reading array[1] produces a *copy* of int16x8, not an + // alias into the array. + + var f = array[1]; + assertEq(f.s3, 12); + assertEq(array[1].s3, 12); + array[1] = int16x8(25, 26, 27, 28, 29, 30, 31, 32); + assertEq(f.s3, 12); + assertEq(array[1].s3, 28); +} + +function testInt16x8Setters() { + var Array = int16x8.array(3); + var array = new Array([int16x8(1, 2, 3, 4, 5, 6, 7, 8), + int16x8(9, 10, 11, 12, 13, 14, 15, 16), + int16x8(17, 18, 19, 20, 21, 22, 23, 24)]); + assertEq(array[1].s3, 12); + + // Test that we are allowed to write int16x8 values into array, + // but not other things. + + array[1] = int16x8(25, 26, 27, 28, 29, 30, 31, 32); + assertEq(array[1].s3, 28); + + assertThrowsInstanceOf(function() { + array[1] = {s0: 25, s1: 26, s2: 27, s3: 28, s4: 29, s5: 30, s6: 31, s7: 32}; + }, TypeError, "Setting int16x8 from an object"); + + assertThrowsInstanceOf(function() { + array[1] = [25, 26, 27, 28, 29, 30, 31, 32]; + }, TypeError, "Setting int16x8 from an array"); + + assertThrowsInstanceOf(function() { + array[1] = 28; + }, TypeError, "Setting int16x8 from a number"); +} + function testInt32x4Alignment() { assertEq(int32x4.byteLength, 16); assertEq(int32x4.byteAlignment, 16); @@ -354,6 +597,18 @@ function test() { testFloat64x2Reify(); testFloat64x2Setters(); + testInt8x16Alignment(); + testInt8x16Getters(); + testInt8x16Handles(); + testInt8x16Reify(); + testInt8x16Setters(); + + testInt16x8Alignment(); + testInt16x8Getters(); + testInt16x8Handles(); + testInt16x8Reify(); + testInt16x8Setters(); + testInt32x4Alignment(); testInt32x4Getters(); testInt32x4Handles(); diff --git a/js/src/tests/ecma_7/SIMD/unary-operations.js b/js/src/tests/ecma_7/SIMD/unary-operations.js index 5a1b2ac3cb9..a3e48fc8576 100644 --- a/js/src/tests/ecma_7/SIMD/unary-operations.js +++ b/js/src/tests/ecma_7/SIMD/unary-operations.js @@ -1,5 +1,7 @@ // |reftest| skip-if(!this.hasOwnProperty("SIMD")) var float32x4 = SIMD.float32x4; +var int8x16 = SIMD.int8x16; +var int16x8 = SIMD.int16x8; var int32x4 = SIMD.int32x4; @@ -106,6 +108,46 @@ function testFloat32x4not() { } } +function testInt8x16neg() { + var vals = [ + [[1, 2, 3, 4, 5, 6, 7, 8, -1, -2, -3, -4, -5, INT8_MAX, INT8_MIN, 0], + [-1, -2, -3, -4, -5, -6, -7, -8, 1, 2, 3, 4, 5, -INT8_MAX, INT8_MIN, 0]] + ]; + for (var [v,w] of vals) { + assertEqX16(int8x16.neg(int8x16(...v)), w); + } +} + +function testInt8x16not() { + var vals = [ + [[1, 2, 3, 4, 5, 6, 7, -1, -2, -3, -4, -5, -6, 0, INT8_MIN, INT8_MAX], + [1, 2, 3, 4, 5, 6, 7, -1, -2, -3, -4, -5, -6, 0, INT8_MIN, INT8_MAX].map((x) => ~x << 24 >> 24)] + ]; + for (var [v,w] of vals) { + assertEqX16(int8x16.not(int8x16(...v)), w); + } +} + +function testInt16x8neg() { + var vals = [ + [[1, 2, 3, -1, -2, 0, INT16_MIN, INT16_MAX], + [-1, -2, -3, 1, 2, 0, INT16_MIN, -INT16_MAX]] + ]; + for (var [v,w] of vals) { + assertEqX8(int16x8.neg(int16x8(...v)), w); + } +} + +function testInt16x8not() { + var vals = [ + [[1, 2, 3, -1, -2, 0, INT16_MIN, INT16_MAX], + [1, 2, 3, -1, -2, 0, INT16_MIN, INT16_MAX].map((x) => ~x << 16 >> 16)] + ]; + for (var [v,w] of vals) { + assertEqX8(int16x8.not(int16x8(...v)), w); + } +} + function testInt32x4neg() { var valsExp = [ [[1, 2, 3, 4], [-1, -2, -3, -4]], @@ -134,6 +176,12 @@ function test() { testFloat32x4reciprocalSqrtApproximation(); testFloat32x4sqrt(); + testInt8x16neg(); + testInt8x16not(); + + testInt16x8neg(); + testInt16x8not(); + testInt32x4neg(); testInt32x4not();