[AArch64] Rewrite feupdateenv (BZ 17009).

This commit is contained in:
Wilco 2014-06-02 12:20:17 +01:00 committed by Marcus Shawcroft
parent 6b4d7a909f
commit c95b301101
3 changed files with 62 additions and 6 deletions

View File

@ -1,3 +1,9 @@
2014-06-02 Wilco <wdijkstr@arm.com>
[BZ #17009]
* sysdeps/aarch64/fpu/feupdateenv (feupdateenv):
Rewrite to reduce FPCR/FPSR accesses.
2014-06-01 David S. Miller <davem@davemloft.net>
* sysdeps/sparc/fpu/libm-test-ulps: Update.

3
NEWS
View File

@ -18,7 +18,8 @@ Version 2.20
16758, 16759, 16760, 16770, 16786, 16789, 16791, 16796, 16799, 16800,
16815, 16823, 16824, 16831, 16838, 16849, 16854, 16876, 16877, 16878,
16885, 16888, 16890, 16912, 16915, 16916, 16917, 16922, 16927, 16928,
16932, 16943, 16958, 16966, 16967, 16965, 16977, 16978, 16984, 16990.
16932, 16943, 16958, 16966, 16967, 16965, 16977, 16978, 16984, 16990,
17009.
* The minimum Linux kernel version that this version of the GNU C Library
can be used with is 2.6.32.

View File

@ -22,16 +22,65 @@
int
feupdateenv (const fenv_t *envp)
{
fpu_control_t fpcr;
fpu_control_t fpcr_new;
fpu_control_t updated_fpcr;
fpu_fpsr_t fpsr;
fpu_fpsr_t fpsr_new;
int excepts;
/* Get the current exception state. */
_FPU_GETCW (fpcr);
_FPU_GETFPSR (fpsr);
excepts = fpsr & FE_ALL_EXCEPT;
/* Install new environment. */
fesetenv (envp);
if ((envp != FE_DFL_ENV) && (envp != FE_NOMASK_ENV))
{
fpcr_new = envp->__fpcr;
fpsr_new = envp->__fpsr | excepts;
/* Raise the saved exceptions. */
feraiseexcept (fpsr & FE_ALL_EXCEPT);
if (fpcr != fpcr_new)
_FPU_SETCW (fpcr_new);
if (fpsr != fpsr_new)
_FPU_SETFPSR (fpsr_new);
if (excepts & (fpcr_new >> FE_EXCEPT_SHIFT))
return feraiseexcept (excepts);
return 0;
}
fpcr_new = fpcr & _FPU_RESERVED;
fpsr_new = fpsr & (_FPU_FPSR_RESERVED | FE_ALL_EXCEPT);
if (envp == FE_DFL_ENV)
{
fpcr_new |= _FPU_DEFAULT;
fpsr_new |= _FPU_FPSR_DEFAULT;
}
else
{
fpcr_new |= _FPU_FPCR_IEEE;
fpsr_new |= _FPU_FPSR_IEEE;
}
_FPU_SETFPSR (fpsr_new);
if (fpcr != fpcr_new)
{
_FPU_SETCW (fpcr_new);
/* Trapping exceptions are optional in AArch64; the relevant enable
bits in FPCR are RES0 hence the absence of support can be detected
by reading back the FPCR and comparing with the required value. */
_FPU_GETCW (updated_fpcr);
if (fpcr_new & ~updated_fpcr)
return 1;
}
if (excepts & (fpcr_new >> FE_EXCEPT_SHIFT))
return feraiseexcept (excepts);
return 0;
}