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

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

Issue 16082008: Increase sanity of integer division handling on ARM (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: addressed Rodolph's comments Created 7 years, 6 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 | « src/arm/assembler-arm.cc ('k') | src/arm/lithium-arm.h » ('j') | 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 1689 matching lines...) Expand 10 before | Expand all | Expand 10 after
1700 __ b(ne, &not_smi_result); 1700 __ b(ne, &not_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, &not_smi_result); 1719 __ b(ne, &not_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
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, &not_smi_result); 1759 __ JumpIfNotPowerOfTwoOrZero(right, scratch1, &not_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
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, &not_zero); 2225 __ b(ne, &not_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(&not_zero); 2229 __ bind(&not_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
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
OLDNEW
« no previous file with comments | « src/arm/assembler-arm.cc ('k') | src/arm/lithium-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698