aboutsummaryrefslogtreecommitdiff
path: root/libgfortran
diff options
context:
space:
mode:
authorFrancois-Xavier Coudert <fxcoudert@gcc.gnu.org>2010-11-16 21:23:19 +0000
committerTobias Burnus <burnus@gcc.gnu.org>2010-11-16 22:23:19 +0100
commit1ec601bf9fb0fbc39b3a6cb90450500f857adae8 (patch)
treee26ad385cfada5f1f2c55f92057a0259de8b98d2 /libgfortran
parent07078664fd6fdcb046cee4adf01ee697e56fcbd3 (diff)
downloadgcc-1ec601bf9fb0fbc39b3a6cb90450500f857adae8.zip
gcc-1ec601bf9fb0fbc39b3a6cb90450500f857adae8.tar.gz
gcc-1ec601bf9fb0fbc39b3a6cb90450500f857adae8.tar.bz2
re PR fortran/32049 (Support on x86_64 also kind=16)
/ 2010-11-13 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> Tobias Burnus <burnus@net-b.de> PR fortran/32049 * Makefile.def: Add libquadmath; build it with language=fortran. * configure.ac: Add libquadmath. * Makefile.tpl: Handle multiple libs in check-[+language+]. * Makefile.in: Regenerate. * configure: Regenerate. libquadmath/ 2010-11-13 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> Tobias Burnus <burnus@net-b.de> PR fortran/32049 Initial implementation and checkin. gcc/fortran/ 2010-11-13 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> Tobias Burnus <burnus@net-b.de> PR fortran/32049 * gfortranspec.c (find_spec_file): New function. (lang_specific_driver): Try to find .spec file and use it. * trans-io.c (iocall): Define * IOCALL_X_REAL128/COMPLEX128(,write). (gfc_build_io_library_fndecls): Build decl for __float128 I/O. (transfer_expr): Call __float128 I/O functions. * trans-types.c (gfc_init_kinds): Allow kind-16 belonging to __float128. gcc/testsuite/ 2010-11-13 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> Tobias Burnus <burnus@net-b.de> PR fortran/32049 * gfortran.dg/quad_1.f90: New. * lib/gcc-defs.exp (gcc-set-multilib-library-path): Use also compiler arguments. * lib/gfortran.exp (gfortran_link_flags): Add libquadmath to library search path; call gcc-set-multilib-library-path with arguments such that libgfortran.spec is found. (gfortran_init): Add path for libgfortran.spec to GFORTRAN_UNDER_TEST. libgomp/ 2010-11-13 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> Tobias Burnus <burnus@net-b.de> PR fortran/32049 * configure.ac: * configure: Regenerate. libgfortran/ 2010-11-13 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> Tobias Burnus <burnus@net-b.de> PR fortran/32049 * Makefile.am: Add missing pow_r16_i4.c, add transfer128.c, link libquadmath, if used. * acinclude.m4 (LIBGFOR_CHECK_FLOAT128): Add. * configure.ac: Use it, touch spec file. * gfortran.map: Add pow_r16_i4 and transfer_(real,complex)128(,write) functions. * intrinsics/cshift0.c (cshift0): Handle __float128 type. * intrinsics/erfc_scaled_inc.c: Ditto. * intrinsics/pack_generic.c (pack): Ditto * intrinsics/spread_generic.c (spread): Ditto. * intrinsics/unpack_generic.c (unpack1): Ditto. * io/read.c (convert_real): Ditto. * io/transfer.c: Update comments. * io/transfer128.c: New file. * io/write_float.def (write_float): Handle __float128 type. * libgfortran.h: #include quadmath_weak.h, define __builtin_infq and nanq. * m4/mtype.m4: Handle __float128 type. * runtime/in_pack_generic.c (internal_pack): Ditto. * runtime/in_unpack_generic.c (internal_unpack): Ditto. * kinds-override.h: New file. * libgfortran.spec.in: Ditto. * generated/pow_r16_i4.c: Generated. * Makefile.in: Regenerate. * configure: Regenerate. * config.h: Regenerate. * bessel_r10.c: Regenerate. * bessel_r16.c: Regenerate. * bessel_r4.c: Regenerate. * bessel_r8.c: Regenerate. * exponent_r16.c: Regenerate. * fraction_r16.c: Regenerate. * nearest_r16.c: Regenerate. * norm2_r10.c: Regenerate. * norm2_r16.c: Regenerate. * norm2_r4.c: Regenerate. * norm2_r8.c: Regenerate. * rrspacing_r16.c: Regenerate. * set_exponent_r16.c: Regenerate. * spacing_r16.c: Regenerate. Co-Authored-By: Tobias Burnus <burnus@net-b.de> From-SVN: r166825
Diffstat (limited to 'libgfortran')
-rw-r--r--libgfortran/ChangeLog45
-rw-r--r--libgfortran/Makefile.am9
-rw-r--r--libgfortran/Makefile.in90
-rw-r--r--libgfortran/acinclude.m476
-rw-r--r--libgfortran/config.h.in3
-rwxr-xr-xlibgfortran/configure148
-rw-r--r--libgfortran/configure.ac13
-rw-r--r--libgfortran/generated/bessel_r10.c1
-rw-r--r--libgfortran/generated/bessel_r16.c9
-rw-r--r--libgfortran/generated/bessel_r4.c1
-rw-r--r--libgfortran/generated/bessel_r8.c1
-rw-r--r--libgfortran/generated/exponent_r16.c2
-rw-r--r--libgfortran/generated/fraction_r16.c2
-rw-r--r--libgfortran/generated/nearest_r16.c2
-rw-r--r--libgfortran/generated/norm2_r10.c1
-rw-r--r--libgfortran/generated/norm2_r16.c7
-rw-r--r--libgfortran/generated/norm2_r4.c1
-rw-r--r--libgfortran/generated/norm2_r8.c1
-rw-r--r--libgfortran/generated/pow_r16_i4.c75
-rw-r--r--libgfortran/generated/rrspacing_r16.c4
-rw-r--r--libgfortran/generated/set_exponent_r16.c2
-rw-r--r--libgfortran/generated/spacing_r16.c4
-rw-r--r--libgfortran/gfortran.map5
-rw-r--r--libgfortran/intrinsics/cshift0.c28
-rw-r--r--libgfortran/intrinsics/erfc_scaled_inc.c11
-rw-r--r--libgfortran/intrinsics/pack_generic.c28
-rw-r--r--libgfortran/intrinsics/spread_generic.c56
-rw-r--r--libgfortran/intrinsics/unpack_generic.c56
-rw-r--r--libgfortran/io/read.c8
-rw-r--r--libgfortran/io/transfer.c20
-rw-r--r--libgfortran/io/transfer128.c108
-rw-r--r--libgfortran/io/write.c1
-rw-r--r--libgfortran/io/write_float.def11
-rw-r--r--libgfortran/kinds-override.h46
-rw-r--r--libgfortran/libgfortran.h18
-rw-r--r--libgfortran/libgfortran.spec.in8
-rw-r--r--libgfortran/m4/mtype.m42
-rwxr-xr-xlibgfortran/mk-kinds-h.sh39
-rw-r--r--libgfortran/runtime/in_pack_generic.c29
-rw-r--r--libgfortran/runtime/in_unpack_generic.c31
40 files changed, 891 insertions, 111 deletions
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog
index bfbf015..51dacdd 100644
--- a/libgfortran/ChangeLog
+++ b/libgfortran/ChangeLog
@@ -1,3 +1,48 @@
+2010-11-16 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+ Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/32049
+ * Makefile.am: Add missing pow_r16_i4.c, add transfer128.c,
+ link libquadmath, if used.
+ * acinclude.m4 (LIBGFOR_CHECK_FLOAT128): Add.
+ * configure.ac: Use it, touch spec file.
+ * gfortran.map: Add pow_r16_i4 and
+ transfer_(real,complex)128(,write) functions.
+ * intrinsics/cshift0.c (cshift0): Handle __float128 type.
+ * intrinsics/erfc_scaled_inc.c: Ditto.
+ * intrinsics/pack_generic.c (pack): Ditto
+ * intrinsics/spread_generic.c (spread): Ditto.
+ * intrinsics/unpack_generic.c (unpack1): Ditto.
+ * io/read.c (convert_real): Ditto.
+ * io/transfer.c: Update comments.
+ * io/transfer128.c: New file.
+ * io/write_float.def (write_float): Handle __float128 type.
+ * libgfortran.h: #include quadmath_weak.h, define __builtin_infq
+ and nanq.
+ * m4/mtype.m4: Handle __float128 type.
+ * runtime/in_pack_generic.c (internal_pack): Ditto.
+ * runtime/in_unpack_generic.c (internal_unpack): Ditto.
+ * kinds-override.h: New file.
+ * libgfortran.spec.in: Ditto.
+ * generated/pow_r16_i4.c: Generated.
+ * Makefile.in: Regenerate.
+ * configure: Regenerate.
+ * config.h: Regenerate.
+ * bessel_r10.c: Regenerate.
+ * bessel_r16.c: Regenerate.
+ * bessel_r4.c: Regenerate.
+ * bessel_r8.c: Regenerate.
+ * exponent_r16.c: Regenerate.
+ * fraction_r16.c: Regenerate.
+ * nearest_r16.c: Regenerate.
+ * norm2_r10.c: Regenerate.
+ * norm2_r16.c: Regenerate.
+ * norm2_r4.c: Regenerate.
+ * norm2_r8.c: Regenerate.
+ * rrspacing_r16.c: Regenerate.
+ * set_exponent_r16.c: Regenerate.
+ * spacing_r16.c: Regenerate.
+
2010-11-09 Janne Blomqvist <jb@gcc.gnu.org>
* io/unix.c (struct unix_stream): Add st_dev and st_ino members.
diff --git a/libgfortran/Makefile.am b/libgfortran/Makefile.am
index 2952f99..d9e6c64 100644
--- a/libgfortran/Makefile.am
+++ b/libgfortran/Makefile.am
@@ -34,9 +34,10 @@ LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS)) \
-no-undefined -bindir "$(bindir)"
toolexeclib_LTLIBRARIES = libgfortran.la
+toolexeclib_DATA = libgfortran.spec
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_DEPENDENCIES = $(version_dep)
+libgfortran_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(LTLDFLAGS) $(LIBQUADLIB) -lm $(extra_ldflags_libgfortran) $(version_arg)
+libgfortran_la_DEPENDENCIES = $(version_dep) libgfortran.spec $(LIBQUADLIB_DEP)
myexeclib_LTLIBRARIES = libgfortranbegin.la
myexeclibdir = $(libdir)/gcc/$(target_alias)/$(gcc_version)$(MULTISUBDIR)
@@ -47,7 +48,7 @@ libgfortranbegin_la_LINK = $(LINK) $(libgfortranbegin_la_LDFLAGS)
## io.h conflicts with a system header on some platforms, so
## use -iquote
AM_CPPFLAGS = -iquote$(srcdir)/io -I$(srcdir)/$(MULTISRCTOP)../gcc \
- -I$(srcdir)/$(MULTISRCTOP)../gcc/config \
+ -I$(srcdir)/$(MULTISRCTOP)../gcc/config $(LIBQUADINCLUDE) \
-I$(MULTIBUILDTOP)../../$(host_subdir)/gcc -D_GNU_SOURCE
# Fortran rules for complex multiplication and division
@@ -71,6 +72,7 @@ io/open.c \
io/read.c \
io/size_from_kind.c \
io/transfer.c \
+io/transfer128.c \
io/unit.c \
io/unix.c \
io/write.c \
@@ -543,6 +545,7 @@ i_pow_c = \
$(srcdir)/generated/pow_i4_i4.c \
$(srcdir)/generated/pow_i8_i4.c \
$(srcdir)/generated/pow_i16_i4.c \
+$(srcdir)/generated/pow_r16_i4.c \
$(srcdir)/generated/pow_c4_i4.c \
$(srcdir)/generated/pow_c8_i4.c \
$(srcdir)/generated/pow_c10_i4.c \
diff --git a/libgfortran/Makefile.in b/libgfortran/Makefile.in
index e6be1c1..da68aef 100644
--- a/libgfortran/Makefile.in
+++ b/libgfortran/Makefile.in
@@ -15,6 +15,7 @@
@SET_MAKE@
+
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
@@ -42,7 +43,7 @@ subdir = .
DIST_COMMON = ChangeLog $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/configure $(am__configure_deps) \
$(srcdir)/config.h.in $(srcdir)/../mkinstalldirs \
- $(srcdir)/../depcomp
+ $(srcdir)/libgfortran.spec.in $(srcdir)/../depcomp
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/../config/depstand.m4 \
$(top_srcdir)/../config/lead-dot.m4 \
@@ -60,7 +61,7 @@ am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
configure.lineno config.status.lineno
mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
CONFIG_HEADER = config.h
-CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_FILES = libgfortran.spec
CONFIG_CLEAN_VPATH_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
@@ -84,7 +85,7 @@ am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__installdirs = "$(DESTDIR)$(myexeclibdir)" \
- "$(DESTDIR)$(toolexeclibdir)"
+ "$(DESTDIR)$(toolexeclibdir)" "$(DESTDIR)$(toolexeclibdir)"
LTLIBRARIES = $(myexeclib_LTLIBRARIES) $(toolexeclib_LTLIBRARIES)
libgfortran_la_LIBADD =
am__objects_1 = backtrace.lo bounds.lo compile_options.lo \
@@ -186,14 +187,14 @@ am__objects_31 = nearest_r4.lo nearest_r8.lo nearest_r10.lo \
nearest_r16.lo
am__objects_32 = set_exponent_r4.lo set_exponent_r8.lo \
set_exponent_r10.lo set_exponent_r16.lo
-am__objects_33 = pow_i4_i4.lo pow_i8_i4.lo pow_i16_i4.lo pow_c4_i4.lo \
- pow_c8_i4.lo pow_c10_i4.lo pow_c16_i4.lo pow_i4_i8.lo \
- pow_i8_i8.lo pow_i16_i8.lo pow_r4_i8.lo pow_r8_i8.lo \
- pow_r10_i8.lo pow_r16_i8.lo pow_c4_i8.lo pow_c8_i8.lo \
- pow_c10_i8.lo pow_c16_i8.lo pow_i4_i16.lo pow_i8_i16.lo \
- pow_i16_i16.lo pow_r4_i16.lo pow_r8_i16.lo pow_r10_i16.lo \
- pow_r16_i16.lo pow_c4_i16.lo pow_c8_i16.lo pow_c10_i16.lo \
- pow_c16_i16.lo
+am__objects_33 = pow_i4_i4.lo pow_i8_i4.lo pow_i16_i4.lo pow_r16_i4.lo \
+ pow_c4_i4.lo pow_c8_i4.lo pow_c10_i4.lo pow_c16_i4.lo \
+ pow_i4_i8.lo pow_i8_i8.lo pow_i16_i8.lo pow_r4_i8.lo \
+ pow_r8_i8.lo pow_r10_i8.lo pow_r16_i8.lo pow_c4_i8.lo \
+ pow_c8_i8.lo pow_c10_i8.lo pow_c16_i8.lo pow_i4_i16.lo \
+ pow_i8_i16.lo pow_i16_i16.lo pow_r4_i16.lo pow_r8_i16.lo \
+ pow_r10_i16.lo pow_r16_i16.lo pow_c4_i16.lo pow_c8_i16.lo \
+ pow_c10_i16.lo pow_c16_i16.lo
am__objects_34 = rrspacing_r4.lo rrspacing_r8.lo rrspacing_r10.lo \
rrspacing_r16.lo
am__objects_35 = spacing_r4.lo spacing_r8.lo spacing_r10.lo \
@@ -228,7 +229,8 @@ am__objects_40 = $(am__objects_2) $(am__objects_3) $(am__objects_4) \
$(am__objects_38) $(am__objects_39)
am__objects_41 = close.lo file_pos.lo format.lo inquire.lo \
intrinsics.lo list_read.lo lock.lo open.lo read.lo \
- size_from_kind.lo transfer.lo unit.lo unix.lo write.lo fbuf.lo
+ size_from_kind.lo transfer.lo transfer128.lo unit.lo unix.lo \
+ write.lo fbuf.lo
am__objects_42 = associated.lo abort.lo access.lo args.lo \
bit_intrinsics.lo c99_functions.lo chdir.lo chmod.lo clock.lo \
cpu_time.lo cshift0.lo ctime.lo date_and_time.lo dtime.lo \
@@ -318,6 +320,7 @@ MULTIDIRS =
MULTISUBDIR =
MULTIDO = true
MULTICLEAN = true
+DATA = $(toolexeclib_DATA)
ETAGS = etags
CTAGS = ctags
ACLOCAL = @ACLOCAL@
@@ -366,6 +369,10 @@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
+LIBQUADINCLUDE = @LIBQUADINCLUDE@
+LIBQUADLIB = @LIBQUADLIB@
+LIBQUADLIB_DEP = @LIBQUADLIB_DEP@
+LIBQUADSPEC = @LIBQUADSPEC@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
@@ -474,16 +481,17 @@ LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS)) \
-no-undefined -bindir "$(bindir)"
toolexeclib_LTLIBRARIES = libgfortran.la
+toolexeclib_DATA = libgfortran.spec
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_DEPENDENCIES = $(version_dep)
+libgfortran_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(LTLDFLAGS) $(LIBQUADLIB) -lm $(extra_ldflags_libgfortran) $(version_arg)
+libgfortran_la_DEPENDENCIES = $(version_dep) libgfortran.spec $(LIBQUADLIB_DEP)
myexeclib_LTLIBRARIES = libgfortranbegin.la
myexeclibdir = $(libdir)/gcc/$(target_alias)/$(gcc_version)$(MULTISUBDIR)
libgfortranbegin_la_SOURCES = fmain.c
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$(srcdir)/$(MULTISRCTOP)../gcc/config $(LIBQUADINCLUDE) \
-I$(MULTIBUILDTOP)../../$(host_subdir)/gcc -D_GNU_SOURCE
gfor_io_src = \
@@ -498,6 +506,7 @@ io/open.c \
io/read.c \
io/size_from_kind.c \
io/transfer.c \
+io/transfer128.c \
io/unit.c \
io/unix.c \
io/write.c \
@@ -969,6 +978,7 @@ i_pow_c = \
$(srcdir)/generated/pow_i4_i4.c \
$(srcdir)/generated/pow_i8_i4.c \
$(srcdir)/generated/pow_i16_i4.c \
+$(srcdir)/generated/pow_r16_i4.c \
$(srcdir)/generated/pow_c4_i4.c \
$(srcdir)/generated/pow_c8_i4.c \
$(srcdir)/generated/pow_c10_i4.c \
@@ -1295,6 +1305,8 @@ $(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
distclean-hdr:
-rm -f config.h stamp-h1
+libgfortran.spec: $(top_builddir)/config.status $(srcdir)/libgfortran.spec.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
install-myexeclibLTLIBRARIES: $(myexeclib_LTLIBRARIES)
@$(NORMAL_INSTALL)
test -z "$(myexeclibdir)" || $(MKDIR_P) "$(DESTDIR)$(myexeclibdir)"
@@ -1712,6 +1724,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pow_r10_i16.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pow_r10_i8.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pow_r16_i16.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pow_r16_i4.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pow_r16_i8.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pow_r4_i16.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pow_r4_i8.Plo@am__quote@
@@ -1804,6 +1817,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/system_clock.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/time.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/transfer.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/transfer128.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/transpose_c10.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/transpose_c16.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/transpose_c4.Plo@am__quote@
@@ -4401,6 +4415,13 @@ pow_i16_i4.lo: $(srcdir)/generated/pow_i16_i4.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 pow_i16_i4.lo `test -f '$(srcdir)/generated/pow_i16_i4.c' || echo '$(srcdir)/'`$(srcdir)/generated/pow_i16_i4.c
+pow_r16_i4.lo: $(srcdir)/generated/pow_r16_i4.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pow_r16_i4.lo -MD -MP -MF $(DEPDIR)/pow_r16_i4.Tpo -c -o pow_r16_i4.lo `test -f '$(srcdir)/generated/pow_r16_i4.c' || echo '$(srcdir)/'`$(srcdir)/generated/pow_r16_i4.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pow_r16_i4.Tpo $(DEPDIR)/pow_r16_i4.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(srcdir)/generated/pow_r16_i4.c' object='pow_r16_i4.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 pow_r16_i4.lo `test -f '$(srcdir)/generated/pow_r16_i4.c' || echo '$(srcdir)/'`$(srcdir)/generated/pow_r16_i4.c
+
pow_c4_i4.lo: $(srcdir)/generated/pow_c4_i4.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pow_c4_i4.lo -MD -MP -MF $(DEPDIR)/pow_c4_i4.Tpo -c -o pow_c4_i4.lo `test -f '$(srcdir)/generated/pow_c4_i4.c' || echo '$(srcdir)/'`$(srcdir)/generated/pow_c4_i4.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pow_c4_i4.Tpo $(DEPDIR)/pow_c4_i4.Plo
@@ -5080,6 +5101,13 @@ transfer.lo: io/transfer.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 transfer.lo `test -f 'io/transfer.c' || echo '$(srcdir)/'`io/transfer.c
+transfer128.lo: io/transfer128.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT transfer128.lo -MD -MP -MF $(DEPDIR)/transfer128.Tpo -c -o transfer128.lo `test -f 'io/transfer128.c' || echo '$(srcdir)/'`io/transfer128.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/transfer128.Tpo $(DEPDIR)/transfer128.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io/transfer128.c' object='transfer128.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 transfer128.lo `test -f 'io/transfer128.c' || echo '$(srcdir)/'`io/transfer128.c
+
unit.lo: io/unit.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unit.lo -MD -MP -MF $(DEPDIR)/unit.Tpo -c -o unit.lo `test -f 'io/unit.c' || echo '$(srcdir)/'`io/unit.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/unit.Tpo $(DEPDIR)/unit.Plo
@@ -5578,6 +5606,26 @@ distclean-multi:
$(MULTICLEAN) $(AM_MAKEFLAGS) DO=distclean multi-clean # $(MAKE)
maintainer-clean-multi:
$(MULTICLEAN) $(AM_MAKEFLAGS) DO=maintainer-clean multi-clean # $(MAKE)
+install-toolexeclibDATA: $(toolexeclib_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(toolexeclibdir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibdir)"
+ @list='$(toolexeclib_DATA)'; test -n "$(toolexeclibdir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(toolexeclibdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(toolexeclibdir)" || exit $$?; \
+ done
+
+uninstall-toolexeclibDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(toolexeclib_DATA)'; test -n "$(toolexeclibdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ test -n "$$files" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(toolexeclibdir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(toolexeclibdir)" && rm -f $$files
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
@@ -5633,9 +5681,9 @@ distclean-tags:
check-am: all-am
check: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) check-am
-all-am: Makefile $(LTLIBRARIES) all-multi config.h
+all-am: Makefile $(LTLIBRARIES) all-multi $(DATA) config.h
installdirs:
- for dir in "$(DESTDIR)$(myexeclibdir)" "$(DESTDIR)$(toolexeclibdir)"; do \
+ for dir in "$(DESTDIR)$(myexeclibdir)" "$(DESTDIR)$(toolexeclibdir)" "$(DESTDIR)$(toolexeclibdir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: $(BUILT_SOURCES)
@@ -5696,7 +5744,7 @@ install-dvi: install-dvi-am
install-dvi-am:
install-exec-am: install-multi install-myexeclibLTLIBRARIES \
- install-toolexeclibLTLIBRARIES
+ install-toolexeclibDATA install-toolexeclibLTLIBRARIES
install-html: install-html-am
@@ -5738,7 +5786,7 @@ ps: ps-am
ps-am:
-uninstall-am: uninstall-myexeclibLTLIBRARIES \
+uninstall-am: uninstall-myexeclibLTLIBRARIES uninstall-toolexeclibDATA \
uninstall-toolexeclibLTLIBRARIES
.MAKE: all all-multi check clean-multi distclean-multi install \
@@ -5755,13 +5803,13 @@ uninstall-am: uninstall-myexeclibLTLIBRARIES \
install-exec-am install-html install-html-am install-info \
install-info-am install-man install-multi \
install-myexeclibLTLIBRARIES install-pdf install-pdf-am \
- install-ps install-ps-am install-strip \
+ install-ps install-ps-am install-strip install-toolexeclibDATA \
install-toolexeclibLTLIBRARIES installcheck installcheck-am \
installdirs maintainer-clean maintainer-clean-generic \
maintainer-clean-multi mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool mostlyclean-multi pdf \
pdf-am ps ps-am tags uninstall uninstall-am \
- uninstall-myexeclibLTLIBRARIES \
+ uninstall-myexeclibLTLIBRARIES uninstall-toolexeclibDATA \
uninstall-toolexeclibLTLIBRARIES
@LIBGFOR_USE_SYMVER_SUN_TRUE@@LIBGFOR_USE_SYMVER_TRUE@gfortran.map-sun : $(srcdir)/gfortran.map \
diff --git a/libgfortran/acinclude.m4 b/libgfortran/acinclude.m4
index 09cd292..cb016f1 100644
--- a/libgfortran/acinclude.m4
+++ b/libgfortran/acinclude.m4
@@ -275,3 +275,79 @@ 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], [
+ LIBQUADSPEC=
+ AC_CACHE_CHECK([whether we have a usable __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;
+ z1 /= 7.Q;
+],
+ libgfor_cv_have_float128=yes,
+ libgfor_cv_have_float128=no)
+ ])
+
+ if test "x$libgfor_cv_have_float128" = xyes; then
+ AC_DEFINE(HAVE_FLOAT128, 1, [Define if have a usable __float128 type.])
+
+ dnl Check whether -Wl,--as-needed is supported
+ dnl
+ dnl Turn warnings into error to avoid testsuite breakage. So enable
+ dnl AC_LANG_WERROR, but there's currently (autoconf 2.64) no way to turn
+ dnl it off again. As a workaround, save and restore werror flag like
+ dnl AC_PATH_XTRA.
+ dnl Cf. http://gcc.gnu.org/ml/gcc-patches/2010-05/msg01889.html
+ ac_xsave_[]_AC_LANG_ABBREV[]_werror_flag=$ac_[]_AC_LANG_ABBREV[]_werror_flag
+ AC_CACHE_CHECK([whether --as-needed works],
+ [libgfor_cv_have_as_needed],
+ [
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -Wl,--as-needed -lm -Wl,--no-as-needed"
+ libgfor_cv_have_as_needed=no
+ AC_LANG_WERROR
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([])],
+ [libgfor_cv_have_as_needed=yes],
+ [libgfor_cv_have_as_needed=no])
+ LDFLAGS="$save_LDFLAGS"
+ ac_[]_AC_LANG_ABBREV[]_werror_flag=$ac_xsave_[]_AC_LANG_ABBREV[]_werror_flag
+ ])
+
+ dnl For static libgfortran linkage, depend on libquadmath only if needed.
+ if test "x$libgfor_cv_have_as_needed" = xyes; then
+ LIBQUADSPEC="%{static-libgfortran:--as-needed} -lquadmath %{static-libgfortran:--no-as-needed}"
+ else
+ LIBQUADSPEC="-lquadmath"
+ fi
+ if test -f ../libquadmath/libquadmath.la; then
+ LIBQUADLIB=../libquadmath/libquadmath.la
+ LIBQUADLIB_DEP=../libquadmath/libquadmath.la
+ LIBQUADINCLUDE='-I$(srcdir)/../libquadmath'
+ else
+ LIBQUADLIB="-lquadmath"
+ LIBQUADLIB_DEP=
+ LIBQUADINCLUDE=
+ fi
+ fi
+
+ dnl For the spec file
+ AC_SUBST(LIBQUADSPEC)
+ AC_SUBST(LIBQUADLIB)
+ AC_SUBST(LIBQUADLIB_DEP)
+ AC_SUBST(LIBQUADINCLUDE)
+
+ dnl We need a conditional for the Makefile
+ AM_CONDITIONAL(LIBGFOR_BUILD_QUAD, [test "x$libgfor_cv_have_float128" = xyes])
+])
diff --git a/libgfortran/config.h.in b/libgfortran/config.h.in
index f5f367f..bd6db10 100644
--- a/libgfortran/config.h.in
+++ b/libgfortran/config.h.in
@@ -381,6 +381,9 @@
/* Define to 1 if you have the <fenv.h> header file. */
#undef HAVE_FENV_H
+/* Define if have a usable __float128 type. */
+#undef HAVE_FLOAT128
+
/* Define to 1 if you have the <floatingpoint.h> header file. */
#undef HAVE_FLOATINGPOINT_H
diff --git a/libgfortran/configure b/libgfortran/configure
index cf2b587..a9d8092 100755
--- a/libgfortran/configure
+++ b/libgfortran/configure
@@ -597,12 +597,19 @@ ac_includes_default="\
# include <unistd.h>
#endif"
+ac_c_werror_flag=
ac_subst_vars='am__EXEEXT_FALSE
am__EXEEXT_TRUE
LTLIBOBJS
LIBOBJS
IEEE_FLAGS
FPU_HOST_HEADER
+LIBGFOR_BUILD_QUAD_FALSE
+LIBGFOR_BUILD_QUAD_TRUE
+LIBQUADINCLUDE
+LIBQUADLIB_DEP
+LIBQUADLIB
+LIBQUADSPEC
extra_ldflags_libgfortran
ac_ct_FC
FCFLAGS
@@ -3408,6 +3415,9 @@ esac
+# Create a spec file, so that compile/link tests don't fail
+test -f libgfortran.spec || touch libgfortran.spec
+
# Check the compiler.
# The same as in boehm-gc and libstdc++. Have to borrow it from there.
# We must force CC to /not/ be precious variables; otherwise
@@ -11362,7 +11372,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 11375 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -11468,7 +11478,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 11481 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -24286,6 +24296,131 @@ $as_echo "#define HAVE_BROKEN_POWF 1" >>confdefs.h
fi
+# Check whether we have a __float128 type
+
+ LIBQUADSPEC=
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we have a usable __float128 type" >&5
+$as_echo_n "checking whether we have a usable __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;
+ z1 /= 7.Q;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ libgfor_cv_have_float128=yes
+else
+ 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
+
+
+ ac_xsave_c_werror_flag=$ac_c_werror_flag
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether --as-needed works" >&5
+$as_echo_n "checking whether --as-needed works... " >&6; }
+if test "${libgfor_cv_have_as_needed+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -Wl,--as-needed -lm -Wl,--no-as-needed"
+ libgfor_cv_have_as_needed=no
+
+ac_c_werror_flag=yes
+ 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. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ libgfor_cv_have_as_needed=yes
+else
+ libgfor_cv_have_as_needed=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS="$save_LDFLAGS"
+ ac_c_werror_flag=$ac_xsave_c_werror_flag
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgfor_cv_have_as_needed" >&5
+$as_echo "$libgfor_cv_have_as_needed" >&6; }
+
+ if test "x$libgfor_cv_have_as_needed" = xyes; then
+ LIBQUADSPEC="%{static-libgfortran:--as-needed} -lquadmath %{static-libgfortran:--no-as-needed}"
+ else
+ LIBQUADSPEC="-lquadmath"
+ fi
+ if test -f ../libquadmath/libquadmath.la; then
+ LIBQUADLIB=../libquadmath/libquadmath.la
+ LIBQUADLIB_DEP=../libquadmath/libquadmath.la
+ LIBQUADINCLUDE='-I$(srcdir)/../libquadmath'
+ else
+ LIBQUADLIB="-lquadmath"
+ LIBQUADLIB_DEP=
+ LIBQUADINCLUDE=
+ fi
+ fi
+
+
+
+
+
+
+ if test "x$libgfor_cv_have_float128" = xyes; then
+ LIBGFOR_BUILD_QUAD_TRUE=
+ LIBGFOR_BUILD_QUAD_FALSE='#'
+else
+ LIBGFOR_BUILD_QUAD_TRUE='#'
+ LIBGFOR_BUILD_QUAD_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; }
@@ -24832,8 +24967,8 @@ else
multilib_arg=
fi
-# Write our Makefile.
-ac_config_files="$ac_config_files Makefile"
+# Write our Makefile and spec file.
+ac_config_files="$ac_config_files Makefile libgfortran.spec"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
@@ -24968,6 +25103,10 @@ if test -z "${LIBGFOR_USE_SYMVER_SUN_TRUE}" && test -z "${LIBGFOR_USE_SYMVER_SUN
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 "${LIBGFOR_BUILD_QUAD_TRUE}" && test -z "${LIBGFOR_BUILD_QUAD_FALSE}"; then
+ as_fn_error "conditional \"LIBGFOR_BUILD_QUAD\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
: ${CONFIG_STATUS=./config.status}
ac_write_fail=0
@@ -25961,6 +26100,7 @@ do
"libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
"gstdint.h") CONFIG_COMMANDS="$CONFIG_COMMANDS gstdint.h" ;;
"Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ "libgfortran.spec") CONFIG_FILES="$CONFIG_FILES libgfortran.spec" ;;
*) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
esac
diff --git a/libgfortran/configure.ac b/libgfortran/configure.ac
index e5517a1..47315d5 100644
--- a/libgfortran/configure.ac
+++ b/libgfortran/configure.ac
@@ -111,6 +111,9 @@ esac
AC_SUBST(toolexecdir)
AC_SUBST(toolexeclibdir)
+# Create a spec file, so that compile/link tests don't fail
+test -f libgfortran.spec || touch libgfortran.spec
+
# Check the compiler.
# The same as in boehm-gc and libstdc++. Have to borrow it from there.
# We must force CC to /not/ be precious variables; otherwise
@@ -459,6 +462,9 @@ 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 for GNU libc feenableexcept
AC_CHECK_LIB([m],[feenableexcept],[have_feenableexcept=yes AC_DEFINE([HAVE_FEENABLEEXCEPT],[1],[libm includes feenableexcept])])
@@ -509,6 +515,9 @@ else
multilib_arg=
fi
-# Write our Makefile.
-AC_CONFIG_FILES(Makefile)
+# Write our Makefile and spec file.
+AC_CONFIG_FILES([
+Makefile
+libgfortran.spec
+])
AC_OUTPUT
diff --git a/libgfortran/generated/bessel_r10.c b/libgfortran/generated/bessel_r10.c
index 93d08d6..87599fe 100644
--- a/libgfortran/generated/bessel_r10.c
+++ b/libgfortran/generated/bessel_r10.c
@@ -31,6 +31,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define MATHFUNC(funcname) funcname ## l
+#define BUILTINMATHFUNC(funcname) MATHFUNC(funcname)
#if defined (HAVE_GFC_REAL_10)
diff --git a/libgfortran/generated/bessel_r16.c b/libgfortran/generated/bessel_r16.c
index da9ab97..7097f6b 100644
--- a/libgfortran/generated/bessel_r16.c
+++ b/libgfortran/generated/bessel_r16.c
@@ -35,12 +35,17 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#else
#define MATHFUNC(funcname) funcname ## l
#endif
+#if defined(GFC_REAL_16_IS_FLOAT128)
+#define BUILTINMATHFUNC(funcname) funcname ## q
+#else
+#define BUILTINMATHFUNC(funcname) funcname ## l
+#endif
#if defined (HAVE_GFC_REAL_16)
-#if (defined(GFC_WITH_QUAD_LIB) || defined(HAVE_JNL))
+#if (defined(GFC_REAL_16_IS_FLOAT128) || defined(HAVE_JNL))
extern void bessel_jn_r16 (gfc_array_r16 * const restrict ret, int n1,
int n2, GFC_REAL_16 x);
export_proto(bessel_jn_r16);
@@ -107,7 +112,7 @@ bessel_jn_r16 (gfc_array_r16 * const restrict ret, int n1, int n2, GFC_REAL_16 x
#endif
-#if (defined(GFC_WITH_QUAD_LIB) || defined(HAVE_YNL))
+#if (defined(GFC_REAL_16_IS_FLOAT128) || defined(HAVE_YNL))
extern void bessel_yn_r16 (gfc_array_r16 * const restrict ret,
int n1, int n2, GFC_REAL_16 x);
export_proto(bessel_yn_r16);
diff --git a/libgfortran/generated/bessel_r4.c b/libgfortran/generated/bessel_r4.c
index 3d6e3ca..75d2ff0 100644
--- a/libgfortran/generated/bessel_r4.c
+++ b/libgfortran/generated/bessel_r4.c
@@ -31,6 +31,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define MATHFUNC(funcname) funcname ## f
+#define BUILTINMATHFUNC(funcname) MATHFUNC(funcname)
#if defined (HAVE_GFC_REAL_4)
diff --git a/libgfortran/generated/bessel_r8.c b/libgfortran/generated/bessel_r8.c
index 7e3bcab..899237b 100644
--- a/libgfortran/generated/bessel_r8.c
+++ b/libgfortran/generated/bessel_r8.c
@@ -31,6 +31,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define MATHFUNC(funcname) funcname
+#define BUILTINMATHFUNC(funcname) MATHFUNC(funcname)
#if defined (HAVE_GFC_REAL_8)
diff --git a/libgfortran/generated/exponent_r16.c b/libgfortran/generated/exponent_r16.c
index 899a2ae..24a115f 100644
--- a/libgfortran/generated/exponent_r16.c
+++ b/libgfortran/generated/exponent_r16.c
@@ -33,7 +33,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define MATHFUNC(funcname) funcname ## l
#endif
-#if defined (HAVE_GFC_REAL_16) && (defined(GFC_WITH_QUAD_LIB) || defined(HAVE_FREXPL))
+#if defined (HAVE_GFC_REAL_16) && (defined(GFC_REAL_16_IS_FLOAT128) || defined(HAVE_FREXPL))
extern GFC_INTEGER_4 exponent_r16 (GFC_REAL_16 s);
export_proto(exponent_r16);
diff --git a/libgfortran/generated/fraction_r16.c b/libgfortran/generated/fraction_r16.c
index 97e283d..1481485 100644
--- a/libgfortran/generated/fraction_r16.c
+++ b/libgfortran/generated/fraction_r16.c
@@ -33,7 +33,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define MATHFUNC(funcname) funcname ## l
#endif
-#if defined (HAVE_GFC_REAL_16) && (defined(GFC_WITH_QUAD_LIB) || defined(HAVE_FREXPL))
+#if defined (HAVE_GFC_REAL_16) && (defined(GFC_REAL_16_IS_FLOAT128) || defined(HAVE_FREXPL))
extern GFC_REAL_16 fraction_r16 (GFC_REAL_16 s);
export_proto(fraction_r16);
diff --git a/libgfortran/generated/nearest_r16.c b/libgfortran/generated/nearest_r16.c
index 474cf36..7a7f430 100644
--- a/libgfortran/generated/nearest_r16.c
+++ b/libgfortran/generated/nearest_r16.c
@@ -33,7 +33,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define MATHFUNC(funcname) funcname ## l
#endif
-#if defined (HAVE_GFC_REAL_16) && (defined(GFC_WITH_QUAD_LIB) || defined(HAVE_COPYSIGNL)) && (defined(GFC_WITH_QUAD_LIB) || defined(HAVE_NEXTAFTERL))
+#if defined (HAVE_GFC_REAL_16) && (defined(GFC_REAL_16_IS_FLOAT128) || defined(HAVE_COPYSIGNL)) && (defined(GFC_REAL_16_IS_FLOAT128) || defined(HAVE_NEXTAFTERL))
extern GFC_REAL_16 nearest_r16 (GFC_REAL_16 s, GFC_REAL_16 dir);
export_proto(nearest_r16);
diff --git a/libgfortran/generated/norm2_r10.c b/libgfortran/generated/norm2_r10.c
index 475a8cf..404cb1c 100644
--- a/libgfortran/generated/norm2_r10.c
+++ b/libgfortran/generated/norm2_r10.c
@@ -33,6 +33,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#if defined (HAVE_GFC_REAL_10) && defined (HAVE_GFC_REAL_10) && defined (HAVE_SQRTL) && defined (HAVE_FABSL)
#define MATHFUNC(funcname) funcname ## l
+#define BUILTINMATHFUNC(funcname) MATHFUNC(funcname)
extern void norm2_r10 (gfc_array_r10 * const restrict,
diff --git a/libgfortran/generated/norm2_r16.c b/libgfortran/generated/norm2_r16.c
index acd5779..100f2e7 100644
--- a/libgfortran/generated/norm2_r16.c
+++ b/libgfortran/generated/norm2_r16.c
@@ -30,13 +30,18 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
-#if defined (HAVE_GFC_REAL_16) && defined (HAVE_GFC_REAL_16) && (defined(GFC_WITH_QUAD_LIB) || defined(HAVE_SQRTL)) && (defined(GFC_WITH_QUAD_LIB) || defined(HAVE_FABSL))
+#if defined (HAVE_GFC_REAL_16) && defined (HAVE_GFC_REAL_16) && (defined(GFC_REAL_16_IS_FLOAT128) || defined(HAVE_SQRTL)) && (defined(GFC_REAL_16_IS_FLOAT128) || defined(HAVE_FABSL))
#if defined(GFC_REAL_16_IS_FLOAT128)
#define MATHFUNC(funcname) funcname ## q
#else
#define MATHFUNC(funcname) funcname ## l
#endif
+#if defined(GFC_REAL_16_IS_FLOAT128)
+#define BUILTINMATHFUNC(funcname) funcname ## q
+#else
+#define BUILTINMATHFUNC(funcname) funcname ## l
+#endif
extern void norm2_r16 (gfc_array_r16 * const restrict,
diff --git a/libgfortran/generated/norm2_r4.c b/libgfortran/generated/norm2_r4.c
index 83e034f..a86f76e 100644
--- a/libgfortran/generated/norm2_r4.c
+++ b/libgfortran/generated/norm2_r4.c
@@ -33,6 +33,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#if defined (HAVE_GFC_REAL_4) && defined (HAVE_GFC_REAL_4) && defined (HAVE_SQRTF) && defined (HAVE_FABSF)
#define MATHFUNC(funcname) funcname ## f
+#define BUILTINMATHFUNC(funcname) MATHFUNC(funcname)
extern void norm2_r4 (gfc_array_r4 * const restrict,
diff --git a/libgfortran/generated/norm2_r8.c b/libgfortran/generated/norm2_r8.c
index 88599e8..14487e8 100644
--- a/libgfortran/generated/norm2_r8.c
+++ b/libgfortran/generated/norm2_r8.c
@@ -33,6 +33,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#if defined (HAVE_GFC_REAL_8) && defined (HAVE_GFC_REAL_8) && defined (HAVE_SQRT) && defined (HAVE_FABS)
#define MATHFUNC(funcname) funcname
+#define BUILTINMATHFUNC(funcname) MATHFUNC(funcname)
extern void norm2_r8 (gfc_array_r8 * const restrict,
diff --git a/libgfortran/generated/pow_r16_i4.c b/libgfortran/generated/pow_r16_i4.c
new file mode 100644
index 0000000..bba2a84
--- /dev/null
+++ b/libgfortran/generated/pow_r16_i4.c
@@ -0,0 +1,75 @@
+/* Support routines for the intrinsic power (**) operator.
+ Copyright 2004, 2007, 2009 Free Software Foundation, Inc.
+ Contributed by Paul Brook
+
+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 3 of the License, or (at your option) any later version.
+
+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.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+#include "libgfortran.h"
+
+
+/* Use Binary Method to calculate the powi. This is not an optimal but
+ a simple and reasonable arithmetic. See section 4.6.3, "Evaluation of
+ Powers" of Donald E. Knuth, "Seminumerical Algorithms", Vol. 2, "The Art
+ of Computer Programming", 3rd Edition, 1998. */
+
+#if defined (HAVE_GFC_REAL_16) && defined (HAVE_GFC_INTEGER_4)
+
+GFC_REAL_16 pow_r16_i4 (GFC_REAL_16 a, GFC_INTEGER_4 b);
+export_proto(pow_r16_i4);
+
+GFC_REAL_16
+pow_r16_i4 (GFC_REAL_16 a, GFC_INTEGER_4 b)
+{
+ GFC_REAL_16 pow, x;
+ GFC_INTEGER_4 n;
+ GFC_UINTEGER_4 u;
+
+ n = b;
+ x = a;
+ pow = 1;
+ if (n != 0)
+ {
+ if (n < 0)
+ {
+
+ u = -n;
+ x = pow / x;
+ }
+ else
+ {
+ u = n;
+ }
+ for (;;)
+ {
+ if (u & 1)
+ pow *= x;
+ u >>= 1;
+ if (u)
+ x *= x;
+ else
+ break;
+ }
+ }
+ return pow;
+}
+
+#endif
diff --git a/libgfortran/generated/rrspacing_r16.c b/libgfortran/generated/rrspacing_r16.c
index 3812435..8c6aae1 100644
--- a/libgfortran/generated/rrspacing_r16.c
+++ b/libgfortran/generated/rrspacing_r16.c
@@ -33,7 +33,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define MATHFUNC(funcname) funcname ## l
#endif
-#if defined (HAVE_GFC_REAL_16) && (defined(GFC_WITH_QUAD_LIB) || defined(HAVE_FABSL)) && (defined(GFC_WITH_QUAD_LIB) || defined(HAVE_FREXPL))
+#if defined (HAVE_GFC_REAL_16) && (defined(GFC_REAL_16_IS_FLOAT128) || defined(HAVE_FABSL)) && (defined(GFC_REAL_16_IS_FLOAT128) || defined(HAVE_FREXPL))
extern GFC_REAL_16 rrspacing_r16 (GFC_REAL_16 s, int p);
export_proto(rrspacing_r16);
@@ -47,7 +47,7 @@ rrspacing_r16 (GFC_REAL_16 s, int p)
if (x == 0.)
return 0.;
MATHFUNC(frexp) (s, &e);
-#if (defined(GFC_WITH_QUAD_LIB) || defined(HAVE_LDEXPL))
+#if (defined(GFC_REAL_16_IS_FLOAT128) || defined(HAVE_LDEXPL))
return MATHFUNC(ldexp) (x, p - e);
#else
return MATHFUNC(scalbn) (x, p - e);
diff --git a/libgfortran/generated/set_exponent_r16.c b/libgfortran/generated/set_exponent_r16.c
index 8842dad..e138344 100644
--- a/libgfortran/generated/set_exponent_r16.c
+++ b/libgfortran/generated/set_exponent_r16.c
@@ -33,7 +33,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define MATHFUNC(funcname) funcname ## l
#endif
-#if defined (HAVE_GFC_REAL_16) && (defined(GFC_WITH_QUAD_LIB) || defined(HAVE_SCALBNL)) && (defined(GFC_WITH_QUAD_LIB) || defined(HAVE_FREXPL))
+#if defined (HAVE_GFC_REAL_16) && (defined(GFC_REAL_16_IS_FLOAT128) || defined(HAVE_SCALBNL)) && (defined(GFC_REAL_16_IS_FLOAT128) || defined(HAVE_FREXPL))
extern GFC_REAL_16 set_exponent_r16 (GFC_REAL_16 s, GFC_INTEGER_4 i);
export_proto(set_exponent_r16);
diff --git a/libgfortran/generated/spacing_r16.c b/libgfortran/generated/spacing_r16.c
index c95c0ba..f26b9fc 100644
--- a/libgfortran/generated/spacing_r16.c
+++ b/libgfortran/generated/spacing_r16.c
@@ -33,7 +33,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define MATHFUNC(funcname) funcname ## l
#endif
-#if defined (HAVE_GFC_REAL_16) && (defined(GFC_WITH_QUAD_LIB) || defined(HAVE_FREXPL))
+#if defined (HAVE_GFC_REAL_16) && (defined(GFC_REAL_16_IS_FLOAT128) || defined(HAVE_FREXPL))
extern GFC_REAL_16 spacing_r16 (GFC_REAL_16 s, int p, int emin, GFC_REAL_16 tiny);
export_proto(spacing_r16);
@@ -47,7 +47,7 @@ spacing_r16 (GFC_REAL_16 s, int p, int emin, GFC_REAL_16 tiny)
MATHFUNC(frexp) (s, &e);
e = e - p;
e = e > emin ? e : emin;
-#if (defined(GFC_WITH_QUAD_LIB) || defined(HAVE_LDEXPL))
+#if (defined(GFC_REAL_16_IS_FLOAT128) || defined(HAVE_LDEXPL))
return MATHFUNC(ldexp) (1., e);
#else
return MATHFUNC(scalbn) (1., e);
diff --git a/libgfortran/gfortran.map b/libgfortran/gfortran.map
index b5fad17..359f6a8 100644
--- a/libgfortran/gfortran.map
+++ b/libgfortran/gfortran.map
@@ -528,6 +528,7 @@ GFORTRAN_1.0 {
_gfortran_pow_r10_i16;
_gfortran_pow_r10_i8;
_gfortran_pow_r16_i16;
+ _gfortran_pow_r16_i4;
_gfortran_pow_r16_i8;
_gfortran_pow_r4_i16;
_gfortran_pow_r4_i8;
@@ -1146,9 +1147,13 @@ GFORTRAN_1.4 {
_gfortran_transfer_character_write;
_gfortran_transfer_character_wide_write;
_gfortran_transfer_complex_write;
+ _gfortran_transfer_complex128;
+ _gfortran_transfer_complex128_write;
_gfortran_transfer_integer_write;
_gfortran_transfer_logical_write;
_gfortran_transfer_real_write;
+ _gfortran_transfer_real128;
+ _gfortran_transfer_real128_write;
} GFORTRAN_1.3;
F2C_1.0 {
diff --git a/libgfortran/intrinsics/cshift0.c b/libgfortran/intrinsics/cshift0.c
index 3ba2b37..25f9833 100644
--- a/libgfortran/intrinsics/cshift0.c
+++ b/libgfortran/intrinsics/cshift0.c
@@ -134,18 +134,26 @@ cshift0 (gfc_array_char * ret, const gfc_array_char * array,
cshift0_r8 ((gfc_array_r8 *)ret, (gfc_array_r8 *) array, shift, which);
return;
-#ifdef HAVE_GFC_REAL_10
+/* FIXME: This here is a hack, which will have to be removed when
+ the array descriptor is reworked. Currently, we don't store the
+ kind value for the type, but only the size. Because on targets with
+ __float128, we have sizeof(logn double) == sizeof(__float128),
+ we cannot discriminate here and have to fall back to the generic
+ handling (which is suboptimal). */
+#if !defined(GFC_REAL_16_IS_FLOAT128)
+# ifdef HAVE_GFC_REAL_10
case GFC_DTYPE_REAL_10:
cshift0_r10 ((gfc_array_r10 *)ret, (gfc_array_r10 *) array, shift,
which);
return;
-#endif
+# endif
-#ifdef HAVE_GFC_REAL_16
+# ifdef HAVE_GFC_REAL_16
case GFC_DTYPE_REAL_16:
cshift0_r16 ((gfc_array_r16 *)ret, (gfc_array_r16 *) array, shift,
which);
return;
+# endif
#endif
case GFC_DTYPE_COMPLEX_4:
@@ -156,18 +164,26 @@ cshift0 (gfc_array_char * ret, const gfc_array_char * array,
cshift0_c8 ((gfc_array_c8 *)ret, (gfc_array_c8 *) array, shift, which);
return;
-#ifdef HAVE_GFC_COMPLEX_10
+/* FIXME: This here is a hack, which will have to be removed when
+ the array descriptor is reworked. Currently, we don't store the
+ kind value for the type, but only the size. Because on targets with
+ __float128, we have sizeof(logn double) == sizeof(__float128),
+ we cannot discriminate here and have to fall back to the generic
+ handling (which is suboptimal). */
+#if !defined(GFC_REAL_16_IS_FLOAT128)
+# ifdef HAVE_GFC_COMPLEX_10
case GFC_DTYPE_COMPLEX_10:
cshift0_c10 ((gfc_array_c10 *)ret, (gfc_array_c10 *) array, shift,
which);
return;
-#endif
+# endif
-#ifdef HAVE_GFC_COMPLEX_16
+# ifdef HAVE_GFC_COMPLEX_16
case GFC_DTYPE_COMPLEX_16:
cshift0_c16 ((gfc_array_c16 *)ret, (gfc_array_c16 *) array, shift,
which);
return;
+# endif
#endif
default:
diff --git a/libgfortran/intrinsics/erfc_scaled_inc.c b/libgfortran/intrinsics/erfc_scaled_inc.c
index 7e4ba7e..c003c66 100644
--- a/libgfortran/intrinsics/erfc_scaled_inc.c
+++ b/libgfortran/intrinsics/erfc_scaled_inc.c
@@ -39,7 +39,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
# 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.RUNTIME respectively. If not, see
# 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)
diff --git a/libgfortran/intrinsics/pack_generic.c b/libgfortran/intrinsics/pack_generic.c
index 1b872ec..7875646 100644
--- a/libgfortran/intrinsics/pack_generic.c
+++ b/libgfortran/intrinsics/pack_generic.c
@@ -301,18 +301,26 @@ pack (gfc_array_char *ret, const gfc_array_char *array,
(gfc_array_l1 *) mask, (gfc_array_r8 *) vector);
return;
-#ifdef HAVE_GFC_REAL_10
+/* FIXME: This here is a hack, which will have to be removed when
+ the array descriptor is reworked. Currently, we don't store the
+ kind value for the type, but only the size. Because on targets with
+ __float128, we have sizeof(logn double) == sizeof(__float128),
+ we cannot discriminate here and have to fall back to the generic
+ handling (which is suboptimal). */
+#if !defined(GFC_REAL_16_IS_FLOAT128)
+# ifdef HAVE_GFC_REAL_10
case GFC_DTYPE_REAL_10:
pack_r10 ((gfc_array_r10 *) ret, (gfc_array_r10 *) array,
(gfc_array_l1 *) mask, (gfc_array_r10 *) vector);
return;
-#endif
+# endif
-#ifdef HAVE_GFC_REAL_16
+# 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
#endif
case GFC_DTYPE_COMPLEX_4:
@@ -325,18 +333,26 @@ pack (gfc_array_char *ret, const gfc_array_char *array,
(gfc_array_l1 *) mask, (gfc_array_c8 *) vector);
return;
-#ifdef HAVE_GFC_COMPLEX_10
+/* FIXME: This here is a hack, which will have to be removed when
+ the array descriptor is reworked. Currently, we don't store the
+ kind value for the type, but only the size. Because on targets with
+ __float128, we have sizeof(logn double) == sizeof(__float128),
+ we cannot discriminate here and have to fall back to the generic
+ handling (which is suboptimal). */
+#if !defined(GFC_REAL_16_IS_FLOAT128)
+# ifdef HAVE_GFC_COMPLEX_10
case GFC_DTYPE_COMPLEX_10:
pack_c10 ((gfc_array_c10 *) ret, (gfc_array_c10 *) array,
(gfc_array_l1 *) mask, (gfc_array_c10 *) vector);
return;
-#endif
+# endif
-#ifdef HAVE_GFC_COMPLEX_16
+# 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
#endif
/* For derived types, let's check the actual alignment of the
diff --git a/libgfortran/intrinsics/spread_generic.c b/libgfortran/intrinsics/spread_generic.c
index 9e20b85..5fe98dd 100644
--- a/libgfortran/intrinsics/spread_generic.c
+++ b/libgfortran/intrinsics/spread_generic.c
@@ -322,18 +322,26 @@ spread (gfc_array_char *ret, const gfc_array_char *source,
*along, *pncopies);
return;
-#ifdef GFC_HAVE_REAL_10
+/* FIXME: This here is a hack, which will have to be removed when
+ the array descriptor is reworked. Currently, we don't store the
+ kind value for the type, but only the size. Because on targets with
+ __float128, we have sizeof(logn double) == sizeof(__float128),
+ we cannot discriminate here and have to fall back to the generic
+ handling (which is suboptimal). */
+#if !defined(GFC_REAL_16_IS_FLOAT128)
+# ifdef GFC_HAVE_REAL_10
case GFC_DTYPE_REAL_10:
spread_r10 ((gfc_array_r10 *) ret, (gfc_array_r10 *) source,
*along, *pncopies);
return;
-#endif
+# endif
-#ifdef GFC_HAVE_REAL_16
+# ifdef GFC_HAVE_REAL_16
case GFC_DTYPE_REAL_16:
spread_r16 ((gfc_array_r16 *) ret, (gfc_array_r16 *) source,
*along, *pncopies);
return;
+# endif
#endif
case GFC_DTYPE_COMPLEX_4:
@@ -346,18 +354,26 @@ spread (gfc_array_char *ret, const gfc_array_char *source,
*along, *pncopies);
return;
-#ifdef GFC_HAVE_COMPLEX_10
+/* FIXME: This here is a hack, which will have to be removed when
+ the array descriptor is reworked. Currently, we don't store the
+ kind value for the type, but only the size. Because on targets with
+ __float128, we have sizeof(logn double) == sizeof(__float128),
+ we cannot discriminate here and have to fall back to the generic
+ handling (which is suboptimal). */
+#if !defined(GFC_REAL_16_IS_FLOAT128)
+# ifdef GFC_HAVE_COMPLEX_10
case GFC_DTYPE_COMPLEX_10:
spread_c10 ((gfc_array_c10 *) ret, (gfc_array_c10 *) source,
*along, *pncopies);
return;
-#endif
+# endif
-#ifdef GFC_HAVE_COMPLEX_16
+# ifdef GFC_HAVE_COMPLEX_16
case GFC_DTYPE_COMPLEX_16:
spread_c16 ((gfc_array_c16 *) ret, (gfc_array_c16 *) source,
*along, *pncopies);
return;
+# endif
#endif
case GFC_DTYPE_DERIVED_2:
@@ -501,18 +517,26 @@ spread_scalar (gfc_array_char *ret, const char *source,
*along, *pncopies);
return;
-#ifdef HAVE_GFC_REAL_10
+/* FIXME: This here is a hack, which will have to be removed when
+ the array descriptor is reworked. Currently, we don't store the
+ kind value for the type, but only the size. Because on targets with
+ __float128, we have sizeof(logn double) == sizeof(__float128),
+ we cannot discriminate here and have to fall back to the generic
+ handling (which is suboptimal). */
+#if !defined(GFC_REAL_16_IS_FLOAT128)
+# ifdef HAVE_GFC_REAL_10
case GFC_DTYPE_REAL_10:
spread_scalar_r10 ((gfc_array_r10 *) ret, (GFC_REAL_10 *) source,
*along, *pncopies);
return;
-#endif
+# endif
-#ifdef HAVE_GFC_REAL_16
+# 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
#endif
case GFC_DTYPE_COMPLEX_4:
@@ -525,18 +549,26 @@ spread_scalar (gfc_array_char *ret, const char *source,
*along, *pncopies);
return;
-#ifdef HAVE_GFC_COMPLEX_10
+/* FIXME: This here is a hack, which will have to be removed when
+ the array descriptor is reworked. Currently, we don't store the
+ kind value for the type, but only the size. Because on targets with
+ __float128, we have sizeof(logn double) == sizeof(__float128),
+ we cannot discriminate here and have to fall back to the generic
+ handling (which is suboptimal). */
+#if !defined(GFC_REAL_16_IS_FLOAT128)
+# ifdef HAVE_GFC_COMPLEX_10
case GFC_DTYPE_COMPLEX_10:
spread_scalar_c10 ((gfc_array_c10 *) ret, (GFC_COMPLEX_10 *) source,
*along, *pncopies);
return;
-#endif
+# endif
-#ifdef HAVE_GFC_COMPLEX_16
+# 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
#endif
case GFC_DTYPE_DERIVED_2:
diff --git a/libgfortran/intrinsics/unpack_generic.c b/libgfortran/intrinsics/unpack_generic.c
index 0256b25..e8e2945 100644
--- a/libgfortran/intrinsics/unpack_generic.c
+++ b/libgfortran/intrinsics/unpack_generic.c
@@ -261,18 +261,26 @@ unpack1 (gfc_array_char *ret, const gfc_array_char *vector,
mask, (gfc_array_r8 *) field);
return;
-#ifdef HAVE_GFC_REAL_10
+/* FIXME: This here is a hack, which will have to be removed when
+ the array descriptor is reworked. Currently, we don't store the
+ kind value for the type, but only the size. Because on targets with
+ __float128, we have sizeof(logn double) == sizeof(__float128),
+ we cannot discriminate here and have to fall back to the generic
+ handling (which is suboptimal). */
+#if !defined(GFC_REAL_16_IS_FLOAT128)
+# ifdef HAVE_GFC_REAL_10
case GFC_DTYPE_REAL_10:
unpack1_r10 ((gfc_array_r10 *) ret, (gfc_array_r10 *) vector,
mask, (gfc_array_r10 *) field);
return;
-#endif
+# endif
-#ifdef HAVE_GFC_REAL_16
+# 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
#endif
case GFC_DTYPE_COMPLEX_4:
@@ -285,18 +293,26 @@ unpack1 (gfc_array_char *ret, const gfc_array_char *vector,
mask, (gfc_array_c8 *) field);
return;
-#ifdef HAVE_GFC_COMPLEX_10
+/* FIXME: This here is a hack, which will have to be removed when
+ the array descriptor is reworked. Currently, we don't store the
+ kind value for the type, but only the size. Because on targets with
+ __float128, we have sizeof(logn double) == sizeof(__float128),
+ we cannot discriminate here and have to fall back to the generic
+ handling (which is suboptimal). */
+#if !defined(GFC_REAL_16_IS_FLOAT128)
+# ifdef HAVE_GFC_COMPLEX_10
case GFC_DTYPE_COMPLEX_10:
unpack1_c10 ((gfc_array_c10 *) ret, (gfc_array_c10 *) vector,
mask, (gfc_array_c10 *) field);
return;
-#endif
+# endif
-#ifdef HAVE_GFC_COMPLEX_16
+# 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
#endif
case GFC_DTYPE_DERIVED_2:
@@ -455,18 +471,26 @@ unpack0 (gfc_array_char *ret, const gfc_array_char *vector,
mask, (GFC_REAL_8 *) field);
return;
-#ifdef HAVE_GFC_REAL_10
+/* FIXME: This here is a hack, which will have to be removed when
+ the array descriptor is reworked. Currently, we don't store the
+ kind value for the type, but only the size. Because on targets with
+ __float128, we have sizeof(logn double) == sizeof(__float128),
+ we cannot discriminate here and have to fall back to the generic
+ handling (which is suboptimal). */
+#if !defined(GFC_REAL_16_IS_FLOAT128)
+# ifdef HAVE_GFC_REAL_10
case GFC_DTYPE_REAL_10:
unpack0_r10 ((gfc_array_r10 *) ret, (gfc_array_r10 *) vector,
mask, (GFC_REAL_10 *) field);
return;
-#endif
+# endif
-#ifdef HAVE_GFC_REAL_16
+# 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
#endif
case GFC_DTYPE_COMPLEX_4:
@@ -479,18 +503,26 @@ unpack0 (gfc_array_char *ret, const gfc_array_char *vector,
mask, (GFC_COMPLEX_8 *) field);
return;
-#ifdef HAVE_GFC_COMPLEX_10
+/* FIXME: This here is a hack, which will have to be removed when
+ the array descriptor is reworked. Currently, we don't store the
+ kind value for the type, but only the size. Because on targets with
+ __float128, we have sizeof(logn double) == sizeof(__float128),
+ we cannot discriminate here and have to fall back to the generic
+ handling (which is suboptimal). */
+#if !defined(GFC_REAL_16_IS_FLOAT128)
+# ifdef HAVE_GFC_COMPLEX_10
case GFC_DTYPE_COMPLEX_10:
unpack0_c10 ((gfc_array_c10 *) ret, (gfc_array_c10 *) vector,
mask, (GFC_COMPLEX_10 *) field);
return;
-#endif
+# endif
-#ifdef HAVE_GFC_COMPLEX_16
+# 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
#endif
case GFC_DTYPE_DERIVED_2:
diff --git a/libgfortran/io/read.c b/libgfortran/io/read.c
index 357ee9f..33486fa 100644
--- a/libgfortran/io/read.c
+++ b/libgfortran/io/read.c
@@ -162,10 +162,16 @@ convert_real (st_parameter_dt *dtp, void *dest, const char *buffer, int length)
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:
+ __qmath_(quadmath_strtopQ) (buffer, NULL, dest);
+ break;
+# elif defined(HAVE_STRTOLD)
case 16:
*((GFC_REAL_16*) dest) = gfc_strtold (buffer, NULL);
break;
+# endif
#endif
default:
diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c
index 6f13113..8fffe0e 100644
--- a/libgfortran/io/transfer.c
+++ b/libgfortran/io/transfer.c
@@ -48,7 +48,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
For other sorts of data transfer, there are zero or more data
transfer statement that depend on the format of the data transfer
- statement.
+ statement. For READ (and for backwards compatibily: for WRITE), one has
transfer_integer
transfer_logical
@@ -56,8 +56,22 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
transfer_character_wide
transfer_real
transfer_complex
-
- These subroutines do not return status.
+ transfer_real128
+ transfer_complex128
+
+ and for WRITE
+
+ transfer_integer_write
+ transfer_logical_write
+ transfer_character_write
+ transfer_character_wide_write
+ transfer_real_write
+ transfer_complex_write
+ transfer_real128_write
+ transfer_complex128_write
+
+ These subroutines do not return status. The *128 functions
+ are in the file transfer128.c.
The last call is a call to st_[read|write]_done(). While
something can easily go wrong with the initial st_read() or
diff --git a/libgfortran/io/transfer128.c b/libgfortran/io/transfer128.c
new file mode 100644
index 0000000..66deabe
--- /dev/null
+++ b/libgfortran/io/transfer128.c
@@ -0,0 +1,108 @@
+/* Copyright (C) 2010
+ Free Software Foundation, Inc.
+
+This file is part of the GNU Fortran 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 3, or (at your option)
+any later version.
+
+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.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+/* Note: This file needs to be a separate translation unit (.o file)
+ to make sure that for static linkage, the libquad dependence only
+ occurs if needed. */
+
+#include "io.h"
+
+
+#if defined(GFC_REAL_16_IS_FLOAT128)
+
+/* The prototypes for the called procedures in transfer.c. */
+
+extern void transfer_real (st_parameter_dt *, void *, int);
+export_proto(transfer_real);
+
+extern void transfer_real_write (st_parameter_dt *, void *, int);
+export_proto(transfer_real_write);
+
+extern void transfer_complex (st_parameter_dt *, void *, int);
+export_proto(transfer_complex);
+
+extern void transfer_complex_write (st_parameter_dt *, void *, int);
+export_proto(transfer_complex_write);
+
+
+/* The prototypes for the procedures in this file. */
+
+extern void transfer_real128 (st_parameter_dt *, void *, int);
+export_proto(transfer_real128);
+
+extern void transfer_real128_write (st_parameter_dt *, void *, int);
+export_proto(transfer_real128_write);
+
+extern void transfer_complex128 (st_parameter_dt *, void *, int);
+export_proto(transfer_complex128);
+
+extern void transfer_complex128_write (st_parameter_dt *, void *, int);
+export_proto(transfer_complex128_write);
+
+
+/* Make sure that libquadmath is pulled in. The functions quadmath_strtopQ
+ and quadmath_dtoaq are weakly referrenced in convert_real and write_float;
+ the pointer assignment with USED attribute make sure that there is a
+ non-weakref dependence if the quadmath functions are used. That avoids
+ segfault when libquad is statically linked. */
+
+void
+transfer_real128 (st_parameter_dt *dtp, void *p, int kind)
+{
+ static void __attribute__((used)) *tmp1 = quadmath_strtopQ;
+ static void __attribute__((used)) *tmp2 = quadmath_dtoaq;
+
+ transfer_real (dtp, p, kind);
+}
+
+
+void
+transfer_real128_write (st_parameter_dt *dtp, void *p, int kind)
+{
+ static void __attribute__((used)) *tmp1 = quadmath_strtopQ;
+ static void __attribute__((used)) *tmp2 = quadmath_dtoaq;
+
+ transfer_real (dtp, p, kind);
+}
+
+
+void
+transfer_complex128 (st_parameter_dt *dtp, void *p, int kind)
+{
+ static void __attribute__((used)) *tmp1 = quadmath_strtopQ;
+ static void __attribute__((used)) *tmp2 = quadmath_dtoaq;
+
+ transfer_complex (dtp, p, kind);
+}
+
+
+void
+transfer_complex128_write (st_parameter_dt *dtp, void *p, int kind)
+{
+/* static void __attribute__((used)) *tmp1 = quadmath_strtopQ;
+ static void __attribute__((used)) *tmp2 = quadmath_dtoaq;*/
+
+ transfer_complex_write (dtp, p, kind);
+}
+#endif
diff --git a/libgfortran/io/write.c b/libgfortran/io/write.c
index 5afbbd5..987c3cd 100644
--- a/libgfortran/io/write.c
+++ b/libgfortran/io/write.c
@@ -1459,6 +1459,7 @@ set_fnode_default (st_parameter_dt *dtp, fnode *f, int length)
/* 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)
diff --git a/libgfortran/io/write_float.def b/libgfortran/io/write_float.def
index b9157df..fc00491 100644
--- a/libgfortran/io/write_float.def
+++ b/libgfortran/io/write_float.def
@@ -973,6 +973,11 @@ sprintf (buffer, "%+-#" STR(MIN_FIELD_WIDTH) ".*" \
#endif
+#if defined(GFC_REAL_16_IS_FLOAT128)
+#define DTOAQ \
+__qmath_(quadmath_dtoaq) (buffer, size, ndigits - 1, tmp);
+#endif
+
#define WRITE_FLOAT(x,y)\
{\
GFC_REAL_ ## x tmp;\
@@ -1002,7 +1007,7 @@ static void
write_float (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
{
-#if defined(HAVE_GFC_REAL_16) && __LDBL_DIG__ > 18
+#if defined(HAVE_GFC_REAL_16) || __LDBL_DIG__ > 18
# define MIN_FIELD_WIDTH 46
#else
# define MIN_FIELD_WIDTH 31
@@ -1057,7 +1062,11 @@ write_float (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
#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:
diff --git a/libgfortran/kinds-override.h b/libgfortran/kinds-override.h
new file mode 100644
index 0000000..952413b
--- /dev/null
+++ b/libgfortran/kinds-override.h
@@ -0,0 +1,46 @@
+/* Header used to override things detected by the mk-kinds-h.sh script.
+ Copyright (C) 2010 Free Software Foundation, Inc.
+
+This file is part of the GNU Fortran 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 3, or (at your option)
+any later version.
+
+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.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+
+/* 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
+
diff --git a/libgfortran/libgfortran.h b/libgfortran/libgfortran.h
index c5dd91a..ac86492 100644
--- a/libgfortran/libgfortran.h
+++ b/libgfortran/libgfortran.h
@@ -46,6 +46,12 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#include <float.h>
#include <stdarg.h>
+/* If we're support quad-precision floating-point type, include the
+ header to our support library. */
+#ifdef HAVE_FLOAT128
+# include "quadmath_weak.h"
+#endif
+
#ifdef __MINGW32__
extern float __strtof (const char *, char **);
#define gfc_strtof __strtof
@@ -309,7 +315,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__
@@ -323,7 +333,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
diff --git a/libgfortran/libgfortran.spec.in b/libgfortran/libgfortran.spec.in
new file mode 100644
index 0000000..95aa3f8
--- /dev/null
+++ b/libgfortran/libgfortran.spec.in
@@ -0,0 +1,8 @@
+#
+# This spec file is read by gfortran when linking.
+# It is used to specify the libraries we need to link in, in the right
+# order.
+#
+
+%rename lib liborig
+*lib: @LIBQUADSPEC@ -lm %(libgcc) %(liborig)
diff --git a/libgfortran/m4/mtype.m4 b/libgfortran/m4/mtype.m4
index fc4ceca..b133e57 100644
--- a/libgfortran/m4/mtype.m4
+++ b/libgfortran/m4/mtype.m4
@@ -5,7 +5,7 @@ define(real_type, `GFC_REAL_'kind)dnl
define(`upcase', `translit(`$*', `a-z', `A-Z')')dnl
define(q,ifelse(kind,4,f,ifelse(kind,8,`',ifelse(kind,10,l,ifelse(kind,16,l,`_'kind)))))dnl
define(Q,translit(q,`a-z',`A-Z'))dnl
-define(hasmathfunc,`ifelse(kind,4,`defined (HAVE_'upcase($1)`F)',ifelse(kind,8,`defined (HAVE_'upcase($1)`)',ifelse(kind,10,`defined (HAVE_'upcase($1)`L)',ifelse(kind,16,`(defined(GFC_WITH_QUAD_LIB) || defined(HAVE_'upcase($1)`L))',`error out'))))')
+define(hasmathfunc,`ifelse(kind,4,`defined (HAVE_'upcase($1)`F)',ifelse(kind,8,`defined (HAVE_'upcase($1)`)',ifelse(kind,10,`defined (HAVE_'upcase($1)`L)',ifelse(kind,16,`(defined(GFC_REAL_16_IS_FLOAT128) || defined(HAVE_'upcase($1)`L))',`error out'))))')
define(mathfunc_macro,`ifelse(kind,16,`#if defined(GFC_REAL_16_IS_FLOAT128)
#define MATHFUNC(funcname) funcname ## q
#else
diff --git a/libgfortran/mk-kinds-h.sh b/libgfortran/mk-kinds-h.sh
index 0b8dbc5..98a95ab 100755
--- a/libgfortran/mk-kinds-h.sh
+++ b/libgfortran/mk-kinds-h.sh
@@ -44,7 +44,14 @@ echo "#define GFC_UINTEGER_LARGEST GFC_UINTEGER_${largest}"
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}"
@@ -103,4 +111,9 @@ for k in $possible_real_kinds; do
rm -f tmp$$.*
done
+
+# After this, we include a header that can override some of the
+# autodetected settings.
+echo '#include "kinds-override.h"'
+
exit 0
diff --git a/libgfortran/runtime/in_pack_generic.c b/libgfortran/runtime/in_pack_generic.c
index 33ce031..014bd8e 100644
--- a/libgfortran/runtime/in_pack_generic.c
+++ b/libgfortran/runtime/in_pack_generic.c
@@ -80,29 +80,46 @@ internal_pack (gfc_array_char * source)
case GFC_DTYPE_REAL_8:
return internal_pack_r8 ((gfc_array_r8 *) source);
-#if defined (HAVE_GFC_REAL_10)
+/* FIXME: This here is a hack, which will have to be removed when
+ the array descriptor is reworked. Currently, we don't store the
+ kind value for the type, but only the size. Because on targets with
+ __float128, we have sizeof(logn double) == sizeof(__float128),
+ we cannot discriminate here and have to fall back to the generic
+ handling (which is suboptimal). */
+#if !defined(GFC_REAL_16_IS_FLOAT128)
+# if defined (HAVE_GFC_REAL_10)
case GFC_DTYPE_REAL_10:
return internal_pack_r10 ((gfc_array_r10 *) source);
-#endif
+# endif
-#if defined (HAVE_GFC_REAL_16)
+# if defined (HAVE_GFC_REAL_16)
case GFC_DTYPE_REAL_16:
return internal_pack_r16 ((gfc_array_r16 *) source);
+# endif
#endif
+
case GFC_DTYPE_COMPLEX_4:
return internal_pack_c4 ((gfc_array_c4 *) source);
case GFC_DTYPE_COMPLEX_8:
return internal_pack_c8 ((gfc_array_c8 *) source);
-#if defined (HAVE_GFC_COMPLEX_10)
+/* FIXME: This here is a hack, which will have to be removed when
+ the array descriptor is reworked. Currently, we don't store the
+ kind value for the type, but only the size. Because on targets with
+ __float128, we have sizeof(logn double) == sizeof(__float128),
+ we cannot discriminate here and have to fall back to the generic
+ handling (which is suboptimal). */
+#if !defined(GFC_REAL_16_IS_FLOAT128)
+# if defined (HAVE_GFC_COMPLEX_10)
case GFC_DTYPE_COMPLEX_10:
return internal_pack_c10 ((gfc_array_c10 *) source);
-#endif
+# endif
-#if defined (HAVE_GFC_COMPLEX_16)
+# if defined (HAVE_GFC_COMPLEX_16)
case GFC_DTYPE_COMPLEX_16:
return internal_pack_c16 ((gfc_array_c16 *) source);
+# endif
#endif
case GFC_DTYPE_DERIVED_2:
diff --git a/libgfortran/runtime/in_unpack_generic.c b/libgfortran/runtime/in_unpack_generic.c
index 3c290cd..a9caf2a 100644
--- a/libgfortran/runtime/in_unpack_generic.c
+++ b/libgfortran/runtime/in_unpack_generic.c
@@ -81,6 +81,7 @@ internal_unpack (gfc_array_char * d, const void * s)
internal_unpack_16 ((gfc_array_i16 *) d, (const GFC_INTEGER_16 *) s);
return;
#endif
+
case GFC_DTYPE_REAL_4:
internal_unpack_r4 ((gfc_array_r4 *) d, (const GFC_REAL_4 *) s);
return;
@@ -89,17 +90,26 @@ internal_unpack (gfc_array_char * d, const void * s)
internal_unpack_r8 ((gfc_array_r8 *) d, (const GFC_REAL_8 *) s);
return;
-#if defined(HAVE_GFC_REAL_10)
+/* FIXME: This here is a hack, which will have to be removed when
+ the array descriptor is reworked. Currently, we don't store the
+ kind value for the type, but only the size. Because on targets with
+ __float128, we have sizeof(logn double) == sizeof(__float128),
+ we cannot discriminate here and have to fall back to the generic
+ handling (which is suboptimal). */
+#if !defined(GFC_REAL_16_IS_FLOAT128)
+# if defined(HAVE_GFC_REAL_10)
case GFC_DTYPE_REAL_10:
internal_unpack_r10 ((gfc_array_r10 *) d, (const GFC_REAL_10 *) s);
return;
-#endif
+# endif
-#if defined(HAVE_GFC_REAL_16)
+# 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
#endif
+
case GFC_DTYPE_COMPLEX_4:
internal_unpack_c4 ((gfc_array_c4 *)d, (const GFC_COMPLEX_4 *)s);
return;
@@ -108,17 +118,26 @@ internal_unpack (gfc_array_char * d, const void * s)
internal_unpack_c8 ((gfc_array_c8 *)d, (const GFC_COMPLEX_8 *)s);
return;
-#if defined(HAVE_GFC_COMPLEX_10)
+/* FIXME: This here is a hack, which will have to be removed when
+ the array descriptor is reworked. Currently, we don't store the
+ kind value for the type, but only the size. Because on targets with
+ __float128, we have sizeof(logn double) == sizeof(__float128),
+ we cannot discriminate here and have to fall back to the generic
+ handling (which is suboptimal). */
+#if !defined(GFC_REAL_16_IS_FLOAT128)
+# if defined(HAVE_GFC_COMPLEX_10)
case GFC_DTYPE_COMPLEX_10:
internal_unpack_c10 ((gfc_array_c10 *) d, (const GFC_COMPLEX_10 *) s);
return;
-#endif
+# endif
-#if defined(HAVE_GFC_COMPLEX_16)
+# 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
#endif
+
case GFC_DTYPE_DERIVED_2:
if (GFC_UNALIGNED_2(d->data) || GFC_UNALIGNED_2(s))
break;