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); |
} |