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 1361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4394 __ and_(scratch, mask); | 4394 __ and_(scratch, mask); |
4395 Register index = scratch; | 4395 Register index = scratch; |
4396 Register probe = mask; | 4396 Register probe = mask; |
4397 __ mov(probe, | 4397 __ mov(probe, |
4398 FieldOperand(number_string_cache, | 4398 FieldOperand(number_string_cache, |
4399 index, | 4399 index, |
4400 times_twice_pointer_size, | 4400 times_twice_pointer_size, |
4401 FixedArray::kHeaderSize)); | 4401 FixedArray::kHeaderSize)); |
4402 __ JumpIfSmi(probe, not_found); | 4402 __ JumpIfSmi(probe, not_found); |
4403 if (CpuFeatures::IsSupported(SSE2)) { | 4403 if (CpuFeatures::IsSupported(SSE2)) { |
4404 CpuFeatures::Scope fscope(SSE2); | 4404 CpuFeatureScope fscope(masm, SSE2); |
4405 __ movdbl(xmm0, FieldOperand(object, HeapNumber::kValueOffset)); | 4405 __ movdbl(xmm0, FieldOperand(object, HeapNumber::kValueOffset)); |
4406 __ movdbl(xmm1, FieldOperand(probe, HeapNumber::kValueOffset)); | 4406 __ movdbl(xmm1, FieldOperand(probe, HeapNumber::kValueOffset)); |
4407 __ ucomisd(xmm0, xmm1); | 4407 __ ucomisd(xmm0, xmm1); |
4408 } else { | 4408 } else { |
4409 __ fld_d(FieldOperand(object, HeapNumber::kValueOffset)); | 4409 __ fld_d(FieldOperand(object, HeapNumber::kValueOffset)); |
4410 __ fld_d(FieldOperand(probe, HeapNumber::kValueOffset)); | 4410 __ fld_d(FieldOperand(probe, HeapNumber::kValueOffset)); |
4411 __ FCmp(); | 4411 __ FCmp(); |
4412 } | 4412 } |
4413 __ j(parity_even, not_found); // Bail out if NaN is involved. | 4413 __ j(parity_even, not_found); // Bail out if NaN is involved. |
4414 __ j(not_equal, not_found); // The cache did not contain this value. | 4414 __ 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... |
4654 __ j(equal, &return_not_equal); | 4654 __ j(equal, &return_not_equal); |
4655 | 4655 |
4656 // Fall through to the general case. | 4656 // Fall through to the general case. |
4657 __ bind(&slow); | 4657 __ bind(&slow); |
4658 } | 4658 } |
4659 | 4659 |
4660 // Generate the number comparison code. | 4660 // Generate the number comparison code. |
4661 Label non_number_comparison; | 4661 Label non_number_comparison; |
4662 Label unordered; | 4662 Label unordered; |
4663 if (CpuFeatures::IsSupported(SSE2)) { | 4663 if (CpuFeatures::IsSupported(SSE2)) { |
4664 CpuFeatures::Scope use_sse2(SSE2); | 4664 CpuFeatureScope use_sse2(masm, SSE2); |
4665 CpuFeatures::Scope use_cmov(CMOV); | 4665 CpuFeatureScope use_cmov(masm, CMOV); |
4666 | 4666 |
4667 FloatingPointHelper::LoadSSE2Operands(masm, &non_number_comparison); | 4667 FloatingPointHelper::LoadSSE2Operands(masm, &non_number_comparison); |
4668 __ ucomisd(xmm0, xmm1); | 4668 __ ucomisd(xmm0, xmm1); |
4669 | 4669 |
4670 // Don't base result on EFLAGS when a NaN is involved. | 4670 // Don't base result on EFLAGS when a NaN is involved. |
4671 __ j(parity_even, &unordered, Label::kNear); | 4671 __ j(parity_even, &unordered, Label::kNear); |
4672 // Return a result of -1, 0, or 1, based on EFLAGS. | 4672 // Return a result of -1, 0, or 1, based on EFLAGS. |
4673 __ mov(eax, 0); // equal | 4673 __ mov(eax, 0); // equal |
4674 __ mov(ecx, Immediate(Smi::FromInt(1))); | 4674 __ mov(ecx, Immediate(Smi::FromInt(1))); |
4675 __ cmov(above, eax, ecx); | 4675 __ cmov(above, eax, ecx); |
(...skipping 2201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6877 if (left_ == CompareIC::SMI) { | 6877 if (left_ == CompareIC::SMI) { |
6878 __ JumpIfNotSmi(edx, &miss); | 6878 __ JumpIfNotSmi(edx, &miss); |
6879 } | 6879 } |
6880 if (right_ == CompareIC::SMI) { | 6880 if (right_ == CompareIC::SMI) { |
6881 __ JumpIfNotSmi(eax, &miss); | 6881 __ JumpIfNotSmi(eax, &miss); |
6882 } | 6882 } |
6883 | 6883 |
6884 // Inlining the double comparison and falling back to the general compare | 6884 // Inlining the double comparison and falling back to the general compare |
6885 // stub if NaN is involved or SSE2 or CMOV is unsupported. | 6885 // stub if NaN is involved or SSE2 or CMOV is unsupported. |
6886 if (CpuFeatures::IsSupported(SSE2) && CpuFeatures::IsSupported(CMOV)) { | 6886 if (CpuFeatures::IsSupported(SSE2) && CpuFeatures::IsSupported(CMOV)) { |
6887 CpuFeatures::Scope scope1(SSE2); | 6887 CpuFeatureScope scope1(masm, SSE2); |
6888 CpuFeatures::Scope scope2(CMOV); | 6888 CpuFeatureScope scope2(masm, CMOV); |
6889 | 6889 |
6890 // Load left and right operand. | 6890 // Load left and right operand. |
6891 Label done, left, left_smi, right_smi; | 6891 Label done, left, left_smi, right_smi; |
6892 __ JumpIfSmi(eax, &right_smi, Label::kNear); | 6892 __ JumpIfSmi(eax, &right_smi, Label::kNear); |
6893 __ cmp(FieldOperand(eax, HeapObject::kMapOffset), | 6893 __ cmp(FieldOperand(eax, HeapObject::kMapOffset), |
6894 masm->isolate()->factory()->heap_number_map()); | 6894 masm->isolate()->factory()->heap_number_map()); |
6895 __ j(not_equal, &maybe_undefined1, Label::kNear); | 6895 __ j(not_equal, &maybe_undefined1, Label::kNear); |
6896 __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset)); | 6896 __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset)); |
6897 __ jmp(&left, Label::kNear); | 6897 __ jmp(&left, Label::kNear); |
6898 __ bind(&right_smi); | 6898 __ bind(&right_smi); |
(...skipping 966 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7865 // Restore ecx. | 7865 // Restore ecx. |
7866 __ pop(ecx); | 7866 __ pop(ecx); |
7867 __ ret(0); | 7867 __ ret(0); |
7868 } | 7868 } |
7869 | 7869 |
7870 #undef __ | 7870 #undef __ |
7871 | 7871 |
7872 } } // namespace v8::internal | 7872 } } // namespace v8::internal |
7873 | 7873 |
7874 #endif // V8_TARGET_ARCH_IA32 | 7874 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |