Skip to content

Commit

Permalink
[AArch64] Rewrite feupdateenv (BZ 17009).
Browse files Browse the repository at this point in the history
  • Loading branch information
Wilco authored and Marcus Shawcroft committed Jun 2, 2014
1 parent 6b4d7a9 commit c95b301
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 6 deletions.
6 changes: 6 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
3 changes: 2 additions & 1 deletion NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
59 changes: 54 additions & 5 deletions sysdeps/aarch64/fpu/feupdateenv.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down

0 comments on commit c95b301

Please sign in to comment.