--- a/js/src/asmjs/AsmJSModule.h
+++ b/js/src/asmjs/AsmJSModule.h
@@ -72,16 +72,29 @@ enum AsmJSAtomicsBuiltinFunction
// Set of known global object SIMD's attributes, i.e. types
enum AsmJSSimdType
{
AsmJSSimdType_int32x4,
AsmJSSimdType_float32x4,
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
{
#define ASMJSSIMDOPERATION(op) AsmJSSimdOperation_##op,
FORALL_SIMD_ASMJS_OP(ASMJSSIMDOPERATION)
#undef ASMJSSIMDOPERATION
};
--- a/js/src/asmjs/AsmJSValidate.cpp
+++ b/js/src/asmjs/AsmJSValidate.cpp
@@ -4965,16 +4965,20 @@ CheckSimdOperationCall(FunctionValidator
return CheckSimdCast(f, call, AsmJSSimdType_float32x4, opType, IsBitCast(false), type);
case AsmJSSimdOperation_fromInt32x4Bits:
return CheckSimdCast(f, call, AsmJSSimdType_int32x4, opType, IsBitCast(true), type);
case AsmJSSimdOperation_fromFloat32x4Bits:
return CheckSimdCast(f, call, AsmJSSimdType_float32x4, opType, IsBitCast(true), type);
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:
return CheckSimdBinary(f, call, opType, MSimdShift::ursh, type);
case AsmJSSimdOperation_abs:
return CheckSimdUnary(f, call, opType, MSimdUnaryArith::abs, type);
case AsmJSSimdOperation_neg:
--- a/js/src/builtin/SIMD.h
+++ b/js/src/builtin/SIMD.h
@@ -242,16 +242,17 @@
V(lessThan, (CompareFunc<Int8x16, LessThan, Bool8x16>), 2) \
V(lessThanOrEqual, (CompareFunc<Int8x16, LessThanOrEqual, Bool8x16>), 2) \
V(load, (Load<Int8x16, 16>), 2) \
V(mul, (BinaryFunc<Int8x16, Mul, Int8x16>), 2) \
V(notEqual, (CompareFunc<Int8x16, NotEqual, Bool8x16>), 2) \
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)
#define INT8X16_TERNARY_FUNCTION_LIST(V) \
V(replaceLane, (ReplaceLane<Int8x16>), 3) \
V(select, (Select<Int8x16, Bool8x16>), 3) \
V(store, (Store<Int8x16, 16>), 3)
@@ -290,16 +291,17 @@
V(lessThan, (CompareFunc<Uint8x16, LessThan, Bool8x16>), 2) \
V(lessThanOrEqual, (CompareFunc<Uint8x16, LessThanOrEqual, Bool8x16>), 2) \
V(load, (Load<Uint8x16, 16>), 2) \
V(mul, (BinaryFunc<Uint8x16, Mul, Uint8x16>), 2) \
V(notEqual, (CompareFunc<Uint8x16, NotEqual, Bool8x16>), 2) \
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)
#define UINT8X16_TERNARY_FUNCTION_LIST(V) \
V(replaceLane, (ReplaceLane<Uint8x16>), 3) \
V(select, (Select<Uint8x16, Bool8x16>), 3) \
V(store, (Store<Uint8x16, 16>), 3)
@@ -338,16 +340,17 @@
V(lessThan, (CompareFunc<Int16x8, LessThan, Bool16x8>), 2) \
V(lessThanOrEqual, (CompareFunc<Int16x8, LessThanOrEqual, Bool16x8>), 2) \
V(load, (Load<Int16x8, 8>), 2) \
V(mul, (BinaryFunc<Int16x8, Mul, Int16x8>), 2) \
V(notEqual, (CompareFunc<Int16x8, NotEqual, Bool16x8>), 2) \
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)
#define INT16X8_TERNARY_FUNCTION_LIST(V) \
V(replaceLane, (ReplaceLane<Int16x8>), 3) \
V(select, (Select<Int16x8, Bool16x8>), 3) \
V(store, (Store<Int16x8, 8>), 3)
@@ -386,16 +389,17 @@
V(lessThan, (CompareFunc<Uint16x8, LessThan, Bool16x8>), 2) \
V(lessThanOrEqual, (CompareFunc<Uint16x8, LessThanOrEqual, Bool16x8>), 2) \
V(load, (Load<Uint16x8, 8>), 2) \
V(mul, (BinaryFunc<Uint16x8, Mul, Uint16x8>), 2) \
V(notEqual, (CompareFunc<Uint16x8, NotEqual, Bool16x8>), 2) \
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)
#define UINT16X8_TERNARY_FUNCTION_LIST(V) \
V(replaceLane, (ReplaceLane<Uint16x8>), 3) \
V(select, (Select<Uint16x8, Bool16x8>), 3) \
V(store, (Store<Uint16x8, 8>), 3)
@@ -438,16 +442,17 @@
V(load3, (Load<Int32x4, 3>), 2) \
V(load2, (Load<Int32x4, 2>), 2) \
V(load1, (Load<Int32x4, 1>), 2) \
V(mul, (BinaryFunc<Int32x4, Mul, Int32x4>), 2) \
V(notEqual, (CompareFunc<Int32x4, NotEqual, Bool32x4>), 2) \
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)
#define INT32X4_TERNARY_FUNCTION_LIST(V) \
V(replaceLane, (ReplaceLane<Int32x4>), 3) \
V(select, (Select<Int32x4, Bool32x4>), 3) \
V(store, (Store<Int32x4, 4>), 3) \
@@ -493,16 +498,17 @@
V(load3, (Load<Uint32x4, 3>), 2) \
V(load2, (Load<Uint32x4, 2>), 2) \
V(load1, (Load<Uint32x4, 1>), 2) \
V(mul, (BinaryFunc<Uint32x4, Mul, Uint32x4>), 2) \
V(notEqual, (CompareFunc<Uint32x4, NotEqual, Bool32x4>), 2) \
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)
#define UINT32X4_TERNARY_FUNCTION_LIST(V) \
V(replaceLane, (ReplaceLane<Uint32x4>), 3) \
V(select, (Select<Uint32x4, Bool32x4>), 3) \
V(store, (Store<Uint32x4, 4>), 3) \
@@ -567,16 +573,17 @@
#define FOREACH_BITWISE_SIMD_BINOP(_) \
_(and) \
_(or) \
_(xor)
// Bitwise shifts defined on integer SIMD types.
#define FOREACH_SHIFT_SIMD_OP(_) \
_(shiftLeftByScalar) \
+ _(shiftRightByScalar) \
_(shiftRightArithmeticByScalar) \
_(shiftRightLogicalByScalar)
// Unary arithmetic operators defined on numeric SIMD types.
#define FOREACH_NUMERIC_SIMD_UNOP(_) \
_(neg)
// Binary arithmetic operators defined on numeric SIMD types.
--- a/js/src/jit-test/tests/SIMD/shift.js
+++ b/js/src/jit-test/tests/SIMD/shift.js
@@ -39,16 +39,23 @@ function f() {
assertEqX4(SIMD.Int32x4.shiftRightLogicalByScalar(v, -1), a.map(ursh(-1)));
assertEqX4(SIMD.Int32x4.shiftRightLogicalByScalar(v, 0), a.map(ursh(0)));
assertEqX4(SIMD.Int32x4.shiftRightLogicalByScalar(v, 1), a.map(ursh(1)));
assertEqX4(SIMD.Int32x4.shiftRightLogicalByScalar(v, 2), a.map(ursh(2)));
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)));
assertEqX4(SIMD.Int32x4.shiftRightArithmeticByScalar(v, c), a.map(rsh(c)));
assertEqX4(SIMD.Int32x4.shiftRightLogicalByScalar(v, c), a.map(ursh(c)));
}
return r;
}
--- a/js/src/jit-test/tests/asm.js/testSIMD.js
+++ b/js/src/jit-test/tests/asm.js/testSIMD.js
@@ -919,45 +919,50 @@ const NOTF32 = 'var nott=f4.not;';
assertAsmTypeFail('glob', USE_ASM + F32 + CF32 + ANDF32 + 'function f() {var x=f4(42, 13.37,-1.42, 23.10); var y=f4(19.89, 2.4, 8.15, 16.36); x=andd(x,y);} return f');
assertAsmTypeFail('glob', USE_ASM + F32 + CF32 + ORF32 + 'function f() {var x=f4(42, 13.37,-1.42, 23.10); var y=f4(19.89, 2.4, 8.15, 16.36); x=orr(x,y);} return f');
assertAsmTypeFail('glob', USE_ASM + F32 + CF32 + XORF32 + 'function f() {var x=f4(42, 13.37,-1.42, 23.10); var y=f4(19.89, 2.4, 8.15, 16.36); x=xorr(x,y);} return f');
assertAsmTypeFail('glob', USE_ASM + F32 + CF32 + NOTF32 + 'function f() {var x=f4(42, 13.37,-1.42, 23.10); x=nott(x);} return 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");
assertAsmTypeFail('glob', USE_ASM + I32 + CI32 + F32 + FROUND + LSHI + "function f() {var x=f4(1,2,3,4); return ci4(lsh(x,42));} return f");
assertAsmTypeFail('glob', USE_ASM + I32 + CI32 + FROUND + LSHI + "function f() {var x=i4(1,2,3,4); return ci4(lsh(x,42.0));} return f");
assertAsmTypeFail('glob', USE_ASM + I32 + CI32 + FROUND + LSHI + "function f() {var x=i4(1,2,3,4); return ci4(lsh(x,f32(42)));} return f");
var input = 'i4(0, 1, ' + INT32_MIN + ', ' + INT32_MAX + ')';
var vinput = [0, 1, INT32_MIN, INT32_MAX];
// TODO: What to do for masks > 31? Should we keep only the five low bits of
// the mask (JS) or not (x86)?
// 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)));
}
// Select
const I32SEL = 'var i4sel = i4.select;'
const F32SEL = 'var f4sel = f4.select;'
assertAsmTypeFail('glob', USE_ASM + I32 + F32 + B32 + CI32 + I32SEL + "function f() {var x=f4(1,2,3,4); return ci4(i4sel(x,x,x));} return f");
--- a/js/src/jit/MCallOptimize.cpp
+++ b/js/src/jit/MCallOptimize.cpp
@@ -3098,18 +3098,20 @@ IonBuilder::inlineSimdInt32x4(CallInfo&
return inlineBinarySimd<MSimdBinaryBitwise>(callInfo, native, MSimdBinaryBitwise::OP##_, \
SimdTypeDescr::Int32x4);
FOREACH_BITWISE_SIMD_BINOP(INLINE_SIMD_BITWISE_)
#undef INLINE_SIMD_BITWISE_
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);
#define INLINE_SIMD_COMPARISON_(OP) \
if (native == js::simd_int32x4_##OP) \
return inlineCompSimd(callInfo, native, MSimdBinaryComp::OP, SimdTypeDescr::Int32x4);
FOREACH_COMP_SIMD_OP(INLINE_SIMD_COMPARISON_)
--- a/js/src/tests/ecma_7/SIMD/shifts.js
+++ b/js/src/tests/ecma_7/SIMD/shifts.js
@@ -86,129 +86,141 @@ function test() {
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.shiftRightByScalar, rsha8);
testBinaryScalarFunc(v, bits, Int8x16.shiftRightArithmeticByScalar, rsha8);
testBinaryScalarFunc(v, bits, Int8x16.shiftRightLogicalByScalar, rshl8);
}
// 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.shiftRightByScalar, rsha16);
testBinaryScalarFunc(v, bits, Int16x8.shiftRightArithmeticByScalar, rsha16);
testBinaryScalarFunc(v, bits, Int16x8.shiftRightLogicalByScalar, rshl16);
}
// 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, lsh32);
+ testBinaryScalarFunc(v, bits, Int32x4.shiftRightByScalar, rsha32);
testBinaryScalarFunc(v, bits, Int32x4.shiftRightArithmeticByScalar, rsha32);
testBinaryScalarFunc(v, bits, Int32x4.shiftRightLogicalByScalar, rshl32);
}
// Test that the shift count is coerced to an int32.
testBinaryScalarFunc(v, undefined, Int32x4.shiftLeftByScalar, lsh32);
testBinaryScalarFunc(v, 3.5, Int32x4.shiftLeftByScalar, lsh32);
testBinaryScalarFunc(v, good, Int32x4.shiftLeftByScalar, lsh32);
}
for (var v of [
Uint8x16(-1, 2, -3, 4, -5, 6, -7, 8, -9, 10, -11, 12, -13, 14, -15, 16),
Uint8x16(INT8_MAX, INT8_MIN, INT8_MAX - 1, INT8_MIN + 1, UINT8_MAX, UINT8_MAX - 1)
])
{
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);
}
// Test that the shift count is coerced to an int32.
testBinaryScalarFunc(v, undefined, Uint8x16.shiftLeftByScalar, ulsh8);
testBinaryScalarFunc(v, 3.5, Uint8x16.shiftLeftByScalar, ulsh8);
testBinaryScalarFunc(v, good, Uint8x16.shiftLeftByScalar, ulsh8);
}
for (var v of [
Uint16x8(-1, 2, -3, 4, -5, 6, -7, 8),
Uint16x8(INT16_MAX, INT16_MIN, INT16_MAX - 1, INT16_MIN + 1, UINT16_MAX, UINT16_MAX - 1)
])
{
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);
}
// Test that the shift count is coerced to an int32.
testBinaryScalarFunc(v, undefined, Uint16x8.shiftLeftByScalar, ulsh16);
testBinaryScalarFunc(v, 3.5, Uint16x8.shiftLeftByScalar, ulsh16);
testBinaryScalarFunc(v, good, Uint16x8.shiftLeftByScalar, ulsh16);
}
for (var v of [
Uint32x4(-1, 2, -3, 4),
Uint32x4(UINT32_MAX, UINT32_MAX - 1, 0, 1),
Uint32x4(INT32_MAX, INT32_MIN, INT32_MAX - 1, INT32_MIN + 1)
])
{
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);
}
// Test that the shift count is coerced to an int32.
testBinaryScalarFunc(v, undefined, Uint32x4.shiftLeftByScalar, ulsh32);
testBinaryScalarFunc(v, 3.5, Uint32x4.shiftLeftByScalar, ulsh32);
testBinaryScalarFunc(v, good, Uint32x4.shiftLeftByScalar, ulsh32);
}
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);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();