Bug 993034: SIMD - Define shallow wrappers macro that call templated functions instead of macro functions; r=nmatsakis
authorBenjamin Bouvier <benj@benj.me>
Wed, 16 Apr 2014 16:21:26 +0200
changeset 197313 87e9fc86154e1e3cd5dbb461578db02c842af3d2
parent 197312 6b1f10cb214adcd31c66c689cc178d9e631c8938
child 197314 330cc814b05bb6a12e632ef9adfbedf73b4c0861
push id3624
push userasasaki@mozilla.com
push dateMon, 09 Jun 2014 21:49:01 +0000
treeherdermozilla-beta@b1a5da15899a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnmatsakis
bugs993034
milestone31.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 993034: SIMD - Define shallow wrappers macro that call templated functions instead of macro functions; r=nmatsakis
js/src/builtin/SIMD.cpp
--- a/js/src/builtin/SIMD.cpp
+++ b/js/src/builtin/SIMD.cpp
@@ -30,78 +30,95 @@ using mozilla::IsNaN;
 namespace js {
 extern const JSFunctionSpec Float32x4Methods[];
 extern const JSFunctionSpec Int32x4Methods[];
 }
 
 ///////////////////////////////////////////////////////////////////////////
 // X4
 
-#define LANE_ACCESSOR(Type32x4, lane) \
-    bool Type32x4##Lane##lane(JSContext *cx, unsigned argc, Value *vp) { \
-        static const char *laneNames[] = {"lane 0", "lane 1", "lane 2", "lane3"}; \
-        CallArgs args = CallArgsFromVp(argc, vp); \
-        if(!args.thisv().isObject() || !args.thisv().toObject().is<TypedObject>()) {        \
-            JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO, \
-                                 X4TypeDescr::class_.name, laneNames[lane], \
-                                 InformalValueTypeName(args.thisv())); \
-            return false; \
-        } \
-        TypedObject &typedObj = args.thisv().toObject().as<TypedObject>(); \
-        TypeDescr &descr = typedObj.typeDescr(); \
-        if (descr.kind() != TypeDescr::X4 || \
-            descr.as<X4TypeDescr>().type() != Type32x4::type) \
-        {  \
-            JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO, \
-                                 X4TypeDescr::class_.name, laneNames[lane], \
-                                 InformalValueTypeName(args.thisv())); \
-            return false; \
-        } \
-        Type32x4::Elem *data = reinterpret_cast<Type32x4::Elem *>(typedObj.typedMem()); \
-        Type32x4::setReturn(args, data[lane]); \
-        return true; \
+static const char *laneNames[] = {"lane 0", "lane 1", "lane 2", "lane3"};
+
+template<typename Type32x4, int lane>
+static bool GetX4Lane(JSContext *cx, unsigned argc, Value *vp) {
+    typedef typename Type32x4::Elem Elem;
+
+    CallArgs args = CallArgsFromVp(argc, vp);
+    if(!args.thisv().isObject() || !args.thisv().toObject().is<TypedObject>()) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
+                             X4TypeDescr::class_.name, laneNames[lane],
+                             InformalValueTypeName(args.thisv()));
+        return false;
     }
-    LANE_ACCESSOR(Float32x4, 0);
-    LANE_ACCESSOR(Float32x4, 1);
-    LANE_ACCESSOR(Float32x4, 2);
-    LANE_ACCESSOR(Float32x4, 3);
-    LANE_ACCESSOR(Int32x4, 0);
-    LANE_ACCESSOR(Int32x4, 1);
-    LANE_ACCESSOR(Int32x4, 2);
-    LANE_ACCESSOR(Int32x4, 3);
+
+    TypedObject &typedObj = args.thisv().toObject().as<TypedObject>();
+    TypeDescr &descr = typedObj.typeDescr();
+    if (descr.kind() != TypeDescr::X4 || descr.as<X4TypeDescr>().type() != Type32x4::type) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
+                             X4TypeDescr::class_.name, laneNames[lane],
+                             InformalValueTypeName(args.thisv()));
+        return false;
+    }
+
+    Elem *data = reinterpret_cast<Elem *>(typedObj.typedMem());
+    Type32x4::setReturn(args, data[lane]);
+    return true;
+}
+
+#define LANE_ACCESSOR(type, lane) \
+static bool type##Lane##lane(JSContext *cx, unsigned argc, Value *vp) { \
+    return GetX4Lane<type, lane>(cx, argc, vp);\
+}
+
+#define FOUR_LANES_ACCESSOR(type) \
+    LANE_ACCESSOR(type, 0); \
+    LANE_ACCESSOR(type, 1); \
+    LANE_ACCESSOR(type, 2); \
+    LANE_ACCESSOR(type, 3);
+
+    FOUR_LANES_ACCESSOR(Int32x4);
+    FOUR_LANES_ACCESSOR(Float32x4);
+#undef FOUR_LANES_ACCESSOR
 #undef LANE_ACCESSOR
 
-#define SIGN_MASK(Type32x4) \
-    bool Type32x4##SignMask(JSContext *cx, unsigned argc, Value *vp) { \
-        CallArgs args = CallArgsFromVp(argc, vp); \
-        if(!args.thisv().isObject() || !args.thisv().toObject().is<TypedObject>()) {        \
-            JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO, \
-                                 X4TypeDescr::class_.name, "signMask", \
-                                 InformalValueTypeName(args.thisv())); \
-            return false; \
-        } \
-        TypedObject &typedObj = args.thisv().toObject().as<TypedObject>(); \
-        TypeDescr &descr = typedObj.typeDescr(); \
-        if (descr.kind() != TypeDescr::X4 || \
-            descr.as<X4TypeDescr>().type() != Type32x4::type) \
-        { \
-            JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO, \
-                                 X4TypeDescr::class_.name, "signMask", \
-                                 InformalValueTypeName(args.thisv())); \
-            return false; \
-        } \
-        Type32x4::Elem *data = reinterpret_cast<Type32x4::Elem *>(typedObj.typedMem()); \
-        int32_t mx = data[0] < 0.0 ? 1 : 0; \
-        int32_t my = data[1] < 0.0 ? 1 : 0; \
-        int32_t mz = data[2] < 0.0 ? 1 : 0; \
-        int32_t mw = data[3] < 0.0 ? 1 : 0; \
-        int32_t result = mx | my << 1 | mz << 2 | mw << 3; \
-        args.rval().setInt32(result); \
-        return true; \
+template<typename Type32x4>
+static bool SignMask(JSContext *cx, unsigned argc, Value *vp) {
+    typedef typename Type32x4::Elem Elem;
+
+    CallArgs args = CallArgsFromVp(argc, vp);
+    if(!args.thisv().isObject() || !args.thisv().toObject().is<TypedObject>()) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
+                             X4TypeDescr::class_.name, "signMask",
+                             InformalValueTypeName(args.thisv()));
+        return false;
     }
+
+    TypedObject &typedObj = args.thisv().toObject().as<TypedObject>();
+    TypeDescr &descr = typedObj.typeDescr();
+    if (descr.kind() != TypeDescr::X4 || descr.as<X4TypeDescr>().type() != Type32x4::type) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
+                             X4TypeDescr::class_.name, "signMask",
+                             InformalValueTypeName(args.thisv()));
+        return false;
+    }
+
+    Elem *data = reinterpret_cast<Elem *>(typedObj.typedMem());
+    int32_t mx = data[0] < 0.0 ? 1 : 0;
+    int32_t my = data[1] < 0.0 ? 1 : 0;
+    int32_t mz = data[2] < 0.0 ? 1 : 0;
+    int32_t mw = data[3] < 0.0 ? 1 : 0;
+    int32_t result = mx | my << 1 | mz << 2 | mw << 3;
+    args.rval().setInt32(result);
+    return true;
+}
+
+#define SIGN_MASK(type) \
+static bool type##SignMask(JSContext *cx, unsigned argc, Value *vp) { \
+    return SignMask<Int32x4>(cx, argc, vp); \
+}
     SIGN_MASK(Float32x4);
     SIGN_MASK(Int32x4);
 #undef SIGN_MASK
 
 const Class X4TypeDescr::class_ = {
     "X4",
     JSCLASS_HAS_RESERVED_SLOTS(JS_DESCR_SLOTS),
     JS_PropertyStub,         /* addProperty */