OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 1689 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1700 __ b(ne, ¬_smi_result); | 1700 __ b(ne, ¬_smi_result); |
1701 } | 1701 } |
1702 | 1702 |
1703 // Perform division by shifting. | 1703 // Perform division by shifting. |
1704 __ clz(scratch1, scratch1); | 1704 __ clz(scratch1, scratch1); |
1705 __ rsb(scratch1, scratch1, Operand(31)); | 1705 __ rsb(scratch1, scratch1, Operand(31)); |
1706 __ mov(right, Operand(left, LSR, scratch1)); | 1706 __ mov(right, Operand(left, LSR, scratch1)); |
1707 __ Ret(); | 1707 __ Ret(); |
1708 | 1708 |
1709 if (CpuFeatures::IsSupported(SUDIV)) { | 1709 if (CpuFeatures::IsSupported(SUDIV)) { |
| 1710 CpuFeatureScope scope(masm, SUDIV); |
1710 Label result_not_zero; | 1711 Label result_not_zero; |
1711 | 1712 |
1712 __ bind(&div_with_sdiv); | 1713 __ bind(&div_with_sdiv); |
1713 // Do division. | 1714 // Do division. |
1714 __ sdiv(scratch1, left, right); | 1715 __ sdiv(scratch1, left, right); |
1715 // Check that the remainder is zero. | 1716 // Check that the remainder is zero. |
1716 __ mls(scratch2, scratch1, right, left); | 1717 __ mls(scratch2, scratch1, right, left); |
1717 __ cmp(scratch2, Operand::Zero()); | 1718 __ cmp(scratch2, Operand::Zero()); |
1718 __ b(ne, ¬_smi_result); | 1719 __ b(ne, ¬_smi_result); |
1719 // Check for negative zero result. | 1720 // Check for negative zero result. |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1756 | 1757 |
1757 // Check for power of two on the right hand side. | 1758 // Check for power of two on the right hand side. |
1758 __ JumpIfNotPowerOfTwoOrZero(right, scratch1, ¬_smi_result); | 1759 __ JumpIfNotPowerOfTwoOrZero(right, scratch1, ¬_smi_result); |
1759 } | 1760 } |
1760 | 1761 |
1761 // Perform modulus by masking (scratch1 contains right - 1). | 1762 // Perform modulus by masking (scratch1 contains right - 1). |
1762 __ and_(right, left, Operand(scratch1)); | 1763 __ and_(right, left, Operand(scratch1)); |
1763 __ Ret(); | 1764 __ Ret(); |
1764 | 1765 |
1765 if (CpuFeatures::IsSupported(SUDIV)) { | 1766 if (CpuFeatures::IsSupported(SUDIV)) { |
| 1767 CpuFeatureScope scope(masm, SUDIV); |
1766 __ bind(&modulo_with_sdiv); | 1768 __ bind(&modulo_with_sdiv); |
1767 __ mov(scratch2, right); | 1769 __ mov(scratch2, right); |
1768 // Perform modulus with sdiv and mls. | 1770 // Perform modulus with sdiv and mls. |
1769 __ sdiv(scratch1, left, right); | 1771 __ sdiv(scratch1, left, right); |
1770 __ mls(right, scratch1, right, left); | 1772 __ mls(right, scratch1, right, left); |
1771 // Return if the result is not 0. | 1773 // Return if the result is not 0. |
1772 __ cmp(right, Operand::Zero()); | 1774 __ cmp(right, Operand::Zero()); |
1773 __ Ret(ne); | 1775 __ Ret(ne); |
1774 // The result is 0, check for -0 case. | 1776 // The result is 0, check for -0 case. |
1775 __ cmp(left, Operand::Zero()); | 1777 __ cmp(left, Operand::Zero()); |
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2201 case Token::MUL: | 2203 case Token::MUL: |
2202 __ vmul(d5, d0, d1); | 2204 __ vmul(d5, d0, d1); |
2203 break; | 2205 break; |
2204 case Token::DIV: | 2206 case Token::DIV: |
2205 __ vdiv(d5, d0, d1); | 2207 __ vdiv(d5, d0, d1); |
2206 break; | 2208 break; |
2207 default: | 2209 default: |
2208 UNREACHABLE(); | 2210 UNREACHABLE(); |
2209 } | 2211 } |
2210 | 2212 |
2211 if (op_ != Token::DIV) { | 2213 if (result_type_ <= BinaryOpIC::INT32) { |
2212 // These operations produce an integer result. | 2214 __ TryDoubleToInt32Exact(scratch1, d5, d8); |
2213 // Try to return a smi if we can. | 2215 // If the ne condition is set, result does |
2214 // Otherwise return a heap number if allowed, or jump to type | 2216 // not fit in a 32-bit integer. |
2215 // transition. | 2217 __ b(ne, &transition); |
2216 | 2218 // Try to tag the result as a Smi, return heap number on overflow. |
2217 if (result_type_ <= BinaryOpIC::INT32) { | 2219 __ SmiTag(scratch1, SetCC); |
2218 __ TryDoubleToInt32Exact(scratch1, d5, d8); | 2220 __ b(vs, &return_heap_number); |
2219 // If the ne condition is set, result does | 2221 // Check for minus zero, transition in that case (because we need |
2220 // not fit in a 32-bit integer. | 2222 // to return a heap number). |
2221 __ b(ne, &transition); | |
2222 } else { | |
2223 __ vcvt_s32_f64(s8, d5); | |
2224 __ vmov(scratch1, s8); | |
2225 } | |
2226 | |
2227 // Check if the result fits in a smi. | |
2228 __ add(scratch2, scratch1, Operand(0x40000000), SetCC); | |
2229 // If not try to return a heap number. | |
2230 __ b(mi, &return_heap_number); | |
2231 // Check for minus zero. Return heap number for minus zero if | |
2232 // double results are allowed; otherwise transition. | |
2233 Label not_zero; | 2223 Label not_zero; |
2234 __ cmp(scratch1, Operand::Zero()); | 2224 ASSERT(kSmiTag == 0); |
2235 __ b(ne, ¬_zero); | 2225 __ b(ne, ¬_zero); |
2236 __ vmov(scratch2, d5.high()); | 2226 __ vmov(scratch2, d5.high()); |
2237 __ tst(scratch2, Operand(HeapNumber::kSignMask)); | 2227 __ tst(scratch2, Operand(HeapNumber::kSignMask)); |
2238 __ b(ne, result_type_ <= BinaryOpIC::INT32 ? &transition | 2228 __ b(ne, &transition); |
2239 : &return_heap_number); | |
2240 __ bind(¬_zero); | 2229 __ bind(¬_zero); |
2241 | 2230 __ mov(r0, scratch1); |
2242 // Tag the result and return. | |
2243 __ SmiTag(r0, scratch1); | |
2244 __ Ret(); | 2231 __ Ret(); |
2245 } else { | |
2246 // DIV just falls through to allocating a heap number. | |
2247 } | 2232 } |
2248 | 2233 |
2249 __ bind(&return_heap_number); | 2234 __ bind(&return_heap_number); |
2250 // Return a heap number, or fall through to type transition or runtime | 2235 // Return a heap number, or fall through to type transition or runtime |
2251 // call if we can't. | 2236 // call if we can't. |
2252 // We are using vfp registers so r5 is available. | 2237 // We are using vfp registers so r5 is available. |
2253 heap_number_result = r5; | 2238 heap_number_result = r5; |
2254 BinaryOpStub_GenerateHeapResultAllocation(masm, | 2239 BinaryOpStub_GenerateHeapResultAllocation(masm, |
2255 heap_number_result, | 2240 heap_number_result, |
2256 heap_number_map, | 2241 heap_number_map, |
(...skipping 5249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7506 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET); | 7491 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET); |
7507 } | 7492 } |
7508 } | 7493 } |
7509 | 7494 |
7510 | 7495 |
7511 #undef __ | 7496 #undef __ |
7512 | 7497 |
7513 } } // namespace v8::internal | 7498 } } // namespace v8::internal |
7514 | 7499 |
7515 #endif // V8_TARGET_ARCH_ARM | 7500 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |