Commit c5c8276f authored by ulan@chromium.org's avatar ulan@chromium.org

Improve double to integer truncation on ARM.

BUG=none
TEST=none

Review URL: https://chromiumcodereview.appspot.com/11412272
Patch from Rodolph Perfetta <rodolph.perfetta@gmail.com>.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@13162 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 3348b5c2
......@@ -4968,7 +4968,6 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
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 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
__ EmitECMATruncate(input_reg,
double_scratch2,
single_scratch,
double_scratch,
scratch1,
scratch2,
scratch3);
......@@ -5072,20 +5071,19 @@ void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
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,
......
......@@ -2490,6 +2490,20 @@ void MacroAssembler::ConvertToInt32(Register source,
}
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,
Register result,
DwVfpRegister double_input,
......@@ -2505,11 +2519,7 @@ void MacroAssembler::EmitVFPTruncate(VFPRoundingMode rounding_mode,
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::EmitOutOfInt32RangeTruncate(Register result,
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 @@ void MacroAssembler::EmitECMATruncate(Register result,
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.
......
......@@ -959,6 +959,14 @@ class MacroAssembler: public Assembler {
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 @@ class MacroAssembler: public Assembler {
// 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);
......
......@@ -3836,7 +3836,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray(
// 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:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment