mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1124291 - SIMD (interpreter): Implemented int8x16 and int16x8 on a CLOSED TREE. r=bbouvier
This commit is contained in:
parent
25191a7cd9
commit
6bb9a5d050
@ -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 \
|
||||
|
@ -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) \
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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()
|
||||
*
|
||||
|
@ -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})`;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
|
@ -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");
|
||||
|
@ -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)
|
||||
|
@ -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") \
|
||||
|
@ -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));
|
||||
|
@ -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) \
|
||||
|
Loading…
Reference in New Issue
Block a user