Index: src/arm/lithium-codegen-arm.cc |
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc |
index 5baed365c0b3922ad98623329a86737c1c71d0d9..99cec39d78ddfdb8a7b6c177b74b19ce821e5bfa 100644 |
--- a/src/arm/lithium-codegen-arm.cc |
+++ b/src/arm/lithium-codegen-arm.cc |
@@ -1038,6 +1038,25 @@ void LCodeGen::DoModI(LModI* instr) { |
__ bind(&ok); |
} |
+ // Try a few common cases before using the generic stub. |
Søren Thygesen Gjesse
2011/01/18 15:58:38
Maybe extend this comment a bit (it took me some t
Karl Klose
2011/01/20 02:12:12
Done.
|
+ const int kUnfolds = 3; |
+ __ mov(scratch, left); |
+ for (int i = 0; i < kUnfolds; i++) { |
+ // Check if the left hand side is less or equal. |
+ if (i == 0) __ cmp(scratch, right); |
+ __ mov(result, scratch, LeaveCC, le); |
+ __ b(le, &done); |
+ if (i < kUnfolds - 1) __ sub(scratch, left, right); |
Søren Thygesen Gjesse
2011/01/18 15:58:38
Shouldn't this be
__ sub(scratch, scratch, right,
Karl Klose
2011/01/20 02:12:12
Thanks for the catch.
On 2011/01/18 15:58:38, Søre
|
+ } |
+ |
+ // Check for power of two on the right hand side. |
Søren Thygesen Gjesse
2011/01/18 15:58:38
I think the code we have in GenericBinaryOpStub do
Karl Klose
2011/01/20 02:12:12
Done.
|
+ const int kMaxPowerOfTwo = 32; |
+ for (int i = 2; i <= kMaxPowerOfTwo; i <<= 1) { |
+ __ cmp(right, Operand(i)); |
+ __ and_(result, left, Operand(i-1), LeaveCC, eq); |
+ __ b(&done, eq); |
+ } |
+ |
// 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); |
@@ -1049,7 +1068,7 @@ void LCodeGen::DoModI(LModI* instr) { |
// 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); |