@@ -864,6 +864,15 @@ extern int __overflow (FILE *, int);
# include <bits/stdio-ldbl.h>
#endif
+/* For platforms where long double had double format, then was converted
+ to some non-IEEE format, then finally to IEEE binary128 format, add
+ redirections to the correct implementation of stdio.h functions. */
+#include <bits/floatn.h>
+#if __HAVE_DISTINCT_FLOAT128 && __LDBL_MANT_DIG__ == 113 && \
+ ! defined __BUILDING_EXTRA_LDBL_FORMAT
+# include <bits/stdio-ieee128.h>
+#endif
+
__END_DECLS
#endif /* <stdio.h> included. */
new file mode 100644
@@ -0,0 +1,20 @@
+ifeq ($(subdir),stdio-common)
+routines += ieee128-printf_fp ieee128-printf_fphex
+CFLAGS-ieee128-printf_fp.c += -mfloat128 -mabi=ieeelongdouble -Wno-psabi
+CFLAGS-ieee128-printf_fphex.c += -mfloat128 -mabi=ieeelongdouble -Wno-psabi
+
+routines += ieee128-vfprintf
+CFLAGS-ieee128-vfprintf.c += -mfloat128 -mabi=ieeelongdouble -Wno-psabi
+
+tests-internal += test-printf-ieee128
+CFLAGS-test-printf-ieee128.c := $(filter-out -mlong-double-128, \
+ $(CFLAGS-test-printf-ieee128.c))
+CFLAGS-test-printf-ieee128.c += -mfloat128 -mabi=ieeelongdouble -Wno-psabi
+
+tests-internal += test-printf-ibm128
+CFLAGS-test-printf-ibm128.c := $(filter-out -mlong-double-128, \
+ $(CFLAGS-test-printf-ibm128.c))
+CFLAGS-test-printf-ibm128.c += -mabi=ibmlongdouble -Wno-psabi
+
+headers += bits/stdio-ieee128.h
+endif
new file mode 100644
@@ -0,0 +1,12 @@
+%include <ldbl-128ibm-compat-abi.h>
+%ifndef LDBL_IBM128_VERSION
+% error "ldbl-128ibm-compat-abi.h must define LDBL_IBM128_VERSION"
+%endif
+
+libc {
+ LDBL_IBM128_VERSION {
+ __ieee128___printf_fp;
+ __ieee128__IO_vfprintf;
+ __ieee128_vfprintf;
+ }
+}
new file mode 100644
@@ -0,0 +1,30 @@
+/* Redirections for stdio functions for -mabi=ieeelongdouble.
+ Copyright (C) 2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _STDIO_H
+# error "Never include <bits/stdio-ibm128.h> directly; use <stdio.h> instead."
+#endif
+
+#include <stdio.h>
+
+#define __IBM128_REDIR(name) \
+ extern __typeof (name) __ieee128_##name; \
+ extern __typeof (name) name __asm (__ASMNAME ("__ieee128_" #name));
+
+__IBM128_REDIR (vfprintf)
+/* To be completed with the other functions. */
new file mode 100644
@@ -0,0 +1,16 @@
+/* Redefine the names of the functions in printf_fp.c before including it. */
+#define __printf_fp __ieee128___printf_fp
+#define __printf_fp_l __ieee128___printf_fp_l
+#define ___printf_fp __ieee128____printf_fp
+#define __guess_grouping __ieee128___guess_grouping
+
+/* Use __mpn_extract_float128 since it handles the floating-point
+ parameter as a floating-point value with binary128 format. */
+#define __mpn_extract_long_double __mpn_extract_float128
+
+/* Skip the inclusion of the redirections of *l functions to __ieee128_*
+ functions during the build of glibc (these redirections would
+ conflict with the internal redirections to __GL_* symbols). */
+#define __BUILDING_EXTRA_LDBL_FORMAT
+
+#include <stdio-common/printf_fp.c>
new file mode 100644
@@ -0,0 +1,16 @@
+/* Redefine the name of the function in printf_fphex.c before including it. */
+#define __printf_fphex __ieee128___printf_fphex
+
+/* Skip the inclusion of the redirections of *l functions to __ieee128_*
+ functions during the build of glibc (these redirections would
+ conflict with the internal redirections to __GL_* symbols). */
+#define __BUILDING_EXTRA_LDBL_FORMAT
+
+/* Explicitly include ieee754.h from the ldbl-128 directory, since this
+ file is building __printf_fphex for long double with IEEE binary128
+ format (implicitly, this header would be included from ldbl-128ibm,
+ which has definitions for long double with IBM Extended Precision
+ format for floating-point). */
+#include <sysdeps/ieee754/ldbl-128/ieee754.h>
+
+#include <sysdeps/ieee754/ldbl-128/printf_fphex.c>
new file mode 100644
@@ -0,0 +1,13 @@
+/* Redefine the names of the functions in vfprintf.c before including it. */
+#define _IO_vfprintf_internal __ieee128__IO_vfprintf_internal
+#define __printf_fp __ieee128___printf_fp
+#define __printf_fphex __ieee128___printf_fphex
+#define vfprintf __ieee128_vfprintf
+#define _IO_vfprintf __ieee128__IO_vfprintf
+
+/* Skip the inclusion of the redirections of *l functions to __ieee128_*
+ functions during the build of glibc (these redirections would
+ conflict with the internal redirections to __GL_* symbols). */
+#define __BUILDING_EXTRA_LDBL_FORMAT
+
+#include <stdio-common/vfprintf.c>
new file mode 100644
@@ -0,0 +1 @@
+#include <test-printf-ldbl-compat.c>
new file mode 100644
@@ -0,0 +1 @@
+#include <test-printf-ldbl-compat.c>
new file mode 100644
@@ -0,0 +1,51 @@
+/* Test for the long double variants of *printf functions.
+ Copyright (C) 2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdio.h>
+
+#include <support/check.h>
+
+static void
+do_test_call_varg (FILE *stream, const char *format, ...)
+{
+ va_list args;
+
+ printf ("%20s", "vfprintf: ");
+ va_start (args, format);
+ vfprintf (stream, format, args);
+ va_end (args);
+ printf ("\n");
+}
+
+static int
+do_test (void)
+{
+ long double ld = -1;
+
+ /* Print in decimal notation. */
+ do_test_call_varg (stdout, "%.60Lf", ld);
+
+ /* Print in hexadecimal notation. */
+ do_test_call_varg (stdout, "%.60La", ld);
+
+ return 0;
+}
+
+#include <support/test-driver.c>
@@ -5,14 +5,35 @@
# error "nldbl-abi.h must define LONG_DOUBLE_COMPAT_VERSION"
#endif
+/* On powerpc64le, a third format for long double is supported since the
+ version described in ldbl-128ibm-compat-abi.h. */
+#include <bits/floatn.h>
+#if __HAVE_DISTINCT_FLOAT128 && __LDBL_MANT_DIG__ == 113
+# include <ldbl-128ibm-compat-abi.h>
+# ifndef LDBL_IBM128_COMPAT_VERSION
+# error "ldbl-128ibm-compat-abi.h must define LDBL_IBM128_COMPAT_VERSION"
+# endif
+#endif
+
#include <shlib-compat.h>
#define LONG_DOUBLE_COMPAT(lib, introduced) \
SHLIB_COMPAT(lib, introduced, LONG_DOUBLE_COMPAT_VERSION)
-#define long_double_symbol(lib, local, symbol) \
+/* When building long double with IEEE long double format on
+ powerpc64le, exposed the symbols with the version defined in
+ ldbl-128ibm-compat-abi.h. */
+#if __HAVE_DISTINCT_FLOAT128 && __LDBL_MANT_DIG__ == 113
+# define long_double_symbol(lib, local, symbol) \
+ long_double_symbol_1 (lib, local, symbol, LDBL_IBM128_COMPAT_VERSION)
+/* Otherwise, expose the symbols with the version from nldbl-abi.h. */
+#else
+# define long_double_symbol(lib, local, symbol) \
long_double_symbol_1 (lib, local, symbol, LONG_DOUBLE_COMPAT_VERSION)
+#endif
#ifdef SHARED
# define ldbl_hidden_def(local, name) libc_hidden_ver (local, name)
# define ldbl_strong_alias(name, aliasname) \
+ ldbl_strong_alias_x (name, aliasname)
+# define ldbl_strong_alias_x(name, aliasname) \
strong_alias (name, __GL_##name##_##aliasname) \
long_double_symbol (libc, __GL_##name##_##aliasname, aliasname);
# define ldbl_weak_alias(name, aliasname) \
@@ -22,7 +43,9 @@
versioned_symbol (lib, local, symbol, version)
#else
# define ldbl_hidden_def(local, name) libc_hidden_def (name)
-# define ldbl_strong_alias(name, aliasname) strong_alias (name, aliasname)
+# define ldbl_strong_alias(name, aliasname) \
+ ldbl_strong_alias_x (name, aliasname)
+# define ldbl_strong_alias_x(name, aliasname) strong_alias (name, aliasname)
# define ldbl_weak_alias(name, aliasname) weak_alias (name, aliasname)
# ifndef __ASSEMBLER__
/* Note that weak_alias cannot be used - it is defined to nothing
new file mode 100644
@@ -0,0 +1,8 @@
+/* ABI version for long double switch to IEEE 128-bit floating point..
+ This is used by the Versions and math_ldbl_opt.h files in
+ sysdeps/ieee754/ldbl-128ibm-compat/. It gives the ABI version where
+ long double == ibm128 was replaced with long double == _Float128
+ for libm *l functions and libc functions using long double. */
+
+#define LDBL_IBM128_VERSION GLIBC_2.28
+#define LDBL_IBM128_COMPAT_VERSION GLIBC_2_28