Revision: 13162
Author: [email protected]
Date: Fri Dec 7 03:29:27 2012
Log: Improve double to integer truncation on ARM.
BUG=none
TEST=none
Review URL: https://chromiumcodereview.appspot.com/11412272
Patch from Rodolph Perfetta <[email protected]>.
http://code.google.com/p/v8/source/detail?r=13162
Modified:
/branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
/branches/bleeding_edge/src/arm/macro-assembler-arm.cc
/branches/bleeding_edge/src/arm/macro-assembler-arm.h
/branches/bleeding_edge/src/arm/stub-cache-arm.cc
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Wed Dec 5
07:49:22 2012
+++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Fri Dec 7
03:29:27 2012
@@ -4968,7 +4968,6 @@
if (instr->truncating()) {
CpuFeatures::Scope scope(VFP2);
Register scratch3 = ToRegister(instr->temp2());
- SwVfpRegister single_scratch = double_scratch.low();
ASSERT(!scratch3.is(input_reg) &&
!scratch3.is(scratch1) &&
!scratch3.is(scratch2));
@@ -4990,7 +4989,7 @@
__ EmitECMATruncate(input_reg,
double_scratch2,
- single_scratch,
+ double_scratch,
scratch1,
scratch2,
scratch3);
@@ -5072,20 +5071,19 @@
Register scratch1 = scratch0();
Register scratch2 = ToRegister(instr->temp());
DwVfpRegister double_input = ToDoubleRegister(instr->value());
+ DwVfpRegister double_scratch = double_scratch0();
Label done;
if (instr->truncating()) {
Register scratch3 = ToRegister(instr->temp2());
- SwVfpRegister single_scratch = double_scratch0().low();
__ EmitECMATruncate(result_reg,
double_input,
- single_scratch,
+ double_scratch,
scratch1,
scratch2,
scratch3);
} else {
- DwVfpRegister double_scratch = double_scratch0();
__ EmitVFPTruncate(kRoundToMinusInf,
result_reg,
double_input,
=======================================
--- /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Wed Dec 5
03:04:10 2012
+++ /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Fri Dec 7
03:29:27 2012
@@ -2488,6 +2488,20 @@
bind(&done);
}
}
+
+
+void MacroAssembler::TryFastDoubleToInt32(Register result,
+ DwVfpRegister double_input,
+ DwVfpRegister double_scratch,
+ Label* done) {
+ ASSERT(!double_input.is(double_scratch));
+
+ 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,
@@ -2505,11 +2519,7 @@
Label done;
// Test for values that can be exactly represented as a signed 32-bit
integer.
- 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);
+ TryFastDoubleToInt32(result, double_input, double_scratch, &done);
// Convert to integer, respecting rounding mode.
int32_t check_inexact_conversion =
@@ -2626,7 +2636,7 @@
void MacroAssembler::EmitECMATruncate(Register result,
DwVfpRegister double_input,
- SwVfpRegister single_scratch,
+ DwVfpRegister double_scratch,
Register scratch,
Register input_high,
Register input_low) {
@@ -2637,16 +2647,18 @@
ASSERT(!scratch.is(result) &&
!scratch.is(input_high) &&
!scratch.is(input_low));
- ASSERT(!single_scratch.is(double_input.low()) &&
- !single_scratch.is(double_input.high()));
+ ASSERT(!double_input.is(double_scratch));
Label done;
+ // Test for values that can be exactly represented as a signed 32-bit
integer.
+ TryFastDoubleToInt32(result, double_input, double_scratch, &done);
+
// Clear cumulative exception flags.
ClearFPSCRBits(kVFPExceptionMask, scratch);
// Try a conversion to a signed integer.
- vcvt_s32_f64(single_scratch, double_input);
- vmov(result, single_scratch);
+ vcvt_s32_f64(double_scratch.low(), double_input);
+ vmov(result, double_scratch.low());
// Retrieve he FPSCR.
vmrs(scratch);
// Check for overflow and NaNs.
=======================================
--- /branches/bleeding_edge/src/arm/macro-assembler-arm.h Wed Dec 5
03:04:10 2012
+++ /branches/bleeding_edge/src/arm/macro-assembler-arm.h Fri Dec 7
03:29:27 2012
@@ -959,6 +959,14 @@
DwVfpRegister double_scratch,
Label *not_int32);
+ // Try to convert a double to a signed 32-bit integer. If the double
value
+ // can be exactly represented as an integer, the code jumps to 'done' and
+ // 'result' contains the integer value. Otherwise, the code falls
through.
+ void TryFastDoubleToInt32(Register result,
+ DwVfpRegister double_input,
+ DwVfpRegister double_scratch,
+ Label* done);
+
// Truncates a double using a specific rounding mode, and writes the
value
// to the result register.
// Clears the z flag (ne condition) if an overflow occurs.
@@ -989,7 +997,7 @@
// Exits with 'result' holding the answer and all other registers
clobbered.
void EmitECMATruncate(Register result,
DwVfpRegister double_input,
- SwVfpRegister single_scratch,
+ DwVfpRegister double_scratch,
Register scratch,
Register scratch2,
Register scratch3);
=======================================
--- /branches/bleeding_edge/src/arm/stub-cache-arm.cc Wed Dec 5 03:04:10
2012
+++ /branches/bleeding_edge/src/arm/stub-cache-arm.cc Fri Dec 7 03:29:27
2012
@@ -3836,7 +3836,7 @@
// not include -kHeapObjectTag into it.
__ sub(r5, value, Operand(kHeapObjectTag));
__ vldr(d0, r5, HeapNumber::kValueOffset);
- __ EmitECMATruncate(r5, d0, s2, r6, r7, r9);
+ __ EmitECMATruncate(r5, d0, d1, r6, r7, r9);
switch (elements_kind) {
case EXTERNAL_BYTE_ELEMENTS:
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev