Revision: 20755
Author: [email protected]
Date: Tue Apr 15 09:58:09 2014 UTC
Log: ARM: Do not set FPSCR when converting to clamped uint8
Setting the FPSCR flags is expensive on some CPUs. Get rid of repeated
setting of the FPSCR by relying on the correct default flags being set
when doing uint8 clamping. Also use vcvt_u32_f64 instead of vcvt_s32_f64,
which enables removing the check against zero (vcvt_u32_f64 will clamp to
zero).
To be on the safe side, add asserts to check that the VFP rounding mode
flags are set to default as expected.
This increases performance of a hot loop repeatedly setting
Uint8ClampedArray values on some CPUs by as much as a factor of 12.
BUG=v8:3253
LOG=N
[email protected], [email protected], [email protected]
Committed: https://code.google.com/p/v8/source/detail?r=20676
Review URL: https://codereview.chromium.org/230473005
Patch from Olli Etuaho <[email protected]>.
http://code.google.com/p/v8/source/detail?r=20755
Modified:
/branches/bleeding_edge/src/arm/macro-assembler-arm.cc
=======================================
--- /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Fri Apr 11
10:04:25 2014 UTC
+++ /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Tue Apr 15
09:58:09 2014 UTC
@@ -796,6 +796,14 @@
// 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);
+ // Don't call Assert here, since Runtime_Abort could re-enter 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::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);
+ VFPCompareAndSetFlags(input_reg, double_scratch);
+ b(ge, &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);
+ // 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);
}
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.