Index: src/ia32/codegen-ia32.cc |
=================================================================== |
--- src/ia32/codegen-ia32.cc (revision 2211) |
+++ src/ia32/codegen-ia32.cc (working copy) |
@@ -1387,7 +1387,10 @@ |
void DeferredInlineSmiOperation::Generate() { |
__ push(src_); |
__ push(Immediate(value_)); |
- GenericBinaryOpStub stub(op_, overwrite_mode_, SMI_CODE_INLINED); |
+ GenericBinaryFlags flags = SMI_CODE_INLINED; |
+ // For mod we don't generate all the Smi code inline. |
+ if (op_ == Token::MOD) flags = SMI_CODE_IN_STUB; |
+ GenericBinaryOpStub stub(op_, overwrite_mode_, flags); |
Kevin Millikin (Chromium)
2009/06/18 07:23:49
You could write this:
GenericBinaryFlags flags =
|
__ CallStub(&stub); |
if (!dst_.is(eax)) __ mov(dst_, eax); |
} |
@@ -1772,6 +1775,33 @@ |
break; |
} |
+ // Generate inline code for mod of powers of 2 and negative powers of 2. |
+ case Token::MOD: |
+ if (!reversed && |
+ int_value != 0 && |
+ (IsPowerOf2(int_value) || IsPowerOf2(-int_value))) { |
+ operand->ToRegister(); |
+ frame_->Spill(operand->reg()); |
+ DeferredCode* deferred = new DeferredInlineSmiOperation(op, |
+ operand->reg(), |
+ operand->reg(), |
+ smi_value, |
+ overwrite_mode); |
+ // Check for negative or non-Smi left hand side. |
+ __ test(operand->reg(), Immediate(kSmiTagMask | 0x80000000)); |
+ deferred->Branch(not_zero); |
+ if (int_value < 0) int_value = -int_value; |
+ if (int_value == 1) { |
+ __ mov(operand->reg(), Immediate(Smi::FromInt(0))); |
+ } else { |
+ __ and_(operand->reg(), (int_value << kSmiTagSize) - 1); |
+ } |
+ deferred->BindExit(); |
+ frame_->Push(operand); |
+ break; |
+ } |
+ // Fall through if we did not find a power of 2 on the right hand side! |
+ |
default: { |
Result constant_operand(value); |
if (reversed) { |