Bug 592631: fast path for x|0, r=dvander
authorJan de Mooij <jandemooij@gmail.com>
Wed, 08 Sep 2010 18:23:27 -0700
changeset 53613 ae6ca63c34c3dc1507f666e665d50bcbaa478bb6
parent 53612 557c44a519a7d59d534c72c6f78387aac810f9ec
child 53614 03fbde5c25b60a9efe1fc4b06a6f562e6ba10cb8
push idunknown
push userunknown
push dateunknown
reviewersdvander
bugs592631
milestone2.0b6pre
Bug 592631: fast path for x|0, r=dvander
js/src/methodjit/FastOps.cpp
--- a/js/src/methodjit/FastOps.cpp
+++ b/js/src/methodjit/FastOps.cpp
@@ -335,16 +335,51 @@ mjit::Compiler::jsop_bitop(JSOp op)
       case JSOP_URSH:
         stub = stubs::Ursh;
         break;
       default:
         JS_NOT_REACHED("wat");
         return;
     }
 
+    bool lhsIntOrDouble = !(lhs->isNotType(JSVAL_TYPE_DOUBLE) && 
+                            lhs->isNotType(JSVAL_TYPE_INT32));
+    
+    /* Fast-path double to int conversion. */
+    if (!lhs->isConstant() && rhs->isConstant() && lhsIntOrDouble &&
+        rhs->isType(JSVAL_TYPE_INT32) && rhs->getValue().toInt32() == 0 &&
+        (op == JSOP_BITOR || op == JSOP_LSH)) {
+        RegisterID reg = frame.copyDataIntoReg(lhs);
+        if (lhs->isType(JSVAL_TYPE_INT32)) {
+            frame.popn(2);
+            frame.pushTypedPayload(JSVAL_TYPE_INT32, reg);
+            return;
+        }
+        MaybeJump isInt;
+        if (!lhs->isType(JSVAL_TYPE_DOUBLE)) {
+            RegisterID typeReg = frame.tempRegForType(lhs);
+            isInt = masm.testInt32(Assembler::Equal, typeReg);
+            Jump notDouble = masm.testDouble(Assembler::NotEqual, typeReg);
+            stubcc.linkExit(notDouble, Uses(2));
+        }
+        frame.loadDouble(lhs, FPRegisters::First, masm);
+        
+        Jump truncateGuard = masm.branchTruncateDoubleToInt32(FPRegisters::First, reg);
+        stubcc.linkExit(truncateGuard, Uses(2));
+        stubcc.leave();
+        stubcc.call(stub);
+        
+        if (isInt.isSet())
+            isInt.get().linkTo(masm.label(), &masm);
+        frame.popn(2);
+        frame.pushTypedPayload(JSVAL_TYPE_INT32, reg);
+        stubcc.rejoin(Changes(1));
+        return;
+    }
+
     /* We only want to handle integers here. */
     if (rhs->isNotType(JSVAL_TYPE_INT32) || lhs->isNotType(JSVAL_TYPE_INT32) || 
         (op == JSOP_URSH && rhs->isConstant() && rhs->getValue().toInt32() % 32 == 0)) {
         prepareStubCall(Uses(2));
         stubCall(stub);
         frame.popn(2);
         if (op == JSOP_URSH)
             frame.pushSynced();