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 |