| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 2479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2490 Register left_reg = left_side.reg(); | 2490 Register left_reg = left_side.reg(); |
| 2491 Handle<Object> right_val = right_side.handle(); | 2491 Handle<Object> right_val = right_side.handle(); |
| 2492 | 2492 |
| 2493 // Here we split control flow to the stub call and inlined cases | 2493 // Here we split control flow to the stub call and inlined cases |
| 2494 // before finally splitting it to the control destination. We use | 2494 // before finally splitting it to the control destination. We use |
| 2495 // a jump target and branching to duplicate the virtual frame at | 2495 // a jump target and branching to duplicate the virtual frame at |
| 2496 // the first split. We manually handle the off-frame references | 2496 // the first split. We manually handle the off-frame references |
| 2497 // by reconstituting them on the non-fall-through path. | 2497 // by reconstituting them on the non-fall-through path. |
| 2498 | 2498 |
| 2499 if (left_side.is_smi()) { | 2499 if (left_side.is_smi()) { |
| 2500 if (FLAG_debug_code) __ AbortIfNotSmi(left_side.reg()); | 2500 if (FLAG_debug_code) { |
| 2501 __ AbortIfNotSmi(left_side.reg()); |
| 2502 } |
| 2501 } else { | 2503 } else { |
| 2502 JumpTarget is_smi; | 2504 JumpTarget is_smi; |
| 2503 __ test(left_side.reg(), Immediate(kSmiTagMask)); | 2505 __ test(left_side.reg(), Immediate(kSmiTagMask)); |
| 2504 is_smi.Branch(zero, taken); | 2506 is_smi.Branch(zero, taken); |
| 2505 | 2507 |
| 2506 bool is_loop_condition = (node->AsExpression() != NULL) && | 2508 bool is_loop_condition = (node->AsExpression() != NULL) && |
| 2507 node->AsExpression()->is_loop_condition(); | 2509 node->AsExpression()->is_loop_condition(); |
| 2508 if (!is_loop_condition && | 2510 if (!is_loop_condition && |
| 2509 CpuFeatures::IsSupported(SSE2) && | 2511 CpuFeatures::IsSupported(SSE2) && |
| 2510 right_val->IsSmi()) { | 2512 right_val->IsSmi()) { |
| 2511 // Right side is a constant smi and left side has been checked | 2513 // Right side is a constant smi and left side has been checked |
| 2512 // not to be a smi. | 2514 // not to be a smi. |
| 2513 CpuFeatures::Scope use_sse2(SSE2); | 2515 CpuFeatures::Scope use_sse2(SSE2); |
| 2514 JumpTarget not_number; | 2516 JumpTarget not_number; |
| 2515 __ cmp(FieldOperand(left_reg, HeapObject::kMapOffset), | 2517 __ cmp(FieldOperand(left_reg, HeapObject::kMapOffset), |
| 2516 Immediate(Factory::heap_number_map())); | 2518 Immediate(Factory::heap_number_map())); |
| 2517 not_number.Branch(not_equal, &left_side); | 2519 not_number.Branch(not_equal, &left_side); |
| 2518 __ movdbl(xmm1, | 2520 __ movdbl(xmm1, |
| 2519 FieldOperand(left_reg, HeapNumber::kValueOffset)); | 2521 FieldOperand(left_reg, HeapNumber::kValueOffset)); |
| 2520 int value = Smi::cast(*right_val)->value(); | 2522 int value = Smi::cast(*right_val)->value(); |
| 2521 if (value == 0) { | 2523 if (value == 0) { |
| 2522 __ xorpd(xmm0, xmm0); | 2524 __ xorpd(xmm0, xmm0); |
| 2523 } else { | 2525 } else { |
| 2524 Result temp = allocator()->Allocate(); | 2526 Result temp = allocator()->Allocate(); |
| 2525 __ mov(temp.reg(), Immediate(value)); | 2527 __ mov(temp.reg(), Immediate(value)); |
| 2526 __ cvtsi2sd(xmm0, Operand(temp.reg())); | 2528 __ cvtsi2sd(xmm0, Operand(temp.reg())); |
| 2527 temp.Unuse(); | 2529 temp.Unuse(); |
| 2528 } | 2530 } |
| 2529 __ comisd(xmm1, xmm0); | 2531 __ ucomisd(xmm1, xmm0); |
| 2530 // Jump to builtin for NaN. | 2532 // Jump to builtin for NaN. |
| 2531 not_number.Branch(parity_even, &left_side); | 2533 not_number.Branch(parity_even, &left_side); |
| 2532 left_side.Unuse(); | 2534 left_side.Unuse(); |
| 2533 dest->true_target()->Branch(DoubleCondition(cc)); | 2535 dest->true_target()->Branch(DoubleCondition(cc)); |
| 2534 dest->false_target()->Jump(); | 2536 dest->false_target()->Jump(); |
| 2535 not_number.Bind(&left_side); | 2537 not_number.Bind(&left_side); |
| 2536 } | 2538 } |
| 2537 | 2539 |
| 2538 // Setup and call the compare stub. | 2540 // Setup and call the compare stub. |
| 2539 CompareStub stub(cc, strict, kCantBothBeNaN); | 2541 CompareStub stub(cc, strict, kCantBothBeNaN); |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2810 | 2812 |
| 2811 // Inline number comparison. | 2813 // Inline number comparison. |
| 2812 if (inline_number_compare) { | 2814 if (inline_number_compare) { |
| 2813 GenerateInlineNumberComparison(&left_side, &right_side, cc, dest); | 2815 GenerateInlineNumberComparison(&left_side, &right_side, cc, dest); |
| 2814 } | 2816 } |
| 2815 | 2817 |
| 2816 // End of in-line compare, call out to the compare stub. Don't include | 2818 // End of in-line compare, call out to the compare stub. Don't include |
| 2817 // number comparison in the stub if it was inlined. | 2819 // number comparison in the stub if it was inlined. |
| 2818 CompareStub stub(cc, strict, nan_info, !inline_number_compare); | 2820 CompareStub stub(cc, strict, nan_info, !inline_number_compare); |
| 2819 Result answer = frame_->CallStub(&stub, &left_side, &right_side); | 2821 Result answer = frame_->CallStub(&stub, &left_side, &right_side); |
| 2820 if (cc == equal) { | 2822 __ test(answer.reg(), Operand(answer.reg())); |
| 2821 __ test(answer.reg(), Operand(answer.reg())); | |
| 2822 } else { | |
| 2823 __ cmp(answer.reg(), 0); | |
| 2824 } | |
| 2825 answer.Unuse(); | 2823 answer.Unuse(); |
| 2826 dest->true_target()->Branch(cc); | 2824 dest->true_target()->Branch(cc); |
| 2827 dest->false_target()->Jump(); | 2825 dest->false_target()->Jump(); |
| 2828 | 2826 |
| 2829 is_smi.Bind(); | 2827 is_smi.Bind(); |
| 2830 left_side = Result(left_reg); | 2828 left_side = Result(left_reg); |
| 2831 right_side = Result(right_reg); | 2829 right_side = Result(right_reg); |
| 2832 __ cmp(left_side.reg(), Operand(right_side.reg())); | 2830 __ cmp(left_side.reg(), Operand(right_side.reg())); |
| 2833 right_side.Unuse(); | 2831 right_side.Unuse(); |
| 2834 left_side.Unuse(); | 2832 left_side.Unuse(); |
| (...skipping 10365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13200 | 13198 |
| 13201 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) | 13199 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) |
| 13202 // tagged as a small integer. | 13200 // tagged as a small integer. |
| 13203 __ bind(&runtime); | 13201 __ bind(&runtime); |
| 13204 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); | 13202 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); |
| 13205 } | 13203 } |
| 13206 | 13204 |
| 13207 #undef __ | 13205 #undef __ |
| 13208 | 13206 |
| 13209 } } // namespace v8::internal | 13207 } } // namespace v8::internal |
| OLD | NEW |