From 9ea502f95ca8fb4e744e354030292d1c3f34a485 Mon Sep 17 00:00:00 2001 From: Andreas Jaeger Date: Sun, 17 Mar 2002 12:07:44 +0000 Subject: * sysdeps/mips/fpu/fraiseexcpt.c (__feraiseexcept): Set cause bits. * sysdeps/mips/fpu/fgetexcptflg.c (__fegetexceptflag): Add comment. * sysdeps/mips/fpu/fclrexcpt.c (__feclearexcept): Clear also cause bits. * sysdeps/mips/fpu/fenv_libc.h (CAUSE_MASK): New. (CAUSE_SHIFT): New. --- sysdeps/mips/fpu/fclrexcpt.c | 11 ++++++++--- sysdeps/mips/fpu/fenv_libc.h | 13 ++++++++----- sysdeps/mips/fpu/fgetexcptflg.c | 6 +++++- sysdeps/mips/fpu/fraiseexcpt.c | 12 +++++++++--- 4 files changed, 30 insertions(+), 12 deletions(-) (limited to 'sysdeps/mips') 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 , 1998. @@ -19,6 +19,7 @@ 02111-1307 USA. */ #include +#include #include #include @@ -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 . @@ -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 , 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 , 2000. @@ -19,6 +19,7 @@ 02111-1307 USA. */ #include +#include #include #include @@ -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); -- cgit v1.2.3