mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-10 15:20:10 +00:00
Speed up the ARM fenv implementation by avoiding unnecessary FPSCR
writes if the FPSCR remains unchanged. 2014-06-24 Wilco <wdijkstr@arm.com> * sysdeps/arm/fclrexcpt.c (feclearexcept): Optimize to avoid unnecessary FPSCR writes. * sysdeps/arm/fedisblxcpt.c (fedisableexcept): Likewise. * sysdeps/arm/feenablxcpt.c (feenableexcept): Likewise. * sysdeps/arm/fsetexcptflg.c (fesetexceptflag): Likewise. * sysdeps/arm/setfpucw.c (__setfpucw): Likewise.
This commit is contained in:
parent
4841e6a6c2
commit
001f7b773c
@ -1,3 +1,12 @@
|
||||
2014-06-24 Wilco <wdijkstr@arm.com>
|
||||
|
||||
* sysdeps/arm/fclrexcpt.c (feclearexcept):
|
||||
Optimize to avoid unnecessary FPSCR writes.
|
||||
* sysdeps/arm/fedisblxcpt.c (fedisableexcept): Likewise.
|
||||
* sysdeps/arm/feenablxcpt.c (feenableexcept): Likewise.
|
||||
* sysdeps/arm/fsetexcptflg.c (fesetexceptflag): Likewise.
|
||||
* sysdeps/arm/setfpucw.c (__setfpucw): Likewise.
|
||||
|
||||
2014-06-24 Wilco <wdijkstr@arm.com>
|
||||
|
||||
* sysdeps/arm/fegetround.c (fegetround): Call get_rounding_mode.
|
||||
|
@ -24,7 +24,7 @@
|
||||
int
|
||||
feclearexcept (int excepts)
|
||||
{
|
||||
fpu_control_t fpscr;
|
||||
fpu_control_t fpscr, new_fpscr;
|
||||
|
||||
/* Fail if a VFP unit isn't present unless nothing needs to be done. */
|
||||
if (!ARM_HAVE_VFP)
|
||||
@ -32,11 +32,11 @@ feclearexcept (int excepts)
|
||||
|
||||
_FPU_GETCW (fpscr);
|
||||
excepts &= FE_ALL_EXCEPT;
|
||||
new_fpscr = fpscr & ~excepts;
|
||||
|
||||
/* Clear the relevant bits. */
|
||||
fpscr = (fpscr & ~FE_ALL_EXCEPT) | (fpscr & FE_ALL_EXCEPT & ~excepts);
|
||||
|
||||
_FPU_SETCW (fpscr);
|
||||
/* Write new exception flags if changed. */
|
||||
if (new_fpscr != fpscr)
|
||||
_FPU_SETCW (new_fpscr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -35,7 +35,9 @@ fedisableexcept (int excepts)
|
||||
excepts &= FE_ALL_EXCEPT;
|
||||
new_fpscr = fpscr & ~(excepts << FE_EXCEPT_SHIFT);
|
||||
|
||||
_FPU_SETCW (new_fpscr);
|
||||
/* Write new exceptions if changed. */
|
||||
if (new_fpscr != fpscr)
|
||||
_FPU_SETCW (new_fpscr);
|
||||
|
||||
return (fpscr >> FE_EXCEPT_SHIFT) & FE_ALL_EXCEPT;
|
||||
}
|
||||
|
@ -25,7 +25,7 @@
|
||||
int
|
||||
feenableexcept (int excepts)
|
||||
{
|
||||
fpu_control_t fpscr, new_fpscr;
|
||||
fpu_control_t fpscr, new_fpscr, updated_fpscr;
|
||||
|
||||
/* Fail if a VFP unit isn't present. */
|
||||
if (!ARM_HAVE_VFP)
|
||||
@ -35,15 +35,15 @@ feenableexcept (int excepts)
|
||||
excepts &= FE_ALL_EXCEPT;
|
||||
new_fpscr = fpscr | (excepts << FE_EXCEPT_SHIFT);
|
||||
|
||||
_FPU_SETCW (new_fpscr);
|
||||
|
||||
if (excepts != 0)
|
||||
if (new_fpscr != fpscr)
|
||||
{
|
||||
_FPU_SETCW (new_fpscr);
|
||||
|
||||
/* Not all VFP architectures support trapping exceptions, so
|
||||
test whether the relevant bits were set and fail if not. */
|
||||
_FPU_GETCW (new_fpscr);
|
||||
if ((new_fpscr & (excepts << FE_EXCEPT_SHIFT))
|
||||
!= (excepts << FE_EXCEPT_SHIFT))
|
||||
_FPU_GETCW (updated_fpscr);
|
||||
|
||||
if (new_fpscr & ~updated_fpscr)
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -25,19 +25,22 @@
|
||||
int
|
||||
fesetexceptflag (const fexcept_t *flagp, int excepts)
|
||||
{
|
||||
fpu_control_t fpscr;
|
||||
fpu_control_t fpscr, new_fpscr;
|
||||
|
||||
/* Fail if a VFP unit isn't present unless nothing needs to be done. */
|
||||
if (!ARM_HAVE_VFP)
|
||||
return (excepts != 0);
|
||||
|
||||
_FPU_GETCW (fpscr);
|
||||
excepts &= FE_ALL_EXCEPT;
|
||||
|
||||
/* Set the desired exception mask. */
|
||||
fpscr &= ~(excepts & FE_ALL_EXCEPT);
|
||||
fpscr |= (*flagp & excepts & FE_ALL_EXCEPT);
|
||||
new_fpscr = fpscr & ~excepts;
|
||||
new_fpscr |= *flagp & excepts;
|
||||
|
||||
/* Write new exception flags if changed. */
|
||||
if (new_fpscr != fpscr)
|
||||
_FPU_SETCW (new_fpscr);
|
||||
|
||||
/* Save state back to the FPU. */
|
||||
_FPU_SETCW (fpscr);
|
||||
return 0;
|
||||
}
|
||||
|
@ -24,19 +24,20 @@
|
||||
void
|
||||
__setfpucw (fpu_control_t set)
|
||||
{
|
||||
fpu_control_t fpscr;
|
||||
fpu_control_t fpscr, new_fpscr;
|
||||
|
||||
/* Do nothing if a VFP unit isn't present. */
|
||||
if (!ARM_HAVE_VFP)
|
||||
return;
|
||||
|
||||
/* Fetch the current control word. */
|
||||
_FPU_GETCW (fpscr);
|
||||
|
||||
/* Preserve the reserved bits, and set the rest as the user
|
||||
specified (or the default, if the user gave zero). */
|
||||
fpscr &= _FPU_RESERVED;
|
||||
fpscr |= set & ~_FPU_RESERVED;
|
||||
new_fpscr = fpscr & _FPU_RESERVED;
|
||||
new_fpscr |= set & ~_FPU_RESERVED;
|
||||
|
||||
_FPU_SETCW (fpscr);
|
||||
/* Write FPSCR if changed. */
|
||||
if (new_fpscr != fpscr)
|
||||
_FPU_SETCW (fpscr);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user