Bug 1112627: Implement shift count saturation; r=Waldo

--HG--
extra : rebase_source : c4c19f9f65f8fc88f45336e2e6f0ece708ae843f
This commit is contained in:
Benjamin Bouvier 2015-04-07 19:47:40 +02:00
Родитель 99fb0c1bf1
Коммит 8d6bd07f3f
3 изменённых файлов: 18 добавлений и 9 удалений

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

@ -601,14 +601,23 @@ template<typename T>
struct WithW {
static inline T apply(int32_t lane, T scalar, T x) { return lane == 3 ? scalar : x; }
};
// For the following three operators, if the value v we're trying to shift is
// such that v << bits can't fit in the int32 range, then we have undefined
// behavior, according to C++11 [expr.shift]p2.
struct ShiftLeft {
static inline int32_t apply(int32_t v, int32_t bits) { return v << bits; }
static inline int32_t apply(int32_t v, int32_t bits) {
return uint32_t(bits) >= 32 ? 0 : v << bits;
}
};
struct ShiftRight {
static inline int32_t apply(int32_t v, int32_t bits) { return v >> bits; }
struct ShiftRightArithmetic {
static inline int32_t apply(int32_t v, int32_t bits) {
return v >> (uint32_t(bits) >= 32 ? 31 : bits);
}
};
struct ShiftRightLogical {
static inline int32_t apply(int32_t v, int32_t bits) { return uint32_t(v) >> (bits & 31); }
static inline int32_t apply(int32_t v, int32_t bits) {
return uint32_t(bits) >= 32 ? 0 : uint32_t(v) >> bits;
}
};
}

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

@ -157,7 +157,7 @@
V(or, (BinaryFunc<Int32x4, Or, Int32x4>), 2) \
V(sub, (BinaryFunc<Int32x4, Sub, Int32x4>), 2) \
V(shiftLeftByScalar, (Int32x4BinaryScalar<ShiftLeft>), 2) \
V(shiftRightArithmeticByScalar, (Int32x4BinaryScalar<ShiftRight>), 2) \
V(shiftRightArithmeticByScalar, (Int32x4BinaryScalar<ShiftRightArithmetic>), 2) \
V(shiftRightLogicalByScalar, (Int32x4BinaryScalar<ShiftRightLogical>), 2) \
V(store, (Store<Int32x4, 4>), 3) \
V(storeXYZ, (Store<Int32x4, 3>), 3) \

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

@ -8,13 +8,13 @@
var int32x4 = SIMD.int32x4;
function lsh(a, b) {
return (a << b) | 0;
return (b >>> 0) >= 32 ? 0 : (a << b) | 0;
}
function rsh(a, b) {
return (a >> b) | 0;
return (a >> Math.min(b >>> 0, 31)) | 0;
}
function ursh(a, b) {
return (a >>> b) | 0;
return (b >>> 0) >= 32 ? 0 : (a >>> b) | 0;
}
function test() {
@ -28,7 +28,7 @@ function test() {
int32x4(INT32_MAX, INT32_MIN, INT32_MAX - 1, INT32_MIN + 1)
])
{
for (var bits = 0; bits < 32; bits++) {
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);