Introduce primitives for common binary operations.
 author Andreas Gal Mon, 26 May 2008 17:29:28 -0700 changeset 17174 5c552143c1b3c335cd55bdc38d2368213815777b parent 17173 343a7e6713a3673d1884d728b97b82a8412e69b9 child 17175 1e8aed6c7201d4db8e8ff1eb332ad8654888d10d push id 1452 push user shaver@mozilla.com push date Fri, 22 Aug 2008 00:08:22 +0000 treeherder autoland@d13bb0868596 [default view] [failures only] perfherder [talos] [build metrics] [platform microbench] (compared to previous push) milestone 1.9.1a1pre
Introduce primitives for common binary operations.
 js/src/jsinterp.cpp file | annotate | diff | comparison | revisions
```--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -2676,16 +2676,89 @@ static inline bool default_value(JSConte
prim_fetch_stack(regs, n, v);
return JS_TRUE;
}

#define DEFAULT_VALUE(cx, n, hint, v)                                         \
if (!default_value(cx, regs, n, hint, v))                                 \
goto error;

+static inline void prim_dadd(jsdouble& a, jsdouble& b, jsdouble& r) {
+    r = a + b;
+}
+
+static inline void prim_dsub(jsdouble& a, jsdouble& b, jsdouble& r) {
+    r = a - b;
+}
+
+static inline void prim_dmul(jsdouble& a, jsdouble& b, jsdouble& r) {
+    r = a * b;
+}
+
+static inline void prim_ddiv(JSContext* cx, JSRuntime* rt, JSFrameRegs& regs, int n, jsdouble& a, jsdouble& b) {
+    if (b == 0) {
+        jsval* vp = &regs.sp[n];
+#ifdef XP_WIN
+        /* XXX MSVC miscompiles such that (NaN == 0) */
+        if (JSDOUBLE_IS_NaN(b))
+            *vp = DOUBLE_TO_JSVAL(rt->jsNaN);
+        else
+#endif
+        if (a == 0 || JSDOUBLE_IS_NaN(a))
+            *vp = DOUBLE_TO_JSVAL(rt->jsNaN);
+        else if ((JSDOUBLE_HI32(a) ^ JSDOUBLE_HI32(b)) >> 31)
+            *vp = DOUBLE_TO_JSVAL(rt->jsNegativeInfinity);
+        else
+            *vp = DOUBLE_TO_JSVAL(rt->jsPositiveInfinity);
+    } else {
+        jsdouble r = a / b;
+        store_number(cx, regs, n, r);
+    }
+}
+
+static inline void prim_dmod(JSContext* cx, JSRuntime* rt, JSFrameRegs& regs, int n, jsdouble& a, jsdouble& b) {
+    if (b == 0) {
+       store_stack_constant(regs, -1, DOUBLE_TO_JSVAL(rt->jsNaN));
+    } else {
+      jsdouble r;
+#ifdef XP_WIN
+      /* Workaround MS fmod bug where 42 % (1/0) => NaN, not 42. */
+      if (!(JSDOUBLE_IS_FINITE(a) && JSDOUBLE_IS_INFINITE(b)))
+          r = a;
+      else
+#endif
+        r = fmod(a, b);
+      store_number(cx, regs, n, r);
+    }
+}
+
+static inline void prim_ior(jsint& a, jsint& b, jsint& r) {
+    r = a | b;
+}
+
+static inline void prim_ixor(jsint& a, jsint& b, jsint& r) {
+    r = a ^ b;
+}
+
+static inline void prim_iand(jsint& a, jsint& b, jsint& r) {
+    r = a & b;
+}
+
+static inline void prim_ilsh(jsint& a, jsint& b, jsint& r) {
+    r = a << (b & 31);
+}
+
+static inline void prim_irsh(jsint& a, jsint& b, jsint& r) {
+    r = a >> (b & 31);
+}
+
+static inline void prim_ursh(uint32& a, jsint& b, uint32& r) {
+    r = a >> (b & 31);
+}
+
/*
* Quickly test if v is an int from the [-2**29, 2**29) range, that is, when
* the lowest bit of v is 1 and the bits 30 and 31 are both either 0 or 1. For
* such v we can do increment or decrement via adding or subtracting two
* without checking that the result overflows JSVAL_INT_MIN or JSVAL_INT_MAX.
*/
#define CAN_DO_FAST_INC_DEC(v)     (((((v) << 1) ^ v) & 0x80000001) == 1)

@@ -3716,31 +3789,31 @@ js_Interpret(JSContext *cx)
} while (0);
PUSH_STACK_OBJECT(obj);
END_CASE(JSOP_BINDNAME)

#define BITWISE_OP(OP)                                                        \
JS_BEGIN_MACRO                                                            \
FETCH_INT(cx, -2, i);                                                 \
FETCH_INT(cx, -1, j);                                                 \
-        i = i OP j;                                                           \
+        prim_##OP(i, j, i);                                                   \
STORE_INT(cx, -1, i);                                                 \
JS_END_MACRO

BEGIN_CASE(JSOP_BITOR)
-            BITWISE_OP(|);
+            BITWISE_OP(ior);
END_CASE(JSOP_BITOR)

BEGIN_CASE(JSOP_BITXOR)
-            BITWISE_OP(^);
+            BITWISE_OP(ixor);
END_CASE(JSOP_BITXOR)

BEGIN_CASE(JSOP_BITAND)
-            BITWISE_OP(&);
+            BITWISE_OP(iand);
END_CASE(JSOP_BITAND)

#define RELATIONAL_OP(OP)                                                     \
JS_BEGIN_MACRO                                                            \
FETCH_STACK(-1, rval);                                                \
FETCH_STACK(-2, lval);                                                \
/* Optimize for two int-tagged operands (typical loop control). */    \
if ((lval & rval) & JSVAL_INT) {                                      \
@@ -3917,36 +3990,36 @@ js_Interpret(JSContext *cx)

#undef EQUALITY_OP
#undef RELATIONAL_OP

#define SIGNED_SHIFT_OP(OP)                                                   \
JS_BEGIN_MACRO                                                            \
FETCH_INT(cx, -2, i);                                                 \
FETCH_INT(cx, -1, j);                                                 \
-        i = i OP (j & 31);                                                    \
+        prim_##OP(i, j, i);                                                   \
STORE_INT(cx, -1, i);                                                 \
JS_END_MACRO

BEGIN_CASE(JSOP_LSH)
-            SIGNED_SHIFT_OP(<<);
+            SIGNED_SHIFT_OP(ilsh);
END_CASE(JSOP_LSH)

BEGIN_CASE(JSOP_RSH)
-            SIGNED_SHIFT_OP(>>);
+            SIGNED_SHIFT_OP(irsh);
END_CASE(JSOP_RSH)

BEGIN_CASE(JSOP_URSH)
{
uint32 u;

FETCH_UINT(cx, -2, u);
FETCH_INT(cx, -1, j);
-            u >>= (j & 31);
+            prim_ursh(u, j, u);
STORE_UINT(cx, -1, u);
}
END_CASE(JSOP_URSH)

#undef BITWISE_OP
#undef SIGNED_SHIFT_OP

@@ -3988,78 +4061,52 @@ js_Interpret(JSContext *cx)
str = js_ConcatStrings(cx, str, str2);
if (!str)
goto error;
STORE_STACK_STRING(-1, str);
} else {
VALUE_TO_NUMBER(cx, -2, lval, d);
VALUE_TO_NUMBER(cx, -1, rval, d2);
-                    d += d2;
STORE_NUMBER(cx, -1, d);
}
}

#define BINARY_OP(OP)                                                         \
JS_BEGIN_MACRO                                                            \
FETCH_NUMBER(cx, -2, d);                                              \
FETCH_NUMBER(cx, -1, d2);                                             \
-        d = d OP d2;                                                          \
+        prim_##OP(d, d2, d);                                                  \
STORE_NUMBER(cx, -1, d);                                              \
JS_END_MACRO

BEGIN_CASE(JSOP_SUB)
-            BINARY_OP(-);
+            BINARY_OP(dsub);
END_CASE(JSOP_SUB)

BEGIN_CASE(JSOP_MUL)
-            BINARY_OP(*);
+            BINARY_OP(dmul);
END_CASE(JSOP_MUL)

BEGIN_CASE(JSOP_DIV)
FETCH_NUMBER(cx, -1, d2);
FETCH_NUMBER(cx, -2, d);
-            if (d2 == 0) {
-#ifdef XP_WIN
-                /* XXX MSVC miscompiles such that (NaN == 0) */
-                if (JSDOUBLE_IS_NaN(d2))
-                    rval = DOUBLE_TO_JSVAL(rt->jsNaN);
-                else
-#endif
-                if (d == 0 || JSDOUBLE_IS_NaN(d))
-                    rval = DOUBLE_TO_JSVAL(rt->jsNaN);
-                else if ((JSDOUBLE_HI32(d) ^ JSDOUBLE_HI32(d2)) >> 31)
-                    rval = DOUBLE_TO_JSVAL(rt->jsNegativeInfinity);
-                else
-                    rval = DOUBLE_TO_JSVAL(rt->jsPositiveInfinity);
-                STORE_STACK(-1, rval);
-            } else {
-                d /= d2;
-                STORE_NUMBER(cx, -1, d);
-            }
+            prim_ddiv(cx, rt, regs, -1, d, d2);
END_CASE(JSOP_DIV)

BEGIN_CASE(JSOP_MOD)
FETCH_NUMBER(cx, -1, d2);
FETCH_NUMBER(cx, -2, d);
-            if (d2 == 0) {
-                STORE_STACK_CONSTANT(-1, DOUBLE_TO_JSVAL(rt->jsNaN));
-            } else {
-#ifdef XP_WIN
-              /* Workaround MS fmod bug where 42 % (1/0) => NaN, not 42. */
-              if (!(JSDOUBLE_IS_FINITE(d) && JSDOUBLE_IS_INFINITE(d2)))
-#endif
-                d = fmod(d, d2);
-                STORE_NUMBER(cx, -1, d);
-            }
+            prim_dmod(cx, rt, regs, -1, d, d2);
END_CASE(JSOP_MOD)

BEGIN_CASE(JSOP_NOT)
POP_BOOLEAN(cx, rval, cond);
cond = !cond;
PUSH_STACK_BOOLEAN(cond);
END_CASE(JSOP_NOT)
```