| 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 |