| Index: src/ia32/codegen-ia32.cc
|
| ===================================================================
|
| --- src/ia32/codegen-ia32.cc (revision 4124)
|
| +++ src/ia32/codegen-ia32.cc (working copy)
|
| @@ -1468,12 +1468,41 @@
|
| left->number_info(),
|
| right->number_info(),
|
| overwrite_mode);
|
| - CheckTwoForSminess(masm_, left->reg(), right->reg(), answer.reg(),
|
| - left->number_info(), right->number_info(), deferred);
|
|
|
| - // Untag both operands.
|
| - __ mov(answer.reg(), left->reg());
|
| - __ SmiUntag(answer.reg());
|
| + Label do_op, left_nonsmi;
|
| + // if right is a smi we make a fast case if left is either a smi
|
| + // or a heapnumber.
|
| + if (CpuFeatures::IsSupported(SSE2) && right->number_info().IsSmi()) {
|
| + __ mov(answer.reg(), left->reg());
|
| + // Fast case - both are actually smis.
|
| + if (!left->number_info().IsSmi()) {
|
| + __ test(answer.reg(), Immediate(kSmiTagMask));
|
| + __ j(not_zero, &left_nonsmi);
|
| + }
|
| + __ SmiUntag(answer.reg());
|
| + __ jmp(&do_op);
|
| +
|
| + __ bind(&left_nonsmi);
|
| + // Branch if not a heapnumber.
|
| + __ cmp(FieldOperand(answer.reg(), HeapObject::kMapOffset),
|
| + Factory::heap_number_map());
|
| + deferred->Branch(not_equal);
|
| +
|
| + // Load integer value into answer register using truncation.
|
| + __ cvttsd2si(answer.reg(),
|
| + FieldOperand(answer.reg(), HeapNumber::kValueOffset));
|
| + // Branch if we do not fit in a smi.
|
| + __ cmp(answer.reg(), 0xc0000000);
|
| + deferred->Branch(negative);
|
| + } else {
|
| + CheckTwoForSminess(masm_, left->reg(), right->reg(), answer.reg(),
|
| + left->number_info(), right->number_info(), deferred);
|
| +
|
| + // Untag both operands.
|
| + __ mov(answer.reg(), left->reg());
|
| + __ SmiUntag(answer.reg());
|
| + }
|
| +
|
| __ SmiUntag(ecx);
|
| // Perform the operation.
|
| switch (op) {
|
|
|