Bug 1160971 - Part 1: SIMD bool vector implementation for the interpreter. r=bbouvier

Also add an ENABLE_SIMD compilation flag that enables SIMD support in the
nightly build only. Previously, SIMD and BINARYDATA used the same flag.

Include a Bool64x2 type to go with the existing Float64x2 type. Neither are in
the current spec.
This commit is contained in:
Sajjad Taheri 2015-12-22 14:17:12 -08:00
parent cf83fb4d5d
commit 567ca4ca9a
17 changed files with 687 additions and 56 deletions

View File

@ -382,6 +382,7 @@ ValidateSimdOperation(JSContext* cx, AsmJSModule::Global& global, HandleValue gl
FOREACH_INT32X4_SIMD_OP(SET_NATIVE_INT32X4)
FOREACH_COMMONX4_SIMD_OP(SET_NATIVE_INT32X4)
FOREACH_FLOAT32X4_SIMD_OP(FALLTHROUGH)
FOREACH_BOOL_SIMD_OP(FALLTHROUGH)
MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("shouldn't have been validated in the first "
"place");
}
@ -391,6 +392,7 @@ ValidateSimdOperation(JSContext* cx, AsmJSModule::Global& global, HandleValue gl
FOREACH_FLOAT32X4_SIMD_OP(SET_NATIVE_FLOAT32X4)
FOREACH_COMMONX4_SIMD_OP(SET_NATIVE_FLOAT32X4)
FOREACH_INT32X4_SIMD_OP(FALLTHROUGH)
FOREACH_BOOL_SIMD_OP(FALLTHROUGH)
MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("shouldn't have been validated in the first "
"place");
}

View File

@ -2567,6 +2567,8 @@ IsSimdValidOperationType(AsmJSSimdType type, AsmJSSimdOperation op)
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
}
return false;
@ -4928,6 +4930,10 @@ CheckSimdOperationCall(FunctionValidator& f, ParseNode* call, const ModuleValida
case AsmJSSimdOperation_splat:
return CheckSimdSplat(f, call, opType, type);
case AsmJSSimdOperation_allTrue:
case AsmJSSimdOperation_anyTrue:
MOZ_CRASH("unreachable and nyi"); // TODO bug 1160971
}
MOZ_CRASH("unexpected simd operation in CheckSimdOperationCall");
}

View File

@ -66,6 +66,10 @@ template bool js::IsVectorObject<Int16x8>(HandleValue v);
template bool js::IsVectorObject<Int32x4>(HandleValue v);
template bool js::IsVectorObject<Float32x4>(HandleValue v);
template bool js::IsVectorObject<Float64x2>(HandleValue v);
template bool js::IsVectorObject<Bool8x16>(HandleValue v);
template bool js::IsVectorObject<Bool16x8>(HandleValue v);
template bool js::IsVectorObject<Bool32x4>(HandleValue v);
template bool js::IsVectorObject<Bool64x2>(HandleValue v);
static inline bool
ErrorBadArgs(JSContext* cx)
@ -231,7 +235,38 @@ class Float64x2Defn {
static const JSFunctionSpec TypedObjectMethods[];
static const JSFunctionSpec Methods[];
};
class Bool8x16Defn {
public:
static const SimdTypeDescr::Type type = SimdTypeDescr::Bool8x16;
static const JSFunctionSpec TypeDescriptorMethods[];
static const JSFunctionSpec TypedObjectMethods[];
static const JSFunctionSpec Methods[];
static constexpr JSPropertySpec* TypedObjectProperties = nullptr;
};
class Bool16x8Defn {
public:
static const SimdTypeDescr::Type type = SimdTypeDescr::Bool16x8;
static const JSFunctionSpec TypeDescriptorMethods[];
static const JSFunctionSpec TypedObjectMethods[];
static const JSFunctionSpec Methods[];
static constexpr JSPropertySpec* TypedObjectProperties = nullptr;
};
class Bool32x4Defn {
public:
static const SimdTypeDescr::Type type = SimdTypeDescr::Bool32x4;
static const JSFunctionSpec TypeDescriptorMethods[];
static const JSFunctionSpec TypedObjectMethods[];
static const JSFunctionSpec Methods[];
static constexpr JSPropertySpec* TypedObjectProperties = nullptr;
};
class Bool64x2Defn {
public:
static const SimdTypeDescr::Type type = SimdTypeDescr::Bool64x2;
static const JSFunctionSpec TypeDescriptorMethods[];
static const JSFunctionSpec TypedObjectMethods[];
static const JSFunctionSpec Methods[];
static constexpr JSPropertySpec* TypedObjectProperties = nullptr;
};
} // namespace
const JSFunctionSpec Float32x4Defn::TypeDescriptorMethods[] = {
@ -359,6 +394,86 @@ const JSFunctionSpec Int32x4Defn::Methods[] = {
JS_FS_END
};
const JSFunctionSpec Bool8x16Defn::TypeDescriptorMethods[] = {
JS_SELF_HOSTED_FN("toSource", "DescrToSource", 0, 0),
JS_SELF_HOSTED_FN("array", "ArrayShorthand", 1, 0),
JS_SELF_HOSTED_FN("equivalent", "TypeDescrEquivalent", 1, 0),
JS_FS_END,
};
const JSFunctionSpec Bool8x16Defn::TypedObjectMethods[] = {
JS_SELF_HOSTED_FN("toSource", "SimdToSource", 0, 0),
JS_FS_END
};
const JSFunctionSpec Bool8x16Defn::Methods[] = {
#define SIMD_BOOL8X16_FUNCTION_ITEM(Name, Func, Operands) \
JS_FN(#Name, js::simd_bool8x16_##Name, Operands, 0),
BOOL8X16_FUNCTION_LIST(SIMD_BOOL8X16_FUNCTION_ITEM)
#undef SIMD_BOOL8X16_FUNCTION_ITEM
JS_FS_END
};
const JSFunctionSpec Bool16x8Defn::TypeDescriptorMethods[] = {
JS_SELF_HOSTED_FN("toSource", "DescrToSource", 0, 0),
JS_SELF_HOSTED_FN("array", "ArrayShorthand", 1, 0),
JS_SELF_HOSTED_FN("equivalent", "TypeDescrEquivalent", 1, 0),
JS_FS_END,
};
const JSFunctionSpec Bool16x8Defn::TypedObjectMethods[] = {
JS_SELF_HOSTED_FN("toSource", "SimdToSource", 0, 0),
JS_FS_END
};
const JSFunctionSpec Bool16x8Defn::Methods[] = {
#define SIMD_BOOL16X8_FUNCTION_ITEM(Name, Func, Operands) \
JS_FN(#Name, js::simd_bool16x8_##Name, Operands, 0),
BOOL16X8_FUNCTION_LIST(SIMD_BOOL16X8_FUNCTION_ITEM)
#undef SIMD_BOOL16X8_FUNCTION_ITEM
JS_FS_END
};
const JSFunctionSpec Bool32x4Defn::TypeDescriptorMethods[] = {
JS_SELF_HOSTED_FN("toSource", "DescrToSource", 0, 0),
JS_SELF_HOSTED_FN("array", "ArrayShorthand", 1, 0),
JS_SELF_HOSTED_FN("equivalent", "TypeDescrEquivalent", 1, 0),
JS_FS_END,
};
const JSFunctionSpec Bool32x4Defn::TypedObjectMethods[] = {
JS_SELF_HOSTED_FN("toSource", "SimdToSource", 0, 0),
JS_FS_END
};
const JSFunctionSpec Bool32x4Defn::Methods[] = {
#define SIMD_BOOL32X4_FUNCTION_ITEM(Name, Func, Operands) \
JS_FN(#Name, js::simd_bool32x4_##Name, Operands, 0),
BOOL32X4_FUNCTION_LIST(SIMD_BOOL32X4_FUNCTION_ITEM)
#undef SIMD_BOOL32X4_FUNCTION_ITEM
JS_FS_END
};
const JSFunctionSpec Bool64x2Defn::TypeDescriptorMethods[] = {
JS_SELF_HOSTED_FN("toSource", "DescrToSource", 0, 0),
JS_SELF_HOSTED_FN("array", "ArrayShorthand", 1, 0),
JS_SELF_HOSTED_FN("equivalent", "TypeDescrEquivalent", 1, 0),
JS_FS_END,
};
const JSFunctionSpec Bool64x2Defn::TypedObjectMethods[] = {
JS_SELF_HOSTED_FN("toSource", "SimdToSource", 0, 0),
JS_FS_END
};
const JSFunctionSpec Bool64x2Defn::Methods[] = {
#define SIMD_BOOL64X2_FUNCTION_ITEM(Name, Func, Operands) \
JS_FN(#Name, js::simd_bool64x2_##Name, Operands, 0),
BOOL64X2_FUNCTION_LIST(SIMD_BOOL64X2_FUNCTION_ITEM)
#undef SIMD_BOOL64x2_FUNCTION_ITEM
JS_FS_END
};
template<typename T>
static JSObject*
CreateAndBindSimdClass(JSContext* cx, Handle<GlobalObject*> global, HandleObject globalSimdObject,
@ -456,6 +571,10 @@ SimdTypeDescr::call(JSContext* cx, unsigned argc, Value* vp)
case SimdTypeDescr::Int32x4: return FillLanes< ::Int32x4>(cx, result, args);
case SimdTypeDescr::Float32x4: return FillLanes< ::Float32x4>(cx, result, args);
case SimdTypeDescr::Float64x2: return FillLanes< ::Float64x2>(cx, result, args);
case SimdTypeDescr::Bool8x16: return FillLanes< ::Bool8x16>(cx, result, args);
case SimdTypeDescr::Bool16x8: return FillLanes< ::Bool16x8>(cx, result, args);
case SimdTypeDescr::Bool32x4: return FillLanes< ::Bool32x4>(cx, result, args);
case SimdTypeDescr::Bool64x2: return FillLanes< ::Bool64x2>(cx, result, args);
}
MOZ_CRASH("unexpected SIMD descriptor");
@ -523,21 +642,41 @@ js::InitSIMDClass(JSContext* cx, HandleObject obj)
if (!i16x8)
return nullptr;
RootedObject f32x4(cx);
f32x4 = CreateAndBindSimdClass<Float32x4Defn>(cx, global, globalSimdObject, cx->names().float32x4);
if (!f32x4)
return nullptr;
RootedObject i32x4(cx);
i32x4 = CreateAndBindSimdClass<Int32x4Defn>(cx, global, globalSimdObject, cx->names().int32x4);
if (!i32x4)
return nullptr;
RootedObject f32x4(cx);
f32x4 = CreateAndBindSimdClass<Float32x4Defn>(cx, global, globalSimdObject, cx->names().float32x4);
if (!f32x4)
return nullptr;
RootedObject f64x2(cx);
f64x2 = CreateAndBindSimdClass<Float64x2Defn>(cx, global, globalSimdObject, cx->names().float64x2);
if (!f64x2)
return nullptr;
RootedObject b8x16(cx);
b8x16 = CreateAndBindSimdClass<Bool8x16Defn>(cx, global, globalSimdObject, cx->names().bool8x16);
if (!b8x16)
return nullptr;
RootedObject b16x8(cx);
b16x8 = CreateAndBindSimdClass<Bool16x8Defn>(cx, global, globalSimdObject, cx->names().bool16x8);
if (!b16x8)
return nullptr;
RootedObject b32x4(cx);
b32x4 = CreateAndBindSimdClass<Bool32x4Defn>(cx, global, globalSimdObject, cx->names().bool32x4);
if (!b32x4)
return nullptr;
RootedObject b64x2(cx);
b64x2 = CreateAndBindSimdClass<Bool64x2Defn>(cx, global, globalSimdObject, cx->names().bool64x2);
if (!b64x2)
return nullptr;
return globalSimdObject;
}
@ -559,11 +698,15 @@ js::CreateSimd(JSContext* cx, const typename V::Elem* data)
return result;
}
template JSObject* js::CreateSimd<Float32x4>(JSContext* cx, const Float32x4::Elem* data);
template JSObject* js::CreateSimd<Float64x2>(JSContext* cx, const Float64x2::Elem* data);
template JSObject* js::CreateSimd<Int8x16>(JSContext* cx, const Int8x16::Elem* data);
template JSObject* js::CreateSimd<Int16x8>(JSContext* cx, const Int16x8::Elem* data);
template JSObject* js::CreateSimd<Int32x4>(JSContext* cx, const Int32x4::Elem* data);
template JSObject* js::CreateSimd<Float32x4>(JSContext* cx, const Float32x4::Elem* data);
template JSObject* js::CreateSimd<Float64x2>(JSContext* cx, const Float64x2::Elem* data);
template JSObject* js::CreateSimd<Bool8x16>(JSContext* cx, const Bool8x16::Elem* data);
template JSObject* js::CreateSimd<Bool16x8>(JSContext* cx, const Bool16x8::Elem* data);
template JSObject* js::CreateSimd<Bool32x4>(JSContext* cx, const Bool32x4::Elem* data);
template JSObject* js::CreateSimd<Bool64x2>(JSContext* cx, const Bool64x2::Elem* data);
namespace js {
// Unary SIMD operators
@ -584,6 +727,10 @@ struct Not {
static T apply(T x) { return ~x; }
};
template<typename T>
struct LogicalNot {
static T apply(T x) { return !x; }
};
template<typename T>
struct RecApprox {
static T apply(T x) { return 1 / x; }
};
@ -779,6 +926,44 @@ ExtractLane(JSContext* cx, unsigned argc, Value* vp)
return true;
}
template<typename V>
static bool
AllTrue(JSContext* cx, unsigned argc, Value* vp)
{
typedef typename V::Elem Elem;
CallArgs args = CallArgsFromVp(argc, vp);
if (args.length() < 1 || !IsVectorObject<V>(args[0]))
return ErrorBadArgs(cx);
Elem* vec = TypedObjectMemory<Elem*>(args[0]);
bool allTrue = true;
for (unsigned i = 0; allTrue && i < V::lanes; i++)
allTrue = vec[i];
args.rval().setBoolean(allTrue);
return true;
}
template<typename V>
static bool
AnyTrue(JSContext* cx, unsigned argc, Value* vp)
{
typedef typename V::Elem Elem;
CallArgs args = CallArgsFromVp(argc, vp);
if (args.length() < 1 || !IsVectorObject<V>(args[0]))
return ErrorBadArgs(cx);
Elem* vec = TypedObjectMemory<Elem*>(args[0]);
bool anyTrue = false;
for (unsigned i = 0; !anyTrue && i < V::lanes; i++)
anyTrue = vec[i];
args.rval().setBoolean(anyTrue);
return true;
}
template<typename V>
static bool
ReplaceLane(JSContext* cx, unsigned argc, Value* vp)
@ -1106,7 +1291,7 @@ Select(JSContext* cx, unsigned argc, Value* vp)
Elem result[V::lanes];
for (unsigned i = 0; i < V::lanes; i++)
result[i] = mask[i] < 0 ? tv[i] : fv[i];
result[i] = mask[i] ? tv[i] : fv[i];
return StoreResult<V>(cx, args, result);
}
@ -1242,3 +1427,39 @@ js::simd_int32x4_##Name(JSContext* cx, unsigned argc, Value* vp) \
}
INT32X4_FUNCTION_LIST(DEFINE_SIMD_INT32X4_FUNCTION)
#undef DEFINE_SIMD_INT32X4_FUNCTION
#define DEFINE_SIMD_BOOL8X16_FUNCTION(Name, Func, Operands) \
bool \
js::simd_bool8x16_##Name(JSContext* cx, unsigned argc, Value* vp) \
{ \
return Func(cx, argc, vp); \
}
BOOL8X16_FUNCTION_LIST(DEFINE_SIMD_BOOL8X16_FUNCTION)
#undef DEFINE_SIMD_BOOL8X16_FUNCTION
#define DEFINE_SIMD_BOOL16X8_FUNCTION(Name, Func, Operands) \
bool \
js::simd_bool16x8_##Name(JSContext* cx, unsigned argc, Value* vp) \
{ \
return Func(cx, argc, vp); \
}
BOOL16X8_FUNCTION_LIST(DEFINE_SIMD_BOOL16X8_FUNCTION)
#undef DEFINE_SIMD_BOOL16X8_FUNCTION
#define DEFINE_SIMD_BOOL32X4_FUNCTION(Name, Func, Operands) \
bool \
js::simd_bool32x4_##Name(JSContext* cx, unsigned argc, Value* vp) \
{ \
return Func(cx, argc, vp); \
}
BOOL32X4_FUNCTION_LIST(DEFINE_SIMD_BOOL32X4_FUNCTION)
#undef DEFINE_SIMD_BOOL32X4_FUNCTION
#define DEFINE_SIMD_BOOL64X2_FUNCTION(Name, Func, Operands) \
bool \
js::simd_bool64x2_##Name(JSContext* cx, unsigned argc, Value* vp) \
{ \
return Func(cx, argc, vp); \
}
BOOL64X2_FUNCTION_LIST(DEFINE_SIMD_BOOL64X2_FUNCTION)
#undef DEFINE_SIMD_BOOL64X2_FUNCTION

View File

@ -17,9 +17,93 @@
/*
* JS SIMD functions.
* Spec matching polyfill:
* https://github.com/johnmccutchan/ecmascript_simd/blob/master/src/ecmascript_simd.js
* https://github.com/tc39/ecmascript_simd/blob/master/src/ecmascript_simd.js
*/
#define BOOL8X16_UNARY_FUNCTION_LIST(V) \
V(not, (UnaryFunc<Bool8x16, LogicalNot, Bool8x16>), 1) \
V(check, (UnaryFunc<Bool8x16, Identity, Bool8x16>), 1) \
V(splat, (FuncSplat<Bool8x16>), 1) \
V(allTrue, (AllTrue<Bool8x16>), 1) \
V(anyTrue, (AnyTrue<Bool8x16>), 1)
#define BOOL8X16_BINARY_FUNCTION_LIST(V) \
V(extractLane, (ExtractLane<Bool8x16>), 2) \
V(and, (BinaryFunc<Bool8x16, And, Bool8x16>), 2) \
V(or, (BinaryFunc<Bool8x16, Or, Bool8x16>), 2) \
V(xor, (BinaryFunc<Bool8x16, Xor, Bool8x16>), 2) \
#define BOOL8X16_TERNARY_FUNCTION_LIST(V) \
V(replaceLane, (ReplaceLane<Bool8x16>), 3)
#define BOOL8X16_FUNCTION_LIST(V) \
BOOL8X16_UNARY_FUNCTION_LIST(V) \
BOOL8X16_BINARY_FUNCTION_LIST(V) \
BOOL8X16_TERNARY_FUNCTION_LIST(V)
#define BOOL16X8_UNARY_FUNCTION_LIST(V) \
V(not, (UnaryFunc<Bool16x8, LogicalNot, Bool16x8>), 1) \
V(check, (UnaryFunc<Bool16x8, Identity, Bool16x8>), 1) \
V(splat, (FuncSplat<Bool16x8>), 1) \
V(allTrue, (AllTrue<Bool16x8>), 1) \
V(anyTrue, (AnyTrue<Bool16x8>), 1)
#define BOOL16X8_BINARY_FUNCTION_LIST(V) \
V(extractLane, (ExtractLane<Bool16x8>), 2) \
V(and, (BinaryFunc<Bool16x8, And, Bool16x8>), 2) \
V(or, (BinaryFunc<Bool16x8, Or, Bool16x8>), 2) \
V(xor, (BinaryFunc<Bool16x8, Xor, Bool16x8>), 2) \
#define BOOL16X8_TERNARY_FUNCTION_LIST(V) \
V(replaceLane, (ReplaceLane<Bool16x8>), 3)
#define BOOL16X8_FUNCTION_LIST(V) \
BOOL16X8_UNARY_FUNCTION_LIST(V) \
BOOL16X8_BINARY_FUNCTION_LIST(V) \
BOOL16X8_TERNARY_FUNCTION_LIST(V)
#define BOOL32X4_UNARY_FUNCTION_LIST(V) \
V(not, (UnaryFunc<Bool32x4, LogicalNot, Bool32x4>), 1) \
V(check, (UnaryFunc<Bool32x4, Identity, Bool32x4>), 1) \
V(splat, (FuncSplat<Bool32x4>), 1) \
V(allTrue, (AllTrue<Bool32x4>), 1) \
V(anyTrue, (AnyTrue<Bool32x4>), 1)
#define BOOL32X4_BINARY_FUNCTION_LIST(V) \
V(extractLane, (ExtractLane<Bool32x4>), 2) \
V(and, (BinaryFunc<Bool32x4, And, Bool32x4>), 2) \
V(or, (BinaryFunc<Bool32x4, Or, Bool32x4>), 2) \
V(xor, (BinaryFunc<Bool32x4, Xor, Bool32x4>), 2) \
#define BOOL32X4_TERNARY_FUNCTION_LIST(V) \
V(replaceLane, (ReplaceLane<Bool32x4>), 3)
#define BOOL32X4_FUNCTION_LIST(V) \
BOOL32X4_UNARY_FUNCTION_LIST(V) \
BOOL32X4_BINARY_FUNCTION_LIST(V) \
BOOL32X4_TERNARY_FUNCTION_LIST(V)
#define BOOL64X2_UNARY_FUNCTION_LIST(V) \
V(not, (UnaryFunc<Bool64x2, LogicalNot, Bool64x2>), 1) \
V(check, (UnaryFunc<Bool64x2, Identity, Bool64x2>), 1) \
V(splat, (FuncSplat<Bool64x2>), 1) \
V(allTrue, (AllTrue<Bool64x2>), 1) \
V(anyTrue, (AnyTrue<Bool64x2>), 1)
#define BOOL64X2_BINARY_FUNCTION_LIST(V) \
V(extractLane, (ExtractLane<Bool64x2>), 2) \
V(and, (BinaryFunc<Bool64x2, And, Bool64x2>), 2) \
V(or, (BinaryFunc<Bool64x2, Or, Bool64x2>), 2) \
V(xor, (BinaryFunc<Bool64x2, Xor, Bool64x2>), 2) \
#define BOOL64X2_TERNARY_FUNCTION_LIST(V) \
V(replaceLane, (ReplaceLane<Bool64x2>), 3)
#define BOOL64X2_FUNCTION_LIST(V) \
BOOL64X2_UNARY_FUNCTION_LIST(V) \
BOOL64X2_BINARY_FUNCTION_LIST(V) \
BOOL64X2_TERNARY_FUNCTION_LIST(V)
#define FLOAT32X4_UNARY_FUNCTION_LIST(V) \
V(abs, (UnaryFunc<Float32x4, Abs, Float32x4>), 1) \
V(check, (UnaryFunc<Float32x4, Identity, Float32x4>), 1) \
@ -40,12 +124,12 @@
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, Int32x4>), 2) \
V(equal, (CompareFunc<Float32x4, Equal, Bool32x4>), 2) \
V(extractLane, (ExtractLane<Float32x4>), 2) \
V(greaterThan, (CompareFunc<Float32x4, GreaterThan, Int32x4>), 2) \
V(greaterThanOrEqual, (CompareFunc<Float32x4, GreaterThanOrEqual, Int32x4>), 2) \
V(lessThan, (CompareFunc<Float32x4, LessThan, Int32x4>), 2) \
V(lessThanOrEqual, (CompareFunc<Float32x4, LessThanOrEqual, Int32x4>), 2) \
V(greaterThan, (CompareFunc<Float32x4, GreaterThan, Bool32x4>), 2) \
V(greaterThanOrEqual, (CompareFunc<Float32x4, GreaterThanOrEqual, Bool32x4>), 2) \
V(lessThan, (CompareFunc<Float32x4, LessThan, Bool32x4>), 2) \
V(lessThanOrEqual, (CompareFunc<Float32x4, LessThanOrEqual, Bool32x4>), 2) \
V(load, (Load<Float32x4, 4>), 2) \
V(load3, (Load<Float32x4, 3>), 2) \
V(load2, (Load<Float32x4, 2>), 2) \
@ -55,14 +139,14 @@
V(min, (BinaryFunc<Float32x4, Minimum, Float32x4>), 2) \
V(minNum, (BinaryFunc<Float32x4, MinNum, Float32x4>), 2) \
V(mul, (BinaryFunc<Float32x4, Mul, Float32x4>), 2) \
V(notEqual, (CompareFunc<Float32x4, NotEqual, Int32x4>), 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)
#define FLOAT32X4_TERNARY_FUNCTION_LIST(V) \
V(replaceLane, (ReplaceLane<Float32x4>), 3) \
V(select, (Select<Float32x4, Int32x4>), 3) \
V(select, (Select<Float32x4, Bool32x4>), 3) \
V(store, (Store<Float32x4, 4>), 3) \
V(store3, (Store<Float32x4, 3>), 3) \
V(store2, (Store<Float32x4, 2>), 3) \
@ -96,12 +180,12 @@
#define FLOAT64X2_BINARY_FUNCTION_LIST(V) \
V(add, (BinaryFunc<Float64x2, Add, Float64x2>), 2) \
V(div, (BinaryFunc<Float64x2, Div, Float64x2>), 2) \
V(equal, (CompareFunc<Float64x2, Equal, Int32x4>), 2) \
V(equal, (CompareFunc<Float64x2, Equal, Bool64x2>), 2) \
V(extractLane, (ExtractLane<Float64x2>), 2) \
V(greaterThan, (CompareFunc<Float64x2, GreaterThan, Int32x4>), 2) \
V(greaterThanOrEqual, (CompareFunc<Float64x2, GreaterThanOrEqual, Int32x4>), 2) \
V(lessThan, (CompareFunc<Float64x2, LessThan, Int32x4>), 2) \
V(lessThanOrEqual, (CompareFunc<Float64x2, LessThanOrEqual, Int32x4>), 2) \
V(greaterThan, (CompareFunc<Float64x2, GreaterThan, Bool64x2>), 2) \
V(greaterThanOrEqual, (CompareFunc<Float64x2, GreaterThanOrEqual, Bool64x2>), 2) \
V(lessThan, (CompareFunc<Float64x2, LessThan, Bool64x2>), 2) \
V(lessThanOrEqual, (CompareFunc<Float64x2, LessThanOrEqual, Bool64x2>), 2) \
V(load, (Load<Float64x2, 2>), 2) \
V(load1, (Load<Float64x2, 1>), 2) \
V(max, (BinaryFunc<Float64x2, Maximum, Float64x2>), 2) \
@ -109,12 +193,12 @@
V(min, (BinaryFunc<Float64x2, Minimum, Float64x2>), 2) \
V(minNum, (BinaryFunc<Float64x2, MinNum, Float64x2>), 2) \
V(mul, (BinaryFunc<Float64x2, Mul, Float64x2>), 2) \
V(notEqual, (CompareFunc<Float64x2, NotEqual, Int32x4>), 2) \
V(notEqual, (CompareFunc<Float64x2, NotEqual, Bool64x2>), 2) \
V(sub, (BinaryFunc<Float64x2, Sub, Float64x2>), 2)
#define FLOAT64X2_TERNARY_FUNCTION_LIST(V) \
V(replaceLane, (ReplaceLane<Float64x2>), 3) \
V(select, (Select<Float64x2, Int32x4>), 3) \
V(select, (Select<Float64x2, Bool64x2>), 3) \
V(store, (Store<Float64x2, 2>), 3) \
V(store1, (Store<Float64x2, 1>), 3)
@ -141,15 +225,15 @@
#define INT8X16_BINARY_FUNCTION_LIST(V) \
V(add, (BinaryFunc<Int8x16, Add, Int8x16>), 2) \
V(and, (BinaryFunc<Int8x16, And, Int8x16>), 2) \
V(equal, (CompareFunc<Int8x16, Equal, Int8x16>), 2) \
V(equal, (CompareFunc<Int8x16, Equal, Bool8x16>), 2) \
V(extractLane, (ExtractLane<Int8x16>), 2) \
V(greaterThan, (CompareFunc<Int8x16, GreaterThan, Int8x16>), 2) \
V(greaterThanOrEqual, (CompareFunc<Int8x16, GreaterThanOrEqual, Int8x16>), 2) \
V(lessThan, (CompareFunc<Int8x16, LessThan, Int8x16>), 2) \
V(lessThanOrEqual, (CompareFunc<Int8x16, LessThanOrEqual, Int8x16>), 2) \
V(greaterThan, (CompareFunc<Int8x16, GreaterThan, Bool8x16>), 2) \
V(greaterThanOrEqual, (CompareFunc<Int8x16, GreaterThanOrEqual, Bool8x16>), 2) \
V(lessThan, (CompareFunc<Int8x16, LessThan, Bool8x16>), 2) \
V(lessThanOrEqual, (CompareFunc<Int8x16, LessThanOrEqual, Bool8x16>), 2) \
V(load, (Load<Int8x16, 16>), 2) \
V(mul, (BinaryFunc<Int8x16, Mul, Int8x16>), 2) \
V(notEqual, (CompareFunc<Int8x16, NotEqual, Int8x16>), 2) \
V(notEqual, (CompareFunc<Int8x16, NotEqual, Bool8x16>), 2) \
V(or, (BinaryFunc<Int8x16, Or, Int8x16>), 2) \
V(sub, (BinaryFunc<Int8x16, Sub, Int8x16>), 2) \
V(shiftLeftByScalar, (BinaryScalar<Int8x16, ShiftLeft>), 2) \
@ -159,7 +243,7 @@
#define INT8X16_TERNARY_FUNCTION_LIST(V) \
V(replaceLane, (ReplaceLane<Int8x16>), 3) \
V(select, (Select<Int8x16, Int8x16>), 3) \
V(select, (Select<Int8x16, Bool8x16>), 3) \
V(selectBits, (SelectBits<Int8x16, Int8x16>), 3) \
V(store, (Store<Int8x16, 16>), 3)
@ -186,15 +270,15 @@
#define INT16X8_BINARY_FUNCTION_LIST(V) \
V(add, (BinaryFunc<Int16x8, Add, Int16x8>), 2) \
V(and, (BinaryFunc<Int16x8, And, Int16x8>), 2) \
V(equal, (CompareFunc<Int16x8, Equal, Int16x8>), 2) \
V(equal, (CompareFunc<Int16x8, Equal, Bool16x8>), 2) \
V(extractLane, (ExtractLane<Int16x8>), 2) \
V(greaterThan, (CompareFunc<Int16x8, GreaterThan, Int16x8>), 2) \
V(greaterThanOrEqual, (CompareFunc<Int16x8, GreaterThanOrEqual, Int16x8>), 2) \
V(lessThan, (CompareFunc<Int16x8, LessThan, Int16x8>), 2) \
V(lessThanOrEqual, (CompareFunc<Int16x8, LessThanOrEqual, Int16x8>), 2) \
V(greaterThan, (CompareFunc<Int16x8, GreaterThan, Bool16x8>), 2) \
V(greaterThanOrEqual, (CompareFunc<Int16x8, GreaterThanOrEqual, Bool16x8>), 2) \
V(lessThan, (CompareFunc<Int16x8, LessThan, Bool16x8>), 2) \
V(lessThanOrEqual, (CompareFunc<Int16x8, LessThanOrEqual, Bool16x8>), 2) \
V(load, (Load<Int16x8, 8>), 2) \
V(mul, (BinaryFunc<Int16x8, Mul, Int16x8>), 2) \
V(notEqual, (CompareFunc<Int16x8, NotEqual, Int16x8>), 2) \
V(notEqual, (CompareFunc<Int16x8, NotEqual, Bool16x8>), 2) \
V(or, (BinaryFunc<Int16x8, Or, Int16x8>), 2) \
V(sub, (BinaryFunc<Int16x8, Sub, Int16x8>), 2) \
V(shiftLeftByScalar, (BinaryScalar<Int16x8, ShiftLeft>), 2) \
@ -204,7 +288,7 @@
#define INT16X8_TERNARY_FUNCTION_LIST(V) \
V(replaceLane, (ReplaceLane<Int16x8>), 3) \
V(select, (Select<Int16x8, Int16x8>), 3) \
V(select, (Select<Int16x8, Bool16x8>), 3) \
V(selectBits, (SelectBits<Int16x8, Int16x8>), 3) \
V(store, (Store<Int16x8, 8>), 3)
@ -233,18 +317,18 @@
#define INT32X4_BINARY_FUNCTION_LIST(V) \
V(add, (BinaryFunc<Int32x4, Add, Int32x4>), 2) \
V(and, (BinaryFunc<Int32x4, And, Int32x4>), 2) \
V(equal, (CompareFunc<Int32x4, Equal, Int32x4>), 2) \
V(equal, (CompareFunc<Int32x4, Equal, Bool32x4>), 2) \
V(extractLane, (ExtractLane<Int32x4>), 2) \
V(greaterThan, (CompareFunc<Int32x4, GreaterThan, Int32x4>), 2) \
V(greaterThanOrEqual, (CompareFunc<Int32x4, GreaterThanOrEqual, Int32x4>), 2) \
V(lessThan, (CompareFunc<Int32x4, LessThan, Int32x4>), 2) \
V(lessThanOrEqual, (CompareFunc<Int32x4, LessThanOrEqual, Int32x4>), 2) \
V(greaterThan, (CompareFunc<Int32x4, GreaterThan, Bool32x4>), 2) \
V(greaterThanOrEqual, (CompareFunc<Int32x4, GreaterThanOrEqual, Bool32x4>), 2) \
V(lessThan, (CompareFunc<Int32x4, LessThan, Bool32x4>), 2) \
V(lessThanOrEqual, (CompareFunc<Int32x4, LessThanOrEqual, Bool32x4>), 2) \
V(load, (Load<Int32x4, 4>), 2) \
V(load3, (Load<Int32x4, 3>), 2) \
V(load2, (Load<Int32x4, 2>), 2) \
V(load1, (Load<Int32x4, 1>), 2) \
V(mul, (BinaryFunc<Int32x4, Mul, Int32x4>), 2) \
V(notEqual, (CompareFunc<Int32x4, NotEqual, Int32x4>), 2) \
V(notEqual, (CompareFunc<Int32x4, NotEqual, Bool32x4>), 2) \
V(or, (BinaryFunc<Int32x4, Or, Int32x4>), 2) \
V(sub, (BinaryFunc<Int32x4, Sub, Int32x4>), 2) \
V(shiftLeftByScalar, (BinaryScalar<Int32x4, ShiftLeft>), 2) \
@ -254,7 +338,7 @@
#define INT32X4_TERNARY_FUNCTION_LIST(V) \
V(replaceLane, (ReplaceLane<Int32x4>), 3) \
V(select, (Select<Int32x4, 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) \
@ -271,6 +355,9 @@
INT32X4_TERNARY_FUNCTION_LIST(V) \
INT32X4_SHUFFLE_FUNCTION_LIST(V)
#define FOREACH_BOOL_SIMD_OP(_) \
_(allTrue) \
_(anyTrue)
#define CONVERSION_INT32X4_SIMD_OP(_) \
_(fromFloat32x4) \
_(fromFloat32x4Bits)
@ -311,6 +398,13 @@
_(notEqual) \
_(greaterThan) \
_(greaterThanOrEqual)
#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(_) \
@ -338,6 +432,7 @@
#define FORALL_SIMD_OP(_) \
FOREACH_INT32X4_SIMD_OP(_) \
FOREACH_FLOAT32X4_SIMD_OP(_) \
FOREACH_BOOL_SIMD_OP(_) \
FOREACH_COMMONX4_SIMD_OP(_)
namespace js {
@ -430,6 +525,58 @@ struct Int32x4 {
}
};
struct Bool8x16 {
typedef int8_t Elem;
static const unsigned lanes = 16;
static const SimdTypeDescr::Type type = SimdTypeDescr::Bool8x16;
static bool Cast(JSContext* cx, JS::HandleValue v, Elem* out) {
*out = ToBoolean(v) ? -1 : 0;
return true;
}
static Value ToValue(Elem value) {
return BooleanValue(value);
}
};
struct Bool16x8 {
typedef int16_t Elem;
static const unsigned lanes = 8;
static const SimdTypeDescr::Type type = SimdTypeDescr::Bool16x8;
static bool Cast(JSContext* cx, JS::HandleValue v, Elem* out) {
*out = ToBoolean(v) ? -1 : 0;
return true;
}
static Value ToValue(Elem value) {
return BooleanValue(value);
}
};
struct Bool32x4 {
typedef int32_t Elem;
static const unsigned lanes = 4;
static const SimdTypeDescr::Type type = SimdTypeDescr::Bool32x4;
static bool Cast(JSContext* cx, JS::HandleValue v, Elem* out) {
*out = ToBoolean(v) ? -1 : 0;
return true;
}
static Value ToValue(Elem value) {
return BooleanValue(value);
}
};
struct Bool64x2 {
typedef int64_t Elem;
static const unsigned lanes = 2;
static const SimdTypeDescr::Type type = SimdTypeDescr::Bool64x2;
static bool Cast(JSContext* cx, JS::HandleValue v, Elem* out) {
*out = ToBoolean(v) ? -1 : 0;
return true;
}
static Value ToValue(Elem value) {
return BooleanValue(value);
}
};
template<typename V>
JSObject* CreateSimd(JSContext* cx, const typename V::Elem* data);
@ -469,6 +616,30 @@ simd_int32x4_##Name(JSContext* cx, unsigned argc, Value* vp);
INT32X4_FUNCTION_LIST(DECLARE_SIMD_INT32x4_FUNCTION)
#undef DECLARE_SIMD_INT32x4_FUNCTION
#define DECLARE_SIMD_BOOL8X16_FUNCTION(Name, Func, Operands) \
extern bool \
simd_bool8x16_##Name(JSContext* cx, unsigned argc, Value* vp);
BOOL8X16_FUNCTION_LIST(DECLARE_SIMD_BOOL8X16_FUNCTION)
#undef DECLARE_SIMD_BOOL8X16_FUNCTION
#define DECLARE_SIMD_BOOL16X8_FUNCTION(Name, Func, Operands) \
extern bool \
simd_bool16x8_##Name(JSContext* cx, unsigned argc, Value* vp);
BOOL16X8_FUNCTION_LIST(DECLARE_SIMD_BOOL16X8_FUNCTION)
#undef DECLARE_SIMD_BOOL16X8_FUNCTION
#define DECLARE_SIMD_BOOL32X4_FUNCTION(Name, Func, Operands) \
extern bool \
simd_bool32x4_##Name(JSContext* cx, unsigned argc, Value* vp);
BOOL32X4_FUNCTION_LIST(DECLARE_SIMD_BOOL32X4_FUNCTION)
#undef DECLARE_SIMD_BOOL32X4_FUNCTION
#define DECLARE_SIMD_BOOL64x2_FUNCTION(Name, Func, Operands) \
extern bool \
simd_bool64x2_##Name(JSContext* cx, unsigned argc, Value* vp);
BOOL64X2_FUNCTION_LIST(DECLARE_SIMD_BOOL64x2_FUNCTION)
#undef DECLARE_SIMD_BOOL64x2_FUNCTION
JSObject*
InitSIMDClass(JSContext* cx, HandleObject obj);

View File

@ -2624,7 +2624,7 @@ static bool
IsSimdAvailable(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
#ifdef JS_CODEGEN_NONE
#if defined(JS_CODEGEN_NONE) || !defined(ENABLE_SIMD)
bool available = false;
#else
bool available = cx->jitSupportsSimd();

View File

@ -422,6 +422,10 @@ SimdTypeDescr::size(Type t)
case SimdTypeDescr::Int32x4:
case SimdTypeDescr::Float32x4:
case SimdTypeDescr::Float64x2:
case SimdTypeDescr::Bool8x16:
case SimdTypeDescr::Bool16x8:
case SimdTypeDescr::Bool32x4:
case SimdTypeDescr::Bool64x2:
return 16;
}
MOZ_CRASH("unexpected SIMD type");
@ -2632,6 +2636,46 @@ js::GetInt32x4TypeDescr(JSContext* cx, unsigned argc, Value* vp)
return true;
}
bool
js::GetBool8x16TypeDescr(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
Rooted<GlobalObject*> global(cx, cx->global());
MOZ_ASSERT(global);
args.rval().setObject(*global->getOrCreateSimdTypeDescr<Bool8x16>(cx));
return true;
}
bool
js::GetBool16x8TypeDescr(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
Rooted<GlobalObject*> global(cx, cx->global());
MOZ_ASSERT(global);
args.rval().setObject(*global->getOrCreateSimdTypeDescr<Bool16x8>(cx));
return true;
}
bool
js::GetBool32x4TypeDescr(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
Rooted<GlobalObject*> global(cx, cx->global());
MOZ_ASSERT(global);
args.rval().setObject(*global->getOrCreateSimdTypeDescr<Bool32x4>(cx));
return true;
}
bool
js::GetBool64x2TypeDescr(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
Rooted<GlobalObject*> global(cx, cx->global());
MOZ_ASSERT(global);
args.rval().setObject(*global->getOrCreateSimdTypeDescr<Bool64x2>(cx));
return true;
}
#define JS_STORE_SCALAR_CLASS_IMPL(_constant, T, _name) \
bool \
js::StoreScalar##T::Func(JSContext*, unsigned argc, Value* vp) \

View File

@ -328,7 +328,7 @@ class ComplexTypeDescr : public TypeDescr
};
/*
* Type descriptors `int8x16`, `int16x8`, `int32x4`, `float32x4` and `float64x2`
* SIMD Type descriptors.
*/
class SimdTypeDescr : public ComplexTypeDescr
{
@ -339,7 +339,11 @@ class SimdTypeDescr : public ComplexTypeDescr
Int32x4 = JS_SIMDTYPEREPR_INT32X4,
Float32x4 = JS_SIMDTYPEREPR_FLOAT32X4,
Float64x2 = JS_SIMDTYPEREPR_FLOAT64X2,
LAST_TYPE = Float64x2
Bool8x16 = JS_SIMDTYPEREPR_BOOL8X16,
Bool16x8 = JS_SIMDTYPEREPR_BOOL16X8,
Bool32x4 = JS_SIMDTYPEREPR_BOOL32X4,
Bool64x2 = JS_SIMDTYPEREPR_BOOL64X2,
LAST_TYPE = Bool64x2
};
static const type::Kind Kind = type::Simd;
@ -844,6 +848,38 @@ bool GetFloat32x4TypeDescr(JSContext* cx, unsigned argc, Value* vp);
*/
bool GetFloat64x2TypeDescr(JSContext* cx, unsigned argc, Value* vp);
/*
* Usage: GetBool8x16TypeDescr()
*
* Returns the bool8x16 type object. SIMD pseudo-module must have
* been initialized for this to be safe.
*/
bool GetBool8x16TypeDescr(JSContext* cx, unsigned argc, Value* vp);
/*
* Usage: GetBool16x8TypeDescr()
*
* Returns the bool16x8 type object. SIMD pseudo-module must have
* been initialized for this to be safe.
*/
bool GetBool16x8TypeDescr(JSContext* cx, unsigned argc, Value* vp);
/*
* Usage: GetBool32x4TypeDescr()
*
* Returns the bool32x4 type object. SIMD pseudo-module must have
* been initialized for this to be safe.
*/
bool GetBool32x4TypeDescr(JSContext* cx, unsigned argc, Value* vp);
/*
* Usage: GetBool64x2TypeDescr()
*
* Returns the bool64x2 type object. SIMD pseudo-module must have
* been initialized for this to be safe.
*/
bool GetBool64x2TypeDescr(JSContext* cx, unsigned argc, Value* vp);
/*
* Usage: GetInt8x16TypeDescr()
*

View File

@ -194,6 +194,50 @@ function TypedObjectGetSimd(descr, typedObj, offset) {
var z = Load_int32(typedObj, offset + 8);
var w = Load_int32(typedObj, offset + 12);
return GetInt32x4TypeDescr()(x, y, z, w);
case JS_SIMDTYPEREPR_BOOL8X16:
var s0 = Load_int8(typedObj, offset + 0);
var s1 = Load_int8(typedObj, offset + 1);
var s2 = Load_int8(typedObj, offset + 2);
var s3 = Load_int8(typedObj, offset + 3);
var s4 = Load_int8(typedObj, offset + 4);
var s5 = Load_int8(typedObj, offset + 5);
var s6 = Load_int8(typedObj, offset + 6);
var s7 = Load_int8(typedObj, offset + 7);
var s8 = Load_int8(typedObj, offset + 8);
var s9 = Load_int8(typedObj, offset + 9);
var s10 = Load_int8(typedObj, offset + 10);
var s11 = Load_int8(typedObj, offset + 11);
var s12 = Load_int8(typedObj, offset + 12);
var s13 = Load_int8(typedObj, offset + 13);
var s14 = Load_int8(typedObj, offset + 14);
var s15 = Load_int8(typedObj, offset + 15);
return GetBool8x16TypeDescr()(s0, s1, s2, s3, s4, s5, s6, s7,
s8, s9, s10, s11, s12, s13, s14, s15);
case JS_SIMDTYPEREPR_BOOL16X8:
var s0 = Load_int16(typedObj, offset + 0);
var s1 = Load_int16(typedObj, offset + 2);
var s2 = Load_int16(typedObj, offset + 4);
var s3 = Load_int16(typedObj, offset + 6);
var s4 = Load_int16(typedObj, offset + 8);
var s5 = Load_int16(typedObj, offset + 10);
var s6 = Load_int16(typedObj, offset + 12);
var s7 = Load_int16(typedObj, offset + 14);
return GetBool16x8TypeDescr()(s0, s1, s2, s3, s4, s5, s6, s7);
case JS_SIMDTYPEREPR_BOOL32X4:
var x = Load_int32(typedObj, offset + 0);
var y = Load_int32(typedObj, offset + 4);
var z = Load_int32(typedObj, offset + 8);
var w = Load_int32(typedObj, offset + 12);
return GetBool32x4TypeDescr()(x, y, z, w);
case JS_SIMDTYPEREPR_BOOL64X2:
var x = Load_int32(typedObj, offset + 0);
var y = Load_int32(typedObj, offset + 8);
return GetBool64x2TypeDescr()(x, y);
}
assert(false, "Unhandled SIMD type: " + type);
@ -363,6 +407,7 @@ function TypedObjectSetSimd(descr, typedObj, offset, fromValue) {
Store_float64(typedObj, offset + 8, Load_float64(fromValue, 8));
break;
case JS_SIMDTYPEREPR_INT8X16:
case JS_SIMDTYPEREPR_BOOL8X16:
Store_int8(typedObj, offset + 0, Load_int8(fromValue, 0));
Store_int8(typedObj, offset + 1, Load_int8(fromValue, 1));
Store_int8(typedObj, offset + 2, Load_int8(fromValue, 2));
@ -381,6 +426,7 @@ function TypedObjectSetSimd(descr, typedObj, offset, fromValue) {
Store_int8(typedObj, offset + 15, Load_int8(fromValue, 15));
break;
case JS_SIMDTYPEREPR_INT16X8:
case JS_SIMDTYPEREPR_BOOL16X8:
Store_int16(typedObj, offset + 0, Load_int16(fromValue, 0));
Store_int16(typedObj, offset + 2, Load_int16(fromValue, 2));
Store_int16(typedObj, offset + 4, Load_int16(fromValue, 4));
@ -391,6 +437,8 @@ function TypedObjectSetSimd(descr, typedObj, offset, fromValue) {
Store_int16(typedObj, offset + 14, Load_int16(fromValue, 14));
break;
case JS_SIMDTYPEREPR_INT32X4:
case JS_SIMDTYPEREPR_BOOL32X4:
case JS_SIMDTYPEREPR_BOOL64X2:
Store_int32(typedObj, offset + 0, Load_int32(fromValue, 0));
Store_int32(typedObj, offset + 4, Load_int32(fromValue, 4));
Store_int32(typedObj, offset + 8, Load_int32(fromValue, 8));
@ -531,6 +579,14 @@ function SimdProtoString(type) {
return "Float32x4";
case JS_SIMDTYPEREPR_FLOAT64X2:
return "Float64x2";
case JS_SIMDTYPEREPR_BOOL8X16:
return "Bool8x16";
case JS_SIMDTYPEREPR_BOOL16X8:
return "Bool16x8";
case JS_SIMDTYPEREPR_BOOL32X4:
return "Bool32x4";
case JS_SIMDTYPEREPR_BOOL64X2:
return "Bool64x2";
}
assert(false, "Unhandled type constant");
@ -540,13 +596,17 @@ function SimdProtoString(type) {
function SimdTypeToLength(type) {
switch (type) {
case JS_SIMDTYPEREPR_INT8X16:
case JS_SIMDTYPEREPR_BOOL8X16:
return 16;
case JS_SIMDTYPEREPR_INT16X8:
case JS_SIMDTYPEREPR_BOOL16X8:
return 8;
case JS_SIMDTYPEREPR_INT32X4:
case JS_SIMDTYPEREPR_FLOAT32X4:
case JS_SIMDTYPEREPR_BOOL32X4:
return 4;
case JS_SIMDTYPEREPR_FLOAT64X2:
case JS_SIMDTYPEREPR_BOOL64X2:
return 2;
}
@ -614,6 +674,48 @@ function SimdToSource() {
var y = callFunction(std_SIMD_Float64x2_extractLane, null, this, 1);
return `SIMD.${protoString}(${x}, ${y})`;
}
case JS_SIMDTYPEREPR_BOOL8X16: {
var s1 = callFunction(std_SIMD_Bool8x16_extractLane, null, this, 0);
var s2 = callFunction(std_SIMD_Bool8x16_extractLane, null, this, 1);
var s3 = callFunction(std_SIMD_Bool8x16_extractLane, null, this, 2);
var s4 = callFunction(std_SIMD_Bool8x16_extractLane, null, this, 3);
var s5 = callFunction(std_SIMD_Bool8x16_extractLane, null, this, 4);
var s6 = callFunction(std_SIMD_Bool8x16_extractLane, null, this, 5);
var s7 = callFunction(std_SIMD_Bool8x16_extractLane, null, this, 6);
var s8 = callFunction(std_SIMD_Bool8x16_extractLane, null, this, 7);
var s9 = callFunction(std_SIMD_Bool8x16_extractLane, null, this, 8);
var s10 = callFunction(std_SIMD_Bool8x16_extractLane, null, this, 9);
var s11 = callFunction(std_SIMD_Bool8x16_extractLane, null, this, 10);
var s12 = callFunction(std_SIMD_Bool8x16_extractLane, null, this, 11);
var s13 = callFunction(std_SIMD_Bool8x16_extractLane, null, this, 12);
var s14 = callFunction(std_SIMD_Bool8x16_extractLane, null, this, 13);
var s15 = callFunction(std_SIMD_Bool8x16_extractLane, null, this, 14);
var s16 = callFunction(std_SIMD_Bool8x16_extractLane, null, this, 15);
return `SIMD.${protoString}(${s1}, ${s2}, ${s3}, ${s4}, ${s5}, ${s6}, ${s7}, ${s8}, ${s9}, ${s10}, ${s11}, ${s12}, ${s13}, ${s14}, ${s15}, ${s16})`;
}
case JS_SIMDTYPEREPR_BOOL16X8: {
var s1 = callFunction(std_SIMD_Bool16x8_extractLane, null, this, 0);
var s2 = callFunction(std_SIMD_Bool16x8_extractLane, null, this, 1);
var s3 = callFunction(std_SIMD_Bool16x8_extractLane, null, this, 2);
var s4 = callFunction(std_SIMD_Bool16x8_extractLane, null, this, 3);
var s5 = callFunction(std_SIMD_Bool16x8_extractLane, null, this, 4);
var s6 = callFunction(std_SIMD_Bool16x8_extractLane, null, this, 5);
var s7 = callFunction(std_SIMD_Bool16x8_extractLane, null, this, 6);
var s8 = callFunction(std_SIMD_Bool16x8_extractLane, null, this, 7);
return `SIMD.${protoString}(${s1}, ${s2}, ${s3}, ${s4}, ${s5}, ${s6}, ${s7}, ${s8})`;
}
case JS_SIMDTYPEREPR_BOOL32X4: {
var x = callFunction(std_SIMD_Bool32x4_extractLane, null, this, 0);
var y = callFunction(std_SIMD_Bool32x4_extractLane, null, this, 1);
var z = callFunction(std_SIMD_Bool32x4_extractLane, null, this, 2);
var w = callFunction(std_SIMD_Bool32x4_extractLane, null, this, 3);
return `SIMD.${protoString}(${x}, ${y}, ${z}, ${w})`;
}
case JS_SIMDTYPEREPR_BOOL64X2: {
var x = callFunction(std_SIMD_Bool64x2_extractLane, null, this, 0);
var y = callFunction(std_SIMD_Bool64x2_extractLane, null, this, 1);
return `SIMD.${protoString}(${x}, ${y})`;
}
}
assert(false, "unexpected SIMD kind");
return '?';

View File

@ -108,5 +108,9 @@
#define JS_SIMDTYPEREPR_INT32X4 2
#define JS_SIMDTYPEREPR_FLOAT32X4 3
#define JS_SIMDTYPEREPR_FLOAT64X2 4
#define JS_SIMDTYPEREPR_BOOL8X16 5
#define JS_SIMDTYPEREPR_BOOL16X8 6
#define JS_SIMDTYPEREPR_BOOL32X4 7
#define JS_SIMDTYPEREPR_BOOL64X2 8
#endif

View File

@ -11251,7 +11251,11 @@ IonBuilder::SimdTypeDescrToMIRType(SimdTypeDescr::Type type)
case SimdTypeDescr::Float32x4: return MIRType_Float32x4;
case SimdTypeDescr::Int8x16:
case SimdTypeDescr::Int16x8:
case SimdTypeDescr::Float64x2: return MIRType_Undefined;
case SimdTypeDescr::Float64x2:
case SimdTypeDescr::Bool8x16:
case SimdTypeDescr::Bool16x8:
case SimdTypeDescr::Bool32x4:
case SimdTypeDescr::Bool64x2: return MIRType_Undefined;
}
MOZ_CRASH("unimplemented MIR type for a SimdTypeDescr::Type");
}

View File

@ -3494,6 +3494,12 @@ SimdTypeToArrayElementType(SimdTypeDescr::Type type)
switch (type) {
case SimdTypeDescr::Float32x4: return Scalar::Float32x4;
case SimdTypeDescr::Int32x4: return Scalar::Int32x4;
// Bool vectors don't have load/store operations.
case SimdTypeDescr::Bool8x16:
case SimdTypeDescr::Bool16x8:
case SimdTypeDescr::Bool32x4:
case SimdTypeDescr::Bool64x2: break;
// Not yet implemented.
case SimdTypeDescr::Int8x16:
case SimdTypeDescr::Int16x8:
case SimdTypeDescr::Float64x2: break;

View File

@ -1358,6 +1358,18 @@ RSimdBox::recover(JSContext* cx, SnapshotIterator& iter) const
case SimdTypeDescr::Int16x8:
MOZ_CRASH("NYI, RSimdBox of Int16x8");
break;
case SimdTypeDescr::Bool8x16:
MOZ_CRASH("NYI, RSimdBox of Bool8x16");
break;
case SimdTypeDescr::Bool16x8:
MOZ_CRASH("NYI, RSimdBox of Bool16x8");
break;
case SimdTypeDescr::Bool32x4:
MOZ_CRASH("NYI, RSimdBox of Bool32x4");
break;
case SimdTypeDescr::Bool64x2:
MOZ_CRASH("NYI, RSimdBox of Bool64x2");
break;
}
if (!resultObject)

View File

@ -50,9 +50,11 @@
#include "builtin/MapObject.h"
#include "builtin/RegExp.h"
#include "builtin/SymbolObject.h"
#ifdef ENABLE_SIMD
# include "builtin/SIMD.h"
#endif
#ifdef ENABLE_BINARYDATA
#include "builtin/SIMD.h"
#include "builtin/TypedObject.h"
# include "builtin/TypedObject.h"
#endif
#include "frontend/BytecodeCompiler.h"
#include "frontend/FullParseHandler.h" // for JS_BufferIsCompileableUnit
@ -1040,8 +1042,10 @@ static const JSStdName builtin_property_names[] = {
#if JS_HAS_UNEVAL
{ EAGER_ATOM(uneval), JSProto_String },
#endif
#ifdef ENABLE_BINARYDATA
#ifdef ENABLE_SIMD
{ EAGER_ATOM(SIMD), JSProto_SIMD },
#endif
#ifdef ENABLE_BINARYDATA
{ EAGER_ATOM(TypedObject), JSProto_TypedObject },
#endif
#ifdef ENABLE_SHARED_ARRAY_BUFFER

View File

@ -49,6 +49,12 @@
#define IF_BDATA(real,imaginary) imaginary
#endif
#ifdef ENABLE_SIMD
# define IF_SIMD(real,imaginary) real
#else
# define IF_SIMD(real,imaginary) imaginary
#endif
#ifdef ENABLE_SHARED_ARRAY_BUFFER
#define IF_SAB(real,imaginary) real
#else
@ -97,7 +103,7 @@ IF_SAB(real,imaginary)(SharedArrayBuffer, 37, InitSharedArrayBufferCla
IF_INTL(real,imaginary) (Intl, 38, InitIntlClass, CLASP(Intl)) \
IF_BDATA(real,imaginary)(TypedObject, 39, InitTypedObjectModuleObject, OCLASP(TypedObjectModule)) \
real(Reflect, 40, InitReflect, nullptr) \
IF_BDATA(real,imaginary)(SIMD, 41, InitSIMDClass, OCLASP(SIMD)) \
IF_SIMD(real,imaginary)(SIMD, 41, InitSIMDClass, OCLASP(SIMD)) \
real(WeakSet, 42, InitWeakSetClass, OCLASP(WeakSet)) \
real(TypedArray, 43, InitViaClassSpec, &js::TypedArrayObject::sharedTypedArrayPrototypeClass) \
IF_SAB(real,imaginary)(Atomics, 44, InitAtomicsClass, OCLASP(Atomics)) \

View File

@ -614,6 +614,7 @@ if CONFIG['MOZ_ETW']:
if CONFIG['NIGHTLY_BUILD']:
DEFINES['ENABLE_BINARYDATA'] = True
DEFINES['ENABLE_SHARED_ARRAY_BUFFER'] = True
DEFINES['ENABLE_SIMD'] = True
DEFINES['EXPORT_JS_API'] = True

View File

@ -23,6 +23,10 @@
macro(ArrayValues, ArrayValues, "ArrayValues") \
macro(ArrayValuesAt, ArrayValuesAt, "ArrayValuesAt") \
macro(Async, Async, "Async") \
macro(bool8x16, bool8x16, "Bool8x16") \
macro(bool16x8, bool16x8, "Bool16x8") \
macro(bool32x4, bool32x4, "Bool32x4") \
macro(bool64x2, bool64x2, "Bool64x2") \
macro(breakdown, breakdown, "breakdown") \
macro(buffer, buffer, "buffer") \
macro(builder, builder, "builder") \

View File

@ -1458,6 +1458,10 @@ static const JSFunctionSpec intrinsic_functions[] = {
JS_INLINABLE_FN("std_SIMD_Int32x4_extractLane", simd_int32x4_extractLane, 2,0, SimdInt32x4),
JS_INLINABLE_FN("std_SIMD_Float32x4_extractLane", simd_float32x4_extractLane,2,0, SimdFloat32x4),
JS_FN("std_SIMD_Float64x2_extractLane", simd_float64x2_extractLane, 2,0),
JS_FN("std_SIMD_Bool8x16_extractLane", simd_bool8x16_extractLane, 2,0),
JS_FN("std_SIMD_Bool16x8_extractLane", simd_bool16x8_extractLane, 2,0),
JS_FN("std_SIMD_Bool32x4_extractLane", simd_bool32x4_extractLane, 2,0),
JS_FN("std_SIMD_Bool64x2_extractLane", simd_bool64x2_extractLane, 2,0),
// Helper funtions after this point.
JS_INLINABLE_FN("ToObject", intrinsic_ToObject, 1,0, IntrinsicToObject),
@ -1598,6 +1602,10 @@ static const JSFunctionSpec intrinsic_functions[] = {
JS_FN("GetInt8x16TypeDescr", js::GetInt8x16TypeDescr, 0, 0),
JS_FN("GetInt16x8TypeDescr", js::GetInt16x8TypeDescr, 0, 0),
JS_FN("GetInt32x4TypeDescr", js::GetInt32x4TypeDescr, 0, 0),
JS_FN("GetBool8x16TypeDescr", js::GetBool8x16TypeDescr, 0, 0),
JS_FN("GetBool16x8TypeDescr", js::GetBool16x8TypeDescr, 0, 0),
JS_FN("GetBool32x4TypeDescr", js::GetBool32x4TypeDescr, 0, 0),
JS_FN("GetBool64x2TypeDescr", js::GetBool64x2TypeDescr, 0, 0),
JS_INLINABLE_FN("ObjectIsTypeDescr" , js::ObjectIsTypeDescr, 1, 0,
IntrinsicObjectIsTypeDescr),