OSDN Git Service

runtime: Add matherr function when appropriate.
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 8 Feb 2012 22:35:30 +0000 (22:35 +0000)
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 8 Feb 2012 22:35:30 +0000 (22:35 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@184024 138bc75d-0d04-0410-961f-82ee72b054a4

libgo/Makefile.am
libgo/Makefile.in
libgo/config.h.in
libgo/configure
libgo/configure.ac
libgo/runtime/go-matherr.c [new file with mode: 0644]

index b94bc06..bb70b0f 100644 (file)
@@ -422,6 +422,7 @@ runtime_files = \
        runtime/go-map-index.c \
        runtime/go-map-len.c \
        runtime/go-map-range.c \
+       runtime/go-matherr.c \
        runtime/go-nanotime.c \
        runtime/go-now.c \
        runtime/go-new-map.c \
index 556de68..d412e69 100644 (file)
@@ -192,12 +192,13 @@ am__libgo_la_SOURCES_DIST = runtime/go-append.c runtime/go-assert.c \
        runtime/go-interface-val-compare.c runtime/go-make-slice.c \
        runtime/go-map-delete.c runtime/go-map-index.c \
        runtime/go-map-len.c runtime/go-map-range.c \
-       runtime/go-nanotime.c runtime/go-now.c runtime/go-new-map.c \
-       runtime/go-new.c runtime/go-nosys.c runtime/go-panic.c \
-       runtime/go-print.c runtime/go-recover.c runtime/go-reflect.c \
-       runtime/go-reflect-call.c runtime/go-reflect-map.c \
-       runtime/go-rune.c runtime/go-runtime-error.c \
-       runtime/go-setenv.c runtime/go-signal.c runtime/go-strcmp.c \
+       runtime/go-matherr.c runtime/go-nanotime.c runtime/go-now.c \
+       runtime/go-new-map.c runtime/go-new.c runtime/go-nosys.c \
+       runtime/go-panic.c runtime/go-print.c runtime/go-recover.c \
+       runtime/go-reflect.c runtime/go-reflect-call.c \
+       runtime/go-reflect-map.c runtime/go-rune.c \
+       runtime/go-runtime-error.c runtime/go-setenv.c \
+       runtime/go-signal.c runtime/go-strcmp.c \
        runtime/go-string-to-byte-array.c \
        runtime/go-string-to-int-array.c runtime/go-strplus.c \
        runtime/go-strslice.c runtime/go-trampoline.c \
@@ -230,22 +231,23 @@ am__objects_4 = go-append.lo go-assert.lo go-assert-interface.lo \
        go-int-array-to-string.lo go-int-to-string.lo \
        go-interface-compare.lo go-interface-eface-compare.lo \
        go-interface-val-compare.lo go-make-slice.lo go-map-delete.lo \
-       go-map-index.lo go-map-len.lo go-map-range.lo go-nanotime.lo \
-       go-now.lo go-new-map.lo go-new.lo go-nosys.lo go-panic.lo \
-       go-print.lo go-recover.lo go-reflect.lo go-reflect-call.lo \
-       go-reflect-map.lo go-rune.lo go-runtime-error.lo go-setenv.lo \
-       go-signal.lo go-strcmp.lo go-string-to-byte-array.lo \
-       go-string-to-int-array.lo go-strplus.lo go-strslice.lo \
-       go-trampoline.lo go-type-complex.lo go-type-eface.lo \
-       go-type-error.lo go-type-float.lo go-type-identity.lo \
-       go-type-interface.lo go-type-string.lo go-typedesc-equal.lo \
-       go-typestring.lo go-unreflect.lo go-unsafe-new.lo \
-       go-unsafe-newarray.lo go-unsafe-pointer.lo go-unwind.lo \
-       chan.lo cpuprof.lo $(am__objects_1) mcache.lo mcentral.lo \
-       $(am__objects_2) mfinal.lo mfixalloc.lo mgc0.lo mheap.lo \
-       msize.lo proc.lo runtime.lo thread.lo yield.lo \
-       $(am__objects_3) iface.lo malloc.lo map.lo mprof.lo reflect.lo \
-       runtime1.lo sema.lo sigqueue.lo string.lo time.lo
+       go-map-index.lo go-map-len.lo go-map-range.lo go-matherr.lo \
+       go-nanotime.lo go-now.lo go-new-map.lo go-new.lo go-nosys.lo \
+       go-panic.lo go-print.lo go-recover.lo go-reflect.lo \
+       go-reflect-call.lo go-reflect-map.lo go-rune.lo \
+       go-runtime-error.lo go-setenv.lo go-signal.lo go-strcmp.lo \
+       go-string-to-byte-array.lo go-string-to-int-array.lo \
+       go-strplus.lo go-strslice.lo go-trampoline.lo \
+       go-type-complex.lo go-type-eface.lo go-type-error.lo \
+       go-type-float.lo go-type-identity.lo go-type-interface.lo \
+       go-type-string.lo go-typedesc-equal.lo go-typestring.lo \
+       go-unreflect.lo go-unsafe-new.lo go-unsafe-newarray.lo \
+       go-unsafe-pointer.lo go-unwind.lo chan.lo cpuprof.lo \
+       $(am__objects_1) mcache.lo mcentral.lo $(am__objects_2) \
+       mfinal.lo mfixalloc.lo mgc0.lo mheap.lo msize.lo proc.lo \
+       runtime.lo thread.lo yield.lo $(am__objects_3) iface.lo \
+       malloc.lo map.lo mprof.lo reflect.lo runtime1.lo sema.lo \
+       sigqueue.lo string.lo time.lo
 am_libgo_la_OBJECTS = $(am__objects_4)
 libgo_la_OBJECTS = $(am_libgo_la_OBJECTS)
 libgo_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
@@ -839,6 +841,7 @@ runtime_files = \
        runtime/go-map-index.c \
        runtime/go-map-len.c \
        runtime/go-map-range.c \
+       runtime/go-matherr.c \
        runtime/go-nanotime.c \
        runtime/go-now.c \
        runtime/go-new-map.c \
@@ -2391,6 +2394,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-map-index.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-map-len.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-map-range.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-matherr.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-nanotime.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-new-map.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-new.Plo@am__quote@
@@ -2679,6 +2683,13 @@ go-map-range.lo: runtime/go-map-range.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-map-range.lo `test -f 'runtime/go-map-range.c' || echo '$(srcdir)/'`runtime/go-map-range.c
 
+go-matherr.lo: runtime/go-matherr.c
+@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-matherr.lo -MD -MP -MF $(DEPDIR)/go-matherr.Tpo -c -o go-matherr.lo `test -f 'runtime/go-matherr.c' || echo '$(srcdir)/'`runtime/go-matherr.c
+@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/go-matherr.Tpo $(DEPDIR)/go-matherr.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='runtime/go-matherr.c' object='go-matherr.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-matherr.lo `test -f 'runtime/go-matherr.c' || echo '$(srcdir)/'`runtime/go-matherr.c
+
 go-nanotime.lo: runtime/go-nanotime.c
 @am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-nanotime.lo -MD -MP -MF $(DEPDIR)/go-nanotime.Tpo -c -o go-nanotime.lo `test -f 'runtime/go-nanotime.c' || echo '$(srcdir)/'`runtime/go-nanotime.c
 @am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/go-nanotime.Tpo $(DEPDIR)/go-nanotime.Plo
index bd19873..44ae428 100644 (file)
@@ -48,6 +48,9 @@
 /* Define to 1 if the system has the type `loff_t'. */
 #undef HAVE_LOFF_T
 
+/* Define to 1 if you have the `matherr' function. */
+#undef HAVE_MATHERR
+
 /* Define to 1 if you have the <memory.h> header file. */
 #undef HAVE_MEMORY_H
 
 /* Define to 1 if you have the `strsignal' function. */
 #undef HAVE_STRSIGNAL
 
+/* Define to 1 if <math.h> defines struct exception */
+#undef HAVE_STRUCT_EXCEPTION
+
 /* Define to 1 if the compiler provides the __sync_bool_compare_and_swap
    function for uint32 */
 #undef HAVE_SYNC_BOOL_COMPARE_AND_SWAP_4
index 5821d32..a93b051 100755 (executable)
@@ -14623,6 +14623,21 @@ done
 CFLAGS="$CFLAGS_hold"
 LIBS="$LIBS_hold"
 
+LIBS_hold="$LIBS"
+LIBS="$LIBS $MATH_LIBS"
+for ac_func in matherr
+do :
+  ac_fn_c_check_func "$LINENO" "matherr" "ac_cv_func_matherr"
+if test "x$ac_cv_func_matherr" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_MATHERR 1
+_ACEOF
+
+fi
+done
+
+LIBS="$LIBS_hold"
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __sync_bool_compare_and_swap_4" >&5
 $as_echo_n "checking for __sync_bool_compare_and_swap_4... " >&6; }
 if test "${libgo_cv_func___sync_bool_compare_and_swap_4+set}" = set; then :
@@ -14784,6 +14799,20 @@ $as_echo "$libgo_cv_c_epoll_event_fd_offset" >&6; }
 STRUCT_EPOLL_EVENT_FD_OFFSET=${libgo_cv_c_epoll_event_fd_offset}
 
 
+ac_fn_c_check_type "$LINENO" "struct exception" "ac_cv_type_struct_exception" "#include <math.h>
+"
+if test "x$ac_cv_type_struct_exception" = x""yes; then :
+  libgo_has_struct_exception=yes
+else
+  libgo_has_struct_exception=no
+fi
+
+if test "$libgo_has_struct_exception" = "yes"; then
+
+$as_echo "#define HAVE_STRUCT_EXCEPTION 1" >>confdefs.h
+
+fi
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether setcontext clobbers TLS variables" >&5
 $as_echo_n "checking whether setcontext clobbers TLS variables... " >&6; }
 if test "${libgo_cv_lib_setcontext_clobbers_tls+set}" = set; then :
index 155a412..6778903 100644 (file)
@@ -478,6 +478,11 @@ AC_CHECK_FUNCS(sem_timedwait)
 CFLAGS="$CFLAGS_hold"
 LIBS="$LIBS_hold"
 
+LIBS_hold="$LIBS"
+LIBS="$LIBS $MATH_LIBS"
+AC_CHECK_FUNCS(matherr)
+LIBS="$LIBS_hold"
+
 AC_CACHE_CHECK([for __sync_bool_compare_and_swap_4],
 [libgo_cv_func___sync_bool_compare_and_swap_4],
 [AC_LINK_IFELSE([
@@ -566,6 +571,16 @@ AC_CACHE_CHECK([epoll_event data.fd offset],
 STRUCT_EPOLL_EVENT_FD_OFFSET=${libgo_cv_c_epoll_event_fd_offset}
 AC_SUBST(STRUCT_EPOLL_EVENT_FD_OFFSET)
 
+dnl See if struct exception is defined in <math.h>.
+AC_CHECK_TYPE([struct exception],
+[libgo_has_struct_exception=yes],
+[libgo_has_struct_exception=no],
+[#include <math.h>])
+if test "$libgo_has_struct_exception" = "yes"; then
+  AC_DEFINE(HAVE_STRUCT_EXCEPTION, 1,
+            [Define to 1 if <math.h> defines struct exception])
+fi
+
 dnl See whether setcontext changes the value of TLS variables.
 AC_CACHE_CHECK([whether setcontext clobbers TLS variables],
 [libgo_cv_lib_setcontext_clobbers_tls],
diff --git a/libgo/runtime/go-matherr.c b/libgo/runtime/go-matherr.c
new file mode 100644 (file)
index 0000000..786f316
--- /dev/null
@@ -0,0 +1,88 @@
+/* go-matherr.c -- a Go version of the matherr function.
+
+   Copyright 2012 The Go Authors. All rights reserved.
+   Use of this source code is governed by a BSD-style
+   license that can be found in the LICENSE file.  */
+
+/* The gccgo version of the math library calls libc functions.  On
+   some systems, such as Solaris, those functions will call matherr on
+   exceptional conditions.  This is a version of matherr appropriate
+   for Go, one which returns the values that the Go math library
+   expects.  This is fine for pure Go programs.  For mixed Go and C
+   programs this will be problematic if the C programs themselves use
+   matherr.  Normally the C version of matherr will override this, and
+   the Go code will just have to cope.  If this turns out to be too
+   problematic we can change to run pure Go code in the math library
+   on systems that use matherr.  */
+
+#include <math.h>
+#include <stdint.h>
+
+#include "config.h"
+
+#if defined(HAVE_MATHERR) && defined(HAVE_STRUCT_EXCEPTION)
+
+#define PI 3.14159265358979323846264338327950288419716939937510582097494459
+
+int
+matherr (struct exception* e)
+{
+  const char *n;
+
+  if (e->type != DOMAIN)
+    return 0;
+
+  n = e->name;
+  if (__builtin_strcmp (n, "acos") == 0
+      || __builtin_strcmp (n, "asin") == 0)
+    e->retval = NAN;
+  else if (__builtin_strcmp (n, "atan2") == 0)
+    {
+      if (e->arg1 == 0 && e->arg2 == 0)
+       {
+         double nz;
+
+         nz = -0.0;
+         if (__builtin_memcmp (&e->arg2, &nz, sizeof (double)) != 0)
+           e->retval = e->arg1;
+         else
+           e->retval = copysign (PI, e->arg1);
+       }
+      else
+       return 0;
+    }
+  else if (__builtin_strcmp (n, "log") == 0
+          || __builtin_strcmp (n, "log10") == 0)
+    e->retval = NAN;
+  else if (__builtin_strcmp (n, "pow") == 0)
+    {
+      if (e->arg1 < 0)
+       e->retval = NAN;
+      else if (e->arg1 == 0 && e->arg2 == 0)
+       e->retval = 1.0;
+      else if (e->arg1 == 0 && e->arg2 < 0)
+       {
+         double i;
+
+         if (modf (e->arg2, &i) == 0 && ((int64_t) i & 1) == 1)
+           e->retval = copysign (INFINITY, e->arg1);
+         else
+           e->retval = INFINITY;
+       }
+      else
+       return 0;
+    }
+  else if (__builtin_strcmp (n, "sqrt") == 0)
+    {
+      if (e->arg1 < 0)
+       e->retval = NAN;
+      else
+       return 0;
+    }
+  else
+    return 0;
+
+  return 1;
+}
+
+#endif