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 |