Bug 1124291 - SIMD (interpreter): Implemented int8x16 and int16x8 on a CLOSED TREE. r=bbouvier

This commit is contained in:
ProgramFOX 2015-07-07 15:31:44 +02:00
parent 25191a7cd9
commit 6bb9a5d050
13 changed files with 564 additions and 102 deletions

View File

@ -669,7 +669,7 @@ struct JSClass {
// the beginning of every global object's slots for use by the
// application.
#define JSCLASS_GLOBAL_APPLICATION_SLOTS 5
#define JSCLASS_GLOBAL_SLOT_COUNT (JSCLASS_GLOBAL_APPLICATION_SLOTS + JSProto_LIMIT * 3 + 30)
#define JSCLASS_GLOBAL_SLOT_COUNT (JSCLASS_GLOBAL_APPLICATION_SLOTS + JSProto_LIMIT * 3 + 32)
#define JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(n) \
(JSCLASS_IS_GLOBAL | JSCLASS_HAS_RESERVED_SLOTS(JSCLASS_GLOBAL_SLOT_COUNT + (n)))
#define JSCLASS_GLOBAL_FLAGS \

View File

@ -34,7 +34,8 @@ using mozilla::FloorLog2;
///////////////////////////////////////////////////////////////////////////
// SIMD
static const char* laneNames[] = {"lane 0", "lane 1", "lane 2", "lane3"};
static const char* laneNames[] = {"lane 0", "lane 1", "lane 2", "lane 3", "lane 4", "lane 5", "lane 6", "lane 7",
"lane 8", "lane 9", "lane 10", "lane 11", "lane 12", "lane 13", "lane 14", "lane 15"};
static bool
CheckVectorObject(HandleValue v, SimdTypeDescr::Type expectedType)
@ -60,6 +61,8 @@ js::IsVectorObject(HandleValue v)
return CheckVectorObject(v, V::type);
}
template bool js::IsVectorObject<Int8x16>(HandleValue v);
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);
@ -145,7 +148,27 @@ static bool type##Lane##lane(JSContext* cx, unsigned argc, Value* vp) { \
FOUR_LANES_ACCESSOR(Int32x4);
FOUR_LANES_ACCESSOR(Float32x4);
#define EIGHT_LANES_ACCESSOR(type) \
FOUR_LANES_ACCESSOR(type) \
LANE_ACCESSOR(type, 4) \
LANE_ACCESSOR(type, 5) \
LANE_ACCESSOR(type, 6) \
LANE_ACCESSOR(type, 7)
EIGHT_LANES_ACCESSOR(Int16x8);
EIGHT_LANES_ACCESSOR(Int8x16);
LANE_ACCESSOR(Int8x16, 8);
LANE_ACCESSOR(Int8x16, 9);
LANE_ACCESSOR(Int8x16, 10);
LANE_ACCESSOR(Int8x16, 11);
LANE_ACCESSOR(Int8x16, 12);
LANE_ACCESSOR(Int8x16, 13);
LANE_ACCESSOR(Int8x16, 14);
LANE_ACCESSOR(Int8x16, 15);
#undef FOUR_LANES_ACCESSOR
#undef EIGHT_LANES_ACCESSOR
LANE_ACCESSOR(Float64x2, 0);
LANE_ACCESSOR(Float64x2, 1);
@ -194,6 +217,8 @@ static bool type##SignMask(JSContext* cx, unsigned argc, Value* vp) { \
}
SIGN_MASK(Float32x4);
SIGN_MASK(Float64x2);
SIGN_MASK(Int8x16);
SIGN_MASK(Int16x8);
SIGN_MASK(Int32x4);
#undef SIGN_MASK
@ -215,6 +240,22 @@ const Class SimdTypeDescr::class_ = {
namespace {
// These classes just exist to group together various properties and so on.
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[];
};
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[];
};
class Int32x4Defn {
public:
static const SimdTypeDescr::Type type = SimdTypeDescr::Int32x4;
@ -298,6 +339,80 @@ const JSFunctionSpec Float64x2Defn::Methods[] = {
JS_FS_END
};
const JSFunctionSpec Int8x16Defn::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 JSPropertySpec Int8x16Defn::TypedObjectProperties[] = {
JS_PSG("s0", Int8x16Lane0, JSPROP_PERMANENT),
JS_PSG("s1", Int8x16Lane1, JSPROP_PERMANENT),
JS_PSG("s2", Int8x16Lane2, JSPROP_PERMANENT),
JS_PSG("s3", Int8x16Lane3, JSPROP_PERMANENT),
JS_PSG("s4", Int8x16Lane4, JSPROP_PERMANENT),
JS_PSG("s5", Int8x16Lane5, JSPROP_PERMANENT),
JS_PSG("s6", Int8x16Lane6, JSPROP_PERMANENT),
JS_PSG("s7", Int8x16Lane7, JSPROP_PERMANENT),
JS_PSG("s8", Int8x16Lane8, JSPROP_PERMANENT),
JS_PSG("s9", Int8x16Lane9, JSPROP_PERMANENT),
JS_PSG("s10", Int8x16Lane10, JSPROP_PERMANENT),
JS_PSG("s11", Int8x16Lane11, JSPROP_PERMANENT),
JS_PSG("s12", Int8x16Lane12, JSPROP_PERMANENT),
JS_PSG("s13", Int8x16Lane13, JSPROP_PERMANENT),
JS_PSG("s14", Int8x16Lane14, JSPROP_PERMANENT),
JS_PSG("s15", Int8x16Lane15, JSPROP_PERMANENT),
JS_PSG("signMask", Int8x16SignMask, JSPROP_PERMANENT),
JS_PS_END
};
const JSFunctionSpec Int8x16Defn::TypedObjectMethods[] = {
JS_SELF_HOSTED_FN("toSource", "SimdToSource", 0, 0),
JS_FS_END
};
const JSFunctionSpec Int8x16Defn::Methods[] = {
#define SIMD_INT8X16_FUNCTION_ITEM(Name, Func, Operands) \
JS_FN(#Name, js::simd_int8x16_##Name, Operands, 0),
INT8X16_FUNCTION_LIST(SIMD_INT8X16_FUNCTION_ITEM)
#undef SIMD_INT8X16_FUNCTION_ITEM
JS_FS_END
};
const JSFunctionSpec Int16x8Defn::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 JSPropertySpec Int16x8Defn::TypedObjectProperties[] = {
JS_PSG("s0", Int16x8Lane0, JSPROP_PERMANENT),
JS_PSG("s1", Int16x8Lane1, JSPROP_PERMANENT),
JS_PSG("s2", Int16x8Lane2, JSPROP_PERMANENT),
JS_PSG("s3", Int16x8Lane3, JSPROP_PERMANENT),
JS_PSG("s4", Int16x8Lane4, JSPROP_PERMANENT),
JS_PSG("s5", Int16x8Lane5, JSPROP_PERMANENT),
JS_PSG("s6", Int16x8Lane6, JSPROP_PERMANENT),
JS_PSG("s7", Int16x8Lane7, JSPROP_PERMANENT),
JS_PSG("signMask", Int16x8SignMask, JSPROP_PERMANENT),
JS_PS_END
};
const JSFunctionSpec Int16x8Defn::TypedObjectMethods[] = {
JS_SELF_HOSTED_FN("toSource", "SimdToSource", 0, 0),
JS_FS_END
};
const JSFunctionSpec Int16x8Defn::Methods[] = {
#define SIMD_INT16X8_FUNCTION_ITEM(Name, Func, Operands) \
JS_FN(#Name, js::simd_int16x8_##Name, Operands, 0),
INT16X8_FUNCTION_LIST(SIMD_INT16X8_FUNCTION_ITEM)
#undef SIMD_INT16X8_FUNCTION_ITEM
JS_FS_END
};
const JSFunctionSpec Int32x4Defn::TypeDescriptorMethods[] = {
JS_SELF_HOSTED_FN("toSource", "DescrToSource", 0, 0),
JS_SELF_HOSTED_FN("array", "ArrayShorthand", 1, 0),
@ -418,6 +533,8 @@ SimdTypeDescr::call(JSContext* cx, unsigned argc, Value* vp)
return false;
switch (descr->type()) {
case SimdTypeDescr::Int8x16: return FillLanes< ::Int8x16>(cx, result, args);
case SimdTypeDescr::Int16x8: return FillLanes< ::Int16x8>(cx, result, args);
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);
@ -455,6 +572,18 @@ SIMDObject::initClass(JSContext* cx, Handle<GlobalObject*> global)
if (!SIMD)
return nullptr;
RootedObject i8x16(cx);
i8x16 = CreateAndBindSimdClass<Int8x16Defn>(cx, global, SIMD, cx->names().int8x16);
if (!i8x16)
return nullptr;
global->setInt8x16TypeDescr(*i8x16);
RootedObject i16x8(cx);
i16x8 = CreateAndBindSimdClass<Int16x8Defn>(cx, global, SIMD, cx->names().int16x8);
if (!i16x8)
return nullptr;
global->setInt16x8TypeDescr(*i16x8);
RootedObject f32x4(cx);
f32x4 = CreateAndBindSimdClass<Float32x4Defn>(cx, global, SIMD, cx->names().float32x4);
if (!f32x4)
@ -512,6 +641,8 @@ js::CreateSimd(JSContext* cx, const typename V::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<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);
namespace js {
@ -580,27 +711,27 @@ struct MaxNum {
};
template<typename T>
struct LessThan {
static int32_t apply(T l, T r) { return l < r ? 0xFFFFFFFF : 0x0; }
static bool apply(T l, T r) { return l < r; }
};
template<typename T>
struct LessThanOrEqual {
static int32_t apply(T l, T r) { return l <= r ? 0xFFFFFFFF : 0x0; }
static bool apply(T l, T r) { return l <= r; }
};
template<typename T>
struct GreaterThan {
static int32_t apply(T l, T r) { return l > r ? 0xFFFFFFFF : 0x0; }
static bool apply(T l, T r) { return l > r; }
};
template<typename T>
struct GreaterThanOrEqual {
static int32_t apply(T l, T r) { return l >= r ? 0xFFFFFFFF : 0x0; }
static bool apply(T l, T r) { return l >= r; }
};
template<typename T>
struct Equal {
static int32_t apply(T l, T r) { return l == r ? 0xFFFFFFFF : 0x0; }
static bool apply(T l, T r) { return l == r; }
};
template<typename T>
struct NotEqual {
static int32_t apply(T l, T r) { return l != r ? 0xFFFFFFFF : 0x0; }
static bool apply(T l, T r) { return l != r; }
};
template<typename T>
struct Xor {
@ -617,19 +748,23 @@ struct Or {
// For the following three operators, if the value v we're trying to shift is
// such that v << bits can't fit in the int32 range, then we have undefined
// behavior, according to C++11 [expr.shift]p2.
template<typename T>
struct ShiftLeft {
static int32_t apply(int32_t v, int32_t bits) {
return uint32_t(bits) >= 32 ? 0 : v << bits;
static T apply(T v, int32_t bits) {
return uint32_t(bits) >= sizeof(T) * 8 ? 0 : v << bits;
}
};
template<typename T>
struct ShiftRightArithmetic {
static int32_t apply(int32_t v, int32_t bits) {
return v >> (uint32_t(bits) >= 32 ? 31 : bits);
static T apply(T v, int32_t bits) {
uint32_t maxBits = sizeof(T) * 8;
return v >> (uint32_t(bits) >= maxBits ? maxBits - 1 : bits);
}
};
template<typename T>
struct ShiftRightLogical {
static int32_t apply(int32_t v, int32_t bits) {
return uint32_t(bits) >= 32 ? 0 : uint32_t(v) >> bits;
static T apply(T v, int32_t bits) {
return uint32_t(bits) >= sizeof(T) * 8 ? 0 : uint32_t(v) >> bits;
}
};
}
@ -792,47 +927,50 @@ Shuffle(JSContext* cx, unsigned argc, Value* vp)
return StoreResult<V>(cx, args, result);
}
template<typename Op>
template<typename V, template<typename T> class Op>
static bool
Int32x4BinaryScalar(JSContext* cx, unsigned argc, Value* vp)
BinaryScalar(JSContext* cx, unsigned argc, Value* vp)
{
typedef typename V::Elem Elem;
CallArgs args = CallArgsFromVp(argc, vp);
if (args.length() != 2)
return ErrorBadArgs(cx);
int32_t result[4];
if (!IsVectorObject<Int32x4>(args[0]))
Elem result[V::lanes];
if (!IsVectorObject<V>(args[0]))
return ErrorBadArgs(cx);
int32_t* val = TypedObjectMemory<int32_t*>(args[0]);
Elem* val = TypedObjectMemory<Elem*>(args[0]);
int32_t bits;
if (!ToInt32(cx, args[1], &bits))
return false;
for (unsigned i = 0; i < 4; i++)
result[i] = Op::apply(val[i], bits);
return StoreResult<Int32x4>(cx, args, result);
for (unsigned i = 0; i < V::lanes; i++)
result[i] = Op<Elem>::apply(val[i], bits);
return StoreResult<V>(cx, args, result);
}
template<typename In, template<typename C> class Op>
template<typename In, template<typename C> class Op, typename Out>
static bool
CompareFunc(JSContext* cx, unsigned argc, Value* vp)
{
typedef typename In::Elem InElem;
typedef typename Out::Elem OutElem;
CallArgs args = CallArgsFromVp(argc, vp);
if (args.length() != 2 || !IsVectorObject<In>(args[0]) || !IsVectorObject<In>(args[1]))
return ErrorBadArgs(cx);
int32_t result[Int32x4::lanes];
OutElem result[Out::lanes];
InElem* left = TypedObjectMemory<InElem*>(args[0]);
InElem* right = TypedObjectMemory<InElem*>(args[1]);
for (unsigned i = 0; i < Int32x4::lanes; i++) {
unsigned j = (i * In::lanes) / Int32x4::lanes;
result[i] = Op<InElem>::apply(left[j], right[j]);
for (unsigned i = 0; i < Out::lanes; i++) {
unsigned j = (i * In::lanes) / Out::lanes;
result[i] = Op<InElem>::apply(left[j], right[j]) ? -1 : 0;
}
return StoreResult<Int32x4>(cx, args, result);
return StoreResult<Out>(cx, args, result);
}
// This struct defines whether we should throw during a conversion attempt,
@ -957,15 +1095,18 @@ FuncSplat(JSContext* cx, unsigned argc, Value* vp)
return StoreResult<Vret>(cx, args, result);
}
template<typename V>
static bool
Int32x4Bool(JSContext* cx, unsigned argc, Value* vp)
Bool(JSContext* cx, unsigned argc, Value* vp)
{
typedef typename V::Elem Elem;
CallArgs args = CallArgsFromVp(argc, vp);
int32_t result[Int32x4::lanes];
for (unsigned i = 0; i < Int32x4::lanes; i++)
Elem result[V::lanes];
for (unsigned i = 0; i < V::lanes; i++)
result[i] = ToBoolean(args.get(i)) ? -1 : 0;
return StoreResult<Int32x4>(cx, args, result);
return StoreResult<V>(cx, args, result);
}
template<typename In>
@ -993,53 +1134,55 @@ Clamp(JSContext* cx, unsigned argc, Value* vp)
return StoreResult<In>(cx, args, result);
}
template<typename V>
template<typename V, typename MaskType>
static bool
BitSelect(JSContext* cx, unsigned argc, Value* vp)
{
typedef typename V::Elem Elem;
typedef typename MaskType::Elem MaskTypeElem;
CallArgs args = CallArgsFromVp(argc, vp);
if (args.length() != 3 || !IsVectorObject<Int32x4>(args[0]) ||
if (args.length() != 3 || !IsVectorObject<MaskType>(args[0]) ||
!IsVectorObject<V>(args[1]) || !IsVectorObject<V>(args[2]))
{
return ErrorBadArgs(cx);
}
int32_t* val = TypedObjectMemory<int32_t*>(args[0]);
int32_t* tv = TypedObjectMemory<int32_t*>(args[1]);
int32_t* fv = TypedObjectMemory<int32_t*>(args[2]);
MaskTypeElem* val = TypedObjectMemory<MaskTypeElem*>(args[0]);
MaskTypeElem* tv = TypedObjectMemory<MaskTypeElem*>(args[1]);
MaskTypeElem* fv = TypedObjectMemory<MaskTypeElem*>(args[2]);
int32_t tr[Int32x4::lanes];
for (unsigned i = 0; i < Int32x4::lanes; i++)
tr[i] = And<int32_t>::apply(val[i], tv[i]);
MaskTypeElem tr[MaskType::lanes];
for (unsigned i = 0; i < MaskType::lanes; i++)
tr[i] = And<MaskTypeElem>::apply(val[i], tv[i]);
int32_t fr[Int32x4::lanes];
for (unsigned i = 0; i < Int32x4::lanes; i++)
fr[i] = And<int32_t>::apply(Not<int32_t>::apply(val[i]), fv[i]);
MaskTypeElem fr[MaskType::lanes];
for (unsigned i = 0; i < MaskType::lanes; i++)
fr[i] = And<MaskTypeElem>::apply(Not<MaskTypeElem>::apply(val[i]), fv[i]);
int32_t orInt[Int32x4::lanes];
for (unsigned i = 0; i < Int32x4::lanes; i++)
orInt[i] = Or<int32_t>::apply(tr[i], fr[i]);
MaskTypeElem orInt[MaskType::lanes];
for (unsigned i = 0; i < MaskType::lanes; i++)
orInt[i] = Or<MaskTypeElem>::apply(tr[i], fr[i]);
Elem* result = reinterpret_cast<Elem*>(orInt);
return StoreResult<V>(cx, args, result);
}
template<typename V>
template<typename V, typename MaskType>
static bool
Select(JSContext* cx, unsigned argc, Value* vp)
{
typedef typename V::Elem Elem;
typedef typename MaskType::Elem MaskTypeElem;
CallArgs args = CallArgsFromVp(argc, vp);
if (args.length() != 3 || !IsVectorObject<Int32x4>(args[0]) ||
if (args.length() != 3 || !IsVectorObject<MaskType>(args[0]) ||
!IsVectorObject<V>(args[1]) || !IsVectorObject<V>(args[2]))
{
return ErrorBadArgs(cx);
}
int32_t* mask = TypedObjectMemory<int32_t*>(args[0]);
MaskTypeElem* mask = TypedObjectMemory<MaskTypeElem*>(args[0]);
Elem* tv = TypedObjectMemory<Elem*>(args[1]);
Elem* fv = TypedObjectMemory<Elem*>(args[2]);
@ -1153,6 +1296,24 @@ js::simd_float64x2_##Name(JSContext* cx, unsigned argc, Value* vp) \
FLOAT64X2_FUNCTION_LIST(DEFINE_SIMD_FLOAT64X2_FUNCTION)
#undef DEFINE_SIMD_FLOAT64X2_FUNCTION
#define DEFINE_SIMD_INT8X16_FUNCTION(Name, Func, Operands) \
bool \
js::simd_int8x16_##Name(JSContext* cx, unsigned argc, Value* vp) \
{ \
return Func(cx, argc, vp); \
}
INT8X16_FUNCTION_LIST(DEFINE_SIMD_INT8X16_FUNCTION)
#undef DEFINE_SIMD_INT8X16_FUNCTION
#define DEFINE_SIMD_INT16X8_FUNCTION(Name, Func, Operands) \
bool \
js::simd_int16x8_##Name(JSContext* cx, unsigned argc, Value* vp) \
{ \
return Func(cx, argc, vp); \
}
INT16X8_FUNCTION_LIST(DEFINE_SIMD_INT16X8_FUNCTION)
#undef DEFINE_SIMD_INT16X8_FUNCTION
#define DEFINE_SIMD_INT32X4_FUNCTION(Name, Func, Operands) \
bool \
js::simd_int32x4_##Name(JSContext* cx, unsigned argc, Value* vp) \

View File

@ -25,6 +25,8 @@
V(check, (UnaryFunc<Float32x4, Identity, Float32x4>), 1) \
V(fromFloat64x2, (FuncConvert<Float64x2, Float32x4> ), 1) \
V(fromFloat64x2Bits, (FuncConvertBits<Float64x2, Float32x4>), 1) \
V(fromInt8x16Bits, (FuncConvertBits<Int8x16, Float32x4>), 1) \
V(fromInt16x8Bits, (FuncConvertBits<Int16x8, Float32x4>), 1) \
V(fromInt32x4, (FuncConvert<Int32x4, Float32x4> ), 1) \
V(fromInt32x4Bits, (FuncConvertBits<Int32x4, Float32x4>), 1) \
V(neg, (UnaryFunc<Float32x4, Neg, Float32x4>), 1) \
@ -38,11 +40,11 @@
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>), 2) \
V(greaterThan, (CompareFunc<Float32x4, GreaterThan>), 2) \
V(greaterThanOrEqual, (CompareFunc<Float32x4, GreaterThanOrEqual>), 2) \
V(lessThan, (CompareFunc<Float32x4, LessThan>), 2) \
V(lessThanOrEqual, (CompareFunc<Float32x4, LessThanOrEqual>), 2) \
V(equal, (CompareFunc<Float32x4, Equal, Int32x4>), 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(load, (Load<Float32x4, 4>), 2) \
V(load3, (Load<Float32x4, 3>), 2) \
V(load2, (Load<Float32x4, 2>), 2) \
@ -52,24 +54,24 @@
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>), 2) \
V(notEqual, (CompareFunc<Float32x4, NotEqual, Int32x4>), 2) \
V(or, (CoercedBinaryFunc<Float32x4, Int32x4, Or, Float32x4>), 2) \
V(store, (Store<Float32x4, 4>), 3) \
V(store3, (Store<Float32x4, 3>), 3) \
V(store2, (Store<Float32x4, 2>), 3) \
V(store1, (Store<Float32x4, 1>), 3) \
V(sub, (BinaryFunc<Float32x4, Sub, Float32x4>), 2) \
V(xor, (CoercedBinaryFunc<Float32x4, Int32x4, Xor, Float32x4>), 2)
#define FLOAT32X4_TERNARY_FUNCTION_LIST(V) \
V(bitselect, BitSelect<Float32x4>, 3) \
V(bitselect, (BitSelect<Float32x4, Int32x4>), 3) \
V(clamp, Clamp<Float32x4>, 3) \
V(replaceLane, (ReplaceLane<Float32x4>), 3) \
V(select, Select<Float32x4>, 3)
V(select, (Select<Float32x4, Int32x4>), 3) \
V(store, (Store<Float32x4, 4>), 3) \
V(store3, (Store<Float32x4, 3>), 3) \
V(store2, (Store<Float32x4, 2>), 3) \
V(store1, (Store<Float32x4, 1>), 3)
#define FLOAT32X4_SHUFFLE_FUNCTION_LIST(V) \
V(swizzle, Swizzle<Float32x4>, 2) \
V(shuffle, Shuffle<Float32x4>, 3)
V(swizzle, Swizzle<Float32x4>, 5) \
V(shuffle, Shuffle<Float32x4>, 6)
#define FLOAT32X4_FUNCTION_LIST(V) \
FLOAT32X4_UNARY_FUNCTION_LIST(V) \
@ -82,6 +84,8 @@
V(check, (UnaryFunc<Float64x2, Identity, Float64x2>), 1) \
V(fromFloat32x4, (FuncConvert<Float32x4, Float64x2> ), 1) \
V(fromFloat32x4Bits, (FuncConvertBits<Float32x4, Float64x2>), 1) \
V(fromInt8x16Bits, (FuncConvertBits<Int8x16, Float64x2>), 1) \
V(fromInt16x8Bits, (FuncConvertBits<Int16x8, Float64x2>), 1) \
V(fromInt32x4, (FuncConvert<Int32x4, Float64x2> ), 1) \
V(fromInt32x4Bits, (FuncConvertBits<Int32x4, Float64x2>), 1) \
V(neg, (UnaryFunc<Float64x2, Neg, Float64x2>), 1) \
@ -93,11 +97,11 @@
#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>), 2) \
V(greaterThan, (CompareFunc<Float64x2, GreaterThan>), 2) \
V(greaterThanOrEqual, (CompareFunc<Float64x2, GreaterThanOrEqual>), 2) \
V(lessThan, (CompareFunc<Float64x2, LessThan>), 2) \
V(lessThanOrEqual, (CompareFunc<Float64x2, LessThanOrEqual>), 2) \
V(equal, (CompareFunc<Float64x2, Equal, Int32x4>), 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(load, (Load<Float64x2, 2>), 2) \
V(load1, (Load<Float64x2, 1>), 2) \
V(max, (BinaryFunc<Float64x2, Maximum, Float64x2>), 2) \
@ -105,20 +109,20 @@
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>), 2) \
V(store, (Store<Float64x2, 2>), 3) \
V(store1, (Store<Float64x2, 1>), 3) \
V(notEqual, (CompareFunc<Float64x2, NotEqual, Int32x4>), 2) \
V(sub, (BinaryFunc<Float64x2, Sub, Float64x2>), 2)
#define FLOAT64X2_TERNARY_FUNCTION_LIST(V) \
V(bitselect, BitSelect<Float64x2>, 3) \
V(bitselect, (BitSelect<Float64x2, Int32x4>), 3) \
V(clamp, Clamp<Float64x2>, 3) \
V(replaceLane, (ReplaceLane<Float64x2>), 3) \
V(select, Select<Float64x2>, 3)
V(select, (Select<Float64x2, Int32x4>), 3) \
V(store, (Store<Float64x2, 2>), 3) \
V(store1, (Store<Float64x2, 1>), 3)
#define FLOAT64X2_SHUFFLE_FUNCTION_LIST(V) \
V(swizzle, Swizzle<Float64x2>, 2) \
V(shuffle, Shuffle<Float64x2>, 3)
V(swizzle, Swizzle<Float64x2>, 3) \
V(shuffle, Shuffle<Float64x2>, 4)
#define FLOAT64X2_FUNCTION_LIST(V) \
FLOAT64X2_UNARY_FUNCTION_LIST(V) \
@ -126,12 +130,110 @@
FLOAT64X2_TERNARY_FUNCTION_LIST(V) \
FLOAT64X2_SHUFFLE_FUNCTION_LIST(V)
#define INT8X16_UNARY_FUNCTION_LIST(V) \
V(check, (UnaryFunc<Int8x16, Identity, Int8x16>), 1) \
V(fromFloat32x4Bits, (FuncConvertBits<Float32x4, Int8x16>), 1) \
V(fromFloat64x2Bits, (FuncConvertBits<Float64x2, Int8x16>), 1) \
V(fromInt16x8Bits, (FuncConvertBits<Int16x8, Int8x16>), 1) \
V(fromInt32x4Bits, (FuncConvertBits<Int32x4, Int8x16>), 1) \
V(neg, (UnaryFunc<Int8x16, Neg, Int8x16>), 1) \
V(not, (UnaryFunc<Int8x16, Not, Int8x16>), 1) \
V(splat, (FuncSplat<Int8x16>), 1)
#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(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(load, (Load<Int8x16, 16>), 2) \
V(mul, (BinaryFunc<Int8x16, Mul, Int8x16>), 2) \
V(notEqual, (CompareFunc<Int8x16, NotEqual, Int8x16>), 2) \
V(or, (BinaryFunc<Int8x16, Or, Int8x16>), 2) \
V(sub, (BinaryFunc<Int8x16, Sub, Int8x16>), 2) \
V(shiftLeftByScalar, (BinaryScalar<Int8x16, ShiftLeft>), 2) \
V(shiftRightArithmeticByScalar, (BinaryScalar<Int8x16, ShiftRightArithmetic>), 2) \
V(shiftRightLogicalByScalar, (BinaryScalar<Int8x16, ShiftRightLogical>), 2) \
V(xor, (BinaryFunc<Int8x16, Xor, Int8x16>), 2)
#define INT8X16_TERNARY_FUNCTION_LIST(V) \
V(bitselect, (BitSelect<Int8x16, Int8x16>), 3) \
V(replaceLane, (ReplaceLane<Int8x16>), 3) \
V(select, (Select<Int8x16, Int8x16>), 3) \
V(store, (Store<Int8x16, 16>), 3)
#define INT8X16_BOOL_FUNCTION_LIST(V) \
V(bool, Bool<Int8x16>, 16)
#define INT8X16_SHUFFLE_FUNCTION_LIST(V) \
V(swizzle, Swizzle<Int8x16>, 17) \
V(shuffle, Shuffle<Int8x16>, 18)
#define INT8X16_FUNCTION_LIST(V) \
INT8X16_UNARY_FUNCTION_LIST(V) \
INT8X16_BINARY_FUNCTION_LIST(V) \
INT8X16_TERNARY_FUNCTION_LIST(V) \
INT8X16_BOOL_FUNCTION_LIST(V) \
INT8X16_SHUFFLE_FUNCTION_LIST(V)
#define INT16X8_UNARY_FUNCTION_LIST(V) \
V(check, (UnaryFunc<Int16x8, Identity, Int16x8>), 1) \
V(fromFloat32x4Bits, (FuncConvertBits<Float32x4, Int16x8>), 1) \
V(fromFloat64x2Bits, (FuncConvertBits<Float64x2, Int16x8>), 1) \
V(fromInt8x16Bits, (FuncConvertBits<Int8x16, Int16x8>), 1) \
V(fromInt32x4Bits, (FuncConvertBits<Int32x4, Int16x8>), 1) \
V(neg, (UnaryFunc<Int16x8, Neg, Int16x8>), 1) \
V(not, (UnaryFunc<Int16x8, Not, Int16x8>), 1) \
V(splat, (FuncSplat<Int16x8>), 1)
#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(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(load, (Load<Int16x8, 8>), 2) \
V(mul, (BinaryFunc<Int16x8, Mul, Int16x8>), 2) \
V(notEqual, (CompareFunc<Int16x8, NotEqual, Int16x8>), 2) \
V(or, (BinaryFunc<Int16x8, Or, Int16x8>), 2) \
V(sub, (BinaryFunc<Int16x8, Sub, Int16x8>), 2) \
V(shiftLeftByScalar, (BinaryScalar<Int16x8, ShiftLeft>), 2) \
V(shiftRightArithmeticByScalar, (BinaryScalar<Int16x8, ShiftRightArithmetic>), 2) \
V(shiftRightLogicalByScalar, (BinaryScalar<Int16x8, ShiftRightLogical>), 2) \
V(xor, (BinaryFunc<Int16x8, Xor, Int16x8>), 2)
#define INT16X8_TERNARY_FUNCTION_LIST(V) \
V(bitselect, (BitSelect<Int16x8, Int16x8>), 3) \
V(replaceLane, (ReplaceLane<Int16x8>), 3) \
V(select, (Select<Int16x8, Int16x8>), 3) \
V(store, (Store<Int16x8, 8>), 3)
#define INT16X8_BOOL_FUNCTION_LIST(V) \
V(bool, Bool<Int16x8>, 8)
#define INT16X8_SHUFFLE_FUNCTION_LIST(V) \
V(swizzle, Swizzle<Int16x8>, 9) \
V(shuffle, Shuffle<Int16x8>, 10)
#define INT16X8_FUNCTION_LIST(V) \
INT16X8_UNARY_FUNCTION_LIST(V) \
INT16X8_BINARY_FUNCTION_LIST(V) \
INT16X8_TERNARY_FUNCTION_LIST(V) \
INT16X8_BOOL_FUNCTION_LIST(V) \
INT16X8_SHUFFLE_FUNCTION_LIST(V)
#define INT32X4_UNARY_FUNCTION_LIST(V) \
V(check, (UnaryFunc<Int32x4, Identity, Int32x4>), 1) \
V(fromFloat32x4, (FuncConvert<Float32x4, Int32x4>), 1) \
V(fromFloat32x4Bits, (FuncConvertBits<Float32x4, Int32x4>), 1) \
V(fromFloat64x2, (FuncConvert<Float64x2, Int32x4>), 1) \
V(fromFloat64x2Bits, (FuncConvertBits<Float64x2, Int32x4>), 1) \
V(fromInt8x16Bits, (FuncConvertBits<Int8x16, Int32x4>), 1) \
V(fromInt16x8Bits, (FuncConvertBits<Int16x8, Int32x4>), 1) \
V(neg, (UnaryFunc<Int32x4, Neg, Int32x4>), 1) \
V(not, (UnaryFunc<Int32x4, Not, Int32x4>), 1) \
V(splat, (FuncSplat<Int32x4>), 0)
@ -139,39 +241,39 @@
#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>), 2) \
V(greaterThan, (CompareFunc<Int32x4, GreaterThan>), 2) \
V(greaterThanOrEqual, (CompareFunc<Int32x4, GreaterThanOrEqual>), 2) \
V(lessThan, (CompareFunc<Int32x4, LessThan>), 2) \
V(lessThanOrEqual, (CompareFunc<Int32x4, LessThanOrEqual>), 2) \
V(equal, (CompareFunc<Int32x4, Equal, 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(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>), 2) \
V(notEqual, (CompareFunc<Int32x4, NotEqual, Int32x4>), 2) \
V(or, (BinaryFunc<Int32x4, Or, Int32x4>), 2) \
V(sub, (BinaryFunc<Int32x4, Sub, Int32x4>), 2) \
V(shiftLeftByScalar, (Int32x4BinaryScalar<ShiftLeft>), 2) \
V(shiftRightArithmeticByScalar, (Int32x4BinaryScalar<ShiftRightArithmetic>), 2) \
V(shiftRightLogicalByScalar, (Int32x4BinaryScalar<ShiftRightLogical>), 2) \
V(store, (Store<Int32x4, 4>), 3) \
V(store3, (Store<Int32x4, 3>), 3) \
V(store2, (Store<Int32x4, 2>), 3) \
V(store1, (Store<Int32x4, 1>), 3) \
V(shiftLeftByScalar, (BinaryScalar<Int32x4, ShiftLeft>), 2) \
V(shiftRightArithmeticByScalar, (BinaryScalar<Int32x4, ShiftRightArithmetic>), 2) \
V(shiftRightLogicalByScalar, (BinaryScalar<Int32x4, ShiftRightLogical>), 2) \
V(xor, (BinaryFunc<Int32x4, Xor, Int32x4>), 2)
#define INT32X4_TERNARY_FUNCTION_LIST(V) \
V(bitselect, BitSelect<Int32x4>, 3) \
V(bitselect, (BitSelect<Int32x4, Int32x4>), 3) \
V(replaceLane, (ReplaceLane<Int32x4>), 3) \
V(select, Select<Int32x4>, 3)
V(select, (Select<Int32x4, Int32x4>), 3) \
V(store, (Store<Int32x4, 4>), 3) \
V(store3, (Store<Int32x4, 3>), 3) \
V(store2, (Store<Int32x4, 2>), 3) \
V(store1, (Store<Int32x4, 1>), 3)
#define INT32X4_QUARTERNARY_FUNCTION_LIST(V) \
V(bool, Int32x4Bool, 4)
V(bool, Bool<Int32x4>, 4)
#define INT32X4_SHUFFLE_FUNCTION_LIST(V) \
V(swizzle, Swizzle<Int32x4>, 2) \
V(shuffle, Shuffle<Int32x4>, 3)
V(swizzle, Swizzle<Int32x4>, 5) \
V(shuffle, Shuffle<Int32x4>, 6)
#define INT32X4_FUNCTION_LIST(V) \
INT32X4_UNARY_FUNCTION_LIST(V) \
@ -304,6 +406,44 @@ struct Float64x2 {
}
};
struct Int8x16 {
typedef int8_t Elem;
static const unsigned lanes = 16;
static const SimdTypeDescr::Type type = SimdTypeDescr::Int8x16;
static TypeDescr& GetTypeDescr(GlobalObject& global) {
return global.int8x16TypeDescr().as<TypeDescr>();
}
static Elem toType(Elem a) {
return JS::ToInt8(a);
}
static bool toType(JSContext* cx, JS::HandleValue v, Elem* out) {
return ToInt8(cx, v, out);
}
static void setReturn(CallArgs& args, Elem value) {
args.rval().setInt32(value);
}
};
struct Int16x8 {
typedef int16_t Elem;
static const unsigned lanes = 8;
static const SimdTypeDescr::Type type = SimdTypeDescr::Int16x8;
static TypeDescr& GetTypeDescr(GlobalObject& global) {
return global.int16x8TypeDescr().as<TypeDescr>();
}
static Elem toType(Elem a) {
return JS::ToInt16(a);
}
static bool toType(JSContext* cx, JS::HandleValue v, Elem* out) {
return ToInt16(cx, v, out);
}
static void setReturn(CallArgs& args, Elem value) {
args.rval().setInt32(value);
}
};
struct Int32x4 {
typedef int32_t Elem;
static const unsigned lanes = 4;
@ -344,6 +484,18 @@ simd_float64x2_##Name(JSContext* cx, unsigned argc, Value* vp);
FLOAT64X2_FUNCTION_LIST(DECLARE_SIMD_FLOAT64X2_FUNCTION)
#undef DECLARE_SIMD_FLOAT64X2_FUNCTION
#define DECLARE_SIMD_INT8X16_FUNCTION(Name, Func, Operands) \
extern bool \
simd_int8x16_##Name(JSContext* cx, unsigned argc, Value* vp);
INT8X16_FUNCTION_LIST(DECLARE_SIMD_INT8X16_FUNCTION)
#undef DECLARE_SIMD_INT8X16_FUNCTION
#define DECLARE_SIMD_INT16X8_FUNCTION(Name, Func, Operands) \
extern bool \
simd_int16x8_##Name(JSContext* cx, unsigned argc, Value* vp);
INT16X8_FUNCTION_LIST(DECLARE_SIMD_INT16X8_FUNCTION)
#undef DECLARE_SIMD_INT16X8_FUNCTION
#define DECLARE_SIMD_INT32x4_FUNCTION(Name, Func, Operands) \
extern bool \
simd_int32x4_##Name(JSContext* cx, unsigned argc, Value* vp);

View File

@ -2618,6 +2618,26 @@ js::GetFloat64x2TypeDescr(JSContext* cx, unsigned argc, Value* vp)
return true;
}
bool
js::GetInt8x16TypeDescr(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
Rooted<GlobalObject*> global(cx, cx->global());
MOZ_ASSERT(global);
args.rval().setObject(global->int8x16TypeDescr());
return true;
}
bool
js::GetInt16x8TypeDescr(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
Rooted<GlobalObject*> global(cx, cx->global());
MOZ_ASSERT(global);
args.rval().setObject(global->int16x8TypeDescr());
return true;
}
bool
js::GetInt32x4TypeDescr(JSContext* cx, unsigned argc, Value* vp)
{

View File

@ -328,12 +328,14 @@ class ComplexTypeDescr : public TypeDescr
};
/*
* Type descriptors `float32x4`, `int32x4` and `float64x2`
* Type descriptors `int8x16`, `int16x8`, `int32x4`, `float32x4` and `float64x2`
*/
class SimdTypeDescr : public ComplexTypeDescr
{
public:
enum Type {
Int8x16 = JS_SIMDTYPEREPR_INT8,
Int16x8 = JS_SIMDTYPEREPR_INT16,
Int32x4 = JS_SIMDTYPEREPR_INT32,
Float32x4 = JS_SIMDTYPEREPR_FLOAT32,
Float64x2 = JS_SIMDTYPEREPR_FLOAT64,
@ -356,6 +358,8 @@ class SimdTypeDescr : public ComplexTypeDescr
};
#define JS_FOR_EACH_SIMD_TYPE_REPR(macro_) \
macro_(SimdTypeDescr::Int8x16, int8_t, int8, 16) \
macro_(SimdTypeDescr::Int16x8, int16_t, int16, 8) \
macro_(SimdTypeDescr::Int32x4, int32_t, int32, 4) \
macro_(SimdTypeDescr::Float32x4, float, float32, 4) \
macro_(SimdTypeDescr::Float64x2, double, float64, 2)
@ -862,6 +866,22 @@ bool GetFloat32x4TypeDescr(JSContext* cx, unsigned argc, Value* vp);
*/
bool GetFloat64x2TypeDescr(JSContext* cx, unsigned argc, Value* vp);
/*
* Usage: GetInt8x16TypeDescr()
*
* Returns the int8x16 type object. SIMD pseudo-module must have
* been initialized for this to be safe.
*/
bool GetInt8x16TypeDescr(JSContext* cx, unsigned argc, Value* vp);
/*
* Usage: GetInt16x8TypeDescr()
*
* Returns the int16x8 type object. SIMD pseudo-module must have
* been initialized for this to be safe.
*/
bool GetInt16x8TypeDescr(JSContext* cx, unsigned argc, Value* vp);
/*
* Usage: GetInt32x4TypeDescr()
*

View File

@ -157,6 +157,37 @@ function TypedObjectGetSimd(descr, typedObj, offset) {
var y = Load_float64(typedObj, offset + 8);
return GetFloat64x2TypeDescr()(x, y);
case JS_SIMDTYPEREPR_INT8:
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 GetInt8x16TypeDescr()(s0, s1, s2, s3, s4, s5, s6, s7,
s8, s9, s10, s11, s12, s13, s14, s15);
case JS_SIMDTYPEREPR_INT16:
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 GetInt8x16TypeDescr()(s0, s1, s2, s3, s4, s5, s6, s7);
case JS_SIMDTYPEREPR_INT32:
var x = Load_int32(typedObj, offset + 0);
var y = Load_int32(typedObj, offset + 4);
@ -331,6 +362,34 @@ function TypedObjectSetSimd(descr, typedObj, offset, fromValue) {
Store_float64(typedObj, offset + 0, Load_float64(fromValue, 0));
Store_float64(typedObj, offset + 8, Load_float64(fromValue, 8));
break;
case JS_SIMDTYPEREPR_INT8:
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));
Store_int8(typedObj, offset + 3, Load_int8(fromValue, 3));
Store_int8(typedObj, offset + 4, Load_int8(fromValue, 4));
Store_int8(typedObj, offset + 5, Load_int8(fromValue, 5));
Store_int8(typedObj, offset + 6, Load_int8(fromValue, 6));
Store_int8(typedObj, offset + 7, Load_int8(fromValue, 7));
Store_int8(typedObj, offset + 8, Load_int8(fromValue, 8));
Store_int8(typedObj, offset + 9, Load_int8(fromValue, 9));
Store_int8(typedObj, offset + 10, Load_int8(fromValue, 10));
Store_int8(typedObj, offset + 11, Load_int8(fromValue, 11));
Store_int8(typedObj, offset + 12, Load_int8(fromValue, 12));
Store_int8(typedObj, offset + 13, Load_int8(fromValue, 13));
Store_int8(typedObj, offset + 14, Load_int8(fromValue, 14));
Store_int8(typedObj, offset + 15, Load_int8(fromValue, 15));
break;
case JS_SIMDTYPEREPR_INT16:
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));
Store_int16(typedObj, offset + 6, Load_int16(fromValue, 6));
Store_int16(typedObj, offset + 8, Load_int16(fromValue, 8));
Store_int16(typedObj, offset + 10, Load_int16(fromValue, 10));
Store_int16(typedObj, offset + 12, Load_int16(fromValue, 12));
Store_int16(typedObj, offset + 14, Load_int16(fromValue, 14));
break;
case JS_SIMDTYPEREPR_INT32:
Store_int32(typedObj, offset + 0, Load_int32(fromValue, 0));
Store_int32(typedObj, offset + 4, Load_int32(fromValue, 4));
@ -462,6 +521,10 @@ function TypedObjectArrayRedimension(newArrayType) {
function SimdProtoString(type) {
switch (type) {
case JS_SIMDTYPEREPR_INT8:
return "int8x16";
case JS_SIMDTYPEREPR_INT16:
return "int16x8";
case JS_SIMDTYPEREPR_INT32:
return "int32x4";
case JS_SIMDTYPEREPR_FLOAT32:
@ -476,6 +539,10 @@ function SimdProtoString(type) {
function SimdTypeToLength(type) {
switch (type) {
case JS_SIMDTYPEREPR_INT8:
return 16;
case JS_SIMDTYPEREPR_INT16:
return 8;
case JS_SIMDTYPEREPR_INT32:
case JS_SIMDTYPEREPR_FLOAT32:
return 4;
@ -499,10 +566,14 @@ function SimdToSource() {
var type = DESCR_TYPE(descr);
var protoString = SimdProtoString(type);
var length = SimdTypeToLength(type);
if (length == 4)
return protoString+"("+this.x+", "+this.y+", "+this.z+", "+this.w+")";
else if (length == 2)
return protoString+"("+this.x+", "+this.y+")";
if (length == 2)
return `${protoString}(${this.x}, ${this.y})`;
else if (length == 4)
return `${protoString}(${this.x}, ${this.y}, ${this.z}, ${this.w})`;
else if (length == 8)
return `${protoString}(${this.s0}, ${this.s1}, ${this.s2}, ${this.s3}, ${this.s4}, ${this.s5}, ${this.s6}, ${this.s7})`;
else if (length == 16)
return `${protoString}(${this.s0}, ${this.s1}, ${this.s2}, ${this.s3}, ${this.s4}, ${this.s5}, ${this.s6}, ${this.s7}, ${this.s8}, ${this.s9}, ${this.s10}, ${this.s11}, ${this.s12}, ${this.s13}, ${this.s14}, ${this.s15})`;
}
///////////////////////////////////////////////////////////////////////////

View File

@ -105,8 +105,10 @@
// prefer SimdTypeRepresentation::TYPE_INT32 etc, since that allows
// you to write a switch which will receive a warning if you omit a
// case.
#define JS_SIMDTYPEREPR_INT32 0
#define JS_SIMDTYPEREPR_FLOAT32 1
#define JS_SIMDTYPEREPR_FLOAT64 2
#define JS_SIMDTYPEREPR_INT8 0
#define JS_SIMDTYPEREPR_INT16 1
#define JS_SIMDTYPEREPR_INT32 2
#define JS_SIMDTYPEREPR_FLOAT32 3
#define JS_SIMDTYPEREPR_FLOAT64 4
#endif

View File

@ -10378,6 +10378,8 @@ IonBuilder::SimdTypeDescrToMIRType(SimdTypeDescr::Type type)
switch (type) {
case SimdTypeDescr::Int32x4: return MIRType_Int32x4;
case SimdTypeDescr::Float32x4: return MIRType_Float32x4;
case SimdTypeDescr::Int8x16:
case SimdTypeDescr::Int16x8:
case SimdTypeDescr::Float64x2: return MIRType_Undefined;
}
MOZ_CRASH("unimplemented MIR type for a SimdTypeDescr::Type");

View File

@ -3093,7 +3093,7 @@ IonBuilder::inlineConstructSimdObject(CallInfo& callInfo, SimdTypeDescr* descr)
// Generic constructor of SIMD valuesX4.
MIRType simdType = SimdTypeDescrToMIRType(descr->type());
// TODO Happens for Float64x2 (Bug 1124205)
// TODO Happens for Float64x2 (Bug 1124205) and Int8x16/Int16x8 (Bug 1136226)
if (simdType == MIRType_Undefined)
return InliningStatus_NotInlined;
@ -3331,6 +3331,8 @@ SimdTypeToScalarType(SimdTypeDescr::Type type)
switch (type) {
case SimdTypeDescr::Float32x4: return Scalar::Float32x4;
case SimdTypeDescr::Int32x4: return Scalar::Int32x4;
case SimdTypeDescr::Int8x16:
case SimdTypeDescr::Int16x8:
case SimdTypeDescr::Float64x2: break;
}
MOZ_CRASH("unexpected simd type");

View File

@ -1344,6 +1344,12 @@ RSimdBox::recover(JSContext* cx, SnapshotIterator& iter) const
case SimdTypeDescr::Float64x2:
MOZ_CRASH("NYI, RSimdBox of Float64x2");
break;
case SimdTypeDescr::Int8x16:
MOZ_CRASH("NYI, RSimdBox of Int8x16");
break;
case SimdTypeDescr::Int16x8:
MOZ_CRASH("NYI, RSimdBox of Int16x8");
break;
}
if (!resultObject)

View File

@ -109,6 +109,8 @@
macro(InitializeNumberFormat, InitializeNumberFormat, "InitializeNumberFormat") \
macro(innermost, innermost, "innermost") \
macro(input, input, "input") \
macro(int8x16, int8x16, "int8x16") \
macro(int16x8, int16x8, "int16x8") \
macro(int32x4, int32x4, "int32x4") \
macro(isFinite, isFinite, "isFinite") \
macro(isNaN, isNaN, "isNaN") \

View File

@ -106,6 +106,8 @@ class GlobalObject : public NativeObject
INTRINSICS,
FLOAT32X4_TYPE_DESCR,
FLOAT64X2_TYPE_DESCR,
INT8X16_TYPE_DESCR,
INT16X8_TYPE_DESCR,
INT32X4_TYPE_DESCR,
FOR_OF_PIC_CHAIN,
@ -449,6 +451,26 @@ class GlobalObject : public NativeObject
return getSlotRef(FLOAT64X2_TYPE_DESCR).toObject();
}
void setInt8x16TypeDescr(JSObject& obj) {
MOZ_ASSERT(getSlotRef(INT8X16_TYPE_DESCR).isUndefined());
setSlot(INT8X16_TYPE_DESCR, ObjectValue(obj));
}
JSObject& int8x16TypeDescr() {
MOZ_ASSERT(getSlotRef(INT8X16_TYPE_DESCR).isObject());
return getSlotRef(INT8X16_TYPE_DESCR).toObject();
}
void setInt16x8TypeDescr(JSObject& obj) {
MOZ_ASSERT(getSlotRef(INT16X8_TYPE_DESCR).isUndefined());
setSlot(INT16X8_TYPE_DESCR, ObjectValue(obj));
}
JSObject& int16x8TypeDescr() {
MOZ_ASSERT(getSlotRef(INT16X8_TYPE_DESCR).isObject());
return getSlotRef(INT16X8_TYPE_DESCR).toObject();
}
void setInt32x4TypeDescr(JSObject& obj) {
MOZ_ASSERT(getSlotRef(INT32X4_TYPE_DESCR).isUndefined());
setSlot(INT32X4_TYPE_DESCR, ObjectValue(obj));

View File

@ -1396,6 +1396,8 @@ static const JSFunctionSpec intrinsic_functions[] = {
JS_FN("GetTypedObjectModule", js::GetTypedObjectModule, 0, 0),
JS_FN("GetFloat32x4TypeDescr", js::GetFloat32x4TypeDescr, 0, 0),
JS_FN("GetFloat64x2TypeDescr", js::GetFloat64x2TypeDescr, 0, 0),
JS_FN("GetInt8x16TypeDescr", js::GetInt8x16TypeDescr, 0, 0),
JS_FN("GetInt16x8TypeDescr", js::GetInt16x8TypeDescr, 0, 0),
JS_FN("GetInt32x4TypeDescr", js::GetInt32x4TypeDescr, 0, 0),
#define LOAD_AND_STORE_SCALAR_FN_DECLS(_constant, _type, _name) \