Chromium Code Reviews| Index: src/ia32/codegen-ia32.cc |
| =================================================================== |
| --- src/ia32/codegen-ia32.cc (revision 3485) |
| +++ src/ia32/codegen-ia32.cc (working copy) |
| @@ -1791,7 +1791,8 @@ |
| } |
| -void CodeGenerator::Comparison(Condition cc, |
| +void CodeGenerator::Comparison(AstNode* node, |
| + Condition cc, |
| bool strict, |
| ControlDestination* dest) { |
| // Strict only makes sense for equality comparisons. |
| @@ -1838,7 +1839,8 @@ |
| default: |
| UNREACHABLE(); |
| } |
| - } else { // Only one side is a constant Smi. |
| + } else { |
| + // Only one side is a constant Smi. |
| // If left side is a constant Smi, reverse the operands. |
| // Since one side is a constant Smi, conversion order does not matter. |
| if (left_side_constant_smi) { |
| @@ -1852,6 +1854,8 @@ |
| // Implement comparison against a constant Smi, inlining the case |
| // where both sides are Smis. |
| left_side.ToRegister(); |
| + Register left_reg = left_side.reg(); |
| + Handle<Object> right_val = right_side.handle(); |
| // Here we split control flow to the stub call and inlined cases |
| // before finally splitting it to the control destination. We use |
| @@ -1859,11 +1863,49 @@ |
| // the first split. We manually handle the off-frame references |
| // by reconstituting them on the non-fall-through path. |
| JumpTarget is_smi; |
| - Register left_reg = left_side.reg(); |
| - Handle<Object> right_val = right_side.handle(); |
| __ test(left_side.reg(), Immediate(kSmiTagMask)); |
| is_smi.Branch(zero, taken); |
| + bool is_for_loop_compare = node->AsCompareOperation() |
|
iposva
2009/12/17 21:03:50
Shouldn't you do a " != NULL" here?
bakster
2009/12/18 06:38:47
Done.
|
| + && node->AsCompareOperation()->is_for_loop_condition(); |
| + if (!is_for_loop_compare |
| + && CpuFeatures::IsSupported(SSE2) |
| + && right_val->IsSmi()) { |
| + // The right side value is either a smi or heap number. |
|
iposva
2009/12/17 21:03:50
Comment does not match the check. Right side is a
bakster
2009/12/18 06:38:47
Done.
|
| + CpuFeatures::Scope use_sse2(SSE2); |
| + JumpTarget not_number; |
| + __ cmp(FieldOperand(left_reg, HeapObject::kMapOffset), |
| + Immediate(Factory::heap_number_map())); |
| + not_number.Branch(not_equal, &left_side); |
| + __ movdbl(xmm1, |
| + FieldOperand(left_reg, HeapNumber::kValueOffset)); |
| + int value = Smi::cast(*right_val)->value(); |
| + if (value == 0) { |
| + __ xorpd(xmm0, xmm0); |
| + } else { |
| + Result temp = allocator()->Allocate(); |
| + __ mov (temp.reg(), Immediate(value)); |
| + __ cvtsi2sd(xmm0, Operand(temp.reg())); |
|
iposva
2009/12/17 21:03:50
Why do you keep converting the value to double fro
bakster
2009/12/18 06:38:47
I'm not sure it makes a difference. I'll try the o
|
| + temp.Unuse(); |
| + } |
| + __ comisd(xmm1, xmm0); |
| + // Jump to builtin for NaN. |
| + not_number.Branch(parity_even, &left_side); |
| + left_side.Unuse(); |
| + Condition double_cc = cc; |
| + switch (cc) { |
| + case less: double_cc = below; break; |
| + case equal: double_cc = equal; break; |
| + case less_equal: double_cc = below_equal; break; |
| + case greater: double_cc = above; break; |
| + case greater_equal: double_cc = above_equal; break; |
| + default: UNREACHABLE(); |
| + } |
| + dest->true_target()->Branch(double_cc); |
| + dest->false_target()->Jump(); |
| + not_number.Bind(&left_side); |
| + } |
| + |
| // Setup and call the compare stub. |
| CompareStub stub(cc, strict); |
| Result result = frame_->CallStub(&stub, &left_side, &right_side); |
| @@ -1887,6 +1929,7 @@ |
| right_side.Unuse(); |
| dest->Split(cc); |
| } |
| + |
| } else if (cc == equal && |
| (left_side_constant_null || right_side_constant_null)) { |
| // To make null checks efficient, we check if either the left side or |
| @@ -1923,7 +1966,8 @@ |
| operand.Unuse(); |
| dest->Split(not_zero); |
| } |
| - } else { // Neither side is a constant Smi or null. |
| + } else { |
| + // Neither side is a constant Smi or null. |
| // If either side is a non-smi constant, skip the smi check. |
| bool known_non_smi = |
| (left_side.is_constant() && !left_side.handle()->IsSmi()) || |
| @@ -2590,7 +2634,7 @@ |
| // Compare and branch to the body if true or the next test if |
| // false. Prefer the next test as a fall through. |
| ControlDestination dest(clause->body_target(), &next_test, false); |
| - Comparison(equal, true, &dest); |
| + Comparison(node, equal, true, &dest); |
| // If the comparison fell through to the true target, jump to the |
| // actual body. |
| @@ -6003,7 +6047,7 @@ |
| } |
| Load(left); |
| Load(right); |
| - Comparison(cc, strict, destination()); |
| + Comparison(node, cc, strict, destination()); |
| } |
| @@ -6802,7 +6846,7 @@ |
| __ push(left); |
| __ push(Immediate(right)); |
| } else { |
| - // The calling convention with registers is left in edx and right in eax. |
| + // The calling convention with registers is left in edx and right in eax. |
|
iposva
2009/12/17 21:03:50
Unmotivated space?
bakster
2009/12/18 06:38:47
Done.
|
| Register left_arg = edx; |
| Register right_arg = eax; |
| if (left.is(left_arg)) { |