2007-03-22  Jakub Jelinek  <jakub@redhat.com>
	[BZ #3427]
	* sysdeps/x86_64/fpu/feholdexcpt.c (feholdexcept): Clear all
	exceptions both in SW and MXCSR.
	* sysdeps/x86_64/fpu/feupdateenv.c: New file.
	* sysdeps/x86_64/fpu/feenablxcpt.c (feenableexcept): Remove dead code.
	* sysdeps/x86_64/fpu/fedisblxcpt.c (fedisableexcept): Likewise.
	* sysdeps/i386/fpu/feholdexcpt.c (feholdexcept): Clear all exceptions
	in MXCSR if SSE is available.
	* sysdeps/i386/fpu/feupdateenv.c: Include unistd.h, dl-procinfo.h
	and ldsodefs.h.
	(__feupdateenv): Query exceptions also from MXCSR if SSE is available.
	Fix comment typo.
	* sysdeps/ia64/fpu/feholdexcpt.c (feholdexcept): Clear all exceptions.
	Return 0 rather than 1.
	* sysdeps/ia64/fpu/feupdateenv.c (feupdateenv): Fix comment typo.
	Remove incorrect part of a comment.  Fix argument to feraiseexcept.
	* math/test-fenv.c (feholdexcept_tests): New function.
	(main): Call it.

2007-01-05  Richard B. Kreckel  <kreckel@ginac.de>

	[BZ #3427]
	* sysdeps/i386/fpu/feholdexcpt.c (feholdexcept): Clear all exceptions
	in SW.
This commit is contained in:
Ulrich Drepper 2007-04-16 20:15:57 +00:00
parent 3431725412
commit a8c79c4088
9 changed files with 220 additions and 28 deletions

View File

@ -1,3 +1,30 @@
2007-03-22 Jakub Jelinek <jakub@redhat.com>
[BZ #3427]
* sysdeps/x86_64/fpu/feholdexcpt.c (feholdexcept): Clear all
exceptions both in SW and MXCSR.
* sysdeps/x86_64/fpu/feupdateenv.c: New file.
* sysdeps/x86_64/fpu/feenablxcpt.c (feenableexcept): Remove dead code.
* sysdeps/x86_64/fpu/fedisblxcpt.c (fedisableexcept): Likewise.
* sysdeps/i386/fpu/feholdexcpt.c (feholdexcept): Clear all exceptions
in MXCSR if SSE is available.
* sysdeps/i386/fpu/feupdateenv.c: Include unistd.h, dl-procinfo.h
and ldsodefs.h.
(__feupdateenv): Query exceptions also from MXCSR if SSE is available.
Fix comment typo.
* sysdeps/ia64/fpu/feholdexcpt.c (feholdexcept): Clear all exceptions.
Return 0 rather than 1.
* sysdeps/ia64/fpu/feupdateenv.c (feupdateenv): Fix comment typo.
Remove incorrect part of a comment. Fix argument to feraiseexcept.
* math/test-fenv.c (feholdexcept_tests): New function.
(main): Call it.
2007-01-05 Richard B. Kreckel <kreckel@ginac.de>
[BZ #3427]
* sysdeps/i386/fpu/feholdexcpt.c (feholdexcept): Clear all exceptions
in SW.
2007-04-13 Jakub Jelinek <jakub@redhat.com>
[BZ #4344]

View File

@ -1,4 +1,5 @@
/* Copyright (C) 1997, 1998, 2000, 2001, 2003 Free Software Foundation, Inc.
/* Copyright (C) 1997, 1998, 2000, 2001, 2003, 2007
Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Andreas Jaeger <aj@suse.de> and
Ulrich Drepper <drepper@cygnus.com>, 1997.
@ -636,6 +637,102 @@ feenv_tests (void)
}
static void
feholdexcept_tests (void)
{
fenv_t saved, saved2;
int res;
feclearexcept (FE_ALL_EXCEPT);
fedisableexcept (FE_ALL_EXCEPT);
#ifdef FE_DIVBYZERO
feraiseexcept (FE_DIVBYZERO);
#endif
test_exceptions ("feholdexcept_tests FE_DIVBYZERO test",
DIVBYZERO_EXC, 0);
res = feholdexcept (&saved);
if (res != 0)
{
printf ("feholdexcept failed: %d\n", res);
++count_errors;
}
#if defined FE_TONEAREST && defined FE_TOWARDZERO
res = fesetround (FE_TOWARDZERO);
if (res != 0)
{
printf ("fesetround failed: %d\n", res);
++count_errors;
}
#endif
test_exceptions ("feholdexcept_tests 0 test", NO_EXC, 0);
feraiseexcept (FE_INVALID);
test_exceptions ("feholdexcept_tests FE_INVALID test",
INVALID_EXC, 0);
res = feupdateenv (&saved);
if (res != 0)
{
printf ("feupdateenv failed: %d\n", res);
++count_errors;
}
#if defined FE_TONEAREST && defined FE_TOWARDZERO
res = fegetround ();
if (res != FE_TONEAREST)
{
printf ("feupdateenv didn't restore rounding mode: %d\n", res);
++count_errors;
}
#endif
test_exceptions ("feholdexcept_tests FE_DIVBYZERO|FE_INVALID test",
DIVBYZERO_EXC | INVALID_EXC, 0);
feclearexcept (FE_ALL_EXCEPT);
feraiseexcept (FE_INVALID);
#if defined FE_TONEAREST && defined FE_UPWARD
res = fesetround (FE_UPWARD);
if (res != 0)
{
printf ("fesetround failed: %d\n", res);
++count_errors;
}
#endif
res = feholdexcept (&saved2);
if (res != 0)
{
printf ("feholdexcept failed: %d\n", res);
++count_errors;
}
#if defined FE_TONEAREST && defined FE_UPWARD
res = fesetround (FE_TONEAREST);
if (res != 0)
{
printf ("fesetround failed: %d\n", res);
++count_errors;
}
#endif
test_exceptions ("feholdexcept_tests 0 2nd test", NO_EXC, 0);
feraiseexcept (FE_INEXACT);
test_exceptions ("feholdexcept_tests FE_INEXACT test",
INEXACT_EXC, 0);
res = feupdateenv (&saved2);
if (res != 0)
{
printf ("feupdateenv failed: %d\n", res);
++count_errors;
}
#if defined FE_TONEAREST && defined FE_UPWARD
res = fegetround ();
if (res != FE_UPWARD)
{
printf ("feupdateenv didn't restore rounding mode: %d\n", res);
++count_errors;
}
fesetround (FE_TONEAREST);
#endif
test_exceptions ("feholdexcept_tests FE_INEXACT|FE_INVALID test",
INVALID_EXC | INEXACT_EXC, 0);
feclearexcept (FE_ALL_EXCEPT);
}
/* IEC 559 and ISO C99 define a default startup environment */
static void
initial_tests (void)
@ -654,6 +751,7 @@ main (void)
initial_tests ();
fe_tests ();
feenv_tests ();
feholdexcept_tests ();
if (count_errors)
{

View File

@ -1,5 +1,5 @@
/* Install given floating-point environment and raise exceptions.
Copyright (C) 1997,99,2000,01 Free Software Foundation, Inc.
Copyright (C) 1997,99,2000,01,07 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@ -20,20 +20,29 @@
#include <fenv.h>
#include <bp-sym.h>
#include <unistd.h>
#include <dl-procinfo.h>
#include <ldsodefs.h>
int
__feupdateenv (const fenv_t *envp)
{
fexcept_t temp;
unsigned int xtemp = 0;
/* Save current exceptions. */
__asm__ ("fnstsw %0" : "=m" (*&temp));
temp &= FE_ALL_EXCEPT;
/* If the CPU supports SSE we test the MXCSR as well. */
if ((GLRO(dl_hwcap) & HWCAP_I386_XMM) != 0)
__asm__ ("stmxcsr %0" : "=m" (*&xtemp));
temp = (temp | xtemp) & FE_ALL_EXCEPT;
/* Install new environment. */
fesetenv (envp);
/* Raise the safed exception. Incidently for us the implementation
/* Raise the saved exception. Incidently for us the implementation
defined format of the values in objects of type fexcept_t is the
same as the ones specified using the FE_* constants. */
feraiseexcept ((int) temp);

View File

@ -1,5 +1,5 @@
/* Store current floating-point environment and clear exceptions.
Copyright (C) 1997, 1999, 2000, 2005 Free Software Foundation, Inc.
Copyright (C) 1997, 1999, 2000, 2005, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Christian Boissat <Christian.Boissat@cern.ch>, 1999
@ -23,12 +23,20 @@
int
feholdexcept (fenv_t *envp)
{
fenv_t fpsr;
/* Save the current state. */
fegetenv (envp);
__asm__ __volatile__ ("mov.m %0=ar.fpsr" : "=r" (fpsr));
*envp = fpsr;
/* set the trap disable bit */
__asm__ __volatile__ ("mov.m ar.fpsr=%0" :: "r" (*envp | FE_ALL_EXCEPT));
/* Set the trap disable bits. */
fpsr |= FE_ALL_EXCEPT;
return 1;
/* And clear the exception bits. */
fpsr &= ~(fenv_t) (FE_ALL_EXCEPT << 13);
__asm__ __volatile__ ("mov.m ar.fpsr=%0" :: "r" (fpsr));
/* Success. */
return 0;
}
libm_hidden_def (feholdexcept)

View File

@ -1,5 +1,5 @@
/* Install given floating-point environment and raise exceptions.
Copyright (C) 1997, 2000 Free Software Foundation, Inc.
Copyright (C) 1997, 2000, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Christian Boissat <Christian.Boissat@cern.ch>, 1999.
@ -32,10 +32,8 @@ feupdateenv (const fenv_t *envp)
/* Install new environment. */
fesetenv (envp);
/* Raise the safed exception. Incidently for us the implementation
defined format of the values in objects of type fexcept_t is the
same as the ones specified using the FE_* constants. */
feraiseexcept ((int) fpsr & FE_ALL_EXCEPT);
/* Raise the saved exceptions. */
feraiseexcept ((int) (fpsr >> 13) & FE_ALL_EXCEPT);
/* Success. */
return 0;

View File

@ -1,5 +1,5 @@
/* Disable floating-point exceptions.
Copyright (C) 2001 Free Software Foundation, Inc.
Copyright (C) 2001, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Andreas Jaeger <aj@suse.de>, 2001.
@ -24,7 +24,7 @@ int
fedisableexcept (int excepts)
{
unsigned short int new_exc, old_exc;
unsigned int new, old;
unsigned int new;
excepts &= FE_ALL_EXCEPT;
@ -40,8 +40,6 @@ fedisableexcept (int excepts)
__asm__ ("stmxcsr %0" : "=m" (*&new));
/* The SSE exception masks are shifted by 7 bits. */
old = (~new) & (FE_ALL_EXCEPT << 7);
new |= excepts << 7;
__asm__ ("ldmxcsr %0" : : "m" (*&new));

View File

@ -1,5 +1,5 @@
/* Enable floating-point exceptions.
Copyright (C) 2001 Free Software Foundation, Inc.
Copyright (C) 2001, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Andreas Jaeger <aj@suse.de>, 2001.
@ -24,7 +24,7 @@ int
feenableexcept (int excepts)
{
unsigned short int new_exc, old_exc;
unsigned int new, old;
unsigned int new;
excepts &= FE_ALL_EXCEPT;
@ -40,8 +40,6 @@ feenableexcept (int excepts)
__asm__ ("stmxcsr %0" : "=m" (*&new));
/* The SSE exception masks are shifted by 7 bits. */
old = (~new) & (FE_ALL_EXCEPT << 7);
new &= ~(excepts << 7);
__asm__ ("ldmxcsr %0" : : "m" (*&new));

View File

@ -1,5 +1,5 @@
/* Store current floating-point environment and clear exceptions.
Copyright (C) 2001, 2005 Free Software Foundation, Inc.
Copyright (C) 2001, 2005, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@ -22,19 +22,24 @@
int
feholdexcept (fenv_t *envp)
{
unsigned short int work;
unsigned int mxcsr;
fenv_t temp;
/* Store the environment. */
__asm__ ("fnstenv %0\n"
"stmxcsr %1" : "=m" (*envp), "=m" (envp->__mxcsr));
"stmxcsr %1" : "=m" (temp), "=m" (temp.__mxcsr));
*envp = temp;
/* Now set all exceptions to non-stop, first the x87 FPU. */
work = envp->__control_word | 0x3f;
__asm__ ("fldcw %0" : : "m" (*&work));
temp.__control_word |= 0x3f;
/* And clear all exceptions. */
temp.__status_word &= ~0x3f;
__asm__ ("fldenv %0" : : "m" (temp));
/* Set the SSE MXCSR register. */
mxcsr = envp->__mxcsr | 0x1f80;
mxcsr = (envp->__mxcsr | 0x1f80) & ~0x3f;
__asm__ ("ldmxcsr %0" : : "m" (*&mxcsr));
return 0;

View File

@ -0,0 +1,51 @@
/* Install given floating-point environment and raise exceptions.
Copyright (C) 1997,99,2000,01,07 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <fenv.h>
int
__feupdateenv (const fenv_t *envp)
{
fexcept_t temp;
unsigned int xtemp;
/* Save current exceptions. */
__asm__ ("fnstsw %0\n\tstmxcsr %1" : "=m" (*&temp), "=m" (xtemp));
temp = (temp | xtemp) & FE_ALL_EXCEPT;
/* Install new environment. */
fesetenv (envp);
/* Raise the saved exception. Incidently for us the implementation
defined format of the values in objects of type fexcept_t is the
same as the ones specified using the FE_* constants. */
feraiseexcept ((int) temp);
/* Success. */
return 0;
}
#include <shlib-compat.h>
#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2)
strong_alias (__feupdateenv, __old_feupdateenv)
compat_symbol (libm, __old_feupdateenv, feupdateenv, GLIBC_2_1);
#endif
versioned_symbol (libm, __feupdateenv, feupdateenv, GLIBC_2_2);