1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-30 22:43:12 +03:00
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> 2007-04-13 Jakub Jelinek <jakub@redhat.com>
[BZ #4344] [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. This file is part of the GNU C Library.
Contributed by Andreas Jaeger <aj@suse.de> and Contributed by Andreas Jaeger <aj@suse.de> and
Ulrich Drepper <drepper@cygnus.com>, 1997. 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 */ /* IEC 559 and ISO C99 define a default startup environment */
static void static void
initial_tests (void) initial_tests (void)
@ -654,6 +751,7 @@ main (void)
initial_tests (); initial_tests ();
fe_tests (); fe_tests ();
feenv_tests (); feenv_tests ();
feholdexcept_tests ();
if (count_errors) if (count_errors)
{ {

View File

@ -1,5 +1,5 @@
/* Install given floating-point environment and raise exceptions. /* 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. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@ -20,20 +20,29 @@
#include <fenv.h> #include <fenv.h>
#include <bp-sym.h> #include <bp-sym.h>
#include <unistd.h>
#include <dl-procinfo.h>
#include <ldsodefs.h>
int int
__feupdateenv (const fenv_t *envp) __feupdateenv (const fenv_t *envp)
{ {
fexcept_t temp; fexcept_t temp;
unsigned int xtemp = 0;
/* Save current exceptions. */ /* Save current exceptions. */
__asm__ ("fnstsw %0" : "=m" (*&temp)); __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. */ /* Install new environment. */
fesetenv (envp); 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 defined format of the values in objects of type fexcept_t is the
same as the ones specified using the FE_* constants. */ same as the ones specified using the FE_* constants. */
feraiseexcept ((int) temp); feraiseexcept ((int) temp);

View File

@ -1,5 +1,5 @@
/* Store current floating-point environment and clear exceptions. /* 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. This file is part of the GNU C Library.
Contributed by Christian Boissat <Christian.Boissat@cern.ch>, 1999 Contributed by Christian Boissat <Christian.Boissat@cern.ch>, 1999
@ -23,12 +23,20 @@
int int
feholdexcept (fenv_t *envp) feholdexcept (fenv_t *envp)
{ {
fenv_t fpsr;
/* Save the current state. */ /* Save the current state. */
fegetenv (envp); __asm__ __volatile__ ("mov.m %0=ar.fpsr" : "=r" (fpsr));
*envp = fpsr;
/* set the trap disable bit */ /* Set the trap disable bits. */
__asm__ __volatile__ ("mov.m ar.fpsr=%0" :: "r" (*envp | FE_ALL_EXCEPT)); 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) libm_hidden_def (feholdexcept)

View File

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

View File

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

View File

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

View File

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