| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 635 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 646 GenerateTypeTransition(masm); | 646 GenerateTypeTransition(masm); |
| 647 } | 647 } |
| 648 | 648 |
| 649 | 649 |
| 650 void StoreBufferOverflowStub::Generate(MacroAssembler* masm) { | 650 void StoreBufferOverflowStub::Generate(MacroAssembler* masm) { |
| 651 // We don't allow a GC during a store buffer overflow so there is no need to | 651 // We don't allow a GC during a store buffer overflow so there is no need to |
| 652 // store the registers in any particular way, but we do have to store and | 652 // store the registers in any particular way, but we do have to store and |
| 653 // restore them. | 653 // restore them. |
| 654 __ pushad(); | 654 __ pushad(); |
| 655 if (save_doubles_ == kSaveFPRegs) { | 655 if (save_doubles_ == kSaveFPRegs) { |
| 656 CpuFeatures::Scope scope(SSE2); | 656 CpuFeatureScope scope(masm, SSE2); |
| 657 __ sub(esp, Immediate(kDoubleSize * XMMRegister::kNumRegisters)); | 657 __ sub(esp, Immediate(kDoubleSize * XMMRegister::kNumRegisters)); |
| 658 for (int i = 0; i < XMMRegister::kNumRegisters; i++) { | 658 for (int i = 0; i < XMMRegister::kNumRegisters; i++) { |
| 659 XMMRegister reg = XMMRegister::from_code(i); | 659 XMMRegister reg = XMMRegister::from_code(i); |
| 660 __ movdbl(Operand(esp, i * kDoubleSize), reg); | 660 __ movdbl(Operand(esp, i * kDoubleSize), reg); |
| 661 } | 661 } |
| 662 } | 662 } |
| 663 const int argument_count = 1; | 663 const int argument_count = 1; |
| 664 | 664 |
| 665 AllowExternalCallThatCantCauseGC scope(masm); | 665 AllowExternalCallThatCantCauseGC scope(masm); |
| 666 __ PrepareCallCFunction(argument_count, ecx); | 666 __ PrepareCallCFunction(argument_count, ecx); |
| 667 __ mov(Operand(esp, 0 * kPointerSize), | 667 __ mov(Operand(esp, 0 * kPointerSize), |
| 668 Immediate(ExternalReference::isolate_address())); | 668 Immediate(ExternalReference::isolate_address())); |
| 669 __ CallCFunction( | 669 __ CallCFunction( |
| 670 ExternalReference::store_buffer_overflow_function(masm->isolate()), | 670 ExternalReference::store_buffer_overflow_function(masm->isolate()), |
| 671 argument_count); | 671 argument_count); |
| 672 if (save_doubles_ == kSaveFPRegs) { | 672 if (save_doubles_ == kSaveFPRegs) { |
| 673 CpuFeatures::Scope scope(SSE2); | 673 CpuFeatureScope scope(masm, SSE2); |
| 674 for (int i = 0; i < XMMRegister::kNumRegisters; i++) { | 674 for (int i = 0; i < XMMRegister::kNumRegisters; i++) { |
| 675 XMMRegister reg = XMMRegister::from_code(i); | 675 XMMRegister reg = XMMRegister::from_code(i); |
| 676 __ movdbl(reg, Operand(esp, i * kDoubleSize)); | 676 __ movdbl(reg, Operand(esp, i * kDoubleSize)); |
| 677 } | 677 } |
| 678 __ add(esp, Immediate(kDoubleSize * XMMRegister::kNumRegisters)); | 678 __ add(esp, Immediate(kDoubleSize * XMMRegister::kNumRegisters)); |
| 679 } | 679 } |
| 680 __ popad(); | 680 __ popad(); |
| 681 __ ret(0); | 681 __ ret(0); |
| 682 } | 682 } |
| 683 | 683 |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 813 __ sub(scratch2, Immediate(HeapNumber::kExponentBias)); | 813 __ sub(scratch2, Immediate(HeapNumber::kExponentBias)); |
| 814 // Load ecx with zero. We use this either for the final shift or | 814 // Load ecx with zero. We use this either for the final shift or |
| 815 // for the answer. | 815 // for the answer. |
| 816 __ xor_(ecx, ecx); | 816 __ xor_(ecx, ecx); |
| 817 // If the exponent is above 83, the number contains no significant | 817 // If the exponent is above 83, the number contains no significant |
| 818 // bits in the range 0..2^31, so the result is zero. | 818 // bits in the range 0..2^31, so the result is zero. |
| 819 static const uint32_t kResultIsZeroExponent = 83; | 819 static const uint32_t kResultIsZeroExponent = 83; |
| 820 __ cmp(scratch2, Immediate(kResultIsZeroExponent)); | 820 __ cmp(scratch2, Immediate(kResultIsZeroExponent)); |
| 821 __ j(above, &done); | 821 __ j(above, &done); |
| 822 if (use_sse3) { | 822 if (use_sse3) { |
| 823 CpuFeatures::Scope scope(SSE3); | 823 CpuFeatureScope scope(masm, SSE3); |
| 824 // Check whether the exponent is too big for a 64 bit signed integer. | 824 // Check whether the exponent is too big for a 64 bit signed integer. |
| 825 static const uint32_t kTooBigExponent = 63; | 825 static const uint32_t kTooBigExponent = 63; |
| 826 __ cmp(scratch2, Immediate(kTooBigExponent)); | 826 __ cmp(scratch2, Immediate(kTooBigExponent)); |
| 827 __ j(greater_equal, conversion_failure); | 827 __ j(greater_equal, conversion_failure); |
| 828 // Load x87 register with heap number. | 828 // Load x87 register with heap number. |
| 829 __ fld_d(FieldOperand(source, HeapNumber::kValueOffset)); | 829 __ fld_d(FieldOperand(source, HeapNumber::kValueOffset)); |
| 830 // Reserve space for 64 bit answer. | 830 // Reserve space for 64 bit answer. |
| 831 __ sub(esp, Immediate(sizeof(uint64_t))); // Nolint. | 831 __ sub(esp, Immediate(sizeof(uint64_t))); // Nolint. |
| 832 // Do conversion, which cannot fail because we checked the exponent. | 832 // Do conversion, which cannot fail because we checked the exponent. |
| 833 __ fisttp_d(Operand(esp, 0)); | 833 __ fisttp_d(Operand(esp, 0)); |
| (...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1176 __ pop(edx); | 1176 __ pop(edx); |
| 1177 } | 1177 } |
| 1178 // IntegerConvert uses ebx and edi as scratch registers. | 1178 // IntegerConvert uses ebx and edi as scratch registers. |
| 1179 // This conversion won't go slow-case. | 1179 // This conversion won't go slow-case. |
| 1180 IntegerConvert(masm, edx, CpuFeatures::IsSupported(SSE3), slow); | 1180 IntegerConvert(masm, edx, CpuFeatures::IsSupported(SSE3), slow); |
| 1181 __ not_(ecx); | 1181 __ not_(ecx); |
| 1182 | 1182 |
| 1183 __ bind(&heapnumber_allocated); | 1183 __ bind(&heapnumber_allocated); |
| 1184 } | 1184 } |
| 1185 if (CpuFeatures::IsSupported(SSE2)) { | 1185 if (CpuFeatures::IsSupported(SSE2)) { |
| 1186 CpuFeatures::Scope use_sse2(SSE2); | 1186 CpuFeatureScope use_sse2(masm, SSE2); |
| 1187 __ cvtsi2sd(xmm0, ecx); | 1187 __ cvtsi2sd(xmm0, ecx); |
| 1188 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0); | 1188 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0); |
| 1189 } else { | 1189 } else { |
| 1190 __ push(ecx); | 1190 __ push(ecx); |
| 1191 __ fild_s(Operand(esp, 0)); | 1191 __ fild_s(Operand(esp, 0)); |
| 1192 __ pop(ecx); | 1192 __ pop(ecx); |
| 1193 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); | 1193 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); |
| 1194 } | 1194 } |
| 1195 __ ret(0); | 1195 __ ret(0); |
| 1196 } | 1196 } |
| (...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1561 // It's OK to overwrite the arguments on the stack because we | 1561 // It's OK to overwrite the arguments on the stack because we |
| 1562 // are about to return. | 1562 // are about to return. |
| 1563 if (op == Token::SHR) { | 1563 if (op == Token::SHR) { |
| 1564 __ mov(Operand(esp, 1 * kPointerSize), left); | 1564 __ mov(Operand(esp, 1 * kPointerSize), left); |
| 1565 __ mov(Operand(esp, 2 * kPointerSize), Immediate(0)); | 1565 __ mov(Operand(esp, 2 * kPointerSize), Immediate(0)); |
| 1566 __ fild_d(Operand(esp, 1 * kPointerSize)); | 1566 __ fild_d(Operand(esp, 1 * kPointerSize)); |
| 1567 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); | 1567 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); |
| 1568 } else { | 1568 } else { |
| 1569 ASSERT_EQ(Token::SHL, op); | 1569 ASSERT_EQ(Token::SHL, op); |
| 1570 if (CpuFeatures::IsSupported(SSE2)) { | 1570 if (CpuFeatures::IsSupported(SSE2)) { |
| 1571 CpuFeatures::Scope use_sse2(SSE2); | 1571 CpuFeatureScope use_sse2(masm, SSE2); |
| 1572 __ cvtsi2sd(xmm0, left); | 1572 __ cvtsi2sd(xmm0, left); |
| 1573 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0); | 1573 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0); |
| 1574 } else { | 1574 } else { |
| 1575 __ mov(Operand(esp, 1 * kPointerSize), left); | 1575 __ mov(Operand(esp, 1 * kPointerSize), left); |
| 1576 __ fild_s(Operand(esp, 1 * kPointerSize)); | 1576 __ fild_s(Operand(esp, 1 * kPointerSize)); |
| 1577 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); | 1577 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); |
| 1578 } | 1578 } |
| 1579 } | 1579 } |
| 1580 __ ret(2 * kPointerSize); | 1580 __ ret(2 * kPointerSize); |
| 1581 break; | 1581 break; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1605 // Left was clobbered but a copy is in edi. Right is in ebx for | 1605 // Left was clobbered but a copy is in edi. Right is in ebx for |
| 1606 // division. | 1606 // division. |
| 1607 __ mov(edx, edi); | 1607 __ mov(edx, edi); |
| 1608 __ mov(eax, right); | 1608 __ mov(eax, right); |
| 1609 break; | 1609 break; |
| 1610 default: UNREACHABLE(); | 1610 default: UNREACHABLE(); |
| 1611 break; | 1611 break; |
| 1612 } | 1612 } |
| 1613 __ AllocateHeapNumber(ecx, ebx, no_reg, slow); | 1613 __ AllocateHeapNumber(ecx, ebx, no_reg, slow); |
| 1614 if (CpuFeatures::IsSupported(SSE2)) { | 1614 if (CpuFeatures::IsSupported(SSE2)) { |
| 1615 CpuFeatures::Scope use_sse2(SSE2); | 1615 CpuFeatureScope use_sse2(masm, SSE2); |
| 1616 FloatingPointHelper::LoadSSE2Smis(masm, ebx); | 1616 FloatingPointHelper::LoadSSE2Smis(masm, ebx); |
| 1617 switch (op) { | 1617 switch (op) { |
| 1618 case Token::ADD: __ addsd(xmm0, xmm1); break; | 1618 case Token::ADD: __ addsd(xmm0, xmm1); break; |
| 1619 case Token::SUB: __ subsd(xmm0, xmm1); break; | 1619 case Token::SUB: __ subsd(xmm0, xmm1); break; |
| 1620 case Token::MUL: __ mulsd(xmm0, xmm1); break; | 1620 case Token::MUL: __ mulsd(xmm0, xmm1); break; |
| 1621 case Token::DIV: __ divsd(xmm0, xmm1); break; | 1621 case Token::DIV: __ divsd(xmm0, xmm1); break; |
| 1622 default: UNREACHABLE(); | 1622 default: UNREACHABLE(); |
| 1623 } | 1623 } |
| 1624 __ movdbl(FieldOperand(ecx, HeapNumber::kValueOffset), xmm0); | 1624 __ movdbl(FieldOperand(ecx, HeapNumber::kValueOffset), xmm0); |
| 1625 } else { // SSE2 not available, use FPU. | 1625 } else { // SSE2 not available, use FPU. |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1770 // Floating point case. | 1770 // Floating point case. |
| 1771 switch (op_) { | 1771 switch (op_) { |
| 1772 case Token::ADD: | 1772 case Token::ADD: |
| 1773 case Token::SUB: | 1773 case Token::SUB: |
| 1774 case Token::MUL: | 1774 case Token::MUL: |
| 1775 case Token::DIV: | 1775 case Token::DIV: |
| 1776 case Token::MOD: { | 1776 case Token::MOD: { |
| 1777 Label not_floats; | 1777 Label not_floats; |
| 1778 Label not_int32; | 1778 Label not_int32; |
| 1779 if (CpuFeatures::IsSupported(SSE2)) { | 1779 if (CpuFeatures::IsSupported(SSE2)) { |
| 1780 CpuFeatures::Scope use_sse2(SSE2); | 1780 CpuFeatureScope use_sse2(masm, SSE2); |
| 1781 // It could be that only SMIs have been seen at either the left | 1781 // It could be that only SMIs have been seen at either the left |
| 1782 // or the right operand. For precise type feedback, patch the IC | 1782 // or the right operand. For precise type feedback, patch the IC |
| 1783 // again if this changes. | 1783 // again if this changes. |
| 1784 // In theory, we would need the same check in the non-SSE2 case, | 1784 // In theory, we would need the same check in the non-SSE2 case, |
| 1785 // but since we don't support Crankshaft on such hardware we can | 1785 // but since we don't support Crankshaft on such hardware we can |
| 1786 // afford not to care about precise type feedback. | 1786 // afford not to care about precise type feedback. |
| 1787 if (left_type_ == BinaryOpIC::SMI) { | 1787 if (left_type_ == BinaryOpIC::SMI) { |
| 1788 __ JumpIfNotSmi(edx, ¬_int32); | 1788 __ JumpIfNotSmi(edx, ¬_int32); |
| 1789 } | 1789 } |
| 1790 if (right_type_ == BinaryOpIC::SMI) { | 1790 if (right_type_ == BinaryOpIC::SMI) { |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1901 __ JumpIfNotSmi(eax, &skip_allocation, Label::kNear); | 1901 __ JumpIfNotSmi(eax, &skip_allocation, Label::kNear); |
| 1902 // Fall through! | 1902 // Fall through! |
| 1903 case NO_OVERWRITE: | 1903 case NO_OVERWRITE: |
| 1904 __ AllocateHeapNumber(eax, ecx, edx, &call_runtime); | 1904 __ AllocateHeapNumber(eax, ecx, edx, &call_runtime); |
| 1905 __ bind(&skip_allocation); | 1905 __ bind(&skip_allocation); |
| 1906 break; | 1906 break; |
| 1907 default: UNREACHABLE(); | 1907 default: UNREACHABLE(); |
| 1908 } | 1908 } |
| 1909 // Store the result in the HeapNumber and return. | 1909 // Store the result in the HeapNumber and return. |
| 1910 if (CpuFeatures::IsSupported(SSE2)) { | 1910 if (CpuFeatures::IsSupported(SSE2)) { |
| 1911 CpuFeatures::Scope use_sse2(SSE2); | 1911 CpuFeatureScope use_sse2(masm, SSE2); |
| 1912 __ cvtsi2sd(xmm0, ebx); | 1912 __ cvtsi2sd(xmm0, ebx); |
| 1913 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0); | 1913 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0); |
| 1914 } else { | 1914 } else { |
| 1915 __ mov(Operand(esp, 1 * kPointerSize), ebx); | 1915 __ mov(Operand(esp, 1 * kPointerSize), ebx); |
| 1916 __ fild_s(Operand(esp, 1 * kPointerSize)); | 1916 __ fild_s(Operand(esp, 1 * kPointerSize)); |
| 1917 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); | 1917 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); |
| 1918 } | 1918 } |
| 1919 __ ret(2 * kPointerSize); // Drop two pushed arguments from the stack. | 1919 __ ret(2 * kPointerSize); // Drop two pushed arguments from the stack. |
| 1920 } | 1920 } |
| 1921 | 1921 |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1991 Label call_runtime; | 1991 Label call_runtime; |
| 1992 | 1992 |
| 1993 // Floating point case. | 1993 // Floating point case. |
| 1994 switch (op_) { | 1994 switch (op_) { |
| 1995 case Token::ADD: | 1995 case Token::ADD: |
| 1996 case Token::SUB: | 1996 case Token::SUB: |
| 1997 case Token::MUL: | 1997 case Token::MUL: |
| 1998 case Token::DIV: { | 1998 case Token::DIV: { |
| 1999 Label not_floats; | 1999 Label not_floats; |
| 2000 if (CpuFeatures::IsSupported(SSE2)) { | 2000 if (CpuFeatures::IsSupported(SSE2)) { |
| 2001 CpuFeatures::Scope use_sse2(SSE2); | 2001 CpuFeatureScope use_sse2(masm, SSE2); |
| 2002 | 2002 |
| 2003 // It could be that only SMIs have been seen at either the left | 2003 // It could be that only SMIs have been seen at either the left |
| 2004 // or the right operand. For precise type feedback, patch the IC | 2004 // or the right operand. For precise type feedback, patch the IC |
| 2005 // again if this changes. | 2005 // again if this changes. |
| 2006 // In theory, we would need the same check in the non-SSE2 case, | 2006 // In theory, we would need the same check in the non-SSE2 case, |
| 2007 // but since we don't support Crankshaft on such hardware we can | 2007 // but since we don't support Crankshaft on such hardware we can |
| 2008 // afford not to care about precise type feedback. | 2008 // afford not to care about precise type feedback. |
| 2009 if (left_type_ == BinaryOpIC::SMI) { | 2009 if (left_type_ == BinaryOpIC::SMI) { |
| 2010 __ JumpIfNotSmi(edx, ¬_floats); | 2010 __ JumpIfNotSmi(edx, ¬_floats); |
| 2011 } | 2011 } |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2118 __ JumpIfNotSmi(eax, &skip_allocation, Label::kNear); | 2118 __ JumpIfNotSmi(eax, &skip_allocation, Label::kNear); |
| 2119 // Fall through! | 2119 // Fall through! |
| 2120 case NO_OVERWRITE: | 2120 case NO_OVERWRITE: |
| 2121 __ AllocateHeapNumber(eax, ecx, edx, &call_runtime); | 2121 __ AllocateHeapNumber(eax, ecx, edx, &call_runtime); |
| 2122 __ bind(&skip_allocation); | 2122 __ bind(&skip_allocation); |
| 2123 break; | 2123 break; |
| 2124 default: UNREACHABLE(); | 2124 default: UNREACHABLE(); |
| 2125 } | 2125 } |
| 2126 // Store the result in the HeapNumber and return. | 2126 // Store the result in the HeapNumber and return. |
| 2127 if (CpuFeatures::IsSupported(SSE2)) { | 2127 if (CpuFeatures::IsSupported(SSE2)) { |
| 2128 CpuFeatures::Scope use_sse2(SSE2); | 2128 CpuFeatureScope use_sse2(masm, SSE2); |
| 2129 __ cvtsi2sd(xmm0, ebx); | 2129 __ cvtsi2sd(xmm0, ebx); |
| 2130 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0); | 2130 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0); |
| 2131 } else { | 2131 } else { |
| 2132 __ mov(Operand(esp, 1 * kPointerSize), ebx); | 2132 __ mov(Operand(esp, 1 * kPointerSize), ebx); |
| 2133 __ fild_s(Operand(esp, 1 * kPointerSize)); | 2133 __ fild_s(Operand(esp, 1 * kPointerSize)); |
| 2134 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); | 2134 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); |
| 2135 } | 2135 } |
| 2136 __ ret(2 * kPointerSize); // Drop two pushed arguments from the stack. | 2136 __ ret(2 * kPointerSize); // Drop two pushed arguments from the stack. |
| 2137 } | 2137 } |
| 2138 | 2138 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2198 masm, &call_runtime, ALLOW_HEAPNUMBER_RESULTS, op_); | 2198 masm, &call_runtime, ALLOW_HEAPNUMBER_RESULTS, op_); |
| 2199 | 2199 |
| 2200 // Floating point case. | 2200 // Floating point case. |
| 2201 switch (op_) { | 2201 switch (op_) { |
| 2202 case Token::ADD: | 2202 case Token::ADD: |
| 2203 case Token::SUB: | 2203 case Token::SUB: |
| 2204 case Token::MUL: | 2204 case Token::MUL: |
| 2205 case Token::DIV: { | 2205 case Token::DIV: { |
| 2206 Label not_floats; | 2206 Label not_floats; |
| 2207 if (CpuFeatures::IsSupported(SSE2)) { | 2207 if (CpuFeatures::IsSupported(SSE2)) { |
| 2208 CpuFeatures::Scope use_sse2(SSE2); | 2208 CpuFeatureScope use_sse2(masm, SSE2); |
| 2209 FloatingPointHelper::LoadSSE2Operands(masm, ¬_floats); | 2209 FloatingPointHelper::LoadSSE2Operands(masm, ¬_floats); |
| 2210 | 2210 |
| 2211 switch (op_) { | 2211 switch (op_) { |
| 2212 case Token::ADD: __ addsd(xmm0, xmm1); break; | 2212 case Token::ADD: __ addsd(xmm0, xmm1); break; |
| 2213 case Token::SUB: __ subsd(xmm0, xmm1); break; | 2213 case Token::SUB: __ subsd(xmm0, xmm1); break; |
| 2214 case Token::MUL: __ mulsd(xmm0, xmm1); break; | 2214 case Token::MUL: __ mulsd(xmm0, xmm1); break; |
| 2215 case Token::DIV: __ divsd(xmm0, xmm1); break; | 2215 case Token::DIV: __ divsd(xmm0, xmm1); break; |
| 2216 default: UNREACHABLE(); | 2216 default: UNREACHABLE(); |
| 2217 } | 2217 } |
| 2218 BinaryOpStub_GenerateHeapResultAllocation(masm, &call_runtime, mode_); | 2218 BinaryOpStub_GenerateHeapResultAllocation(masm, &call_runtime, mode_); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2299 __ JumpIfNotSmi(eax, &skip_allocation, Label::kNear); | 2299 __ JumpIfNotSmi(eax, &skip_allocation, Label::kNear); |
| 2300 // Fall through! | 2300 // Fall through! |
| 2301 case NO_OVERWRITE: | 2301 case NO_OVERWRITE: |
| 2302 __ AllocateHeapNumber(eax, ecx, edx, &call_runtime); | 2302 __ AllocateHeapNumber(eax, ecx, edx, &call_runtime); |
| 2303 __ bind(&skip_allocation); | 2303 __ bind(&skip_allocation); |
| 2304 break; | 2304 break; |
| 2305 default: UNREACHABLE(); | 2305 default: UNREACHABLE(); |
| 2306 } | 2306 } |
| 2307 // Store the result in the HeapNumber and return. | 2307 // Store the result in the HeapNumber and return. |
| 2308 if (CpuFeatures::IsSupported(SSE2)) { | 2308 if (CpuFeatures::IsSupported(SSE2)) { |
| 2309 CpuFeatures::Scope use_sse2(SSE2); | 2309 CpuFeatureScope use_sse2(masm, SSE2); |
| 2310 __ cvtsi2sd(xmm0, ebx); | 2310 __ cvtsi2sd(xmm0, ebx); |
| 2311 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0); | 2311 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0); |
| 2312 } else { | 2312 } else { |
| 2313 __ mov(Operand(esp, 1 * kPointerSize), ebx); | 2313 __ mov(Operand(esp, 1 * kPointerSize), ebx); |
| 2314 __ fild_s(Operand(esp, 1 * kPointerSize)); | 2314 __ fild_s(Operand(esp, 1 * kPointerSize)); |
| 2315 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); | 2315 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); |
| 2316 } | 2316 } |
| 2317 __ ret(2 * kPointerSize); | 2317 __ ret(2 * kPointerSize); |
| 2318 } | 2318 } |
| 2319 break; | 2319 break; |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2469 __ cmp(ebx, Immediate(factory->heap_number_map())); | 2469 __ cmp(ebx, Immediate(factory->heap_number_map())); |
| 2470 __ j(not_equal, &runtime_call); | 2470 __ j(not_equal, &runtime_call); |
| 2471 // Input is a HeapNumber. Push it on the FPU stack and load its | 2471 // Input is a HeapNumber. Push it on the FPU stack and load its |
| 2472 // low and high words into ebx, edx. | 2472 // low and high words into ebx, edx. |
| 2473 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset)); | 2473 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset)); |
| 2474 __ mov(edx, FieldOperand(eax, HeapNumber::kExponentOffset)); | 2474 __ mov(edx, FieldOperand(eax, HeapNumber::kExponentOffset)); |
| 2475 __ mov(ebx, FieldOperand(eax, HeapNumber::kMantissaOffset)); | 2475 __ mov(ebx, FieldOperand(eax, HeapNumber::kMantissaOffset)); |
| 2476 | 2476 |
| 2477 __ bind(&loaded); | 2477 __ bind(&loaded); |
| 2478 } else { // UNTAGGED. | 2478 } else { // UNTAGGED. |
| 2479 CpuFeatures::Scope scope(SSE2); | 2479 CpuFeatureScope scope(masm, SSE2); |
| 2480 if (CpuFeatures::IsSupported(SSE4_1)) { | 2480 if (CpuFeatures::IsSupported(SSE4_1)) { |
| 2481 CpuFeatures::Scope sse4_scope(SSE4_1); | 2481 CpuFeatureScope sse4_scope(masm, SSE4_1); |
| 2482 __ pextrd(edx, xmm1, 0x1); // copy xmm1[63..32] to edx. | 2482 __ pextrd(edx, xmm1, 0x1); // copy xmm1[63..32] to edx. |
| 2483 } else { | 2483 } else { |
| 2484 __ pshufd(xmm0, xmm1, 0x1); | 2484 __ pshufd(xmm0, xmm1, 0x1); |
| 2485 __ movd(edx, xmm0); | 2485 __ movd(edx, xmm0); |
| 2486 } | 2486 } |
| 2487 __ movd(ebx, xmm1); | 2487 __ movd(ebx, xmm1); |
| 2488 } | 2488 } |
| 2489 | 2489 |
| 2490 // ST[0] or xmm1 == double value | 2490 // ST[0] or xmm1 == double value |
| 2491 // ebx = low 32 bits of double value | 2491 // ebx = low 32 bits of double value |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2542 __ cmp(edx, Operand(ecx, kIntSize)); | 2542 __ cmp(edx, Operand(ecx, kIntSize)); |
| 2543 __ j(not_equal, &cache_miss, Label::kNear); | 2543 __ j(not_equal, &cache_miss, Label::kNear); |
| 2544 // Cache hit! | 2544 // Cache hit! |
| 2545 Counters* counters = masm->isolate()->counters(); | 2545 Counters* counters = masm->isolate()->counters(); |
| 2546 __ IncrementCounter(counters->transcendental_cache_hit(), 1); | 2546 __ IncrementCounter(counters->transcendental_cache_hit(), 1); |
| 2547 __ mov(eax, Operand(ecx, 2 * kIntSize)); | 2547 __ mov(eax, Operand(ecx, 2 * kIntSize)); |
| 2548 if (tagged) { | 2548 if (tagged) { |
| 2549 __ fstp(0); | 2549 __ fstp(0); |
| 2550 __ ret(kPointerSize); | 2550 __ ret(kPointerSize); |
| 2551 } else { // UNTAGGED. | 2551 } else { // UNTAGGED. |
| 2552 CpuFeatures::Scope scope(SSE2); | 2552 CpuFeatureScope scope(masm, SSE2); |
| 2553 __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset)); | 2553 __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset)); |
| 2554 __ Ret(); | 2554 __ Ret(); |
| 2555 } | 2555 } |
| 2556 | 2556 |
| 2557 __ bind(&cache_miss); | 2557 __ bind(&cache_miss); |
| 2558 __ IncrementCounter(counters->transcendental_cache_miss(), 1); | 2558 __ IncrementCounter(counters->transcendental_cache_miss(), 1); |
| 2559 // Update cache with new value. | 2559 // Update cache with new value. |
| 2560 // We are short on registers, so use no_reg as scratch. | 2560 // We are short on registers, so use no_reg as scratch. |
| 2561 // This gives slightly larger code. | 2561 // This gives slightly larger code. |
| 2562 if (tagged) { | 2562 if (tagged) { |
| 2563 __ AllocateHeapNumber(eax, edi, no_reg, &runtime_call_clear_stack); | 2563 __ AllocateHeapNumber(eax, edi, no_reg, &runtime_call_clear_stack); |
| 2564 } else { // UNTAGGED. | 2564 } else { // UNTAGGED. |
| 2565 CpuFeatures::Scope scope(SSE2); | 2565 CpuFeatureScope scope(masm, SSE2); |
| 2566 __ AllocateHeapNumber(eax, edi, no_reg, &skip_cache); | 2566 __ AllocateHeapNumber(eax, edi, no_reg, &skip_cache); |
| 2567 __ sub(esp, Immediate(kDoubleSize)); | 2567 __ sub(esp, Immediate(kDoubleSize)); |
| 2568 __ movdbl(Operand(esp, 0), xmm1); | 2568 __ movdbl(Operand(esp, 0), xmm1); |
| 2569 __ fld_d(Operand(esp, 0)); | 2569 __ fld_d(Operand(esp, 0)); |
| 2570 __ add(esp, Immediate(kDoubleSize)); | 2570 __ add(esp, Immediate(kDoubleSize)); |
| 2571 } | 2571 } |
| 2572 GenerateOperation(masm, type_); | 2572 GenerateOperation(masm, type_); |
| 2573 __ mov(Operand(ecx, 0), ebx); | 2573 __ mov(Operand(ecx, 0), ebx); |
| 2574 __ mov(Operand(ecx, kIntSize), edx); | 2574 __ mov(Operand(ecx, kIntSize), edx); |
| 2575 __ mov(Operand(ecx, 2 * kIntSize), eax); | 2575 __ mov(Operand(ecx, 2 * kIntSize), eax); |
| 2576 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); | 2576 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); |
| 2577 if (tagged) { | 2577 if (tagged) { |
| 2578 __ ret(kPointerSize); | 2578 __ ret(kPointerSize); |
| 2579 } else { // UNTAGGED. | 2579 } else { // UNTAGGED. |
| 2580 CpuFeatures::Scope scope(SSE2); | 2580 CpuFeatureScope scope(masm, SSE2); |
| 2581 __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset)); | 2581 __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset)); |
| 2582 __ Ret(); | 2582 __ Ret(); |
| 2583 | 2583 |
| 2584 // Skip cache and return answer directly, only in untagged case. | 2584 // Skip cache and return answer directly, only in untagged case. |
| 2585 __ bind(&skip_cache); | 2585 __ bind(&skip_cache); |
| 2586 __ sub(esp, Immediate(kDoubleSize)); | 2586 __ sub(esp, Immediate(kDoubleSize)); |
| 2587 __ movdbl(Operand(esp, 0), xmm1); | 2587 __ movdbl(Operand(esp, 0), xmm1); |
| 2588 __ fld_d(Operand(esp, 0)); | 2588 __ fld_d(Operand(esp, 0)); |
| 2589 GenerateOperation(masm, type_); | 2589 GenerateOperation(masm, type_); |
| 2590 __ fstp_d(Operand(esp, 0)); | 2590 __ fstp_d(Operand(esp, 0)); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2603 | 2603 |
| 2604 // Call runtime, doing whatever allocation and cleanup is necessary. | 2604 // Call runtime, doing whatever allocation and cleanup is necessary. |
| 2605 if (tagged) { | 2605 if (tagged) { |
| 2606 __ bind(&runtime_call_clear_stack); | 2606 __ bind(&runtime_call_clear_stack); |
| 2607 __ fstp(0); | 2607 __ fstp(0); |
| 2608 __ bind(&runtime_call); | 2608 __ bind(&runtime_call); |
| 2609 ExternalReference runtime = | 2609 ExternalReference runtime = |
| 2610 ExternalReference(RuntimeFunction(), masm->isolate()); | 2610 ExternalReference(RuntimeFunction(), masm->isolate()); |
| 2611 __ TailCallExternalReference(runtime, 1, 1); | 2611 __ TailCallExternalReference(runtime, 1, 1); |
| 2612 } else { // UNTAGGED. | 2612 } else { // UNTAGGED. |
| 2613 CpuFeatures::Scope scope(SSE2); | 2613 CpuFeatureScope scope(masm, SSE2); |
| 2614 __ bind(&runtime_call_clear_stack); | 2614 __ bind(&runtime_call_clear_stack); |
| 2615 __ bind(&runtime_call); | 2615 __ bind(&runtime_call); |
| 2616 __ AllocateHeapNumber(eax, edi, no_reg, &skip_cache); | 2616 __ AllocateHeapNumber(eax, edi, no_reg, &skip_cache); |
| 2617 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm1); | 2617 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm1); |
| 2618 { | 2618 { |
| 2619 FrameScope scope(masm, StackFrame::INTERNAL); | 2619 FrameScope scope(masm, StackFrame::INTERNAL); |
| 2620 __ push(eax); | 2620 __ push(eax); |
| 2621 __ CallRuntime(RuntimeFunction(), 1); | 2621 __ CallRuntime(RuntimeFunction(), 1); |
| 2622 } | 2622 } |
| 2623 __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset)); | 2623 __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset)); |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2769 __ mov(edx, Immediate(0)); | 2769 __ mov(edx, Immediate(0)); |
| 2770 __ jmp(&load_arg2); | 2770 __ jmp(&load_arg2); |
| 2771 | 2771 |
| 2772 __ bind(&arg1_is_object); | 2772 __ bind(&arg1_is_object); |
| 2773 __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset)); | 2773 __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset)); |
| 2774 __ cmp(ebx, factory->heap_number_map()); | 2774 __ cmp(ebx, factory->heap_number_map()); |
| 2775 __ j(not_equal, &check_undefined_arg1); | 2775 __ j(not_equal, &check_undefined_arg1); |
| 2776 | 2776 |
| 2777 // Get the untagged integer version of the edx heap number in ecx. | 2777 // Get the untagged integer version of the edx heap number in ecx. |
| 2778 if (left_type == BinaryOpIC::INT32 && CpuFeatures::IsSupported(SSE2)) { | 2778 if (left_type == BinaryOpIC::INT32 && CpuFeatures::IsSupported(SSE2)) { |
| 2779 CpuFeatures::Scope use_sse2(SSE2); | 2779 CpuFeatureScope use_sse2(masm, SSE2); |
| 2780 ConvertHeapNumberToInt32(masm, edx, conversion_failure); | 2780 ConvertHeapNumberToInt32(masm, edx, conversion_failure); |
| 2781 } else { | 2781 } else { |
| 2782 IntegerConvert(masm, edx, use_sse3, conversion_failure); | 2782 IntegerConvert(masm, edx, use_sse3, conversion_failure); |
| 2783 } | 2783 } |
| 2784 __ mov(edx, ecx); | 2784 __ mov(edx, ecx); |
| 2785 | 2785 |
| 2786 // Here edx has the untagged integer, eax has a Smi or a heap number. | 2786 // Here edx has the untagged integer, eax has a Smi or a heap number. |
| 2787 __ bind(&load_arg2); | 2787 __ bind(&load_arg2); |
| 2788 | 2788 |
| 2789 // Test if arg2 is a Smi. | 2789 // Test if arg2 is a Smi. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 2804 __ mov(ecx, Immediate(0)); | 2804 __ mov(ecx, Immediate(0)); |
| 2805 __ jmp(&done); | 2805 __ jmp(&done); |
| 2806 | 2806 |
| 2807 __ bind(&arg2_is_object); | 2807 __ bind(&arg2_is_object); |
| 2808 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); | 2808 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); |
| 2809 __ cmp(ebx, factory->heap_number_map()); | 2809 __ cmp(ebx, factory->heap_number_map()); |
| 2810 __ j(not_equal, &check_undefined_arg2); | 2810 __ j(not_equal, &check_undefined_arg2); |
| 2811 // Get the untagged integer version of the eax heap number in ecx. | 2811 // Get the untagged integer version of the eax heap number in ecx. |
| 2812 | 2812 |
| 2813 if (right_type == BinaryOpIC::INT32 && CpuFeatures::IsSupported(SSE2)) { | 2813 if (right_type == BinaryOpIC::INT32 && CpuFeatures::IsSupported(SSE2)) { |
| 2814 CpuFeatures::Scope use_sse2(SSE2); | 2814 CpuFeatureScope use_sse2(masm, SSE2); |
| 2815 ConvertHeapNumberToInt32(masm, eax, conversion_failure); | 2815 ConvertHeapNumberToInt32(masm, eax, conversion_failure); |
| 2816 } else { | 2816 } else { |
| 2817 IntegerConvert(masm, eax, use_sse3, conversion_failure); | 2817 IntegerConvert(masm, eax, use_sse3, conversion_failure); |
| 2818 } | 2818 } |
| 2819 | 2819 |
| 2820 __ bind(&done); | 2820 __ bind(&done); |
| 2821 __ mov(eax, edx); | 2821 __ mov(eax, edx); |
| 2822 } | 2822 } |
| 2823 | 2823 |
| 2824 | 2824 |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3012 __ mov(scratch, FieldOperand(eax, HeapObject::kMapOffset)); | 3012 __ mov(scratch, FieldOperand(eax, HeapObject::kMapOffset)); |
| 3013 __ cmp(scratch, factory->heap_number_map()); | 3013 __ cmp(scratch, factory->heap_number_map()); |
| 3014 __ j(not_equal, non_float); // argument in eax is not a number -> NaN | 3014 __ j(not_equal, non_float); // argument in eax is not a number -> NaN |
| 3015 | 3015 |
| 3016 // Fall-through: Both operands are numbers. | 3016 // Fall-through: Both operands are numbers. |
| 3017 __ bind(&done); | 3017 __ bind(&done); |
| 3018 } | 3018 } |
| 3019 | 3019 |
| 3020 | 3020 |
| 3021 void MathPowStub::Generate(MacroAssembler* masm) { | 3021 void MathPowStub::Generate(MacroAssembler* masm) { |
| 3022 CpuFeatures::Scope use_sse2(SSE2); | 3022 CpuFeatureScope use_sse2(masm, SSE2); |
| 3023 Factory* factory = masm->isolate()->factory(); | 3023 Factory* factory = masm->isolate()->factory(); |
| 3024 const Register exponent = eax; | 3024 const Register exponent = eax; |
| 3025 const Register base = edx; | 3025 const Register base = edx; |
| 3026 const Register scratch = ecx; | 3026 const Register scratch = ecx; |
| 3027 const XMMRegister double_result = xmm3; | 3027 const XMMRegister double_result = xmm3; |
| 3028 const XMMRegister double_base = xmm2; | 3028 const XMMRegister double_base = xmm2; |
| 3029 const XMMRegister double_exponent = xmm1; | 3029 const XMMRegister double_exponent = xmm1; |
| 3030 const XMMRegister double_scratch = xmm4; | 3030 const XMMRegister double_scratch = xmm4; |
| 3031 | 3031 |
| 3032 Label call_runtime, done, exponent_not_smi, int_exponent; | 3032 Label call_runtime, done, exponent_not_smi, int_exponent; |
| (...skipping 1367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4400 __ and_(scratch, mask); | 4400 __ and_(scratch, mask); |
| 4401 Register index = scratch; | 4401 Register index = scratch; |
| 4402 Register probe = mask; | 4402 Register probe = mask; |
| 4403 __ mov(probe, | 4403 __ mov(probe, |
| 4404 FieldOperand(number_string_cache, | 4404 FieldOperand(number_string_cache, |
| 4405 index, | 4405 index, |
| 4406 times_twice_pointer_size, | 4406 times_twice_pointer_size, |
| 4407 FixedArray::kHeaderSize)); | 4407 FixedArray::kHeaderSize)); |
| 4408 __ JumpIfSmi(probe, not_found); | 4408 __ JumpIfSmi(probe, not_found); |
| 4409 if (CpuFeatures::IsSupported(SSE2)) { | 4409 if (CpuFeatures::IsSupported(SSE2)) { |
| 4410 CpuFeatures::Scope fscope(SSE2); | 4410 CpuFeatureScope fscope(masm, SSE2); |
| 4411 __ movdbl(xmm0, FieldOperand(object, HeapNumber::kValueOffset)); | 4411 __ movdbl(xmm0, FieldOperand(object, HeapNumber::kValueOffset)); |
| 4412 __ movdbl(xmm1, FieldOperand(probe, HeapNumber::kValueOffset)); | 4412 __ movdbl(xmm1, FieldOperand(probe, HeapNumber::kValueOffset)); |
| 4413 __ ucomisd(xmm0, xmm1); | 4413 __ ucomisd(xmm0, xmm1); |
| 4414 } else { | 4414 } else { |
| 4415 __ fld_d(FieldOperand(object, HeapNumber::kValueOffset)); | 4415 __ fld_d(FieldOperand(object, HeapNumber::kValueOffset)); |
| 4416 __ fld_d(FieldOperand(probe, HeapNumber::kValueOffset)); | 4416 __ fld_d(FieldOperand(probe, HeapNumber::kValueOffset)); |
| 4417 __ FCmp(); | 4417 __ FCmp(); |
| 4418 } | 4418 } |
| 4419 __ j(parity_even, not_found); // Bail out if NaN is involved. | 4419 __ j(parity_even, not_found); // Bail out if NaN is involved. |
| 4420 __ j(not_equal, not_found); // The cache did not contain this value. | 4420 __ j(not_equal, not_found); // The cache did not contain this value. |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4660 __ j(equal, &return_not_equal); | 4660 __ j(equal, &return_not_equal); |
| 4661 | 4661 |
| 4662 // Fall through to the general case. | 4662 // Fall through to the general case. |
| 4663 __ bind(&slow); | 4663 __ bind(&slow); |
| 4664 } | 4664 } |
| 4665 | 4665 |
| 4666 // Generate the number comparison code. | 4666 // Generate the number comparison code. |
| 4667 Label non_number_comparison; | 4667 Label non_number_comparison; |
| 4668 Label unordered; | 4668 Label unordered; |
| 4669 if (CpuFeatures::IsSupported(SSE2)) { | 4669 if (CpuFeatures::IsSupported(SSE2)) { |
| 4670 CpuFeatures::Scope use_sse2(SSE2); | 4670 CpuFeatureScope use_sse2(masm, SSE2); |
| 4671 CpuFeatures::Scope use_cmov(CMOV); | 4671 CpuFeatureScope use_cmov(masm, CMOV); |
| 4672 | 4672 |
| 4673 FloatingPointHelper::LoadSSE2Operands(masm, &non_number_comparison); | 4673 FloatingPointHelper::LoadSSE2Operands(masm, &non_number_comparison); |
| 4674 __ ucomisd(xmm0, xmm1); | 4674 __ ucomisd(xmm0, xmm1); |
| 4675 | 4675 |
| 4676 // Don't base result on EFLAGS when a NaN is involved. | 4676 // Don't base result on EFLAGS when a NaN is involved. |
| 4677 __ j(parity_even, &unordered, Label::kNear); | 4677 __ j(parity_even, &unordered, Label::kNear); |
| 4678 // Return a result of -1, 0, or 1, based on EFLAGS. | 4678 // Return a result of -1, 0, or 1, based on EFLAGS. |
| 4679 __ mov(eax, 0); // equal | 4679 __ mov(eax, 0); // equal |
| 4680 __ mov(ecx, Immediate(Smi::FromInt(1))); | 4680 __ mov(ecx, Immediate(Smi::FromInt(1))); |
| 4681 __ cmov(above, eax, ecx); | 4681 __ cmov(above, eax, ecx); |
| (...skipping 2201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6883 if (left_ == CompareIC::SMI) { | 6883 if (left_ == CompareIC::SMI) { |
| 6884 __ JumpIfNotSmi(edx, &miss); | 6884 __ JumpIfNotSmi(edx, &miss); |
| 6885 } | 6885 } |
| 6886 if (right_ == CompareIC::SMI) { | 6886 if (right_ == CompareIC::SMI) { |
| 6887 __ JumpIfNotSmi(eax, &miss); | 6887 __ JumpIfNotSmi(eax, &miss); |
| 6888 } | 6888 } |
| 6889 | 6889 |
| 6890 // Inlining the double comparison and falling back to the general compare | 6890 // Inlining the double comparison and falling back to the general compare |
| 6891 // stub if NaN is involved or SSE2 or CMOV is unsupported. | 6891 // stub if NaN is involved or SSE2 or CMOV is unsupported. |
| 6892 if (CpuFeatures::IsSupported(SSE2) && CpuFeatures::IsSupported(CMOV)) { | 6892 if (CpuFeatures::IsSupported(SSE2) && CpuFeatures::IsSupported(CMOV)) { |
| 6893 CpuFeatures::Scope scope1(SSE2); | 6893 CpuFeatureScope scope1(masm, SSE2); |
| 6894 CpuFeatures::Scope scope2(CMOV); | 6894 CpuFeatureScope scope2(masm, CMOV); |
| 6895 | 6895 |
| 6896 // Load left and right operand. | 6896 // Load left and right operand. |
| 6897 Label done, left, left_smi, right_smi; | 6897 Label done, left, left_smi, right_smi; |
| 6898 __ JumpIfSmi(eax, &right_smi, Label::kNear); | 6898 __ JumpIfSmi(eax, &right_smi, Label::kNear); |
| 6899 __ cmp(FieldOperand(eax, HeapObject::kMapOffset), | 6899 __ cmp(FieldOperand(eax, HeapObject::kMapOffset), |
| 6900 masm->isolate()->factory()->heap_number_map()); | 6900 masm->isolate()->factory()->heap_number_map()); |
| 6901 __ j(not_equal, &maybe_undefined1, Label::kNear); | 6901 __ j(not_equal, &maybe_undefined1, Label::kNear); |
| 6902 __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset)); | 6902 __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset)); |
| 6903 __ jmp(&left, Label::kNear); | 6903 __ jmp(&left, Label::kNear); |
| 6904 __ bind(&right_smi); | 6904 __ bind(&right_smi); |
| (...skipping 968 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7873 // Restore ecx. | 7873 // Restore ecx. |
| 7874 __ pop(ecx); | 7874 __ pop(ecx); |
| 7875 __ ret(0); | 7875 __ ret(0); |
| 7876 } | 7876 } |
| 7877 | 7877 |
| 7878 #undef __ | 7878 #undef __ |
| 7879 | 7879 |
| 7880 } } // namespace v8::internal | 7880 } } // namespace v8::internal |
| 7881 | 7881 |
| 7882 #endif // V8_TARGET_ARCH_IA32 | 7882 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |