ifeq ($(subdir),stdio-common)
-routines += ieee128-printf_size
+ldbl-extra-routines += printf_size \
+ asprintf \
+ dprintf \
+ fprintf \
+ printf \
+ snprintf \
+ sprintf \
+ vasprintf \
+ vdprintf \
+ vfprintf \
+ vprintf \
+ vsnprintf \
+ vsprintf
+
+# Printing long double values with IEEE binary128 format reuses part
+# of the internal float128 implementation (__printf_fp, __printf_fphex,
+# and __float128 variables and union members). Thus, the compilation of
+# the following functions, must have -mfloat128 and -mabi=ibmlongdouble
+# passed to the compiler.
+CFLAGS-vfprintf-internal.c += -mfloat128 -mabi=ibmlongdouble
+
+# Basic tests for the implementation of long double with IEEE binary128
+# format and for the related redirections in installed headers.
+tests-internal += test-printf-ieee128 test-printf-ibm128
+CFLAGS-test-printf-ieee128.c += -mfloat128 -mabi=ieeelongdouble -Wno-psabi
+CFLAGS-test-printf-ibm128.c += -mabi=ibmlongdouble -Wno-psabi
tests-internal += test-printf-size-ieee128 test-printf-size-ibm128
CFLAGS-test-printf-size-ieee128.c += -mfloat128 -mabi=ieeelongdouble -Wno-psabi
$(SHELL) $^ '$(test-program-prefix)' $@; \
$(evaluate-test)
endif
+
+# Add IEEE binary128 files as make targets.
+routines += $(foreach r,$(ldbl-extra-routines),ieee128-$(r))
+
+# On powerpc64le, the routines responsible for converting between long
+# double and string (e.g.: printf, scanf, strtold, strfroml) default to
+# IBM long double mode. When support for TS 18661-3 was added, several
+# internal functions were modified so that they could also handle
+# floating-point variables with IEEE binary128 format, but as an
+# additional type, _Float128.
+#
+# The following rule ensures that the string conversion routines will
+# always be built in IBM long double mode, with additional support for
+# IEEE binary128, through the use of -mabi=ibmlongdouble and -mfloat128.
+ldbl-ibm128-files := $(objpfx)test-%-ibm128^ \
+ $(foreach r,$(ldbl-extra-routines),$(objpfx)$(r)^) \
+ $(foreach r,$(ldbl-extra-routines),$(objpfx)$(r)-internal^)
+obj-suf-foreach = $(foreach suf,$(all-object-suffixes),$(subst ^,$(suf),$(1)))
+$(call obj-suf-foreach,$(ldbl-ibm128-files)): \
+ sysdep-CFLAGS += -mabi=ibmlongdouble
__wcstoieee128_l;
__printf_sizeieee128;
+
+ __asprintfieee128;
+ __dprintfieee128;
+ __fprintfieee128;
+ __printfieee128;
+ __snprintfieee128;
+ __sprintfieee128;
+
+ __vasprintfieee128;
+ __vdprintfieee128;
+ __vfprintfieee128;
+ __vprintfieee128;
+ __vsnprintfieee128;
+ __vsprintfieee128;
}
+}
--- /dev/null
+/* Wrapper for asprintf. IEEE128 version.
+ Copyright (C) 2019 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 <libio/libioP.h>
+
+extern int
+___ieee128_asprintf (char **string_ptr, const char *format, ...)
+{
+ va_list ap;
+ int done;
+
+ va_start (ap, format);
+ done = __vasprintf_internal (string_ptr, format, ap,
+ PRINTF_LDBL_USES_FLOAT128);
+ va_end (ap);
+
+ return done;
+}
+strong_alias (___ieee128_asprintf, __asprintfieee128)
--- /dev/null
+/* Wrapper for dprintf. IEEE128 version.
+ Copyright (C) 2019 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 <libio/libioP.h>
+
+extern int
+___ieee128_dprintf (int d, const char *format, ...)
+{
+ va_list ap;
+ int done;
+
+ va_start (ap, format);
+ done = __vdprintf_internal (d, format, ap, PRINTF_LDBL_USES_FLOAT128);
+ va_end (ap);
+
+ return done;
+}
+strong_alias (___ieee128_dprintf, __dprintfieee128)
--- /dev/null
+/* Wrapper for fprintf. IEEE128 version.
+ Copyright (C) 2019 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 <libio/libioP.h>
+
+extern int
+___ieee128_fprintf (FILE *fp, const char *format, ...)
+{
+ va_list ap;
+ int done;
+
+ va_start (ap, format);
+ done = __vfprintf_internal (fp, format, ap, PRINTF_LDBL_USES_FLOAT128);
+ va_end (ap);
+
+ return done;
+}
+strong_alias (___ieee128_fprintf, __fprintfieee128)
--- /dev/null
+/* Wrapper for printf. IEEE128 version.
+ Copyright (C) 2019 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 <libio/libioP.h>
+
+extern int
+___ieee128_printf (const char *format, ...)
+{
+ va_list ap;
+ int done;
+
+ va_start (ap, format);
+ done = __vfprintf_internal (stdout, format, ap,
+ PRINTF_LDBL_USES_FLOAT128);
+ va_end (ap);
+
+ return done;
+}
+strong_alias (___ieee128_printf, __printfieee128)
--- /dev/null
+/* Wrapper for snprintf. IEEE128 version.
+ Copyright (C) 2019 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 <libio/libioP.h>
+
+extern int
+___ieee128_snprintf (char *s, size_t maxlen, const char *format, ...)
+{
+ va_list ap;
+ int done;
+
+ va_start (ap, format);
+ done = __vsnprintf_internal (s, maxlen, format, ap,
+ PRINTF_LDBL_USES_FLOAT128);
+ va_end (ap);
+
+ return done;
+}
+strong_alias (___ieee128_snprintf, __snprintfieee128)
--- /dev/null
+/* Wrapper for sprintf. IEEE128 version.
+ Copyright (C) 2019 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 <libio/libioP.h>
+
+extern int
+___ieee128_sprintf (char *s, const char *format, ...)
+{
+ va_list ap;
+ int done;
+
+ va_start (ap, format);
+ done = __vsprintf_internal (s, -1, format, ap,
+ PRINTF_LDBL_USES_FLOAT128);
+ va_end (ap);
+
+ return done;
+}
+strong_alias (___ieee128_sprintf, __sprintfieee128)
--- /dev/null
+/* Wrapper for vasprintf. IEEE128 version.
+ Copyright (C) 2019 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 <libio/libioP.h>
+
+extern int
+___ieee128_vasprintf (char **result_ptr, const char *format, va_list ap)
+{
+ return __vasprintf_internal (result_ptr, format, ap,
+ PRINTF_LDBL_USES_FLOAT128);
+}
+strong_alias (___ieee128_vasprintf, __vasprintfieee128)
--- /dev/null
+/* Wrapper for vdprintf. IEEE128 version.
+ Copyright (C) 2019 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 <libio/libioP.h>
+
+extern int
+___ieee128_vdprintf (int d, const char *format, va_list ap)
+{
+ return __vdprintf_internal (d, format, ap, PRINTF_LDBL_USES_FLOAT128);
+}
+strong_alias (___ieee128_vdprintf, __vdprintfieee128)
--- /dev/null
+/* Wrapper for vfprintf. IEEE128 version.
+ Copyright (C) 2019 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 <libio/libioP.h>
+
+extern int
+___ieee128_vfprintf (FILE *fp, const char *format, va_list ap)
+{
+ return __vfprintf_internal (fp, format, ap, PRINTF_LDBL_USES_FLOAT128);
+}
+strong_alias (___ieee128_vfprintf, __vfprintfieee128)
--- /dev/null
+/* Wrapper for vprintf. IEEE128 version.
+ Copyright (C) 2019 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 <libio/libioP.h>
+
+extern int
+___ieee128_vprintf (const char *format, va_list ap)
+{
+ return __vfprintf_internal (stdout, format, ap,
+ PRINTF_LDBL_USES_FLOAT128);
+}
+strong_alias (___ieee128_vprintf, __vprintfieee128)
--- /dev/null
+/* Wrapper for vsnprintf. IEEE128 version.
+ Copyright (C) 2019 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 <libio/libioP.h>
+
+extern int
+___ieee128_vsnprintf (char *string, size_t maxlen, const char *format,
+ va_list ap)
+{
+ return __vsnprintf_internal (string, maxlen, format, ap,
+ PRINTF_LDBL_USES_FLOAT128);
+}
+strong_alias (___ieee128_vsnprintf, __vsnprintfieee128)
--- /dev/null
+/* Wrapper for vsprintf. IEEE128 version.
+ Copyright (C) 2019 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 <libio/libioP.h>
+
+extern int
+___ieee128_vsprintf (char *string, const char *format, va_list ap)
+{
+ return __vsprintf_internal (string, -1, format, ap,
+ PRINTF_LDBL_USES_FLOAT128);
+}
+strong_alias (___ieee128_vsprintf, __vsprintfieee128)
--- /dev/null
+#include <test-printf-ldbl-compat.c>
--- /dev/null
+#include <test-printf-ldbl-compat.c>
--- /dev/null
+/* Test for the long double variants of *printf functions.
+ Copyright (C) 2019 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 <stdlib.h>
+
+#include <support/capture_subprocess.h>
+#include <support/check.h>
+
+static void
+do_test_call_varg (FILE *stream, const char *format, ...)
+{
+ char *buffer = NULL;
+ char string[128];
+ va_list args;
+
+ printf ("%15s", "vasprintf: ");
+ va_start (args, format);
+ vasprintf (&buffer, format, args);
+ va_end (args);
+ if (buffer == NULL)
+ printf ("Error using vasprintf\n");
+ else
+ {
+ printf ("%s", buffer);
+ free (buffer);
+ }
+ printf ("\n");
+
+ printf ("%15s", "vdprintf: ");
+ va_start (args, format);
+ vdprintf (fileno (stream), format, args);
+ va_end (args);
+ printf ("\n");
+
+ printf ("%15s", "vfprintf: ");
+ va_start (args, format);
+ vfprintf (stream, format, args);
+ va_end (args);
+ printf ("\n");
+
+ printf ("%15s", "vprintf: ");
+ va_start (args, format);
+ vprintf (format, args);
+ va_end (args);
+ printf ("\n");
+
+ printf ("%15s", "vsnprintf: ");
+ va_start (args, format);
+ vsnprintf (string, 127, format, args);
+ va_end (args);
+ printf ("%s", string);
+ printf ("\n");
+
+ printf ("%15s", "vsprintf: ");
+ va_start (args, format);
+ vsprintf (string, format, args);
+ va_end (args);
+ printf ("%s", string);
+ printf ("\n");
+}
+
+static void
+do_test_call_rarg (FILE *stream, const char *format, long double ld)
+{
+ char *buffer = NULL;
+ char string[128];
+
+ printf ("%15s", "asprintf: ");
+ asprintf (&buffer, format, ld);
+ if (buffer == NULL)
+ printf ("Error using asprintf\n");
+ else
+ {
+ printf ("%s", buffer);
+ free (buffer);
+ }
+ printf ("\n");
+
+ printf ("%15s", "dprintf: ");
+ dprintf (fileno (stream), format, ld);
+ printf ("\n");
+
+ printf ("%15s", "fprintf: ");
+ fprintf (stream, format, ld);
+ printf ("\n");
+
+ printf ("%15s", "printf: ");
+ printf (format, ld);
+ printf ("\n");
+
+ printf ("%15s", "snprintf: ");
+ snprintf (string, 127, format, ld);
+ printf ("%s", string);
+ printf ("\n");
+
+ printf ("%15s", "sprintf: ");
+ sprintf (string, format, ld);
+ printf ("%s", string);
+ printf ("\n");
+}
+
+static void
+do_test_call (void)
+{
+ long double ld = -1;
+
+ /* Print in decimal notation. */
+ do_test_call_rarg (stdout, "%.10Lf", ld);
+ do_test_call_varg (stdout, "%.10Lf", ld);
+
+ /* Print in hexadecimal notation. */
+ do_test_call_rarg (stdout, "%.10La", ld);
+ do_test_call_varg (stdout, "%.10La", ld);
+}
+
+static int
+do_test (void)
+{
+ struct support_capture_subprocess result;
+ result = support_capture_subprocess ((void *) &do_test_call, NULL);
+
+ /* Compare against the expected output. */
+ const char *expected =
+ " asprintf: -1.0000000000\n"
+ " dprintf: -1.0000000000\n"
+ " fprintf: -1.0000000000\n"
+ " printf: -1.0000000000\n"
+ " snprintf: -1.0000000000\n"
+ " sprintf: -1.0000000000\n"
+ " vasprintf: -1.0000000000\n"
+ " vdprintf: -1.0000000000\n"
+ " vfprintf: -1.0000000000\n"
+ " vprintf: -1.0000000000\n"
+ " vsnprintf: -1.0000000000\n"
+ " vsprintf: -1.0000000000\n"
+ " asprintf: -0x1.0000000000p+0\n"
+ " dprintf: -0x1.0000000000p+0\n"
+ " fprintf: -0x1.0000000000p+0\n"
+ " printf: -0x1.0000000000p+0\n"
+ " snprintf: -0x1.0000000000p+0\n"
+ " sprintf: -0x1.0000000000p+0\n"
+ " vasprintf: -0x1.0000000000p+0\n"
+ " vdprintf: -0x1.0000000000p+0\n"
+ " vfprintf: -0x1.0000000000p+0\n"
+ " vprintf: -0x1.0000000000p+0\n"
+ " vsnprintf: -0x1.0000000000p+0\n"
+ " vsprintf: -0x1.0000000000p+0\n";
+ TEST_COMPARE_STRING (expected, result.out.buffer);
+
+ return 0;
+}
+
+#include <support/test-driver.c>