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

Unified Diff: src/arm/stub-cache-arm.cc

Issue 12393008: [v8-dev] Split and replace the EmitVFPTruncate routine to only do what is needed. Floor (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 7 years, 10 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/arm/macro-assembler-arm.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/arm/stub-cache-arm.cc
===================================================================
--- src/arm/stub-cache-arm.cc (revision 13783)
+++ src/arm/stub-cache-arm.cc (working copy)
@@ -2135,11 +2135,8 @@
__ CheckMap(r0, r1, Heap::kHeapNumberMapRootIndex, &slow, DONT_DO_SMI_CHECK);
- Label wont_fit_smi, no_vfp_exception, restore_fpscr_and_return;
+ Label smi_check, just_return;
- // If vfp3 is enabled, we use the fpu rounding with the RM (round towards
- // minus infinity) mode.
-
// Load the HeapNumber value.
// We will need access to the value in the core registers, so we load it
// with ldrd and move it to the fpu. It also spares a sub instruction for
@@ -2148,73 +2145,46 @@
__ Ldrd(r4, r5, FieldMemOperand(r0, HeapNumber::kValueOffset));
__ vmov(d1, r4, r5);
- // Backup FPSCR.
- __ vmrs(r3);
- // Set custom FPCSR:
- // - Set rounding mode to "Round towards Minus Infinity"
- // (i.e. bits [23:22] = 0b10).
- // - Clear vfp cumulative exception flags (bits [3:0]).
- // - Make sure Flush-to-zero mode control bit is unset (bit 22).
- __ bic(r9, r3,
- Operand(kVFPExceptionMask | kVFPRoundingModeMask | kVFPFlushToZeroMask));
- __ orr(r9, r9, Operand(kRoundToMinusInf));
- __ vmsr(r9);
-
- // Convert the argument to an integer.
- __ vcvt_s32_f64(s0, d1, kFPSCRRounding);
-
- // Use vcvt latency to start checking for special cases.
- // Get the argument exponent and clear the sign bit.
- __ bic(r6, r5, Operand(HeapNumber::kSignMask));
- __ mov(r6, Operand(r6, LSR, HeapNumber::kMantissaBitsInTopWord));
-
- // Retrieve FPSCR and check for vfp exceptions.
- __ vmrs(r9);
- __ tst(r9, Operand(kVFPExceptionMask));
- __ b(&no_vfp_exception, eq);
-
- // Check for NaN, Infinity, and -Infinity.
+ // Check for NaN, Infinities and -0.
// They are invariant through a Math.Floor call, so just
// return the original argument.
- __ sub(r7, r6, Operand(HeapNumber::kExponentMask
- >> HeapNumber::kMantissaBitsInTopWord), SetCC);
- __ b(&restore_fpscr_and_return, eq);
- // We had an overflow or underflow in the conversion. Check if we
- // have a big exponent.
- __ cmp(r7, Operand(HeapNumber::kMantissaBits));
- // If greater or equal, the argument is already round and in r0.
- __ b(&restore_fpscr_and_return, ge);
- __ b(&wont_fit_smi);
+ __ Sbfx(r3, r5, HeapNumber::kExponentShift, HeapNumber::kExponentBits);
+ __ cmp(r3, Operand(-1));
+ __ b(eq, &just_return);
+ __ eor(r3, r5, Operand(0x80000000u));
+ __ orr(r3, r3, r4, SetCC);
+ __ b(eq, &just_return);
+ // Test for values that can be exactly represented as a
+ // signed 32-bit integer.
+ __ TryDoubleToInt32Exact(r0, d1, d2);
+ // If exact, check smi
+ __ b(eq, &smi_check);
+ __ cmp(r5, Operand(0));
- __ bind(&no_vfp_exception);
- // Move the result back to general purpose register r0.
- __ vmov(r0, s0);
- // Check if the result fits into a smi.
+ // If input is in ]+0, +inf[, the cmp has clear overflow and negative
hans 2013/03/01 14:47:54 ultra nit: "has cleared"?
+ // (V=0 and N=0), the two following instructions won't execute and
+ // we fall through smi_check to check if the result can fit into an smi.
+
+ // If input is in ]-inf, -0[, sub one and, go to slow if we have
+ // an overflow. Else we fall through smi check.
+ // Hint: if x is a negative, non integer number,
+ // floor(x) <=> round_to_zero(x) - 1.
+ __ sub(r0, r0, Operand(1), SetCC, mi);
+ __ b(vs, &slow);
+
+ __ bind(&smi_check);
+ // Check if the result can fit into an smi. If we had an overflow,
+ // the result is either 0x80000000 or 0x7FFFFFFF and won't fit into an smi.
__ add(r1, r0, Operand(0x40000000), SetCC);
- __ b(&wont_fit_smi, mi);
+ // If result doesn't fit into an smi, branch to slow.
+ __ b(&slow, mi);
// Tag the result.
- STATIC_ASSERT(kSmiTag == 0);
__ mov(r0, Operand(r0, LSL, kSmiTagSize));
- // Check for -0.
- __ cmp(r0, Operand::Zero());
- __ b(&restore_fpscr_and_return, ne);
- // r5 already holds the HeapNumber exponent.
- __ tst(r5, Operand(HeapNumber::kSignMask));
- // If our HeapNumber is negative it was -0, so load its address and return.
- // Else r0 is loaded with 0, so we can also just return.
- __ ldr(r0, MemOperand(sp, 0 * kPointerSize), ne);
-
- __ bind(&restore_fpscr_and_return);
- // Restore FPSCR and return.
- __ vmsr(r3);
+ __ bind(&just_return);
__ Drop(argc + 1);
__ Ret();
- __ bind(&wont_fit_smi);
- // Restore FPCSR and fall to slow case.
- __ vmsr(r3);
-
__ bind(&slow);
// Tail call the full function. We do not have to patch the receiver
// because the function makes no use of it.
@@ -3363,12 +3333,7 @@
DONT_DO_SMI_CHECK);
__ sub(ip, key, Operand(kHeapObjectTag));
__ vldr(double_scratch0, ip, HeapNumber::kValueOffset);
- __ EmitVFPTruncate(kRoundToZero,
- scratch0,
- double_scratch0,
- scratch1,
- double_scratch1,
- kCheckForInexactConversion);
+ __ TryDoubleToInt32Exact(scratch0, double_scratch0, double_scratch1);
__ b(ne, fail);
__ TrySmiTag(scratch0, fail, scratch1);
__ mov(key, scratch0);
« no previous file with comments | « src/arm/macro-assembler-arm.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698