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]

[libgfortran] FPE support for ppc-darwin


Attached patch should add support for -ffpe-trap={zero,denormal,precision,underflow,overflow} on ppc-darwin. Unfortunately, I don't have access to such computer any more, so I'm looking for someone to test this patch. Once compiled, you can test it with, eg:

$ cat a.f
      real*8 x
      x = -1
      print *, sqrt(x)
      end
$ gfortran a.f && ./a.out
                     NaN
$ gfortran a.f -ffpe-trap=invalid && ./a.out
Floating point exception


Thanks! FX
Index: configure.host
===================================================================
--- configure.host	(revision 112610)
+++ configure.host	(working copy)
@@ -24,6 +24,8 @@
 case "${host_cpu}" in
   i?86 | x86_64)
     fpu_host='fpu-387' ;;
+  powerpc*-*-darwin*)
+    fpu_host='fpu-ppc-darwin' ;;
 esac
 
 # CONFIGURATION-SPECIFIC OVERRIDES
Index: config/fpu-ppc-darwin.h
===================================================================
--- config/fpu-ppc-darwin.h	(revision 0)
+++ config/fpu-ppc-darwin.h	(revision 0)
@@ -0,0 +1,86 @@
+/* FPU-related code for Darwin on PowerPC
+   Copyright 2006 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.  */
+
+#include <fenv.h>
+#include <signal.h>
+#include <ucontext.h>
+#include <mach/thread_status.h>
+#include <stdlib.h>
+
+#include "io/io.h"
+
+/* From http://developer.apple.com/documentation/Performance/Conceptual/Mac_OSX_Numerics/Mac_OSX_Numerics.pdf , page 7-15. */
+
+#define fegetenvd(x) asm volatile("mffs %0" : "=f" (x));
+#define fesetenvd(x) asm volatile("mtfsf 255,%0" : : "f" (x));
+
+enum {
+  FE_ENABLE_INEXACT    = 0x00000008,
+  FE_ENABLE_DIVBYZERO  = 0x00000010,
+  FE_ENABLE_UNDERFLOW  = 0x00000020,
+  FE_ENABLE_OVERFLOW   = 0x00000040,
+  FE_ENABLE_INVALID    = 0x00000080,
+  FE_ENABLE_ALL_EXCEPT = 0x000000F8
+};
+
+typedef union {
+  struct {
+    unsigned long hi;
+    unsigned long lo;
+  } i;
+  double d;
+} hexdouble;
+
+static void sighandler (int signum)
+{
+  signal (signum, SIG_DFL);
+  runtime_error ("Floating Point Exception");
+}
+
+void set_fpu (void)
+{
+  hexdouble t;
+
+  fegetenvd(t.d);
+  if (options.fpe & GFC_FPE_DENORMAL)
+    st_printf ("Fortran runtime warning: IEEE 'denormal number' "
+	       "exception not supported.\n");
+  if (options.fpe & GFC_FPE_PRECISION)
+    t.i.lo |= FE_ENABLE_INEXACT;
+  if (options.fpe & GFC_FPE_ZERO)
+    t.i.lo |= FE_ENABLE_DIVBYZERO;
+  if (options.fpe & GFC_FPE_UNDERFLOW)
+    t.i.lo |= FE_ENABLE_UNDERFLOW;
+  if (options.fpe & GFC_FPE_OVERFLOW)
+    t.i.lo |= FE_ENABLE_OVERFLOW;
+  if (options.fpe & GFC_FPE_INVALID)
+    t.i.lo |= FE_ENABLE_INVALID;
+  fesetenvd(t.d);
+}

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