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

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

Issue 12223039: Add missing type feedback collection to ia32 BinaryOpStubs for bitwise operations (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 10 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 | « no previous file | no next file » | 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 729 matching lines...) Expand 10 before | Expand all | Expand 10 after
740 // Expects operands in edx, eax. 740 // Expects operands in edx, eax.
741 static void LoadFloatSmis(MacroAssembler* masm, Register scratch); 741 static void LoadFloatSmis(MacroAssembler* masm, Register scratch);
742 742
743 // Test if operands are smi or number objects (fp). Requirements: 743 // Test if operands are smi or number objects (fp). Requirements:
744 // operand_1 in eax, operand_2 in edx; falls through on float 744 // operand_1 in eax, operand_2 in edx; falls through on float
745 // operands, jumps to the non_float label otherwise. 745 // operands, jumps to the non_float label otherwise.
746 static void CheckFloatOperands(MacroAssembler* masm, 746 static void CheckFloatOperands(MacroAssembler* masm,
747 Label* non_float, 747 Label* non_float,
748 Register scratch); 748 Register scratch);
749 749
750 // Checks that the two floating point numbers on top of the FPU stack
751 // have int32 values.
752 static void CheckFloatOperandsAreInt32(MacroAssembler* masm,
753 Label* non_int32);
754
755 // Takes the operands in edx and eax and loads them as integers in eax 750 // Takes the operands in edx and eax and loads them as integers in eax
756 // and ecx. 751 // and ecx.
757 static void LoadUnknownsAsIntegers(MacroAssembler* masm, 752 static void LoadUnknownsAsIntegers(MacroAssembler* masm,
758 bool use_sse3, 753 bool use_sse3,
754 BinaryOpIC::TypeInfo left_type,
755 BinaryOpIC::TypeInfo right_type,
759 Label* operand_conversion_failure); 756 Label* operand_conversion_failure);
760 757
761 // Must only be called after LoadUnknownsAsIntegers. Assumes that the
762 // operands are pushed on the stack, and that their conversions to int32
763 // are in eax and ecx. Checks that the original numbers were in the int32
764 // range.
765 static void CheckLoadedIntegersWereInt32(MacroAssembler* masm,
766 bool use_sse3,
767 Label* not_int32);
768
769 // Assumes that operands are smis or heap numbers and loads them 758 // Assumes that operands are smis or heap numbers and loads them
770 // into xmm0 and xmm1. Operands are in edx and eax. 759 // into xmm0 and xmm1. Operands are in edx and eax.
771 // Leaves operands unchanged. 760 // Leaves operands unchanged.
772 static void LoadSSE2Operands(MacroAssembler* masm); 761 static void LoadSSE2Operands(MacroAssembler* masm);
773 762
774 // Test if operands are numbers (smi or HeapNumber objects), and load 763 // Test if operands are numbers (smi or HeapNumber objects), and load
775 // them into xmm0 and xmm1 if they are. Jump to label not_numbers if 764 // them into xmm0 and xmm1 if they are. Jump to label not_numbers if
776 // either operand is not a number. Operands are in edx and eax. 765 // either operand is not a number. Operands are in edx and eax.
777 // Leaves operands unchanged. 766 // Leaves operands unchanged.
778 static void LoadSSE2Operands(MacroAssembler* masm, Label* not_numbers); 767 static void LoadSSE2Operands(MacroAssembler* masm, Label* not_numbers);
779 768
780 // Similar to LoadSSE2Operands but assumes that both operands are smis. 769 // Similar to LoadSSE2Operands but assumes that both operands are smis.
781 // Expects operands in edx, eax. 770 // Expects operands in edx, eax.
782 static void LoadSSE2Smis(MacroAssembler* masm, Register scratch); 771 static void LoadSSE2Smis(MacroAssembler* masm, Register scratch);
783 772
784 // Checks that the two floating point numbers loaded into xmm0 and xmm1 773 // Checks that the two floating point numbers loaded into xmm0 and xmm1
785 // have int32 values. 774 // have int32 values.
786 static void CheckSSE2OperandsAreInt32(MacroAssembler* masm, 775 static void CheckSSE2OperandsAreInt32(MacroAssembler* masm,
787 Label* non_int32, 776 Label* non_int32,
788 Register scratch); 777 Register scratch);
789 778
779 // Checks that |operand| has an int32 value. If |int32_result| is different
780 // from |scratch|, it will contain that int32 value.
790 static void CheckSSE2OperandIsInt32(MacroAssembler* masm, 781 static void CheckSSE2OperandIsInt32(MacroAssembler* masm,
791 Label* non_int32, 782 Label* non_int32,
792 XMMRegister operand, 783 XMMRegister operand,
784 Register int32_result,
793 Register scratch, 785 Register scratch,
794 XMMRegister xmm_scratch); 786 XMMRegister xmm_scratch);
795 }; 787 };
796 788
797 789
798 // Get the integer part of a heap number. Surprisingly, all this bit twiddling 790 // Get the integer part of a heap number. Surprisingly, all this bit twiddling
799 // is faster than using the built-in instructions on floating point registers. 791 // is faster than using the built-in instructions on floating point registers.
800 // Trashes edi and ebx. Dest is ecx. Source cannot be ecx or one of the 792 // Trashes edi and ebx. Dest is ecx. Source cannot be ecx or one of the
801 // trashed registers. 793 // trashed registers.
802 static void IntegerConvert(MacroAssembler* masm, 794 static void IntegerConvert(MacroAssembler* masm,
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
916 __ j(greater, &negative, Label::kNear); 908 __ j(greater, &negative, Label::kNear);
917 __ mov(ecx, scratch2); 909 __ mov(ecx, scratch2);
918 __ jmp(&done, Label::kNear); 910 __ jmp(&done, Label::kNear);
919 __ bind(&negative); 911 __ bind(&negative);
920 __ sub(ecx, scratch2); 912 __ sub(ecx, scratch2);
921 } 913 }
922 __ bind(&done); 914 __ bind(&done);
923 } 915 }
924 916
925 917
918 // Uses SSE2 to convert the heap number in |source| to an integer.
919 // Result is in ecx. Trashes ebx, xmm0, and xmm1.
920 static void ConvertHeapNumberToInt32(MacroAssembler* masm,
Jakob Kummerow 2013/02/07 15:28:35 Basically a drop-in replacement for IntegerConvert
921 Register source,
922 Label* conversion_failure) {
923 __ movdbl(xmm0, FieldOperand(source, HeapNumber::kValueOffset));
924 FloatingPointHelper::CheckSSE2OperandIsInt32(
925 masm, conversion_failure, xmm0, ecx, ebx, xmm1);
926 }
927
928
926 void UnaryOpStub::PrintName(StringStream* stream) { 929 void UnaryOpStub::PrintName(StringStream* stream) {
927 const char* op_name = Token::Name(op_); 930 const char* op_name = Token::Name(op_);
928 const char* overwrite_name = NULL; // Make g++ happy. 931 const char* overwrite_name = NULL; // Make g++ happy.
929 switch (mode_) { 932 switch (mode_) {
930 case UNARY_NO_OVERWRITE: overwrite_name = "Alloc"; break; 933 case UNARY_NO_OVERWRITE: overwrite_name = "Alloc"; break;
931 case UNARY_OVERWRITE: overwrite_name = "Overwrite"; break; 934 case UNARY_OVERWRITE: overwrite_name = "Overwrite"; break;
932 } 935 }
933 stream->Add("UnaryOpStub_%s_%s_%s", 936 stream->Add("UnaryOpStub_%s_%s_%s",
934 op_name, 937 op_name,
935 overwrite_name, 938 overwrite_name,
(...skipping 854 matching lines...) Expand 10 before | Expand all | Expand 10 after
1790 switch (op_) { 1793 switch (op_) {
1791 case Token::ADD: __ addsd(xmm0, xmm1); break; 1794 case Token::ADD: __ addsd(xmm0, xmm1); break;
1792 case Token::SUB: __ subsd(xmm0, xmm1); break; 1795 case Token::SUB: __ subsd(xmm0, xmm1); break;
1793 case Token::MUL: __ mulsd(xmm0, xmm1); break; 1796 case Token::MUL: __ mulsd(xmm0, xmm1); break;
1794 case Token::DIV: __ divsd(xmm0, xmm1); break; 1797 case Token::DIV: __ divsd(xmm0, xmm1); break;
1795 default: UNREACHABLE(); 1798 default: UNREACHABLE();
1796 } 1799 }
1797 // Check result type if it is currently Int32. 1800 // Check result type if it is currently Int32.
1798 if (result_type_ <= BinaryOpIC::INT32) { 1801 if (result_type_ <= BinaryOpIC::INT32) {
1799 FloatingPointHelper::CheckSSE2OperandIsInt32( 1802 FloatingPointHelper::CheckSSE2OperandIsInt32(
1800 masm, &not_int32, xmm0, ecx, xmm2); 1803 masm, &not_int32, xmm0, ecx, ecx, xmm2);
1801 } 1804 }
1802 BinaryOpStub_GenerateHeapResultAllocation(masm, &call_runtime, mode_); 1805 BinaryOpStub_GenerateHeapResultAllocation(masm, &call_runtime, mode_);
1803 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0); 1806 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0);
1804 __ ret(0); 1807 __ ret(0);
1805 } 1808 }
1806 } else { // SSE2 not available, use FPU. 1809 } else { // SSE2 not available, use FPU.
1807 FloatingPointHelper::CheckFloatOperands(masm, &not_floats, ebx); 1810 FloatingPointHelper::CheckFloatOperands(masm, &not_floats, ebx);
1808 FloatingPointHelper::LoadFloatOperands( 1811 FloatingPointHelper::LoadFloatOperands(
1809 masm, 1812 masm,
1810 ecx, 1813 ecx,
1811 FloatingPointHelper::ARGS_IN_REGISTERS); 1814 FloatingPointHelper::ARGS_IN_REGISTERS);
1812 FloatingPointHelper::CheckFloatOperandsAreInt32(masm, &not_int32);
1813 if (op_ == Token::MOD) { 1815 if (op_ == Token::MOD) {
1814 // The operands are now on the FPU stack, but we don't need them. 1816 // The operands are now on the FPU stack, but we don't need them.
1815 __ fstp(0); 1817 __ fstp(0);
1816 __ fstp(0); 1818 __ fstp(0);
1817 GenerateRegisterArgsPush(masm); 1819 GenerateRegisterArgsPush(masm);
1818 __ InvokeBuiltin(Builtins::MOD, JUMP_FUNCTION); 1820 __ InvokeBuiltin(Builtins::MOD, JUMP_FUNCTION);
1819 } else { 1821 } else {
1820 switch (op_) { 1822 switch (op_) {
1821 case Token::ADD: __ faddp(1); break; 1823 case Token::ADD: __ faddp(1); break;
1822 case Token::SUB: __ fsubp(1); break; 1824 case Token::SUB: __ fsubp(1); break;
(...skipping 21 matching lines...) Expand all
1844 case Token::BIT_OR: 1846 case Token::BIT_OR:
1845 case Token::BIT_AND: 1847 case Token::BIT_AND:
1846 case Token::BIT_XOR: 1848 case Token::BIT_XOR:
1847 case Token::SAR: 1849 case Token::SAR:
1848 case Token::SHL: 1850 case Token::SHL:
1849 case Token::SHR: { 1851 case Token::SHR: {
1850 GenerateRegisterArgsPush(masm); 1852 GenerateRegisterArgsPush(masm);
1851 Label not_floats; 1853 Label not_floats;
1852 Label not_int32; 1854 Label not_int32;
1853 Label non_smi_result; 1855 Label non_smi_result;
1854 // We do not check the input arguments here, as any value is
1855 // unconditionally truncated to an int32 anyway. To get the
1856 // right optimized code, int32 type feedback is just right.
Jakob Kummerow 2013/02/07 15:28:35 Yeah, well, turns out it's not quite right after a
1857 bool use_sse3 = platform_specific_bit_; 1856 bool use_sse3 = platform_specific_bit_;
1858 FloatingPointHelper::LoadUnknownsAsIntegers(masm, 1857 FloatingPointHelper::LoadUnknownsAsIntegers(
1859 use_sse3, 1858 masm, use_sse3, left_type_, right_type_, &not_floats);
1860 &not_floats);
1861 FloatingPointHelper::CheckLoadedIntegersWereInt32(masm, use_sse3,
1862 &not_int32);
1863 switch (op_) { 1859 switch (op_) {
1864 case Token::BIT_OR: __ or_(eax, ecx); break; 1860 case Token::BIT_OR: __ or_(eax, ecx); break;
1865 case Token::BIT_AND: __ and_(eax, ecx); break; 1861 case Token::BIT_AND: __ and_(eax, ecx); break;
1866 case Token::BIT_XOR: __ xor_(eax, ecx); break; 1862 case Token::BIT_XOR: __ xor_(eax, ecx); break;
1867 case Token::SAR: __ sar_cl(eax); break; 1863 case Token::SAR: __ sar_cl(eax); break;
1868 case Token::SHL: __ shl_cl(eax); break; 1864 case Token::SHL: __ shl_cl(eax); break;
1869 case Token::SHR: __ shr_cl(eax); break; 1865 case Token::SHR: __ shr_cl(eax); break;
1870 default: UNREACHABLE(); 1866 default: UNREACHABLE();
1871 } 1867 }
1872 if (op_ == Token::SHR) { 1868 if (op_ == Token::SHR) {
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
2006 // afford not to care about precise type feedback. 2002 // afford not to care about precise type feedback.
2007 if (left_type_ == BinaryOpIC::SMI) { 2003 if (left_type_ == BinaryOpIC::SMI) {
2008 __ JumpIfNotSmi(edx, &not_floats); 2004 __ JumpIfNotSmi(edx, &not_floats);
2009 } 2005 }
2010 if (right_type_ == BinaryOpIC::SMI) { 2006 if (right_type_ == BinaryOpIC::SMI) {
2011 __ JumpIfNotSmi(eax, &not_floats); 2007 __ JumpIfNotSmi(eax, &not_floats);
2012 } 2008 }
2013 FloatingPointHelper::LoadSSE2Operands(masm, &not_floats); 2009 FloatingPointHelper::LoadSSE2Operands(masm, &not_floats);
2014 if (left_type_ == BinaryOpIC::INT32) { 2010 if (left_type_ == BinaryOpIC::INT32) {
2015 FloatingPointHelper::CheckSSE2OperandIsInt32( 2011 FloatingPointHelper::CheckSSE2OperandIsInt32(
2016 masm, &not_floats, xmm0, ecx, xmm2); 2012 masm, &not_floats, xmm0, ecx, ecx, xmm2);
2017 } 2013 }
2018 if (right_type_ == BinaryOpIC::INT32) { 2014 if (right_type_ == BinaryOpIC::INT32) {
2019 FloatingPointHelper::CheckSSE2OperandIsInt32( 2015 FloatingPointHelper::CheckSSE2OperandIsInt32(
2020 masm, &not_floats, xmm1, ecx, xmm2); 2016 masm, &not_floats, xmm1, ecx, ecx, xmm2);
2021 } 2017 }
2022 2018
2023 switch (op_) { 2019 switch (op_) {
2024 case Token::ADD: __ addsd(xmm0, xmm1); break; 2020 case Token::ADD: __ addsd(xmm0, xmm1); break;
2025 case Token::SUB: __ subsd(xmm0, xmm1); break; 2021 case Token::SUB: __ subsd(xmm0, xmm1); break;
2026 case Token::MUL: __ mulsd(xmm0, xmm1); break; 2022 case Token::MUL: __ mulsd(xmm0, xmm1); break;
2027 case Token::DIV: __ divsd(xmm0, xmm1); break; 2023 case Token::DIV: __ divsd(xmm0, xmm1); break;
2028 default: UNREACHABLE(); 2024 default: UNREACHABLE();
2029 } 2025 }
2030 BinaryOpStub_GenerateHeapResultAllocation(masm, &call_runtime, mode_); 2026 BinaryOpStub_GenerateHeapResultAllocation(masm, &call_runtime, mode_);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
2068 case Token::SAR: 2064 case Token::SAR:
2069 case Token::SHL: 2065 case Token::SHL:
2070 case Token::SHR: { 2066 case Token::SHR: {
2071 GenerateRegisterArgsPush(masm); 2067 GenerateRegisterArgsPush(masm);
2072 Label not_floats; 2068 Label not_floats;
2073 Label non_smi_result; 2069 Label non_smi_result;
2074 // We do not check the input arguments here, as any value is 2070 // We do not check the input arguments here, as any value is
2075 // unconditionally truncated to an int32 anyway. To get the 2071 // unconditionally truncated to an int32 anyway. To get the
2076 // right optimized code, int32 type feedback is just right. 2072 // right optimized code, int32 type feedback is just right.
2077 bool use_sse3 = platform_specific_bit_; 2073 bool use_sse3 = platform_specific_bit_;
2078 FloatingPointHelper::LoadUnknownsAsIntegers(masm, 2074 FloatingPointHelper::LoadUnknownsAsIntegers(
2079 use_sse3, 2075 masm, use_sse3, left_type_, right_type_, &not_floats);
2080 &not_floats);
2081 switch (op_) { 2076 switch (op_) {
2082 case Token::BIT_OR: __ or_(eax, ecx); break; 2077 case Token::BIT_OR: __ or_(eax, ecx); break;
2083 case Token::BIT_AND: __ and_(eax, ecx); break; 2078 case Token::BIT_AND: __ and_(eax, ecx); break;
2084 case Token::BIT_XOR: __ xor_(eax, ecx); break; 2079 case Token::BIT_XOR: __ xor_(eax, ecx); break;
2085 case Token::SAR: __ sar_cl(eax); break; 2080 case Token::SAR: __ sar_cl(eax); break;
2086 case Token::SHL: __ shl_cl(eax); break; 2081 case Token::SHL: __ shl_cl(eax); break;
2087 case Token::SHR: __ shr_cl(eax); break; 2082 case Token::SHR: __ shr_cl(eax); break;
2088 default: UNREACHABLE(); 2083 default: UNREACHABLE();
2089 } 2084 }
2090 if (op_ == Token::SHR) { 2085 if (op_ == Token::SHR) {
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
2249 case Token::BIT_OR: 2244 case Token::BIT_OR:
2250 case Token::BIT_AND: 2245 case Token::BIT_AND:
2251 case Token::BIT_XOR: 2246 case Token::BIT_XOR:
2252 case Token::SAR: 2247 case Token::SAR:
2253 case Token::SHL: 2248 case Token::SHL:
2254 case Token::SHR: { 2249 case Token::SHR: {
2255 Label non_smi_result; 2250 Label non_smi_result;
2256 bool use_sse3 = platform_specific_bit_; 2251 bool use_sse3 = platform_specific_bit_;
2257 FloatingPointHelper::LoadUnknownsAsIntegers(masm, 2252 FloatingPointHelper::LoadUnknownsAsIntegers(masm,
2258 use_sse3, 2253 use_sse3,
2254 BinaryOpIC::GENERIC,
Jakob Kummerow 2013/02/07 15:28:35 Strictly speaking, this is inconsistent, but it do
2255 BinaryOpIC::GENERIC,
2259 &call_runtime); 2256 &call_runtime);
2260 switch (op_) { 2257 switch (op_) {
2261 case Token::BIT_OR: __ or_(eax, ecx); break; 2258 case Token::BIT_OR: __ or_(eax, ecx); break;
2262 case Token::BIT_AND: __ and_(eax, ecx); break; 2259 case Token::BIT_AND: __ and_(eax, ecx); break;
2263 case Token::BIT_XOR: __ xor_(eax, ecx); break; 2260 case Token::BIT_XOR: __ xor_(eax, ecx); break;
2264 case Token::SAR: __ sar_cl(eax); break; 2261 case Token::SAR: __ sar_cl(eax); break;
2265 case Token::SHL: __ shl_cl(eax); break; 2262 case Token::SHL: __ shl_cl(eax); break;
2266 case Token::SHR: __ shr_cl(eax); break; 2263 case Token::SHR: __ shr_cl(eax); break;
2267 default: UNREACHABLE(); 2264 default: UNREACHABLE();
2268 } 2265 }
(...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after
2729 ASSERT(type == TranscendentalCache::LOG); 2726 ASSERT(type == TranscendentalCache::LOG);
2730 __ fldln2(); 2727 __ fldln2();
2731 __ fxch(); 2728 __ fxch();
2732 __ fyl2x(); 2729 __ fyl2x();
2733 } 2730 }
2734 } 2731 }
2735 2732
2736 2733
2737 // Input: edx, eax are the left and right objects of a bit op. 2734 // Input: edx, eax are the left and right objects of a bit op.
2738 // Output: eax, ecx are left and right integers for a bit op. 2735 // Output: eax, ecx are left and right integers for a bit op.
2739 void FloatingPointHelper::LoadUnknownsAsIntegers(MacroAssembler* masm, 2736 // Warning: can clobber inputs even when it jumps to |conversion_failure|!
2740 bool use_sse3, 2737 void FloatingPointHelper::LoadUnknownsAsIntegers(
2741 Label* conversion_failure) { 2738 MacroAssembler* masm,
2739 bool use_sse3,
2740 BinaryOpIC::TypeInfo left_type,
2741 BinaryOpIC::TypeInfo right_type,
2742 Label* conversion_failure) {
2742 // Check float operands. 2743 // Check float operands.
2743 Label arg1_is_object, check_undefined_arg1; 2744 Label arg1_is_object, check_undefined_arg1;
2744 Label arg2_is_object, check_undefined_arg2; 2745 Label arg2_is_object, check_undefined_arg2;
2745 Label load_arg2, done; 2746 Label load_arg2, done;
2746 2747
2747 // Test if arg1 is a Smi. 2748 // Test if arg1 is a Smi.
2748 __ JumpIfNotSmi(edx, &arg1_is_object, Label::kNear); 2749 if (left_type == BinaryOpIC::SMI) {
2750 __ JumpIfNotSmi(edx, conversion_failure);
2751 } else {
2752 __ JumpIfNotSmi(edx, &arg1_is_object, Label::kNear);
2753 }
2749 2754
2750 __ SmiUntag(edx); 2755 __ SmiUntag(edx);
2751 __ jmp(&load_arg2); 2756 __ jmp(&load_arg2);
2752 2757
2753 // If the argument is undefined it converts to zero (ECMA-262, section 9.5). 2758 // If the argument is undefined it converts to zero (ECMA-262, section 9.5).
2754 __ bind(&check_undefined_arg1); 2759 __ bind(&check_undefined_arg1);
2755 Factory* factory = masm->isolate()->factory(); 2760 Factory* factory = masm->isolate()->factory();
2756 __ cmp(edx, factory->undefined_value()); 2761 __ cmp(edx, factory->undefined_value());
2757 __ j(not_equal, conversion_failure); 2762 __ j(not_equal, conversion_failure);
2758 __ mov(edx, Immediate(0)); 2763 __ mov(edx, Immediate(0));
2759 __ jmp(&load_arg2); 2764 __ jmp(&load_arg2);
2760 2765
2761 __ bind(&arg1_is_object); 2766 __ bind(&arg1_is_object);
2762 __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset)); 2767 __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset));
2763 __ cmp(ebx, factory->heap_number_map()); 2768 __ cmp(ebx, factory->heap_number_map());
2764 __ j(not_equal, &check_undefined_arg1); 2769 if (left_type == BinaryOpIC::INT32 && CpuFeatures::IsSupported(SSE2)) {
2765 2770 CpuFeatures::Scope use_sse2(SSE2);
2766 // Get the untagged integer version of the edx heap number in ecx. 2771 __ j(not_equal, conversion_failure);
2767 IntegerConvert(masm, edx, use_sse3, conversion_failure); 2772 // Get the untagged integer version of the edx heap number in ecx.
2773 ConvertHeapNumberToInt32(masm, edx, conversion_failure);
2774 } else {
2775 __ j(not_equal, &check_undefined_arg1);
2776 // Get the untagged integer version of the edx heap number in ecx.
2777 IntegerConvert(masm, edx, use_sse3, conversion_failure);
2778 }
2768 __ mov(edx, ecx); 2779 __ mov(edx, ecx);
2769 2780
2770 // Here edx has the untagged integer, eax has a Smi or a heap number. 2781 // Here edx has the untagged integer, eax has a Smi or a heap number.
2771 __ bind(&load_arg2); 2782 __ bind(&load_arg2);
2772 2783
2773 // Test if arg2 is a Smi. 2784 // Test if arg2 is a Smi.
2774 __ JumpIfNotSmi(eax, &arg2_is_object, Label::kNear); 2785 if (right_type == BinaryOpIC::SMI) {
2786 __ JumpIfNotSmi(eax, conversion_failure);
2787 } else {
2788 __ JumpIfNotSmi(eax, &arg2_is_object, Label::kNear);
2789 }
2775 2790
2776 __ SmiUntag(eax); 2791 __ SmiUntag(eax);
2777 __ mov(ecx, eax); 2792 __ mov(ecx, eax);
2778 __ jmp(&done); 2793 __ jmp(&done);
2779 2794
2780 // If the argument is undefined it converts to zero (ECMA-262, section 9.5). 2795 // If the argument is undefined it converts to zero (ECMA-262, section 9.5).
2781 __ bind(&check_undefined_arg2); 2796 __ bind(&check_undefined_arg2);
2782 __ cmp(eax, factory->undefined_value()); 2797 __ cmp(eax, factory->undefined_value());
2783 __ j(not_equal, conversion_failure); 2798 __ j(not_equal, conversion_failure);
2784 __ mov(ecx, Immediate(0)); 2799 __ mov(ecx, Immediate(0));
2785 __ jmp(&done); 2800 __ jmp(&done);
2786 2801
2787 __ bind(&arg2_is_object); 2802 __ bind(&arg2_is_object);
2788 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); 2803 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
2789 __ cmp(ebx, factory->heap_number_map()); 2804 __ cmp(ebx, factory->heap_number_map());
2790 __ j(not_equal, &check_undefined_arg2); 2805 if (right_type == BinaryOpIC::INT32 && CpuFeatures::IsSupported(SSE2)) {
2806 CpuFeatures::Scope use_sse2(SSE2);
2807 __ j(not_equal, conversion_failure);
2808 // Get the untagged integer version of the eax heap number in ecx.
2809 ConvertHeapNumberToInt32(masm, eax, conversion_failure);
2810 } else {
2811 __ j(not_equal, &check_undefined_arg2);
2812 // Get the untagged integer version of the eax heap number in ecx.
2813 IntegerConvert(masm, eax, use_sse3, conversion_failure);
2814 }
2791 2815
2792 // Get the untagged integer version of the eax heap number in ecx.
2793 IntegerConvert(masm, eax, use_sse3, conversion_failure);
2794 __ bind(&done); 2816 __ bind(&done);
2795 __ mov(eax, edx); 2817 __ mov(eax, edx);
2796 } 2818 }
2797 2819
2798 2820
2799 void FloatingPointHelper::CheckLoadedIntegersWereInt32(MacroAssembler* masm,
2800 bool use_sse3,
2801 Label* not_int32) {
2802 return;
Jakob Kummerow 2013/02/07 15:28:35 Who are we kidding?
2803 }
2804
2805
2806 void FloatingPointHelper::LoadFloatOperand(MacroAssembler* masm, 2821 void FloatingPointHelper::LoadFloatOperand(MacroAssembler* masm,
2807 Register number) { 2822 Register number) {
2808 Label load_smi, done; 2823 Label load_smi, done;
2809 2824
2810 __ JumpIfSmi(number, &load_smi, Label::kNear); 2825 __ JumpIfSmi(number, &load_smi, Label::kNear);
2811 __ fld_d(FieldOperand(number, HeapNumber::kValueOffset)); 2826 __ fld_d(FieldOperand(number, HeapNumber::kValueOffset));
2812 __ jmp(&done, Label::kNear); 2827 __ jmp(&done, Label::kNear);
2813 2828
2814 __ bind(&load_smi); 2829 __ bind(&load_smi);
2815 __ SmiUntag(number); 2830 __ SmiUntag(number);
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
2890 2905
2891 __ mov(scratch, right); 2906 __ mov(scratch, right);
2892 __ SmiUntag(scratch); 2907 __ SmiUntag(scratch);
2893 __ cvtsi2sd(xmm1, scratch); 2908 __ cvtsi2sd(xmm1, scratch);
2894 } 2909 }
2895 2910
2896 2911
2897 void FloatingPointHelper::CheckSSE2OperandsAreInt32(MacroAssembler* masm, 2912 void FloatingPointHelper::CheckSSE2OperandsAreInt32(MacroAssembler* masm,
2898 Label* non_int32, 2913 Label* non_int32,
2899 Register scratch) { 2914 Register scratch) {
2900 CheckSSE2OperandIsInt32(masm, non_int32, xmm0, scratch, xmm2); 2915 CheckSSE2OperandIsInt32(masm, non_int32, xmm0, scratch, scratch, xmm2);
2901 CheckSSE2OperandIsInt32(masm, non_int32, xmm1, scratch, xmm2); 2916 CheckSSE2OperandIsInt32(masm, non_int32, xmm1, scratch, scratch, xmm2);
2902 } 2917 }
2903 2918
2904 2919
2905 void FloatingPointHelper::CheckSSE2OperandIsInt32(MacroAssembler* masm, 2920 void FloatingPointHelper::CheckSSE2OperandIsInt32(MacroAssembler* masm,
2906 Label* non_int32, 2921 Label* non_int32,
2907 XMMRegister operand, 2922 XMMRegister operand,
2923 Register int32_result,
2908 Register scratch, 2924 Register scratch,
2909 XMMRegister xmm_scratch) { 2925 XMMRegister xmm_scratch) {
2910 __ cvttsd2si(scratch, Operand(operand)); 2926 __ cvttsd2si(int32_result, Operand(operand));
2911 __ cvtsi2sd(xmm_scratch, scratch); 2927 __ cvtsi2sd(xmm_scratch, int32_result);
2912 __ pcmpeqd(xmm_scratch, operand); 2928 __ pcmpeqd(xmm_scratch, operand);
2913 __ movmskps(scratch, xmm_scratch); 2929 __ movmskps(scratch, xmm_scratch);
2914 // Two least significant bits should be both set. 2930 // Two least significant bits should be both set.
2915 __ not_(scratch); 2931 __ not_(scratch);
2916 __ test(scratch, Immediate(3)); 2932 __ test(scratch, Immediate(3));
2917 __ j(not_zero, non_int32); 2933 __ j(not_zero, non_int32);
2918 } 2934 }
2919 2935
2920 2936
2921 void FloatingPointHelper::LoadFloatOperands(MacroAssembler* masm, 2937 void FloatingPointHelper::LoadFloatOperands(MacroAssembler* masm,
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
2991 __ JumpIfSmi(eax, &done, Label::kNear); 3007 __ JumpIfSmi(eax, &done, Label::kNear);
2992 __ mov(scratch, FieldOperand(eax, HeapObject::kMapOffset)); 3008 __ mov(scratch, FieldOperand(eax, HeapObject::kMapOffset));
2993 __ cmp(scratch, factory->heap_number_map()); 3009 __ cmp(scratch, factory->heap_number_map());
2994 __ j(not_equal, non_float); // argument in eax is not a number -> NaN 3010 __ j(not_equal, non_float); // argument in eax is not a number -> NaN
2995 3011
2996 // Fall-through: Both operands are numbers. 3012 // Fall-through: Both operands are numbers.
2997 __ bind(&done); 3013 __ bind(&done);
2998 } 3014 }
2999 3015
3000 3016
3001 void FloatingPointHelper::CheckFloatOperandsAreInt32(MacroAssembler* masm,
Jakob Kummerow 2013/02/07 15:28:35 This seems rather similar in functionality to Floa
3002 Label* non_int32) {
3003 return;
3004 }
3005
3006
3007 void MathPowStub::Generate(MacroAssembler* masm) { 3017 void MathPowStub::Generate(MacroAssembler* masm) {
3008 CpuFeatures::Scope use_sse2(SSE2); 3018 CpuFeatures::Scope use_sse2(SSE2);
3009 Factory* factory = masm->isolate()->factory(); 3019 Factory* factory = masm->isolate()->factory();
3010 const Register exponent = eax; 3020 const Register exponent = eax;
3011 const Register base = edx; 3021 const Register base = edx;
3012 const Register scratch = ecx; 3022 const Register scratch = ecx;
3013 const XMMRegister double_result = xmm3; 3023 const XMMRegister double_result = xmm3;
3014 const XMMRegister double_base = xmm2; 3024 const XMMRegister double_base = xmm2;
3015 const XMMRegister double_exponent = xmm1; 3025 const XMMRegister double_exponent = xmm1;
3016 const XMMRegister double_scratch = xmm4; 3026 const XMMRegister double_scratch = xmm4;
(...skipping 4670 matching lines...) Expand 10 before | Expand all | Expand 10 after
7687 // Restore ecx. 7697 // Restore ecx.
7688 __ pop(ecx); 7698 __ pop(ecx);
7689 __ ret(0); 7699 __ ret(0);
7690 } 7700 }
7691 7701
7692 #undef __ 7702 #undef __
7693 7703
7694 } } // namespace v8::internal 7704 } } // namespace v8::internal
7695 7705
7696 #endif // V8_TARGET_ARCH_IA32 7706 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698