diff options
-rw-r--r-- | sysdeps/mips/fpu/fclrexcpt.c | 11 | ||||
-rw-r--r-- | sysdeps/mips/fpu/fenv_libc.h | 13 | ||||
-rw-r--r-- | sysdeps/mips/fpu/fgetexcptflg.c | 6 | ||||
-rw-r--r-- | sysdeps/mips/fpu/fraiseexcpt.c | 12 |
4 files changed, 30 insertions, 12 deletions
diff --git a/sysdeps/mips/fpu/fclrexcpt.c b/sysdeps/mips/fpu/fclrexcpt.c index 9fb2d7e803..2c35047a8c 100644 --- a/sysdeps/mips/fpu/fclrexcpt.c +++ b/sysdeps/mips/fpu/fclrexcpt.c @@ -1,5 +1,5 @@ /* Clear given exceptions in current floating-point environment. - Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2000, 2002 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Andreas Jaeger <aj@suse.de>, 1998. @@ -19,6 +19,7 @@ 02111-1307 USA. */ #include <fenv.h> +#include <fenv_libc.h> #include <fpu_control.h> #include <shlib-compat.h> @@ -33,8 +34,11 @@ __feclearexcept (int excepts) /* Read the complete control word. */ _FPU_GETCW (cw); - /* Clear exception bits. */ - cw &= ~excepts; + /* Clear exception flag bits and cause bits. If the cause bit is not + cleared, the next CTC instruction (just below) will re-generate + the exception. */ + + cw &= ~(excepts | (excepts << CAUSE_SHIFT)); /* Put the new data in effect. */ _FPU_SETCW (cw); @@ -42,6 +46,7 @@ __feclearexcept (int excepts) /* Success. */ return 0; } + #if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2) strong_alias (__feclearexcept, __old_feclearexcept) compat_symbol (libm, __old_feclearexcept, feclearexcept, GLIBC_2_1); diff --git a/sysdeps/mips/fpu/fenv_libc.h b/sysdeps/mips/fpu/fenv_libc.h index dc30888ada..d971d2c711 100644 --- a/sysdeps/mips/fpu/fenv_libc.h +++ b/sysdeps/mips/fpu/fenv_libc.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 Free Software Foundation, Inc. +/* Copyright (C) 2000, 2002 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Andreas Jaeger <aj@suse.de>. @@ -20,10 +20,13 @@ #ifndef _FENV_LIBC_H #define _FENV_LIBC_H 1 -/* Mask for enabling exceptions. */ -#define ENABLE_MASK 0xF80U +/* Mask for enabling exceptions and for the CAUSE bits. */ +#define ENABLE_MASK 0x00F80U +#define CAUSE_MASK 0x1F000U + +/* Shift for FE_* flags to get up to the ENABLE bits and the CAUSE bits. */ +#define ENABLE_SHIFT 5 +#define CAUSE_SHIFT 10 -/* Shift for FE_* flags. */ -#define ENABLE_SHIFT 5 #endif /* _FENV_LIBC_H */ diff --git a/sysdeps/mips/fpu/fgetexcptflg.c b/sysdeps/mips/fpu/fgetexcptflg.c index d4bbfc3a2a..4f802afb40 100644 --- a/sysdeps/mips/fpu/fgetexcptflg.c +++ b/sysdeps/mips/fpu/fgetexcptflg.c @@ -1,5 +1,5 @@ /* Store current representation for exceptions. - Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2000, 2002 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Andreas Jaeger <aj@suse.de>, 1998. @@ -30,6 +30,10 @@ __fegetexceptflag (fexcept_t *flagp, int excepts) /* Get the current exceptions. */ _FPU_GETCW (temp); + /* It is important that the CAUSE bits are not saved here. If they + were, a call to fesetexceptflag() would generate an + exception. */ + *flagp = temp & excepts & FE_ALL_EXCEPT; /* Success. */ diff --git a/sysdeps/mips/fpu/fraiseexcpt.c b/sysdeps/mips/fpu/fraiseexcpt.c index 582210aca3..e2472e35f2 100644 --- a/sysdeps/mips/fpu/fraiseexcpt.c +++ b/sysdeps/mips/fpu/fraiseexcpt.c @@ -1,5 +1,5 @@ /* Raise given exceptions. - Copyright (C) 2000 Free Software Foundation, Inc. + Copyright (C) 2000, 2002 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Andreas Jaeger <aj@suse.de>, 2000. @@ -19,6 +19,7 @@ 02111-1307 USA. */ #include <fenv.h> +#include <fenv_libc.h> #include <fpu_control.h> #include <shlib-compat.h> @@ -30,8 +31,13 @@ __feraiseexcept (int excepts) /* Get current state. */ _FPU_GETCW (cw); - /* Set exceptions bits. */ - cw |= (excepts & FE_ALL_EXCEPT); + /* Set flag bits (which are accumulative), and *also* set the cause + bits. The setting of the cause bits is what actually causes the + hardware to generate the exception, if the corresponding enable + bit is set as well. */ + + excepts &= FE_ALL_EXCEPT; + cw |= excepts | (excepts << CAUSE_SHIFT); /* Set new state. */ _FPU_SETCW (cw); |