mirror of
git://sourceware.org/git/glibc.git
synced 2025-01-18 12:16:13 +08:00
[BZ #3427]
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:
parent
3431725412
commit
a8c79c4088
27
ChangeLog
27
ChangeLog
@ -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]
|
||||
|
100
math/test-fenv.c
100
math/test-fenv.c
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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;
|
||||
|
51
sysdeps/x86_64/fpu/feupdateenv.c
Normal file
51
sysdeps/x86_64/fpu/feupdateenv.c
Normal 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);
|
Loading…
Reference in New Issue
Block a user