This is the mail archive of the fortran@gcc.gnu.org mailing list for the GNU Fortran project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [gfortran,patch] FPE options, once again


> 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
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]