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

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

Issue 275253004: Require CMOV support for the ia32 port. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: restore uses of cmov 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 611 matching lines...) Expand 10 before | Expand all | Expand 10 after
622 } else { 622 } else {
623 __ mov(result_reg, exponent_operand); 623 __ mov(result_reg, exponent_operand);
624 } 624 }
625 __ and_(result_reg, 625 __ and_(result_reg,
626 Immediate(static_cast<uint32_t>(Double::kSignificandMask >> 32))); 626 Immediate(static_cast<uint32_t>(Double::kSignificandMask >> 32)));
627 __ add(result_reg, 627 __ add(result_reg,
628 Immediate(static_cast<uint32_t>(Double::kHiddenBit >> 32))); 628 Immediate(static_cast<uint32_t>(Double::kHiddenBit >> 32)));
629 __ shrd(result_reg, scratch1); 629 __ shrd(result_reg, scratch1);
630 __ shr_cl(result_reg); 630 __ shr_cl(result_reg);
631 __ test(ecx, Immediate(32)); 631 __ test(ecx, Immediate(32));
632 if (CpuFeatures::IsSupported(CMOV)) { 632 __ cmov(not_equal, scratch1, result_reg);
633 CpuFeatureScope use_cmov(masm, CMOV);
634 __ cmov(not_equal, scratch1, result_reg);
635 } else {
636 Label skip_mov;
637 __ j(equal, &skip_mov, Label::kNear);
638 __ mov(scratch1, result_reg);
639 __ bind(&skip_mov);
640 }
641 } 633 }
642 634
643 // If the double was negative, negate the integer result. 635 // If the double was negative, negate the integer result.
644 __ bind(&check_negative); 636 __ bind(&check_negative);
645 __ mov(result_reg, scratch1); 637 __ mov(result_reg, scratch1);
646 __ neg(result_reg); 638 __ neg(result_reg);
647 if (stash_exponent_copy) { 639 if (stash_exponent_copy) {
648 __ cmp(MemOperand(esp, 0), Immediate(0)); 640 __ cmp(MemOperand(esp, 0), Immediate(0));
649 } else { 641 } else {
650 __ cmp(exponent_operand, Immediate(0)); 642 __ cmp(exponent_operand, Immediate(0));
651 } 643 }
652 if (CpuFeatures::IsSupported(CMOV)) {
653 CpuFeatureScope use_cmov(masm, CMOV);
654 __ cmov(greater, result_reg, scratch1); 644 __ cmov(greater, result_reg, scratch1);
655 } else {
656 Label skip_mov;
657 __ j(less_equal, &skip_mov, Label::kNear);
658 __ mov(result_reg, scratch1);
659 __ bind(&skip_mov);
660 }
661 645
662 // Restore registers 646 // Restore registers
663 __ bind(&done); 647 __ bind(&done);
664 if (stash_exponent_copy) { 648 if (stash_exponent_copy) {
665 __ add(esp, Immediate(kDoubleSize / 2)); 649 __ add(esp, Immediate(kDoubleSize / 2));
666 } 650 }
667 __ bind(&done_no_stash); 651 __ bind(&done_no_stash);
668 if (!final_result_reg.is(result_reg)) { 652 if (!final_result_reg.is(result_reg)) {
669 ASSERT(final_result_reg.is(ecx)); 653 ASSERT(final_result_reg.is(ecx));
670 __ mov(final_result_reg, result_reg); 654 __ mov(final_result_reg, result_reg);
(...skipping 1390 matching lines...) Expand 10 before | Expand all | Expand 10 after
2061 // Generate the number comparison code. 2045 // Generate the number comparison code.
2062 Label non_number_comparison; 2046 Label non_number_comparison;
2063 Label unordered; 2047 Label unordered;
2064 __ bind(&generic_heap_number_comparison); 2048 __ bind(&generic_heap_number_comparison);
2065 2049
2066 FloatingPointHelper::LoadSSE2Operands(masm, &non_number_comparison); 2050 FloatingPointHelper::LoadSSE2Operands(masm, &non_number_comparison);
2067 __ ucomisd(xmm0, xmm1); 2051 __ ucomisd(xmm0, xmm1);
2068 // Don't base result on EFLAGS when a NaN is involved. 2052 // Don't base result on EFLAGS when a NaN is involved.
2069 __ j(parity_even, &unordered, Label::kNear); 2053 __ j(parity_even, &unordered, Label::kNear);
2070 2054
2071 if (CpuFeatures::IsSupported(CMOV)) { 2055 __ mov(eax, 0); // equal
2072 CpuFeatureScope use_cmov(masm, CMOV); 2056 __ mov(ecx, Immediate(Smi::FromInt(1)));
2073 // Return a result of -1, 0, or 1, based on EFLAGS. 2057 __ cmov(above, eax, ecx);
2074 __ mov(eax, 0); // equal 2058 __ mov(ecx, Immediate(Smi::FromInt(-1)));
2075 __ mov(ecx, Immediate(Smi::FromInt(1))); 2059 __ cmov(below, eax, ecx);
2076 __ cmov(above, eax, ecx); 2060 __ ret(0);
2077 __ mov(ecx, Immediate(Smi::FromInt(-1)));
2078 __ cmov(below, eax, ecx);
2079 __ ret(0);
2080 } else {
2081 Label below_label, above_label;
2082 // Return a result of -1, 0, or 1, based on EFLAGS.
2083 __ j(below, &below_label, Label::kNear);
2084 __ j(above, &above_label, Label::kNear);
2085
2086 __ Move(eax, Immediate(0));
2087 __ ret(0);
2088
2089 __ bind(&below_label);
2090 __ mov(eax, Immediate(Smi::FromInt(-1)));
2091 __ ret(0);
2092
2093 __ bind(&above_label);
2094 __ mov(eax, Immediate(Smi::FromInt(1)));
2095 __ ret(0);
2096 }
2097 2061
2098 // If one of the numbers was NaN, then the result is always false. 2062 // If one of the numbers was NaN, then the result is always false.
2099 // The cc is never not-equal. 2063 // The cc is never not-equal.
2100 __ bind(&unordered); 2064 __ bind(&unordered);
2101 ASSERT(cc != not_equal); 2065 ASSERT(cc != not_equal);
2102 if (cc == less || cc == less_equal) { 2066 if (cc == less || cc == less_equal) {
2103 __ mov(eax, Immediate(Smi::FromInt(1))); 2067 __ mov(eax, Immediate(Smi::FromInt(1)));
2104 } else { 2068 } else {
2105 __ mov(eax, Immediate(Smi::FromInt(-1))); 2069 __ mov(eax, Immediate(Smi::FromInt(-1)));
2106 } 2070 }
(...skipping 1662 matching lines...) Expand 10 before | Expand all | Expand 10 after
3769 Label unordered, maybe_undefined1, maybe_undefined2; 3733 Label unordered, maybe_undefined1, maybe_undefined2;
3770 Label miss; 3734 Label miss;
3771 3735
3772 if (left_ == CompareIC::SMI) { 3736 if (left_ == CompareIC::SMI) {
3773 __ JumpIfNotSmi(edx, &miss); 3737 __ JumpIfNotSmi(edx, &miss);
3774 } 3738 }
3775 if (right_ == CompareIC::SMI) { 3739 if (right_ == CompareIC::SMI) {
3776 __ JumpIfNotSmi(eax, &miss); 3740 __ JumpIfNotSmi(eax, &miss);
3777 } 3741 }
3778 3742
3779 // Inlining the double comparison and falling back to the general compare 3743 // Load left and right operand.
3780 // stub if NaN is involved or SSE2 or CMOV is unsupported. 3744 Label done, left, left_smi, right_smi;
3781 if (CpuFeatures::IsSupported(CMOV)) { 3745 __ JumpIfSmi(eax, &right_smi, Label::kNear);
3782 CpuFeatureScope scope2(masm, CMOV); 3746 __ cmp(FieldOperand(eax, HeapObject::kMapOffset),
3747 isolate()->factory()->heap_number_map());
3748 __ j(not_equal, &maybe_undefined1, Label::kNear);
3749 __ movsd(xmm1, FieldOperand(eax, HeapNumber::kValueOffset));
3750 __ jmp(&left, Label::kNear);
3751 __ bind(&right_smi);
3752 __ mov(ecx, eax); // Can't clobber eax because we can still jump away.
3753 __ SmiUntag(ecx);
3754 __ Cvtsi2sd(xmm1, ecx);
3783 3755
3784 // Load left and right operand. 3756 __ bind(&left);
3785 Label done, left, left_smi, right_smi; 3757 __ JumpIfSmi(edx, &left_smi, Label::kNear);
3786 __ JumpIfSmi(eax, &right_smi, Label::kNear); 3758 __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
3787 __ cmp(FieldOperand(eax, HeapObject::kMapOffset), 3759 isolate()->factory()->heap_number_map());
3788 isolate()->factory()->heap_number_map()); 3760 __ j(not_equal, &maybe_undefined2, Label::kNear);
3789 __ j(not_equal, &maybe_undefined1, Label::kNear); 3761 __ movsd(xmm0, FieldOperand(edx, HeapNumber::kValueOffset));
3790 __ movsd(xmm1, FieldOperand(eax, HeapNumber::kValueOffset)); 3762 __ jmp(&done);
3791 __ jmp(&left, Label::kNear); 3763 __ bind(&left_smi);
3792 __ bind(&right_smi); 3764 __ mov(ecx, edx); // Can't clobber edx because we can still jump away.
3793 __ mov(ecx, eax); // Can't clobber eax because we can still jump away. 3765 __ SmiUntag(ecx);
3794 __ SmiUntag(ecx); 3766 __ Cvtsi2sd(xmm0, ecx);
3795 __ Cvtsi2sd(xmm1, ecx);
3796 3767
3797 __ bind(&left); 3768 __ bind(&done);
3798 __ JumpIfSmi(edx, &left_smi, Label::kNear); 3769 // Compare operands.
3799 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), 3770 __ ucomisd(xmm0, xmm1);
3800 isolate()->factory()->heap_number_map());
3801 __ j(not_equal, &maybe_undefined2, Label::kNear);
3802 __ movsd(xmm0, FieldOperand(edx, HeapNumber::kValueOffset));
3803 __ jmp(&done);
3804 __ bind(&left_smi);
3805 __ mov(ecx, edx); // Can't clobber edx because we can still jump away.
3806 __ SmiUntag(ecx);
3807 __ Cvtsi2sd(xmm0, ecx);
3808 3771
3809 __ bind(&done); 3772 // Don't base result on EFLAGS when a NaN is involved.
3810 // Compare operands. 3773 __ j(parity_even, &unordered, Label::kNear);
3811 __ ucomisd(xmm0, xmm1);
3812 3774
3813 // Don't base result on EFLAGS when a NaN is involved. 3775 // Return a result of -1, 0, or 1, based on EFLAGS.
3814 __ j(parity_even, &unordered, Label::kNear); 3776 // Performing mov, because xor would destroy the flag register.
3815 3777 __ mov(eax, 0); // equal
3816 // Return a result of -1, 0, or 1, based on EFLAGS. 3778 __ mov(ecx, Immediate(Smi::FromInt(1)));
3817 // Performing mov, because xor would destroy the flag register. 3779 __ cmov(above, eax, ecx);
3818 __ mov(eax, 0); // equal 3780 __ mov(ecx, Immediate(Smi::FromInt(-1)));
3819 __ mov(ecx, Immediate(Smi::FromInt(1))); 3781 __ cmov(below, eax, ecx);
3820 __ cmov(above, eax, ecx); 3782 __ ret(0);
3821 __ mov(ecx, Immediate(Smi::FromInt(-1)));
3822 __ cmov(below, eax, ecx);
3823 __ ret(0);
3824 } else {
3825 __ mov(ecx, edx);
3826 __ and_(ecx, eax);
3827 __ JumpIfSmi(ecx, &generic_stub, Label::kNear);
3828
3829 __ cmp(FieldOperand(eax, HeapObject::kMapOffset),
3830 isolate()->factory()->heap_number_map());
3831 __ j(not_equal, &maybe_undefined1, Label::kNear);
3832 __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
3833 isolate()->factory()->heap_number_map());
3834 __ j(not_equal, &maybe_undefined2, Label::kNear);
3835 }
3836 3783
3837 __ bind(&unordered); 3784 __ bind(&unordered);
3838 __ bind(&generic_stub); 3785 __ bind(&generic_stub);
3839 ICCompareStub stub(isolate(), op_, CompareIC::GENERIC, CompareIC::GENERIC, 3786 ICCompareStub stub(isolate(), op_, CompareIC::GENERIC, CompareIC::GENERIC,
3840 CompareIC::GENERIC); 3787 CompareIC::GENERIC);
3841 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET); 3788 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET);
3842 3789
3843 __ bind(&maybe_undefined1); 3790 __ bind(&maybe_undefined1);
3844 if (Token::IsOrderedRelationalCompareOp(op_)) { 3791 if (Token::IsOrderedRelationalCompareOp(op_)) {
3845 __ cmp(eax, Immediate(isolate()->factory()->undefined_value())); 3792 __ cmp(eax, Immediate(isolate()->factory()->undefined_value()));
(...skipping 1282 matching lines...) Expand 10 before | Expand all | Expand 10 after
5128 Operand(ebp, 7 * kPointerSize), 5075 Operand(ebp, 7 * kPointerSize),
5129 NULL); 5076 NULL);
5130 } 5077 }
5131 5078
5132 5079
5133 #undef __ 5080 #undef __
5134 5081
5135 } } // namespace v8::internal 5082 } } // namespace v8::internal
5136 5083
5137 #endif // V8_TARGET_ARCH_IA32 5084 #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