public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: For testing: full __float128 patch
@ 2010-08-30  1:55 Uros Bizjak
  2010-08-30  1:59 ` Steve Kargl
  0 siblings, 1 reply; 23+ messages in thread
From: Uros Bizjak @ 2010-08-30  1:55 UTC (permalink / raw)
  To: Fortran List; +Cc: Steve Kargl, FX, gcc

[-- Attachment #1: Type: text/plain, Size: 1382 bytes --]

Hello!

> On Sun, Aug 29, 2010 at 09:01:49AM +0200, FX wrote:
> > GCC >= 4.5 is needed. I'll add a check to libquad's configure.
> > 
> > FX
> > 
> 
> Further testing on i386-*-freebsd runs into undefined symbols.
> 
> libquad.so: undefined reference to `__getf2'
> libquad.so: undefined reference to `__eqtf2'
> libquad.so: undefined reference to `__addtf3'
> libquad.so: undefined reference to `__floatsitf'
> libquad.so: undefined reference to `__trunctfxf2'
> libquad.so: undefined reference to `__divtf3'
> libquad.so: undefined reference to `__letf2'
> libquad.so: undefined reference to `__unordtf2'
> libquad.so: undefined reference to `__fixtfdi'
> libquad.so: undefined reference to `__fixtfsi'
> libquad.so: undefined reference to `__lttf2'
> libquad.so: undefined reference to `__netf2'
> libquad.so: undefined reference to `__extendxftf2'
> libquad.so: undefined reference to `__extenddftf2'
> libquad.so: undefined reference to `__multf3'
> libquad.so: undefined reference to `__gttf2'
> libquad.so: undefined reference to `__subtf3'
> libgfortran.so: undefined reference to `__floatunditf'
> libquad.so: undefined reference to `__trunctfdf2'
> 
> 
> AFAICT, these should come from libgcc_s.so.1, but for whatever
> reason these are missing.  I have been unable to find how
> to induce gcc to build the required files. 

Try to build gcc with attached patch...

Uros.

[-- Attachment #2: c.diff.txt --]
[-- Type: text/plain, Size: 523 bytes --]

Index: config.gcc
===================================================================
--- config.gcc	(revision 163630)
+++ config.gcc	(working copy)
@@ -3485,6 +3485,9 @@
 	i[34567]86-*-cygwin* | i[34567]86-*-mingw* | x86_64-*-mingw*)
 		tmake_file="${tmake_file} i386/t-fprules-softfp soft-fp/t-softfp"
 		;;
+	i[34567]86-*-freebsd* | x86_64-*-freebsd*)
+		tmake_file="${tmake_file} i386/t-fprules-softfp soft-fp/t-softfp"
+		;;
 	ia64*-*-linux*)
 		tmake_file="${tmake_file} ia64/t-fprules-softfp soft-fp/t-softfp"
 		;;

^ permalink raw reply	[flat|nested] 23+ messages in thread
* For testing: full __float128 patch
@ 2010-08-29  0:57 FX
  2010-08-29  1:48 ` Steve Kargl
  0 siblings, 1 reply; 23+ messages in thread
From: FX @ 2010-08-29  0:57 UTC (permalink / raw)
  To: Fortran List, gcc

[-- Attachment #1: Type: text/plain, Size: 2378 bytes --]

Before I submit it officially for review, I want this patch to get some exposure while I clean up a few remaining dusty corners. To test the patch on x86_64-linux, proceed as follows:

  -- Get libquad from http://quatramaran.ens.fr/~coudert/tmp/libquad.tar.bz2 , then ./configure --prefix=/foo && make && make install 
  -- Build GCC with the extra configure argument: --with-quad=/foo (to be given to the toplevel configure command, like --with-gmp, nothing fancy)

Things to test in particular:

  -- I've tested this on linux and Mac OS; although it's pretty much OS-insensitive, does it work on things like FreeBSD and Windows?
  -- check carefully I/O support; in particular, the "output formatting" (i.e. writing out the values) involves a wrapper of my own around the gdtoa code, which was a bit painful to write, so bugs might have crawled in there


Things that do not yet work, or may change:

  -- this is only for platform that support __float128 (targets without TFmode would break); I'm working on an updated front-end patch as proposed by Andrew and Tobias

  -- I realized that the exponentiation builtins are not properly handled by the front-end (all exponentiations involving __float128 or its complex counterpart give wrong code); I'll work on a fix

  -- Array intrinsics *do not work at all*. This is a limitation of the array descriptor structure, which I cannot overcome by myself. The current patch only changes these files (in_pack_generic.c, in_unpack_generic.c, pack_generic.c, spread_generic.c, unpack_generic.c, cshift0.c) to make them compile, but they will yield wrong results.

  -- the integration of libquad depends on how the discussion with the SC turns out; the current scheme is not nice at all in case of multilibs, see below

Please note: in case of a multilib build, unless you have a system which supports fat libraries (MacOS), only the variant that corresponds to the libquad you've built will have support enabled. Typically, on a x86_64 system where you've built libquad with the default 64-bit compiler, you'll only have libquad support in the -m64 variant of libgfortran, and not the -m32 variant.



All comment are of course welcome. I think the two preliminary commits allowed to keep the size of this final patch to a reasonable value under 1kLOC (less than 600 without regenerated files).

FX


[-- Attachment #2: full_testing.diff --]
[-- Type: application/octet-stream, Size: 28985 bytes --]

Index: gcc/fortran/trans-types.c
===================================================================
--- gcc/fortran/trans-types.c	(revision 163619)
+++ gcc/fortran/trans-types.c	(working copy)
@@ -414,7 +414,8 @@ gfc_init_kinds (void)
 	 support is done.  */
 	if (mode != TYPE_MODE (float_type_node)
 	  && (mode != TYPE_MODE (double_type_node))
-          && (mode != TYPE_MODE (long_double_type_node)))
+          && (mode != TYPE_MODE (long_double_type_node))
+	  && (mode != TFmode))
 	continue;
 
       /* Let the kind equal the precision divided by 8, rounding up.  Again,
Index: libgfortran/configure
===================================================================
--- libgfortran/configure	(revision 163619)
+++ libgfortran/configure	(working copy)
@@ -603,6 +603,8 @@ LTLIBOBJS
 LIBOBJS
 IEEE_FLAGS
 FPU_HOST_HEADER
+GFOR_USE_QUAD_LIB_FALSE
+GFOR_USE_QUAD_LIB_TRUE
 extra_ldflags_libgfortran
 ac_ct_FC
 FCFLAGS
@@ -691,6 +693,8 @@ host_os
 host_vendor
 host_cpu
 host
+QUADINC
+QUADLIBS
 onestep
 onestep_FALSE
 onestep_TRUE
@@ -746,6 +750,9 @@ enable_option_checking
 with_build_libsubdir
 enable_version_specific_runtime_libs
 enable_intermodule
+with_quad
+with_quad_include
+with_quad_lib
 enable_maintainer_mode
 enable_multilib
 enable_dependency_tracking
@@ -1404,6 +1411,11 @@ Optional Packages:
   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
   --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
   --with-build-libsubdir=DIR  Directory where to find libraries for build system
+  --with-quad=PATH         specify prefix directory for the installed quad package.
+                          Equivalent to --with-quad-include=PATH/include
+                          plus --with-quad-lib=PATH/lib
+  --with-quad-include=PATH specify directory for installed quad include files
+  --with-quad-lib=PATH     specify directory for the installed quad library
   --with-pic              try to use only PIC/non-PIC objects [default=use
                           both]
   --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
@@ -2733,6 +2745,40 @@ fi
 
 
 
+# Build with a quad-float support library
+
+# Check whether --with-quad was given.
+if test "${with_quad+set}" = set; then :
+  withval=$with_quad;
+fi
+
+
+# Check whether --with-quad_include was given.
+if test "${with_quad_include+set}" = set; then :
+  withval=$with_quad_include;
+fi
+
+
+# Check whether --with-quad_lib was given.
+if test "${with_quad_lib+set}" = set; then :
+  withval=$with_quad_lib;
+fi
+
+
+if test "x$with_quad" != x; then
+  QUADLIBS="-L$with_quad/lib $QUADLIBS"
+  QUADINC="-I$with_quad/include $QUADINC"
+fi
+if test "x$with_quad_include" != x; then
+  QUADINC="-I$with_quad_include $QUADINC"
+fi
+if test "x$with_quad_lib" != x; then
+  QUADLIBS="-L$with_quad_lib $QUADLIBS"
+fi
+
+
+
+
 # Gets build, host, target, *_vendor, *_cpu, *_os, etc.
 #
 # You will slowly go insane if you do not grok the following fact:  when
@@ -11362,7 +11408,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11365 "configure"
+#line 11411 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11468,7 +11514,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11471 "configure"
+#line 11517 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -24468,6 +24514,129 @@ $as_echo "#define HAVE_BROKEN_POWF 1" >>
   fi
 
 
+# Check whether we have a __float128 type
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we have a __float128 type" >&5
+$as_echo_n "checking whether we have a __float128 type... " >&6; }
+if test "${libgfor_cv_have_float128+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    if test x$gcc_no_link = xyes; then
+  as_fn_error "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5
+fi
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* no header */
+
+int
+main ()
+{
+
+  typedef _Complex float __attribute__((mode(TC))) __complex128;
+
+  __float128 x;
+  x = __builtin_huge_valq() - 2.e1000Q;
+
+  __complex128 z1, z2;
+  z1 = x;
+  z2 = 2.Q;
+
+  z1 /= z2;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "libgfor_cv_have_float128=yes"
+else
+  eval "libgfor_cv_have_float128=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgfor_cv_have_float128" >&5
+$as_echo "$libgfor_cv_have_float128" >&6; }
+
+  if test "x$libgfor_cv_have_float128" = xyes; then
+
+$as_echo "#define HAVE_FLOAT128 1" >>confdefs.h
+
+  fi
+
+
+# Check whether we have a quad-precision float library
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we have a quad-precision float library" >&5
+$as_echo_n "checking whether we have a quad-precision float library... " >&6; }
+if test "${libgfor_cv_have_quad_lib+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    save_LIBS="$LIBS"
+    LIBS="$LIBS $QUADLIBS -lquad"
+    save_CFLAGS="$CFLAGS"
+    CFLAGS="$CFLAGS $QUADINC"
+    if test x$gcc_no_link = xyes; then
+  as_fn_error "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5
+fi
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+  #include <quad.h>
+
+int
+main ()
+{
+
+  __complex128 z;
+  __float128 x;
+
+  z = 2.Q;
+  x = cargq (x);
+  x = sqrtq (x);
+
+  char buffer[100];
+  libgfortran_dtoaq (buffer, 30, 40, x);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "libgfor_cv_have_quad_lib=yes"
+else
+  eval "libgfor_cv_have_quad_lib=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+    LIBS="$save_LIBS"
+    CFLAGS="$save_CFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgfor_cv_have_quad_lib" >&5
+$as_echo "$libgfor_cv_have_quad_lib" >&6; }
+
+  if test "x$libgfor_cv_have_quad_lib" = xyes; then
+
+$as_echo "#define GFC_WITH_QUAD_LIB 1" >>confdefs.h
+
+  fi
+
+     if test "x$libgfor_cv_have_quad_lib" = xyes; then
+  GFOR_USE_QUAD_LIB_TRUE=
+  GFOR_USE_QUAD_LIB_FALSE='#'
+else
+  GFOR_USE_QUAD_LIB_TRUE='#'
+  GFOR_USE_QUAD_LIB_FALSE=
+fi
+
+
+
 # Check for GNU libc feenableexcept
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for feenableexcept in -lm" >&5
 $as_echo_n "checking for feenableexcept in -lm... " >&6; }
@@ -25150,6 +25319,10 @@ if test -z "${LIBGFOR_USE_SYMVER_SUN_TRU
   as_fn_error "conditional \"LIBGFOR_USE_SYMVER_SUN\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${GFOR_USE_QUAD_LIB_TRUE}" && test -z "${GFOR_USE_QUAD_LIB_FALSE}"; then
+  as_fn_error "conditional \"GFOR_USE_QUAD_LIB\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 
 : ${CONFIG_STATUS=./config.status}
 ac_write_fail=0
Index: libgfortran/Makefile.in
===================================================================
--- libgfortran/Makefile.in	(revision 163619)
+++ libgfortran/Makefile.in	(working copy)
@@ -381,6 +381,8 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
 PACKAGE_URL = @PACKAGE_URL@
 PACKAGE_VERSION = @PACKAGE_VERSION@
 PATH_SEPARATOR = @PATH_SEPARATOR@
+QUADINC = @QUADINC@
+QUADLIBS = @QUADLIBS@
 RANLIB = @RANLIB@
 SECTION_FLAGS = @SECTION_FLAGS@
 SED = @SED@
@@ -463,12 +465,16 @@ gcc_version := $(shell cat $(top_srcdir)
 @LIBGFOR_USE_SYMVER_FALSE@version_dep = 
 @LIBGFOR_USE_SYMVER_GNU_TRUE@@LIBGFOR_USE_SYMVER_TRUE@version_dep = $(srcdir)/gfortran.map
 @LIBGFOR_USE_SYMVER_SUN_TRUE@@LIBGFOR_USE_SYMVER_TRUE@version_dep = gfortran.map-sun
+@GFOR_USE_QUAD_LIB_FALSE@quad_link = 
+
+# Compile and link with quad float library if present
+@GFOR_USE_QUAD_LIB_TRUE@quad_link = -lquad
 LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS)) \
 	    -no-undefined -bindir "$(bindir)"
 
 toolexeclib_LTLIBRARIES = libgfortran.la
 libgfortran_la_LINK = $(LINK) $(libgfortran_la_LDFLAGS)
-libgfortran_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(LTLDFLAGS) -lm $(extra_ldflags_libgfortran) $(version_arg)
+libgfortran_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(LTLDFLAGS) $(QUADLIBS) $(quad_link) -lm $(extra_ldflags_libgfortran) $(version_arg)
 libgfortran_la_DEPENDENCIES = $(version_dep)
 myexeclib_LTLIBRARIES = libgfortranbegin.la
 myexeclibdir = $(libdir)/gcc/$(target_alias)/$(gcc_version)$(MULTISUBDIR)
@@ -477,7 +483,8 @@ libgfortranbegin_la_LDFLAGS = -static
 libgfortranbegin_la_LINK = $(LINK) $(libgfortranbegin_la_LDFLAGS)
 AM_CPPFLAGS = -iquote$(srcdir)/io -I$(srcdir)/$(MULTISRCTOP)../gcc \
 	      -I$(srcdir)/$(MULTISRCTOP)../gcc/config \
-	      -I$(MULTIBUILDTOP)../../$(host_subdir)/gcc -D_GNU_SOURCE
+	      -I$(MULTIBUILDTOP)../../$(host_subdir)/gcc -D_GNU_SOURCE \
+	      $(QUADINC)
 
 gfor_io_src = \
 io/close.c \
Index: libgfortran/runtime/in_pack_generic.c
===================================================================
--- libgfortran/runtime/in_pack_generic.c	(revision 163619)
+++ libgfortran/runtime/in_pack_generic.c	(working copy)
@@ -85,10 +85,6 @@ internal_pack (gfc_array_char * source)
       return internal_pack_r10 ((gfc_array_r10 *) source);
 #endif
 
-#if defined (HAVE_GFC_REAL_16)
-    case GFC_DTYPE_REAL_16:
-      return internal_pack_r16 ((gfc_array_r16 *) source);
-#endif
     case GFC_DTYPE_COMPLEX_4:
       return internal_pack_c4 ((gfc_array_c4 *) source);
 	
@@ -100,10 +96,6 @@ internal_pack (gfc_array_char * source)
       return internal_pack_c10 ((gfc_array_c10 *) source);
 #endif
 
-#if defined (HAVE_GFC_COMPLEX_16)
-    case GFC_DTYPE_COMPLEX_16:
-      return internal_pack_c16 ((gfc_array_c16 *) source);
-#endif
 
     case GFC_DTYPE_DERIVED_2:
       if (GFC_UNALIGNED_2(source->data))
Index: libgfortran/runtime/in_unpack_generic.c
===================================================================
--- libgfortran/runtime/in_unpack_generic.c	(revision 163619)
+++ libgfortran/runtime/in_unpack_generic.c	(working copy)
@@ -95,11 +95,6 @@ internal_unpack (gfc_array_char * d, con
       return;
 #endif
 
-#if defined(HAVE_GFC_REAL_16)
-    case GFC_DTYPE_REAL_16:
-      internal_unpack_r16 ((gfc_array_r16 *) d, (const GFC_REAL_16 *) s);
-      return;
-#endif
     case GFC_DTYPE_COMPLEX_4:
       internal_unpack_c4 ((gfc_array_c4 *)d, (const GFC_COMPLEX_4 *)s);
       return;
@@ -114,11 +109,6 @@ internal_unpack (gfc_array_char * d, con
       return;
 #endif
 
-#if defined(HAVE_GFC_COMPLEX_16)
-    case GFC_DTYPE_COMPLEX_16:
-      internal_unpack_c16 ((gfc_array_c16 *) d, (const GFC_COMPLEX_16 *) s);
-      return;
-#endif
     case GFC_DTYPE_DERIVED_2:
       if (GFC_UNALIGNED_2(d->data) || GFC_UNALIGNED_2(s))
 	break;
Index: libgfortran/intrinsics/pack_generic.c
===================================================================
--- libgfortran/intrinsics/pack_generic.c	(revision 163619)
+++ libgfortran/intrinsics/pack_generic.c	(working copy)
@@ -310,12 +310,6 @@ pack (gfc_array_char *ret, const gfc_arr
       return;
 #endif
 
-#ifdef HAVE_GFC_REAL_16
-    case GFC_DTYPE_REAL_16:
-      pack_r16 ((gfc_array_r16 *) ret, (gfc_array_r16 *) array,
-		(gfc_array_l1 *) mask, (gfc_array_r16 *) vector);
-      return;
-#endif
     case GFC_DTYPE_COMPLEX_4:
       pack_c4 ((gfc_array_c4 *) ret, (gfc_array_c4 *) array,
 	       (gfc_array_l1 *) mask, (gfc_array_c4 *) vector);
@@ -333,12 +327,6 @@ pack (gfc_array_char *ret, const gfc_arr
       return;
 #endif
 
-#ifdef HAVE_GFC_COMPLEX_16
-    case GFC_DTYPE_COMPLEX_16:
-      pack_c16 ((gfc_array_c16 *) ret, (gfc_array_c16 *) array,
-		(gfc_array_l1 *) mask, (gfc_array_c16 *) vector);
-      return;
-#endif
 
       /* For derived types, let's check the actual alignment of the
 	 data pointers.  If they are aligned, we can safely call
Index: libgfortran/intrinsics/erfc_scaled_inc.c
===================================================================
--- libgfortran/intrinsics/erfc_scaled_inc.c	(revision 163619)
+++ libgfortran/intrinsics/erfc_scaled_inc.c	(working copy)
@@ -39,7 +39,7 @@ see the files COPYING3 and COPYING.RUNTI
 # define EXP(x) exp(x)
 # define TRUNC(x) trunc(x)
 
-#else
+#elif (KIND == 10) || (KIND == 16 && defined(GFC_REAL_16_IS_LONG_DOUBLE))
 
 # ifdef HAVE_EXPL
 #  define EXP(x) expl(x)
@@ -48,6 +48,15 @@ see the files COPYING3 and COPYING.RUNTI
 #  define TRUNC(x) truncl(x)
 # endif
 
+#elif (KIND == 16 && defined(GFC_REAL_16_IS_FLOAT128))
+
+#  define EXP(x) expq(x)
+#  define TRUNC(x) truncq(x)
+
+#else
+
+# error "What exactly is it that you want me to do?"
+
 #endif
 
 #if defined(EXP) && defined(TRUNC)
Index: libgfortran/intrinsics/cshift0.c
===================================================================
--- libgfortran/intrinsics/cshift0.c	(revision 163619)
+++ libgfortran/intrinsics/cshift0.c	(working copy)
@@ -141,13 +141,6 @@ cshift0 (gfc_array_char * ret, const gfc
       return;
 #endif
 
-#ifdef HAVE_GFC_REAL_16
-    case GFC_DTYPE_REAL_16:
-      cshift0_r16 ((gfc_array_r16 *)ret, (gfc_array_r16 *) array, shift,
-		   which);
-      return;
-#endif
-
     case GFC_DTYPE_COMPLEX_4:
       cshift0_c4 ((gfc_array_c4 *)ret, (gfc_array_c4 *) array, shift, which);
       return;
@@ -163,12 +156,6 @@ cshift0 (gfc_array_char * ret, const gfc
       return;
 #endif
 
-#ifdef HAVE_GFC_COMPLEX_16
-    case GFC_DTYPE_COMPLEX_16:
-      cshift0_c16 ((gfc_array_c16 *)ret, (gfc_array_c16 *) array, shift,
-		   which);
-      return;
-#endif
 
     default:
       break;
Index: libgfortran/intrinsics/spread_generic.c
===================================================================
--- libgfortran/intrinsics/spread_generic.c	(revision 163619)
+++ libgfortran/intrinsics/spread_generic.c	(working copy)
@@ -329,12 +329,6 @@ spread (gfc_array_char *ret, const gfc_a
       return;
 #endif
 
-#ifdef GFC_HAVE_REAL_16
-    case GFC_DTYPE_REAL_16:
-      spread_r16 ((gfc_array_r16 *) ret, (gfc_array_r16 *) source,
-		 *along, *pncopies);
-      return;
-#endif
 
     case GFC_DTYPE_COMPLEX_4:
       spread_c4 ((gfc_array_c4 *) ret, (gfc_array_c4 *) source,
@@ -353,13 +347,6 @@ spread (gfc_array_char *ret, const gfc_a
       return;
 #endif
 
-#ifdef GFC_HAVE_COMPLEX_16
-    case GFC_DTYPE_COMPLEX_16:
-      spread_c16 ((gfc_array_c16 *) ret, (gfc_array_c16 *) source,
-		 *along, *pncopies);
-      return;
-#endif
-
     case GFC_DTYPE_DERIVED_2:
       if (GFC_UNALIGNED_2(ret->data) || GFC_UNALIGNED_2(source->data))
 	break;
@@ -508,13 +495,6 @@ spread_scalar (gfc_array_char *ret, cons
       return;
 #endif
 
-#ifdef HAVE_GFC_REAL_16
-    case GFC_DTYPE_REAL_16:
-      spread_scalar_r16 ((gfc_array_r16 *) ret, (GFC_REAL_16 *) source,
-			*along, *pncopies);
-      return;
-#endif
-
     case GFC_DTYPE_COMPLEX_4:
       spread_scalar_c4 ((gfc_array_c4 *) ret, (GFC_COMPLEX_4 *) source,
 			*along, *pncopies);
@@ -532,13 +512,6 @@ spread_scalar (gfc_array_char *ret, cons
       return;
 #endif
 
-#ifdef HAVE_GFC_COMPLEX_16
-    case GFC_DTYPE_COMPLEX_16:
-      spread_scalar_c16 ((gfc_array_c16 *) ret, (GFC_COMPLEX_16 *) source,
-			*along, *pncopies);
-      return;
-#endif
-
     case GFC_DTYPE_DERIVED_2:
       if (GFC_UNALIGNED_2(ret->data) || GFC_UNALIGNED_2(source))
 	break;
Index: libgfortran/intrinsics/unpack_generic.c
===================================================================
--- libgfortran/intrinsics/unpack_generic.c	(revision 163619)
+++ libgfortran/intrinsics/unpack_generic.c	(working copy)
@@ -267,13 +267,6 @@ unpack1 (gfc_array_char *ret, const gfc_
 	  return;
 #endif
 
-#ifdef HAVE_GFC_REAL_16
-    case GFC_DTYPE_REAL_16:
-      unpack1_r16 ((gfc_array_r16 *) ret, (gfc_array_r16 *) vector,
-		   mask, (gfc_array_r16 *) field);
-      return;
-#endif
-
     case GFC_DTYPE_COMPLEX_4:
       unpack1_c4 ((gfc_array_c4 *) ret, (gfc_array_c4 *) vector,
 		  mask, (gfc_array_c4 *) field);
@@ -291,13 +284,6 @@ unpack1 (gfc_array_char *ret, const gfc_
       return;
 #endif
 
-#ifdef HAVE_GFC_COMPLEX_16
-    case GFC_DTYPE_COMPLEX_16:
-      unpack1_c16 ((gfc_array_c16 *) ret, (gfc_array_c16 *) vector,
-		   mask, (gfc_array_c16 *) field);
-      return;
-#endif
-
     case GFC_DTYPE_DERIVED_2:
       if (GFC_UNALIGNED_2(ret->data) || GFC_UNALIGNED_2(vector->data)
 	  || GFC_UNALIGNED_2(field->data))
@@ -460,13 +446,6 @@ unpack0 (gfc_array_char *ret, const gfc_
       return;
 #endif
 
-#ifdef HAVE_GFC_REAL_16
-    case GFC_DTYPE_REAL_16:
-      unpack0_r16 ((gfc_array_r16 *) ret, (gfc_array_r16 *) vector,
-		   mask, (GFC_REAL_16 *) field);
-      return;
-#endif
-
     case GFC_DTYPE_COMPLEX_4:
       unpack0_c4 ((gfc_array_c4 *) ret, (gfc_array_c4 *) vector,
 		  mask, (GFC_COMPLEX_4 *) field);
@@ -484,12 +463,6 @@ unpack0 (gfc_array_char *ret, const gfc_
       return;
 #endif
 
-#ifdef HAVE_GFC_COMPLEX_16
-    case GFC_DTYPE_COMPLEX_16:
-      unpack0_c16 ((gfc_array_c16 *) ret, (gfc_array_c16 *) vector,
-		   mask, (GFC_COMPLEX_16 *) field);
-      return;
-#endif
     case GFC_DTYPE_DERIVED_2:
       if (GFC_UNALIGNED_2(ret->data) || GFC_UNALIGNED_2(vector->data)
 	  || GFC_UNALIGNED_2(field))
Index: libgfortran/configure.ac
===================================================================
--- libgfortran/configure.ac	(revision 163619)
+++ libgfortran/configure.ac	(working copy)
@@ -34,6 +34,27 @@ AC_MSG_RESULT($enable_intermodule)
 AM_CONDITIONAL(onestep,[test x$onestep = x-onestep])
 AC_SUBST(onestep)
 
+# Build with a quad-float support library
+AC_ARG_WITH(quad, [  --with-quad=PATH         specify prefix directory for the installed quad package.
+                          Equivalent to --with-quad-include=PATH/include
+                          plus --with-quad-lib=PATH/lib])
+AC_ARG_WITH(quad_include, [  --with-quad-include=PATH specify directory for installed quad include files])
+AC_ARG_WITH(quad_lib, [  --with-quad-lib=PATH     specify directory for the installed quad library])
+
+if test "x$with_quad" != x; then
+  QUADLIBS="-L$with_quad/lib $QUADLIBS"
+  QUADINC="-I$with_quad/include $QUADINC"
+fi
+if test "x$with_quad_include" != x; then
+  QUADINC="-I$with_quad_include $QUADINC"
+fi
+if test "x$with_quad_lib" != x; then
+  QUADLIBS="-L$with_quad_lib $QUADLIBS"
+fi
+
+AC_SUBST(QUADLIBS)
+AC_SUBST(QUADINC)
+
 # Gets build, host, target, *_vendor, *_cpu, *_os, etc.
 #
 # You will slowly go insane if you do not grok the following fact:  when
@@ -468,6 +489,12 @@ LIBGFOR_CHECK_MINGW_SNPRINTF
 # Check for a broken powf implementation
 LIBGFOR_CHECK_FOR_BROKEN_POWF
 
+# Check whether we have a __float128 type
+LIBGFOR_CHECK_FLOAT128
+
+# Check whether we have a quad-precision float library
+LIBGFOR_CHECK_QUAD_LIB
+
 # Check for GNU libc feenableexcept
 AC_CHECK_LIB([m],[feenableexcept],[have_feenableexcept=yes AC_DEFINE([HAVE_FEENABLEEXCEPT],[1],[libm includes feenableexcept])])
 
Index: libgfortran/libgfortran.h
===================================================================
--- libgfortran/libgfortran.h	(revision 163619)
+++ libgfortran/libgfortran.h	(working copy)
@@ -314,6 +314,30 @@ internal_proto(big_endian);
   (GFC_INTEGER_16)((((GFC_UINTEGER_16)1) << 127) - 1)
 #endif
 
+
+/* What are the C types corresponding to the real(kind=10) and
+   real(kind=16) types? We currently rely on the following assumptions:
+     -- if real(kind=10) exists, i.e. if HAVE_GFC_REAL_10 is defined,
+        then it is necessarily the "long double" type
+     -- if real(kind=16) exists, then:
+         * if HAVE_GFC_REAL_10, real(kind=16) is "__float128"
+	 * otherwise, real(kind=16) is "long double"
+   To allow to change this in the future, we create the
+   GFC_REAL_16_IS_FLOAT128 macro that is used throughout libgfortran.  */
+#if defined(HAVE_GFC_REAL_16)
+# if defined(HAVE_GFC_REAL_10)
+#  define GFC_REAL_16_IS_FLOAT128
+#  if !defined(HAVE_FLOAT128)
+#   error "Where has __float128 gone?"
+#  endif
+# else
+#  define GFC_REAL_16_IS_LONG_DOUBLE
+# endif
+#endif
+
+//#include "quad.h"
+
+
 /* M{IN,AX}{LOC,VAL} need also infinities and NaNs if supported.  */
 
 #ifdef __FLT_HAS_INFINITY__
@@ -327,7 +351,11 @@ internal_proto(big_endian);
 #  define GFC_REAL_10_INFINITY __builtin_infl ()
 # endif
 # ifdef HAVE_GFC_REAL_16
-#  define GFC_REAL_16_INFINITY __builtin_infl ()
+#  ifdef GFC_REAL_16_IS_LONG_DOUBLE
+#   define GFC_REAL_16_INFINITY __builtin_infl ()
+#  else
+#   define GFC_REAL_16_INFINITY __builtin_infq ()
+#  endif
 # endif
 #endif
 #ifdef __FLT_HAS_QUIET_NAN__
@@ -341,7 +369,11 @@ internal_proto(big_endian);
 #  define GFC_REAL_10_QUIET_NAN __builtin_nanl ("")
 # endif
 # ifdef HAVE_GFC_REAL_16
-#  define GFC_REAL_16_QUIET_NAN __builtin_nanl ("")
+#  ifdef GFC_REAL_16_IS_LONG_DOUBLE
+#   define GFC_REAL_16_QUIET_NAN __builtin_nanl ("")
+#  else
+#   define GFC_REAL_16_QUIET_NAN nanq ("")
+#  endif
 # endif
 #endif
 
Index: libgfortran/config.h.in
===================================================================
--- libgfortran/config.h.in	(revision 163619)
+++ libgfortran/config.h.in	(working copy)
@@ -1,5 +1,8 @@
 /* config.h.in.  Generated from configure.ac by autoheader.  */
 
+/* Define if we have a quad-precision float library. */
+#undef GFC_WITH_QUAD_LIB
+
 /* Define to 0 if the target shouldn't use #pragma weak */
 #undef GTHREAD_USE_WEAK
 
@@ -390,6 +393,9 @@
 /* Define to 1 if you have the <fenv.h> header file. */
 #undef HAVE_FENV_H
 
+/* Define if have a __float128 type. */
+#undef HAVE_FLOAT128
+
 /* Define to 1 if you have the <floatingpoint.h> header file. */
 #undef HAVE_FLOATINGPOINT_H
 
Index: libgfortran/acinclude.m4
===================================================================
--- libgfortran/acinclude.m4	(revision 163619)
+++ libgfortran/acinclude.m4	(working copy)
@@ -388,3 +388,66 @@ esac])
     AC_DEFINE(HAVE_BROKEN_POWF, 1, [Define if powf is broken.])
   fi
 ])
+
+dnl Check whether we have a __float128 type
+AC_DEFUN([LIBGFOR_CHECK_FLOAT128], [
+  AC_CACHE_CHECK([whether we have a __float128 type],
+                 libgfor_cv_have_float128, [
+    AC_TRY_LINK([
+/* no header */
+],[
+  typedef _Complex float __attribute__((mode(TC))) __complex128;
+
+  __float128 x;
+  x = __builtin_huge_valq() - 2.e1000Q;
+
+  __complex128 z1, z2;
+  z1 = x;
+  z2 = 2.Q;
+
+  z1 /= z2;
+],
+    eval "libgfor_cv_have_float128=yes",
+    eval "libgfor_cv_have_float128=no")
+  ])
+
+  if test "x$libgfor_cv_have_float128" = xyes; then
+    AC_DEFINE(HAVE_FLOAT128, 1, [Define if have a __float128 type.])
+  fi
+])
+
+dnl Check whether we have a quad-precision float library
+AC_DEFUN([LIBGFOR_CHECK_QUAD_LIB], [
+  AC_CACHE_CHECK([whether we have a quad-precision float library],
+                 libgfor_cv_have_quad_lib, [
+    save_LIBS="$LIBS"
+    LIBS="$LIBS $QUADLIBS -lquad"
+    save_CFLAGS="$CFLAGS"
+    CFLAGS="$CFLAGS $QUADINC"
+    AC_TRY_LINK([
+  #include <quad.h>
+],[
+  __complex128 z;
+  __float128 x;
+
+  z = 2.Q;
+  x = cargq (x);
+  x = sqrtq (x);
+  
+  char buffer[100];
+  libgfortran_dtoaq (buffer, 30, 40, x);
+],
+      eval "libgfor_cv_have_quad_lib=yes",
+      eval "libgfor_cv_have_quad_lib=no")
+
+    LIBS="$save_LIBS"
+    CFLAGS="$save_CFLAGS"
+  ])
+
+  if test "x$libgfor_cv_have_quad_lib" = xyes; then
+    AC_DEFINE(GFC_WITH_QUAD_LIB, 1, [Define if we have a quad-precision float library.])
+  fi
+
+  dnl We need a conditional for the Makefile
+  AM_CONDITIONAL(GFOR_USE_QUAD_LIB, [test "x$libgfor_cv_have_quad_lib" = xyes])
+])
Index: libgfortran/io/read.c
===================================================================
--- libgfortran/io/read.c	(revision 163619)
+++ libgfortran/io/read.c	(working copy)
@@ -162,10 +162,16 @@ convert_real (st_parameter_dt *dtp, void
       break;
 #endif
 
-#if defined(HAVE_GFC_REAL_16) && defined (HAVE_STRTOLD)
+#if defined(HAVE_GFC_REAL_16)
+# if defined(GFC_REAL_16_IS_FLOAT128)
+    case 16:
+      libgfortran_strtopQ (buffer, NULL, dest);
+      break;
+# elif defined(HAVE_STRTOLD)
     case 16:
       *((GFC_REAL_16*) dest) = gfc_strtold (buffer, NULL);
       break;
+# endif
 #endif
 
     default:
Index: libgfortran/io/write.c
===================================================================
--- libgfortran/io/write.c	(revision 163619)
+++ libgfortran/io/write.c	(working copy)
@@ -1459,6 +1459,7 @@ set_fnode_default (st_parameter_dt *dtp,
 /* Output a real number with default format.
    This is 1PG14.7E2 for REAL(4), 1PG23.15E3 for REAL(8),
    1PG28.19E4 for REAL(10) and 1PG43.34E4 for REAL(16).  */
+// FX -- FIXME: should we change the default format for __float128-real(16)?
 
 void
 write_real (st_parameter_dt *dtp, const char *source, int length)
Index: libgfortran/io/write_float.def
===================================================================
--- libgfortran/io/write_float.def	(revision 163619)
+++ libgfortran/io/write_float.def	(working copy)
@@ -973,6 +973,11 @@ sprintf (buffer, "%+-#" STR(MIN_FIELD_WI
 
 #endif
 
+#if defined(GFC_REAL_16_IS_FLOAT128)
+#define DTOAQ \
+libgfortran_dtoaq (buffer, size, ndigits - 1, tmp);
+#endif
+
 #define WRITE_FLOAT(x,y)\
 {\
 	GFC_REAL_ ## x tmp;\
@@ -1057,7 +1062,11 @@ write_float (st_parameter_dt *dtp, const
 #endif
 #ifdef HAVE_GFC_REAL_16
     case 16:
+# ifdef GFC_REAL_16_IS_FLOAT128
+      WRITE_FLOAT(16,Q)
+# else
       WRITE_FLOAT(16,L)
+# endif
       break;
 #endif
     default:
Index: libgfortran/Makefile.am
===================================================================
--- libgfortran/Makefile.am	(revision 163619)
+++ libgfortran/Makefile.am	(working copy)
@@ -30,12 +30,19 @@ version_arg =
 version_dep =
 endif
 
+# Compile and link with quad float library if present
+if GFOR_USE_QUAD_LIB
+quad_link = -lquad
+else
+quad_link =
+endif
+
 LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS)) \
 	    -no-undefined -bindir "$(bindir)"
 
 toolexeclib_LTLIBRARIES = libgfortran.la
 libgfortran_la_LINK = $(LINK) $(libgfortran_la_LDFLAGS)
-libgfortran_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(LTLDFLAGS) -lm $(extra_ldflags_libgfortran) $(version_arg)
+libgfortran_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(LTLDFLAGS) $(QUADLIBS) $(quad_link) -lm $(extra_ldflags_libgfortran) $(version_arg)
 libgfortran_la_DEPENDENCIES = $(version_dep)
 
 myexeclib_LTLIBRARIES = libgfortranbegin.la
@@ -48,7 +55,8 @@ libgfortranbegin_la_LINK = $(LINK) $(lib
 ## use -iquote
 AM_CPPFLAGS = -iquote$(srcdir)/io -I$(srcdir)/$(MULTISRCTOP)../gcc \
 	      -I$(srcdir)/$(MULTISRCTOP)../gcc/config \
-	      -I$(MULTIBUILDTOP)../../$(host_subdir)/gcc -D_GNU_SOURCE
+	      -I$(MULTIBUILDTOP)../../$(host_subdir)/gcc -D_GNU_SOURCE \
+	      $(QUADINC)
 
 # Fortran rules for complex multiplication and division
 AM_CFLAGS += -fcx-fortran-rules
Index: libgfortran/mk-kinds-h.sh
===================================================================
--- libgfortran/mk-kinds-h.sh	(revision 163619)
+++ libgfortran/mk-kinds-h.sh	(working copy)
@@ -44,7 +44,14 @@ echo "#define GFC_UINTEGER_LARGEST GFC_U
 echo "#define GFC_DEFAULT_CHAR ${smallest}"
 echo ""
 
-REAL_10_FOUND=
+
+# Get the kind value for long double, so we may disambiguate it
+# from __float128.
+echo "use iso_c_binding; print *, c_long_double ; end" > tmq$$.f90
+long_double_kind=`$compile -S -fdump-parse-tree tmq$$.f90 | grep TRANSFER \
+			| sed 's/ *TRANSFER *//'`
+rm -f tmq$$.*
+
 
 for k in $possible_real_kinds; do
   echo "  real (kind=$k) :: x" > tmp$$.f90
@@ -52,17 +59,18 @@ for k in $possible_real_kinds; do
   echo "  end" >> tmp$$.f90
   if $compile -S tmp$$.f90 > /dev/null 2>&1; then
     case $k in
-      4) ctype="float" ; suffix="f" ;;
-      8) ctype="double" ; suffix="" ;;
-      10) ctype="long double" ; suffix="l" ; REAL_10_FOUND=1 ;;
-      16) ctype="long double"
-	  suffix="l"
-	  # Disable REAL(16) if it is just __float128
-	  # until the library is fixed
-	  if [ -n "$REAL_10_FOUND" ]; then
-	    continue
-	  fi
-	  ;;
+      4) ctype="float" ; cplxtype="complex float" ; suffix="f" ;;
+      8) ctype="double" ; cplxtype="complex double" ; suffix="" ;;
+      10) ctype="long double" ; cplxtype="complex long double" ; suffix="l" ;;
+      16) if [ $long_double_kind -eq 10 ]; then
+	    ctype="__float128"
+	    cplxtype="_Complex float __attribute__((mode(TC)))"
+	    suffix="q"
+	  else
+	    ctype="long double"
+	    cplxtype="complex long double"
+	    suffix="l"
+	  fi ;;
       *) echo "$0: Unknown type" >&2 ; exit 1 ;;
     esac
 
@@ -86,7 +94,7 @@ for k in $possible_real_kinds; do
 
     # Output the information we've gathered
     echo "typedef ${ctype} GFC_REAL_${k};"
-    echo "typedef complex ${ctype} GFC_COMPLEX_${k};"
+    echo "typedef ${cplxtype} GFC_COMPLEX_${k};"
     echo "#define HAVE_GFC_REAL_${k}"
     echo "#define HAVE_GFC_COMPLEX_${k}"
     echo "#define GFC_REAL_${k}_HUGE ${huge}${suffix}"

^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2010-08-31  4:32 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-08-30  1:55 For testing: full __float128 patch Uros Bizjak
2010-08-30  1:59 ` Steve Kargl
2010-08-30  7:42   ` Uros Bizjak
2010-08-30 10:46     ` Gerald Pfeifer
2010-08-30 16:48       ` Gerald Pfeifer
2010-08-30 17:34         ` Joseph S. Myers
2010-08-30 17:43           ` Uros Bizjak
2010-08-30 18:27             ` Richard Henderson
2010-08-30 19:25               ` Uros Bizjak
2010-08-30 19:38                 ` Uros Bizjak
2010-08-30 19:51                   ` Richard Henderson
2010-08-30 19:54                   ` Jakub Jelinek
2010-08-30 22:29                     ` Uros Bizjak
2010-08-31  4:32                       ` Steve Kargl
2010-08-31  7:10                         ` Steve Kargl
2010-08-31  3:37                   ` Joseph S. Myers
2010-08-30 17:37     ` Steve Kargl
  -- strict thread matches above, loose matches on Subject: below --
2010-08-29  0:57 FX
2010-08-29  1:48 ` Steve Kargl
2010-08-29  7:03   ` Steve Kargl
2010-08-29 11:43     ` Steve Kargl
2010-08-29 12:02     ` FX
2010-08-29 20:48       ` Steve Kargl

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).