| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 1755 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1766 case Token::SHR: | 1766 case Token::SHR: |
| 1767 GenerateTypeTransitionWithSavedArgs(masm); | 1767 GenerateTypeTransitionWithSavedArgs(masm); |
| 1768 break; | 1768 break; |
| 1769 default: | 1769 default: |
| 1770 UNREACHABLE(); | 1770 UNREACHABLE(); |
| 1771 } | 1771 } |
| 1772 } | 1772 } |
| 1773 | 1773 |
| 1774 | 1774 |
| 1775 void TypeRecordingBinaryOpStub::GenerateStringStub(MacroAssembler* masm) { | 1775 void TypeRecordingBinaryOpStub::GenerateStringStub(MacroAssembler* masm) { |
| 1776 Label call_runtime; |
| 1776 ASSERT(operands_type_ == TRBinaryOpIC::STRING); | 1777 ASSERT(operands_type_ == TRBinaryOpIC::STRING); |
| 1777 ASSERT(op_ == Token::ADD); | 1778 ASSERT(op_ == Token::ADD); |
| 1779 // If one of the arguments is a string, call the string add stub. |
| 1780 // Otherwise, transition to the generic TRBinaryOpIC type. |
| 1778 | 1781 |
| 1779 // Try to add arguments as strings, otherwise, transition to the generic | 1782 // Registers containing left and right operands respectively. |
| 1780 // TRBinaryOpIC type. | 1783 Register left = edx; |
| 1781 GenerateAddStrings(masm); | 1784 Register right = eax; |
| 1785 |
| 1786 // Test if left operand is a string. |
| 1787 NearLabel left_not_string; |
| 1788 __ test(left, Immediate(kSmiTagMask)); |
| 1789 __ j(zero, &left_not_string); |
| 1790 __ CmpObjectType(left, FIRST_NONSTRING_TYPE, ecx); |
| 1791 __ j(above_equal, &left_not_string); |
| 1792 |
| 1793 StringAddStub string_add_left_stub(NO_STRING_CHECK_LEFT_IN_STUB); |
| 1794 GenerateRegisterArgsPush(masm); |
| 1795 __ TailCallStub(&string_add_left_stub); |
| 1796 |
| 1797 // Left operand is not a string, test right. |
| 1798 __ bind(&left_not_string); |
| 1799 __ test(right, Immediate(kSmiTagMask)); |
| 1800 __ j(zero, &call_runtime); |
| 1801 __ CmpObjectType(right, FIRST_NONSTRING_TYPE, ecx); |
| 1802 __ j(above_equal, &call_runtime); |
| 1803 |
| 1804 StringAddStub string_add_right_stub(NO_STRING_CHECK_RIGHT_IN_STUB); |
| 1805 GenerateRegisterArgsPush(masm); |
| 1806 __ TailCallStub(&string_add_right_stub); |
| 1807 |
| 1808 // Neither argument is a string. |
| 1809 __ bind(&call_runtime); |
| 1782 GenerateTypeTransition(masm); | 1810 GenerateTypeTransition(masm); |
| 1783 } | 1811 } |
| 1784 | 1812 |
| 1785 | 1813 |
| 1786 void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { | 1814 void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { |
| 1787 Label call_runtime; | 1815 Label call_runtime; |
| 1788 ASSERT(operands_type_ == TRBinaryOpIC::INT32); | 1816 ASSERT(operands_type_ == TRBinaryOpIC::INT32); |
| 1789 | 1817 |
| 1790 // Floating point case. | 1818 // Floating point case. |
| 1791 switch (op_) { | 1819 switch (op_) { |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1932 __ bind(¬_int32); | 1960 __ bind(¬_int32); |
| 1933 GenerateTypeTransitionWithSavedArgs(masm); | 1961 GenerateTypeTransitionWithSavedArgs(masm); |
| 1934 break; | 1962 break; |
| 1935 } | 1963 } |
| 1936 default: UNREACHABLE(); break; | 1964 default: UNREACHABLE(); break; |
| 1937 } | 1965 } |
| 1938 | 1966 |
| 1939 // If an allocation fails, or SHR or MOD hit a hard case, | 1967 // If an allocation fails, or SHR or MOD hit a hard case, |
| 1940 // use the runtime system to get the correct result. | 1968 // use the runtime system to get the correct result. |
| 1941 __ bind(&call_runtime); | 1969 __ bind(&call_runtime); |
| 1942 GenerateCallRuntime(masm); | 1970 |
| 1971 switch (op_) { |
| 1972 case Token::ADD: |
| 1973 GenerateRegisterArgsPush(masm); |
| 1974 __ InvokeBuiltin(Builtins::ADD, JUMP_FUNCTION); |
| 1975 break; |
| 1976 case Token::SUB: |
| 1977 GenerateRegisterArgsPush(masm); |
| 1978 __ InvokeBuiltin(Builtins::SUB, JUMP_FUNCTION); |
| 1979 break; |
| 1980 case Token::MUL: |
| 1981 GenerateRegisterArgsPush(masm); |
| 1982 __ InvokeBuiltin(Builtins::MUL, JUMP_FUNCTION); |
| 1983 break; |
| 1984 case Token::DIV: |
| 1985 GenerateRegisterArgsPush(masm); |
| 1986 __ InvokeBuiltin(Builtins::DIV, JUMP_FUNCTION); |
| 1987 break; |
| 1988 case Token::MOD: |
| 1989 GenerateRegisterArgsPush(masm); |
| 1990 __ InvokeBuiltin(Builtins::MOD, JUMP_FUNCTION); |
| 1991 break; |
| 1992 case Token::BIT_OR: |
| 1993 __ InvokeBuiltin(Builtins::BIT_OR, JUMP_FUNCTION); |
| 1994 break; |
| 1995 case Token::BIT_AND: |
| 1996 __ InvokeBuiltin(Builtins::BIT_AND, JUMP_FUNCTION); |
| 1997 break; |
| 1998 case Token::BIT_XOR: |
| 1999 __ InvokeBuiltin(Builtins::BIT_XOR, JUMP_FUNCTION); |
| 2000 break; |
| 2001 case Token::SAR: |
| 2002 __ InvokeBuiltin(Builtins::SAR, JUMP_FUNCTION); |
| 2003 break; |
| 2004 case Token::SHL: |
| 2005 __ InvokeBuiltin(Builtins::SHL, JUMP_FUNCTION); |
| 2006 break; |
| 2007 case Token::SHR: |
| 2008 __ InvokeBuiltin(Builtins::SHR, JUMP_FUNCTION); |
| 2009 break; |
| 2010 default: |
| 2011 UNREACHABLE(); |
| 2012 } |
| 1943 } | 2013 } |
| 1944 | 2014 |
| 1945 | 2015 |
| 1946 void TypeRecordingBinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) { | 2016 void TypeRecordingBinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) { |
| 1947 Label call_runtime; | 2017 Label call_runtime; |
| 1948 ASSERT(operands_type_ == TRBinaryOpIC::HEAP_NUMBER); | 2018 ASSERT(operands_type_ == TRBinaryOpIC::HEAP_NUMBER); |
| 1949 | 2019 |
| 1950 // Floating point case. | 2020 // Floating point case. |
| 1951 switch (op_) { | 2021 switch (op_) { |
| 1952 case Token::ADD: | 2022 case Token::ADD: |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2072 __ bind(¬_floats); | 2142 __ bind(¬_floats); |
| 2073 GenerateTypeTransitionWithSavedArgs(masm); | 2143 GenerateTypeTransitionWithSavedArgs(masm); |
| 2074 break; | 2144 break; |
| 2075 } | 2145 } |
| 2076 default: UNREACHABLE(); break; | 2146 default: UNREACHABLE(); break; |
| 2077 } | 2147 } |
| 2078 | 2148 |
| 2079 // If an allocation fails, or SHR or MOD hit a hard case, | 2149 // If an allocation fails, or SHR or MOD hit a hard case, |
| 2080 // use the runtime system to get the correct result. | 2150 // use the runtime system to get the correct result. |
| 2081 __ bind(&call_runtime); | 2151 __ bind(&call_runtime); |
| 2082 GenerateCallRuntime(masm); | 2152 |
| 2153 switch (op_) { |
| 2154 case Token::ADD: |
| 2155 GenerateRegisterArgsPush(masm); |
| 2156 __ InvokeBuiltin(Builtins::ADD, JUMP_FUNCTION); |
| 2157 break; |
| 2158 case Token::SUB: |
| 2159 GenerateRegisterArgsPush(masm); |
| 2160 __ InvokeBuiltin(Builtins::SUB, JUMP_FUNCTION); |
| 2161 break; |
| 2162 case Token::MUL: |
| 2163 GenerateRegisterArgsPush(masm); |
| 2164 __ InvokeBuiltin(Builtins::MUL, JUMP_FUNCTION); |
| 2165 break; |
| 2166 case Token::DIV: |
| 2167 GenerateRegisterArgsPush(masm); |
| 2168 __ InvokeBuiltin(Builtins::DIV, JUMP_FUNCTION); |
| 2169 break; |
| 2170 case Token::MOD: |
| 2171 GenerateRegisterArgsPush(masm); |
| 2172 __ InvokeBuiltin(Builtins::MOD, JUMP_FUNCTION); |
| 2173 break; |
| 2174 case Token::BIT_OR: |
| 2175 __ InvokeBuiltin(Builtins::BIT_OR, JUMP_FUNCTION); |
| 2176 break; |
| 2177 case Token::BIT_AND: |
| 2178 __ InvokeBuiltin(Builtins::BIT_AND, JUMP_FUNCTION); |
| 2179 break; |
| 2180 case Token::BIT_XOR: |
| 2181 __ InvokeBuiltin(Builtins::BIT_XOR, JUMP_FUNCTION); |
| 2182 break; |
| 2183 case Token::SAR: |
| 2184 __ InvokeBuiltin(Builtins::SAR, JUMP_FUNCTION); |
| 2185 break; |
| 2186 case Token::SHL: |
| 2187 __ InvokeBuiltin(Builtins::SHL, JUMP_FUNCTION); |
| 2188 break; |
| 2189 case Token::SHR: |
| 2190 __ InvokeBuiltin(Builtins::SHR, JUMP_FUNCTION); |
| 2191 break; |
| 2192 default: |
| 2193 UNREACHABLE(); |
| 2194 } |
| 2083 } | 2195 } |
| 2084 | 2196 |
| 2085 | 2197 |
| 2086 void TypeRecordingBinaryOpStub::GenerateGeneric(MacroAssembler* masm) { | 2198 void TypeRecordingBinaryOpStub::GenerateGeneric(MacroAssembler* masm) { |
| 2087 Label call_runtime; | 2199 Label call_runtime; |
| 2088 | 2200 |
| 2089 __ IncrementCounter(&Counters::generic_binary_stub_calls, 1); | 2201 __ IncrementCounter(&Counters::generic_binary_stub_calls, 1); |
| 2090 | 2202 |
| 2091 switch (op_) { | 2203 switch (op_) { |
| 2092 case Token::ADD: | 2204 case Token::ADD: |
| 2093 case Token::SUB: | 2205 case Token::SUB: |
| 2094 case Token::MUL: | 2206 case Token::MUL: |
| 2095 case Token::DIV: | 2207 case Token::DIV: |
| 2208 break; |
| 2096 case Token::MOD: | 2209 case Token::MOD: |
| 2097 break; | |
| 2098 case Token::BIT_OR: | 2210 case Token::BIT_OR: |
| 2099 case Token::BIT_AND: | 2211 case Token::BIT_AND: |
| 2100 case Token::BIT_XOR: | 2212 case Token::BIT_XOR: |
| 2101 case Token::SAR: | 2213 case Token::SAR: |
| 2102 case Token::SHL: | 2214 case Token::SHL: |
| 2103 case Token::SHR: | 2215 case Token::SHR: |
| 2104 GenerateRegisterArgsPush(masm); | 2216 GenerateRegisterArgsPush(masm); |
| 2105 break; | 2217 break; |
| 2106 default: | 2218 default: |
| 2107 UNREACHABLE(); | 2219 UNREACHABLE(); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2153 } | 2265 } |
| 2154 __ bind(¬_floats); | 2266 __ bind(¬_floats); |
| 2155 break; | 2267 break; |
| 2156 } | 2268 } |
| 2157 case Token::MOD: { | 2269 case Token::MOD: { |
| 2158 // For MOD we go directly to runtime in the non-smi case. | 2270 // For MOD we go directly to runtime in the non-smi case. |
| 2159 break; | 2271 break; |
| 2160 } | 2272 } |
| 2161 case Token::BIT_OR: | 2273 case Token::BIT_OR: |
| 2162 case Token::BIT_AND: | 2274 case Token::BIT_AND: |
| 2163 case Token::BIT_XOR: | 2275 case Token::BIT_XOR: |
| 2164 case Token::SAR: | 2276 case Token::SAR: |
| 2165 case Token::SHL: | 2277 case Token::SHL: |
| 2166 case Token::SHR: { | 2278 case Token::SHR: { |
| 2167 Label non_smi_result; | 2279 Label non_smi_result; |
| 2168 FloatingPointHelper::LoadUnknownsAsIntegers(masm, | 2280 FloatingPointHelper::LoadUnknownsAsIntegers(masm, |
| 2169 use_sse3_, | 2281 use_sse3_, |
| 2170 &call_runtime); | 2282 &call_runtime); |
| 2171 switch (op_) { | 2283 switch (op_) { |
| 2172 case Token::BIT_OR: __ or_(eax, Operand(ecx)); break; | 2284 case Token::BIT_OR: __ or_(eax, Operand(ecx)); break; |
| 2173 case Token::BIT_AND: __ and_(eax, Operand(ecx)); break; | 2285 case Token::BIT_AND: __ and_(eax, Operand(ecx)); break; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2226 __ ret(2 * kPointerSize); | 2338 __ ret(2 * kPointerSize); |
| 2227 } | 2339 } |
| 2228 break; | 2340 break; |
| 2229 } | 2341 } |
| 2230 default: UNREACHABLE(); break; | 2342 default: UNREACHABLE(); break; |
| 2231 } | 2343 } |
| 2232 | 2344 |
| 2233 // If all else fails, use the runtime system to get the correct | 2345 // If all else fails, use the runtime system to get the correct |
| 2234 // result. | 2346 // result. |
| 2235 __ bind(&call_runtime); | 2347 __ bind(&call_runtime); |
| 2348 switch (op_) { |
| 2349 case Token::ADD: { |
| 2350 GenerateRegisterArgsPush(masm); |
| 2351 // Test for string arguments before calling runtime. |
| 2352 // Registers containing left and right operands respectively. |
| 2353 Register lhs, rhs; |
| 2354 lhs = edx; |
| 2355 rhs = eax; |
| 2236 | 2356 |
| 2237 // Try to add strings before calling runtime. | 2357 // Test if left operand is a string. |
| 2238 if (op_ == Token::ADD) { | 2358 NearLabel lhs_not_string; |
| 2239 GenerateAddStrings(masm); | 2359 __ test(lhs, Immediate(kSmiTagMask)); |
| 2240 } | 2360 __ j(zero, &lhs_not_string); |
| 2361 __ CmpObjectType(lhs, FIRST_NONSTRING_TYPE, ecx); |
| 2362 __ j(above_equal, &lhs_not_string); |
| 2241 | 2363 |
| 2242 // Generate the runtime call. | 2364 StringAddStub string_add_left_stub(NO_STRING_CHECK_LEFT_IN_STUB); |
| 2243 GenerateCallRuntime(masm); | 2365 __ TailCallStub(&string_add_left_stub); |
| 2244 } | |
| 2245 | 2366 |
| 2367 NearLabel call_add_runtime; |
| 2368 // Left operand is not a string, test right. |
| 2369 __ bind(&lhs_not_string); |
| 2370 __ test(rhs, Immediate(kSmiTagMask)); |
| 2371 __ j(zero, &call_add_runtime); |
| 2372 __ CmpObjectType(rhs, FIRST_NONSTRING_TYPE, ecx); |
| 2373 __ j(above_equal, &call_add_runtime); |
| 2246 | 2374 |
| 2247 void TypeRecordingBinaryOpStub::GenerateAddStrings(MacroAssembler* masm) { | 2375 StringAddStub string_add_right_stub(NO_STRING_CHECK_RIGHT_IN_STUB); |
| 2248 // If one of the arguments is a string, call the string add stub. | 2376 __ TailCallStub(&string_add_right_stub); |
| 2249 // Registers containing left and right operands respectively. | |
| 2250 NearLabel left_not_string, neither_string; | |
| 2251 Register left = edx; | |
| 2252 Register right = eax; | |
| 2253 | 2377 |
| 2254 // Test if left operand is a string. | 2378 // Neither argument is a string. |
| 2255 __ test(left, Immediate(kSmiTagMask)); | 2379 __ bind(&call_add_runtime); |
| 2256 __ j(zero, &left_not_string); | |
| 2257 __ CmpObjectType(left, FIRST_NONSTRING_TYPE, ecx); | |
| 2258 __ j(above_equal, &left_not_string); | |
| 2259 | |
| 2260 StringAddStub string_add_left_stub(NO_STRING_CHECK_LEFT_IN_STUB); | |
| 2261 GenerateRegisterArgsPush(masm); | |
| 2262 __ TailCallStub(&string_add_left_stub); | |
| 2263 | |
| 2264 // Left operand is not a string, test right. | |
| 2265 __ bind(&left_not_string); | |
| 2266 __ test(right, Immediate(kSmiTagMask)); | |
| 2267 __ j(zero, &neither_string); | |
| 2268 __ CmpObjectType(right, FIRST_NONSTRING_TYPE, ecx); | |
| 2269 __ j(above_equal, &neither_string); | |
| 2270 | |
| 2271 StringAddStub string_add_right_stub(NO_STRING_CHECK_RIGHT_IN_STUB); | |
| 2272 GenerateRegisterArgsPush(masm); | |
| 2273 __ TailCallStub(&string_add_right_stub); | |
| 2274 | |
| 2275 // Neither argument is a string. | |
| 2276 __ bind(&neither_string); | |
| 2277 } | |
| 2278 | |
| 2279 | |
| 2280 void TypeRecordingBinaryOpStub::GenerateCallRuntime(MacroAssembler* masm) { | |
| 2281 switch (op_) { | |
| 2282 case Token::ADD: | |
| 2283 GenerateRegisterArgsPush(masm); | |
| 2284 __ InvokeBuiltin(Builtins::ADD, JUMP_FUNCTION); | 2380 __ InvokeBuiltin(Builtins::ADD, JUMP_FUNCTION); |
| 2285 break; | 2381 break; |
| 2382 } |
| 2286 case Token::SUB: | 2383 case Token::SUB: |
| 2287 GenerateRegisterArgsPush(masm); | 2384 GenerateRegisterArgsPush(masm); |
| 2288 __ InvokeBuiltin(Builtins::SUB, JUMP_FUNCTION); | 2385 __ InvokeBuiltin(Builtins::SUB, JUMP_FUNCTION); |
| 2289 break; | 2386 break; |
| 2290 case Token::MUL: | 2387 case Token::MUL: |
| 2291 GenerateRegisterArgsPush(masm); | 2388 GenerateRegisterArgsPush(masm); |
| 2292 __ InvokeBuiltin(Builtins::MUL, JUMP_FUNCTION); | 2389 __ InvokeBuiltin(Builtins::MUL, JUMP_FUNCTION); |
| 2293 break; | 2390 break; |
| 2294 case Token::DIV: | 2391 case Token::DIV: |
| 2295 GenerateRegisterArgsPush(masm); | 2392 GenerateRegisterArgsPush(masm); |
| 2296 __ InvokeBuiltin(Builtins::DIV, JUMP_FUNCTION); | 2393 __ InvokeBuiltin(Builtins::DIV, JUMP_FUNCTION); |
| 2297 break; | 2394 break; |
| 2298 case Token::MOD: | 2395 case Token::MOD: |
| 2299 GenerateRegisterArgsPush(masm); | |
| 2300 __ InvokeBuiltin(Builtins::MOD, JUMP_FUNCTION); | 2396 __ InvokeBuiltin(Builtins::MOD, JUMP_FUNCTION); |
| 2301 break; | 2397 break; |
| 2302 case Token::BIT_OR: | 2398 case Token::BIT_OR: |
| 2303 __ InvokeBuiltin(Builtins::BIT_OR, JUMP_FUNCTION); | 2399 __ InvokeBuiltin(Builtins::BIT_OR, JUMP_FUNCTION); |
| 2304 break; | 2400 break; |
| 2305 case Token::BIT_AND: | 2401 case Token::BIT_AND: |
| 2306 __ InvokeBuiltin(Builtins::BIT_AND, JUMP_FUNCTION); | 2402 __ InvokeBuiltin(Builtins::BIT_AND, JUMP_FUNCTION); |
| 2307 break; | 2403 break; |
| 2308 case Token::BIT_XOR: | 2404 case Token::BIT_XOR: |
| 2309 __ InvokeBuiltin(Builtins::BIT_XOR, JUMP_FUNCTION); | 2405 __ InvokeBuiltin(Builtins::BIT_XOR, JUMP_FUNCTION); |
| (...skipping 4101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6411 // Do a tail call to the rewritten stub. | 6507 // Do a tail call to the rewritten stub. |
| 6412 __ jmp(Operand(edi)); | 6508 __ jmp(Operand(edi)); |
| 6413 } | 6509 } |
| 6414 | 6510 |
| 6415 | 6511 |
| 6416 #undef __ | 6512 #undef __ |
| 6417 | 6513 |
| 6418 } } // namespace v8::internal | 6514 } } // namespace v8::internal |
| 6419 | 6515 |
| 6420 #endif // V8_TARGET_ARCH_IA32 | 6516 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |