From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 3773 invoked by alias); 28 Aug 2010 23:25:00 -0000 Received: (qmail 3756 invoked by uid 22791); 28 Aug 2010 23:24:59 -0000 X-SWARE-Spam-Status: No, hits=-0.8 required=5.0 tests=AWL,BAYES_20,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE,TW_GD,TW_IB X-Spam-Check-By: sourceware.org Received: from mail-ww0-f51.google.com (HELO mail-ww0-f51.google.com) (74.125.82.51) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sat, 28 Aug 2010 23:24:53 +0000 Received: by wwb39 with SMTP id 39so1850237wwb.8 for ; Sat, 28 Aug 2010 16:24:50 -0700 (PDT) Received: by 10.227.136.129 with SMTP id r1mr2833018wbt.114.1283037890091; Sat, 28 Aug 2010 16:24:50 -0700 (PDT) Received: from [192.168.0.101] (chufi.coudert.name [88.162.139.106]) by mx.google.com with ESMTPS id b23sm4811800wbb.4.2010.08.28.16.24.48 (version=TLSv1/SSLv3 cipher=RC4-MD5); Sat, 28 Aug 2010 16:24:49 -0700 (PDT) From: FX Content-Type: multipart/mixed; boundary=Apple-Mail-54--211990757 Subject: For testing: full __float128 patch Date: Sun, 29 Aug 2010 00:57:00 -0000 Message-Id: <371798FD-2297-422F-9301-39344E88E4AE@gmail.com> To: Fortran List , gcc@gcc.gnu.org Mime-Version: 1.0 (Apple Message framework v1081) Mailing-List: contact gcc-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-owner@gcc.gnu.org X-SW-Source: 2010-08/txt/msg00431.txt.bz2 --Apple-Mail-54--211990757 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii Content-length: 2403 Before I submit it officially for review, I want this patch to get some exp= osure 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.bz= 2 , then ./configure --prefix=3D/foo && make && make install=20 -- Build GCC with the extra configure argument: --with-quad=3D/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-ins= ensitive, 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 c= ode, 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 TFm= ode 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 b= y the front-end (all exponentiations involving __float128 or its complex co= unterpart give wrong code); I'll work on a fix -- Array intrinsics *do not work at all*. This is a limitation of the arr= ay descriptor structure, which I cannot overcome by myself. The current pat= ch only changes these files (in_pack_generic.c, in_unpack_generic.c, pack_g= eneric.c, spread_generic.c, unpack_generic.c, cshift0.c) to make them compi= le, but they will yield wrong results. -- the integration of libquad depends on how the discussion with the SC t= urns out; the current scheme is not nice at all in case of multilibs, see b= elow Please note: in case of a multilib build, unless you have a system which su= pports fat libraries (MacOS), only the variant that corresponds to the libq= uad you've built will have support enabled. Typically, on a x86_64 system w= here you've built libquad with the default 64-bit compiler, you'll only hav= e libquad support in the -m64 variant of libgfortran, and not the -m32 vari= ant. All comment are of course welcome. I think the two preliminary commits allo= wed to keep the size of this final patch to a reasonable value under 1kLOC = (less than 600 without regenerated files). FX --Apple-Mail-54--211990757 Content-Disposition: attachment; filename=full_testing.diff Content-Type: application/octet-stream; name="full_testing.diff" Content-Transfer-Encoding: 7bit Content-length: 28985 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 + +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 header file. */ #undef HAVE_FENV_H +/* Define if have a __float128 type. */ +#undef HAVE_FLOAT128 + /* Define to 1 if you have the 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 +],[ + __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}" --Apple-Mail-54--211990757--