Bug 1123777: Have SIMD shifts + splat + with functions apply ToInt32 to their scalar arguments; r=till

--HG--
extra : rebase_source : 9d7aa748738c8ec1a13ac53d15946a5c8665c956
This commit is contained in:
Benjamin Bouvier 2015-02-03 20:37:05 +01:00
Родитель b06e99dd64
Коммит d8781fab29
8 изменённых файлов: 157 добавлений и 177 удалений

Просмотреть файл

@ -722,27 +722,18 @@ FuncWith(JSContext *cx, unsigned argc, Value *vp)
typedef typename V::Elem Elem; typedef typename V::Elem Elem;
CallArgs args = CallArgsFromVp(argc, vp); CallArgs args = CallArgsFromVp(argc, vp);
if (args.length() != 2 || !IsVectorObject<V>(args[0]) || if (args.length() != 2 || !IsVectorObject<V>(args[0]))
(!args[1].isNumber() && !args[1].isBoolean()))
{
return ErrorBadArgs(cx); return ErrorBadArgs(cx);
}
Elem *val = TypedObjectMemory<Elem *>(args[0]); Elem *vec = TypedObjectMemory<Elem *>(args[0]);
Elem result[V::lanes]; Elem result[V::lanes];
if (args[1].isNumber()) { Elem value;
Elem withAsNumber; if (!V::toType(cx, args[1], &value))
if (!V::toType(cx, args[1], &withAsNumber)) return false;
return false;
for (unsigned i = 0; i < V::lanes; i++) for (unsigned i = 0; i < V::lanes; i++)
result[i] = OpWith<Elem>::apply(i, withAsNumber, val[i]); result[i] = OpWith<Elem>::apply(i, value, vec[i]);
} else {
MOZ_ASSERT(args[1].isBoolean());
bool withAsBool = args[1].toBoolean();
for (unsigned i = 0; i < V::lanes; i++)
result[i] = OpWith<Elem>::apply(i, withAsBool, val[i]);
}
return StoreResult<V>(cx, args, result); return StoreResult<V>(cx, args, result);
} }
@ -816,7 +807,7 @@ Int32x4BinaryScalar(JSContext *cx, unsigned argc, Value *vp)
return ErrorBadArgs(cx); return ErrorBadArgs(cx);
int32_t result[4]; int32_t result[4];
if (!IsVectorObject<Int32x4>(args[0]) || !args[1].isNumber()) if (!IsVectorObject<Int32x4>(args[0]))
return ErrorBadArgs(cx); return ErrorBadArgs(cx);
int32_t *val = TypedObjectMemory<int32_t *>(args[0]); int32_t *val = TypedObjectMemory<int32_t *>(args[0]);
@ -911,7 +902,7 @@ FuncSplat(JSContext *cx, unsigned argc, Value *vp)
typedef typename Vret::Elem RetElem; typedef typename Vret::Elem RetElem;
CallArgs args = CallArgsFromVp(argc, vp); CallArgs args = CallArgsFromVp(argc, vp);
if (args.length() != 1 || !args[0].isNumber()) if (args.length() != 1)
return ErrorBadArgs(cx); return ErrorBadArgs(cx);
RetElem arg; RetElem arg;

Просмотреть файл

@ -273,7 +273,10 @@ struct Float32x4 {
return a; return a;
} }
static bool toType(JSContext *cx, JS::HandleValue v, Elem *out) { static bool toType(JSContext *cx, JS::HandleValue v, Elem *out) {
*out = v.toNumber(); double d;
if (!ToNumber(cx, v, &d))
return false;
*out = float(d);
return true; return true;
} }
static void setReturn(CallArgs &args, Elem value) { static void setReturn(CallArgs &args, Elem value) {
@ -293,8 +296,7 @@ struct Float64x2 {
return a; return a;
} }
static bool toType(JSContext *cx, JS::HandleValue v, Elem *out) { static bool toType(JSContext *cx, JS::HandleValue v, Elem *out) {
*out = v.toNumber(); return ToNumber(cx, v, out);
return true;
} }
static void setReturn(CallArgs &args, Elem value) { static void setReturn(CallArgs &args, Elem value) {
args.rval().setDouble(JS::CanonicalizeNaN(value)); args.rval().setDouble(JS::CanonicalizeNaN(value));

Просмотреть файл

@ -1,91 +0,0 @@
// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'float32x4 with';
function test() {
print(BUGNUMBER + ": " + summary);
var a = float32x4(1, 2, 3, 4);
var x = SIMD.float32x4.withX(a, 5);
var y = SIMD.float32x4.withY(a, 5);
var z = SIMD.float32x4.withZ(a, 5);
var w = SIMD.float32x4.withW(a, 5);
assertEq(x.x, 5);
assertEq(x.y, 2);
assertEq(x.z, 3);
assertEq(x.w, 4);
assertEq(y.x, 1);
assertEq(y.y, 5);
assertEq(y.z, 3);
assertEq(y.w, 4);
assertEq(z.x, 1);
assertEq(z.y, 2);
assertEq(z.z, 5);
assertEq(z.w, 4);
assertEq(w.x, 1);
assertEq(w.y, 2);
assertEq(w.z, 3);
assertEq(w.w, 5);
var b = float32x4(1.87, 2.08, 3.84, 4.17);
var x1 = SIMD.float32x4.withX(b, 5.38);
var y1 = SIMD.float32x4.withY(b, 5.19);
var z1 = SIMD.float32x4.withZ(b, 5.11);
var w1 = SIMD.float32x4.withW(b, 5.07);
assertEq(x1.x, Math.fround(5.38));
assertEq(x1.y, Math.fround(2.08));
assertEq(x1.z, Math.fround(3.84));
assertEq(x1.w, Math.fround(4.17));
assertEq(y1.x, Math.fround(1.87));
assertEq(y1.y, Math.fround(5.19));
assertEq(y1.z, Math.fround(3.84));
assertEq(y1.w, Math.fround(4.17));
assertEq(z1.x, Math.fround(1.87));
assertEq(z1.y, Math.fround(2.08));
assertEq(z1.z, Math.fround(5.11));
assertEq(z1.w, Math.fround(4.17));
assertEq(w1.x, Math.fround(1.87));
assertEq(w1.y, Math.fround(2.08));
assertEq(w1.z, Math.fround(3.84));
assertEq(w1.w, Math.fround(5.07));
var c = float32x4(NaN, -0, Infinity, -Infinity);
var x2 = SIMD.float32x4.withX(c, 0);
var y2 = SIMD.float32x4.withY(c, 0);
var z2 = SIMD.float32x4.withZ(c, 0);
var w2 = SIMD.float32x4.withW(c, 0);
assertEq(x2.x, 0);
assertEq(x2.y, -0);
assertEq(x2.z, Infinity);
assertEq(x2.w, -Infinity);
assertEq(y2.x, NaN);
assertEq(y2.y, 0);
assertEq(y2.z, Infinity);
assertEq(y2.w, -Infinity);
assertEq(z2.x, NaN);
assertEq(z2.y, -0);
assertEq(z2.z, 0);
assertEq(z2.w, -Infinity);
assertEq(w2.x, NaN);
assertEq(w2.y, -0);
assertEq(w2.z, Infinity);
assertEq(w2.w, 0);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

Просмотреть файл

@ -1,36 +0,0 @@
// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
var BUGNUMBER = 1031203;
var float64x2 = SIMD.float64x2;
var summary = 'float64x2 with';
/*
* Any copyright is dedicated to the Public Domain.
* https://creativecommons.org/publicdomain/zero/1.0/
*/
function test() {
print(BUGNUMBER + ": " + summary);
var a = float64x2(1, 2);
var x = float64x2.withX(a, 5);
var y = float64x2.withY(a, 5);
assertEq(x.x, 5);
assertEq(x.y, 2);
assertEq(y.x, 1);
assertEq(y.y, 5);
var b = float64x2(NaN, -0);
var x1 = float64x2.withX(b, Infinity);
var y1 = float64x2.withY(b, -Infinity);
assertEq(x1.x, Infinity);
assertEq(x1.y, -0);
assertEq(y1.x, NaN);
assertEq(y1.y, -Infinity);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

Просмотреть файл

@ -1,28 +0,0 @@
// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'int32x4 with';
function test() {
print(BUGNUMBER + ": " + summary);
var INT32_MAX = Math.pow(2, 31) - 1;
var a = int32x4(1, 2, 3, 4);
var x = SIMD.int32x4.withX(a, 5);
var y = SIMD.int32x4.withY(a, 5);
var z = SIMD.int32x4.withZ(a, 5);
var w = SIMD.int32x4.withW(a, INT32_MAX + 1);
assertEq(x.x, 5);
assertEq(y.y, 5);
assertEq(z.z, 5);
assertEq(w.w, (INT32_MAX + 1) | 0);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

Просмотреть файл

@ -18,6 +18,11 @@ function ursh(a, b) {
} }
function test() { function test() {
function TestError() {};
var good = {valueOf: () => 21};
var bad = {valueOf: () => {throw new TestError(); }};
for (var v of [ for (var v of [
int32x4(-1, 2, -3, 4), int32x4(-1, 2, -3, 4),
int32x4(INT32_MAX, INT32_MIN, INT32_MAX - 1, INT32_MIN + 1) int32x4(INT32_MAX, INT32_MIN, INT32_MAX - 1, INT32_MIN + 1)
@ -28,8 +33,17 @@ function test() {
testBinaryScalarFunc(v, bits, int32x4.shiftRightArithmeticByScalar, rsh); testBinaryScalarFunc(v, bits, int32x4.shiftRightArithmeticByScalar, rsh);
testBinaryScalarFunc(v, bits, int32x4.shiftRightLogicalByScalar, ursh); testBinaryScalarFunc(v, bits, int32x4.shiftRightLogicalByScalar, ursh);
} }
// 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);
} }
var v = SIMD.int32x4(1,2,3,4);
assertThrowsInstanceOf(() => SIMD.int32x4.shiftLeftByScalar(v, bad), TestError);
assertThrowsInstanceOf(() => SIMD.int32x4.shiftRightArithmeticByScalar(v, bad), TestError);
assertThrowsInstanceOf(() => SIMD.int32x4.shiftRightLogicalByScalar(v, bad), TestError);
if (typeof reportCompare === "function") if (typeof reportCompare === "function")
reportCompare(true, true); reportCompare(true, true);
} }

Просмотреть файл

@ -0,0 +1,38 @@
// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
var float64x2 = SIMD.float64x2;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
function TestSplatX4(type, inputs, coerceFunc) {
for (var x of inputs) {
assertEqX4(SIMD[type].splat(x), [x, x, x, x].map(coerceFunc));
}
}
function TestSplatX2(type, inputs, coerceFunc) {
for (var x of inputs) {
assertEqX2(SIMD[type].splat(x), [x, x].map(coerceFunc));
}
}
function test() {
function TestError(){};
var good = {valueOf: () => 19.89};
var bad = {valueOf: () => { throw new TestError(); }};
TestSplatX4('int32x4', [0, undefined, 3.5, 42, -1337, INT32_MAX, INT32_MAX + 1, good], (x) => x | 0);
assertThrowsInstanceOf(() => SIMD.int32x4.splat(bad), TestError);
TestSplatX4('float32x4', [0, undefined, 3.5, 42, -13.37, Infinity, NaN, -0, good], (x) => Math.fround(x));
assertThrowsInstanceOf(() => SIMD.float32x4.splat(bad), TestError);
TestSplatX2('float64x2', [0, undefined, 3.5, 42, -13.37, Infinity, NaN, -0, good], (x) => +x);
assertThrowsInstanceOf(() => SIMD.float64x2.splat(bad), TestError);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

Просмотреть файл

@ -0,0 +1,90 @@
// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var float64x2 = SIMD.float64x2;
var summary = 'with{X,Y,Z,W}';
function withX(arr, x) {
if (arr.length == 2)
return [x, arr[1]];
return [x, arr[1], arr[2], arr[3]];
}
function withY(arr, x) {
if (arr.length == 2)
return [arr[0], x];
return [arr[0], x, arr[2], arr[3]];
}
function withZ(arr, x) {
return [arr[0], arr[1], x, arr[3]];
}
function withW(arr, x) {
return [arr[0], arr[1], arr[2], x];
}
function testWith(vec, scalar, simdFunc, func) {
var varr = simdToArray(vec);
var observed = simdToArray(simdFunc(vec, scalar));
var expected = func(varr, scalar);
for (var i = 0; i < observed.length; i++)
assertEq(observed[i], expected[i]);
}
function test() {
print(BUGNUMBER + ": " + summary);
function testType(type, inputs) {
var length = simdToArray(inputs[0][0]).length;
for (var [vec, s] of inputs) {
testWith(vec, s, SIMD[type].withX, withX);
testWith(vec, s, SIMD[type].withY, withY);
if (length <= 2)
continue;
testWith(vec, s, SIMD[type].withZ, withZ);
testWith(vec, s, SIMD[type].withW, withW);
}
}
function TestError(){};
var good = {valueOf: () => 42};
var bad = {valueOf: () => {throw new TestError(); }};
var float32x4inputs = [
[float32x4(1, 2, 3, 4), 5],
[float32x4(1.87, 2.08, 3.84, 4.17), Math.fround(13.37)],
[float32x4(NaN, -0, Infinity, -Infinity), 0]
];
testType('float32x4', float32x4inputs);
var v = float32x4inputs[1][0];
assertEqX4(float32x4.withX(v, good), withX(simdToArray(v), good | 0));
assertThrowsInstanceOf(() => float32x4.withX(v, bad), TestError);
var float64x2inputs = [
[float64x2(1, 2), 5],
[float64x2(1.87, 2.08), Math.fround(13.37)],
[float64x2(NaN, -0), 0]
];
testType('float64x2', float64x2inputs);
var v = float64x2inputs[1][0];
assertEqX4(float64x2.withX(v, good), withX(simdToArray(v), good | 0));
assertThrowsInstanceOf(() => float64x2.withX(v, bad), TestError);
var int32x4inputs = [
[int32x4(1, 2, 3, 4), 5],
[int32x4(INT32_MIN, INT32_MAX, 3, 4), INT32_MIN],
];
testType('int32x4', int32x4inputs);
var v = int32x4inputs[1][0];
assertEqX4(int32x4.withX(v, good), withX(simdToArray(v), good | 0));
assertThrowsInstanceOf(() => int32x4.withX(v, bad), TestError);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();