зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1048923: Distinguish unary and binary SIMD functions; r=nmatsakis
--HG-- extra : rebase_source : 5c34fcd13998388dc0d0755f9bbc5779b5f5a5f8
This commit is contained in:
Родитель
a3d7346207
Коммит
d5f030ad5a
|
@ -429,30 +429,33 @@ template JSObject *js::CreateSimd<Float32x4>(JSContext *cx, Float32x4::Elem *dat
|
|||
template JSObject *js::CreateSimd<Int32x4>(JSContext *cx, Int32x4::Elem *data);
|
||||
|
||||
namespace js {
|
||||
// Unary SIMD operators
|
||||
template<typename T>
|
||||
struct Abs {
|
||||
static inline T apply(T x, T zero) { return x < 0 ? -1 * x : x; }
|
||||
static inline T apply(T x) { return x < 0 ? -1 * x : x; }
|
||||
};
|
||||
template<typename T>
|
||||
struct Neg {
|
||||
static inline T apply(T x, T zero) { return -1 * x; }
|
||||
static inline T apply(T x) { return -1 * x; }
|
||||
};
|
||||
template<typename T>
|
||||
struct Not {
|
||||
static inline T apply(T x, T zero) { return ~x; }
|
||||
static inline T apply(T x) { return ~x; }
|
||||
};
|
||||
template<typename T>
|
||||
struct Rec {
|
||||
static inline T apply(T x, T zero) { return 1 / x; }
|
||||
static inline T apply(T x) { return 1 / x; }
|
||||
};
|
||||
template<typename T>
|
||||
struct RecSqrt {
|
||||
static inline T apply(T x, T zero) { return 1 / sqrt(x); }
|
||||
static inline T apply(T x) { return 1 / sqrt(x); }
|
||||
};
|
||||
template<typename T>
|
||||
struct Sqrt {
|
||||
static inline T apply(T x, T zero) { return sqrt(x); }
|
||||
static inline T apply(T x) { return sqrt(x); }
|
||||
};
|
||||
|
||||
// Binary SIMD operators
|
||||
template<typename T>
|
||||
struct Add {
|
||||
static inline T apply(T l, T r) { return l + r; }
|
||||
|
@ -582,43 +585,56 @@ StoreResult(JSContext *cx, CallArgs &args, typename Out::Elem *result)
|
|||
// and converts the result to the type Out.
|
||||
template<typename In, typename Coercion, template<typename C> class Op, typename Out>
|
||||
static bool
|
||||
CoercedFunc(JSContext *cx, unsigned argc, Value *vp)
|
||||
CoercedUnaryFunc(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
typedef typename Coercion::Elem CoercionElem;
|
||||
typedef typename Out::Elem RetElem;
|
||||
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
if (args.length() != 1 && args.length() != 2)
|
||||
if (args.length() != 1 || !IsVectorObject<In>(args[0]))
|
||||
return ErrorBadArgs(cx);
|
||||
|
||||
CoercionElem result[Coercion::lanes];
|
||||
if (args.length() == 1) {
|
||||
if (!IsVectorObject<In>(args[0]))
|
||||
return ErrorBadArgs(cx);
|
||||
|
||||
CoercionElem *val = TypedObjectMemory<CoercionElem *>(args[0]);
|
||||
for (unsigned i = 0; i < Coercion::lanes; i++)
|
||||
result[i] = Op<CoercionElem>::apply(val[i], 0);
|
||||
} else {
|
||||
JS_ASSERT(args.length() == 2);
|
||||
if (!IsVectorObject<In>(args[0]) || !IsVectorObject<In>(args[1]))
|
||||
return ErrorBadArgs(cx);
|
||||
|
||||
CoercionElem *left = TypedObjectMemory<CoercionElem *>(args[0]);
|
||||
CoercionElem *right = TypedObjectMemory<CoercionElem *>(args[1]);
|
||||
for (unsigned i = 0; i < Coercion::lanes; i++)
|
||||
result[i] = Op<CoercionElem>::apply(left[i], right[i]);
|
||||
}
|
||||
|
||||
CoercionElem *val = TypedObjectMemory<CoercionElem *>(args[0]);
|
||||
for (unsigned i = 0; i < Coercion::lanes; i++)
|
||||
result[i] = Op<CoercionElem>::apply(val[i]);
|
||||
return StoreResult<Out>(cx, args, (RetElem*) result);
|
||||
}
|
||||
|
||||
// Same as above, with Coercion == Out
|
||||
// Coerces the inputs of type In to the type Coercion, apply the operator Op
|
||||
// and converts the result to the type Out.
|
||||
template<typename In, typename Coercion, template<typename C> class Op, typename Out>
|
||||
static bool
|
||||
CoercedBinaryFunc(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
typedef typename Coercion::Elem CoercionElem;
|
||||
typedef typename Out::Elem RetElem;
|
||||
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
if (args.length() != 2 || !IsVectorObject<In>(args[0]) || !IsVectorObject<In>(args[1]))
|
||||
return ErrorBadArgs(cx);
|
||||
|
||||
CoercionElem result[Coercion::lanes];
|
||||
CoercionElem *left = TypedObjectMemory<CoercionElem *>(args[0]);
|
||||
CoercionElem *right = TypedObjectMemory<CoercionElem *>(args[1]);
|
||||
for (unsigned i = 0; i < Coercion::lanes; i++)
|
||||
result[i] = Op<CoercionElem>::apply(left[i], right[i]);
|
||||
return StoreResult<Out>(cx, args, (RetElem *) result);
|
||||
}
|
||||
|
||||
// Same as above, with no coercion, i.e. Coercion == In.
|
||||
template<typename In, template<typename C> class Op, typename Out>
|
||||
static bool
|
||||
Func(JSContext *cx, unsigned argc, Value *vp)
|
||||
UnaryFunc(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
return CoercedFunc<In, Out, Op, Out>(cx, argc, vp);
|
||||
return CoercedUnaryFunc<In, Out, Op, Out>(cx, argc, vp);
|
||||
}
|
||||
|
||||
template<typename In, template<typename C> class Op, typename Out>
|
||||
static bool
|
||||
BinaryFunc(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
return CoercedBinaryFunc<In, Out, Op, Out>(cx, argc, vp);
|
||||
}
|
||||
|
||||
template<typename V, template<typename T> class OpWith>
|
||||
|
@ -856,7 +872,7 @@ Int32x4Select(JSContext *cx, unsigned argc, Value *vp)
|
|||
|
||||
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], 0), fv[i]);
|
||||
fr[i] = And<int32_t>::apply(Not<int32_t>::apply(val[i]), fv[i]);
|
||||
|
||||
int32_t orInt[Int32x4::lanes];
|
||||
for (unsigned i = 0; i < Int32x4::lanes; i++)
|
||||
|
|
|
@ -18,98 +18,98 @@
|
|||
* https://github.com/johnmccutchan/ecmascript_simd/blob/master/src/ecmascript_simd.js
|
||||
*/
|
||||
|
||||
#define FLOAT32X4_NULLARY_FUNCTION_LIST(V) \
|
||||
#define FLOAT32X4_NULLARY_FUNCTION_LIST(V) \
|
||||
V(zero, (FuncZero<Float32x4>), 0, 0, Zero)
|
||||
|
||||
#define FLOAT32X4_UNARY_FUNCTION_LIST(V) \
|
||||
V(abs, (Func<Float32x4, Abs, Float32x4>), 1, 0, Abs) \
|
||||
V(fromInt32x4Bits, (FuncConvertBits<Int32x4, Float32x4>), 1, 0, FromInt32x4Bits) \
|
||||
V(neg, (Func<Float32x4, Neg, Float32x4>), 1, 0, Neg) \
|
||||
V(not, (CoercedFunc<Float32x4, Int32x4, Not, Float32x4>), 1, 0, Not) \
|
||||
V(reciprocal, (Func<Float32x4, Rec, Float32x4>), 1, 0, Reciprocal) \
|
||||
V(reciprocalSqrt, (Func<Float32x4, RecSqrt, Float32x4>), 1, 0, ReciprocalSqrt) \
|
||||
V(splat, (FuncSplat<Float32x4>), 1, 0, Splat) \
|
||||
V(sqrt, (Func<Float32x4, Sqrt, Float32x4>), 1, 0, Sqrt) \
|
||||
#define FLOAT32X4_UNARY_FUNCTION_LIST(V) \
|
||||
V(abs, (UnaryFunc<Float32x4, Abs, Float32x4>), 1, 0, Abs) \
|
||||
V(fromInt32x4Bits, (FuncConvertBits<Int32x4, Float32x4>), 1, 0, FromInt32x4Bits) \
|
||||
V(neg, (UnaryFunc<Float32x4, Neg, Float32x4>), 1, 0, Neg) \
|
||||
V(not, (CoercedUnaryFunc<Float32x4, Int32x4, Not, Float32x4>), 1, 0, Not) \
|
||||
V(reciprocal, (UnaryFunc<Float32x4, Rec, Float32x4>), 1, 0, Reciprocal) \
|
||||
V(reciprocalSqrt, (UnaryFunc<Float32x4, RecSqrt, Float32x4>), 1, 0, ReciprocalSqrt) \
|
||||
V(splat, (FuncSplat<Float32x4>), 1, 0, Splat) \
|
||||
V(sqrt, (UnaryFunc<Float32x4, Sqrt, Float32x4>), 1, 0, Sqrt) \
|
||||
V(fromInt32x4, (FuncConvert<Int32x4, Float32x4> ), 1, 0, FromInt32x4)
|
||||
|
||||
#define FLOAT32X4_BINARY_FUNCTION_LIST(V) \
|
||||
V(add, (Func<Float32x4, Add, Float32x4>), 2, 0, Add) \
|
||||
V(and, (CoercedFunc<Float32x4, Int32x4, And, Float32x4>), 2, 0, And) \
|
||||
V(div, (Func<Float32x4, Div, Float32x4>), 2, 0, Div) \
|
||||
V(equal, (Func<Float32x4, Equal, Int32x4>), 2, 0, Equal) \
|
||||
V(greaterThan, (Func<Float32x4, GreaterThan, Int32x4>), 2, 0, GreaterThan) \
|
||||
V(greaterThanOrEqual, (Func<Float32x4, GreaterThanOrEqual, Int32x4>), 2, 0, GreaterThanOrEqual) \
|
||||
V(lessThan, (Func<Float32x4, LessThan, Int32x4>), 2, 0, LessThan) \
|
||||
V(lessThanOrEqual, (Func<Float32x4, LessThanOrEqual, Int32x4>), 2, 0, LessThanOrEqual) \
|
||||
V(max, (Func<Float32x4, Maximum, Float32x4>), 2, 0, Max) \
|
||||
V(min, (Func<Float32x4, Minimum, Float32x4>), 2, 0, Min) \
|
||||
V(mul, (Func<Float32x4, Mul, Float32x4>), 2, 0, Mul) \
|
||||
V(notEqual, (Func<Float32x4, NotEqual, Int32x4>), 2, 0, NotEqual) \
|
||||
V(shuffle, FuncShuffle<Float32x4>, 2, 0, Shuffle) \
|
||||
V(or, (CoercedFunc<Float32x4, Int32x4, Or, Float32x4>), 2, 0, Or) \
|
||||
V(scale, (FuncWith<Float32x4, Scale>), 2, 0, Scale) \
|
||||
V(sub, (Func<Float32x4, Sub, Float32x4>), 2, 0, Sub) \
|
||||
V(withX, (FuncWith<Float32x4, WithX>), 2, 0, WithX) \
|
||||
V(withY, (FuncWith<Float32x4, WithY>), 2, 0, WithY) \
|
||||
V(withZ, (FuncWith<Float32x4, WithZ>), 2, 0, WithZ) \
|
||||
V(withW, (FuncWith<Float32x4, WithW>), 2, 0, WithW) \
|
||||
V(xor, (CoercedFunc<Float32x4, Int32x4, Xor, Float32x4>), 2, 0, Xor)
|
||||
#define FLOAT32X4_BINARY_FUNCTION_LIST(V) \
|
||||
V(add, (BinaryFunc<Float32x4, Add, Float32x4>), 2, 0, Add) \
|
||||
V(and, (CoercedBinaryFunc<Float32x4, Int32x4, And, Float32x4>), 2, 0, And) \
|
||||
V(div, (BinaryFunc<Float32x4, Div, Float32x4>), 2, 0, Div) \
|
||||
V(equal, (BinaryFunc<Float32x4, Equal, Int32x4>), 2, 0, Equal) \
|
||||
V(greaterThan, (BinaryFunc<Float32x4, GreaterThan, Int32x4>), 2, 0, GreaterThan) \
|
||||
V(greaterThanOrEqual, (BinaryFunc<Float32x4, GreaterThanOrEqual, Int32x4>), 2, 0, GreaterThanOrEqual) \
|
||||
V(lessThan, (BinaryFunc<Float32x4, LessThan, Int32x4>), 2, 0, LessThan) \
|
||||
V(lessThanOrEqual, (BinaryFunc<Float32x4, LessThanOrEqual, Int32x4>), 2, 0, LessThanOrEqual) \
|
||||
V(max, (BinaryFunc<Float32x4, Maximum, Float32x4>), 2, 0, Max) \
|
||||
V(min, (BinaryFunc<Float32x4, Minimum, Float32x4>), 2, 0, Min) \
|
||||
V(mul, (BinaryFunc<Float32x4, Mul, Float32x4>), 2, 0, Mul) \
|
||||
V(notEqual, (BinaryFunc<Float32x4, NotEqual, Int32x4>), 2, 0, NotEqual) \
|
||||
V(shuffle, FuncShuffle<Float32x4>, 2, 0, Shuffle) \
|
||||
V(or, (CoercedBinaryFunc<Float32x4, Int32x4, Or, Float32x4>), 2, 0, Or) \
|
||||
V(scale, (FuncWith<Float32x4, Scale>), 2, 0, Scale) \
|
||||
V(sub, (BinaryFunc<Float32x4, Sub, Float32x4>), 2, 0, Sub) \
|
||||
V(withX, (FuncWith<Float32x4, WithX>), 2, 0, WithX) \
|
||||
V(withY, (FuncWith<Float32x4, WithY>), 2, 0, WithY) \
|
||||
V(withZ, (FuncWith<Float32x4, WithZ>), 2, 0, WithZ) \
|
||||
V(withW, (FuncWith<Float32x4, WithW>), 2, 0, WithW) \
|
||||
V(xor, (CoercedBinaryFunc<Float32x4, Int32x4, Xor, Float32x4>), 2, 0, Xor)
|
||||
|
||||
#define FLOAT32X4_TERNARY_FUNCTION_LIST(V) \
|
||||
V(clamp, Float32x4Clamp, 3, 0, Clamp) \
|
||||
#define FLOAT32X4_TERNARY_FUNCTION_LIST(V) \
|
||||
V(clamp, Float32x4Clamp, 3, 0, Clamp) \
|
||||
V(shuffleMix, FuncShuffle<Float32x4>, 3, 0, ShuffleMix)
|
||||
|
||||
#define FLOAT32X4_FUNCTION_LIST(V) \
|
||||
FLOAT32X4_NULLARY_FUNCTION_LIST(V) \
|
||||
FLOAT32X4_UNARY_FUNCTION_LIST(V) \
|
||||
FLOAT32X4_BINARY_FUNCTION_LIST(V) \
|
||||
#define FLOAT32X4_FUNCTION_LIST(V) \
|
||||
FLOAT32X4_NULLARY_FUNCTION_LIST(V) \
|
||||
FLOAT32X4_UNARY_FUNCTION_LIST(V) \
|
||||
FLOAT32X4_BINARY_FUNCTION_LIST(V) \
|
||||
FLOAT32X4_TERNARY_FUNCTION_LIST(V)
|
||||
|
||||
#define INT32X4_NULLARY_FUNCTION_LIST(V) \
|
||||
#define INT32X4_NULLARY_FUNCTION_LIST(V) \
|
||||
V(zero, (FuncZero<Int32x4>), 0, 0, Zero)
|
||||
|
||||
#define INT32X4_UNARY_FUNCTION_LIST(V) \
|
||||
V(fromFloat32x4Bits, (FuncConvertBits<Float32x4, Int32x4>), 1, 0, FromFloat32x4Bits) \
|
||||
V(neg, (Func<Int32x4, Neg, Int32x4>), 1, 0, Neg) \
|
||||
V(not, (Func<Int32x4, Not, Int32x4>), 1, 0, Not) \
|
||||
V(splat, (FuncSplat<Int32x4>), 0, 0, Splat) \
|
||||
#define INT32X4_UNARY_FUNCTION_LIST(V) \
|
||||
V(fromFloat32x4Bits, (FuncConvertBits<Float32x4, Int32x4>), 1, 0, FromFloat32x4Bits) \
|
||||
V(neg, (UnaryFunc<Int32x4, Neg, Int32x4>), 1, 0, Neg) \
|
||||
V(not, (UnaryFunc<Int32x4, Not, Int32x4>), 1, 0, Not) \
|
||||
V(splat, (FuncSplat<Int32x4>), 0, 0, Splat) \
|
||||
V(fromFloat32x4, (FuncConvert<Float32x4, Int32x4>), 1, 0, FromFloat32x4)
|
||||
|
||||
#define INT32X4_BINARY_FUNCTION_LIST(V) \
|
||||
V(add, (Func<Int32x4, Add, Int32x4>), 2, 0, Add) \
|
||||
V(and, (Func<Int32x4, And, Int32x4>), 2, 0, And) \
|
||||
V(equal, (Func<Int32x4, Equal, Int32x4>), 2, 0, Equal) \
|
||||
V(greaterThan, (Func<Int32x4, GreaterThan, Int32x4>), 2, 0, GreaterThan) \
|
||||
V(lessThan, (Func<Int32x4, LessThan, Int32x4>), 2, 0, LessThan) \
|
||||
V(mul, (Func<Int32x4, Mul, Int32x4>), 2, 0, Mul) \
|
||||
V(or, (Func<Int32x4, Or, Int32x4>), 2, 0, Or) \
|
||||
V(sub, (Func<Int32x4, Sub, Int32x4>), 2, 0, Sub) \
|
||||
V(shiftLeft, (Int32x4BinaryScalar<ShiftLeft>), 2, 0, ShiftLeft) \
|
||||
V(shiftRight, (Int32x4BinaryScalar<ShiftRight>), 2, 0, ShiftRight) \
|
||||
V(shiftRightLogical, (Int32x4BinaryScalar<ShiftRightLogical>), 2, 0, ShiftRightLogical) \
|
||||
V(shuffle, FuncShuffle<Int32x4>, 2, 0, Shuffle) \
|
||||
V(withFlagX, (FuncWith<Int32x4, WithFlagX>), 2, 0, WithFlagX) \
|
||||
V(withFlagY, (FuncWith<Int32x4, WithFlagY>), 2, 0, WithFlagY) \
|
||||
V(withFlagZ, (FuncWith<Int32x4, WithFlagZ>), 2, 0, WithFlagZ) \
|
||||
V(withFlagW, (FuncWith<Int32x4, WithFlagW>), 2, 0, WithFlagW) \
|
||||
V(withX, (FuncWith<Int32x4, WithX>), 2, 0, WithX) \
|
||||
V(withY, (FuncWith<Int32x4, WithY>), 2, 0, WithY) \
|
||||
V(withZ, (FuncWith<Int32x4, WithZ>), 2, 0, WithZ) \
|
||||
V(withW, (FuncWith<Int32x4, WithW>), 2, 0, WithW) \
|
||||
V(xor, (Func<Int32x4, Xor, Int32x4>), 2, 0, Xor)
|
||||
#define INT32X4_BINARY_FUNCTION_LIST(V) \
|
||||
V(add, (BinaryFunc<Int32x4, Add, Int32x4>), 2, 0, Add) \
|
||||
V(and, (BinaryFunc<Int32x4, And, Int32x4>), 2, 0, And) \
|
||||
V(equal, (BinaryFunc<Int32x4, Equal, Int32x4>), 2, 0, Equal) \
|
||||
V(greaterThan, (BinaryFunc<Int32x4, GreaterThan, Int32x4>), 2, 0, GreaterThan) \
|
||||
V(lessThan, (BinaryFunc<Int32x4, LessThan, Int32x4>), 2, 0, LessThan) \
|
||||
V(mul, (BinaryFunc<Int32x4, Mul, Int32x4>), 2, 0, Mul) \
|
||||
V(or, (BinaryFunc<Int32x4, Or, Int32x4>), 2, 0, Or) \
|
||||
V(sub, (BinaryFunc<Int32x4, Sub, Int32x4>), 2, 0, Sub) \
|
||||
V(shiftLeft, (Int32x4BinaryScalar<ShiftLeft>), 2, 0, ShiftLeft) \
|
||||
V(shiftRight, (Int32x4BinaryScalar<ShiftRight>), 2, 0, ShiftRight) \
|
||||
V(shiftRightLogical, (Int32x4BinaryScalar<ShiftRightLogical>), 2, 0, ShiftRightLogical) \
|
||||
V(shuffle, FuncShuffle<Int32x4>, 2, 0, Shuffle) \
|
||||
V(withFlagX, (FuncWith<Int32x4, WithFlagX>), 2, 0, WithFlagX) \
|
||||
V(withFlagY, (FuncWith<Int32x4, WithFlagY>), 2, 0, WithFlagY) \
|
||||
V(withFlagZ, (FuncWith<Int32x4, WithFlagZ>), 2, 0, WithFlagZ) \
|
||||
V(withFlagW, (FuncWith<Int32x4, WithFlagW>), 2, 0, WithFlagW) \
|
||||
V(withX, (FuncWith<Int32x4, WithX>), 2, 0, WithX) \
|
||||
V(withY, (FuncWith<Int32x4, WithY>), 2, 0, WithY) \
|
||||
V(withZ, (FuncWith<Int32x4, WithZ>), 2, 0, WithZ) \
|
||||
V(withW, (FuncWith<Int32x4, WithW>), 2, 0, WithW) \
|
||||
V(xor, (BinaryFunc<Int32x4, Xor, Int32x4>), 2, 0, Xor)
|
||||
|
||||
#define INT32X4_TERNARY_FUNCTION_LIST(V) \
|
||||
V(select, Int32x4Select, 3, 0, Select) \
|
||||
#define INT32X4_TERNARY_FUNCTION_LIST(V) \
|
||||
V(select, Int32x4Select, 3, 0, Select) \
|
||||
V(shuffleMix, FuncShuffle<Int32x4>, 3, 0, ShuffleMix)
|
||||
|
||||
#define INT32X4_QUARTERNARY_FUNCTION_LIST(V) \
|
||||
#define INT32X4_QUARTERNARY_FUNCTION_LIST(V) \
|
||||
V(bool, Int32x4Bool, 4, 0, Bool)
|
||||
|
||||
#define INT32X4_FUNCTION_LIST(V) \
|
||||
INT32X4_NULLARY_FUNCTION_LIST(V) \
|
||||
INT32X4_UNARY_FUNCTION_LIST(V) \
|
||||
INT32X4_BINARY_FUNCTION_LIST(V) \
|
||||
INT32X4_TERNARY_FUNCTION_LIST(V) \
|
||||
#define INT32X4_FUNCTION_LIST(V) \
|
||||
INT32X4_NULLARY_FUNCTION_LIST(V) \
|
||||
INT32X4_UNARY_FUNCTION_LIST(V) \
|
||||
INT32X4_BINARY_FUNCTION_LIST(V) \
|
||||
INT32X4_TERNARY_FUNCTION_LIST(V) \
|
||||
INT32X4_QUARTERNARY_FUNCTION_LIST(V)
|
||||
|
||||
namespace js {
|
||||
|
|
Загрузка…
Ссылка в новой задаче