diff --git a/libio/stdio.h b/libio/stdio.h
index 731f8e56f4..6d6b3e6062 100644
--- a/libio/stdio.h
+++ b/libio/stdio.h
@@ -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.  */
diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/Makefile b/sysdeps/ieee754/ldbl-128ibm-compat/Makefile
new file mode 100644
index 0000000000..ef04cbb67f
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm-compat/Makefile
@@ -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
diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/Versions b/sysdeps/ieee754/ldbl-128ibm-compat/Versions
new file mode 100644
index 0000000000..ea4e096cce
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm-compat/Versions
@@ -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;
+  }
+}
diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/bits/stdio-ieee128.h b/sysdeps/ieee754/ldbl-128ibm-compat/bits/stdio-ieee128.h
new file mode 100644
index 0000000000..a393c0b209
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm-compat/bits/stdio-ieee128.h
@@ -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.  */
diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-printf_fp.c b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-printf_fp.c
new file mode 100644
index 0000000000..813315f8b0
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-printf_fp.c
@@ -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>
diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-printf_fphex.c b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-printf_fphex.c
new file mode 100644
index 0000000000..e3da570a16
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-printf_fphex.c
@@ -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>
diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-vfprintf.c b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-vfprintf.c
new file mode 100644
index 0000000000..db9cd79b24
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-vfprintf.c
@@ -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>
diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/test-printf-ibm128.c b/sysdeps/ieee754/ldbl-128ibm-compat/test-printf-ibm128.c
new file mode 100644
index 0000000000..5de4ea3e7f
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm-compat/test-printf-ibm128.c
@@ -0,0 +1 @@
+#include <test-printf-ldbl-compat.c>
diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/test-printf-ieee128.c b/sysdeps/ieee754/ldbl-128ibm-compat/test-printf-ieee128.c
new file mode 100644
index 0000000000..5de4ea3e7f
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm-compat/test-printf-ieee128.c
@@ -0,0 +1 @@
+#include <test-printf-ldbl-compat.c>
diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/test-printf-ldbl-compat.c b/sysdeps/ieee754/ldbl-128ibm-compat/test-printf-ldbl-compat.c
new file mode 100644
index 0000000000..03014507b4
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm-compat/test-printf-ldbl-compat.c
@@ -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>
diff --git a/sysdeps/ieee754/ldbl-opt/math_ldbl_opt.h b/sysdeps/ieee754/ldbl-opt/math_ldbl_opt.h
index 61ba784f86..78e5d4b496 100644
--- a/sysdeps/ieee754/ldbl-opt/math_ldbl_opt.h
+++ b/sysdeps/ieee754/ldbl-opt/math_ldbl_opt.h
@@ -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
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/ldbl-128ibm-compat-abi.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/ldbl-128ibm-compat-abi.h
new file mode 100644
index 0000000000..6eb0e72b07
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/ldbl-128ibm-compat-abi.h
@@ -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
