Implement fast code for the common cases of left hand sides that are less than...

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6421 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 5b2dff98
...@@ -1039,6 +1039,37 @@ void LCodeGen::DoModI(LModI* instr) { ...@@ -1039,6 +1039,37 @@ void LCodeGen::DoModI(LModI* instr) {
__ bind(&ok); __ 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 // Call the generic stub. The numbers in r0 and r1 have
// to be tagged to Smis. If that is not possible, deoptimize. // to be tagged to Smis. If that is not possible, deoptimize.
DeferredModI* deferred = new DeferredModI(this, instr); DeferredModI* deferred = new DeferredModI(this, instr);
...@@ -1050,7 +1081,7 @@ void LCodeGen::DoModI(LModI* instr) { ...@@ -1050,7 +1081,7 @@ void LCodeGen::DoModI(LModI* instr) {
// If the result in r0 is a Smi, untag it, else deoptimize. // If the result in r0 is a Smi, untag it, else deoptimize.
__ BranchOnNotSmi(result, &deoptimize); __ BranchOnNotSmi(result, &deoptimize);
__ mov(result, Operand(result, ASR, 1)); __ SmiUntag(result);
__ b(al, &done); __ b(al, &done);
__ bind(&deoptimize); __ bind(&deoptimize);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment