Fix powerpc fesetexceptflag clearing FE_INVALID (bug 20455).

As shown by the test math/test-fexcept, the powerpc fesetexceptflag
implementation fails to clear a previously set FE_INVALID flag, when
that flag is clear in the saved exceptions and FE_INVALID is included
in the mask of flags to restore, because it fails to mask out the
sub-exceptions of FE_INVALID from the FPSCR state.  This patch fixes
the masking logic accordingly.

Tested for powerpc.

	[BZ #20455]
	* sysdeps/powerpc/fpu/fsetexcptflg.c (__fesetexceptflag): Mask out
	all FE_INVALID sub-exceptions from FPSCR when FE_INVALID specified
	to be restored.
This commit is contained in:
Joseph Myers 2016-08-10 21:47:35 +00:00
parent 5220a1aa8d
commit f792117921
2 changed files with 9 additions and 1 deletions

View File

@ -1,5 +1,10 @@
2016-08-10 Joseph Myers <joseph@codesourcery.com>
[BZ #20455]
* sysdeps/powerpc/fpu/fsetexcptflg.c (__fesetexceptflag): Mask out
all FE_INVALID sub-exceptions from FPSCR when FE_INVALID specified
to be restored.
* math/test-fexcept-traps.c: New file.
* math/test-fexcept.c: Likewise.
* math/Makefile (tests): Add test-fexcept and test-fexcept-traps.

View File

@ -31,7 +31,10 @@ __fesetexceptflag (const fexcept_t *flagp, int excepts)
flag = *flagp & excepts;
/* Replace the exception status */
n.l = ((u.l & ~(FPSCR_STICKY_BITS & excepts))
int excepts_mask = FPSCR_STICKY_BITS & excepts;
if ((excepts & FE_INVALID) != 0)
excepts_mask |= FE_ALL_INVALID;
n.l = ((u.l & ~excepts_mask)
| (flag & FPSCR_STICKY_BITS)
| (flag >> ((31 - FPSCR_VX) - (31 - FPSCR_VXSOFT))
& FE_INVALID_SOFTWARE));