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

Unified Diff: src/arm/macro-assembler-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
Index: src/arm/macro-assembler-arm.cc
===================================================================
--- src/arm/macro-assembler-arm.cc (revision 13783)
+++ src/arm/macro-assembler-arm.cc (working copy)
@@ -2525,74 +2525,76 @@
}
-void MacroAssembler::TryFastDoubleToInt32(Register result,
- DwVfpRegister double_input,
- DwVfpRegister double_scratch,
- Label* done) {
+void MacroAssembler::TestDoubleIsInt32(DwVfpRegister double_input,
+ DwVfpRegister double_scratch) {
ASSERT(!double_input.is(double_scratch));
+ ASSERT(CpuFeatures::IsSupported(VFP2));
+ CpuFeatures::Scope scope(VFP2);
vcvt_s32_f64(double_scratch.low(), double_input);
- vmov(result, double_scratch.low());
vcvt_f64_s32(double_scratch, double_scratch.low());
VFPCompareAndSetFlags(double_input, double_scratch);
- b(eq, done);
}
-void MacroAssembler::EmitVFPTruncate(VFPRoundingMode rounding_mode,
- Register result,
- DwVfpRegister double_input,
- Register scratch,
- DwVfpRegister double_scratch,
- CheckForInexactConversion check_inexact) {
- ASSERT(!result.is(scratch));
+void MacroAssembler::TryDoubleToInt32Exact(Register result,
+ DwVfpRegister double_input,
+ DwVfpRegister double_scratch) {
ASSERT(!double_input.is(double_scratch));
-
ASSERT(CpuFeatures::IsSupported(VFP2));
CpuFeatures::Scope scope(VFP2);
- Register prev_fpscr = result;
- Label done;
- // Test for values that can be exactly represented as a signed 32-bit integer.
- TryFastDoubleToInt32(result, double_input, double_scratch, &done);
+ vcvt_s32_f64(double_scratch.low(), double_input);
+ vmov(result, double_scratch.low());
+ vcvt_f64_s32(double_scratch, double_scratch.low());
+ VFPCompareAndSetFlags(double_input, double_scratch);
+}
- // Convert to integer, respecting rounding mode.
- int32_t check_inexact_conversion =
- (check_inexact == kCheckForInexactConversion) ? kVFPInexactExceptionBit : 0;
- // Set custom FPCSR:
- // - Set rounding mode.
- // - Clear vfp cumulative exception flags.
- // - Make sure Flush-to-zero mode control bit is unset.
- vmrs(prev_fpscr);
- bic(scratch,
- prev_fpscr,
- Operand(kVFPExceptionMask |
- check_inexact_conversion |
- kVFPRoundingModeMask |
- kVFPFlushToZeroMask));
- // 'Round To Nearest' is encoded by 0b00 so no bits need to be set.
- if (rounding_mode != kRoundToNearest) {
- orr(scratch, scratch, Operand(rounding_mode));
- }
- vmsr(scratch);
+void MacroAssembler::TryInt32Floor(Register result,
+ DwVfpRegister double_input,
+ Register input_high,
+ DwVfpRegister double_scratch,
+ Label* done,
+ Label* exact) {
+ ASSERT(!result.is(input_high));
+ ASSERT(!double_input.is(double_scratch));
+ ASSERT(CpuFeatures::IsSupported(VFP2));
+ CpuFeatures::Scope scope(VFP2);
+ Label negative, exception;
- // Convert the argument to an integer.
- vcvt_s32_f64(double_scratch.low(),
- double_input,
- (rounding_mode == kRoundToZero) ? kDefaultRoundToZero
- : kFPSCRRounding);
+ // Test for NaN and infinities.
+ Sbfx(result, input_high,
+ HeapNumber::kExponentShift, HeapNumber::kExponentBits);
+ cmp(result, Operand(-1));
+ b(eq, &exception);
+ // Test for values that can be exactly represented as a
+ // signed 32-bit integer.
+ TryDoubleToInt32Exact(result, double_input, double_scratch);
+ // If exact, return (result already fetched).
+ b(eq, exact);
+ cmp(input_high, Operand::Zero());
+ b(mi, &negative);
- // Retrieve FPSCR.
- vmrs(scratch);
- // Restore FPSCR.
- vmsr(prev_fpscr);
- // Move the converted value into the result register.
- vmov(result, double_scratch.low());
- // Check for vfp exceptions.
- tst(scratch, Operand(kVFPExceptionMask | check_inexact_conversion));
+ // Input is in ]+0, +inf[.
+ // If result equals 0x7fffffff input was out of range or
+ // in ]0x7fffffff, 0x80000000[. We ignore this last case which
+ // could fits into an int32, that means we always think input was
+ // out of range and always go to exception.
+ // If result < 0x7fffffff, go to done, result fetched.
+ cmn(result, Operand(1));
+ b(mi, &exception);
+ b(done);
- bind(&done);
+ // Input is in ]-inf, -0[.
+ // If x is a non integer negative number,
+ // floor(x) <=> round_to_zero(x) - 1.
+ bind(&negative);
+ sub(result, result, Operand(1), SetCC);
+ // If result is still negative, go to done, result fetched.
+ // Else, we had an overflow and we fall through exception.
+ b(mi, done);
+ bind(&exception);
}
@@ -2687,33 +2689,25 @@
Label done;
// Test if the value can be exactly represented as a signed integer.
- vcvt_s32_f64(double_scratch.low(), double_input);
- vmov(result, double_scratch.low());
- vcvt_f64_s32(double_scratch, double_scratch.low());
- // Note: this comparison is cheaper than reading the FPSCR exception bits.
- VFPCompareAndSetFlags(double_input, double_scratch);
+ TryDoubleToInt32Exact(result, double_input, double_scratch);
b(eq, &done);
// Check the exception flags. If they are not set, we are done.
// If they are set, it could be because of the conversion above, or because
// they were set before this code.
vmrs(scratch);
- tst(scratch, Operand(kVFPOverflowExceptionBit |
- kVFPUnderflowExceptionBit |
- kVFPInvalidOpExceptionBit));
+ tst(scratch, Operand(kVFPInvalidOpExceptionBit));
b(eq, &done);
// Clear cumulative exception flags.
- bic(scratch, scratch, Operand(kVFPExceptionMask));
+ bic(scratch, scratch, Operand(kVFPInvalidOpExceptionBit));
vmsr(scratch);
// Try a conversion to a signed integer.
vcvt_s32_f64(double_scratch.low(), double_input);
// Retrieve the FPSCR.
vmrs(scratch);
- // Check for overflow and NaNs.
- tst(scratch, Operand(kVFPOverflowExceptionBit |
- kVFPUnderflowExceptionBit |
- kVFPInvalidOpExceptionBit));
+ // Check for invalid conversions (out of range and NaNs).
+ tst(scratch, Operand(kVFPInvalidOpExceptionBit));
// If we had no exceptions we are done.
b(eq, &done);

Powered by Google App Engine
This is Rietveld 408576698