Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(440)

Side by Side Diff: src/ia32/code-stubs-ia32.cc

Issue 277963002: Require CMOV support for the ia32 port. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/assembler-ia32.cc ('k') | src/ia32/macro-assembler-ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "v8.h" 5 #include "v8.h"
6 6
7 #if V8_TARGET_ARCH_IA32 7 #if V8_TARGET_ARCH_IA32
8 8
9 #include "bootstrapper.h" 9 #include "bootstrapper.h"
10 #include "code-stubs.h" 10 #include "code-stubs.h"
(...skipping 597 matching lines...) Expand 10 before | Expand all | Expand 10 after
608 } else { 608 } else {
609 __ mov(result_reg, exponent_operand); 609 __ mov(result_reg, exponent_operand);
610 } 610 }
611 __ and_(result_reg, 611 __ and_(result_reg,
612 Immediate(static_cast<uint32_t>(Double::kSignificandMask >> 32))); 612 Immediate(static_cast<uint32_t>(Double::kSignificandMask >> 32)));
613 __ add(result_reg, 613 __ add(result_reg,
614 Immediate(static_cast<uint32_t>(Double::kHiddenBit >> 32))); 614 Immediate(static_cast<uint32_t>(Double::kHiddenBit >> 32)));
615 __ shrd(result_reg, scratch1); 615 __ shrd(result_reg, scratch1);
616 __ shr_cl(result_reg); 616 __ shr_cl(result_reg);
617 __ test(ecx, Immediate(32)); 617 __ test(ecx, Immediate(32));
618 if (CpuFeatures::IsSupported(CMOV)) { 618 __ cmov(not_equal, scratch1, result_reg);
619 CpuFeatureScope use_cmov(masm, CMOV);
620 __ cmov(not_equal, scratch1, result_reg);
621 } else {
622 Label skip_mov;
623 __ j(equal, &skip_mov, Label::kNear);
624 __ mov(scratch1, result_reg);
625 __ bind(&skip_mov);
626 }
627 } 619 }
628 620
629 // If the double was negative, negate the integer result. 621 // If the double was negative, negate the integer result.
630 __ bind(&check_negative); 622 __ bind(&check_negative);
631 __ mov(result_reg, scratch1); 623 __ mov(result_reg, scratch1);
632 __ neg(result_reg); 624 __ neg(result_reg);
633 if (stash_exponent_copy) { 625 if (stash_exponent_copy) {
634 __ cmp(MemOperand(esp, 0), Immediate(0)); 626 __ cmp(MemOperand(esp, 0), Immediate(0));
635 } else { 627 } else {
636 __ cmp(exponent_operand, Immediate(0)); 628 __ cmp(exponent_operand, Immediate(0));
637 } 629 }
638 if (CpuFeatures::IsSupported(CMOV)) { 630 __ cmov(greater, result_reg, scratch1);
639 CpuFeatureScope use_cmov(masm, CMOV);
640 __ cmov(greater, result_reg, scratch1);
641 } else {
642 Label skip_mov;
643 __ j(less_equal, &skip_mov, Label::kNear);
644 __ mov(result_reg, scratch1);
645 __ bind(&skip_mov);
646 }
647 631
648 // Restore registers 632 // Restore registers
649 __ bind(&done); 633 __ bind(&done);
650 if (stash_exponent_copy) { 634 if (stash_exponent_copy) {
651 __ add(esp, Immediate(kDoubleSize / 2)); 635 __ add(esp, Immediate(kDoubleSize / 2));
652 } 636 }
653 __ bind(&done_no_stash); 637 __ bind(&done_no_stash);
654 if (!final_result_reg.is(result_reg)) { 638 if (!final_result_reg.is(result_reg)) {
655 ASSERT(final_result_reg.is(ecx)); 639 ASSERT(final_result_reg.is(ecx));
656 __ mov(final_result_reg, result_reg); 640 __ mov(final_result_reg, result_reg);
(...skipping 1390 matching lines...) Expand 10 before | Expand all | Expand 10 after
2047 // Generate the number comparison code. 2031 // Generate the number comparison code.
2048 Label non_number_comparison; 2032 Label non_number_comparison;
2049 Label unordered; 2033 Label unordered;
2050 __ bind(&generic_heap_number_comparison); 2034 __ bind(&generic_heap_number_comparison);
2051 2035
2052 FloatingPointHelper::LoadSSE2Operands(masm, &non_number_comparison); 2036 FloatingPointHelper::LoadSSE2Operands(masm, &non_number_comparison);
2053 __ ucomisd(xmm0, xmm1); 2037 __ ucomisd(xmm0, xmm1);
2054 // Don't base result on EFLAGS when a NaN is involved. 2038 // Don't base result on EFLAGS when a NaN is involved.
2055 __ j(parity_even, &unordered, Label::kNear); 2039 __ j(parity_even, &unordered, Label::kNear);
2056 2040
2057 if (CpuFeatures::IsSupported(CMOV)) { 2041 // Return a result of -1, 0, or 1, based on EFLAGS.
2058 CpuFeatureScope use_cmov(masm, CMOV); 2042 __ mov(eax, 0); // equal
2059 // Return a result of -1, 0, or 1, based on EFLAGS. 2043 __ mov(ecx, Immediate(Smi::FromInt(1)));
2060 __ mov(eax, 0); // equal 2044 __ cmov(above, eax, ecx);
2061 __ mov(ecx, Immediate(Smi::FromInt(1))); 2045 __ mov(ecx, Immediate(Smi::FromInt(-1)));
2062 __ cmov(above, eax, ecx); 2046 __ cmov(below, eax, ecx);
2063 __ mov(ecx, Immediate(Smi::FromInt(-1))); 2047 __ ret(0);
2064 __ cmov(below, eax, ecx);
2065 __ ret(0);
2066 } else {
2067 Label below_label, above_label;
2068 // Return a result of -1, 0, or 1, based on EFLAGS.
2069 __ j(below, &below_label, Label::kNear);
2070 __ j(above, &above_label, Label::kNear);
2071
2072 __ Move(eax, Immediate(0));
2073 __ ret(0);
2074
2075 __ bind(&below_label);
2076 __ mov(eax, Immediate(Smi::FromInt(-1)));
2077 __ ret(0);
2078
2079 __ bind(&above_label);
2080 __ mov(eax, Immediate(Smi::FromInt(1)));
2081 __ ret(0);
2082 }
2083 2048
2084 // If one of the numbers was NaN, then the result is always false. 2049 // If one of the numbers was NaN, then the result is always false.
2085 // The cc is never not-equal. 2050 // The cc is never not-equal.
2086 __ bind(&unordered); 2051 __ bind(&unordered);
2087 ASSERT(cc != not_equal); 2052 ASSERT(cc != not_equal);
2088 if (cc == less || cc == less_equal) { 2053 if (cc == less || cc == less_equal) {
2089 __ mov(eax, Immediate(Smi::FromInt(1))); 2054 __ mov(eax, Immediate(Smi::FromInt(1)));
2090 } else { 2055 } else {
2091 __ mov(eax, Immediate(Smi::FromInt(-1))); 2056 __ mov(eax, Immediate(Smi::FromInt(-1)));
2092 } 2057 }
(...skipping 1664 matching lines...) Expand 10 before | Expand all | Expand 10 after
3757 3722
3758 if (left_ == CompareIC::SMI) { 3723 if (left_ == CompareIC::SMI) {
3759 __ JumpIfNotSmi(edx, &miss); 3724 __ JumpIfNotSmi(edx, &miss);
3760 } 3725 }
3761 if (right_ == CompareIC::SMI) { 3726 if (right_ == CompareIC::SMI) {
3762 __ JumpIfNotSmi(eax, &miss); 3727 __ JumpIfNotSmi(eax, &miss);
3763 } 3728 }
3764 3729
3765 // Inlining the double comparison and falling back to the general compare 3730 // Inlining the double comparison and falling back to the general compare
3766 // stub if NaN is involved or SSE2 or CMOV is unsupported. 3731 // stub if NaN is involved or SSE2 or CMOV is unsupported.
3767 if (CpuFeatures::IsSupported(CMOV)) { 3732 // Load left and right operand.
3768 CpuFeatureScope scope2(masm, CMOV); 3733 Label done, left, left_smi, right_smi;
3734 __ JumpIfSmi(eax, &right_smi, Label::kNear);
3735 __ cmp(FieldOperand(eax, HeapObject::kMapOffset),
3736 isolate()->factory()->heap_number_map());
3737 __ j(not_equal, &maybe_undefined1, Label::kNear);
3738 __ movsd(xmm1, FieldOperand(eax, HeapNumber::kValueOffset));
3739 __ jmp(&left, Label::kNear);
3740 __ bind(&right_smi);
3741 __ mov(ecx, eax); // Can't clobber eax because we can still jump away.
3742 __ SmiUntag(ecx);
3743 __ Cvtsi2sd(xmm1, ecx);
3769 3744
3770 // Load left and right operand. 3745 __ bind(&left);
3771 Label done, left, left_smi, right_smi; 3746 __ JumpIfSmi(edx, &left_smi, Label::kNear);
3772 __ JumpIfSmi(eax, &right_smi, Label::kNear); 3747 __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
3773 __ cmp(FieldOperand(eax, HeapObject::kMapOffset), 3748 isolate()->factory()->heap_number_map());
3774 isolate()->factory()->heap_number_map()); 3749 __ j(not_equal, &maybe_undefined2, Label::kNear);
3775 __ j(not_equal, &maybe_undefined1, Label::kNear); 3750 __ movsd(xmm0, FieldOperand(edx, HeapNumber::kValueOffset));
3776 __ movsd(xmm1, FieldOperand(eax, HeapNumber::kValueOffset)); 3751 __ jmp(&done);
3777 __ jmp(&left, Label::kNear); 3752 __ bind(&left_smi);
3778 __ bind(&right_smi); 3753 __ mov(ecx, edx); // Can't clobber edx because we can still jump away.
3779 __ mov(ecx, eax); // Can't clobber eax because we can still jump away. 3754 __ SmiUntag(ecx);
3780 __ SmiUntag(ecx); 3755 __ Cvtsi2sd(xmm0, ecx);
3781 __ Cvtsi2sd(xmm1, ecx);
3782 3756
3783 __ bind(&left); 3757 __ bind(&done);
3784 __ JumpIfSmi(edx, &left_smi, Label::kNear); 3758 // Compare operands.
3785 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), 3759 __ ucomisd(xmm0, xmm1);
3786 isolate()->factory()->heap_number_map());
3787 __ j(not_equal, &maybe_undefined2, Label::kNear);
3788 __ movsd(xmm0, FieldOperand(edx, HeapNumber::kValueOffset));
3789 __ jmp(&done);
3790 __ bind(&left_smi);
3791 __ mov(ecx, edx); // Can't clobber edx because we can still jump away.
3792 __ SmiUntag(ecx);
3793 __ Cvtsi2sd(xmm0, ecx);
3794 3760
3795 __ bind(&done); 3761 // Don't base result on EFLAGS when a NaN is involved.
3796 // Compare operands. 3762 __ j(parity_even, &unordered, Label::kNear);
3797 __ ucomisd(xmm0, xmm1);
3798 3763
3799 // Don't base result on EFLAGS when a NaN is involved. 3764 // Return a result of -1, 0, or 1, based on EFLAGS.
3800 __ j(parity_even, &unordered, Label::kNear); 3765 // Performing mov, because xor would destroy the flag register.
3801 3766 __ mov(eax, 0); // equal
3802 // Return a result of -1, 0, or 1, based on EFLAGS. 3767 __ mov(ecx, Immediate(Smi::FromInt(1)));
3803 // Performing mov, because xor would destroy the flag register. 3768 __ cmov(above, eax, ecx);
3804 __ mov(eax, 0); // equal 3769 __ mov(ecx, Immediate(Smi::FromInt(-1)));
3805 __ mov(ecx, Immediate(Smi::FromInt(1))); 3770 __ cmov(below, eax, ecx);
3806 __ cmov(above, eax, ecx); 3771 __ ret(0);
3807 __ mov(ecx, Immediate(Smi::FromInt(-1)));
3808 __ cmov(below, eax, ecx);
3809 __ ret(0);
3810 } else {
3811 __ mov(ecx, edx);
3812 __ and_(ecx, eax);
3813 __ JumpIfSmi(ecx, &generic_stub, Label::kNear);
3814
3815 __ cmp(FieldOperand(eax, HeapObject::kMapOffset),
3816 isolate()->factory()->heap_number_map());
3817 __ j(not_equal, &maybe_undefined1, Label::kNear);
3818 __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
3819 isolate()->factory()->heap_number_map());
3820 __ j(not_equal, &maybe_undefined2, Label::kNear);
3821 }
3822 3772
3823 __ bind(&unordered); 3773 __ bind(&unordered);
3824 __ bind(&generic_stub); 3774 __ bind(&generic_stub);
3825 ICCompareStub stub(isolate(), op_, CompareIC::GENERIC, CompareIC::GENERIC, 3775 ICCompareStub stub(isolate(), op_, CompareIC::GENERIC, CompareIC::GENERIC,
3826 CompareIC::GENERIC); 3776 CompareIC::GENERIC);
3827 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET); 3777 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET);
3828 3778
3829 __ bind(&maybe_undefined1); 3779 __ bind(&maybe_undefined1);
3830 if (Token::IsOrderedRelationalCompareOp(op_)) { 3780 if (Token::IsOrderedRelationalCompareOp(op_)) {
3831 __ cmp(eax, Immediate(isolate()->factory()->undefined_value())); 3781 __ cmp(eax, Immediate(isolate()->factory()->undefined_value()));
(...skipping 1282 matching lines...) Expand 10 before | Expand all | Expand 10 after
5114 Operand(ebp, 7 * kPointerSize), 5064 Operand(ebp, 7 * kPointerSize),
5115 NULL); 5065 NULL);
5116 } 5066 }
5117 5067
5118 5068
5119 #undef __ 5069 #undef __
5120 5070
5121 } } // namespace v8::internal 5071 } } // namespace v8::internal
5122 5072
5123 #endif // V8_TARGET_ARCH_IA32 5073 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/assembler-ia32.cc ('k') | src/ia32/macro-assembler-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698