Patchwork libgo patch committed: Provide i386 long double math fns if needed

login
register
mail settings
Submitter Ian Taylor
Date April 27, 2012, 4:38 p.m.
Message ID <mcrmx5x3zaq.fsf@dhcp-172-18-216-180.mtv.corp.google.com>
Download mbox | patch
Permalink /patch/155542/
State New
Headers show

Comments

Ian Taylor - April 27, 2012, 4:38 p.m.
This patch to libgo provides the long double math functions if they are
not in the system libm.  This is needed on i386 because the Go frontend
automatically converts calls to these functions from float64 (aka C
double) to C long double, as guided by express_precision_type.  This is
done so that the compiler can use the x87 instructions when available.
However, when not optimizing, the compiler will still emit a call to the
function.  This occurs in particular when running the libgo math test;
I'm not sure it actually happens at any other time.  This patch provides
a sufficient implementation of these functions for use by Go.  This
fixes another part of PR 52358.  Bootstrapped and ran Go testsuite on
x86_64-unknown-linux-gnu and i386-sun-solaris2.9.  Committed to mainline
and 4.7 branch.

Ian

Patch

diff -r a253ccfa3489 libgo/configure.ac
--- a/libgo/configure.ac	Fri Apr 27 09:30:57 2012 -0700
+++ b/libgo/configure.ac	Fri Apr 27 09:33:21 2012 -0700
@@ -489,6 +489,11 @@ 
 AC_TYPE_OFF_T
 AC_CHECK_TYPES([loff_t])
 
+LIBS_hold="$LIBS"
+LIBS="$LIBS -lm"
+AC_CHECK_FUNCS(cosl expl logl sinl tanl acosl asinl atanl atan2l expm1l ldexpl log10l log1pl)
+LIBS="$LIBS_hold"
+
 CFLAGS_hold="$CFLAGS"
 CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
 LIBS_hold="$LIBS"
diff -r a253ccfa3489 libgo/runtime/go-nosys.c
--- a/libgo/runtime/go-nosys.c	Fri Apr 27 09:30:57 2012 -0700
+++ b/libgo/runtime/go-nosys.c	Fri Apr 27 09:33:21 2012 -0700
@@ -13,6 +13,7 @@ 
 
 #include <errno.h>
 #include <fcntl.h>
+#include <math.h>
 #include <stdint.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -239,3 +240,116 @@ 
   return -1;
 }
 #endif
+
+/* Long double math functions.  These are needed on old i386 systems
+   that don't have them in libm.  The compiler translates calls to
+   these functions on float64 to call an 80-bit floating point
+   function instead, because when optimizing that function can be
+   executed as an x87 instructure.  However, when not optimizing, this
+   translates into a call to the math function.  So on systems that
+   don't provide these functions, we provide a version that just calls
+   the float64 version.  */
+
+#ifndef HAVE_COSL
+long double
+cosl (long double a)
+{
+  return (long double) cos ((double) a);
+}
+#endif
+
+#ifndef HAVE_EXPL
+long double
+expl (long double a)
+{
+  return (long double) exp ((double) a);
+}
+#endif
+
+#ifndef HAVE_LOGL
+long double
+logl (long double a)
+{
+  return (long double) log ((double) a);
+}
+#endif
+
+#ifndef HAVE_SINL
+long double
+sinl (long double a)
+{
+  return (long double) sin ((double) a);
+}
+#endif
+
+#ifndef HAVE_TANL
+long double
+tanl (long double a)
+{
+  return (long double) tan ((double) a);
+}
+#endif
+
+#ifndef HAVE_ACOSL
+long double
+acosl (long double a)
+{
+  return (long double) acos ((double) a);
+}
+#endif
+
+#ifndef HAVE_ASINL
+long double
+asinl (long double a)
+{
+  return (long double) asin ((double) a);
+}
+#endif
+
+#ifndef HAVE_ATANL
+long double
+atanl (long double a)
+{
+  return (long double) atan ((double) a);
+}
+#endif
+
+#ifndef HAVE_ATAN2L
+long double
+atan2l (long double a, long double b)
+{
+  return (long double) atan2 ((double) a, (double) b);
+}
+#endif
+
+#ifndef HAVE_EXPM1L
+long double
+expm1l (long double a)
+{
+  return (long double) expm1 ((double) a);
+}
+#endif
+
+#ifndef HAVE_LDEXPL
+long double
+ldexpl (long double a, int exp)
+{
+  return (long double) ldexp ((double) a, exp);
+}
+#endif
+
+#ifndef HAVE_LOG10L
+long double
+log10l (long double a)
+{
+  return (long double) log10 ((double) a);
+}
+#endif
+
+#ifndef HAVE_LOG1PL
+long double
+log1pl (long double a)
+{
+  return (long double) log1p ((double) a);
+}
+#endif