[INFER] Merge JSOP_RSH with jsop_bitop, bug 643109. r=bhackett
authorJan de Mooij <jandemooij@gmail.com>
Thu, 24 Mar 2011 12:37:57 -0700
changeset 74846 7bfbc13e500a03b1c72822b1c22291c061938531
parent 74845 87cbe5b2742ab5d66e86d0bf3ef1a7f2f2efa33b
child 74847 3d71887519174eeea07dc5ad5aa5ba089f61f311
push id2
push userbsmedberg@mozilla.com
push dateFri, 19 Aug 2011 14:38:13 +0000
reviewersbhackett
bugs643109
milestone2.0b13pre
[INFER] Merge JSOP_RSH with jsop_bitop, bug 643109. r=bhackett
js/src/methodjit/Compiler.cpp
js/src/methodjit/Compiler.h
js/src/methodjit/FastArithmetic.cpp
js/src/methodjit/FastOps.cpp
--- a/js/src/methodjit/Compiler.cpp
+++ b/js/src/methodjit/Compiler.cpp
@@ -1423,17 +1423,17 @@ mjit::Compiler::generateMethod()
           }
           END_CASE(JSOP_GE)
 
           BEGIN_CASE(JSOP_LSH)
             jsop_bitop(op);
           END_CASE(JSOP_LSH)
 
           BEGIN_CASE(JSOP_RSH)
-            jsop_rsh();
+            jsop_bitop(op);
           END_CASE(JSOP_RSH)
 
           BEGIN_CASE(JSOP_URSH)
             jsop_bitop(op);
           END_CASE(JSOP_URSH)
 
           BEGIN_CASE(JSOP_ADD)
             if (!jsop_binary(op, stubs::Add, knownPushedType(0), pushedTypeSet(0)))
--- a/js/src/methodjit/Compiler.h
+++ b/js/src/methodjit/Compiler.h
@@ -566,26 +566,16 @@ class Compiler : public BaseCompiler
                             MaybeJump &lhsUnknownDone);
     void emitRightDoublePath(FrameEntry *lhs, FrameEntry *rhs, FrameState::BinaryAlloc &regs,
                              MaybeJump &rhsNotNumber2);
     bool tryBinaryConstantFold(JSContext *cx, FrameState &frame, JSOp op,
                                FrameEntry *lhs, FrameEntry *rhs, Value *vp);
 
     /* Fast opcodes. */
     void jsop_bitop(JSOp op);
-    void jsop_rsh();
-    RegisterID rightRegForShift(FrameEntry *rhs);
-    void jsop_rsh_int_int(FrameEntry *lhs, FrameEntry *rhs);
-    void jsop_rsh_const_int(FrameEntry *lhs, FrameEntry *rhs);
-    void jsop_rsh_int_const(FrameEntry *lhs, FrameEntry *rhs);
-    void jsop_rsh_int_unknown(FrameEntry *lhs, FrameEntry *rhs);
-    void jsop_rsh_const_const(FrameEntry *lhs, FrameEntry *rhs);
-    void jsop_rsh_const_unknown(FrameEntry *lhs, FrameEntry *rhs);
-    void jsop_rsh_unknown_const(FrameEntry *lhs, FrameEntry *rhs);
-    void jsop_rsh_unknown_any(FrameEntry *lhs, FrameEntry *rhs);
     bool jsop_mod();
     void jsop_neg();
     void jsop_bitnot();
     void jsop_not();
     void jsop_typeof();
     bool booleanJumpScript(JSOp op, jsbytecode *target);
     bool jsop_ifneq(JSOp op, jsbytecode *target);
     bool jsop_andor(JSOp op, jsbytecode *target);
--- a/js/src/methodjit/FastArithmetic.cpp
+++ b/js/src/methodjit/FastArithmetic.cpp
@@ -76,20 +76,16 @@ mjit::Compiler::tryBinaryConstantFold(JS
         needInt = false;
         break;
 
       case JSOP_MOD:
         needInt = (L.isInt32() && R.isInt32() &&
                    L.toInt32() >= 0 && R.toInt32() > 0);
         break;
 
-      case JSOP_RSH:
-        needInt = true;
-        break;
-
       default:
         JS_NOT_REACHED("NYI");
         needInt = false; /* Silence compiler warning. */
         break;
     }
 
     double dL = 0, dR = 0;
     int32_t nL = 0, nR = 0;
@@ -136,20 +132,16 @@ mjit::Compiler::tryBinaryConstantFold(JS
         if (needInt)
             nL %= nR;
         else if (dR == 0)
             dL = js_NaN;
         else
             dL = js_fmod(dL, dR);
         break;
 
-      case JSOP_RSH:
-        nL >>= (nR & 31);
-        break;
-
       default:
         JS_NOT_REACHED("NYI");
         break;
     }
 
     if (needInt)
         vp->setInt32(nL);
     else
--- a/js/src/methodjit/FastOps.cpp
+++ b/js/src/methodjit/FastOps.cpp
@@ -53,76 +53,16 @@
 
 #include "jsautooplen.h"
 
 using namespace js;
 using namespace js::mjit;
 
 typedef JSC::MacroAssembler::RegisterID RegisterID;
 
-RegisterID
-mjit::Compiler::rightRegForShift(FrameEntry *rhs)
-{
-#if defined(JS_CPU_X86) || defined(JS_CPU_X64)
-    /*
-     * Gross: RHS _must_ be in ECX, on x86.
-     * Note that we take this first so that we can't up with other register
-     * allocations (below) owning ecx before rhs.
-     */
-    RegisterID reg = JSC::X86Registers::ecx;
-    if (!rhs->isConstant())
-        frame.copyDataIntoReg(rhs, reg);
-    return reg;
-#else
-    if (rhs->isConstant())
-        return frame.allocReg();
-    return frame.copyDataIntoReg(rhs);
-#endif
-}
-
-void
-mjit::Compiler::jsop_rsh_const_int(FrameEntry *lhs, FrameEntry *rhs)
-{
-    RegisterID rhsData = rightRegForShift(rhs);
-    RegisterID result = frame.allocReg();
-    masm.move(Imm32(lhs->getValue().toInt32()), result);
-    masm.rshift32(rhsData, result);
-
-    frame.freeReg(rhsData);
-    frame.popn(2);
-    frame.pushTypedPayload(JSVAL_TYPE_INT32, result);
-}
-
-void
-mjit::Compiler::jsop_rsh_int_int(FrameEntry *lhs, FrameEntry *rhs)
-{
-    RegisterID rhsData = rightRegForShift(rhs);
-    RegisterID lhsData = frame.copyDataIntoReg(lhs);
-    masm.rshift32(rhsData, lhsData);
-    frame.freeReg(rhsData);
-    frame.popn(2);
-    frame.pushTypedPayload(JSVAL_TYPE_INT32, lhsData);
-}
-
-void
-mjit::Compiler::jsop_rsh_int_const(FrameEntry *lhs, FrameEntry *rhs)
-{
-    int32 shiftAmount = rhs->getValue().toInt32();
-
-    if (!shiftAmount) {
-        frame.pop();
-        return;
-    }
-
-    RegisterID result = frame.copyDataIntoReg(lhs);
-    masm.rshift32(Imm32(shiftAmount), result);
-    frame.popn(2);
-    frame.pushTypedPayload(JSVAL_TYPE_INT32, result);
-}
-
 void
 mjit::Compiler::ensureInteger(FrameEntry *fe, Uses uses)
 {
     if (fe->isConstant()) {
         if (!fe->isType(JSVAL_TYPE_INT32)) {
             JS_ASSERT(fe->isType(JSVAL_TYPE_DOUBLE));
             fe->convertConstantDoubleToInt32(cx);
         }
@@ -175,57 +115,16 @@ mjit::Compiler::ensureInteger(FrameEntry
         intGuard.linkTo(masm.label(), &masm);
 
         frame.freeReg(fpreg);
         frame.learnType(fe, JSVAL_TYPE_INT32, dataReg);
     }
 }
 
 void
-mjit::Compiler::jsop_rsh()
-{
-    FrameEntry *rhs = frame.peek(-1);
-    FrameEntry *lhs = frame.peek(-2);
-
-    Value v;
-    if (tryBinaryConstantFold(cx, frame, JSOP_RSH, lhs, rhs, &v)) {
-        JS_ASSERT(v.isInt32());
-        frame.popn(2);
-        frame.push(v);
-        return;
-    }
-
-    if ((lhs->isNotType(JSVAL_TYPE_INT32) && lhs->isNotType(JSVAL_TYPE_DOUBLE)) ||
-        (rhs->isNotType(JSVAL_TYPE_INT32) && rhs->isNotType(JSVAL_TYPE_DOUBLE))) {
-        prepareStubCall(Uses(2));
-        INLINE_STUBCALL(stubs::Rsh);
-        frame.popn(2);
-        frame.pushSynced(JSVAL_TYPE_INT32);
-        return;
-    }
-
-    ensureInteger(lhs, Uses(2));
-    ensureInteger(rhs, Uses(2));
-
-    stubcc.leave();
-    OOL_STUBCALL(stubs::Rsh);
-
-    JS_ASSERT(!(lhs->isConstant() && rhs->isConstant()));
-    if (lhs->isConstant()) {
-        jsop_rsh_const_int(lhs, rhs);
-    } else if (rhs->isConstant()) {
-        jsop_rsh_int_const(lhs, rhs);
-    } else {
-        jsop_rsh_int_int(lhs, rhs);
-    }
-
-    stubcc.rejoin(Changes(1));
-}
-
-void
 mjit::Compiler::jsop_bitnot()
 {
     FrameEntry *top = frame.peek(-1);
 
     /* We only want to handle integers here. */
     if (top->isTypeKnown() && top->getKnownType() != JSVAL_TYPE_INT32) {
         prepareStubCall(Uses(1));
         INLINE_STUBCALL(stubs::BitNot);
@@ -272,16 +171,19 @@ mjit::Compiler::jsop_bitop(JSOp op)
         stub = stubs::BitAnd;
         break;
       case JSOP_BITXOR:
         stub = stubs::BitXor;
         break;
       case JSOP_LSH:
         stub = stubs::Lsh;
         break;
+      case JSOP_RSH:
+        stub = stubs::Rsh;
+        break;
       case JSOP_URSH:
         stub = stubs::Ursh;
         break;
       default:
         JS_NOT_REACHED("wat");
         return;
     }
 
@@ -334,19 +236,22 @@ mjit::Compiler::jsop_bitop(JSOp op)
             return;
           case JSOP_BITXOR:
             frame.push(Int32Value(L ^ R));
             return;
           case JSOP_BITAND:
             frame.push(Int32Value(L & R));
             return;
           case JSOP_LSH:
-            frame.push(Int32Value(L << R));
+            frame.push(Int32Value(L << (R & 31)));
             return;
-          case JSOP_URSH: 
+          case JSOP_RSH:
+            frame.push(Int32Value(L >> (R & 31)));
+            return;
+          case JSOP_URSH:
           {
             uint32 unsignedL;
             if (ValueToECMAUint32(cx, lhs->getValue(), (uint32_t*)&unsignedL)) {
                 Value v = NumberValue(uint32(unsignedL >> (R & 31)));
                 JS_ASSERT(v.isInt32());
                 frame.push(v);
                 return;
             }
@@ -396,29 +301,32 @@ mjit::Compiler::jsop_bitop(JSOp op)
             else
                 masm.or32(rhsReg, reg);
         }
 
         break;
       }
 
       case JSOP_LSH:
+      case JSOP_RSH:
       case JSOP_URSH:
       {
         /* Not commutative. */
         if (rhs->isConstant()) {
             RegisterID reg = frame.ownRegForData(lhs);
             int shift = rhs->getValue().toInt32() & 0x1F;
 
             stubcc.leave();
             OOL_STUBCALL(stub);
 
             if (shift) {
                 if (op == JSOP_LSH)
                     masm.lshift32(Imm32(shift), reg);
+                else if (op == JSOP_RSH)
+                    masm.rshift32(Imm32(shift), reg);
                 else
                     masm.urshift32(Imm32(shift), reg);
             }
             frame.popn(2);
             
             /* x >>> 0 may result in a double, handled above. */
             JS_ASSERT_IF(op == JSOP_URSH, shift >= 1);
             frame.pushTypedPayload(JSVAL_TYPE_INT32, reg);
@@ -448,16 +356,18 @@ mjit::Compiler::jsop_bitop(JSOp op)
             } else {
                 reg = frame.copyDataIntoReg(lhs);
             }
             frame.unpinReg(rr);
         }
         
         if (op == JSOP_LSH) {
             masm.lshift32(rr, reg);
+        } else if (op == JSOP_RSH) {
+            masm.rshift32(rr, reg);
         } else {
             masm.urshift32(rr, reg);
             
             Jump isNegative = masm.branch32(Assembler::LessThan, reg, Imm32(0));
             stubcc.linkExit(isNegative, Uses(2));
         }
         break;
       }