--- a/js/src/asmjs/AsmJSValidate.cpp
+++ b/js/src/asmjs/AsmJSValidate.cpp
@@ -2422,27 +2422,16 @@ class FunctionCompiler
{
if (inDeadCode())
return nullptr;
T *ins = T::NewAsmJS(alloc(), lhs, rhs, type);
curBlock_->add(ins);
return ins;
}
- MDefinition *unarySimd(MDefinition *input, MSimdUnaryArith::Operation op, MIRType type)
- {
- if (inDeadCode())
- return nullptr;
-
- MOZ_ASSERT(IsSimdType(input->type()) && input->type() == type);
- MInstruction *ins = MSimdUnaryArith::NewAsmJS(alloc(), input, op, type);
- curBlock_->add(ins);
- return ins;
- }
-
MDefinition *binarySimd(MDefinition *lhs, MDefinition *rhs, MSimdBinaryArith::Operation op,
MIRType type)
{
if (inDeadCode())
return nullptr;
MOZ_ASSERT(IsSimdType(lhs->type()) && rhs->type() == lhs->type());
MOZ_ASSERT(lhs->type() == type);
@@ -4859,28 +4848,16 @@ class CheckSimdVectorScalarArgs
coercedFormalType.toChars());
}
return true;
}
};
} // anonymous namespace
-static inline bool
-CheckSimdUnary(FunctionCompiler &f, ParseNode *call, Type retType, MSimdUnaryArith::Operation op,
- MDefinition **def, Type *type)
-{
- DefinitionVector defs;
- if (!CheckSimdCallArgs(f, call, 1, CheckArgIsSubtypeOf(retType), &defs))
- return false;
- *def = f.unarySimd(defs[0], op, retType.toMIRType());
- *type = retType;
- return true;
-}
-
template<class OpEnum>
static inline bool
CheckSimdBinary(FunctionCompiler &f, ParseNode *call, Type retType, OpEnum op, MDefinition **def,
Type *type)
{
DefinitionVector argDefs;
if (!CheckSimdCallArgs(f, call, 2, CheckArgIsSubtypeOf(retType), &argDefs))
return false;
@@ -5003,29 +4980,16 @@ CheckSimdOperationCall(FunctionCompiler
case AsmJSSimdOperation_shiftLeft:
return CheckSimdBinary(f, call, Type::Int32x4, MSimdShift::lsh, def, type);
case AsmJSSimdOperation_shiftRight:
return CheckSimdBinary(f, call, Type::Int32x4, MSimdShift::rsh, def, type);
case AsmJSSimdOperation_shiftRightLogical:
return CheckSimdBinary(f, call, Type::Int32x4, MSimdShift::ursh, def, type);
- case AsmJSSimdOperation_abs:
- return CheckSimdUnary(f, call, retType, MSimdUnaryArith::abs, def, type);
- case AsmJSSimdOperation_neg:
- return CheckSimdUnary(f, call, retType, MSimdUnaryArith::neg, def, type);
- case AsmJSSimdOperation_not:
- return CheckSimdUnary(f, call, retType, MSimdUnaryArith::not_, def, type);
- case AsmJSSimdOperation_sqrt:
- return CheckSimdUnary(f, call, retType, MSimdUnaryArith::sqrt, def, type);
- case AsmJSSimdOperation_reciprocal:
- return CheckSimdUnary(f, call, retType, MSimdUnaryArith::reciprocal, def, type);
- case AsmJSSimdOperation_reciprocalSqrt:
- return CheckSimdUnary(f, call, retType, MSimdUnaryArith::reciprocalSqrt, def, type);
-
case AsmJSSimdOperation_splat: {
DefinitionVector defs;
Type formalType = retType.simdToCoercedScalarType();
if (!CheckSimdCallArgs(f, call, 1, CheckArgIsSubtypeOf(formalType), &defs))
return false;
*def = f.splatSimd(defs[0], retType.toMIRType());
*type = retType;
return true;
--- a/js/src/builtin/SIMD.h
+++ b/js/src/builtin/SIMD.h
@@ -115,20 +115,16 @@
#define FOREACH_INT32X4_SIMD_OP(_) \
_(fromFloat32x4) \
_(fromFloat32x4Bits) \
_(shiftLeft) \
_(shiftRight) \
_(shiftRightLogical)
#define FOREACH_FLOAT32X4_SIMD_OP(_) \
- _(abs) \
- _(sqrt) \
- _(reciprocal) \
- _(reciprocalSqrt) \
_(fromInt32x4) \
_(fromInt32x4Bits) \
_(mul) \
_(div) \
_(max) \
_(min) \
_(lessThanOrEqual) \
_(notEqual) \
@@ -142,19 +138,17 @@
_(and) \
_(or) \
_(xor) \
_(select) \
_(splat) \
_(withX) \
_(withY) \
_(withZ) \
- _(withW) \
- _(not) \
- _(neg)
+ _(withW)
#define FORALL_SIMD_OP(_) \
FOREACH_INT32X4_SIMD_OP(_) \
FOREACH_FLOAT32X4_SIMD_OP(_) \
FOREACH_COMMONX4_SIMD_OP(_)
namespace js {
class SIMDObject : public JSObject
--- a/js/src/jit-test/tests/asm.js/testSIMD.js
+++ b/js/src/jit-test/tests/asm.js/testSIMD.js
@@ -19,24 +19,21 @@ const F32M = 'var f4m = f4.mul;'
const F32D = 'var f4d = f4.div;'
const FROUND = 'var f32=glob.Math.fround;'
const INT32_MAX = Math.pow(2, 31) - 1;
const INT32_MIN = INT32_MAX + 1 | 0;
const assertEqFFI = {assertEq:assertEq};
-function assertEqX4(real, expected, assertFunc) {
- if (typeof assertFunc === 'undefined')
- assertFunc = assertEq;
-
- assertFunc(real.x, expected[0]);
- assertFunc(real.y, expected[1]);
- assertFunc(real.z, expected[2]);
- assertFunc(real.w, expected[3]);
+function assertEqX4(real, expected) {
+ assertEq(real.x, expected[0]);
+ assertEq(real.y, expected[1]);
+ assertEq(real.z, expected[2]);
+ assertEq(real.w, expected[3]);
}
function CheckI4(header, code, expected) {
// code needs to contain a local called x
header = USE_ASM + I32 + header;
var lanes = ['x', 'y', 'z', 'w'];
for (var i = 0; i < 4; ++i) {
var lane = lanes[i];
@@ -442,78 +439,16 @@ CheckF4(F32S, 'var x=f4(13.37,2,3,4); va
assertAsmTypeFail('glob', USE_ASM + I32 + "var f4m=i4.mul; function f() {} return f");
assertAsmTypeFail('glob', USE_ASM + I32 + "var f4d=i4.div; function f() {} return f");
CheckF4(F32M, 'var x=f4(1,2,3,4); x=f4m(x,x)', [1,4,9,16]);
CheckF4(F32M, 'var x=f4(1,2,3,4); var y=f4(4,3,5,2); x=f4m(x,y)', [4,6,15,8]);
CheckF4(F32M, 'var x=f4(13.37,2,3,4); var y=f4(4,3,5,2); x=f4m(x,y)', [Math.fround(13.37) * 4,6,15,8]);
CheckF4(F32M, 'var x=f4(13.37,2,3,4); var y=f4(4,3,5,2); x=f4(f4m(x,y))', [Math.fround(13.37) * 4,6,15,8]);
-// Unary arithmetic operators
-function CheckUnaryF4(op, checkFunc, assertFunc) {
- var _ = asmLink(asmCompile('glob', USE_ASM + F32 + 'var op=f4.' + op + '; function f(x){x=f4(x); return f4(op(x)); } return f'), this);
- return function(input) {
- var simd = SIMD.float32x4(input[0], input[1], input[2], input[3]);
-
- var exp = input.map(Math.fround).map(checkFunc).map(Math.fround);
- var obs = _(simd);
- assertEqX4(obs, exp, assertFunc);
- }
-}
-
-function CheckUnaryI4(op, checkFunc) {
- var _ = asmLink(asmCompile('glob', USE_ASM + I32 + 'var op=i4.' + op + '; function f(x){x=i4(x); return i4(op(x)); } return f'), this);
- return function(input) {
- var simd = SIMD.int32x4(input[0], input[1], input[2], input[3]);
- assertEqX4(_(simd), input.map(checkFunc).map(function(x) { return x | 0}));
- }
-}
-
-CheckUnaryI4('neg', function(x) { return -x })([1, -2, INT32_MIN, INT32_MAX]);
-CheckUnaryI4('not', function(x) { return ~x })([1, -2, INT32_MIN, INT32_MAX]);
-
-var CheckAbs = CheckUnaryF4('abs', Math.abs);
-CheckAbs([1, 42.42, 0.63, 13.37]);
-CheckAbs([NaN, -Infinity, Infinity, 0]);
-
-var CheckNegF = CheckUnaryF4('neg', function(x) { return -x });
-CheckNegF([1, 42.42, 0.63, 13.37]);
-CheckNegF([NaN, -Infinity, Infinity, 0]);
-
-var CheckNotF = CheckUnaryF4('not', (function() {
- var f32 = new Float32Array(1);
- var i32 = new Int32Array(f32.buffer);
- return function(x) {
- f32[0] = x;
- i32[0] = ~i32[0];
- return f32[0];
- }
-})());
-CheckNotF([1, 42.42, 0.63, 13.37]);
-CheckNotF([NaN, -Infinity, Infinity, 0]);
-
-var CheckSqrt = CheckUnaryF4('sqrt', function(x) { return Math.sqrt(x); });
-CheckSqrt([1, 42.42, 0.63, 13.37]);
-CheckSqrt([NaN, -Infinity, Infinity, 0]);
-
-// Reciprocal and reciprocalSqrt give approximate results
-function assertNear(a, b) {
- if (a !== a && b === b)
- throw 'Observed NaN, expected ' + b;
- if (Math.abs(a - b) > 1e-3)
- throw 'More than 1e-3 between ' + a + ' and ' + b;
-}
-var CheckRecp = CheckUnaryF4('reciprocal', function(x) { return 1 / x; }, assertNear);
-CheckRecp([1, 42.42, 0.63, 13.37]);
-CheckRecp([NaN, -Infinity, Infinity, 0]);
-
-var CheckRecp = CheckUnaryF4('reciprocalSqrt', function(x) { return 1 / Math.sqrt(x); }, assertNear);
-CheckRecp([1, 42.42, 0.63, 13.37]);
-CheckRecp([NaN, -Infinity, Infinity, 0]);
-
// Min/Max
assertAsmTypeFail('glob', USE_ASM + I32 + "var f4m=i4.min; function f() {} return f");
assertAsmTypeFail('glob', USE_ASM + I32 + "var f4d=i4.max; function f() {} return f");
const F32MIN = 'var min = f4.min;'
const F32MAX = 'var max = f4.max;'
// TODO amend tests once float32x4.min/max is fully specified, for NaN and -0