зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1233111 - Implement SIMD shiftRightByScalar(). r=bbouvier
This is the right shift function that the SIMD.js spec requires. The old shiftRightArithmeticByScalar() and shiftRightLogicalByScalar() functions will go away. These functions perform an arithmetic shift for signed types and a logical shift for unsigned types. Add support to Odin and Ion too, at least for the Int32x4 variant. --HG-- extra : rebase_source : 7852f266a1ad505436c4c1607c17d542d81b2673
This commit is contained in:
Родитель
c265e4ff17
Коммит
4ac36bc255
|
@ -77,6 +77,19 @@ enum AsmJSSimdType
|
|||
AsmJSSimdType_bool32x4
|
||||
};
|
||||
|
||||
static inline bool
|
||||
IsSignedIntSimdType(AsmJSSimdType type)
|
||||
{
|
||||
switch (type) {
|
||||
case AsmJSSimdType_int32x4:
|
||||
return true;
|
||||
case AsmJSSimdType_float32x4:
|
||||
case AsmJSSimdType_bool32x4:
|
||||
return false;
|
||||
}
|
||||
MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("Unknown SIMD type");
|
||||
}
|
||||
|
||||
// Set of known operations, for a given SIMD type (int32x4, float32x4,...)
|
||||
enum AsmJSSimdOperation
|
||||
{
|
||||
|
|
|
@ -4970,6 +4970,10 @@ CheckSimdOperationCall(FunctionValidator& f, ParseNode* call, const ModuleValida
|
|||
|
||||
case AsmJSSimdOperation_shiftLeftByScalar:
|
||||
return CheckSimdBinary(f, call, opType, MSimdShift::lsh, type);
|
||||
case AsmJSSimdOperation_shiftRightByScalar:
|
||||
return CheckSimdBinary(f, call, opType,
|
||||
IsSignedIntSimdType(opType) ? MSimdShift::rsh : MSimdShift::ursh,
|
||||
type);
|
||||
case AsmJSSimdOperation_shiftRightArithmeticByScalar:
|
||||
return CheckSimdBinary(f, call, opType, MSimdShift::rsh, type);
|
||||
case AsmJSSimdOperation_shiftRightLogicalByScalar:
|
||||
|
|
|
@ -247,6 +247,7 @@
|
|||
V(or, (BinaryFunc<Int8x16, Or, Int8x16>), 2) \
|
||||
V(sub, (BinaryFunc<Int8x16, Sub, Int8x16>), 2) \
|
||||
V(shiftLeftByScalar, (BinaryScalar<Int8x16, ShiftLeft>), 2) \
|
||||
V(shiftRightByScalar, (BinaryScalar<Int8x16, ShiftRightArithmetic>), 2) \
|
||||
V(shiftRightArithmeticByScalar, (BinaryScalar<Int8x16, ShiftRightArithmetic>), 2) \
|
||||
V(shiftRightLogicalByScalar, (BinaryScalar<Int8x16, ShiftRightLogical>), 2) \
|
||||
V(xor, (BinaryFunc<Int8x16, Xor, Int8x16>), 2)
|
||||
|
@ -295,6 +296,7 @@
|
|||
V(or, (BinaryFunc<Uint8x16, Or, Uint8x16>), 2) \
|
||||
V(sub, (BinaryFunc<Uint8x16, Sub, Uint8x16>), 2) \
|
||||
V(shiftLeftByScalar, (BinaryScalar<Uint8x16, ShiftLeft>), 2) \
|
||||
V(shiftRightByScalar, (BinaryScalar<Uint8x16, ShiftRightLogical>), 2) \
|
||||
V(shiftRightArithmeticByScalar, (BinaryScalar<Uint8x16, ShiftRightArithmetic>), 2) \
|
||||
V(shiftRightLogicalByScalar, (BinaryScalar<Uint8x16, ShiftRightLogical>), 2) \
|
||||
V(xor, (BinaryFunc<Uint8x16, Xor, Uint8x16>), 2)
|
||||
|
@ -343,6 +345,7 @@
|
|||
V(or, (BinaryFunc<Int16x8, Or, Int16x8>), 2) \
|
||||
V(sub, (BinaryFunc<Int16x8, Sub, Int16x8>), 2) \
|
||||
V(shiftLeftByScalar, (BinaryScalar<Int16x8, ShiftLeft>), 2) \
|
||||
V(shiftRightByScalar, (BinaryScalar<Int16x8, ShiftRightArithmetic>), 2) \
|
||||
V(shiftRightArithmeticByScalar, (BinaryScalar<Int16x8, ShiftRightArithmetic>), 2) \
|
||||
V(shiftRightLogicalByScalar, (BinaryScalar<Int16x8, ShiftRightLogical>), 2) \
|
||||
V(xor, (BinaryFunc<Int16x8, Xor, Int16x8>), 2)
|
||||
|
@ -391,6 +394,7 @@
|
|||
V(or, (BinaryFunc<Uint16x8, Or, Uint16x8>), 2) \
|
||||
V(sub, (BinaryFunc<Uint16x8, Sub, Uint16x8>), 2) \
|
||||
V(shiftLeftByScalar, (BinaryScalar<Uint16x8, ShiftLeft>), 2) \
|
||||
V(shiftRightByScalar, (BinaryScalar<Uint16x8, ShiftRightLogical>), 2) \
|
||||
V(shiftRightArithmeticByScalar, (BinaryScalar<Uint16x8, ShiftRightArithmetic>), 2) \
|
||||
V(shiftRightLogicalByScalar, (BinaryScalar<Uint16x8, ShiftRightLogical>), 2) \
|
||||
V(xor, (BinaryFunc<Uint16x8, Xor, Uint16x8>), 2)
|
||||
|
@ -443,6 +447,7 @@
|
|||
V(or, (BinaryFunc<Int32x4, Or, Int32x4>), 2) \
|
||||
V(sub, (BinaryFunc<Int32x4, Sub, Int32x4>), 2) \
|
||||
V(shiftLeftByScalar, (BinaryScalar<Int32x4, ShiftLeft>), 2) \
|
||||
V(shiftRightByScalar, (BinaryScalar<Int32x4, ShiftRightArithmetic>), 2) \
|
||||
V(shiftRightArithmeticByScalar, (BinaryScalar<Int32x4, ShiftRightArithmetic>), 2) \
|
||||
V(shiftRightLogicalByScalar, (BinaryScalar<Int32x4, ShiftRightLogical>), 2) \
|
||||
V(xor, (BinaryFunc<Int32x4, Xor, Int32x4>), 2)
|
||||
|
@ -498,6 +503,7 @@
|
|||
V(or, (BinaryFunc<Uint32x4, Or, Uint32x4>), 2) \
|
||||
V(sub, (BinaryFunc<Uint32x4, Sub, Uint32x4>), 2) \
|
||||
V(shiftLeftByScalar, (BinaryScalar<Uint32x4, ShiftLeft>), 2) \
|
||||
V(shiftRightByScalar, (BinaryScalar<Uint32x4, ShiftRightLogical>), 2) \
|
||||
V(shiftRightArithmeticByScalar, (BinaryScalar<Uint32x4, ShiftRightArithmetic>), 2) \
|
||||
V(shiftRightLogicalByScalar, (BinaryScalar<Uint32x4, ShiftRightLogical>), 2) \
|
||||
V(xor, (BinaryFunc<Uint32x4, Xor, Uint32x4>), 2)
|
||||
|
@ -572,6 +578,7 @@
|
|||
// Bitwise shifts defined on integer SIMD types.
|
||||
#define FOREACH_SHIFT_SIMD_OP(_) \
|
||||
_(shiftLeftByScalar) \
|
||||
_(shiftRightByScalar) \
|
||||
_(shiftRightArithmeticByScalar) \
|
||||
_(shiftRightLogicalByScalar)
|
||||
|
||||
|
|
|
@ -44,6 +44,13 @@ function f() {
|
|||
assertEqX4(SIMD.Int32x4.shiftRightLogicalByScalar(v, 31), a.map(ursh(31)));
|
||||
assertEqX4(SIMD.Int32x4.shiftRightLogicalByScalar(v, 32), a.map(ursh(32)));
|
||||
|
||||
assertEqX4(SIMD.Int32x4.shiftRightByScalar(v, -1), a.map(rsh(31)));
|
||||
assertEqX4(SIMD.Int32x4.shiftRightByScalar(v, 0), a.map(rsh(0)));
|
||||
assertEqX4(SIMD.Int32x4.shiftRightByScalar(v, 1), a.map(rsh(1)));
|
||||
assertEqX4(SIMD.Int32x4.shiftRightByScalar(v, 2), a.map(rsh(2)));
|
||||
assertEqX4(SIMD.Int32x4.shiftRightByScalar(v, 31), a.map(rsh(31)));
|
||||
assertEqX4(SIMD.Int32x4.shiftRightByScalar(v, 32), a.map(rsh(31)));
|
||||
|
||||
// Non constant shift counts
|
||||
var c = shifts[i % shifts.length];
|
||||
assertEqX4(SIMD.Int32x4.shiftLeftByScalar(v, c), a.map(lsh(c)));
|
||||
|
|
|
@ -924,7 +924,8 @@ assertAsmTypeFail('glob', USE_ASM + F32 + CF32 + NOTF32 + 'function f() {var x=f
|
|||
|
||||
// Logical ops
|
||||
const LSHI = 'var lsh=i4.shiftLeftByScalar;'
|
||||
const RSHI = 'var rsh=i4.shiftRightArithmeticByScalar;'
|
||||
const RSHI = 'var rsh=i4.shiftRightByScalar;'
|
||||
const ARSHI = 'var arsh=i4.shiftRightArithmeticByScalar;'
|
||||
const URSHI = 'var ursh=i4.shiftRightLogicalByScalar;'
|
||||
|
||||
assertAsmTypeFail('glob', USE_ASM + I32 + CI32 + F32 + FROUND + LSHI + "function f() {var x=f4(1,2,3,4); return ci4(lsh(x,f32(42)));} return f");
|
||||
|
@ -940,19 +941,23 @@ var vinput = [0, 1, INT32_MIN, INT32_MAX];
|
|||
// Behave as x86 for now, fix when more broadly specified. See also bug 1068028
|
||||
function Lsh(i) { if (i > 31) return () => 0; return function(x) { return (x << i) | 0 } }
|
||||
function Rsh(i) { if (i > 31) return (x) => (x<0)?-1:0; return function(x) { return (x >> i) | 0 } }
|
||||
function Arsh(i) { if (i > 31) return (x) => (x<0)?-1:0; return function(x) { return (x >> i) | 0 } }
|
||||
function Ursh(i) { if (i > 31) return () => 0; return function(x) { return (x >>> i) | 0 } }
|
||||
|
||||
var asmLsh = asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + LSHI + 'function f(x, y){x=x|0;y=y|0; var v=' + input + ';return ci4(lsh(v, x+y))} return f;'), this)
|
||||
var asmRsh = asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + RSHI + 'function f(x, y){x=x|0;y=y|0; var v=' + input + ';return ci4(rsh(v, x+y))} return f;'), this)
|
||||
var asmArsh = asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + ARSHI + 'function f(x, y){x=x|0;y=y|0; var v=' + input + ';return ci4(arsh(v, x+y))} return f;'), this)
|
||||
var asmUrsh = asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + URSHI + 'function f(x, y){x=x|0;y=y|0; var v=' + input + ';return ci4(ursh(v, x+y))} return f;'), this)
|
||||
|
||||
for (var i = 1; i < 64; i++) {
|
||||
CheckI4(LSHI, 'var x=' + input + '; x=lsh(x, ' + i + ')', vinput.map(Lsh(i)));
|
||||
CheckI4(RSHI, 'var x=' + input + '; x=rsh(x, ' + i + ')', vinput.map(Rsh(i)));
|
||||
CheckI4(ARSHI, 'var x=' + input + '; x=arsh(x, ' + i + ')', vinput.map(Arsh(i)));
|
||||
CheckI4(URSHI, 'var x=' + input + '; x=ursh(x, ' + i + ')', vinput.map(Ursh(i)));
|
||||
|
||||
assertEqX4(asmLsh(i, 3), vinput.map(Lsh(i + 3)));
|
||||
assertEqX4(asmRsh(i, 3), vinput.map(Rsh(i + 3)));
|
||||
assertEqX4(asmArsh(i, 3), vinput.map(Arsh(i + 3)));
|
||||
assertEqX4(asmUrsh(i, 3), vinput.map(Ursh(i + 3)));
|
||||
}
|
||||
|
||||
|
|
|
@ -3107,8 +3107,10 @@ IonBuilder::inlineSimdInt32x4(CallInfo& callInfo, JSNative native)
|
|||
|
||||
if (native == js::simd_int32x4_shiftLeftByScalar)
|
||||
return inlineBinarySimd<MSimdShift>(callInfo, native, MSimdShift::lsh, SimdTypeDescr::Int32x4);
|
||||
if (native == js::simd_int32x4_shiftRightArithmeticByScalar)
|
||||
if (native == js::simd_int32x4_shiftRightArithmeticByScalar ||
|
||||
native == js::simd_int32x4_shiftRightByScalar) {
|
||||
return inlineBinarySimd<MSimdShift>(callInfo, native, MSimdShift::rsh, SimdTypeDescr::Int32x4);
|
||||
}
|
||||
if (native == js::simd_int32x4_shiftRightLogicalByScalar)
|
||||
return inlineBinarySimd<MSimdShift>(callInfo, native, MSimdShift::ursh, SimdTypeDescr::Int32x4);
|
||||
|
||||
|
|
|
@ -91,6 +91,7 @@ function test() {
|
|||
{
|
||||
for (var bits = -2; bits < 12; bits++) {
|
||||
testBinaryScalarFunc(v, bits, Int8x16.shiftLeftByScalar, lsh8);
|
||||
testBinaryScalarFunc(v, bits, Int8x16.shiftRightByScalar, rsha8);
|
||||
testBinaryScalarFunc(v, bits, Int8x16.shiftRightArithmeticByScalar, rsha8);
|
||||
testBinaryScalarFunc(v, bits, Int8x16.shiftRightLogicalByScalar, rshl8);
|
||||
}
|
||||
|
@ -106,6 +107,7 @@ function test() {
|
|||
{
|
||||
for (var bits = -2; bits < 20; bits++) {
|
||||
testBinaryScalarFunc(v, bits, Int16x8.shiftLeftByScalar, lsh16);
|
||||
testBinaryScalarFunc(v, bits, Int16x8.shiftRightByScalar, rsha16);
|
||||
testBinaryScalarFunc(v, bits, Int16x8.shiftRightArithmeticByScalar, rsha16);
|
||||
testBinaryScalarFunc(v, bits, Int16x8.shiftRightLogicalByScalar, rshl16);
|
||||
}
|
||||
|
@ -121,6 +123,7 @@ function test() {
|
|||
{
|
||||
for (var bits = -2; bits < 36; bits++) {
|
||||
testBinaryScalarFunc(v, bits, Int32x4.shiftLeftByScalar, lsh32);
|
||||
testBinaryScalarFunc(v, bits, Int32x4.shiftRightByScalar, rsha32);
|
||||
testBinaryScalarFunc(v, bits, Int32x4.shiftRightArithmeticByScalar, rsha32);
|
||||
testBinaryScalarFunc(v, bits, Int32x4.shiftRightLogicalByScalar, rshl32);
|
||||
}
|
||||
|
@ -137,6 +140,7 @@ function test() {
|
|||
{
|
||||
for (var bits = -2; bits < 12; bits++) {
|
||||
testBinaryScalarFunc(v, bits, Uint8x16.shiftLeftByScalar, ulsh8);
|
||||
testBinaryScalarFunc(v, bits, Uint8x16.shiftRightByScalar, urshl8);
|
||||
testBinaryScalarFunc(v, bits, Uint8x16.shiftRightArithmeticByScalar, ursha8);
|
||||
testBinaryScalarFunc(v, bits, Uint8x16.shiftRightLogicalByScalar, urshl8);
|
||||
}
|
||||
|
@ -152,6 +156,7 @@ function test() {
|
|||
{
|
||||
for (var bits = -2; bits < 20; bits++) {
|
||||
testBinaryScalarFunc(v, bits, Uint16x8.shiftLeftByScalar, ulsh16);
|
||||
testBinaryScalarFunc(v, bits, Uint16x8.shiftRightByScalar, urshl16);
|
||||
testBinaryScalarFunc(v, bits, Uint16x8.shiftRightArithmeticByScalar, ursha16);
|
||||
testBinaryScalarFunc(v, bits, Uint16x8.shiftRightLogicalByScalar, urshl16);
|
||||
}
|
||||
|
@ -168,6 +173,7 @@ function test() {
|
|||
{
|
||||
for (var bits = -2; bits < 36; bits++) {
|
||||
testBinaryScalarFunc(v, bits, Uint32x4.shiftLeftByScalar, ulsh32);
|
||||
testBinaryScalarFunc(v, bits, Uint32x4.shiftRightByScalar, urshl32);
|
||||
testBinaryScalarFunc(v, bits, Uint32x4.shiftRightArithmeticByScalar, ursha32);
|
||||
testBinaryScalarFunc(v, bits, Uint32x4.shiftRightLogicalByScalar, urshl32);
|
||||
}
|
||||
|
@ -179,31 +185,37 @@ function test() {
|
|||
|
||||
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.shiftRightByScalar(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.shiftRightByScalar(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.shiftRightByScalar(v, bad), TestError);
|
||||
assertThrowsInstanceOf(() => SIMD.Int32x4.shiftRightArithmeticByScalar(v, bad), TestError);
|
||||
assertThrowsInstanceOf(() => SIMD.Int32x4.shiftRightLogicalByScalar(v, bad), TestError);
|
||||
|
||||
var v = SIMD.Uint8x16(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16);
|
||||
assertThrowsInstanceOf(() => SIMD.Uint8x16.shiftLeftByScalar(v, bad), TestError);
|
||||
assertThrowsInstanceOf(() => SIMD.Uint8x16.shiftRightByScalar(v, bad), TestError);
|
||||
assertThrowsInstanceOf(() => SIMD.Uint8x16.shiftRightArithmeticByScalar(v, bad), TestError);
|
||||
assertThrowsInstanceOf(() => SIMD.Uint8x16.shiftRightLogicalByScalar(v, bad), TestError);
|
||||
|
||||
var v = SIMD.Uint16x8(1,2,3,4,5,6,7,8);
|
||||
assertThrowsInstanceOf(() => SIMD.Uint16x8.shiftLeftByScalar(v, bad), TestError);
|
||||
assertThrowsInstanceOf(() => SIMD.Uint16x8.shiftRightByScalar(v, bad), TestError);
|
||||
assertThrowsInstanceOf(() => SIMD.Uint16x8.shiftRightArithmeticByScalar(v, bad), TestError);
|
||||
assertThrowsInstanceOf(() => SIMD.Uint16x8.shiftRightLogicalByScalar(v, bad), TestError);
|
||||
|
||||
var v = SIMD.Uint32x4(1,2,3,4);
|
||||
assertThrowsInstanceOf(() => SIMD.Uint32x4.shiftLeftByScalar(v, bad), TestError);
|
||||
assertThrowsInstanceOf(() => SIMD.Uint32x4.shiftRightByScalar(v, bad), TestError);
|
||||
assertThrowsInstanceOf(() => SIMD.Uint32x4.shiftRightArithmeticByScalar(v, bad), TestError);
|
||||
assertThrowsInstanceOf(() => SIMD.Uint32x4.shiftRightLogicalByScalar(v, bad), TestError);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче