diff options
author | Ulrich Drepper <drepper@redhat.com> | 2007-04-16 20:13:01 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2007-04-16 20:13:01 +0000 |
commit | 34317254127a027848079aabdd17efa1deb9279f (patch) | |
tree | 9d03227f7ee7c7b9b5a14c0f16b9aabfd657ce81 /sysdeps/i386/fpu | |
parent | 30a3aa753041e9506b6183dc1ad06257f7693192 (diff) | |
download | glibc-34317254127a027848079aabdd17efa1deb9279f.tar.gz glibc-34317254127a027848079aabdd17efa1deb9279f.tar.xz glibc-34317254127a027848079aabdd17efa1deb9279f.zip |
(feholdexcept): Clear all exceptions in SW.
Diffstat (limited to 'sysdeps/i386/fpu')
-rw-r--r-- | sysdeps/i386/fpu/feholdexcpt.c | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/sysdeps/i386/fpu/feholdexcpt.c b/sysdeps/i386/fpu/feholdexcpt.c index feaa24b8d9..e9fdfcae87 100644 --- a/sysdeps/i386/fpu/feholdexcpt.c +++ b/sysdeps/i386/fpu/feholdexcpt.c @@ -1,5 +1,6 @@ /* Store current floating-point environment and clear exceptions. - Copyright (C) 1997, 1999, 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 1997, 1999, 2003, 2004, 2005, 2007 + Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. @@ -26,14 +27,19 @@ int feholdexcept (fenv_t *envp) { - unsigned short int work; + fenv_t temp; /* Store the environment. */ - __asm__ ("fnstenv %0" : "=m" (*envp)); + __asm__ ("fnstenv %0" : "=m" (temp)); + *envp = temp; /* Now set all exceptions to non-stop. */ - 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)); /* If the CPU supports SSE we set the MXCSR as well. */ if ((GLRO(dl_hwcap) & HWCAP_I386_XMM) != 0) @@ -43,8 +49,8 @@ feholdexcept (fenv_t *envp) /* Get the current control word. */ __asm__ ("stmxcsr %0" : "=m" (*&xwork)); - /* Set all exceptions to non-stop. */ - xwork |= 0x1f80; + /* Set all exceptions to non-stop and clear them. */ + xwork = (xwork | 0x1f80) & ~0x3f; __asm__ ("ldmxcsr %0" : : "m" (*&xwork)); } |