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

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

Issue 12391055: Cleaned up CpuFeature scope handling. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fixed nits Created 7 years, 9 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/code-stubs-ia32.h ('k') | src/ia32/codegen-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 // 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
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
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
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
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
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
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, &not_int32); 1788 __ JumpIfNotSmi(edx, &not_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
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
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, &not_floats); 2010 __ JumpIfNotSmi(edx, &not_floats);
2011 } 2011 }
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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, &not_floats); 2209 FloatingPointHelper::LoadSSE2Operands(masm, &not_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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/ia32/code-stubs-ia32.h ('k') | src/ia32/codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698