| Index: src/arm/macro-assembler-arm.cc
|
| diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc
|
| index 1633adc1331e203edbacf85a6419a81b02e13653..5bba07ff05bb4ccb16926790b8b87f06a1d641aa 100644
|
| --- a/src/arm/macro-assembler-arm.cc
|
| +++ b/src/arm/macro-assembler-arm.cc
|
| @@ -796,6 +796,14 @@ void MacroAssembler::VFPEnsureFPSCRState(Register scratch) {
|
| // If needed, restore wanted bits of FPSCR.
|
| Label fpscr_done;
|
| vmrs(scratch);
|
| + if (emit_debug_code()) {
|
| + Label rounding_mode_correct;
|
| + tst(scratch, Operand(kVFPRoundingModeMask));
|
| + b(eq, &rounding_mode_correct);
|
| + // Can't call Assert here, as it will recurse back here.
|
| + stop("Default rounding mode not set");
|
| + bind(&rounding_mode_correct);
|
| + }
|
| tst(scratch, Operand(kVFPDefaultNaNModeControlBit));
|
| b(ne, &fpscr_done);
|
| orr(scratch, scratch, Operand(kVFPDefaultNaNModeControlBit));
|
| @@ -3800,36 +3808,19 @@ void MacroAssembler::ClampUint8(Register output_reg, Register input_reg) {
|
| void MacroAssembler::ClampDoubleToUint8(Register result_reg,
|
| DwVfpRegister input_reg,
|
| LowDwVfpRegister double_scratch) {
|
| - Label above_zero;
|
| Label done;
|
| - Label in_bounds;
|
| -
|
| - VFPCompareAndSetFlags(input_reg, 0.0);
|
| - b(gt, &above_zero);
|
| -
|
| - // Double value is less than zero, NaN or Inf, return 0.
|
| - mov(result_reg, Operand::Zero());
|
| - b(al, &done);
|
|
|
| - // Double value is >= 255, return 255.
|
| - bind(&above_zero);
|
| + // Handle inputs >= 255 (including +infinity).
|
| Vmov(double_scratch, 255.0, result_reg);
|
| - VFPCompareAndSetFlags(input_reg, double_scratch);
|
| - b(le, &in_bounds);
|
| mov(result_reg, Operand(255));
|
| - b(al, &done);
|
| -
|
| - // In 0-255 range, round and truncate.
|
| - bind(&in_bounds);
|
| - // Save FPSCR.
|
| - vmrs(ip);
|
| - // Set rounding mode to round to the nearest integer by clearing bits[23:22].
|
| - bic(result_reg, ip, Operand(kVFPRoundingModeMask));
|
| - vmsr(result_reg);
|
| - vcvt_s32_f64(double_scratch.low(), input_reg, kFPSCRRounding);
|
| + VFPCompareAndSetFlags(input_reg, double_scratch);
|
| + b(ge, &done);
|
| +
|
| + // For inputs < 255 (including negative) vcvt_u32_f64 with round-to-nearest
|
| + // rounding mode will provide the correct result.
|
| + vcvt_u32_f64(double_scratch.low(), input_reg, kFPSCRRounding);
|
| vmov(result_reg, double_scratch.low());
|
| - // Restore FPSCR.
|
| - vmsr(ip);
|
| +
|
| bind(&done);
|
| }
|
|
|
|
|