| Index: src/arm/lithium-codegen-arm.cc
|
| ===================================================================
|
| --- src/arm/lithium-codegen-arm.cc (revision 13783)
|
| +++ src/arm/lithium-codegen-arm.cc (working copy)
|
| @@ -3898,25 +3898,22 @@
|
| CpuFeatures::Scope scope(VFP2);
|
| DwVfpRegister input = ToDoubleRegister(instr->value());
|
| Register result = ToRegister(instr->result());
|
| - Register scratch = scratch0();
|
| + Register input_high = scratch0();
|
| + Label done, exact;
|
|
|
| - __ EmitVFPTruncate(kRoundToMinusInf,
|
| - result,
|
| - input,
|
| - scratch,
|
| - double_scratch0());
|
| - DeoptimizeIf(ne, instr->environment());
|
| + __ vmov(input_high, input.high());
|
| + __ TryInt32Floor(result, input, input_high, double_scratch0(), &done, &exact);
|
| + DeoptimizeIf(al, instr->environment());
|
|
|
| + __ bind(&exact);
|
| if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
|
| // Test for -0.
|
| - Label done;
|
| __ cmp(result, Operand::Zero());
|
| __ b(ne, &done);
|
| - __ vmov(scratch, input.high());
|
| - __ tst(scratch, Operand(HeapNumber::kSignMask));
|
| - DeoptimizeIf(ne, instr->environment());
|
| - __ bind(&done);
|
| + __ cmp(input_high, Operand::Zero());
|
| + DeoptimizeIf(mi, instr->environment());
|
| }
|
| + __ bind(&done);
|
| }
|
|
|
|
|
| @@ -3925,63 +3922,37 @@
|
| DwVfpRegister input = ToDoubleRegister(instr->value());
|
| Register result = ToRegister(instr->result());
|
| DwVfpRegister double_scratch1 = ToDoubleRegister(instr->temp());
|
| - Register scratch = scratch0();
|
| - Label done, check_sign_on_zero;
|
| + DwVfpRegister input_plus_dot_five = double_scratch1;
|
| + Register input_high = scratch0();
|
| + DwVfpRegister dot_five = double_scratch0();
|
| + Label convert, done;
|
|
|
| - // Extract exponent bits.
|
| - __ vmov(result, input.high());
|
| - __ ubfx(scratch,
|
| - result,
|
| - HeapNumber::kExponentShift,
|
| - HeapNumber::kExponentBits);
|
| -
|
| - // If the number is in ]-0.5, +0.5[, the result is +/- 0.
|
| - __ cmp(scratch, Operand(HeapNumber::kExponentBias - 2));
|
| - __ mov(result, Operand::Zero(), LeaveCC, le);
|
| + __ Vmov(dot_five, 0.5, scratch0());
|
| + __ vabs(double_scratch1, input);
|
| + __ VFPCompareAndSetFlags(double_scratch1, dot_five);
|
| + // If input is in [-0.5, -0], the result is -0.
|
| + // If input is in [+0, +0.5[, the result is +0.
|
| + // If the input is +0.5, the result is 1.
|
| + __ b(hi, &convert); // Out of [-0.5, +0.5].
|
| if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
|
| - __ b(le, &check_sign_on_zero);
|
| - } else {
|
| - __ b(le, &done);
|
| + __ vmov(input_high, input.high());
|
| + __ cmp(input_high, Operand::Zero());
|
| + DeoptimizeIf(mi, instr->environment()); // [-0.5, -0].
|
| }
|
| + __ VFPCompareAndSetFlags(input, dot_five);
|
| + __ mov(result, Operand(1), LeaveCC, eq); // +0.5.
|
| + // Remaining cases: [+0, +0.5[ or [-0.5, +0.5[, depending on
|
| + // flag kBailoutOnMinusZero.
|
| + __ mov(result, Operand::Zero(), LeaveCC, ne);
|
| + __ b(&done);
|
|
|
| - // The following conversion will not work with numbers
|
| - // outside of ]-2^32, 2^32[.
|
| - __ cmp(scratch, Operand(HeapNumber::kExponentBias + 32));
|
| - DeoptimizeIf(ge, instr->environment());
|
| -
|
| - __ Vmov(double_scratch0(), 0.5, scratch);
|
| - __ vadd(double_scratch0(), input, double_scratch0());
|
| -
|
| - // Save the original sign for later comparison.
|
| - __ and_(scratch, result, Operand(HeapNumber::kSignMask));
|
| -
|
| - // Check sign of the result: if the sign changed, the input
|
| - // value was in ]0.5, 0[ and the result should be -0.
|
| - __ vmov(result, double_scratch0().high());
|
| - __ eor(result, result, Operand(scratch), SetCC);
|
| - if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
|
| - DeoptimizeIf(mi, instr->environment());
|
| - } else {
|
| - __ mov(result, Operand::Zero(), LeaveCC, mi);
|
| - __ b(mi, &done);
|
| - }
|
| -
|
| - __ EmitVFPTruncate(kRoundToMinusInf,
|
| - result,
|
| - double_scratch0(),
|
| - scratch,
|
| - double_scratch1);
|
| - DeoptimizeIf(ne, instr->environment());
|
| -
|
| - if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
|
| - // Test for -0.
|
| - __ cmp(result, Operand::Zero());
|
| - __ b(ne, &done);
|
| - __ bind(&check_sign_on_zero);
|
| - __ vmov(scratch, input.high());
|
| - __ tst(scratch, Operand(HeapNumber::kSignMask));
|
| - DeoptimizeIf(ne, instr->environment());
|
| - }
|
| + __ bind(&convert);
|
| + __ vadd(input_plus_dot_five, input, dot_five);
|
| + __ vmov(input_high, input_plus_dot_five.high());
|
| + // Reuse dot_five (double_scratch0) as we no longer need this value.
|
| + __ TryInt32Floor(result, input_plus_dot_five, input_high, double_scratch0(),
|
| + &done, &done);
|
| + DeoptimizeIf(al, instr->environment());
|
| __ bind(&done);
|
| }
|
|
|
| @@ -5233,12 +5204,7 @@
|
|
|
| __ sub(ip, input_reg, Operand(kHeapObjectTag));
|
| __ vldr(double_scratch, ip, HeapNumber::kValueOffset);
|
| - __ EmitVFPTruncate(kRoundToZero,
|
| - input_reg,
|
| - double_scratch,
|
| - scratch1,
|
| - double_scratch2,
|
| - kCheckForInexactConversion);
|
| + __ TryDoubleToInt32Exact(input_reg, double_scratch, double_scratch2);
|
| DeoptimizeIf(ne, instr->environment());
|
|
|
| if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
|
| @@ -5334,15 +5300,8 @@
|
| scratch2,
|
| scratch3);
|
| } else {
|
| - __ EmitVFPTruncate(kRoundToMinusInf,
|
| - result_reg,
|
| - double_input,
|
| - scratch1,
|
| - double_scratch,
|
| - kCheckForInexactConversion);
|
| -
|
| - // Deoptimize if we had a vfp invalid exception,
|
| - // including inexact operation.
|
| + __ TryDoubleToInt32Exact(result_reg, double_input, double_scratch);
|
| + // Deoptimize if the input wasn't a int32 (inside a double).
|
| DeoptimizeIf(ne, instr->environment());
|
| }
|
| __ bind(&done);
|
|
|