Bug 1094855: SIMD: Add minNum/maxNum and update min/max in the interpreter; r=till

--HG--
rename : js/src/tests/ecma_6/TypedObject/simd/float32x4max.js => js/src/tests/ecma_6/TypedObject/simd/float32x4-minmax.js
This commit is contained in:
Benjamin Bouvier 2014-11-21 17:27:17 +01:00
parent 1573dcdb29
commit 1479e9ee9d
10 changed files with 98 additions and 87 deletions

View File

@ -508,11 +508,19 @@ struct Mul {
};
template<typename T>
struct Minimum {
static inline T apply(T l, T r) { return l < r ? l : r; }
static inline T apply(T l, T r) { return math_min_impl(l, r); }
};
template<typename T>
struct MinNum {
static inline T apply(T l, T r) { return IsNaN(l) ? r : (IsNaN(r) ? l : math_min_impl(l, r)); }
};
template<typename T>
struct Maximum {
static inline T apply(T l, T r) { return l > r ? l : r; }
static inline T apply(T l, T r) { return math_max_impl(l, r); }
};
template<typename T>
struct MaxNum {
static inline T apply(T l, T r) { return IsNaN(l) ? r : (IsNaN(r) ? l : math_max_impl(l, r)); }
};
template<typename T>
struct LessThan {

View File

@ -46,7 +46,9 @@
V(loadXY, (Load<Float32x4, 2>), 2, 0) \
V(loadX, (Load<Float32x4, 1>), 2, 0) \
V(max, (BinaryFunc<Float32x4, Maximum, Float32x4>), 2, 0) \
V(maxNum, (BinaryFunc<Float32x4, MaxNum, Float32x4>), 2, 0) \
V(min, (BinaryFunc<Float32x4, Minimum, Float32x4>), 2, 0) \
V(minNum, (BinaryFunc<Float32x4, MinNum, Float32x4>), 2, 0) \
V(mul, (BinaryFunc<Float32x4, Mul, Float32x4>), 2, 0) \
V(notEqual, (CompareFunc<Float32x4, NotEqual>), 2, 0) \
V(or, (CoercedBinaryFunc<Float32x4, Int32x4, Or, Float32x4>), 2, 0) \

View File

@ -565,8 +565,8 @@ js::math_log(JSContext *cx, unsigned argc, Value *vp)
return true;
}
static double
max_double(double x, double y)
double
js::math_max_impl(double x, double y)
{
// Math.max(num, NaN) => NaN, Math.max(-0, +0) => +0
if (x > y || IsNaN(x) || (x == y && IsNegative(y)))
@ -584,14 +584,14 @@ js::math_max(JSContext *cx, unsigned argc, Value *vp)
double x;
if (!ToNumber(cx, args[i], &x))
return false;
maxval = max_double(x, maxval);
maxval = math_max_impl(x, maxval);
}
args.rval().setNumber(maxval);
return true;
}
static double
min_double(double x, double y)
double
js::math_min_impl(double x, double y)
{
// Math.min(num, NaN) => NaN, Math.min(-0, +0) => -0
if (x < y || IsNaN(x) || (x == y && IsNegativeZero(x)))
@ -609,7 +609,7 @@ js::math_min(JSContext *cx, unsigned argc, Value *vp)
double x;
if (!ToNumber(cx, args[i], &x))
return false;
minval = min_double(x, minval);
minval = math_min_impl(x, minval);
}
args.rval().setNumber(minval);
return true;
@ -626,9 +626,9 @@ js::minmax_impl(JSContext *cx, bool max, HandleValue a, HandleValue b, MutableHa
return false;
if (max)
res.setNumber(max_double(x, y));
res.setNumber(math_max_impl(x, y));
else
res.setNumber(min_double(x, y));
res.setNumber(math_min_impl(x, y));
return true;
}

View File

@ -120,9 +120,15 @@ math_abs_handle(JSContext *cx, js::HandleValue v, js::MutableHandleValue r);
extern bool
math_abs(JSContext *cx, unsigned argc, js::Value *vp);
extern double
math_max_impl(double x, double y);
extern bool
math_max(JSContext *cx, unsigned argc, js::Value *vp);
extern double
math_min_impl(double x, double y);
extern bool
math_min(JSContext *cx, unsigned argc, js::Value *vp);

View File

@ -0,0 +1,54 @@
// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
function testMaxFloat32(v, w) {
return testBinaryFunc(v, w, float32x4.max, (x, y) => Math.fround(Math.max(x, y)));
}
function testMinFloat32(v, w) {
return testBinaryFunc(v, w, float32x4.min, (x, y) => Math.fround(Math.min(x, y)));
}
function maxNum(x, y) {
if (x != x)
return y;
if (y != y)
return x;
return Math.max(x, y);
}
function minNum(x, y) {
if (x != x)
return y;
if (y != y)
return x;
return Math.min(x, y);
}
function testMaxNumFloat32(v, w) {
return testBinaryFunc(v, w, float32x4.maxNum, maxNum);
}
function testMinNumFloat32(v, w) {
return testBinaryFunc(v, w, float32x4.minNum, minNum);
}
function test() {
print(BUGNUMBER + ": " + summary);
for ([v, w] of [[float32x4(1, 20, 30, 4), float32x4(10, 2, 3, 40)],
[float32x4(9.999, 2.1234, 30.4443, 4), float32x4(10, 2.1233, 30.4444, 4.0001)],
[float32x4(NaN, -Infinity, +Infinity, -0), float32x4(13.37, 42.42, NaN, 0)]])
{
testMinFloat32(v, w);
testMaxFloat32(v, w);
testMinNumFloat32(v, w);
testMaxNumFloat32(v, w);
}
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -1,35 +0,0 @@
// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'float32x4 max';
function test() {
print(BUGNUMBER + ": " + summary);
// FIXME -- Bug 1081697: Amend to check for correctness of -0/Infinity/-Infinity border cases.
// FIXME -- Bug 1068028: Amend to check for correctness of NaN border cases once the semantics are defined.
var a = float32x4(1, 20, 30, 4);
var b = float32x4(10, 2, 3, 40);
var c = SIMD.float32x4.max(a, b);
assertEq(c.x, 10);
assertEq(c.y, 20);
assertEq(c.z, 30);
assertEq(c.w, 40);
var d = float32x4(9.999, 2.1234, 30.4443, 4);
var e = float32x4(10, 2.1233, 30.4444, 4.0001);
var f = float32x4.max(d, e);
assertEq(f.x, 10);
assertEq(f.y, Math.fround(2.1234));
assertEq(f.z, Math.fround(30.4444));
assertEq(f.w, Math.fround(4.0001));
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -1,35 +0,0 @@
// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'float32x4 min';
function test() {
print(BUGNUMBER + ": " + summary);
// FIXME -- Bug 1081697: Amend to check for correctness of -0/Infinity/-Infinity border cases.
// FIXME -- Bug 1068028: Amend to check for correctness of NaN border cases once the semantics are defined.
var a = float32x4(1, 20, 3, 40);
var b = float32x4(10, 2, 30, 4);
var c = SIMD.float32x4.min(a, b);
assertEq(c.x, 1);
assertEq(c.y, 2);
assertEq(c.z, 3);
assertEq(c.w, 4);
var d = float32x4(1.4321, 20.5567, 30.8999, 4.0002);
var e = float32x4(1.432, 20.5568, 30.8998, 4.0001);
var f = float32x4.min(d, e);
assertEq(f.x, Math.fround(1.432));
assertEq(f.y, Math.fround(20.5567));
assertEq(f.z, Math.fround(30.8998));
assertEq(f.w, Math.fround(4.0001));
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -4,9 +4,6 @@ var int32x4 = SIMD.int32x4;
var summary = 'int32x4 select';
const INT32_MAX = Math.pow(2, 31) - 1;
const INT32_MIN = INT32_MAX + 1 | 0;
function test() {
print(BUGNUMBER + ": " + summary);

View File

@ -10,3 +10,21 @@ function assertEqX4(v, arr) {
}
}
function simdToArray(v) {
return [v.x, v.y, v.z, v.w];
}
const INT32_MAX = Math.pow(2, 31) - 1;
const INT32_MIN = -Math.pow(2, 31);
assertEq(INT32_MAX + 1 | 0, INT32_MIN);
function testBinaryFunc(v, w, simdFunc, func) {
var varr = simdToArray(v);
var warr = simdToArray(w);
var observed = simdToArray(simdFunc(v, w));
var expected = varr.map(function(v, i) { return func(varr[i], warr[i]); });
for (var i = 0; i < observed.length; i++)
assertEq(observed[i], expected[i]);
}

View File

@ -8,10 +8,6 @@
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
function simdToArray(v) {
return [v.x, v.y, v.z, v.w];
}
function swizzle(arr, x, y, z, w) {
return [arr[x], arr[y], arr[z], arr[w]];
}