Subject: [clisp-list] fenv.h support

From: Will Newton <[email-masked]>
Date: Wed Sep 4 18:26:01 2002

CLISP relies on the fpu_control.h header to set the FPU behaviour on Linux. 
Unfortunately, fpu_control.h is unportable in many ways. The general anwser 
seems to be to use fenv.h, a standard header in C99. This patch will enable 
fenv.h support in preference to fpu_control.h if it is available. I have 
tested it and it *seems* to work. I've tried dividing by zero etc. in the 
interpreter and everything seems to function normally on my i386 Linux 
machine. It would be best if this patch got some testing before being 
considered for inclusion.

Thanks,
--- clisp.old/src/autoconf/aclocal.m4	2002-07-25 22:35:35.000000000 +0100
+++ clisp/src/autoconf/aclocal.m4	2002-09-05 02:10:41.000000000 +0100
@@ -1879,6 +1879,14 @@
 AC_DEFINE(HAVE_SIGALTSTACK))dnl
 ])dnl
 dnl
+AC_DEFUN(CL_FENV,
+dnl Check for fenv.h and add math library to LIBS
+[AC_CHECK_HEADERS(fenv.h)dnl
+if test "$ac_cv_header_fenv_h" = yes; then
+LIBS="$LIBS -lm"
+fi
+])dnl
+dnl
 AC_DEFUN(CL_FPU_CONTROL,
 [dnl Check for Linux with <fpu_control.h> and fpu_control_t or __setfpucw().
 dnl glibc versions since October 1998 define fpu_control_t. Earlier versions
@@ -4525,4 +4533,4 @@
   *big*)    ;;
 esac
 ])dnl
-dnl
+dnl 
--- clisp.old/src/unixconf.h.in	2002-07-25 22:35:35.000000000 +0100
+++ clisp/src/unixconf.h.in	2002-09-05 01:23:57.000000000 +0100
@@ -223,6 +223,10 @@
    function. */
 #undef HAVE_SETFPUCW
 
+/* fenv.h */
+/* Define if you have C99 floating point */
+#undef HAVE_FENV_H
+
 /* CL_RAISE */
 /* Define if you have the raise() function. */
 #undef HAVE_RAISE
--- clisp.old/src/configure.in	2002-07-25 22:35:31.000000000 +0100
+++ clisp/src/configure.in	2002-09-05 01:44:40.000000000 +0100
@@ -160,6 +160,8 @@
                       dnl DEFS SIGACTION_NEED_UNBLOCK
 CL_SIGINTERRUPT
                       dnl DEFS HAVE_SIGINTERRUPT, HAVE_SIGVEC
+CL_FENV
+                      dnl Check for C99 FPU control headers
 CL_FPU_CONTROL
                       dnl DEFS HAVE_FPU_CONTROL_T, HAVE_SETFPUCW
 CL_RAISE
--- clisp.old/src/spvw.d	2002-07-24 19:03:59.000000000 +0100
+++ clisp/src/spvw.d	2002-09-05 01:32:45.000000000 +0100
@@ -23,7 +23,9 @@
 
 #include "version.h"
 
-#if defined(UNIX_LINUX) && (defined(FAST_FLOAT) || defined(FAST_DOUBLE)) && defined(HAVE_SETFPUCW)
+#if defined(HAVE_FENV_H)
+  #include <fenv.h>
+#elif defined(UNIX_LINUX) && (defined(FAST_FLOAT) || defined(FAST_DOUBLE)) && defined(HAVE_SETFPUCW)
   #include <fpu_control.h>
 #endif
 
@@ -1704,7 +1706,14 @@
           end_system_call();
         }
       #endif
-      #if defined(UNIX_LINUX) && (defined(FAST_FLOAT) || defined(FAST_DOUBLE)) && !defined(HAVE_FPU_CONTROL_T) && defined(HAVE_SETFPUCW)
+      #if defined(UNIX_LINUX) && defined(HAVE_FENV_H)
+      # Disable SIGFPE
+      # signal(SIGFPE, SIG_IGN);
+      fenv_t holdenv;
+      feholdexcept(&holdenv);
+      # Round to nearest
+      fesetround(FE_TONEAREST);
+      #elif defined(UNIX_LINUX) && (defined(FAST_FLOAT) || defined(FAST_DOUBLE)) && !defined(HAVE_FPU_CONTROL_T) && defined(HAVE_SETFPUCW)
       # Damit Division durch 0.0 ein NaN und kein SIGFPE liefert.
       __setfpucw(_FPU_IEEE);
       #endif
--- clisp.old/src/unixaux.d	2002-07-25 22:35:35.000000000 +0100
+++ clisp/src/unixaux.d	2002-09-05 01:18:35.000000000 +0100
@@ -471,7 +471,7 @@
 
 # =============================================================================
 
-#if defined(UNIX_LINUX) && (defined(FAST_FLOAT) || defined(FAST_DOUBLE)) && (defined(HAVE_FPU_CONTROL_T) || !defined(HAVE_SETFPUCW))
+#if !defined(HAVE_FENV_H) && defined(UNIX_LINUX) && (defined(FAST_FLOAT) || defined(FAST_DOUBLE)) && (defined(HAVE_FPU_CONTROL_T) || !defined(HAVE_SETFPUCW))
 
 # Damit Division durch 0.0 ein NaN und kein SIGFPE liefert:
 # Entweder mit -lieee linken,

---

From: Bruno Haible <[email-masked]>
Date: Thu Sep 5 09:01:02 2002

> >     But the functions declared in it don't work on
> >     all platforms (in particular they don't work on i686).
> >     The glibc maintainers don't want to fix it; they say these
> >     are hardware limitations.
> 
> That sounds quite unlikely - I'm certainly sure i686 can implement enough 
> different modes for clisp. Do you have any link to any discussion of this?

Here are the links:
http://sources.redhat.com/ml/libc-alpha/2002-05/msg00241.html
http://sources.redhat.com/ml/libc-alpha/2002-06/msg00154.html

Bruno