Bug 1160971 - Part 4: Delete signMask and selectBits. r=bbouvier

These operations were removed from the SIMD.js spec.

Also remove TypedObjectProperties from SIMD objects, since there are no such
properties defined in the spec.

Remove the bitwise operations from the Float32x4 type. The current version of
the spec defines these operations on integer and boolean types only.

Reorganize the operation lists in SIMD.h to be friendlier to the boolean
vectors. Also reflect the lact of bitwise operators on floating point types.
This commit is contained in:
Jakob Stoklund Olesen 2015-12-22 14:17:13 -08:00
parent 1b4833cacd
commit f07361dc96
34 changed files with 317 additions and 808 deletions

View File

@ -379,20 +379,16 @@ ValidateSimdOperation(JSContext* cx, AsmJSModule::Global& global, HandleValue gl
#define FALLTHROUGH(op) case AsmJSSimdOperation_##op:
case AsmJSSimdType_int32x4:
switch (global.simdOperation()) {
FOREACH_INT32X4_SIMD_OP(SET_NATIVE_INT32X4)
FOREACH_COMMONX4_SIMD_OP(SET_NATIVE_INT32X4)
FOREACH_FLOAT32X4_SIMD_OP(FALLTHROUGH)
FOREACH_BOOL_SIMD_OP(FALLTHROUGH)
FORALL_INT32X4_ASMJS_OP(SET_NATIVE_INT32X4)
default:
MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("shouldn't have been validated in the first "
"place");
}
break;
case AsmJSSimdType_float32x4:
switch (global.simdOperation()) {
FOREACH_FLOAT32X4_SIMD_OP(SET_NATIVE_FLOAT32X4)
FOREACH_COMMONX4_SIMD_OP(SET_NATIVE_FLOAT32X4)
FOREACH_INT32X4_SIMD_OP(FALLTHROUGH)
FOREACH_BOOL_SIMD_OP(FALLTHROUGH)
FORALL_FLOAT32X4_ASMJS_OP(SET_NATIVE_FLOAT32X4)
default:
MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("shouldn't have been validated in the first "
"place");
}

View File

@ -80,7 +80,7 @@ enum AsmJSSimdType
enum AsmJSSimdOperation
{
#define ASMJSSIMDOPERATION(op) AsmJSSimdOperation_##op,
FORALL_SIMD_OP(ASMJSSIMDOPERATION)
FORALL_SIMD_ASMJS_OP(ASMJSSIMDOPERATION)
#undef ASMJSSIMDOPERATION
};

View File

@ -1335,7 +1335,7 @@ class MOZ_STACK_CLASS ModuleValidator
#define ADDSTDLIBSIMDOPNAME(op) || !addStandardLibrarySimdOpName(#op, AsmJSSimdOperation_##op)
if (!standardLibrarySimdOpNames_.init()
FORALL_SIMD_OP(ADDSTDLIBSIMDOPNAME))
FORALL_SIMD_ASMJS_OP(ADDSTDLIBSIMDOPNAME))
{
return false;
}
@ -2559,19 +2559,23 @@ IsSimdTypeName(ModuleValidator& m, PropertyName* name, AsmJSSimdType* type)
static bool
IsSimdValidOperationType(AsmJSSimdType type, AsmJSSimdOperation op)
{
switch (op) {
#define CASE(op) case AsmJSSimdOperation_##op:
FOREACH_COMMONX4_SIMD_OP(CASE)
return true;
FOREACH_INT32X4_SIMD_OP(CASE)
return type == AsmJSSimdType_int32x4;
FOREACH_FLOAT32X4_SIMD_OP(CASE)
return type == AsmJSSimdType_float32x4;
FOREACH_BOOL_SIMD_OP(CASE)
return false; // TODO bug 1160971
#undef CASE
switch(type) {
case AsmJSSimdType_int32x4:
switch (op) {
FORALL_INT32X4_ASMJS_OP(CASE) return true;
default: return false;
}
break;
case AsmJSSimdType_float32x4:
switch (op) {
FORALL_FLOAT32X4_ASMJS_OP(CASE) return true;
default: return false;
}
break;
}
return false;
#undef CASE
MOZ_CRASH("Unhandles SIMD type");
}
static bool
@ -3198,37 +3202,6 @@ CheckLoadArray(FunctionValidator& f, ParseNode* elem, Type* type)
return true;
}
static bool
CheckDotAccess(FunctionValidator& f, ParseNode* elem, Type* type)
{
MOZ_ASSERT(elem->isKind(PNK_DOT));
size_t opcodeAt = f.tempOp();
ParseNode* base = DotBase(elem);
Type baseType;
if (!CheckExpr(f, base, &baseType))
return false;
if (!baseType.isSimd())
return f.failf(base, "expected SIMD type, got %s", baseType.toChars());
ModuleValidator& m = f.m();
PropertyName* field = DotMember(elem);
JSAtomState& names = m.cx()->names();
if (field != names.signMask)
return f.fail(base, "dot access field must be signMask");
*type = Type::Signed;
switch (baseType.simdType()) {
case AsmJSSimdType_int32x4: f.patchOp(opcodeAt, I32::I32X4SignMask); break;
case AsmJSSimdType_float32x4: f.patchOp(opcodeAt, I32::F32X4SignMask); break;
}
return true;
}
static bool
CheckStoreArray(FunctionValidator& f, ParseNode* lhs, ParseNode* rhs, Type* type)
{
@ -4535,7 +4508,7 @@ static bool
CheckSimdBinary(FunctionValidator& f, ParseNode* call, AsmJSSimdType opType,
MSimdBinaryBitwise::Operation op, Type* type)
{
SwitchPackOp(f, opType, I32X4::BinaryBitwise, F32X4::BinaryBitwise);
SwitchPackOp(f, opType, I32X4::BinaryBitwise, F32X4::Bad);
return CheckSimdBinaryGuts(f, call, opType, op, type);
}
@ -4796,12 +4769,9 @@ CheckSimdStore(FunctionValidator& f, ParseNode* call, AsmJSSimdType opType,
}
static bool
CheckSimdSelect(FunctionValidator& f, ParseNode* call, AsmJSSimdType opType, bool isElementWise,
Type* type)
CheckSimdSelect(FunctionValidator& f, ParseNode* call, AsmJSSimdType opType, Type* type)
{
SwitchPackOp(f, opType,
isElementWise ? I32X4::Select : I32X4::BitSelect,
isElementWise ? F32X4::Select : F32X4::BitSelect);
SwitchPackOp(f, opType, I32X4::Select, F32X4::Select);
if (!CheckSimdCallArgs(f, call, 3, CheckSimdSelectArgs(opType)))
return false;
*type = opType;
@ -4843,8 +4813,8 @@ CheckSimdOperationCall(FunctionValidator& f, ParseNode* call, const ModuleValida
#define OP_CHECK_CASE_LIST_(OP) \
case AsmJSSimdOperation_##OP: \
return CheckSimdBinary(f, call, opType, MSimdBinaryArith::Op_##OP, type);
ARITH_COMMONX4_SIMD_OP(OP_CHECK_CASE_LIST_)
BINARY_ARITH_FLOAT32X4_SIMD_OP(OP_CHECK_CASE_LIST_)
FOREACH_NUMERIC_SIMD_BINOP(OP_CHECK_CASE_LIST_)
FOREACH_FLOAT_SIMD_BINOP(OP_CHECK_CASE_LIST_)
#undef OP_CHECK_CASE_LIST_
case AsmJSSimdOperation_lessThan:
@ -4923,10 +4893,8 @@ CheckSimdOperationCall(FunctionValidator& f, ParseNode* call, const ModuleValida
case AsmJSSimdOperation_store3:
return CheckSimdStore(f, call, opType, 3, type);
case AsmJSSimdOperation_selectBits:
return CheckSimdSelect(f, call, opType, /*isElementWise */ false, type);
case AsmJSSimdOperation_select:
return CheckSimdSelect(f, call, opType, /*isElementWise */ true, type);
return CheckSimdSelect(f, call, opType, type);
case AsmJSSimdOperation_splat:
return CheckSimdSplat(f, call, opType, type);
@ -5661,7 +5629,6 @@ CheckExpr(FunctionValidator& f, ParseNode* expr, Type* type)
switch (expr->getKind()) {
case PNK_NAME: return CheckVarRef(f, expr, type);
case PNK_ELEM: return CheckLoadArray(f, expr, type);
case PNK_DOT: return CheckDotAccess(f, expr, type);
case PNK_ASSIGN: return CheckAssign(f, expr, type);
case PNK_POS: return CheckPos(f, expr, type);
case PNK_NOT: return CheckNot(f, expr, type);

View File

@ -172,9 +172,6 @@ enum class I32 : uint8_t
AtomicsBinOp,
// SIMD opcodes
I32X4SignMask,
F32X4SignMask,
I32X4ExtractLane,
// Specific to AsmJS
@ -328,7 +325,6 @@ enum class I32X4 : uint8_t
Swizzle,
Shuffle,
Select,
BitSelect,
Splat,
Load,
@ -363,7 +359,6 @@ enum class F32X4 : uint8_t
Unary,
Binary,
BinaryBitwise,
ReplaceLane,
@ -372,7 +367,6 @@ enum class F32X4 : uint8_t
Swizzle,
Shuffle,
Select,
BitSelect,
Splat,
Load,

View File

@ -309,8 +309,7 @@ class FunctionCompiler
return ins;
}
MDefinition* selectSimd(MDefinition* mask, MDefinition* lhs, MDefinition* rhs, MIRType type,
bool isElementWise)
MDefinition* selectSimd(MDefinition* mask, MDefinition* lhs, MDefinition* rhs, MIRType type)
{
if (inDeadCode())
return nullptr;
@ -319,7 +318,7 @@ class FunctionCompiler
MOZ_ASSERT(mask->type() == MIRType_Int32x4);
MOZ_ASSERT(IsSimdType(lhs->type()) && rhs->type() == lhs->type());
MOZ_ASSERT(lhs->type() == type);
MSimdSelect* ins = MSimdSelect::NewAsmJS(alloc(), mask, lhs, rhs, type, isElementWise);
MSimdSelect* ins = MSimdSelect::NewAsmJS(alloc(), mask, lhs, rhs, type);
curBlock_->add(ins);
return ins;
}
@ -578,17 +577,6 @@ class FunctionCompiler
return ins;
}
MDefinition* extractSignMask(MDefinition* base)
{
if (inDeadCode())
return nullptr;
MOZ_ASSERT(IsSimdType(base->type()));
MSimdSignMask* ins = MSimdSignMask::NewAsmJS(alloc(), base);
curBlock_->add(ins);
return ins;
}
template<typename T>
MDefinition* constructSimd(MDefinition* x, MDefinition* y, MDefinition* z, MDefinition* w,
MIRType type)
@ -1342,16 +1330,6 @@ EmitLoadArray(FunctionCompiler& f, Scalar::Type scalarType, MDefinition** def)
return true;
}
static bool
EmitSignMask(FunctionCompiler& f, ValType type, MDefinition** def)
{
MDefinition* in;
if (!EmitExpr(f, type, &in))
return false;
*def = f.extractSignMask(in);
return true;
}
static bool
EmitStore(FunctionCompiler& f, Scalar::Type viewType, MDefinition** def)
{
@ -1897,15 +1875,13 @@ EmitSimdStore(FunctionCompiler& f, ValType type, MDefinition** def)
return true;
}
typedef bool IsElementWise;
static bool
EmitSimdSelect(FunctionCompiler& f, ValType type, bool isElementWise, MDefinition** def)
EmitSimdSelect(FunctionCompiler& f, ValType type, MDefinition** def)
{
MDefinition* defs[3];
if (!EmitI32X4Expr(f, &defs[0]) || !EmitExpr(f, type, &defs[1]) || !EmitExpr(f, type, &defs[2]))
return false;
*def = f.selectSimd(defs[0], defs[1], defs[2], ToMIRType(type), isElementWise);
*def = f.selectSimd(defs[0], defs[1], defs[2], ToMIRType(type));
return true;
}
@ -2645,10 +2621,6 @@ EmitI32Expr(FunctionCompiler& f, MDefinition** def)
return EmitAtomicsStore(f, def);
case I32::AtomicsBinOp:
return EmitAtomicsBinOp(f, def);
case I32::I32X4SignMask:
return EmitSignMask(f, ValType::I32x4, def);
case I32::F32X4SignMask:
return EmitSignMask(f, ValType::F32x4, def);
case I32::I32X4ExtractLane:
return EmitExtractLane(f, ValType::I32x4, def);
case I32::Bad:
@ -2855,9 +2827,7 @@ EmitI32X4Expr(FunctionCompiler& f, MDefinition** def)
case I32X4::Shuffle:
return EmitSimdShuffle(f, ValType::I32x4, def);
case I32X4::Select:
return EmitSimdSelect(f, ValType::I32x4, IsElementWise(true), def);
case I32X4::BitSelect:
return EmitSimdSelect(f, ValType::I32x4, IsElementWise(false), def);
return EmitSimdSelect(f, ValType::I32x4, def);
case I32X4::Splat:
return EmitSimdSplat(f, ValType::I32x4, def);
case I32X4::Load:
@ -2903,8 +2873,6 @@ EmitF32X4Expr(FunctionCompiler& f, MDefinition** def)
return EmitSimdUnary(f, ValType::F32x4, def);
case F32X4::Binary:
return EmitSimdBinaryArith(f, ValType::F32x4, def);
case F32X4::BinaryBitwise:
return EmitSimdBinaryBitwise(f, ValType::F32x4, def);
case F32X4::ReplaceLane:
return EmitSimdReplaceLane(f, ValType::F32x4, def);
case F32X4::FromI32X4:
@ -2916,9 +2884,7 @@ EmitF32X4Expr(FunctionCompiler& f, MDefinition** def)
case F32X4::Shuffle:
return EmitSimdShuffle(f, ValType::F32x4, def);
case F32X4::Select:
return EmitSimdSelect(f, ValType::F32x4, IsElementWise(true), def);
case F32X4::BitSelect:
return EmitSimdSelect(f, ValType::F32x4, IsElementWise(false), def);
return EmitSimdSelect(f, ValType::F32x4, def);
case F32X4::Splat:
return EmitSimdSplat(f, ValType::F32x4, def);
case F32X4::Load:

View File

@ -131,54 +131,6 @@ TypedObjectMemory(HandleValue v)
return reinterpret_cast<Elem>(obj.typedMem());
}
template<typename SimdType>
static bool SignMask(JSContext* cx, unsigned argc, Value* vp)
{
typedef typename SimdType::Elem Elem;
CallArgs args = CallArgsFromVp(argc, vp);
if (!args.thisv().isObject() || !args.thisv().toObject().is<TypedObject>()) {
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
SimdTypeDescr::class_.name, "signMask",
InformalValueTypeName(args.thisv()));
return false;
}
TypedObject& typedObj = args.thisv().toObject().as<TypedObject>();
TypeDescr& descr = typedObj.typeDescr();
if (descr.kind() != type::Simd || descr.as<SimdTypeDescr>().type() != SimdType::type) {
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
SimdTypeDescr::class_.name, "signMask",
InformalValueTypeName(args.thisv()));
return false;
}
// Load the data as integer so that we treat the sign bit consistently,
// since -0.0 is not less than zero, but it still has the sign bit set.
typedef typename mozilla::SignedStdintTypeForSize<sizeof(Elem)>::Type Int;
static_assert(SimdType::lanes * sizeof(Int) <= jit::Simd128DataSize,
"signMask access should respect the bounds of the type");
const Elem* elems = reinterpret_cast<const Elem*>(typedObj.typedMem());
int32_t result = 0;
for (unsigned i = 0; i < SimdType::lanes; ++i) {
Int x = mozilla::BitwiseCast<Int>(elems[i]);
result |= (x < 0) << i;
}
args.rval().setInt32(result);
return true;
}
#define SIGN_MASK(type) \
static bool type##SignMask(JSContext* cx, unsigned argc, Value* vp) { \
return SignMask<type>(cx, argc, vp); \
}
SIGN_MASK(Float32x4);
SIGN_MASK(Float64x2);
SIGN_MASK(Int8x16);
SIGN_MASK(Int16x8);
SIGN_MASK(Int32x4);
#undef SIGN_MASK
const Class SimdTypeDescr::class_ = {
"SIMD",
JSCLASS_HAS_RESERVED_SLOTS(JS_DESCR_SLOTS) | JSCLASS_BACKGROUND_FINALIZE,
@ -200,7 +152,6 @@ class Int8x16Defn {
public:
static const SimdTypeDescr::Type type = SimdTypeDescr::Int8x16;
static const JSFunctionSpec TypeDescriptorMethods[];
static const JSPropertySpec TypedObjectProperties[];
static const JSFunctionSpec TypedObjectMethods[];
static const JSFunctionSpec Methods[];
};
@ -208,7 +159,6 @@ class Int16x8Defn {
public:
static const SimdTypeDescr::Type type = SimdTypeDescr::Int16x8;
static const JSFunctionSpec TypeDescriptorMethods[];
static const JSPropertySpec TypedObjectProperties[];
static const JSFunctionSpec TypedObjectMethods[];
static const JSFunctionSpec Methods[];
};
@ -216,7 +166,6 @@ class Int32x4Defn {
public:
static const SimdTypeDescr::Type type = SimdTypeDescr::Int32x4;
static const JSFunctionSpec TypeDescriptorMethods[];
static const JSPropertySpec TypedObjectProperties[];
static const JSFunctionSpec TypedObjectMethods[];
static const JSFunctionSpec Methods[];
};
@ -224,7 +173,6 @@ class Float32x4Defn {
public:
static const SimdTypeDescr::Type type = SimdTypeDescr::Float32x4;
static const JSFunctionSpec TypeDescriptorMethods[];
static const JSPropertySpec TypedObjectProperties[];
static const JSFunctionSpec TypedObjectMethods[];
static const JSFunctionSpec Methods[];
};
@ -232,7 +180,6 @@ class Float64x2Defn {
public:
static const SimdTypeDescr::Type type = SimdTypeDescr::Float64x2;
static const JSFunctionSpec TypeDescriptorMethods[];
static const JSPropertySpec TypedObjectProperties[];
static const JSFunctionSpec TypedObjectMethods[];
static const JSFunctionSpec Methods[];
};
@ -242,7 +189,6 @@ class Bool8x16Defn {
static const JSFunctionSpec TypeDescriptorMethods[];
static const JSFunctionSpec TypedObjectMethods[];
static const JSFunctionSpec Methods[];
static constexpr JSPropertySpec* TypedObjectProperties = nullptr;
};
class Bool16x8Defn {
public:
@ -250,7 +196,6 @@ class Bool16x8Defn {
static const JSFunctionSpec TypeDescriptorMethods[];
static const JSFunctionSpec TypedObjectMethods[];
static const JSFunctionSpec Methods[];
static constexpr JSPropertySpec* TypedObjectProperties = nullptr;
};
class Bool32x4Defn {
public:
@ -258,7 +203,6 @@ class Bool32x4Defn {
static const JSFunctionSpec TypeDescriptorMethods[];
static const JSFunctionSpec TypedObjectMethods[];
static const JSFunctionSpec Methods[];
static constexpr JSPropertySpec* TypedObjectProperties = nullptr;
};
class Bool64x2Defn {
public:
@ -266,7 +210,6 @@ class Bool64x2Defn {
static const JSFunctionSpec TypeDescriptorMethods[];
static const JSFunctionSpec TypedObjectMethods[];
static const JSFunctionSpec Methods[];
static constexpr JSPropertySpec* TypedObjectProperties = nullptr;
};
} // namespace
@ -277,11 +220,6 @@ const JSFunctionSpec Float32x4Defn::TypeDescriptorMethods[] = {
JS_FS_END
};
const JSPropertySpec Float32x4Defn::TypedObjectProperties[] = {
JS_PSG("signMask", Float32x4SignMask, JSPROP_PERMANENT),
JS_PS_END
};
const JSFunctionSpec Float32x4Defn::TypedObjectMethods[] = {
JS_SELF_HOSTED_FN("toSource", "SimdToSource", 0, 0),
JS_FS_END
@ -302,11 +240,6 @@ const JSFunctionSpec Float64x2Defn::TypeDescriptorMethods[] = {
JS_FS_END
};
const JSPropertySpec Float64x2Defn::TypedObjectProperties[] = {
JS_PSG("signMask", Float64x2SignMask, JSPROP_PERMANENT),
JS_PS_END
};
const JSFunctionSpec Float64x2Defn::TypedObjectMethods[] = {
JS_SELF_HOSTED_FN("toSource", "SimdToSource", 0, 0),
JS_FS_END
@ -327,11 +260,6 @@ const JSFunctionSpec Int8x16Defn::TypeDescriptorMethods[] = {
JS_FS_END,
};
const JSPropertySpec Int8x16Defn::TypedObjectProperties[] = {
JS_PSG("signMask", Int8x16SignMask, JSPROP_PERMANENT),
JS_PS_END
};
const JSFunctionSpec Int8x16Defn::TypedObjectMethods[] = {
JS_SELF_HOSTED_FN("toSource", "SimdToSource", 0, 0),
JS_FS_END
@ -352,11 +280,6 @@ const JSFunctionSpec Int16x8Defn::TypeDescriptorMethods[] = {
JS_FS_END,
};
const JSPropertySpec Int16x8Defn::TypedObjectProperties[] = {
JS_PSG("signMask", Int16x8SignMask, JSPROP_PERMANENT),
JS_PS_END
};
const JSFunctionSpec Int16x8Defn::TypedObjectMethods[] = {
JS_SELF_HOSTED_FN("toSource", "SimdToSource", 0, 0),
JS_FS_END
@ -377,11 +300,6 @@ const JSFunctionSpec Int32x4Defn::TypeDescriptorMethods[] = {
JS_FS_END,
};
const JSPropertySpec Int32x4Defn::TypedObjectProperties[] = {
JS_PSG("signMask", Int32x4SignMask, JSPROP_PERMANENT),
JS_PS_END
};
const JSFunctionSpec Int32x4Defn::TypedObjectMethods[] = {
JS_SELF_HOSTED_FN("toSource", "SimdToSource", 0, 0),
JS_FS_END
@ -517,8 +435,7 @@ CreateAndBindSimdClass(JSContext* cx, Handle<GlobalObject*> global, HandleObject
return nullptr;
if (!LinkConstructorAndPrototype(cx, typeDescr, proto) ||
!DefinePropertiesAndFunctions(cx, proto, T::TypedObjectProperties,
T::TypedObjectMethods))
!JS_DefineFunctions(cx, proto, T::TypedObjectMethods))
{
return nullptr;
}

View File

@ -114,7 +114,6 @@
V(fromInt32x4, (FuncConvert<Int32x4, Float32x4> ), 1) \
V(fromInt32x4Bits, (FuncConvertBits<Int32x4, Float32x4>), 1) \
V(neg, (UnaryFunc<Float32x4, Neg, Float32x4>), 1) \
V(not, (CoercedUnaryFunc<Float32x4, Int32x4, Not, Float32x4>), 1) \
V(reciprocalApproximation, (UnaryFunc<Float32x4, RecApprox, Float32x4>), 1) \
V(reciprocalSqrtApproximation, (UnaryFunc<Float32x4, RecSqrtApprox, Float32x4>), 1) \
V(splat, (FuncSplat<Float32x4>), 1) \
@ -122,7 +121,6 @@
#define FLOAT32X4_BINARY_FUNCTION_LIST(V) \
V(add, (BinaryFunc<Float32x4, Add, Float32x4>), 2) \
V(and, (CoercedBinaryFunc<Float32x4, Int32x4, And, Float32x4>), 2) \
V(div, (BinaryFunc<Float32x4, Div, Float32x4>), 2) \
V(equal, (CompareFunc<Float32x4, Equal, Bool32x4>), 2) \
V(extractLane, (ExtractLane<Float32x4>), 2) \
@ -140,9 +138,7 @@
V(minNum, (BinaryFunc<Float32x4, MinNum, Float32x4>), 2) \
V(mul, (BinaryFunc<Float32x4, Mul, Float32x4>), 2) \
V(notEqual, (CompareFunc<Float32x4, NotEqual, Bool32x4>), 2) \
V(or, (CoercedBinaryFunc<Float32x4, Int32x4, Or, Float32x4>), 2) \
V(sub, (BinaryFunc<Float32x4, Sub, Float32x4>), 2) \
V(xor, (CoercedBinaryFunc<Float32x4, Int32x4, Xor, Float32x4>), 2)
V(sub, (BinaryFunc<Float32x4, Sub, Float32x4>), 2)
#define FLOAT32X4_TERNARY_FUNCTION_LIST(V) \
V(replaceLane, (ReplaceLane<Float32x4>), 3) \
@ -244,7 +240,6 @@
#define INT8X16_TERNARY_FUNCTION_LIST(V) \
V(replaceLane, (ReplaceLane<Int8x16>), 3) \
V(select, (Select<Int8x16, Bool8x16>), 3) \
V(selectBits, (SelectBits<Int8x16, Int8x16>), 3) \
V(store, (Store<Int8x16, 16>), 3)
#define INT8X16_SHUFFLE_FUNCTION_LIST(V) \
@ -289,7 +284,6 @@
#define INT16X8_TERNARY_FUNCTION_LIST(V) \
V(replaceLane, (ReplaceLane<Int16x8>), 3) \
V(select, (Select<Int16x8, Bool16x8>), 3) \
V(selectBits, (SelectBits<Int16x8, Int16x8>), 3) \
V(store, (Store<Int16x8, 8>), 3)
#define INT16X8_SHUFFLE_FUNCTION_LIST(V) \
@ -339,7 +333,6 @@
#define INT32X4_TERNARY_FUNCTION_LIST(V) \
V(replaceLane, (ReplaceLane<Int32x4>), 3) \
V(select, (Select<Int32x4, Bool32x4>), 3) \
V(selectBits, (SelectBits<Int32x4, Int32x4>), 3) \
V(store, (Store<Int32x4, 4>), 3) \
V(store3, (Store<Int32x4, 3>), 3) \
V(store2, (Store<Int32x4, 2>), 3) \
@ -355,58 +348,235 @@
INT32X4_TERNARY_FUNCTION_LIST(V) \
INT32X4_SHUFFLE_FUNCTION_LIST(V)
#define FOREACH_BOOL_SIMD_OP(_) \
/*
* The FOREACH macros below partition all of the SIMD operations into disjoint
* sets.
*/
// Operations available on all SIMD types. Mixed arity.
#define FOREACH_COMMON_SIMD_OP(_) \
_(extractLane) \
_(replaceLane) \
_(check) \
_(splat)
// Lanewise operations available on numeric SIMD types.
// Include lane-wise select here since it is not arithmetic and defined on
// numeric types too.
#define FOREACH_LANE_SIMD_OP(_) \
_(select) \
_(swizzle) \
_(shuffle)
// Memory operations available on numeric SIMD types.
#define FOREACH_MEMORY_SIMD_OP(_) \
_(load) \
_(store)
// Memory operations available on numeric X4 SIMD types.
#define FOREACH_MEMORY_X4_SIMD_OP(_) \
_(load1) \
_(load2) \
_(load3) \
_(store1) \
_(store2) \
_(store3)
// Unary operations on Bool vectors.
#define FOREACH_BOOL_SIMD_UNOP(_) \
_(allTrue) \
_(anyTrue)
#define CONVERSION_INT32X4_SIMD_OP(_) \
// Unary bitwise SIMD operators defined on all integer and boolean SIMD types.
#define FOREACH_BITWISE_SIMD_UNOP(_) \
_(not)
// Binary bitwise SIMD operators defined on all integer and boolean SIMD types.
#define FOREACH_BITWISE_SIMD_BINOP(_) \
_(and) \
_(or) \
_(xor)
// Bitwise shifts defined on integer SIMD types.
#define FOREACH_SHIFT_SIMD_OP(_) \
_(shiftLeftByScalar) \
_(shiftRightArithmeticByScalar) \
_(shiftRightLogicalByScalar)
// Unary arithmetic operators defined on numeric SIMD types.
#define FOREACH_NUMERIC_SIMD_UNOP(_) \
_(neg)
// Binary arithmetic operators defined on numeric SIMD types.
#define FOREACH_NUMERIC_SIMD_BINOP(_) \
_(add) \
_(sub) \
_(mul)
// Unary arithmetic operators defined on floating point SIMD types.
#define FOREACH_FLOAT_SIMD_UNOP(_) \
_(abs) \
_(sqrt) \
_(reciprocalApproximation) \
_(reciprocalSqrtApproximation)
// Binary arithmetic operators defined on floating point SIMD types.
#define FOREACH_FLOAT_SIMD_BINOP(_) \
_(div) \
_(max) \
_(min) \
_(maxNum) \
_(minNum)
// Comparison operators defined on numeric SIMD types.
#define FOREACH_COMP_SIMD_OP(_) \
_(lessThan) \
_(lessThanOrEqual) \
_(equal) \
_(notEqual) \
_(greaterThan) \
_(greaterThanOrEqual)
/*
* All SIMD operations, excluding casts.
*/
#define FORALL_SIMD_NONCAST_OP(_) \
FOREACH_COMMON_SIMD_OP(_) \
FOREACH_LANE_SIMD_OP(_) \
FOREACH_MEMORY_SIMD_OP(_) \
FOREACH_MEMORY_X4_SIMD_OP(_) \
FOREACH_BOOL_SIMD_UNOP(_) \
FOREACH_BITWISE_SIMD_UNOP(_) \
FOREACH_BITWISE_SIMD_BINOP(_) \
FOREACH_SHIFT_SIMD_OP(_) \
FOREACH_NUMERIC_SIMD_UNOP(_) \
FOREACH_NUMERIC_SIMD_BINOP(_) \
FOREACH_FLOAT_SIMD_UNOP(_) \
FOREACH_FLOAT_SIMD_BINOP(_) \
FOREACH_COMP_SIMD_OP(_)
/*
* All operations on integer SIMD types, excluding casts and
* FOREACH_MEMORY_X4_OP.
*/
#define FORALL_INT_SIMD_OP(_) \
FOREACH_COMMON_SIMD_OP(_) \
FOREACH_LANE_SIMD_OP(_) \
FOREACH_MEMORY_SIMD_OP(_) \
FOREACH_BITWISE_SIMD_UNOP(_) \
FOREACH_BITWISE_SIMD_BINOP(_) \
FOREACH_SHIFT_SIMD_OP(_) \
FOREACH_NUMERIC_SIMD_UNOP(_) \
FOREACH_NUMERIC_SIMD_BINOP(_) \
FOREACH_COMP_SIMD_OP(_)
/*
* All operations on floating point SIMD types, excluding casts and
* FOREACH_MEMORY_X4_OP.
*/
#define FORALL_FLOAT_SIMD_OP(_) \
FOREACH_COMMON_SIMD_OP(_) \
FOREACH_LANE_SIMD_OP(_) \
FOREACH_MEMORY_SIMD_OP(_) \
FOREACH_NUMERIC_SIMD_UNOP(_) \
FOREACH_NUMERIC_SIMD_BINOP(_) \
FOREACH_FLOAT_SIMD_UNOP(_) \
FOREACH_FLOAT_SIMD_BINOP(_) \
FOREACH_COMP_SIMD_OP(_)
/*
* All operations on Bool SIMD types.
*
* These types don't have casts, so no need to specialize.
*/
#define FORALL_BOOL_SIMD_OP(_) \
FOREACH_COMMON_SIMD_OP(_) \
FOREACH_BOOL_SIMD_UNOP(_) \
FOREACH_BITWISE_SIMD_UNOP(_) \
FOREACH_BITWISE_SIMD_BINOP(_)
/*
* The sets of cast operations are listed per type below.
*
* These sets are not disjoint.
*/
#define FOREACH_INT8X16_SIMD_CAST(_) \
_(fromFloat32x4Bits) \
_(fromFloat64x2Bits) \
_(fromInt16x8Bits) \
_(fromInt32x4Bits)
#define FOREACH_INT16X8_SIMD_CAST(_) \
_(fromFloat32x4Bits) \
_(fromFloat64x2Bits) \
_(fromInt8x16Bits) \
_(fromInt32x4Bits)
#define FOREACH_INT32X4_SIMD_CAST(_) \
_(fromFloat32x4) \
_(fromFloat32x4Bits) \
_(fromFloat64x2Bits) \
_(fromInt8x16Bits) \
_(fromInt16x8Bits)
#define FOREACH_FLOAT32X4_SIMD_CAST(_)\
_(fromFloat64x2Bits) \
_(fromInt8x16Bits) \
_(fromInt16x8Bits) \
_(fromInt32x4) \
_(fromInt32x4Bits)
#define FOREACH_FLOAT64X2_SIMD_CAST(_)\
_(fromFloat32x4Bits) \
_(fromInt8x16Bits) \
_(fromInt16x8Bits) \
_(fromInt32x4Bits)
// All operations on Int32x4.
#define FORALL_INT32X4_SIMD_OP(_) \
FORALL_INT_SIMD_OP(_) \
FOREACH_MEMORY_X4_SIMD_OP(_) \
FOREACH_INT32X4_SIMD_CAST(_)
// All operations on Float32X4
#define FORALL_FLOAT32X4_SIMD_OP(_) \
FORALL_FLOAT_SIMD_OP(_) \
FOREACH_MEMORY_X4_SIMD_OP(_) \
FOREACH_FLOAT32X4_SIMD_CAST(_)
/*
* All SIMD operations assuming only 32x4 types exist.
* This is used in the current asm.js impl.
*/
#define FORALL_SIMD_ASMJS_OP(_) \
FORALL_SIMD_NONCAST_OP(_) \
_(fromFloat32x4) \
_(fromFloat32x4Bits) \
_(fromInt32x4) \
_(fromInt32x4Bits)
// All operations on Int32x4 in the asm.js world
#define FORALL_INT32X4_ASMJS_OP(_) \
FORALL_INT_SIMD_OP(_) \
FOREACH_MEMORY_X4_SIMD_OP(_) \
_(fromFloat32x4) \
_(fromFloat32x4Bits)
#define FOREACH_INT32X4_SIMD_OP(_) \
CONVERSION_INT32X4_SIMD_OP(_) \
_(selectBits) \
_(shiftLeftByScalar) \
_(shiftRightArithmeticByScalar) \
_(shiftRightLogicalByScalar)
#define UNARY_ARITH_FLOAT32X4_SIMD_OP(_) \
_(abs) \
_(sqrt) \
_(reciprocalApproximation) \
_(reciprocalSqrtApproximation)
#define BINARY_ARITH_FLOAT32X4_SIMD_OP(_) \
_(div) \
_(max) \
_(min) \
_(maxNum) \
_(minNum)
#define FOREACH_FLOAT32X4_SIMD_OP(_) \
UNARY_ARITH_FLOAT32X4_SIMD_OP(_) \
BINARY_ARITH_FLOAT32X4_SIMD_OP(_)\
_(fromInt32x4) \
// All operations on Float32X4 in the asm.js world.
#define FORALL_FLOAT32X4_ASMJS_OP(_) \
FORALL_FLOAT_SIMD_OP(_) \
FOREACH_MEMORY_X4_SIMD_OP(_) \
_(fromInt32x4) \
_(fromInt32x4Bits)
#define ARITH_COMMONX4_SIMD_OP(_) \
_(add) \
_(sub) \
_(mul)
#define BITWISE_COMMONX4_SIMD_OP(_) \
_(and) \
_(or) \
_(xor)
#define COMP_COMMONX4_TO_BOOL32X4_SIMD_OP(_) \
_(lessThan) \
_(lessThanOrEqual) \
_(equal) \
_(notEqual) \
_(greaterThan) \
_(greaterThanOrEqual)
// TODO: remove when all SIMD calls are inlined (bug 1112155)
#define ION_COMMONX4_SIMD_OP(_) \
ARITH_COMMONX4_SIMD_OP(_) \
BITWISE_COMMONX4_SIMD_OP(_) \
FOREACH_NUMERIC_SIMD_BINOP(_) \
_(extractLane) \
_(replaceLane) \
_(select) \
_(splat) \
_(not) \
_(neg) \
_(swizzle) \
_(shuffle) \
@ -419,14 +589,6 @@
_(store2) \
_(store3) \
_(check)
#define FOREACH_COMMONX4_SIMD_OP(_) \
ION_COMMONX4_SIMD_OP(_) \
COMP_COMMONX4_TO_BOOL32X4_SIMD_OP(_)
#define FORALL_SIMD_OP(_) \
FOREACH_INT32X4_SIMD_OP(_) \
FOREACH_FLOAT32X4_SIMD_OP(_) \
FOREACH_BOOL_SIMD_OP(_) \
FOREACH_COMMONX4_SIMD_OP(_)
namespace js {

View File

@ -211,11 +211,6 @@ Optimization failed because SIMD JIT support was not enabled.
The type observed as being retrieved from this property access did not
match an optimizable type.
### UnknownSimdProperty
The property being accessed on the object is not one of the optimizable
property names.
### HasCommonInliningPath
Inlining was abandoned because the inlining call path was repeated. A

View File

@ -120,11 +120,6 @@ conditions are documented below:
Attempts to optimize a property access on `window` which refers to
a property on the global object.
### GetProp_SimdGetter
Optimizes property accesses to SIMD vectors. Accesses to properties
signMask, x, y, w, and z are optimized.
### GetProp_TypedObject
Optimizes accesses to properties on TypedObjects.

View File

@ -1,40 +0,0 @@
load(libdir + "simd.js");
setJitCompilerOption("ion.warmup.trigger", 50);
var helpers = (function() {
var i32 = new Int32Array(2);
var f32 = new Float32Array(i32.buffer);
return {
and: function(x, y) {
f32[0] = x;
f32[1] = y;
i32[0] = i32[0] & i32[1];
return f32[0];
},
or: function(x, y) {
f32[0] = x;
f32[1] = y;
i32[0] = i32[0] | i32[1];
return f32[0];
},
xor: function(x, y) {
f32[0] = x;
f32[1] = y;
i32[0] = i32[0] ^ i32[1];
return f32[0];
},
}
})();
function f() {
var f1 = SIMD.Float32x4(1, 2, 3, 4);
var f2 = SIMD.Float32x4(4, 3, 2, 1);
for (var i = 0; i < 150; i++) {
assertEqX4(SIMD.Float32x4.and(f1, f2), binaryX4(helpers.and, f1, f2));
assertEqX4(SIMD.Float32x4.or(f1, f2), binaryX4(helpers.or, f1, f2));
assertEqX4(SIMD.Float32x4.xor(f1, f2), binaryX4(helpers.xor, f1, f2));
}
}
f();

View File

@ -19,15 +19,11 @@ function f() {
assertEq(SIMD.Int32x4.extractLane(i4, 2), 3);
assertEq(SIMD.Int32x4.extractLane(i4, 3), -4);
assertEq(i4.signMask, 0b1010);
assertEq(SIMD.Float32x4.extractLane(f4, 0), v);
assertEq(SIMD.Float32x4.extractLane(f4, 1), NaN);
assertEq(SIMD.Float32x4.extractLane(f4, 2), Infinity);
assertEq(SIMD.Float32x4.extractLane(f4, 3), -0);
assertEq(f4.signMask, 0b1000);
assertEq(SIMD.Bool32x4.extractLane(b4, 0), true);
assertEq(SIMD.Bool32x4.extractLane(b4, 1), true);
assertEq(SIMD.Bool32x4.extractLane(b4, 2), false);

View File

@ -2,14 +2,6 @@ load(libdir + 'simd.js');
setJitCompilerOption("ion.warmup.trigger", 50);
function selectBits(mask, ifTrue, ifFalse) {
var Int32x4 = SIMD.Int32x4;
var tr = Int32x4.and(mask, ifTrue);
var fr = Int32x4.and(Int32x4.not(mask), ifFalse);
var orApplied = Int32x4.or(tr, fr);
return simdToArray(orApplied);
}
function select(type, mask, ifTrue, ifFalse) {
var arr = [];
for (var i = 0; i < 4; i++) {
@ -37,10 +29,7 @@ function f() {
assertEqX4(SIMD.Int32x4.select(TFTF, i1, i2), select(SIMD.Int32x4, TFTF, i1, i2));
assertEqX4(SIMD.Int32x4.select(TTFT, i1, i2), select(SIMD.Int32x4, TTFT, i1, i2));
assertEqX4(SIMD.Int32x4.selectBits(mask, i1, i2), selectBits(mask, i1, i2));
}
}
f();

View File

@ -18,7 +18,6 @@ function f() {
var b4 = SIMD.Bool32x4(true, false, true, false);
var BitOrZero = (x) => x | 0;
for (var i = 0; i < 150; i++) {
assertEqX4(SIMD.Float32x4.not(f4), unaryX4(notf, f4, Math.fround));
assertEqX4(SIMD.Float32x4.neg(f4), unaryX4((x) => -x, f4, Math.fround));
assertEqX4(SIMD.Float32x4.abs(f4), unaryX4(Math.abs, f4, Math.fround));
assertEqX4(SIMD.Float32x4.sqrt(f4), unaryX4(Math.sqrt, f4, Math.fround));

View File

@ -155,6 +155,13 @@ assertAsmTypeFail('glob', USE_ASM + I32 + EXTI4 + "function f() {var x=i4(1,2,3,
assertAsmTypeFail('glob', USE_ASM + I32 + EXTF4 + "function f() {var x=i4(1,2,3,4); return e(x,0) | 0;} return f");
assertAsmTypeFail('glob', USE_ASM + I32 + EXTI4 + "function f() {var x=i4(1,2,3,4); var i=0; return e(x,i) | 0;} return f");
// The signMask property is no longer supported. Replaced by allTrue / anyTrue.
assertAsmTypeFail('glob', USE_ASM + "function f() {var x=42; return x.signMask;} return f");
assertAsmTypeFail('glob', USE_ASM + "function f() {var x=42.; return x.signMask;} return f");
assertAsmTypeFail('glob', USE_ASM + FROUND + "function f() {var x=f32(42.); return x.signMask;} return f");
assertAsmTypeFail('glob', USE_ASM + I32 + 'function f() { var x=i4(1,2,3,4); return x.signMask | 0 } return f');
assertAsmTypeFail('glob', USE_ASM + F32 + FROUND + 'var Infinity = glob.Infinity; function f() { var x=f4(0,0,0,0); x=f4(f32(1), f32(-13.37), f32(42), f32(-Infinity)); return x.signMask | 0 } return f');
// signMask
function CheckSignMask(innerBody, type, expected) {
var coerceBefore, coerceAfter, extractLane;
@ -201,17 +208,6 @@ assertAsmTypeFail('glob', USE_ASM + I32 + "function f() {var x=i4(1,2,3,4); var
assertAsmTypeFail('glob', USE_ASM + I32 + "function f() {var x=i4(1,2,3,4); return (x.signMask > (1>>>0)) | 0;} return f");
assertAsmTypeFail('glob', USE_ASM + I32 + FROUND + "function f() {var x=i4(1,2,3,4); var y=f32(0.0); y=x.signMask;} return f");
assertAsmTypeFail('glob', USE_ASM + "function f() {var x=42; return x.signMask;} return f");
assertAsmTypeFail('glob', USE_ASM + "function f() {var x=42.; return x.signMask;} return f");
assertAsmTypeFail('glob', USE_ASM + FROUND + "function f() {var x=f32(42.); return x.signMask;} return f");
assertEq(asmLink(asmCompile('glob', USE_ASM + I32 + 'function f() { var x=i4(1,2,3,4); return x.signMask | 0 } return f'), this)(), 0b0000);
assertEq(asmLink(asmCompile('glob', USE_ASM + I32 + 'function f() { var x=i4(0,-1, ' + INT32_MAX + ',' + INT32_MIN + '); return x.signMask | 0 } return f'), this)(), 0b1010);
assertEq(asmLink(asmCompile('glob', USE_ASM + F32 + FROUND + 'var Infinity = glob.Infinity; function f() { var x=f4(0,0,0,0); x=f4(f32(1), f32(-13.37), f32(42), f32(-Infinity)); return x.signMask | 0 } return f'), this)(), 0b1010);
assertEq(asmLink(asmCompile('glob', USE_ASM + F32 + FROUND + 'var Infinity = glob.Infinity; function f() { var x=f4(0,0,0,0); x=f4(f32(-1), f32(0), f32(-0.000001), f32(Infinity)); return x.signMask | 0 } return f'), this)(), 0b0101);
assertEq(asmLink(asmCompile('glob', USE_ASM + F32 + FROUND + 'var NaN = glob.NaN; function f() { var x=f4(0,0,0,0); x=f4(f32(-1), f32(NaN), f32(-0), f32(0)); return x.signMask | 0 } return f'), this)(), 0b0101);
// 1.3.3. Variable assignments
assertAsmTypeFail('glob', USE_ASM + I32 + I32A + "function f() {var x=i4(1,2,3,4); x=i4();} return f");
assertAsmTypeFail('glob', USE_ASM + I32 + I32A + "function f() {var x=i4(1,2,3,4); x=i4(1);} return f");
@ -575,18 +571,6 @@ 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]);
@ -831,30 +815,16 @@ CheckI4(ANDI32, 'var x=i4(42,1337,-1,13); var y=i4(2, 4, 7, 15); x=andd(x,y)', [
CheckI4(ORI32, ' var x=i4(42,1337,-1,13); var y=i4(2, 4, 7, 15); x=orr(x,y)', [42 | 2, 1337 | 4, -1 | 7, 13 | 15]);
CheckI4(XORI32, 'var x=i4(42,1337,-1,13); var y=i4(2, 4, 7, 15); x=xorr(x,y)', [42 ^ 2, 1337 ^ 4, -1 ^ 7, 13 ^ 15]);
// No bitwise ops on Float32x4.
const ANDF32 = 'var andd=f4.and;';
const ORF32 = 'var orr=f4.or;';
const XORF32 = 'var xorr=f4.xor;';
const NOTF32 = 'var nott=f4.not;';
var bitwise = (function() {
var asf32 = new Float32Array(2);
var asi32 = new Int32Array(asf32.buffer);
function andd(x, y) { asf32[0] = x; asf32[1] = y; asi32[0] = asi32[0] & asi32[1]; return asf32[0]; }
function orr(x, y) { asf32[0] = x; asf32[1] = y; asi32[0] = asi32[0] | asi32[1]; return asf32[0]; }
function xorr(x, y) { asf32[0] = x; asf32[1] = y; asi32[0] = asi32[0] ^ asi32[1]; return asf32[0]; }
function andx4(x, y) { var res = []; for (var i = 0; i < 4; i++) res[i] = andd(x[i], y[i]); return res; }
function orx4(x, y) { var res = []; for (var i = 0; i < 4; i++) res[i] = orr(x[i], y[i]); return res; }
function xorx4(x, y) { var res = []; for (var i = 0; i < 4; i++) res[i] = xorr(x[i], y[i]); return res; }
return {
and: andx4,
or: orx4,
xor: xorx4
}
})();
CheckF4(ANDF32, '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)', bitwise.and([42, 13.37, -1.42, 23.10], [19.89, 2.4, 8.15, 16.36]));
CheckF4(ORF32, '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)', bitwise.or( [42, 13.37, -1.42, 23.10], [19.89, 2.4, 8.15, 16.36]));
CheckF4(XORF32, '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)', bitwise.xor([42, 13.37, -1.42, 23.10], [19.89, 2.4, 8.15, 16.36]));
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;'

View File

@ -5705,7 +5705,11 @@ GetTemplateObjectForNative(JSContext* cx, Native native, const CallArgs& args,
// Operations producing an int32x4.
if (false
ION_COMMONX4_SIMD_OP(ADD_INT32X4_SIMD_OP_NAME_)
FOREACH_INT32X4_SIMD_OP(ADD_INT32X4_SIMD_OP_NAME_))
FOREACH_BITWISE_SIMD_UNOP(ADD_INT32X4_SIMD_OP_NAME_)
FOREACH_BITWISE_SIMD_BINOP(ADD_INT32X4_SIMD_OP_NAME_)
FOREACH_SHIFT_SIMD_OP(ADD_INT32X4_SIMD_OP_NAME_)
ADD_INT32X4_SIMD_OP_NAME_(fromFloat32x4)
ADD_INT32X4_SIMD_OP_NAME_(fromFloat32x4Bits))
{
Rooted<SimdTypeDescr*> descr(cx, cx->global()->getOrCreateSimdTypeDescr<Int32x4>(cx));
res.set(cx->compartment()->jitCompartment()->getSimdTemplateObjectFor(cx, descr));
@ -5713,9 +5717,10 @@ GetTemplateObjectForNative(JSContext* cx, Native native, const CallArgs& args,
}
// Operations producing a bool32x4.
if (false
BITWISE_COMMONX4_SIMD_OP(ADD_BOOL32X4_SIMD_OP_NAME_)
COMP_COMMONX4_TO_BOOL32X4_SIMD_OP(ADD_INT32X4_SIMD_OP_NAME_)
COMP_COMMONX4_TO_BOOL32X4_SIMD_OP(ADD_FLOAT32X4_SIMD_OP_NAME_))
FOREACH_BITWISE_SIMD_UNOP(ADD_BOOL32X4_SIMD_OP_NAME_)
FOREACH_BITWISE_SIMD_BINOP(ADD_BOOL32X4_SIMD_OP_NAME_)
FOREACH_COMP_SIMD_OP(ADD_INT32X4_SIMD_OP_NAME_)
FOREACH_COMP_SIMD_OP(ADD_FLOAT32X4_SIMD_OP_NAME_))
{
Rooted<SimdTypeDescr*> descr(cx, cx->global()->getOrCreateSimdTypeDescr<Bool32x4>(cx));
res.set(cx->compartment()->jitCompartment()->getSimdTemplateObjectFor(cx, descr));
@ -5723,7 +5728,10 @@ GetTemplateObjectForNative(JSContext* cx, Native native, const CallArgs& args,
}
// Operations producing a float32x4.
if (false
FOREACH_FLOAT32X4_SIMD_OP(ADD_FLOAT32X4_SIMD_OP_NAME_)
FOREACH_FLOAT_SIMD_UNOP(ADD_FLOAT32X4_SIMD_OP_NAME_)
FOREACH_FLOAT_SIMD_BINOP(ADD_FLOAT32X4_SIMD_OP_NAME_)
ADD_FLOAT32X4_SIMD_OP_NAME_(fromInt32x4)
ADD_FLOAT32X4_SIMD_OP_NAME_(fromInt32x4Bits)
ION_COMMONX4_SIMD_OP(ADD_FLOAT32X4_SIMD_OP_NAME_))
{
Rooted<SimdTypeDescr*> descr(cx, cx->global()->getOrCreateSimdTypeDescr<Float32x4>(cx));

View File

@ -10997,11 +10997,6 @@ IonBuilder::jsop_getprop(PropertyName* name)
if (!getPropTryConstant(&emitted, obj, NameToId(name), types) || emitted)
return emitted;
// Try to emit SIMD getter loads
trackOptimizationAttempt(TrackedStrategy::GetProp_SimdGetter);
if (!getPropTrySimdGetter(&emitted, obj, name) || emitted)
return emitted;
// Try to emit loads from known binary data blocks
trackOptimizationAttempt(TrackedStrategy::GetProp_TypedObject);
if (!getPropTryTypedObject(&emitted, obj, name) || emitted)
@ -11260,50 +11255,6 @@ IonBuilder::SimdTypeDescrToMIRType(SimdTypeDescr::Type type)
MOZ_CRASH("unimplemented MIR type for a SimdTypeDescr::Type");
}
bool
IonBuilder::getPropTrySimdGetter(bool* emitted, MDefinition* obj, PropertyName* name)
{
MOZ_ASSERT(!*emitted);
if (!JitSupportsSimd()) {
trackOptimizationOutcome(TrackedOutcome::NoSimdJitSupport);
return true;
}
TypedObjectPrediction objPrediction = typedObjectPrediction(obj);
if (objPrediction.isUseless()) {
trackOptimizationOutcome(TrackedOutcome::AccessNotTypedObject);
return true;
}
if (objPrediction.kind() != type::Simd) {
trackOptimizationOutcome(TrackedOutcome::AccessNotSimdObject);
return true;
}
MIRType type = SimdTypeDescrToMIRType(objPrediction.simdType());
if (type == MIRType_Undefined) {
trackOptimizationOutcome(TrackedOutcome::SimdTypeNotOptimized);
return true;
}
const JSAtomState& names = compartment->runtime()->names();
// Reading the signMask property.
if (name != names.signMask) {
// Unknown getprop access on a SIMD value
trackOptimizationOutcome(TrackedOutcome::UnknownSimdProperty);
return true;
}
MSimdSignMask* ins = MSimdSignMask::New(alloc(), obj, type);
current->add(ins);
current->push(ins);
trackOptimizationSuccess();
*emitted = true;
return true;
}
bool
IonBuilder::getPropTryTypedObject(bool* emitted,
MDefinition* obj,

View File

@ -441,7 +441,6 @@ class IonBuilder
TemporaryTypeSet* types);
bool getPropTryInlineAccess(bool* emitted, MDefinition* obj, PropertyName* name,
BarrierKind barrier, TemporaryTypeSet* types);
bool getPropTrySimdGetter(bool* emitted, MDefinition* obj, PropertyName* name);
bool getPropTryTypedObject(bool* emitted, MDefinition* obj, PropertyName* name);
bool getPropTryScalarPropOfTypedObject(bool* emitted, MDefinition* typedObj,
int32_t fieldOffset,
@ -882,8 +881,7 @@ class IonBuilder
InliningStatus inlineSimdCheck(CallInfo& callInfo, JSNative native, SimdTypeDescr::Type type);
InliningStatus inlineSimdConvert(CallInfo& callInfo, JSNative native, bool isCast,
SimdTypeDescr::Type from, SimdTypeDescr::Type to);
InliningStatus inlineSimdSelect(CallInfo& callInfo, JSNative native, bool isElementWise,
SimdTypeDescr::Type type);
InliningStatus inlineSimdSelect(CallInfo& callInfo, JSNative native, SimdTypeDescr::Type type);
bool prepareForSimdLoadStore(CallInfo& callInfo, Scalar::Type simdType, MInstruction** elements,
MDefinition** index, Scalar::Type* arrayType);

View File

@ -4134,25 +4134,6 @@ LIRGenerator::visitSimdInsertElement(MSimdInsertElement* ins)
}
}
void
LIRGenerator::visitSimdSignMask(MSimdSignMask* ins)
{
MDefinition* input = ins->input();
MOZ_ASSERT(IsSimdType(input->type()));
MOZ_ASSERT(ins->type() == MIRType_Int32);
LUse use = useRegisterAtStart(input);
switch (input->type()) {
case MIRType_Int32x4:
case MIRType_Float32x4:
define(new(alloc()) LSimdSignMaskX4(use), ins);
break;
default:
MOZ_CRASH("Unexpected SIMD type extracting sign bits.");
}
}
void
LIRGenerator::visitSimdAllTrue(MSimdAllTrue* ins)
{

View File

@ -285,7 +285,6 @@ class LIRGenerator : public LIRGeneratorSpecific
void visitSimdUnbox(MSimdUnbox* ins);
void visitSimdExtractElement(MSimdExtractElement* ins);
void visitSimdInsertElement(MSimdInsertElement* ins);
void visitSimdSignMask(MSimdSignMask* ins);
void visitSimdSwizzle(MSimdSwizzle* ins);
void visitSimdGeneralShuffle(MSimdGeneralShuffle* ins);
void visitSimdShuffle(MSimdShuffle* ins);

View File

@ -3058,7 +3058,7 @@ IonBuilder::inlineSimdBool32x4(CallInfo& callInfo, JSNative native)
return inlineBinarySimd<MSimdBinaryBitwise>(callInfo, native, MSimdBinaryBitwise::OP##_, \
SimdTypeDescr::Bool32x4);
BITWISE_COMMONX4_SIMD_OP(INLINE_SIMD_BITWISE_)
FOREACH_BITWISE_SIMD_BINOP(INLINE_SIMD_BITWISE_)
#undef INLINE_SIMD_BITWISE_
if (native == js::simd_bool32x4_extractLane)
@ -3090,7 +3090,7 @@ IonBuilder::inlineSimdInt32x4(CallInfo& callInfo, JSNative native)
return inlineBinarySimd<MSimdBinaryArith>(callInfo, native, MSimdBinaryArith::Op_##OP, \
SimdTypeDescr::Int32x4);
ARITH_COMMONX4_SIMD_OP(INLINE_INT32X4_SIMD_ARITH_)
FOREACH_NUMERIC_SIMD_BINOP(INLINE_INT32X4_SIMD_ARITH_)
#undef INLINE_INT32X4_SIMD_ARITH_
#define INLINE_SIMD_BITWISE_(OP) \
@ -3098,7 +3098,7 @@ IonBuilder::inlineSimdInt32x4(CallInfo& callInfo, JSNative native)
return inlineBinarySimd<MSimdBinaryBitwise>(callInfo, native, MSimdBinaryBitwise::OP##_, \
SimdTypeDescr::Int32x4);
BITWISE_COMMONX4_SIMD_OP(INLINE_SIMD_BITWISE_)
FOREACH_BITWISE_SIMD_BINOP(INLINE_SIMD_BITWISE_)
#undef INLINE_SIMD_BITWISE_
if (native == js::simd_int32x4_shiftLeftByScalar)
@ -3112,7 +3112,7 @@ IonBuilder::inlineSimdInt32x4(CallInfo& callInfo, JSNative native)
if (native == js::simd_int32x4_##OP) \
return inlineCompSimd(callInfo, native, MSimdBinaryComp::OP, SimdTypeDescr::Int32x4);
COMP_COMMONX4_TO_BOOL32X4_SIMD_OP(INLINE_SIMD_COMPARISON_)
FOREACH_COMP_SIMD_OP(INLINE_SIMD_COMPARISON_)
#undef INLINE_SIMD_COMPARISON_
if (native == js::simd_int32x4_extractLane)
@ -3137,11 +3137,8 @@ IonBuilder::inlineSimdInt32x4(CallInfo& callInfo, JSNative native)
if (native == js::simd_int32x4_check)
return inlineSimdCheck(callInfo, native, SimdTypeDescr::Int32x4);
typedef bool IsElementWise;
if (native == js::simd_int32x4_select)
return inlineSimdSelect(callInfo, native, IsElementWise(true), SimdTypeDescr::Int32x4);
if (native == js::simd_int32x4_selectBits)
return inlineSimdSelect(callInfo, native, IsElementWise(false), SimdTypeDescr::Int32x4);
return inlineSimdSelect(callInfo, native, SimdTypeDescr::Int32x4);
if (native == js::simd_int32x4_swizzle)
return inlineSimdShuffle(callInfo, native, SimdTypeDescr::Int32x4, 1, 4);
@ -3178,23 +3175,15 @@ IonBuilder::inlineSimdFloat32x4(CallInfo& callInfo, JSNative native)
return inlineBinarySimd<MSimdBinaryArith>(callInfo, native, MSimdBinaryArith::Op_##OP, \
SimdTypeDescr::Float32x4);
ARITH_COMMONX4_SIMD_OP(INLINE_FLOAT32X4_SIMD_ARITH_)
BINARY_ARITH_FLOAT32X4_SIMD_OP(INLINE_FLOAT32X4_SIMD_ARITH_)
FOREACH_NUMERIC_SIMD_BINOP(INLINE_FLOAT32X4_SIMD_ARITH_)
FOREACH_FLOAT_SIMD_BINOP(INLINE_FLOAT32X4_SIMD_ARITH_)
#undef INLINE_FLOAT32X4_SIMD_ARITH_
#define INLINE_SIMD_BITWISE_(OP) \
if (native == js::simd_float32x4_##OP) \
return inlineBinarySimd<MSimdBinaryBitwise>(callInfo, native, MSimdBinaryBitwise::OP##_, \
SimdTypeDescr::Float32x4);
BITWISE_COMMONX4_SIMD_OP(INLINE_SIMD_BITWISE_)
#undef INLINE_SIMD_BITWISE_
#define INLINE_SIMD_COMPARISON_(OP) \
if (native == js::simd_float32x4_##OP) \
return inlineCompSimd(callInfo, native, MSimdBinaryComp::OP, SimdTypeDescr::Float32x4);
COMP_COMMONX4_TO_BOOL32X4_SIMD_OP(INLINE_SIMD_COMPARISON_)
FOREACH_COMP_SIMD_OP(INLINE_SIMD_COMPARISON_)
#undef INLINE_SIMD_COMPARISON_
if (native == js::simd_float32x4_extractLane)
@ -3206,13 +3195,10 @@ IonBuilder::inlineSimdFloat32x4(CallInfo& callInfo, JSNative native)
if (native == js::simd_float32x4_##OP) \
return inlineUnarySimd(callInfo, native, MSimdUnaryArith::OP, SimdTypeDescr::Float32x4);
UNARY_ARITH_FLOAT32X4_SIMD_OP(INLINE_SIMD_FLOAT32X4_UNARY_)
FOREACH_FLOAT_SIMD_UNOP(INLINE_SIMD_FLOAT32X4_UNARY_)
INLINE_SIMD_FLOAT32X4_UNARY_(neg)
#undef INLINE_SIMD_FLOAT32X4_UNARY_
if (native == js::simd_float32x4_not)
return inlineUnarySimd(callInfo, native, MSimdUnaryArith::not_, SimdTypeDescr::Float32x4);
typedef bool IsCast;
if (native == js::simd_float32x4_fromInt32x4)
return inlineSimdConvert(callInfo, native, IsCast(false), SimdTypeDescr::Int32x4, SimdTypeDescr::Float32x4);
@ -3225,9 +3211,8 @@ IonBuilder::inlineSimdFloat32x4(CallInfo& callInfo, JSNative native)
if (native == js::simd_float32x4_check)
return inlineSimdCheck(callInfo, native, SimdTypeDescr::Float32x4);
typedef bool IsElementWise;
if (native == js::simd_float32x4_select)
return inlineSimdSelect(callInfo, native, IsElementWise(true), SimdTypeDescr::Float32x4);
return inlineSimdSelect(callInfo, native, SimdTypeDescr::Float32x4);
if (native == js::simd_float32x4_swizzle)
return inlineSimdShuffle(callInfo, native, SimdTypeDescr::Float32x4, 1, 4);
@ -3521,8 +3506,7 @@ IonBuilder::inlineSimdConvert(CallInfo& callInfo, JSNative native, bool isCast,
}
IonBuilder::InliningStatus
IonBuilder::inlineSimdSelect(CallInfo& callInfo, JSNative native, bool isElementWise,
SimdTypeDescr::Type type)
IonBuilder::inlineSimdSelect(CallInfo& callInfo, JSNative native, SimdTypeDescr::Type type)
{
InlineTypedObject* templateObj = nullptr;
if (!checkInlineSimd(callInfo, native, type, 3, &templateObj))
@ -3531,7 +3515,7 @@ IonBuilder::inlineSimdSelect(CallInfo& callInfo, JSNative native, bool isElement
// See comment in inlineBinarySimd
MIRType mirType = SimdTypeDescrToMIRType(type);
MSimdSelect* ins = MSimdSelect::New(alloc(), callInfo.getArg(0), callInfo.getArg(1),
callInfo.getArg(2), mirType, isElementWise);
callInfo.getArg(2), mirType);
return boxSimd(callInfo, ins, templateObj);
}

View File

@ -1718,46 +1718,6 @@ class MSimdInsertElement
ALLOW_CLONE(MSimdInsertElement)
};
// Extracts the sign bits from a given vector, returning an MIRType_Int32.
class MSimdSignMask
: public MUnaryInstruction,
public SimdPolicy<0>::Data
{
protected:
explicit MSimdSignMask(MDefinition* obj, MIRType type)
: MUnaryInstruction(obj)
{
setResultType(MIRType_Int32);
specialization_ = type;
setMovable();
}
public:
INSTRUCTION_HEADER(SimdSignMask)
static MSimdSignMask* NewAsmJS(TempAllocator& alloc, MDefinition* obj)
{
MOZ_ASSERT(IsSimdType(obj->type()));
return new(alloc) MSimdSignMask(obj, obj->type());
}
static MSimdSignMask* New(TempAllocator& alloc, MDefinition* obj, MIRType type)
{
return new(alloc) MSimdSignMask(obj, type);
}
AliasSet getAliasSet() const override {
return AliasSet::None();
}
bool congruentTo(const MDefinition* ins) const override {
if (!ins->isSimdSignMask())
return false;
return congruentIfOperandsEqual(ins);
}
ALLOW_CLONE(MSimdSignMask)
};
// Returns true if all lanes are true.
class MSimdAllTrue
: public MUnaryInstruction,
@ -2062,7 +2022,7 @@ class MSimdUnaryArith
public:
enum Operation {
#define OP_LIST_(OP) OP,
UNARY_ARITH_FLOAT32X4_SIMD_OP(OP_LIST_)
FOREACH_FLOAT_SIMD_UNOP(OP_LIST_)
neg,
not_
#undef OP_LIST_
@ -2132,14 +2092,14 @@ class MSimdBinaryComp
public:
enum Operation {
#define NAME_(x) x,
COMP_COMMONX4_TO_BOOL32X4_SIMD_OP(NAME_)
FOREACH_COMP_SIMD_OP(NAME_)
#undef NAME_
};
static const char* OperationName(Operation op) {
switch (op) {
#define NAME_(x) case x: return #x;
COMP_COMMONX4_TO_BOOL32X4_SIMD_OP(NAME_)
FOREACH_COMP_SIMD_OP(NAME_)
#undef NAME_
}
MOZ_CRASH("unexpected operation");
@ -2216,16 +2176,16 @@ class MSimdBinaryArith
public:
enum Operation {
#define OP_LIST_(OP) Op_##OP,
ARITH_COMMONX4_SIMD_OP(OP_LIST_)
BINARY_ARITH_FLOAT32X4_SIMD_OP(OP_LIST_)
FOREACH_NUMERIC_SIMD_BINOP(OP_LIST_)
FOREACH_FLOAT_SIMD_BINOP(OP_LIST_)
#undef OP_LIST_
};
static const char* OperationName(Operation op) {
switch (op) {
#define OP_CASE_LIST_(OP) case Op_##OP: return #OP;
ARITH_COMMONX4_SIMD_OP(OP_CASE_LIST_)
BINARY_ARITH_FLOAT32X4_SIMD_OP(OP_CASE_LIST_)
FOREACH_NUMERIC_SIMD_BINOP(OP_CASE_LIST_)
FOREACH_FLOAT_SIMD_BINOP(OP_CASE_LIST_)
#undef OP_CASE_LIST_
}
MOZ_CRASH("unexpected operation");
@ -2410,11 +2370,8 @@ class MSimdSelect
: public MTernaryInstruction,
public SimdSelectPolicy::Data
{
bool isElementWise_;
MSimdSelect(MDefinition* mask, MDefinition* lhs, MDefinition* rhs, MIRType type,
bool isElementWise)
: MTernaryInstruction(mask, lhs, rhs), isElementWise_(isElementWise)
MSimdSelect(MDefinition* mask, MDefinition* lhs, MDefinition* rhs, MIRType type)
: MTernaryInstruction(mask, lhs, rhs)
{
MOZ_ASSERT(IsSimdType(type));
setResultType(type);
@ -2425,18 +2382,18 @@ class MSimdSelect
public:
INSTRUCTION_HEADER(SimdSelect)
static MSimdSelect* NewAsmJS(TempAllocator& alloc, MDefinition* mask, MDefinition* lhs,
MDefinition* rhs, MIRType t, bool isElementWise)
MDefinition* rhs, MIRType t)
{
MOZ_ASSERT(mask->type() == (isElementWise ? MIRType_Bool32x4 : t));
MOZ_ASSERT(mask->type() == MIRType_Bool32x4);
MOZ_ASSERT(lhs->type() == rhs->type());
MOZ_ASSERT(lhs->type() == t);
return new(alloc) MSimdSelect(mask, lhs, rhs, t, isElementWise);
return new(alloc) MSimdSelect(mask, lhs, rhs, t);
}
static MSimdSelect* New(TempAllocator& alloc, MDefinition* mask, MDefinition* lhs,
MDefinition* rhs, MIRType t, bool isElementWise)
MDefinition* rhs, MIRType t)
{
return new(alloc) MSimdSelect(mask, lhs, rhs, t, isElementWise);
return new(alloc) MSimdSelect(mask, lhs, rhs, t);
}
MDefinition* mask() const {
@ -2447,14 +2404,8 @@ class MSimdSelect
return AliasSet::None();
}
bool isElementWise() const {
return isElementWise_;
}
bool congruentTo(const MDefinition* ins) const override {
if (!congruentIfOperandsEqual(ins))
return false;
return isElementWise_ == ins->toSimdSelect()->isElementWise();
return congruentIfOperandsEqual(ins);
}
ALLOW_CLONE(MSimdSelect)

View File

@ -21,7 +21,6 @@ namespace jit {
_(SimdReinterpretCast) \
_(SimdExtractElement) \
_(SimdInsertElement) \
_(SimdSignMask) \
_(SimdSwizzle) \
_(SimdGeneralShuffle) \
_(SimdShuffle) \

View File

@ -245,7 +245,6 @@ class CodeGeneratorARM : public CodeGeneratorShared
void visitSimdReinterpretCast(LSimdReinterpretCast* ins) { MOZ_CRASH("NYI"); }
void visitSimdExtractElementI(LSimdExtractElementI* ins) { MOZ_CRASH("NYI"); }
void visitSimdExtractElementF(LSimdExtractElementF* ins) { MOZ_CRASH("NYI"); }
void visitSimdSignMaskX4(LSimdSignMaskX4* ins) { MOZ_CRASH("NYI"); }
void visitSimdGeneralShuffleI(LSimdGeneralShuffleI* lir) { MOZ_CRASH("NYI"); }
void visitSimdGeneralShuffleF(LSimdGeneralShuffleF* lir) { MOZ_CRASH("NYI"); }
void visitSimdSwizzleI(LSimdSwizzleI* lir) { MOZ_CRASH("NYI"); }

View File

@ -240,7 +240,6 @@ class CodeGeneratorARM64 : public CodeGeneratorShared
void visitFloat32x4(LFloat32x4* ins) { MOZ_CRASH("NYI"); }
void visitSimdExtractElementI(LSimdExtractElementI* ins) { MOZ_CRASH("NYI"); }
void visitSimdExtractElementF(LSimdExtractElementF* ins) { MOZ_CRASH("NYI"); }
void visitSimdSignMaskX4(LSimdSignMaskX4* ins) { MOZ_CRASH("NYI"); }
void visitSimdBinaryCompIx4(LSimdBinaryCompIx4* lir) { MOZ_CRASH("NYI"); }
void visitSimdBinaryCompFx4(LSimdBinaryCompFx4* lir) { MOZ_CRASH("NYI"); }
void visitSimdBinaryArithIx4(LSimdBinaryArithIx4* lir) { MOZ_CRASH("NYI"); }

View File

@ -243,7 +243,6 @@ class CodeGeneratorMIPSShared : public CodeGeneratorShared
void visitSimdReinterpretCast(LSimdReinterpretCast* ins) { MOZ_CRASH("NYI"); }
void visitSimdExtractElementI(LSimdExtractElementI* ins) { MOZ_CRASH("NYI"); }
void visitSimdExtractElementF(LSimdExtractElementF* ins) { MOZ_CRASH("NYI"); }
void visitSimdSignMaskX4(LSimdSignMaskX4* ins) { MOZ_CRASH("NYI"); }
void visitSimdBinaryCompIx4(LSimdBinaryCompIx4* lir) { MOZ_CRASH("NYI"); }
void visitSimdBinaryCompFx4(LSimdBinaryCompFx4* lir) { MOZ_CRASH("NYI"); }
void visitSimdBinaryArithIx4(LSimdBinaryArithIx4* lir) { MOZ_CRASH("NYI"); }

View File

@ -325,16 +325,6 @@ class LSimdInsertElementF : public LSimdInsertElementBase
{}
};
class LSimdSignMaskX4 : public LInstructionHelper<1, 1, 0>
{
public:
LIR_HEADER(SimdSignMaskX4);
explicit LSimdSignMaskX4(const LAllocation& input) {
setOperand(0, input);
}
};
// Base class for both int32x4 and float32x4 shuffle instructions.
class LSimdSwizzleBase : public LInstructionHelper<1, 1, 0>
{

View File

@ -30,7 +30,6 @@
_(SimdExtractElementF) \
_(SimdInsertElementI) \
_(SimdInsertElementF) \
_(SimdSignMaskX4) \
_(SimdGeneralShuffleI) \
_(SimdGeneralShuffleF) \
_(SimdSwizzleI) \

View File

@ -2522,16 +2522,6 @@ CodeGeneratorX86Shared::visitSimdInsertElementF(LSimdInsertElementF* ins)
masm.freeStack(Simd128DataSize);
}
void
CodeGeneratorX86Shared::visitSimdSignMaskX4(LSimdSignMaskX4* ins)
{
FloatRegister input = ToFloatRegister(ins->input());
Register output = ToRegister(ins->output());
// For Float32x4 and Int32x4.
masm.vmovmskps(input, output);
}
void
CodeGeneratorX86Shared::visitSimdAllTrue(LSimdAllTrue* ins)
{
@ -3354,20 +3344,19 @@ CodeGeneratorX86Shared::visitSimdSelect(LSimdSelect* ins)
masm.vmovaps(mask, temp);
MSimdSelect* mir = ins->mir();
if (mir->isElementWise()) {
if (AssemblerX86Shared::HasAVX()) {
masm.vblendvps(mask, onTrue, onFalse, output);
return;
}
// SSE4.1 has plain blendvps which can do this, but it is awkward
// to use because it requires the mask to be in xmm0.
// Propagate sign to all bits of mask vector, if necessary.
if (!mir->mask()->isSimdBinaryComp())
masm.packedRightShiftByScalar(Imm32(31), temp);
if (AssemblerX86Shared::HasAVX()) {
masm.vblendvps(mask, onTrue, onFalse, output);
return;
}
// SSE4.1 has plain blendvps which can do this, but it is awkward
// to use because it requires the mask to be in xmm0.
// Propagate sign to all bits of mask vector, if necessary.
if (!mir->mask()->isSimdBinaryComp())
masm.packedRightShiftByScalar(Imm32(31), temp);
masm.bitwiseAndX4(Operand(temp), output);
masm.bitwiseAndNotX4(Operand(onFalse), temp);
masm.bitwiseOrX4(Operand(temp), output);

View File

@ -267,7 +267,6 @@ class CodeGeneratorX86Shared : public CodeGeneratorShared
void visitSimdExtractElementF(LSimdExtractElementF* lir);
void visitSimdInsertElementI(LSimdInsertElementI* lir);
void visitSimdInsertElementF(LSimdInsertElementF* lir);
void visitSimdSignMaskX4(LSimdSignMaskX4* ins);
void visitSimdSwizzleI(LSimdSwizzleI* lir);
void visitSimdSwizzleF(LSimdSwizzleF* lir);
void visitSimdShuffle(LSimdShuffle* lir);

View File

@ -24,29 +24,6 @@ function testFloat32x4add() {
}
}
function testFloat32x4and() {
var andf = (function() {
var i = new Int32Array(3);
var f = new Float32Array(i.buffer);
return function(x, y) {
f[0] = x;
f[1] = y;
i[2] = i[0] & i[1];
return f[2];
};
})();
var vals = [
[[1, 2, 3, 4], [10, 20, 30, 40]],
[[1.51, 2.98, 3.65, 4.34], [10.29, 20.12, 30.79, 40.41]],
[[NaN, -0, Infinity, -Infinity], [NaN, -0, -Infinity, Infinity]]
];
for (var [v,w] of vals) {
testBinaryFunc(Float32x4(...v), Float32x4(...w), Float32x4.and, andf);
}
}
function testFloat32x4div() {
function divf(a, b) {
return Math.fround(Math.fround(a) / Math.fround(b));
@ -79,29 +56,6 @@ function testFloat32x4mul() {
}
}
function testFloat32x4or() {
var orf = (function() {
var i = new Int32Array(3);
var f = new Float32Array(i.buffer);
return function(x, y) {
f[0] = x;
f[1] = y;
i[2] = i[0] | i[1];
return f[2];
};
})();
var vals = [
[[1, 2, 3, 4], [10, 20, 30, 40]],
[[1.12, 2.39, 3.83, 4.57], [10.76, 20.41, 30.96, 40.23]],
[[NaN, -0, Infinity, -Infinity], [5, 5, -Infinity, Infinity]]
];
for (var [v,w] of vals) {
testBinaryFunc(Float32x4(...v), Float32x4(...w), Float32x4.or, orf);
}
}
function testFloat32x4sub() {
function subf(a, b) {
return Math.fround(Math.fround(a) - Math.fround(b));
@ -118,29 +72,6 @@ function testFloat32x4sub() {
}
}
function testFloat32x4xor() {
var xorf = (function() {
var i = new Int32Array(3);
var f = new Float32Array(i.buffer);
return function(x, y) {
f[0] = x;
f[1] = y;
i[2] = i[0] ^ i[1];
return f[2];
};
})();
var vals = [
[[1, 2, 3, 4], [10, 20, 30, 40]],
[[1.07, 2.62, 3.79, 4.15], [10.38, 20.47, 30.44, 40.16]],
[[NaN, -0, Infinity, -Infinity], [-0, Infinity, -Infinity, NaN]]
];
for (var [v,w] of vals) {
testBinaryFunc(Float32x4(...v), Float32x4(...w), Float32x4.xor, xorf);
}
}
var i8x16vals = [
[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
[10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160]],
@ -504,12 +435,9 @@ function testBool64x2xor() {
function test() {
testFloat32x4add();
testFloat32x4and();
testFloat32x4div();
testFloat32x4mul();
testFloat32x4or();
testFloat32x4sub();
testFloat32x4xor();
testInt8x16add();
testInt8x16and();

View File

@ -31,20 +31,6 @@ function getMask(i, maskLength) {
throw new Error("Invalid mask length.");
}
function getSelectBitsMask(i, maskLength) {
var args = [];
for (var j = 0; j < maskLength; j++)
args.push((!!((i >> j) & 1)) ? -1 : 0);
if (maskLength == 4)
return Int32x4(...args);
else if (maskLength == 8)
return Int16x8(...args);
else if (maskLength == 16)
return Int8x16(...args);
else
throw new Error("Invalid mask length.");
}
function select(mask, ifTrue, ifFalse) {
var m = simdToArray(mask);
var tv = simdToArray(ifTrue);
@ -71,65 +57,6 @@ function testSelect(type, inputs) {
}
}
function selectBits(type, mask, ifTrue, ifFalse) {
var tr = type.and(mask, ifTrue);
var fr = type.and(type.not(mask), ifFalse);
var orApplied = type.or(tr, fr);
return simdToArray(orApplied);
}
/**
* This tests type.selectBits on all boolean masks, as in select. For these,
* selectBits(mask, x, y) === select(mask, x, y)
*/
function testSelectBitsSimple(type, inputs) {
var x, y;
var maskLength = simdLengthType(type);
for (var i = 0; i < Math.pow(maskLength, 2); i++) {
var bitsMask = getSelectBitsMask(i, maskLength);
var mask = getMask(i, maskLength);
for ([x, y] of inputs){
assertEqVec(type.selectBits(bitsMask, x, y), selectBits(type, bitsMask, x, y));
assertEqVec(type.selectBits(bitsMask, x, y), simdToArray(type.select(mask, x, y)));
}
}
}
/**
* This tests type.selectBits on a few hand-defined masks. For these,
* selectBits(mask, x, y) !== select(mask, x, y)
*/
function testSelectBitsComplex(type, inputs) {
var masks8 = [
Int8x16(0x42, 42, INT8_MAX, INT8_MIN, INT8_MAX + 1, INT8_MIN - 1, 13, 37, -42, 125, -125, -1, 1, 0xA, 0xB, 0xC)
]
var masks16 = [
Int16x8(0x42, 42, INT16_MAX, INT16_MIN, INT16_MAX + 1, INT16_MIN - 1, 13, 37),
Int16x8(-42, 125, -125, -1, 1, 0xA, 0xB, 0xC)
]
var masks32 = [
Int32x4(1337, 0x1337, 0x42, 42),
Int32x4(0x00FF1CE, 0xBAADF00D, 0xDEADBEEF, 0xCAFED00D),
Int32x4(0xD15EA5E, 0xDEADC0DE, 0xFACEB00C, 0x4B1D4B1D)
];
var masks;
if (type == SIMD.Int8x16)
masks = masks8;
else if (type == SIMD.Int16x8)
masks = masks16;
else if (type == SIMD.Int32x4)
masks = masks32;
else
throw new Error("Unknown mask type.");
var x, y;
for (var mask of masks) {
for ([x, y] of inputs)
assertEqVec(type.selectBits(mask, x, y), selectBits(type, mask, x, y));
}
}
function test() {
var inputs = [
[Int8x16(0,4,9,16,25,36,49,64,81,121,-4,-9,-16,-25,-36,-49), Int8x16(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)],
@ -138,8 +65,6 @@ function test() {
];
testSelect(Int8x16, inputs);
testSelectBitsSimple(Int8x16, inputs);
testSelectBitsComplex(Int8x16, inputs);
inputs = [
[Int16x8(0,4,9,16,25,36,49,64), Int16x8(1,2,3,4,5,6,7,8)],
@ -148,8 +73,6 @@ function test() {
];
testSelect(Int16x8, inputs);
testSelectBitsSimple(Int16x8, inputs);
testSelectBitsComplex(Int16x8, inputs);
inputs = [
[Int32x4(0,4,9,16), Int32x4(1,2,3,4)],
@ -157,8 +80,6 @@ function test() {
];
testSelect(Int32x4, inputs);
testSelectBitsSimple(Int32x4, inputs);
testSelectBitsComplex(Int32x4, inputs);
inputs = [
[Float32x4(0.125,4.25,9.75,16.125), Float32x4(1.5,2.75,3.25,4.5)],

View File

@ -1,63 +0,0 @@
// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
var Float32x4 = SIMD.Float32x4;
var Int8x16 = SIMD.Int8x16;
var Int16x8 = SIMD.Int16x8;
var Int32x4 = SIMD.Int32x4;
function test_Float32x4() {
var v, w;
for ([v, w] of [[Float32x4(-1, 20, 30, 4), 0b0001],
[Float32x4(9.999, 2.1234, 30.4443, -4), 0b1000],
[Float32x4(0, -Infinity, +Infinity, -0), 0b1010]])
{
assertEq(v.signMask, w);
}
if (typeof reportCompare === "function")
reportCompare(true, true);
}
function test_Int8x16() {
var v, w;
for ([v, w] of [[Int8x16(-1, 20, 30, 4, -5, 6, 70, -80, 9, 100, -11, 12, 13, -14, 15, -16), 0b1010010010010001],
[Int8x16(10, 2, 30.2, -4, -5.2, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), 0b11000],
[Int8x16(0, INT8_MIN, INT8_MAX, -0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), 0b10]])
{
assertEq(v.signMask, w);
}
if (typeof reportCompare === "function")
reportCompare(true, true);
}
function test_Int16x8() {
var v, w;
for ([v, w] of [[Int16x8(-1, 20, 30, 4, -5, 6, 70, -80), 0b10010001],
[Int16x8(10, 2, 30.2, -4, -5.2, 6, 7, 8), 0b11000],
[Int16x8(0, INT16_MIN, INT16_MAX, -0, 5, 6, 7, 8), 0b10]])
{
assertEq(v.signMask, w);
}
if (typeof reportCompare === "function")
reportCompare(true, true);
}
function test_Int32x4() {
var v, w;
for ([v, w] of [[Int32x4(-1, 20, 30, 4), 0b0001],
[Int32x4(10, 2, 30.2, -4), 0b1000],
[Int32x4(0, 0x80000000, 0x7fffffff, -0), 0b0010]])
{
assertEq(v.signMask, w);
}
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test_Float32x4();
test_Int8x16();
test_Int16x8();
test_Int32x4();

View File

@ -89,28 +89,6 @@ function testFloat32x4sqrt() {
}
}
function testFloat32x4not() {
var notf = (function() {
var i = new Int32Array(1);
var f = new Float32Array(i.buffer);
return function(x) {
f[0] = x;
i[0] = ~i[0];
return f[0];
};
})();
var vals = [
[2, 13, -37, 4.2],
[2.897, 13.245, -37.781, 5.28],
[NaN, -0, Infinity, -Infinity]
];
for (var v of vals) {
assertEqX4(Float32x4.not(Float32x4(...v)), v.map(notf));
}
}
function testInt8x16neg() {
var vals = [
[[1, 2, 3, 4, 5, 6, 7, 8, -1, -2, -3, -4, -5, INT8_MAX, INT8_MIN, 0],
@ -322,7 +300,6 @@ function testBool64x2anyTrue() {
function test() {
testFloat32x4abs();
testFloat32x4neg();
testFloat32x4not();
testFloat32x4reciprocalApproximation();
testFloat32x4reciprocalSqrtApproximation();
testFloat32x4sqrt();

View File

@ -203,7 +203,6 @@
macro(sensitivity, sensitivity, "sensitivity") \
macro(set, set, "set") \
macro(shape, shape, "shape") \
macro(signMask, signMask, "signMask") \
macro(size, size, "size") \
macro(source, source, "source") \
macro(stack, stack, "stack") \
@ -254,11 +253,7 @@
macro(watch, watch, "watch") \
macro(WeakSet_add, WeakSet_add, "WeakSet_add") \
macro(writable, writable, "writable") \
macro(w, w, "w") \
macro(x, x, "x") \
macro(y, y, "y") \
macro(yield, yield, "yield") \
macro(z, z, "z") \
macro(raw, raw, "raw") \
/* Type names must be contiguous and ordered; see js::TypeName. */ \
macro(undefined, undefined, "undefined") \