This is the mail archive of the
fortran@gcc.gnu.org
mailing list for the GNU Fortran project.
Re: [gfortran,patch] FPE options, once again
- From: François-Xavier Coudert <fxcoudert at gmail dot com>
- To: FX Coudert <fxcoudert at gmail dot com>, GNU GFortran <fortran at gcc dot gnu dot org>
- Date: Fri, 7 Oct 2005 10:21:06 +0200
- Subject: Re: [gfortran,patch] FPE options, once again
- Domainkey-signature: a=rsa-sha1; q=dns; c=nofws; s=beta; d=gmail.com; h=received:message-id:date:from:reply-to:to:subject:in-reply-to:mime-version:content-type:references; b=IFdPZe6ELzQY51pSugm/P8CJ4Hr1gD05lXXDD4wgbq5fj6CpmzBp03+8yy+2MV5UWTqwujlr5HFNsE4vbn/nsLePc6JnYXIMzGLIWrxNb1y4pQqJm6B4uNNKkidD57J9evIENOabXRXzPGTwTlhZ4qRgbTGM5hNy3L4WAwYOOxs=
- References: <431768A9.9050409@gmail.com> <200509081750.12480.paul@codesourcery.com> <43384FEB.9050606@gmail.com> <43419D3A.8070904@gmail.com> <20051006223049.GE3918@vipunen.hut.fi>
- Reply-to: François-Xavier Coudert <fxcoudert at gmail dot com>
> The libgfortran/config/* files are missing from the patch.
I'm sorry, my home computer is down so I can't repost the whole patch
now, but they haven't changed from the previous patch. The main patch
is at http://gcc.gnu.org/ml/gcc-patches/2005-09/msg01642.html, with
additional config/* files as attached.
FX
Index: libgfortran/config/fpu-387.h
===================================================================
RCS file: libgfortran/config/fpu-387.h
diff -N libgfortran/config/fpu-387.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ libgfortran/config/fpu-387.h 1 Sep 2005 20:34:54 -0000
@@ -0,0 +1,103 @@
+/* FPU-related code for x86 and x86_64 processors.
+ Copyright 2005 Free Software Foundation, Inc.
+ Contributed by Francois-Xavier Coudert <coudert@clipper.ens.fr>
+
+This file is part of the GNU Fortran 95 runtime library (libgfortran).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+Libgfortran 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with libgfortran; see the file COPYING. If not,
+write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
+
+
+static int
+has_sse (void)
+{
+#ifdef __x86_64__
+ return 1;
+#else
+ unsigned int eax, ebx, ecx, edx;
+
+ /* See if we can use cpuid. */
+ asm volatile ("pushfl; pushfl; popl %0; movl %0,%1; xorl %2,%0;"
+ "pushl %0; popfl; pushfl; popl %0; popfl"
+ : "=&r" (eax), "=&r" (ebx)
+ : "i" (0x00200000));
+
+ if (((eax ^ ebx) & 0x00200000) == 0)
+ return 0;
+
+ /* Check the highest input value for eax. */
+ asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1"
+ : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx)
+ : "0" (0));
+
+ if (eax == 0)
+ return 0;
+
+ asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1"
+ : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx)
+ : "0" (1));
+
+ if (edx & (1 << 25))
+ return 1;
+
+ return 0;
+#endif
+}
+
+void set_fpu (void)
+{
+ short cw;
+ int cw_sse;
+
+ /* i387 -- see linux <fpu_control.h> header file for details. */
+#define _FPU_MASK_IM 0x01
+#define _FPU_MASK_DM 0x02
+#define _FPU_MASK_ZM 0x04
+#define _FPU_MASK_OM 0x08
+#define _FPU_MASK_UM 0x10
+#define _FPU_MASK_PM 0x20
+ asm volatile ("fnstcw %0" : "=m" (cw));
+ cw |= _FPU_MASK_IM | _FPU_MASK_DM | _FPU_MASK_ZM | _FPU_MASK_OM | _FPU_MASK_UM | _FPU_MASK_PM;
+ if (options.fpu_invalid == 1) cw &= ~_FPU_MASK_IM;
+ if (options.fpu_denormal == 1) cw &= ~_FPU_MASK_DM;
+ if (options.fpu_zerodiv == 1) cw &= ~_FPU_MASK_ZM;
+ if (options.fpu_overflow == 1) cw &= ~_FPU_MASK_OM;
+ if (options.fpu_underflow == 1) cw &= ~_FPU_MASK_UM;
+ if (options.fpu_precision_loss == 1) cw &= ~_FPU_MASK_PM;
+ asm volatile ("fldcw %0" : : "m" (cw));
+
+ if (has_sse())
+ {
+ /* SSE */
+ asm volatile ("stmxcsr %0" : : "m" (cw_sse));
+ cw_sse &= 0xFFFF0000;
+ if (options.fpu_invalid != 1) cw_sse |= 1 << 7;
+ if (options.fpu_denormal != 1) cw_sse |= 1 << 8;
+ if (options.fpu_zerodiv != 1) cw_sse |= 1 << 9;
+ if (options.fpu_overflow != 1) cw_sse |= 1 << 10;
+ if (options.fpu_underflow != 1) cw_sse |= 1 << 11;
+ if (options.fpu_precision_loss != 1) cw_sse |= 1 << 12;
+ asm volatile ("ldmxcsr %0" : : "m" (cw_sse));
+ }
+}
Index: libgfortran/config/fpu-generic.h
===================================================================
RCS file: libgfortran/config/fpu-generic.h
diff -N libgfortran/config/fpu-generic.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ libgfortran/config/fpu-generic.h 1 Sep 2005 20:34:54 -0000
@@ -0,0 +1,57 @@
+/* Fallback FPU-related code (for systems not otherwise supported).
+ Copyright 2005 Free Software Foundation, Inc.
+ Contributed by Francois-Xavier Coudert <coudert@clipper.ens.fr>
+
+This file is part of the GNU Fortran 95 runtime library (libgfortran).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+Libgfortran 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with libgfortran; see the file COPYING. If not,
+write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
+
+
+/* Fallback FPU-related code for systems not otherwise supported. This
+ is mainly telling the user that we will not be able to do what he
+ requested. */
+
+void
+set_fpu (void)
+{
+ if (options.fpu_invalid == 1)
+ st_printf ("Fortran runtime warning: IEEE 'invalid operation' "
+ "exception not supported.\n");
+ if (options.fpu_denormal == 1)
+ st_printf ("Fortran runtime warning: IEEE 'denormal number' "
+ "exception not supported.\n");
+ if (options.fpu_zerodiv == 1)
+ st_printf ("Fortran runtime warning: IEEE 'division by zero' "
+ "exception not supported.\n");
+ if (options.fpu_overflow == 1)
+ st_printf ("Fortran runtime warning: IEEE 'overflow' "
+ "exception not supported.\n");
+ if (options.fpu_underflow == 1)
+ st_printf ("Fortran runtime warning: IEEE 'underflow' "
+ "exception not supported.\n");
+ if (options.fpu_precision_loss == 1)
+ st_printf ("Fortran runtime warning: IEEE 'loss of precision' "
+ "exception not supported.\n");
+}
Index: libgfortran/config/fpu-glibc.h
===================================================================
RCS file: libgfortran/config/fpu-glibc.h
diff -N libgfortran/config/fpu-glibc.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ libgfortran/config/fpu-glibc.h 1 Sep 2005 20:34:54 -0000
@@ -0,0 +1,93 @@
+/* FPU-related code for systems with GNU libc.
+ Copyright 2005 Free Software Foundation, Inc.
+ Contributed by Francois-Xavier Coudert <coudert@clipper.ens.fr>
+
+This file is part of the GNU Fortran 95 runtime library (libgfortran).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+Libgfortran 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with libgfortran; see the file COPYING. If not,
+write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
+
+
+/* FPU-related code for systems with the GNU libc, providing the
+ feenableexcept function in fenv.h to set individual exceptions
+ (there's nothing to do that in C99). */
+
+#define __USE_GNU
+#ifdef HAVE_FENV_H
+#include <fenv.h>
+#endif
+
+void set_fpu (void)
+{
+ fedisableexcept (FE_ALL_EXCEPT);
+
+ if (options.fpu_invalid == 1)
+#ifdef FE_INVALID
+ feenableexcept (FE_INVALID);
+#else
+ st_printf ("Fortran runtime warning: IEEE 'invalid operation' "
+ "exception not supported.\n");
+#endif
+
+/* glibc does never have a FE_DENORMAL. */
+ if (options.fpu_denormal == 1)
+#ifdef FE_DENORMAL
+ feenableexcept (FE_DENORMAL);
+#else
+ st_printf ("Fortran runtime warning: IEEE 'denormal number' "
+ "exception not supported.\n");
+#endif
+
+ if (options.fpu_zerodiv == 1)
+#ifdef FE_DIVBYZERO
+ feenableexcept (FE_DIVBYZERO);
+#else
+ st_printf ("Fortran runtime warning: IEEE 'division by zero' "
+ "exception not supported.\n");
+#endif
+
+ if (options.fpu_overflow == 1)
+#ifdef FE_OVERFLOW
+ feenableexcept (FE_OVERFLOW);
+#else
+ st_printf ("Fortran runtime warning: IEEE 'overflow' "
+ "exception not supported.\n");
+#endif
+
+ if (options.fpu_underflow == 1)
+#ifdef FE_UNDERFLOW
+ feenableexcept (FE_UNDERFLOW);
+#else
+ st_printf ("Fortran runtime warning: IEEE 'underflow' "
+ "exception not supported.\n");
+#endif
+
+ if (options.fpu_precision_loss == 1)
+#ifdef FE_INEXACT
+ feenableexcept (FE_INEXACT);
+#else
+ st_printf ("Fortran runtime warning: IEEE 'loss of precision' "
+ "exception not supported.\n");
+#endif
+}