mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
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:
parent
1b4833cacd
commit
f07361dc96
@ -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");
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ enum AsmJSSimdType
|
||||
enum AsmJSSimdOperation
|
||||
{
|
||||
#define ASMJSSIMDOPERATION(op) AsmJSSimdOperation_##op,
|
||||
FORALL_SIMD_OP(ASMJSSIMDOPERATION)
|
||||
FORALL_SIMD_ASMJS_OP(ASMJSSIMDOPERATION)
|
||||
#undef ASMJSSIMDOPERATION
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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();
|
@ -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);
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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;'
|
||||
|
@ -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));
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -21,7 +21,6 @@ namespace jit {
|
||||
_(SimdReinterpretCast) \
|
||||
_(SimdExtractElement) \
|
||||
_(SimdInsertElement) \
|
||||
_(SimdSignMask) \
|
||||
_(SimdSwizzle) \
|
||||
_(SimdGeneralShuffle) \
|
||||
_(SimdShuffle) \
|
||||
|
@ -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"); }
|
||||
|
@ -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"); }
|
||||
|
@ -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"); }
|
||||
|
@ -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>
|
||||
{
|
||||
|
@ -30,7 +30,6 @@
|
||||
_(SimdExtractElementF) \
|
||||
_(SimdInsertElementI) \
|
||||
_(SimdInsertElementF) \
|
||||
_(SimdSignMaskX4) \
|
||||
_(SimdGeneralShuffleI) \
|
||||
_(SimdGeneralShuffleF) \
|
||||
_(SimdSwizzleI) \
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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)],
|
||||
|
@ -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();
|
@ -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();
|
||||
|
@ -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") \
|
||||
|
Loading…
Reference in New Issue
Block a user