Revision: 6421
Author: [email protected]
Date: Thu Jan 20 09:42:29 2011
Log: Implement fast code for the common cases of left hand sides that are less than three times larger as the right hand side and and right hand sides that are powers of two up and including 32.

In the covered special cases the result is computed directly, else the generic stub is called. The implementation deoptimizes only for mod 0 and if the result may be a negative zero.

BUG=none
TEST=none

Review URL: http://codereview.chromium.org/6331005
http://code.google.com/p/v8/source/detail?r=6421

Modified:
 /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc

=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Thu Jan 20 06:20:54 2011 +++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Thu Jan 20 09:42:29 2011
@@ -1039,6 +1039,37 @@
     __ bind(&ok);
   }

+  // Try a few common cases before using the generic stub.
+  Label call_stub;
+  const int kUnfolds = 3;
+  // Skip if either side is negative.
+  __ cmp(left, Operand(0));
+  __ cmp(right, Operand(0), NegateCondition(mi));
+  __ b(mi, &call_stub);
+  // If the right hand side is smaller than the (nonnegative)
+  // left hand side, it is the result. Else try a few subtractions
+  // of the left hand side.
+  __ mov(scratch, left);
+  for (int i = 0; i < kUnfolds; i++) {
+    // Check if the left hand side is less or equal than the
+    // the right hand side.
+    __ cmp(scratch, right);
+    __ mov(result, scratch, LeaveCC, lt);
+    __ b(lt, &done);
+    // If not, reduce the left hand side by the right hand
+    // side and check again.
+    if (i < kUnfolds - 1) __ sub(scratch, scratch, right);
+  }
+
+  // Check for power of two on the right hand side.
+  __ sub(scratch, right, Operand(1), SetCC);
+  __ b(mi, &call_stub);
+  __ tst(scratch, right);
+  __ b(ne, &call_stub);
+  // Perform modulo operation.
+  __ and_(result, scratch, Operand(left));
+
+  __ bind(&call_stub);
   // Call the generic stub. The numbers in r0 and r1 have
   // to be tagged to Smis. If that is not possible, deoptimize.
   DeferredModI* deferred = new DeferredModI(this, instr);
@@ -1050,7 +1081,7 @@

   // If the result in r0 is a Smi, untag it, else deoptimize.
   __ BranchOnNotSmi(result, &deoptimize);
-  __ mov(result, Operand(result, ASR, 1));
+  __ SmiUntag(result);

   __ b(al, &done);
   __ bind(&deoptimize);

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to