public inbox for libstdc++-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/meissner/heads/work029)] Add C++ runtime support for new 128-bit long double format
@ 2020-11-30 18:59 Michael Meissner
  0 siblings, 0 replies; 2+ messages in thread
From: Michael Meissner @ 2020-11-30 18:59 UTC (permalink / raw)
  To: gcc-cvs, libstdc++-cvs

https://gcc.gnu.org/g:97976b7288508f42089cd9235ba9417ad954ffb1

commit 97976b7288508f42089cd9235ba9417ad954ffb1
Author: Michael Meissner <meissner@linux.ibm.com>
Date:   Mon Nov 30 13:57:32 2020 -0500

    Add C++ runtime support for new 128-bit long double format
    
    libstdc++-v3/
    2020-11-11  Jonathan Wakely  <jwakely@redhat.com>
    
                * config.h.in: Regenerate.
                * config/abi/pre/gnu.ver: Make patterns less greedy. Add CXXABI_1.3.12
                symbol version.
                * config/os/gnu-linux/ldbl-ieee128-extra.ver: New file with patterns
                for IEEE128 long double symbols.
                * configure: Regenerate.
                * configure.ac: Enable alternative 128-bit long double format on
                powerpc64*-*-linux*.
                * doc/Makefile.in: Regenerate.
                * fragment.am: Regenerate.
                * include/Makefile.am: Set _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT.
                * include/Makefile.in: Regenerate.
                * include/bits/c++config: Define inline namespace for new long double
                symbols. Don't define _GLIBCXX_USE_FLOAT128 when it's the same type
                as long double.
                * include/bits/locale_classes.h [_GLIBCXX_LONG_DOUBLE_ALT128_COMPAT]
                (locale::_Impl::_M_init_extra_ldbl128): Declare new member function.
                * include/bits/locale_facets.h (_GLIBCXX_NUM_FACETS): Simplify by
                only counting narrow character facets.
                (_GLIBCXX_NUM_CXX11_FACETS): Likewise.
                (_GLIBCXX_NUM_LBDL_ALT128_FACETS): New.
                [_GLIBCXX_LONG_DOUBLE_ALT128_COMPAT] (num_get::__do_get): Define
                vtable placeholder for __ibm128 long double type.
                [_GLIBCXX_LONG_DOUBLE_ALT128_COMPAT && __LONG_DOUBLE_IEEE128__]
                (num_get::__do_get): Declare vtable placeholder for __ibm128 long
                double type.
                [_GLIBCXX_LONG_DOUBLE_ALT128_COMPAT && __LONG_DOUBLE_IEEE128__]
                (num_put::__do_put): Likewise.
                * include/bits/locale_facets.tcc
                [_GLIBCXX_LONG_DOUBLE_ALT128_COMPAT && __LONG_DOUBLE_IEEE128__]
                (num_get::__do_get, num_put::__do_put): Define.
                * include/bits/locale_facets_nonio.h
                [_GLIBCXX_LONG_DOUBLE_ALT128_COMPAT && __LONG_DOUBLE_IEEE128__]
                (money_get::__do_get): Declare vtable placeholder for __ibm128 long
                double type.
                [_GLIBCXX_LONG_DOUBLE_ALT128_COMPAT && __LONG_DOUBLE_IEEE128__]
                (money_put::__do_put): Likewise.
                * include/bits/locale_facets_nonio.tcc
                [_GLIBCXX_LONG_DOUBLE_ALT128_COMPAT && __LONG_DOUBLE_IEEE128__]
                (money_get::__do_get, money_put::__do_put): Define.
                * libsupc++/Makefile.in: Regenerate.
                * po/Makefile.in: Regenerate.
                * python/Makefile.in: Regenerate.
                * src/Makefile.am: Add compatibility-ldbl-alt128.cc and
                compatibility-ldbl-alt128-cxx11.cc sources and recipes for objects.
                * src/Makefile.in: Regenerate.
                * src/c++11/Makefile.in: Regenerate.
                * src/c++11/compatibility-ldbl-alt128-cxx11.cc: New file defining
                symbols using the old 128-bit long double format, for the cxx11 ABI.
                * src/c++11/compatibility-ldbl-alt128.cc: Likewise, for the
                gcc4-compatible ABI.
                * src/c++11/compatibility-ldbl-facets-aliases.h: New header for long
                double compat aliases.
                * src/c++11/cow-locale_init.cc: Add comment.
                * src/c++11/cxx11-locale-inst.cc: Define C and C_is_char
                unconditionally.
                * src/c++11/cxx11-wlocale-inst.cc: Add sanity check. Include
                locale-inst.cc directly, not via cxx11-locale-inst.cc.
                * src/c++11/locale-inst-monetary.h: New header for monetary category
                instantiations.
                * src/c++11/locale-inst-numeric.h: New header for numeric category
                instantiations.
                * src/c++11/locale-inst.cc: Include new headers for monetary, numeric,
                and long double definitions.
                * src/c++11/wlocale-inst.cc: Remove long double compat aliases that
                are defined in new header now.
                * src/c++17/Makefile.in: Regenerate.
                * src/c++98/Makefile.in: Regenerate.
                * src/c++98/locale_init.cc (num_facets): Adjust calculation.
                (locale::_Impl::_Impl(size_t)): Call _M_init_extra_ldbl128.
                * src/c++98/localename.cc (num_facets): Adjust calculation.
                (locale::_Impl::_Impl(const char*, size_t)): Call
                _M_init_extra_ldbl128.
                * src/filesystem/Makefile.in: Regenerate.
                * testsuite/Makefile.in: Regenerate.
                * testsuite/util/testsuite_abi.cc: Add new symbol versions.

Diff:
---
 libstdc++-v3/config/abi/pre/gnu.ver                |   8 +-
 .../config/os/gnu-linux/ldbl-ieee128-extra.ver     |  51 +++++
 libstdc++-v3/configure.ac                          |  35 ++-
 libstdc++-v3/fragment.am                           |   8 +-
 libstdc++-v3/include/Makefile.am                   |   6 +
 libstdc++-v3/include/bits/c++config                |  32 ++-
 libstdc++-v3/include/bits/locale_classes.h         |   4 +
 libstdc++-v3/include/bits/locale_facets.h          |  28 +++
 libstdc++-v3/include/bits/locale_facets.tcc        |  27 +++
 libstdc++-v3/include/bits/locale_facets_nonio.h    |  24 ++-
 libstdc++-v3/include/bits/locale_facets_nonio.tcc  |  61 +++++-
 libstdc++-v3/src/Makefile.am                       |  32 ++-
 .../src/c++11/compatibility-ldbl-alt128-cxx11.cc   | 102 +++++++++
 .../src/c++11/compatibility-ldbl-alt128.cc         | 234 +++++++++++++++++++++
 .../src/c++11/compatibility-ldbl-facets-aliases.h  | 128 +++++++++++
 libstdc++-v3/src/c++11/cow-locale_init.cc          |   1 +
 libstdc++-v3/src/c++11/cxx11-locale-inst.cc        |   6 +-
 libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc       |   8 +-
 libstdc++-v3/src/c++11/locale-inst-monetary.h      |  69 ++++++
 libstdc++-v3/src/c++11/locale-inst-numeric.h       | 133 ++++++++++++
 libstdc++-v3/src/c++11/locale-inst.cc              | 200 +-----------------
 libstdc++-v3/src/c++11/wlocale-inst.cc             |  45 +---
 libstdc++-v3/src/c++98/locale_init.cc              |  17 +-
 libstdc++-v3/src/c++98/localename.cc               |  16 +-
 libstdc++-v3/testsuite/util/testsuite_abi.cc       |  14 +-
 25 files changed, 1026 insertions(+), 263 deletions(-)

diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver
index 46769db1530..f2c88cbce2d 100644
--- a/libstdc++-v3/config/abi/pre/gnu.ver
+++ b/libstdc++-v3/config/abi/pre/gnu.ver
@@ -682,7 +682,7 @@ GLIBCXX_3.4 {
     _ZNSt12__basic_fileIcED*;
 
     # std::__convert_to_v
-    _ZSt14__convert_to_vI[^g]*;
+    _ZSt14__convert_to_vI[^gU]*;
 
     # __gnu_cxx::stdio_sync_filebuf
     _ZTVN9__gnu_cxx18stdio_sync_filebufI[cw]St11char_traitsI[cw]EEE;
@@ -931,7 +931,7 @@ GLIBCXX_3.4 {
     _ZGVNSt8time_putI[cw]*;
     _ZGVNSt9money_getI[cw]*;
     _ZGVNSt9money_putI[cw]*;
-    _ZGVNSt1[^07]*;
+    _ZGVNSt1[^079]*;
     _ZGVNSt10moneypunctI[cw]Lb[01]*;
 
     # exception constructors taking std::string
@@ -2702,6 +2702,10 @@ CXXABI_1.3.13 {
 
 } CXXABI_1.3.12;
 
+CXXABI_1.3.12 {
+
+} CXXABI_1.3.11;
+
 # Symbols in the support library (libsupc++) supporting transactional memory.
 CXXABI_TM_1 {
 
diff --git a/libstdc++-v3/config/os/gnu-linux/ldbl-ieee128-extra.ver b/libstdc++-v3/config/os/gnu-linux/ldbl-ieee128-extra.ver
new file mode 100644
index 00000000000..dca371b11f0
--- /dev/null
+++ b/libstdc++-v3/config/os/gnu-linux/ldbl-ieee128-extra.ver
@@ -0,0 +1,51 @@
+# Appended to version file.
+
+GLIBCXX_IEEE128_3.4.26 {
+
+  *__gnu_cxx_ieee128*;
+
+  _ZNSt14numeric_limitsIu9__ieee128E*;
+  _ZNSirsERu9__ieee128;
+  _ZNSolsEu9__ieee128;
+  _ZNSt13basic_istreamIwSt11char_traitsIwEErsERu9__ieee128;
+  _ZNSt13basic_ostreamIwSt11char_traitsIwEElsEu9__ieee128;
+  _ZSt14__convert_to_vIu9__ieee128EvPKcRT_RSt12_Ios_IostateRKP*;
+  _ZStlsIu9__ieee128[cw]St11char_traitsI[cw]EERSt13basic_ostreamIT0_T1_ES6_RKSt7complexIT_E;
+  _ZStrsIu9__ieee128[cw]St11char_traitsI[cw]EERSt13basic_istreamIT0_T1_ES6_RSt7complexIT_E;
+
+  _ZNSi10_M_extractIu9__ieee128EERSiRT_;
+  _ZNSt13basic_istreamIwSt11char_traitsIwEE10_M_extractIu9__ieee128EERS2_RT_;
+  _ZNSo9_M_insertIu9__ieee128EERSoT_;
+  _ZNSt13basic_ostreamIwSt11char_traitsIwEE9_M_insertIu9__ieee128EERS2_T_;
+
+  _ZNKSt3tr14hashIu9__ieee128EclEu9__ieee128;
+  _ZNKSt4hashIu9__ieee128EclEu9__ieee128;
+
+  _ZNKSt19__gnu_cxx11_ieee1289money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES4_S4_bRSt8ios_baseRSt12_Ios_IostateRNSt7__cxx1112basic_stringIcS3_SaIcEEE;
+  _ZNKSt19__gnu_cxx11_ieee1289money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES4_S4_bRSt8ios_baseRSt12_Ios_IostateRu9__ieee128;
+  _ZNKSt19__gnu_cxx11_ieee1289money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE8__do_getES4_S4_bRSt8ios_baseRSt12_Ios_IostateRd;
+  _ZNKSt19__gnu_cxx11_ieee1289money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE8__do_getES4_S4_bRSt8ios_baseRSt12_Ios_IostateRg;
+  _ZNKSt19__gnu_cxx11_ieee1289money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES4_bRSt8ios_basecRKNSt7__cxx1112basic_stringIcS3_SaIcEEE;
+  _ZNKSt19__gnu_cxx11_ieee1289money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES4_bRSt8ios_basecu9__ieee128;
+  _ZNKSt19__gnu_cxx11_ieee1289money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE8__do_putES4_bRSt8ios_basecd;
+  _ZNKSt19__gnu_cxx11_ieee1289money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE8__do_putES4_bRSt8ios_basecg;
+  _ZSt9has_facetINSt19__gnu_cxx11_ieee1289money_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEEEEbRKSt6locale;
+  _ZSt9has_facetINSt19__gnu_cxx11_ieee1289money_putI[cw]St19ostreambuf_iteratorI[cw]St11char_traitsI[cw]EEEEEbRKSt6locale;
+  _ZSt9use_facetINSt19__gnu_cxx11_ieee1289money_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEEEERKT_RKSt6locale;
+  _ZSt9use_facetINSt19__gnu_cxx11_ieee1289money_putI[cw]St19ostreambuf_iteratorI[cw]St11char_traitsI[cw]EEEEERKT_RKSt6locale;
+  _ZTINSt19__gnu_cxx11_ieee1289money_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEEE;
+  _ZTVNSt19__gnu_cxx11_ieee1289money_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEEE;
+  _ZTINSt19__gnu_cxx11_ieee1289money_putI[cw]St19ostreambuf_iteratorI[cw]St11char_traitsI[cw]EEEE;
+  _ZTVNSt19__gnu_cxx11_ieee1289money_putI[cw]St19ostreambuf_iteratorI[cw]St11char_traitsI[cw]EEEE;
+
+  _ZNKSt19__gnu_cxx11_ieee1289money_putI[cw]St19ostreambuf_iteratorI[cw]St11char_traitsI[cw]EEE3putES4_bRSt8ios_base[cw]u9__ieee128;
+
+} GLIBCXX_3.4.26;
+
+CXXABI_IEEE128_1.3.12 {
+
+  _ZT[IS]u9__ieee128;
+  _ZT[IS]Pu9__ieee128;
+  _ZT[IS]PKu9__ieee128;
+
+} CXXABI_1.3.12;
diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac
index cbfdf4c6bad..9d5b9b33ce9 100644
--- a/libstdc++-v3/configure.ac
+++ b/libstdc++-v3/configure.ac
@@ -404,7 +404,11 @@ GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI([yes])
 GLIBCXX_DEFAULT_ABI
 
 ac_ldbl_compat=no
+ac_ldbl_alt128_compat=no
+ac_ldbl_ieee128_default=no
 LONG_DOUBLE_COMPAT_FLAGS="-mlong-double-64"
+LONG_DOUBLE_128_FLAGS=
+LONG_DOUBLE_ALT128_COMPAT_FLAGS=
 case "$target" in
   powerpc*-*-linux* | \
   sparc*-*-linux* | \
@@ -421,12 +425,41 @@ case "$target" in
     port_specific_symbol_files="\$(top_srcdir)/config/os/gnu-linux/ldbl-extra.ver"
     case "$target" in
       powerpc*-*-linux*)
-	LONG_DOUBLE_COMPAT_FLAGS="$LONG_DOUBLE_COMPAT_FLAGS -mno-gnu-attribute" ;;
+	LONG_DOUBLE_COMPAT_FLAGS="$LONG_DOUBLE_COMPAT_FLAGS -mno-gnu-attribute"
+        # Check for IEEE128 support in libc:
+        AC_CHECK_FUNCS(frexpf128,
+                       [ac_ldbl_ieee128_in_libc=yes],
+                       [ac_ldbl_ieee128_in_libc=no])
+        if test $ac_ldbl_ieee128_in_libc = yes; then
+          # Determine which long double format is the compiler's default:
+          AC_TRY_COMPILE(, [
+            #ifndef __LONG_DOUBLE_IEEE128__
+            #error compiler defaults to ibm128
+            #endif
+          ], [ac_ldbl_ieee128_default=yes], [ac_ldbl_ieee128_default=no])
+          # Library objects should use IEEE128 long double format by default.
+          if test "$ac_ldbl_ieee128_default" = no; then
+            # Add -mabi=ieeelongdouble to ensire that.
+            LONG_DOUBLE_128_FLAGS="-mabi=ieeelongdouble -mno-gnu-attribute -Wno-psabi"
+          fi
+          # Except for the ones that explicitly use these flags:
+          LONG_DOUBLE_ALT128_COMPAT_FLAGS="-mabi=ibmlongdouble -mno-gnu-attribute -Wno-psabi"
+          AC_DEFINE([_GLIBCXX_LONG_DOUBLE_ALT128_COMPAT],1,
+                [Define if compatibility should be provided for alternative 128-bit long double formats.])
+          port_specific_symbol_files="$port_specific_symbol_files \$(top_srcdir)/config/os/gnu-linux/ldbl-ieee128-extra.ver"
+          ac_ldbl_alt128_compat=yes
+        else
+          ac_ldbl_alt128_compat=no
+        fi
+	;;
     esac
   fi
 esac
 AC_SUBST(LONG_DOUBLE_COMPAT_FLAGS)
+AC_SUBST(LONG_DOUBLE_128_FLAGS)
+AC_SUBST(LONG_DOUBLE_ALT128_COMPAT_FLAGS)
 GLIBCXX_CONDITIONAL(GLIBCXX_LDBL_COMPAT, test $ac_ldbl_compat = yes)
+GLIBCXX_CONDITIONAL(GLIBCXX_LDBL_ALT128_COMPAT, test $ac_ldbl_alt128_compat = yes)
 
 # Check if assembler supports disabling hardware capability support.
 GCC_CHECK_ASSEMBLER_HWCAP
diff --git a/libstdc++-v3/fragment.am b/libstdc++-v3/fragment.am
index 216c572fc60..54645739e5c 100644
--- a/libstdc++-v3/fragment.am
+++ b/libstdc++-v3/fragment.am
@@ -25,10 +25,16 @@ else
 XTEMPLATE_FLAGS =
 endif
 
+if GLIBCXX_LDBL_ALT128_COMPAT
+LDBL_128_FLAGS = $(LONG_DOUBLE_128_FLAGS)
+else
+LDBL_128_FLAGS =
+endif
+
 # These bits are all figured out from configure.  Look in acinclude.m4
 # or configure.ac to see how they are set.  See GLIBCXX_EXPORT_FLAGS.
 CONFIG_CXXFLAGS = \
-	$(SECTION_FLAGS) $(HWCAP_CFLAGS) -frandom-seed=$@
+	$(SECTION_FLAGS) $(HWCAP_CFLAGS) -frandom-seed=$@ $(LDBL_128_FLAGS)
 
 WARN_CXXFLAGS = \
 	$(WARN_FLAGS) $(WERROR_FLAG) -fdiagnostics-show-location=once 
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index ca413b8fdfe..5bd61bea6e3 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -1293,6 +1293,10 @@ ${host_builddir}/c++config.h: ${CONFIG_HEADER} \
 	grep "^[	 ]*#[	 ]*define[	 ][	 ]*_GLIBCXX_LONG_DOUBLE_COMPAT[	 ][	 ]*1[	 ]*$$" \
 	${CONFIG_HEADER} > /dev/null 2>&1 \
 	&& ldbl_compat='s,^#undef _GLIBCXX_LONG_DOUBLE_COMPAT$$,#define _GLIBCXX_LONG_DOUBLE_COMPAT 1,' ;\
+	ldbl_alt128_compat='s,g,g,' ;\
+	grep "^[	 ]*#[	 ]*define[	 ][	 ]*_GLIBCXX_LONG_DOUBLE_ALT128_COMPAT[	 ][	 ]*1[	 ]*$$" \
+	${CONFIG_HEADER} > /dev/null 2>&1 \
+	&& ldbl_alt128_compat='s,^#undef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT$$,#define _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT 1,' ;\
 	sed -e "s,define __GLIBCXX__,define __GLIBCXX__ $$date," \
 	-e "s,define _GLIBCXX_RELEASE,define _GLIBCXX_RELEASE $$release," \
 	-e "s,define _GLIBCXX_INLINE_VERSION, define _GLIBCXX_INLINE_VERSION $$ns_version," \
@@ -1303,6 +1307,7 @@ ${host_builddir}/c++config.h: ${CONFIG_HEADER} \
 	-e "s,define _GLIBCXX_USE_ALLOCATOR_NEW, define _GLIBCXX_USE_ALLOCATOR_NEW $$allocatornew," \
 	-e "s,define _GLIBCXX_USE_FLOAT128,$$float128," \
 	-e "$$ldbl_compat" \
+	-e "$$ldbl_alt128_compat" \
 	    < ${glibcxx_srcdir}/include/bits/c++config > $@ ;\
 	sed -e 's/HAVE_/_GLIBCXX_HAVE_/g' \
 	    -e 's/PACKAGE/_GLIBCXX_PACKAGE/g' \
@@ -1313,6 +1318,7 @@ ${host_builddir}/c++config.h: ${CONFIG_HEADER} \
 	    -e 's/_LARGE_FILES/_GLIBCXX_LARGE_FILES/g' \
 	    -e 's/ICONV_CONST/_GLIBCXX_ICONV_CONST/g' \
 	    -e '/[	 ]_GLIBCXX_LONG_DOUBLE_COMPAT[	 ]/d' \
+	    -e '/[	 ]_GLIBCXX_LONG_DOUBLE_ALT128_COMPAT[	 ]/d' \
 	    < ${CONFIG_HEADER} >> $@ ;\
 	echo "" >> $@ ;\
 	echo "#endif // _GLIBCXX_CXX_CONFIG_H" >> $@
diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config
index 2e6c880ad95..6af203d03ec 100644
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -425,8 +425,28 @@ _GLIBCXX_END_NAMESPACE_VERSION
 // GLIBCXX_ABI Deprecated
 // Define if compatibility should be provided for -mlong-double-64.
 #undef _GLIBCXX_LONG_DOUBLE_COMPAT
+// Define if compatibility should be provided for alternative 128-bit long
+// double formats.
+#undef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT
+
+// Inline namespaces for long double 128 modes.
+#if defined _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT \
+  && defined __LONG_DOUBLE_IEEE128__
+namespace std
+{
+  // Namespaces for 128-bit IEEE long double format on 64-bit POWER LE.
+  inline namespace __gnu_cxx_ieee128 { }
+  inline namespace __gnu_cxx11_ieee128 { }
+}
+# define _GLIBCXX_NAMESPACE_LDBL __gnu_cxx_ieee128::
+# define _GLIBCXX_BEGIN_NAMESPACE_LDBL namespace __gnu_cxx_ieee128 {
+# define _GLIBCXX_END_NAMESPACE_LDBL }
+# define _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 __gnu_cxx11_ieee128::
+# define _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11 namespace __gnu_cxx11_ieee128 {
+# define _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 }
+
+#else // _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT && IEEE128
 
-// Inline namespace for long double 128 mode.
 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
 namespace std
 {
@@ -440,6 +460,7 @@ namespace std
 # define _GLIBCXX_BEGIN_NAMESPACE_LDBL
 # define _GLIBCXX_END_NAMESPACE_LDBL
 #endif
+
 #if _GLIBCXX_USE_CXX11_ABI
 # define _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_NAMESPACE_CXX11
 # define _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_BEGIN_NAMESPACE_CXX11
@@ -450,6 +471,8 @@ namespace std
 # define _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_END_NAMESPACE_LDBL
 #endif
 
+#endif // _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT && IEEE128
+
 // Debug Mode implies checking assertions.
 #if defined(_GLIBCXX_DEBUG) && !defined(_GLIBCXX_ASSERTIONS)
 # define _GLIBCXX_ASSERTIONS 1
@@ -648,9 +671,12 @@ namespace std
 # define __cpp_lib_char8_t 201907L
 #endif
 
-/* Define if __float128 is supported on this host. */
+/* Define if __float128 is supported on this host.  */
 #if defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__)
-#define _GLIBCXX_USE_FLOAT128
+/* For powerpc64 don't use __float128 when it's the same type as long double. */
+# if !(defined(_GLIBCXX_LONG_DOUBLE_ALT128_COMPAT) && defined(__LONG_DOUBLE_IEEE128__))
+#  define _GLIBCXX_USE_FLOAT128
+# endif
 #endif
 
 #if __GNUC__ >= 7
diff --git a/libstdc++-v3/include/bits/locale_classes.h b/libstdc++-v3/include/bits/locale_classes.h
index ab90682cde2..ed7764e06e7 100644
--- a/libstdc++-v3/include/bits/locale_classes.h
+++ b/libstdc++-v3/include/bits/locale_classes.h
@@ -625,6 +625,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
     void _M_init_extra(facet**);
     void _M_init_extra(void*, void*, const char*, const char*);
+
+#ifdef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT
+    void _M_init_extra_ldbl128(bool);
+#endif
   };
 
 
diff --git a/libstdc++-v3/include/bits/locale_facets.h b/libstdc++-v3/include/bits/locale_facets.h
index 3e0ae8776c9..9b262c2d228 100644
--- a/libstdc++-v3/include/bits/locale_facets.h
+++ b/libstdc++-v3/include/bits/locale_facets.h
@@ -65,6 +65,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 # define _GLIBCXX_NUM_UNICODE_FACETS 2
 #endif
 
+// Facets duplicated for alt128 long double format
+// num_get, num_put, money_get, money_put (+ cxx11 money_get, money_put)
+#define _GLIBCXX_NUM_LBDL_ALT128_FACETS (4 + (_GLIBCXX_USE_DUAL_ABI ? 2 : 0))
+
   // Convert string to numeric value of type _Tp and store results.
   // NB: This is specialized for all required types, there is no
   // generic definition.
@@ -2252,6 +2256,10 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL
 
       // XXX GLIBCXX_ABI Deprecated
 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
+      // For __gnu_cxx_ldbl128::num_get and __gnu_cxx_ieee128::num_get
+      // this entry in the vtable is for a 64-bit "long double" with the
+      // same format as double. This keeps the vtable layout consistent
+      // with std::num_get (visible when -mlong-double-64 is used).
       virtual iter_type
       __do_get(iter_type, iter_type, ios_base&, ios_base::iostate&,
 	       double&) const;
@@ -2264,8 +2272,21 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL
       virtual iter_type
       do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, void*&) const;
 
+      // XXX GLIBCXX_ABI Deprecated
+#if defined _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT \
+      && defined __LONG_DOUBLE_IEEE128__
+      // For __gnu_cxx_ieee128::num_get this entry in the vtable is for
+      // the non-IEEE 128-bit "long double" (aka "double double"). This
+      // is consistent with __gnu_cxx_ldbl128::num_get (-mabi=ibmlongdouble)
+      virtual iter_type
+      __do_get(iter_type, iter_type, ios_base&, ios_base::iostate&,
+	       __ibm128&) const;
+#endif
+
       // XXX GLIBCXX_ABI Deprecated
 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
+      // For __gnu_cxx_ldbl128::num_get and __gnu_cxx_ieee128::num_get
+      // this entry in the vtable is for the 128-bit "long double" type.
       virtual iter_type
       do_get(iter_type, iter_type, ios_base&, ios_base::iostate&,
 	     long double&) const;
@@ -2545,6 +2566,13 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL
       virtual iter_type
       do_put(iter_type, ios_base&, char_type, const void*) const;
 
+      // XXX GLIBCXX_ABI Deprecated
+#if defined _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT \
+      && defined __LONG_DOUBLE_IEEE128__
+      virtual iter_type
+      __do_put(iter_type, ios_base&, char_type, __ibm128) const;
+#endif
+
       // XXX GLIBCXX_ABI Deprecated
 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
       virtual iter_type
diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc
index ebc993339a6..4fdca180a87 100644
--- a/libstdc++-v3/include/bits/locale_facets.tcc
+++ b/libstdc++-v3/include/bits/locale_facets.tcc
@@ -772,6 +772,24 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL
       return __beg;
     }
 
+#if defined _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT \
+      && defined __LONG_DOUBLE_IEEE128__
+  template<typename _CharT, typename _InIter>
+    _InIter
+    num_get<_CharT, _InIter>::
+    __do_get(iter_type __beg, iter_type __end, ios_base& __io,
+	     ios_base::iostate& __err, __ibm128& __v) const
+    {
+      string __xtrc;
+      __xtrc.reserve(32);
+      __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
+      std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale());
+      if (__beg == __end)
+	__err |= ios_base::eofbit;
+      return __beg;
+    }
+#endif
+
   // For use by integer and floating-point types after they have been
   // converted into a char_type string.
   template<typename _CharT, typename _OutIter>
@@ -1194,6 +1212,15 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL
       return __s;
     }
 
+#if defined _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT \
+      && defined __LONG_DOUBLE_IEEE128__
+  template<typename _CharT, typename _OutIter>
+    _OutIter
+    num_put<_CharT, _OutIter>::
+    __do_put(iter_type __s, ios_base& __io, char_type __fill,
+	     __ibm128 __v) const
+    { return _M_insert_float(__s, __io, __fill, 'L', __v); }
+#endif
 _GLIBCXX_END_NAMESPACE_LDBL
 
   // Construct correctly padded string, as per 22.2.2.2.2
diff --git a/libstdc++-v3/include/bits/locale_facets_nonio.h b/libstdc++-v3/include/bits/locale_facets_nonio.h
index b76eac435bd..6af68d3fa90 100644
--- a/libstdc++-v3/include/bits/locale_facets_nonio.h
+++ b/libstdc++-v3/include/bits/locale_facets_nonio.h
@@ -1566,7 +1566,7 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11
        */
       // XXX GLIBCXX_ABI Deprecated
 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ \
-      && _GLIBCXX_USE_CXX11_ABI == 0
+      && (_GLIBCXX_USE_CXX11_ABI == 0 || defined __LONG_DOUBLE_IEEE128__)
       virtual iter_type
       __do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
 	       ios_base::iostate& __err, double& __units) const;
@@ -1587,9 +1587,17 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11
       do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
 	     ios_base::iostate& __err, string_type& __digits) const;
 
+      // XXX GLIBCXX_ABI Deprecated
+#if defined _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT \
+      && defined __LONG_DOUBLE_IEEE128__
+      virtual iter_type
+      __do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
+	       ios_base::iostate& __err, __ibm128& __units) const;
+#endif
+
       // XXX GLIBCXX_ABI Deprecated
 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ \
-      && _GLIBCXX_USE_CXX11_ABI == 0
+      && (_GLIBCXX_USE_CXX11_ABI == 0 || defined __LONG_DOUBLE_IEEE128__)
       virtual iter_type
       do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
 	     ios_base::iostate& __err, long double& __units) const;
@@ -1711,7 +1719,7 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11
        */
       // XXX GLIBCXX_ABI Deprecated
 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ \
-      && _GLIBCXX_USE_CXX11_ABI == 0
+      && (_GLIBCXX_USE_CXX11_ABI == 0 || defined __LONG_DOUBLE_IEEE128__)
       virtual iter_type
       __do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
 	       double __units) const;
@@ -1744,9 +1752,17 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11
       do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
 	     const string_type& __digits) const;
 
+      // XXX GLIBCXX_ABI Deprecated
+#if defined _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT \
+      && defined __LONG_DOUBLE_IEEE128__
+      virtual iter_type
+      __do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
+	       __ibm128 __units) const;
+#endif
+
       // XXX GLIBCXX_ABI Deprecated
 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ \
-      && _GLIBCXX_USE_CXX11_ABI == 0
+      && (_GLIBCXX_USE_CXX11_ABI == 0 || defined __LONG_DOUBLE_IEEE128__)
       virtual iter_type
       do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
 	     long double __units) const;
diff --git a/libstdc++-v3/include/bits/locale_facets_nonio.tcc b/libstdc++-v3/include/bits/locale_facets_nonio.tcc
index a8639f6ba28..9e2b6577969 100644
--- a/libstdc++-v3/include/bits/locale_facets_nonio.tcc
+++ b/libstdc++-v3/include/bits/locale_facets_nonio.tcc
@@ -350,7 +350,7 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11
       }
 
 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ \
-      && _GLIBCXX_USE_CXX11_ABI == 0
+      && (_GLIBCXX_USE_CXX11_ABI == 0 || defined __LONG_DOUBLE_IEEE128__)
   template<typename _CharT, typename _InIter>
     _InIter
     money_get<_CharT, _InIter>::
@@ -401,6 +401,22 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11
       return __beg;
     }
 
+#if defined _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT \
+      && defined __LONG_DOUBLE_IEEE128__
+  template<typename _CharT, typename _InIter>
+    _InIter
+    money_get<_CharT, _InIter>::
+    __do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io,
+	     ios_base::iostate& __err, __ibm128& __units) const
+    {
+      string __str;
+      __beg = __intl ? _M_extract<true>(__beg, __end, __io, __err, __str)
+	             : _M_extract<false>(__beg, __end, __io, __err, __str);
+      std::__convert_to_v(__str.c_str(), __units, __err, _S_get_c_locale());
+      return __beg;
+    }
+#endif
+
   template<typename _CharT, typename _OutIter>
     template<bool _Intl>
       _OutIter
@@ -562,7 +578,7 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11
       }
 
 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ \
-      && _GLIBCXX_USE_CXX11_ABI == 0
+      && (_GLIBCXX_USE_CXX11_ABI == 0 || defined __LONG_DOUBLE_IEEE128__)
   template<typename _CharT, typename _OutIter>
     _OutIter
     money_put<_CharT, _OutIter>::
@@ -617,6 +633,47 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11
     { return __intl ? _M_insert<true>(__s, __io, __fill, __digits)
 	            : _M_insert<false>(__s, __io, __fill, __digits); }
 
+#if defined _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT \
+      && defined __LONG_DOUBLE_IEEE128__
+  template<typename _CharT, typename _OutIter>
+    _OutIter
+    money_put<_CharT, _OutIter>::
+    __do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
+	     __ibm128 __units) const
+    {
+      const locale __loc = __io.getloc();
+      const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
+#if _GLIBCXX_USE_C99_STDIO
+      // First try a buffer perhaps big enough.
+      int __cs_size = 64;
+      char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // 328. Bad sprintf format modifier in money_put<>::do_put()
+      int __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size,
+					"%.*Lf", 0, __units);
+      // If the buffer was not large enough, try again with the correct size.
+      if (__len >= __cs_size)
+	{
+	  __cs_size = __len + 1;
+	  __cs = static_cast<char*>(__builtin_alloca(__cs_size));
+	  __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size,
+					"%.*Lf", 0, __units);
+	}
+#else
+      // max_exponent10 + 1 for the integer part, + 2 for sign and '\0'.
+      const int __cs_size =
+	__gnu_cxx::__numeric_traits<long double>::__max_exponent10 + 3;
+      char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
+      int __len = std::__convert_from_v(_S_get_c_locale(), __cs, 0, "%.*Lf", 
+					0, __units);
+#endif
+      string_type __digits(__len, char_type());
+      __ctype.widen(__cs, __cs + __len, &__digits[0]);
+      return __intl ? _M_insert<true>(__s, __io, __fill, __digits)
+	            : _M_insert<false>(__s, __io, __fill, __digits);
+    }
+#endif
+
 _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11
 
   // NB: Not especially useful. Without an ios_base object or some
diff --git a/libstdc++-v3/src/Makefile.am b/libstdc++-v3/src/Makefile.am
index 21b6db7fb1c..739d15d2ccb 100644
--- a/libstdc++-v3/src/Makefile.am
+++ b/libstdc++-v3/src/Makefile.am
@@ -71,6 +71,20 @@ else
 ldbl_compat_sources =
 endif
 
+if GLIBCXX_LDBL_ALT128_COMPAT
+if ENABLE_DUAL_ABI
+ldbl_alt128_compat_cxx11_sources = \
+	compatibility-ldbl-alt128-cxx11.cc
+else
+ldbl_alt128_compat_cxx11_sources =
+endif
+ldbl_alt128_compat_sources = \
+	compatibility-ldbl-alt128.cc \
+	${ldbl_alt128_compat_cxx11_sources}
+else
+ldbl_alt128_compat_sources =
+endif
+
 
 parallel_compat_sources = \
 	compatibility-parallel_list.cc  compatibility-parallel_list-2.cc
@@ -87,7 +101,8 @@ cxx11_sources = \
 	compatibility-atomic-c++0x.cc \
 	compatibility-thread-c++0x.cc \
 	compatibility-chrono.cc \
-	compatibility-condvar.cc
+	compatibility-condvar.cc \
+	${ldbl_alt128_compat_sources}
 
 libstdc___la_SOURCES = $(cxx98_sources) $(cxx11_sources)
 
@@ -121,6 +136,21 @@ compatibility-ldbl.o: compatibility-ldbl.cc
 	$(CXXCOMPILE) $(LONG_DOUBLE_COMPAT_FLAGS) -c $<
 endif
 
+# Use special rules for compatibility-ldbl-alt128.cc compilation, as we need to
+# ensure it is compiled with the correct flag.
+if GLIBCXX_LDBL_ALT128_COMPAT
+compatibility-ldbl-alt128.lo: compatibility-ldbl-alt128.cc
+	$(LTCXXCOMPILE) $(LONG_DOUBLE_ALT128_COMPAT_FLAGS) -std=gnu++11 -c $<
+compatibility-ldbl-alt128.o: compatibility-ldbl-alt128.cc
+	$(CXXCOMPILE) $(LONG_DOUBLE_ALT128_COMPAT_FLAGS) -std=gnu++11 -c $<
+if ENABLE_DUAL_ABI
+compatibility-ldbl-alt128-cxx11.lo: compatibility-ldbl-alt128-cxx11.cc
+	$(LTCXXCOMPILE) $(LONG_DOUBLE_ALT128_COMPAT_FLAGS) -std=gnu++11 -c $<
+compatibility-ldbl-alt128-cxx11.o: compatibility-ldbl-alt128-cxx11.cc
+	$(CXXCOMPILE) $(LONG_DOUBLE_ALT128_COMPAT_FLAGS) -std=gnu++11 -c $<
+endif
+endif
+
 # Use special rules for C++11 files/objects.
 compatibility-c++0x.lo: compatibility-c++0x.cc
 	$(LTCXXCOMPILE) -std=gnu++11 -c $<
diff --git a/libstdc++-v3/src/c++11/compatibility-ldbl-alt128-cxx11.cc b/libstdc++-v3/src/c++11/compatibility-ldbl-alt128-cxx11.cc
new file mode 100644
index 00000000000..21d5a6ca421
--- /dev/null
+++ b/libstdc++-v3/src/c++11/compatibility-ldbl-alt128-cxx11.cc
@@ -0,0 +1,102 @@
+// Compatibility symbols for alternate 128-bit long-double format -*- C++ -*-
+
+// Copyright (C) 2018 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library 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.
+
+// This 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 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/>.
+
+#define _GLIBCXX_USE_CXX11_ABI 1
+#include <locale>
+
+#ifdef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT
+
+#if !defined(_GLIBCXX_USE_DUAL_ABI)
+#error "compatibility-ldbl-alt128-cxx11.cc must only be compiled when dual ABI is enabled"
+#endif
+
+#ifndef __LONG_DOUBLE_IBM128__
+#error "compatibility-ldbl-alt128.cc must be compiled with -mabi=ibmlongdouble"
+#endif
+
+#define C char
+#define C_is_char
+#include "locale-inst-monetary.h"
+
+#ifdef _GLIBCXX_USE_WCHAR_T
+# undef C
+# undef C_is_char
+# define C wchar_t
+# include "locale-inst-monetary.h"
+#endif
+
+#include <functional>
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  namespace
+  {
+    alignas(money_get<char>) char money_get_c[sizeof(money_get<char>)];
+    alignas(money_put<char>) char money_put_c[sizeof(money_put<char>)];
+#ifdef _GLIBCXX_USE_WCHAR_T
+    alignas(money_get<wchar_t>) char money_get_w[sizeof(money_get<wchar_t>)];
+    alignas(money_put<wchar_t>) char money_put_w[sizeof(money_put<wchar_t>)];
+#endif
+
+  template<typename Facet>
+    void
+    init_facet(function<void(const locale::id*, const locale::facet*)>& func,
+	       Facet* facet)
+    {
+      func(&Facet::id, facet);
+    }
+
+  } // namespace
+
+  template class function<void(const locale::id*, const locale::facet*)>;
+
+  void
+  __locale_Impl_init_extra_ldbl128(
+      function<void(const locale::id*, const locale::facet*)> f,
+      bool classic)
+  {
+    if (classic)
+      {
+	init_facet(f, new (&money_get_c) money_get<char>(1));
+	init_facet(f, new (&money_put_c) money_put<char>(1));
+#ifdef _GLIBCXX_USE_WCHAR_T
+	init_facet(f, new (&money_get_w) money_get<wchar_t>(1));
+	init_facet(f, new (&money_put_w) money_put<wchar_t>(1));
+#endif
+      }
+    else
+      {
+	init_facet(f, new money_get<char>);
+	init_facet(f, new money_put<char>);
+#ifdef _GLIBCXX_USE_WCHAR_T
+	init_facet(f, new money_get<wchar_t>);
+	init_facet(f, new money_put<wchar_t>);
+#endif
+      }
+  }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
+#endif
diff --git a/libstdc++-v3/src/c++11/compatibility-ldbl-alt128.cc b/libstdc++-v3/src/c++11/compatibility-ldbl-alt128.cc
new file mode 100644
index 00000000000..27852f6e271
--- /dev/null
+++ b/libstdc++-v3/src/c++11/compatibility-ldbl-alt128.cc
@@ -0,0 +1,234 @@
+// Compatibility symbols for alternate 128-bit long-double format -*- C++ -*-
+
+// Copyright (C) 2018 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library 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.
+
+// This 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 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/>.
+
+#define _GLIBCXX_USE_CXX11_ABI 0
+#include <locale>
+
+#ifdef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT
+
+#ifndef __LONG_DOUBLE_IBM128__
+#error "compatibility-ldbl-alt128.cc must be compiled with -mabi=ibmlongdouble"
+#endif
+
+#define C char
+#define C_is_char
+#include "locale-inst-numeric.h"
+#include "locale-inst-monetary.h"
+#include "compatibility-ldbl-facets-aliases.h"
+
+#ifdef _GLIBCXX_USE_WCHAR_T
+# undef C
+# undef C_is_char
+# define C wchar_t
+# include "locale-inst-numeric.h"
+# include "locale-inst-monetary.h"
+# include "compatibility-ldbl-facets-aliases.h"
+# undef C
+#endif
+
+#include <limits>
+#include <functional>
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  // long double
+  const bool numeric_limits<long double>::is_specialized;
+  const int  numeric_limits<long double>::digits;
+  const int  numeric_limits<long double>::digits10;
+  const int  numeric_limits<long double>::max_digits10;
+  const bool numeric_limits<long double>::is_signed;
+  const bool numeric_limits<long double>::is_integer;
+  const bool numeric_limits<long double>::is_exact;
+  const int  numeric_limits<long double>::radix;
+  const int  numeric_limits<long double>::min_exponent;
+  const int  numeric_limits<long double>::min_exponent10;
+  const int  numeric_limits<long double>::max_exponent;
+  const int  numeric_limits<long double>::max_exponent10;
+  const bool numeric_limits<long double>::has_infinity;
+  const bool numeric_limits<long double>::has_quiet_NaN;
+  const bool numeric_limits<long double>::has_signaling_NaN;
+  const float_denorm_style numeric_limits<long double>::has_denorm;
+  const bool numeric_limits<long double>::has_denorm_loss;
+  const bool numeric_limits<long double>::is_iec559;
+  const bool numeric_limits<long double>::is_bounded;
+  const bool numeric_limits<long double>::is_modulo;
+  const bool numeric_limits<long double>::traps;
+  const bool numeric_limits<long double>::tinyness_before;
+  const float_round_style numeric_limits<long double>::round_style;
+
+  template<>
+    void
+    __convert_to_v(const char* __s, long double& __v, ios_base::iostate& __err,
+		   const __c_locale& __cloc) throw()
+    {
+      char* __sanity;
+#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
+      // Prefer strtold_l, as __strtold_l isn't prototyped in more recent
+      // glibc versions.
+      __v = strtold_l(__s, &__sanity, __cloc);
+#else
+      __v = __strtold_l(__s, &__sanity, __cloc);
+#endif
+
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // 23. Num_get overflow result.
+      if (__sanity == __s || *__sanity != '\0')
+	{
+	  __v = 0.0l;
+	  __err = ios_base::failbit;
+	}
+      else if (__v == numeric_limits<long double>::infinity())
+	{
+	  __v = numeric_limits<long double>::max();
+	  __err = ios_base::failbit;
+	}
+      else if (__v == -numeric_limits<long double>::infinity())
+	{
+	  __v = -numeric_limits<long double>::max();
+	  __err = ios_base::failbit;
+	}
+    }
+
+  namespace
+  {
+    alignas(money_get<char>) char money_get_c[sizeof(money_get<char>)];
+    alignas(money_put<char>) char money_put_c[sizeof(money_put<char>)];
+    alignas(num_get<char>) char num_get_c[sizeof(num_get<char>)];
+    alignas(num_put<char>) char num_put_c[sizeof(num_put<char>)];
+#ifdef _GLIBCXX_USE_WCHAR_T
+    alignas(money_get<wchar_t>) char money_get_w[sizeof(money_get<wchar_t>)];
+    alignas(money_put<wchar_t>) char money_put_w[sizeof(money_put<wchar_t>)];
+    alignas(num_get<wchar_t>) char num_get_w[sizeof(num_get<wchar_t>)];
+    alignas(num_put<wchar_t>) char num_put_w[sizeof(num_put<wchar_t>)];
+#endif
+  }
+
+  extern void
+  __locale_Impl_init_extra_ldbl128(
+      function<void(const locale::id*, const locale::facet*)>,
+      bool);
+
+  void
+  locale::_Impl::_M_init_extra_ldbl128(bool classic)
+  {
+    if (classic)
+      {
+	_M_init_facet(new (&money_get_c) money_get<char>(1));
+	_M_init_facet(new (&money_put_c) money_put<char>(1));
+	_M_init_facet(new (&num_get_c) num_get<char>(1));
+	_M_init_facet(new (&num_put_c) num_put<char>(1));
+#ifdef _GLIBCXX_USE_WCHAR_T
+	_M_init_facet(new (&money_get_w) money_get<wchar_t>(1));
+	_M_init_facet(new (&money_put_w) money_put<wchar_t>(1));
+	_M_init_facet(new (&num_get_w) num_get<wchar_t>(1));
+	_M_init_facet(new (&num_put_w) num_put<wchar_t>(1));
+#endif
+      }
+    else
+      {
+	_M_init_facet(new money_get<char>);
+	_M_init_facet(new money_put<char>);
+	_M_init_facet(new num_get<char>);
+	_M_init_facet(new num_put<char>);
+#ifdef _GLIBCXX_USE_WCHAR_T
+	_M_init_facet(new money_get<wchar_t>);
+	_M_init_facet(new money_put<wchar_t>);
+	_M_init_facet(new num_get<wchar_t>);
+	_M_init_facet(new num_put<wchar_t>);
+#endif
+      }
+
+#if _GLIBCXX_USE_DUAL_ABI
+    __locale_Impl_init_extra_ldbl128(
+	[this](const locale::id* i, const facet* f) {
+	    _M_install_facet(i, f);
+	},
+	classic);
+#endif
+  }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
+
+#include <istream>
+#include <ostream>
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+  template istream& istream::operator>>(long double&);
+  template istream& istream::_M_extract(long double&);
+  template ostream& ostream::operator<<(long double);
+  template ostream& ostream::_M_insert(long double);
+#ifdef _GLIBCXX_USE_WCHAR_T
+  template wistream& wistream::operator>>(long double&);
+  template wistream& wistream::_M_extract(long double&);
+  template wostream& wostream::operator<<(long double);
+  template wostream& wostream::_M_insert(long double);
+#endif
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
+
+#include <complex>
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+  template
+    basic_istream<char, char_traits<char> >&
+    operator>>(basic_istream<char, char_traits<char> >&,
+	       complex<long double>&);
+  template
+    basic_ostream<char, char_traits<char> >&
+    operator<<(basic_ostream<char, char_traits<char> >&,
+               const complex<long double>&);
+#ifdef _GLIBCXX_USE_WCHAR_T
+  template
+    basic_istream<wchar_t, char_traits<wchar_t> >&
+    operator>>(basic_istream<wchar_t, char_traits<wchar_t> >&,
+               complex<long double>&);
+  template
+    basic_ostream<wchar_t, char_traits<wchar_t> >&
+    operator<<(basic_ostream<wchar_t, char_traits<wchar_t> >&,
+               const complex<long double>&);
+#endif
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
+
+#include <cmath>
+#include <tr1/functional>
+
+// For std::tr1::hash<long double>::operator()
+#include "../c++98/hash-long-double-tr1-aux.cc"
+
+// std::tr1::hash<long double>::operator()
+// and std::hash<long double>::operator()
+// are the same, no need to duplicate them.
+extern "C" void
+_ZNKSt4hashIgEclEg (void)
+  __attribute__((alias ("_ZNKSt3tr14hashIgEclEg")));
+
+#endif
diff --git a/libstdc++-v3/src/c++11/compatibility-ldbl-facets-aliases.h b/libstdc++-v3/src/c++11/compatibility-ldbl-facets-aliases.h
new file mode 100644
index 00000000000..7bdf9810d0e
--- /dev/null
+++ b/libstdc++-v3/src/c++11/compatibility-ldbl-facets-aliases.h
@@ -0,0 +1,128 @@
+// Compatibility aliases for long double support in locales -*- C++ -*-
+
+// Copyright (C) 1999-2018 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library 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.
+
+// This 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 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/>.
+
+#ifndef C
+#define "This file should not be compiled directly, only included"
+#endif
+
+#ifndef _GLIBCXX_LONG_DOUBLE_COMPAT
+#define "This file should only be used for _GLIBCXX_LONG_DOUBLE_COMPAT builds"
+#endif
+
+// XXX GLIBCXX_ABI Deprecated
+#if defined __LONG_DOUBLE_128__ && ! defined __LONG_DOUBLE_IEEE128__
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wattribute-alias"
+
+#define _GLIBCXX_LDBL_COMPAT(dbl, ldbl) \
+  extern "C" void ldbl (void) __attribute__ ((alias (#dbl), weak))
+
+// Define members of std::num_get and std::num_put as aliases for
+// members of __gnu_cxx_ldbl128::num_get and __gnu_cxx_ldbl128::num_put
+#ifdef C_is_char
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIjEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
+		     _ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIjEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIlEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
+		     _ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIlEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intImEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
+		     _ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intImEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intItEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
+		     _ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intItEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIxEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
+		     _ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIxEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIyEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
+		     _ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIyEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intIlEES4_S4_RSt8ios_basecT_,
+		     _ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intIlEES3_S3_RSt8ios_basecT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intImEES4_S4_RSt8ios_basecT_,
+		     _ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intImEES3_S3_RSt8ios_basecT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intIxEES4_S4_RSt8ios_basecT_,
+		     _ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intIxEES3_S3_RSt8ios_basecT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intIyEES4_S4_RSt8ios_basecT_,
+		     _ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intIyEES3_S3_RSt8ios_basecT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES4_S4_RSt8ios_baseccT_,
+		     _ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_,
+		     _ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIeEES3_S3_RSt8ios_baseccT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1289money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE10_M_extractILb0EEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRSs,
+		     _ZNKSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE10_M_extractILb0EEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRSs);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1289money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE10_M_extractILb1EEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRSs,
+		     _ZNKSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE10_M_extractILb1EEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRSs);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1289money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE9_M_insertILb0EEES4_S4_RSt8ios_basecRKSs,
+		     _ZNKSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE9_M_insertILb0EEES3_S3_RSt8ios_basecRKSs);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1289money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE9_M_insertILb1EEES4_S4_RSt8ios_basecRKSs,
+		     _ZNKSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE9_M_insertILb1EEES3_S3_RSt8ios_basecRKSs);
+#else // ! C_is_char
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIjEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
+		     _ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIjEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIlEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
+		     _ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIlEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intImEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
+		     _ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intImEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intItEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
+		     _ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intItEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIxEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
+		     _ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIxEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIyEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
+		     _ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIyEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intIlEES4_S4_RSt8ios_basewT_,
+		     _ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intIlEES3_S3_RSt8ios_basewT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intImEES4_S4_RSt8ios_basewT_,
+		     _ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intImEES3_S3_RSt8ios_basewT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intIxEES4_S4_RSt8ios_basewT_,
+		     _ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intIxEES3_S3_RSt8ios_basewT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intIyEES4_S4_RSt8ios_basewT_,
+		     _ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intIyEES3_S3_RSt8ios_basewT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE15_M_insert_floatIdEES4_S4_RSt8ios_basewcT_,
+		     _ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE15_M_insert_floatIdEES3_S3_RSt8ios_basewcT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE15_M_insert_floatIdEES3_S3_RSt8ios_basewcT_,
+		     _ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE15_M_insert_floatIeEES3_S3_RSt8ios_basewcT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1289money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE10_M_extractILb0EEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRSs,
+		     _ZNKSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE10_M_extractILb0EEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRSs);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1289money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE10_M_extractILb1EEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRSs,
+		     _ZNKSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE10_M_extractILb1EEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRSs);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1289money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE9_M_insertILb0EEES4_S4_RSt8ios_basewRKSbIwS3_SaIwEE,
+		     _ZNKSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE9_M_insertILb0EEES3_S3_RSt8ios_basewRKSbIwS2_SaIwEE);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1289money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE9_M_insertILb1EEES4_S4_RSt8ios_basewRKSbIwS3_SaIwEE,
+		     _ZNKSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE9_M_insertILb1EEES3_S3_RSt8ios_basewRKSbIwS2_SaIwEE);
+#endif // C_is_char
+
+
+#if defined _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT
+// Define __gnu_cxx_ieee128::num_put<>::_M_insert_float(..., __ibm128) as
+// alias of __gnu_cxx_ldbl128::num_put<>::_M_insert_float(..., __ibm128)
+# ifdef C_is_char
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIgEES4_S4_RSt8ios_baseccT_,
+		     _ZNKSt17__gnu_cxx_ieee1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIgEES4_S4_RSt8ios_baseccT_);
+# else
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE15_M_insert_floatIgEES4_S4_RSt8ios_basewcT_,
+		     _ZNKSt17__gnu_cxx_ieee1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE15_M_insert_floatIgEES4_S4_RSt8ios_basewcT_);
+# endif
+#endif // _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT
+
+#undef _GLIBCXX_LDBL_COMPAT
+#pragma GCC diagnostic pop
+
+#endif  // __LONG_DOUBLE_128__ && ! __LONG_DOUBLE_IEEE128__
diff --git a/libstdc++-v3/src/c++11/cow-locale_init.cc b/libstdc++-v3/src/c++11/cow-locale_init.cc
index 98a2ef41f56..bf270712e47 100644
--- a/libstdc++-v3/src/c++11/cow-locale_init.cc
+++ b/libstdc++-v3/src/c++11/cow-locale_init.cc
@@ -125,6 +125,7 @@ namespace
     _M_init_facet_unchecked(new (&messages_w) std::messages<wchar_t>(1));
 #endif
 
+    // The caches must be populated last, after creating all facets.
     _M_caches[numpunct<char>::id._M_id()] = __npc;
     _M_caches[moneypunct<char, false>::id._M_id()] = __mpcf;
     _M_caches[moneypunct<char, true>::id._M_id()] = __mpct;
diff --git a/libstdc++-v3/src/c++11/cxx11-locale-inst.cc b/libstdc++-v3/src/c++11/cxx11-locale-inst.cc
index 7b132a748bf..9378550124f 100644
--- a/libstdc++-v3/src/c++11/cxx11-locale-inst.cc
+++ b/libstdc++-v3/src/c++11/cxx11-locale-inst.cc
@@ -32,8 +32,6 @@
 # error This file should not be compiled for this configuration.
 #endif
 
-#ifndef C
-# define C char
-# define C_is_char
-#endif
+#define C char
+#define C_is_char
 # include "locale-inst.cc"
diff --git a/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc b/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc
index cf3d6dc7e34..07eb6008361 100644
--- a/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc
+++ b/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc
@@ -24,9 +24,15 @@
 // ISO C++ 14882: 22.1  Locales
 //
 
+// Facet wchar_t instantiations using new ABI strings.
+
 #define _GLIBCXX_USE_CXX11_ABI 1
 #include <bits/c++config.h>
+#if ! _GLIBCXX_USE_DUAL_ABI
+# error This file should not be compiled for this configuration.
+#endif
+
 #ifdef _GLIBCXX_USE_WCHAR_T
 #define C wchar_t
-#include "cxx11-locale-inst.cc"
+#include "locale-inst.cc"
 #endif
diff --git a/libstdc++-v3/src/c++11/locale-inst-monetary.h b/libstdc++-v3/src/c++11/locale-inst-monetary.h
new file mode 100644
index 00000000000..e9b3e7c4e0c
--- /dev/null
+++ b/libstdc++-v3/src/c++11/locale-inst-monetary.h
@@ -0,0 +1,69 @@
+// Explicit instantantiations for monetary facets -*- C++ -*-
+
+// Copyright (C) 2018 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library 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.
+
+// This 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 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/>.
+
+#ifndef C
+#define "This file should not be compiled directly, only included"
+#endif
+
+// This header is included multiple times, to instantiate these symbols
+// for char/wchar_t and for both std::string ABIs,
+// and (depending on the target) for two long double formats.
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+  template const money_put<C>& use_facet<money_put<C> >(const locale&);
+  template const money_get<C>& use_facet<money_get<C> >(const locale&);
+
+  template bool has_facet<money_put<C> >(const locale&);
+  template bool has_facet<money_get<C> >(const locale&);
+
+_GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11
+  template class money_get<C, istreambuf_iterator<C> >;
+  template class money_put<C, ostreambuf_iterator<C> >;
+
+  template
+    istreambuf_iterator<C>
+    money_get<C, istreambuf_iterator<C> >::
+    _M_extract<true>(istreambuf_iterator<C>, istreambuf_iterator<C>,
+		     ios_base&, ios_base::iostate&, string&) const;
+
+  template
+    istreambuf_iterator<C>
+    money_get<C, istreambuf_iterator<C> >::
+    _M_extract<false>(istreambuf_iterator<C>, istreambuf_iterator<C>,
+		      ios_base&, ios_base::iostate&, string&) const;
+
+  template
+    ostreambuf_iterator<C>
+    money_put<C, ostreambuf_iterator<C> >::
+    _M_insert<true>(ostreambuf_iterator<C>, ios_base&, C,
+		    const string_type&) const;
+
+  template
+    ostreambuf_iterator<C>
+    money_put<C, ostreambuf_iterator<C> >::
+    _M_insert<false>(ostreambuf_iterator<C>, ios_base&, C,
+		     const string_type&) const;
+_GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11
+} // namespace std
diff --git a/libstdc++-v3/src/c++11/locale-inst-numeric.h b/libstdc++-v3/src/c++11/locale-inst-numeric.h
new file mode 100644
index 00000000000..0ec93e27937
--- /dev/null
+++ b/libstdc++-v3/src/c++11/locale-inst-numeric.h
@@ -0,0 +1,133 @@
+// Explicit instantantiations for numeric facets -*- C++ -*-
+
+// Copyright (C) 2018 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library 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.
+
+// This 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 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/>.
+
+#ifndef C
+#define "This file should not be compiled directly, only included"
+#endif
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+#if ! _GLIBCXX_USE_CXX11_ABI
+  template const num_get<C>& use_facet<num_get<C> >(const locale&);
+  template const num_put<C>& use_facet<num_put<C> >(const locale&);
+
+  template bool has_facet<num_get<C> >(const locale&);
+  template bool has_facet<num_put<C> >(const locale&);
+#endif
+
+_GLIBCXX_BEGIN_NAMESPACE_LDBL
+
+#if ! _GLIBCXX_USE_CXX11_ABI
+  template class num_get<C, istreambuf_iterator<C> >;
+  template class num_put<C, ostreambuf_iterator<C> >;
+#endif
+
+  // num_get member function templates
+  template
+    istreambuf_iterator<C>
+    num_get<C, istreambuf_iterator<C> >::
+    _M_extract_int(istreambuf_iterator<C>, istreambuf_iterator<C>,
+		   ios_base&, ios_base::iostate&,
+		   long&) const;
+
+  template
+    istreambuf_iterator<C>
+    num_get<C, istreambuf_iterator<C> >::
+    _M_extract_int(istreambuf_iterator<C>, istreambuf_iterator<C>,
+		   ios_base&, ios_base::iostate&,
+		   unsigned short&) const;
+
+  template
+    istreambuf_iterator<C>
+    num_get<C, istreambuf_iterator<C> >::
+    _M_extract_int(istreambuf_iterator<C>, istreambuf_iterator<C>,
+		   ios_base&, ios_base::iostate&,
+		   unsigned int&) const;
+
+  template
+    istreambuf_iterator<C>
+    num_get<C, istreambuf_iterator<C> >::
+    _M_extract_int(istreambuf_iterator<C>, istreambuf_iterator<C>,
+		   ios_base&, ios_base::iostate&,
+		   unsigned long&) const;
+
+#ifdef _GLIBCXX_USE_LONG_LONG
+  template
+    istreambuf_iterator<C>
+    num_get<C, istreambuf_iterator<C> >::
+    _M_extract_int(istreambuf_iterator<C>, istreambuf_iterator<C>,
+		   ios_base&, ios_base::iostate&,
+		   long long&) const;
+
+  template
+    istreambuf_iterator<C>
+    num_get<C, istreambuf_iterator<C> >::
+    _M_extract_int(istreambuf_iterator<C>, istreambuf_iterator<C>,
+		   ios_base&, ios_base::iostate&,
+		   unsigned long long&) const;
+#endif
+
+#if ! _GLIBCXX_USE_CXX11_ABI
+  // num_put member function templates
+  template
+    ostreambuf_iterator<C>
+    num_put<C, ostreambuf_iterator<C> >::
+    _M_insert_int(ostreambuf_iterator<C>, ios_base&, C,
+		  long) const;
+
+  template
+    ostreambuf_iterator<C>
+    num_put<C, ostreambuf_iterator<C> >::
+    _M_insert_int(ostreambuf_iterator<C>, ios_base&, C,
+		  unsigned long) const;
+
+#ifdef _GLIBCXX_USE_LONG_LONG
+  template
+    ostreambuf_iterator<C>
+    num_put<C, ostreambuf_iterator<C> >::
+    _M_insert_int(ostreambuf_iterator<C>, ios_base&, C,
+		  long long) const;
+
+  template
+    ostreambuf_iterator<C>
+    num_put<C, ostreambuf_iterator<C> >::
+    _M_insert_int(ostreambuf_iterator<C>, ios_base&, C,
+		  unsigned long long) const;
+#endif
+
+  template
+    ostreambuf_iterator<C>
+    num_put<C, ostreambuf_iterator<C> >::
+    _M_insert_float(ostreambuf_iterator<C>, ios_base&, C, char,
+		    double) const;
+
+  template
+    ostreambuf_iterator<C>
+    num_put<C, ostreambuf_iterator<C> >::
+    _M_insert_float(ostreambuf_iterator<C>, ios_base&, C, char,
+		    long double) const;
+#endif
+
+_GLIBCXX_END_NAMESPACE_LDBL
+} // namespace std
diff --git a/libstdc++-v3/src/c++11/locale-inst.cc b/libstdc++-v3/src/c++11/locale-inst.cc
index 4dc7f5c0780..cd99648e8f6 100644
--- a/libstdc++-v3/src/c++11/locale-inst.cc
+++ b/libstdc++-v3/src/c++11/locale-inst.cc
@@ -43,6 +43,9 @@
 # define C_is_char
 #endif
 
+#include "locale-inst-numeric.h"
+#include "locale-inst-monetary.h"
+
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -58,33 +61,6 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
   template class moneypunct_byname<C, false>;
   template class moneypunct_byname<C, true>;
 _GLIBCXX_END_NAMESPACE_CXX11
-_GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11
-  template class money_get<C, istreambuf_iterator<C> >;
-  template class money_put<C, ostreambuf_iterator<C> >;
-  template
-    istreambuf_iterator<C>
-    money_get<C, istreambuf_iterator<C> >::
-    _M_extract<true>(istreambuf_iterator<C>, istreambuf_iterator<C>,
-		     ios_base&, ios_base::iostate&, string&) const;
-
-  template
-    istreambuf_iterator<C>
-    money_get<C, istreambuf_iterator<C> >::
-    _M_extract<false>(istreambuf_iterator<C>, istreambuf_iterator<C>,
-		      ios_base&, ios_base::iostate&, string&) const;
-
-  template
-    ostreambuf_iterator<C>
-    money_put<C, ostreambuf_iterator<C> >::
-    _M_insert<true>(ostreambuf_iterator<C>, ios_base&, C,
-		    const string_type&) const;
-
-  template
-    ostreambuf_iterator<C>
-    money_put<C, ostreambuf_iterator<C> >::
-    _M_insert<false>(ostreambuf_iterator<C>, ios_base&, C,
-		     const string_type&) const;
-_GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11
 
   // numpunct, numpunct_byname, num_get, and num_put
 #if ! _GLIBCXX_USE_CXX11_ABI
@@ -94,97 +70,6 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
   template class numpunct<C>;
   template class numpunct_byname<C>;
 _GLIBCXX_END_NAMESPACE_CXX11
-_GLIBCXX_BEGIN_NAMESPACE_LDBL
-#if ! _GLIBCXX_USE_CXX11_ABI
-  template class num_get<C, istreambuf_iterator<C> >;
-#endif
-
-  template
-    istreambuf_iterator<C>
-    num_get<C, istreambuf_iterator<C> >::
-    _M_extract_int(istreambuf_iterator<C>, istreambuf_iterator<C>,
-		   ios_base&, ios_base::iostate&,
-		   long&) const;
-
-  template
-    istreambuf_iterator<C>
-    num_get<C, istreambuf_iterator<C> >::
-    _M_extract_int(istreambuf_iterator<C>, istreambuf_iterator<C>,
-		   ios_base&, ios_base::iostate&,
-		   unsigned short&) const;
-
-  template
-    istreambuf_iterator<C>
-    num_get<C, istreambuf_iterator<C> >::
-    _M_extract_int(istreambuf_iterator<C>, istreambuf_iterator<C>,
-		   ios_base&, ios_base::iostate&,
-		   unsigned int&) const;
-
-  template
-    istreambuf_iterator<C>
-    num_get<C, istreambuf_iterator<C> >::
-    _M_extract_int(istreambuf_iterator<C>, istreambuf_iterator<C>,
-		   ios_base&, ios_base::iostate&,
-		   unsigned long&) const;
-
-#ifdef _GLIBCXX_USE_LONG_LONG
-  template
-    istreambuf_iterator<C>
-    num_get<C, istreambuf_iterator<C> >::
-    _M_extract_int(istreambuf_iterator<C>, istreambuf_iterator<C>,
-		   ios_base&, ios_base::iostate&,
-		   long long&) const;
-
-  template
-    istreambuf_iterator<C>
-    num_get<C, istreambuf_iterator<C> >::
-    _M_extract_int(istreambuf_iterator<C>, istreambuf_iterator<C>,
-		   ios_base&, ios_base::iostate&,
-		   unsigned long long&) const;
-#endif
-
-#if ! _GLIBCXX_USE_CXX11_ABI
-  template class num_put<C, ostreambuf_iterator<C> >;
-
-  template
-    ostreambuf_iterator<C>
-    num_put<C, ostreambuf_iterator<C> >::
-    _M_insert_int(ostreambuf_iterator<C>, ios_base&, C,
-		  long) const;
-
-  template
-    ostreambuf_iterator<C>
-    num_put<C, ostreambuf_iterator<C> >::
-    _M_insert_int(ostreambuf_iterator<C>, ios_base&, C,
-		  unsigned long) const;
-
-#ifdef _GLIBCXX_USE_LONG_LONG
-  template
-    ostreambuf_iterator<C>
-    num_put<C, ostreambuf_iterator<C> >::
-    _M_insert_int(ostreambuf_iterator<C>, ios_base&, C,
-		  long long) const;
-
-  template
-    ostreambuf_iterator<C>
-    num_put<C, ostreambuf_iterator<C> >::
-    _M_insert_int(ostreambuf_iterator<C>, ios_base&, C,
-		  unsigned long long) const;
-#endif
-
-  template
-    ostreambuf_iterator<C>
-    num_put<C, ostreambuf_iterator<C> >::
-    _M_insert_float(ostreambuf_iterator<C>, ios_base&, C, char,
-		    double) const;
-
-  template
-    ostreambuf_iterator<C>
-    num_put<C, ostreambuf_iterator<C> >::
-    _M_insert_float(ostreambuf_iterator<C>, ios_base&, C, char,
-		    long double) const;
-#endif
-_GLIBCXX_END_NAMESPACE_LDBL
 
   // time_get and time_put
 #if ! _GLIBCXX_USE_CXX11_ABI
@@ -250,16 +135,6 @@ _GLIBCXX_END_NAMESPACE_CXX11
     const numpunct<C>&
     use_facet<numpunct<C> >(const locale&);
 
-#if ! _GLIBCXX_USE_CXX11_ABI
-  template
-    const num_put<C>&
-    use_facet<num_put<C> >(const locale&);
-
-  template
-    const num_get<C>&
-    use_facet<num_get<C> >(const locale&);
-#endif
-
   template
     const moneypunct<C, true>&
     use_facet<moneypunct<C, true> >(const locale&);
@@ -268,14 +143,6 @@ _GLIBCXX_END_NAMESPACE_CXX11
     const moneypunct<C, false>&
     use_facet<moneypunct<C, false> >(const locale&);
 
-  template
-    const money_put<C>&
-    use_facet<money_put<C> >(const locale&);
-
-  template
-    const money_get<C>&
-    use_facet<money_get<C> >(const locale&);
-
 #if ! _GLIBCXX_USE_CXX11_ABI
   template
     const __timepunct<C>&
@@ -313,28 +180,10 @@ _GLIBCXX_END_NAMESPACE_CXX11
     bool
     has_facet<numpunct<C> >(const locale&);
 
-#if ! _GLIBCXX_USE_CXX11_ABI
-  template
-    bool
-    has_facet<num_put<C> >(const locale&);
-
-  template
-    bool
-    has_facet<num_get<C> >(const locale&);
-#endif
-
   template
     bool
     has_facet<moneypunct<C> >(const locale&);
 
-  template
-    bool
-    has_facet<money_put<C> >(const locale&);
-
-  template
-    bool
-    has_facet<money_get<C> >(const locale&);
-
 #if ! _GLIBCXX_USE_CXX11_ABI
   template
     bool
@@ -380,45 +229,6 @@ _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
 
 // XXX GLIBCXX_ABI Deprecated
-#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined C_is_char \
-      && _GLIBCXX_USE_CXX11_ABI == 0
-
-#pragma GCC diagnostic ignored "-Wattribute-alias"
-
-#define _GLIBCXX_LDBL_COMPAT(dbl, ldbl) \
-  extern "C" void ldbl (void) __attribute__ ((alias (#dbl), weak))
-
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIjEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
-		     _ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIjEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIlEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
-		     _ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIlEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intImEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
-		     _ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intImEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intItEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
-		     _ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intItEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIxEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
-		     _ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIxEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIyEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
-		     _ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIyEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intIlEES4_S4_RSt8ios_basecT_,
-		     _ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intIlEES3_S3_RSt8ios_basecT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intImEES4_S4_RSt8ios_basecT_,
-		     _ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intImEES3_S3_RSt8ios_basecT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intIxEES4_S4_RSt8ios_basecT_,
-		     _ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intIxEES3_S3_RSt8ios_basecT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intIyEES4_S4_RSt8ios_basecT_,
-		     _ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intIyEES3_S3_RSt8ios_basecT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES4_S4_RSt8ios_baseccT_,
-		     _ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_,
-		     _ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIeEES3_S3_RSt8ios_baseccT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1289money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE10_M_extractILb0EEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRSs,
-		     _ZNKSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE10_M_extractILb0EEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRSs);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1289money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE10_M_extractILb1EEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRSs,
-		     _ZNKSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE10_M_extractILb1EEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRSs);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1289money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE9_M_insertILb0EEES4_S4_RSt8ios_basecRKSs,
-		     _ZNKSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE9_M_insertILb0EEES3_S3_RSt8ios_basecRKSs);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1289money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE9_M_insertILb1EEES4_S4_RSt8ios_basecRKSs,
-		     _ZNKSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE9_M_insertILb1EEES3_S3_RSt8ios_basecRKSs);
-
+#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && ! _GLIBCXX_USE_CXX11_ABI
+#include "compatibility-ldbl-facets-aliases.h"
 #endif // _GLIBCXX_LONG_DOUBLE_COMPAT
diff --git a/libstdc++-v3/src/c++11/wlocale-inst.cc b/libstdc++-v3/src/c++11/wlocale-inst.cc
index 3a54fb51aab..a9a246f8f97 100644
--- a/libstdc++-v3/src/c++11/wlocale-inst.cc
+++ b/libstdc++-v3/src/c++11/wlocale-inst.cc
@@ -33,47 +33,4 @@
 #ifdef _GLIBCXX_USE_WCHAR_T
 #define C wchar_t
 #include "locale-inst.cc"
-
-// XXX GLIBCXX_ABI Deprecated
-#if defined _GLIBCXX_LONG_DOUBLE_COMPAT
-
-#pragma GCC diagnostic ignored "-Wattribute-alias"
-
-#define _GLIBCXX_LDBL_COMPAT(dbl, ldbl) \
-  extern "C" void ldbl (void) __attribute__ ((alias (#dbl), weak))
-
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIjEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
-		     _ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIjEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIlEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
-		     _ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIlEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intImEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
-		     _ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intImEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intItEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
-		     _ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intItEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIxEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
-		     _ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIxEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIyEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
-		     _ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIyEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intIlEES4_S4_RSt8ios_basewT_,
-		     _ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intIlEES3_S3_RSt8ios_basewT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intImEES4_S4_RSt8ios_basewT_,
-		     _ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intImEES3_S3_RSt8ios_basewT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intIxEES4_S4_RSt8ios_basewT_,
-		     _ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intIxEES3_S3_RSt8ios_basewT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intIyEES4_S4_RSt8ios_basewT_,
-		     _ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intIyEES3_S3_RSt8ios_basewT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE15_M_insert_floatIdEES4_S4_RSt8ios_basewcT_,
-		     _ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE15_M_insert_floatIdEES3_S3_RSt8ios_basewcT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE15_M_insert_floatIdEES3_S3_RSt8ios_basewcT_,
-		     _ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE15_M_insert_floatIeEES3_S3_RSt8ios_basewcT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1289money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE10_M_extractILb0EEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRSs,
-		     _ZNKSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE10_M_extractILb0EEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRSs);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1289money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE10_M_extractILb1EEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRSs,
-		     _ZNKSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE10_M_extractILb1EEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRSs);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1289money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE9_M_insertILb0EEES4_S4_RSt8ios_basewRKSbIwS3_SaIwEE,
-		     _ZNKSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE9_M_insertILb0EEES3_S3_RSt8ios_basewRKSbIwS2_SaIwEE);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1289money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE9_M_insertILb1EEES4_S4_RSt8ios_basewRKSbIwS3_SaIwEE,
-		     _ZNKSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE9_M_insertILb1EEES3_S3_RSt8ios_basewRKSbIwS2_SaIwEE);
-
-#endif // _GLIBCXX_LONG_DOUBLE_COMPAT
-#endif
+#endif // _GLIBCXX_USE_WCHAR_T
diff --git a/libstdc++-v3/src/c++98/locale_init.cc b/libstdc++-v3/src/c++98/locale_init.cc
index c3841ccbd3c..77c6eecc1a3 100644
--- a/libstdc++-v3/src/c++98/locale_init.cc
+++ b/libstdc++-v3/src/c++98/locale_init.cc
@@ -57,8 +57,16 @@ _GLIBCXX_LOC_ID(_ZNSt8messagesIwE2idE);
 
 namespace
 {
-  const int num_facets = _GLIBCXX_NUM_FACETS + _GLIBCXX_NUM_UNICODE_FACETS
-    + (_GLIBCXX_USE_DUAL_ABI ? _GLIBCXX_NUM_CXX11_FACETS : 0);
+  const int num_facets = (
+      _GLIBCXX_NUM_FACETS + _GLIBCXX_NUM_CXX11_FACETS
+#ifdef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT
+      + _GLIBCXX_NUM_LBDL_ALT128_FACETS
+#endif
+      )
+#ifdef _GLIBCXX_USE_WCHAR_T
+    * 2
+#endif
+    + _GLIBCXX_NUM_UNICODE_FACETS;
 
   __gnu_cxx::__mutex&
   get_locale_mutex()
@@ -559,6 +567,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 #endif
 
+#ifdef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT
+    _M_init_extra_ldbl128(true);
+#endif
+
 #if _GLIBCXX_USE_DUAL_ABI
     facet* extra[] = { __npc, __mpcf, __mpct
 # ifdef  _GLIBCXX_USE_WCHAR_T
@@ -566,6 +578,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 # endif
     };
 
+    // This call must be after creating all facets, as it sets caches.
     _M_init_extra(extra);
 #endif
 
diff --git a/libstdc++-v3/src/c++98/localename.cc b/libstdc++-v3/src/c++98/localename.cc
index 243acce164c..29f439ffa9a 100644
--- a/libstdc++-v3/src/c++98/localename.cc
+++ b/libstdc++-v3/src/c++98/localename.cc
@@ -171,8 +171,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
   }
 
-const int num_facets = _GLIBCXX_NUM_FACETS + _GLIBCXX_NUM_UNICODE_FACETS
-  + (_GLIBCXX_USE_DUAL_ABI ? _GLIBCXX_NUM_CXX11_FACETS : 0);
+const int num_facets = (
+    _GLIBCXX_NUM_FACETS + _GLIBCXX_NUM_CXX11_FACETS
+#ifdef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT
+    + _GLIBCXX_NUM_LBDL_ALT128_FACETS
+#endif
+    )
+#ifdef _GLIBCXX_USE_WCHAR_T
+  * 2
+#endif
+  + _GLIBCXX_NUM_UNICODE_FACETS;
 
   // Construct named _Impl.
   locale::_Impl::
@@ -284,6 +292,10 @@ const int num_facets = _GLIBCXX_NUM_FACETS + _GLIBCXX_NUM_UNICODE_FACETS
         _M_init_extra(&__cloc, &__clocm, __s, __smon);
 #endif
 
+#ifdef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT
+	_M_init_extra_ldbl128(false);
+#endif
+
 	locale::facet::_S_destroy_c_locale(__cloc);
 	if (__clocm != __cloc)
 	  locale::facet::_S_destroy_c_locale(__clocm);
diff --git a/libstdc++-v3/testsuite/util/testsuite_abi.cc b/libstdc++-v3/testsuite/util/testsuite_abi.cc
index 33b9ec15935..bbe397ae8a4 100644
--- a/libstdc++-v3/testsuite/util/testsuite_abi.cc
+++ b/libstdc++-v3/testsuite/util/testsuite_abi.cc
@@ -207,6 +207,7 @@ check_version(symbol& test, bool added)
       known_versions.push_back("GLIBCXX_3.4.24");
       known_versions.push_back("GLIBCXX_3.4.25");
       known_versions.push_back("GLIBCXX_3.4.26");
+      known_versions.push_back("GLIBCXX_IEEE128_3.4.26");
       known_versions.push_back("GLIBCXX_3.4.27");
       known_versions.push_back("GLIBCXX_3.4.28");
       known_versions.push_back("GLIBCXX_3.4.29");
@@ -225,6 +226,7 @@ check_version(symbol& test, bool added)
       known_versions.push_back("CXXABI_1.3.10");
       known_versions.push_back("CXXABI_1.3.11");
       known_versions.push_back("CXXABI_1.3.12");
+      known_versions.push_back("CXXABI_IEEE128_1.3.12");
       known_versions.push_back("CXXABI_1.3.13");
       known_versions.push_back("CXXABI_TM_1");
       known_versions.push_back("CXXABI_FLOAT128");
@@ -260,7 +262,17 @@ check_version(symbol& test, bool added)
 	  && test.demangled_name.find("std::__cxx11::") != 0)
 	{
 	  if (test.version_name.find("_LDBL_") == std::string::npos
-	      && test.version_name.find("_FLOAT128") == std::string::npos)
+	      && test.version_name.find("_FLOAT128") == std::string::npos
+	      && test.version_name.find("_IEEE128") == std::string::npos)
+	    test.version_status = symbol::incompatible;
+	}
+
+      // Check that IEEE128 long double compatibility symbols demangled as
+      // __ieee128 are put into some _LDBL_IEEE version name.
+      // XXX is this right? might not want *everything* for __ieee128 in here.
+      if (added && test.demangled_name.find("__ieee128") != std::string::npos)
+	{
+	  if (test.version_name.find("_IEEE128") == std::string::npos)
 	    test.version_status = symbol::incompatible;
 	}


^ permalink raw reply	[flat|nested] 2+ messages in thread

* [gcc(refs/users/meissner/heads/work029)] Add C++ runtime support for new 128-bit long double format
@ 2020-11-30 19:06 Michael Meissner
  0 siblings, 0 replies; 2+ messages in thread
From: Michael Meissner @ 2020-11-30 19:06 UTC (permalink / raw)
  To: gcc-cvs, libstdc++-cvs

https://gcc.gnu.org/g:3e79044f9f0c2fbbd55b0760f7558c0917c80e2d

commit 3e79044f9f0c2fbbd55b0760f7558c0917c80e2d
Author: Michael Meissner <meissner@linux.ibm.com>
Date:   Mon Nov 30 13:57:32 2020 -0500

    Add C++ runtime support for new 128-bit long double format
    
    libstdc++-v3/
    2020-11-11  Jonathan Wakely  <jwakely@redhat.com>
    
                * config.h.in: Regenerate.
                * config/abi/pre/gnu.ver: Make patterns less greedy. Add CXXABI_1.3.12
                symbol version.
                * config/os/gnu-linux/ldbl-ieee128-extra.ver: New file with patterns
                for IEEE128 long double symbols.
                * configure: Regenerate.
                * configure.ac: Enable alternative 128-bit long double format on
                powerpc64*-*-linux*.
                * doc/Makefile.in: Regenerate.
                * fragment.am: Regenerate.
                * include/Makefile.am: Set _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT.
                * include/Makefile.in: Regenerate.
                * include/bits/c++config: Define inline namespace for new long double
                symbols. Don't define _GLIBCXX_USE_FLOAT128 when it's the same type
                as long double.
                * include/bits/locale_classes.h [_GLIBCXX_LONG_DOUBLE_ALT128_COMPAT]
                (locale::_Impl::_M_init_extra_ldbl128): Declare new member function.
                * include/bits/locale_facets.h (_GLIBCXX_NUM_FACETS): Simplify by
                only counting narrow character facets.
                (_GLIBCXX_NUM_CXX11_FACETS): Likewise.
                (_GLIBCXX_NUM_LBDL_ALT128_FACETS): New.
                [_GLIBCXX_LONG_DOUBLE_ALT128_COMPAT] (num_get::__do_get): Define
                vtable placeholder for __ibm128 long double type.
                [_GLIBCXX_LONG_DOUBLE_ALT128_COMPAT && __LONG_DOUBLE_IEEE128__]
                (num_get::__do_get): Declare vtable placeholder for __ibm128 long
                double type.
                [_GLIBCXX_LONG_DOUBLE_ALT128_COMPAT && __LONG_DOUBLE_IEEE128__]
                (num_put::__do_put): Likewise.
                * include/bits/locale_facets.tcc
                [_GLIBCXX_LONG_DOUBLE_ALT128_COMPAT && __LONG_DOUBLE_IEEE128__]
                (num_get::__do_get, num_put::__do_put): Define.
                * include/bits/locale_facets_nonio.h
                [_GLIBCXX_LONG_DOUBLE_ALT128_COMPAT && __LONG_DOUBLE_IEEE128__]
                (money_get::__do_get): Declare vtable placeholder for __ibm128 long
                double type.
                [_GLIBCXX_LONG_DOUBLE_ALT128_COMPAT && __LONG_DOUBLE_IEEE128__]
                (money_put::__do_put): Likewise.
                * include/bits/locale_facets_nonio.tcc
                [_GLIBCXX_LONG_DOUBLE_ALT128_COMPAT && __LONG_DOUBLE_IEEE128__]
                (money_get::__do_get, money_put::__do_put): Define.
                * libsupc++/Makefile.in: Regenerate.
                * po/Makefile.in: Regenerate.
                * python/Makefile.in: Regenerate.
                * src/Makefile.am: Add compatibility-ldbl-alt128.cc and
                compatibility-ldbl-alt128-cxx11.cc sources and recipes for objects.
                * src/Makefile.in: Regenerate.
                * src/c++11/Makefile.in: Regenerate.
                * src/c++11/compatibility-ldbl-alt128-cxx11.cc: New file defining
                symbols using the old 128-bit long double format, for the cxx11 ABI.
                * src/c++11/compatibility-ldbl-alt128.cc: Likewise, for the
                gcc4-compatible ABI.
                * src/c++11/compatibility-ldbl-facets-aliases.h: New header for long
                double compat aliases.
                * src/c++11/cow-locale_init.cc: Add comment.
                * src/c++11/cxx11-locale-inst.cc: Define C and C_is_char
                unconditionally.
                * src/c++11/cxx11-wlocale-inst.cc: Add sanity check. Include
                locale-inst.cc directly, not via cxx11-locale-inst.cc.
                * src/c++11/locale-inst-monetary.h: New header for monetary category
                instantiations.
                * src/c++11/locale-inst-numeric.h: New header for numeric category
                instantiations.
                * src/c++11/locale-inst.cc: Include new headers for monetary, numeric,
                and long double definitions.
                * src/c++11/wlocale-inst.cc: Remove long double compat aliases that
                are defined in new header now.
                * src/c++17/Makefile.in: Regenerate.
                * src/c++98/Makefile.in: Regenerate.
                * src/c++98/locale_init.cc (num_facets): Adjust calculation.
                (locale::_Impl::_Impl(size_t)): Call _M_init_extra_ldbl128.
                * src/c++98/localename.cc (num_facets): Adjust calculation.
                (locale::_Impl::_Impl(const char*, size_t)): Call
                _M_init_extra_ldbl128.
                * src/filesystem/Makefile.in: Regenerate.
                * testsuite/Makefile.in: Regenerate.
                * testsuite/util/testsuite_abi.cc: Add new symbol versions.

Diff:
---
 libstdc++-v3/ChangeLog.meissner                    |   0
 libstdc++-v3/config/abi/pre/gnu.ver                |   8 +-
 .../config/os/gnu-linux/ldbl-ieee128-extra.ver     |  51 +++++
 libstdc++-v3/configure.ac                          |  35 ++-
 libstdc++-v3/fragment.am                           |   8 +-
 libstdc++-v3/include/Makefile.am                   |   6 +
 libstdc++-v3/include/bits/c++config                |  32 ++-
 libstdc++-v3/include/bits/locale_classes.h         |   4 +
 libstdc++-v3/include/bits/locale_facets.h          |  28 +++
 libstdc++-v3/include/bits/locale_facets.tcc        |  27 +++
 libstdc++-v3/include/bits/locale_facets_nonio.h    |  24 ++-
 libstdc++-v3/include/bits/locale_facets_nonio.tcc  |  61 +++++-
 libstdc++-v3/src/Makefile.am                       |  32 ++-
 .../src/c++11/compatibility-ldbl-alt128-cxx11.cc   | 102 +++++++++
 .../src/c++11/compatibility-ldbl-alt128.cc         | 234 +++++++++++++++++++++
 .../src/c++11/compatibility-ldbl-facets-aliases.h  | 128 +++++++++++
 libstdc++-v3/src/c++11/cow-locale_init.cc          |   1 +
 libstdc++-v3/src/c++11/cxx11-locale-inst.cc        |   6 +-
 libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc       |   8 +-
 libstdc++-v3/src/c++11/locale-inst-monetary.h      |  69 ++++++
 libstdc++-v3/src/c++11/locale-inst-numeric.h       | 133 ++++++++++++
 libstdc++-v3/src/c++11/locale-inst.cc              | 200 +-----------------
 libstdc++-v3/src/c++11/wlocale-inst.cc             |  45 +---
 libstdc++-v3/src/c++98/locale_init.cc              |  17 +-
 libstdc++-v3/src/c++98/localename.cc               |  16 +-
 libstdc++-v3/testsuite/util/testsuite_abi.cc       |  14 +-
 26 files changed, 1026 insertions(+), 263 deletions(-)

diff --git a/libstdc++-v3/ChangeLog.meissner b/libstdc++-v3/ChangeLog.meissner
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver
index 46769db1530..f2c88cbce2d 100644
--- a/libstdc++-v3/config/abi/pre/gnu.ver
+++ b/libstdc++-v3/config/abi/pre/gnu.ver
@@ -682,7 +682,7 @@ GLIBCXX_3.4 {
     _ZNSt12__basic_fileIcED*;
 
     # std::__convert_to_v
-    _ZSt14__convert_to_vI[^g]*;
+    _ZSt14__convert_to_vI[^gU]*;
 
     # __gnu_cxx::stdio_sync_filebuf
     _ZTVN9__gnu_cxx18stdio_sync_filebufI[cw]St11char_traitsI[cw]EEE;
@@ -931,7 +931,7 @@ GLIBCXX_3.4 {
     _ZGVNSt8time_putI[cw]*;
     _ZGVNSt9money_getI[cw]*;
     _ZGVNSt9money_putI[cw]*;
-    _ZGVNSt1[^07]*;
+    _ZGVNSt1[^079]*;
     _ZGVNSt10moneypunctI[cw]Lb[01]*;
 
     # exception constructors taking std::string
@@ -2702,6 +2702,10 @@ CXXABI_1.3.13 {
 
 } CXXABI_1.3.12;
 
+CXXABI_1.3.12 {
+
+} CXXABI_1.3.11;
+
 # Symbols in the support library (libsupc++) supporting transactional memory.
 CXXABI_TM_1 {
 
diff --git a/libstdc++-v3/config/os/gnu-linux/ldbl-ieee128-extra.ver b/libstdc++-v3/config/os/gnu-linux/ldbl-ieee128-extra.ver
new file mode 100644
index 00000000000..dca371b11f0
--- /dev/null
+++ b/libstdc++-v3/config/os/gnu-linux/ldbl-ieee128-extra.ver
@@ -0,0 +1,51 @@
+# Appended to version file.
+
+GLIBCXX_IEEE128_3.4.26 {
+
+  *__gnu_cxx_ieee128*;
+
+  _ZNSt14numeric_limitsIu9__ieee128E*;
+  _ZNSirsERu9__ieee128;
+  _ZNSolsEu9__ieee128;
+  _ZNSt13basic_istreamIwSt11char_traitsIwEErsERu9__ieee128;
+  _ZNSt13basic_ostreamIwSt11char_traitsIwEElsEu9__ieee128;
+  _ZSt14__convert_to_vIu9__ieee128EvPKcRT_RSt12_Ios_IostateRKP*;
+  _ZStlsIu9__ieee128[cw]St11char_traitsI[cw]EERSt13basic_ostreamIT0_T1_ES6_RKSt7complexIT_E;
+  _ZStrsIu9__ieee128[cw]St11char_traitsI[cw]EERSt13basic_istreamIT0_T1_ES6_RSt7complexIT_E;
+
+  _ZNSi10_M_extractIu9__ieee128EERSiRT_;
+  _ZNSt13basic_istreamIwSt11char_traitsIwEE10_M_extractIu9__ieee128EERS2_RT_;
+  _ZNSo9_M_insertIu9__ieee128EERSoT_;
+  _ZNSt13basic_ostreamIwSt11char_traitsIwEE9_M_insertIu9__ieee128EERS2_T_;
+
+  _ZNKSt3tr14hashIu9__ieee128EclEu9__ieee128;
+  _ZNKSt4hashIu9__ieee128EclEu9__ieee128;
+
+  _ZNKSt19__gnu_cxx11_ieee1289money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES4_S4_bRSt8ios_baseRSt12_Ios_IostateRNSt7__cxx1112basic_stringIcS3_SaIcEEE;
+  _ZNKSt19__gnu_cxx11_ieee1289money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES4_S4_bRSt8ios_baseRSt12_Ios_IostateRu9__ieee128;
+  _ZNKSt19__gnu_cxx11_ieee1289money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE8__do_getES4_S4_bRSt8ios_baseRSt12_Ios_IostateRd;
+  _ZNKSt19__gnu_cxx11_ieee1289money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE8__do_getES4_S4_bRSt8ios_baseRSt12_Ios_IostateRg;
+  _ZNKSt19__gnu_cxx11_ieee1289money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES4_bRSt8ios_basecRKNSt7__cxx1112basic_stringIcS3_SaIcEEE;
+  _ZNKSt19__gnu_cxx11_ieee1289money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES4_bRSt8ios_basecu9__ieee128;
+  _ZNKSt19__gnu_cxx11_ieee1289money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE8__do_putES4_bRSt8ios_basecd;
+  _ZNKSt19__gnu_cxx11_ieee1289money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE8__do_putES4_bRSt8ios_basecg;
+  _ZSt9has_facetINSt19__gnu_cxx11_ieee1289money_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEEEEbRKSt6locale;
+  _ZSt9has_facetINSt19__gnu_cxx11_ieee1289money_putI[cw]St19ostreambuf_iteratorI[cw]St11char_traitsI[cw]EEEEEbRKSt6locale;
+  _ZSt9use_facetINSt19__gnu_cxx11_ieee1289money_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEEEERKT_RKSt6locale;
+  _ZSt9use_facetINSt19__gnu_cxx11_ieee1289money_putI[cw]St19ostreambuf_iteratorI[cw]St11char_traitsI[cw]EEEEERKT_RKSt6locale;
+  _ZTINSt19__gnu_cxx11_ieee1289money_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEEE;
+  _ZTVNSt19__gnu_cxx11_ieee1289money_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEEE;
+  _ZTINSt19__gnu_cxx11_ieee1289money_putI[cw]St19ostreambuf_iteratorI[cw]St11char_traitsI[cw]EEEE;
+  _ZTVNSt19__gnu_cxx11_ieee1289money_putI[cw]St19ostreambuf_iteratorI[cw]St11char_traitsI[cw]EEEE;
+
+  _ZNKSt19__gnu_cxx11_ieee1289money_putI[cw]St19ostreambuf_iteratorI[cw]St11char_traitsI[cw]EEE3putES4_bRSt8ios_base[cw]u9__ieee128;
+
+} GLIBCXX_3.4.26;
+
+CXXABI_IEEE128_1.3.12 {
+
+  _ZT[IS]u9__ieee128;
+  _ZT[IS]Pu9__ieee128;
+  _ZT[IS]PKu9__ieee128;
+
+} CXXABI_1.3.12;
diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac
index cbfdf4c6bad..9d5b9b33ce9 100644
--- a/libstdc++-v3/configure.ac
+++ b/libstdc++-v3/configure.ac
@@ -404,7 +404,11 @@ GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI([yes])
 GLIBCXX_DEFAULT_ABI
 
 ac_ldbl_compat=no
+ac_ldbl_alt128_compat=no
+ac_ldbl_ieee128_default=no
 LONG_DOUBLE_COMPAT_FLAGS="-mlong-double-64"
+LONG_DOUBLE_128_FLAGS=
+LONG_DOUBLE_ALT128_COMPAT_FLAGS=
 case "$target" in
   powerpc*-*-linux* | \
   sparc*-*-linux* | \
@@ -421,12 +425,41 @@ case "$target" in
     port_specific_symbol_files="\$(top_srcdir)/config/os/gnu-linux/ldbl-extra.ver"
     case "$target" in
       powerpc*-*-linux*)
-	LONG_DOUBLE_COMPAT_FLAGS="$LONG_DOUBLE_COMPAT_FLAGS -mno-gnu-attribute" ;;
+	LONG_DOUBLE_COMPAT_FLAGS="$LONG_DOUBLE_COMPAT_FLAGS -mno-gnu-attribute"
+        # Check for IEEE128 support in libc:
+        AC_CHECK_FUNCS(frexpf128,
+                       [ac_ldbl_ieee128_in_libc=yes],
+                       [ac_ldbl_ieee128_in_libc=no])
+        if test $ac_ldbl_ieee128_in_libc = yes; then
+          # Determine which long double format is the compiler's default:
+          AC_TRY_COMPILE(, [
+            #ifndef __LONG_DOUBLE_IEEE128__
+            #error compiler defaults to ibm128
+            #endif
+          ], [ac_ldbl_ieee128_default=yes], [ac_ldbl_ieee128_default=no])
+          # Library objects should use IEEE128 long double format by default.
+          if test "$ac_ldbl_ieee128_default" = no; then
+            # Add -mabi=ieeelongdouble to ensire that.
+            LONG_DOUBLE_128_FLAGS="-mabi=ieeelongdouble -mno-gnu-attribute -Wno-psabi"
+          fi
+          # Except for the ones that explicitly use these flags:
+          LONG_DOUBLE_ALT128_COMPAT_FLAGS="-mabi=ibmlongdouble -mno-gnu-attribute -Wno-psabi"
+          AC_DEFINE([_GLIBCXX_LONG_DOUBLE_ALT128_COMPAT],1,
+                [Define if compatibility should be provided for alternative 128-bit long double formats.])
+          port_specific_symbol_files="$port_specific_symbol_files \$(top_srcdir)/config/os/gnu-linux/ldbl-ieee128-extra.ver"
+          ac_ldbl_alt128_compat=yes
+        else
+          ac_ldbl_alt128_compat=no
+        fi
+	;;
     esac
   fi
 esac
 AC_SUBST(LONG_DOUBLE_COMPAT_FLAGS)
+AC_SUBST(LONG_DOUBLE_128_FLAGS)
+AC_SUBST(LONG_DOUBLE_ALT128_COMPAT_FLAGS)
 GLIBCXX_CONDITIONAL(GLIBCXX_LDBL_COMPAT, test $ac_ldbl_compat = yes)
+GLIBCXX_CONDITIONAL(GLIBCXX_LDBL_ALT128_COMPAT, test $ac_ldbl_alt128_compat = yes)
 
 # Check if assembler supports disabling hardware capability support.
 GCC_CHECK_ASSEMBLER_HWCAP
diff --git a/libstdc++-v3/fragment.am b/libstdc++-v3/fragment.am
index 216c572fc60..54645739e5c 100644
--- a/libstdc++-v3/fragment.am
+++ b/libstdc++-v3/fragment.am
@@ -25,10 +25,16 @@ else
 XTEMPLATE_FLAGS =
 endif
 
+if GLIBCXX_LDBL_ALT128_COMPAT
+LDBL_128_FLAGS = $(LONG_DOUBLE_128_FLAGS)
+else
+LDBL_128_FLAGS =
+endif
+
 # These bits are all figured out from configure.  Look in acinclude.m4
 # or configure.ac to see how they are set.  See GLIBCXX_EXPORT_FLAGS.
 CONFIG_CXXFLAGS = \
-	$(SECTION_FLAGS) $(HWCAP_CFLAGS) -frandom-seed=$@
+	$(SECTION_FLAGS) $(HWCAP_CFLAGS) -frandom-seed=$@ $(LDBL_128_FLAGS)
 
 WARN_CXXFLAGS = \
 	$(WARN_FLAGS) $(WERROR_FLAG) -fdiagnostics-show-location=once 
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index ca413b8fdfe..5bd61bea6e3 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -1293,6 +1293,10 @@ ${host_builddir}/c++config.h: ${CONFIG_HEADER} \
 	grep "^[	 ]*#[	 ]*define[	 ][	 ]*_GLIBCXX_LONG_DOUBLE_COMPAT[	 ][	 ]*1[	 ]*$$" \
 	${CONFIG_HEADER} > /dev/null 2>&1 \
 	&& ldbl_compat='s,^#undef _GLIBCXX_LONG_DOUBLE_COMPAT$$,#define _GLIBCXX_LONG_DOUBLE_COMPAT 1,' ;\
+	ldbl_alt128_compat='s,g,g,' ;\
+	grep "^[	 ]*#[	 ]*define[	 ][	 ]*_GLIBCXX_LONG_DOUBLE_ALT128_COMPAT[	 ][	 ]*1[	 ]*$$" \
+	${CONFIG_HEADER} > /dev/null 2>&1 \
+	&& ldbl_alt128_compat='s,^#undef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT$$,#define _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT 1,' ;\
 	sed -e "s,define __GLIBCXX__,define __GLIBCXX__ $$date," \
 	-e "s,define _GLIBCXX_RELEASE,define _GLIBCXX_RELEASE $$release," \
 	-e "s,define _GLIBCXX_INLINE_VERSION, define _GLIBCXX_INLINE_VERSION $$ns_version," \
@@ -1303,6 +1307,7 @@ ${host_builddir}/c++config.h: ${CONFIG_HEADER} \
 	-e "s,define _GLIBCXX_USE_ALLOCATOR_NEW, define _GLIBCXX_USE_ALLOCATOR_NEW $$allocatornew," \
 	-e "s,define _GLIBCXX_USE_FLOAT128,$$float128," \
 	-e "$$ldbl_compat" \
+	-e "$$ldbl_alt128_compat" \
 	    < ${glibcxx_srcdir}/include/bits/c++config > $@ ;\
 	sed -e 's/HAVE_/_GLIBCXX_HAVE_/g' \
 	    -e 's/PACKAGE/_GLIBCXX_PACKAGE/g' \
@@ -1313,6 +1318,7 @@ ${host_builddir}/c++config.h: ${CONFIG_HEADER} \
 	    -e 's/_LARGE_FILES/_GLIBCXX_LARGE_FILES/g' \
 	    -e 's/ICONV_CONST/_GLIBCXX_ICONV_CONST/g' \
 	    -e '/[	 ]_GLIBCXX_LONG_DOUBLE_COMPAT[	 ]/d' \
+	    -e '/[	 ]_GLIBCXX_LONG_DOUBLE_ALT128_COMPAT[	 ]/d' \
 	    < ${CONFIG_HEADER} >> $@ ;\
 	echo "" >> $@ ;\
 	echo "#endif // _GLIBCXX_CXX_CONFIG_H" >> $@
diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config
index 2e6c880ad95..6af203d03ec 100644
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -425,8 +425,28 @@ _GLIBCXX_END_NAMESPACE_VERSION
 // GLIBCXX_ABI Deprecated
 // Define if compatibility should be provided for -mlong-double-64.
 #undef _GLIBCXX_LONG_DOUBLE_COMPAT
+// Define if compatibility should be provided for alternative 128-bit long
+// double formats.
+#undef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT
+
+// Inline namespaces for long double 128 modes.
+#if defined _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT \
+  && defined __LONG_DOUBLE_IEEE128__
+namespace std
+{
+  // Namespaces for 128-bit IEEE long double format on 64-bit POWER LE.
+  inline namespace __gnu_cxx_ieee128 { }
+  inline namespace __gnu_cxx11_ieee128 { }
+}
+# define _GLIBCXX_NAMESPACE_LDBL __gnu_cxx_ieee128::
+# define _GLIBCXX_BEGIN_NAMESPACE_LDBL namespace __gnu_cxx_ieee128 {
+# define _GLIBCXX_END_NAMESPACE_LDBL }
+# define _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 __gnu_cxx11_ieee128::
+# define _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11 namespace __gnu_cxx11_ieee128 {
+# define _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 }
+
+#else // _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT && IEEE128
 
-// Inline namespace for long double 128 mode.
 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
 namespace std
 {
@@ -440,6 +460,7 @@ namespace std
 # define _GLIBCXX_BEGIN_NAMESPACE_LDBL
 # define _GLIBCXX_END_NAMESPACE_LDBL
 #endif
+
 #if _GLIBCXX_USE_CXX11_ABI
 # define _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_NAMESPACE_CXX11
 # define _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_BEGIN_NAMESPACE_CXX11
@@ -450,6 +471,8 @@ namespace std
 # define _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_END_NAMESPACE_LDBL
 #endif
 
+#endif // _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT && IEEE128
+
 // Debug Mode implies checking assertions.
 #if defined(_GLIBCXX_DEBUG) && !defined(_GLIBCXX_ASSERTIONS)
 # define _GLIBCXX_ASSERTIONS 1
@@ -648,9 +671,12 @@ namespace std
 # define __cpp_lib_char8_t 201907L
 #endif
 
-/* Define if __float128 is supported on this host. */
+/* Define if __float128 is supported on this host.  */
 #if defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__)
-#define _GLIBCXX_USE_FLOAT128
+/* For powerpc64 don't use __float128 when it's the same type as long double. */
+# if !(defined(_GLIBCXX_LONG_DOUBLE_ALT128_COMPAT) && defined(__LONG_DOUBLE_IEEE128__))
+#  define _GLIBCXX_USE_FLOAT128
+# endif
 #endif
 
 #if __GNUC__ >= 7
diff --git a/libstdc++-v3/include/bits/locale_classes.h b/libstdc++-v3/include/bits/locale_classes.h
index ab90682cde2..ed7764e06e7 100644
--- a/libstdc++-v3/include/bits/locale_classes.h
+++ b/libstdc++-v3/include/bits/locale_classes.h
@@ -625,6 +625,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
     void _M_init_extra(facet**);
     void _M_init_extra(void*, void*, const char*, const char*);
+
+#ifdef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT
+    void _M_init_extra_ldbl128(bool);
+#endif
   };
 
 
diff --git a/libstdc++-v3/include/bits/locale_facets.h b/libstdc++-v3/include/bits/locale_facets.h
index 3e0ae8776c9..9b262c2d228 100644
--- a/libstdc++-v3/include/bits/locale_facets.h
+++ b/libstdc++-v3/include/bits/locale_facets.h
@@ -65,6 +65,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 # define _GLIBCXX_NUM_UNICODE_FACETS 2
 #endif
 
+// Facets duplicated for alt128 long double format
+// num_get, num_put, money_get, money_put (+ cxx11 money_get, money_put)
+#define _GLIBCXX_NUM_LBDL_ALT128_FACETS (4 + (_GLIBCXX_USE_DUAL_ABI ? 2 : 0))
+
   // Convert string to numeric value of type _Tp and store results.
   // NB: This is specialized for all required types, there is no
   // generic definition.
@@ -2252,6 +2256,10 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL
 
       // XXX GLIBCXX_ABI Deprecated
 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
+      // For __gnu_cxx_ldbl128::num_get and __gnu_cxx_ieee128::num_get
+      // this entry in the vtable is for a 64-bit "long double" with the
+      // same format as double. This keeps the vtable layout consistent
+      // with std::num_get (visible when -mlong-double-64 is used).
       virtual iter_type
       __do_get(iter_type, iter_type, ios_base&, ios_base::iostate&,
 	       double&) const;
@@ -2264,8 +2272,21 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL
       virtual iter_type
       do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, void*&) const;
 
+      // XXX GLIBCXX_ABI Deprecated
+#if defined _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT \
+      && defined __LONG_DOUBLE_IEEE128__
+      // For __gnu_cxx_ieee128::num_get this entry in the vtable is for
+      // the non-IEEE 128-bit "long double" (aka "double double"). This
+      // is consistent with __gnu_cxx_ldbl128::num_get (-mabi=ibmlongdouble)
+      virtual iter_type
+      __do_get(iter_type, iter_type, ios_base&, ios_base::iostate&,
+	       __ibm128&) const;
+#endif
+
       // XXX GLIBCXX_ABI Deprecated
 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
+      // For __gnu_cxx_ldbl128::num_get and __gnu_cxx_ieee128::num_get
+      // this entry in the vtable is for the 128-bit "long double" type.
       virtual iter_type
       do_get(iter_type, iter_type, ios_base&, ios_base::iostate&,
 	     long double&) const;
@@ -2545,6 +2566,13 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL
       virtual iter_type
       do_put(iter_type, ios_base&, char_type, const void*) const;
 
+      // XXX GLIBCXX_ABI Deprecated
+#if defined _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT \
+      && defined __LONG_DOUBLE_IEEE128__
+      virtual iter_type
+      __do_put(iter_type, ios_base&, char_type, __ibm128) const;
+#endif
+
       // XXX GLIBCXX_ABI Deprecated
 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
       virtual iter_type
diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc
index ebc993339a6..4fdca180a87 100644
--- a/libstdc++-v3/include/bits/locale_facets.tcc
+++ b/libstdc++-v3/include/bits/locale_facets.tcc
@@ -772,6 +772,24 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL
       return __beg;
     }
 
+#if defined _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT \
+      && defined __LONG_DOUBLE_IEEE128__
+  template<typename _CharT, typename _InIter>
+    _InIter
+    num_get<_CharT, _InIter>::
+    __do_get(iter_type __beg, iter_type __end, ios_base& __io,
+	     ios_base::iostate& __err, __ibm128& __v) const
+    {
+      string __xtrc;
+      __xtrc.reserve(32);
+      __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
+      std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale());
+      if (__beg == __end)
+	__err |= ios_base::eofbit;
+      return __beg;
+    }
+#endif
+
   // For use by integer and floating-point types after they have been
   // converted into a char_type string.
   template<typename _CharT, typename _OutIter>
@@ -1194,6 +1212,15 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL
       return __s;
     }
 
+#if defined _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT \
+      && defined __LONG_DOUBLE_IEEE128__
+  template<typename _CharT, typename _OutIter>
+    _OutIter
+    num_put<_CharT, _OutIter>::
+    __do_put(iter_type __s, ios_base& __io, char_type __fill,
+	     __ibm128 __v) const
+    { return _M_insert_float(__s, __io, __fill, 'L', __v); }
+#endif
 _GLIBCXX_END_NAMESPACE_LDBL
 
   // Construct correctly padded string, as per 22.2.2.2.2
diff --git a/libstdc++-v3/include/bits/locale_facets_nonio.h b/libstdc++-v3/include/bits/locale_facets_nonio.h
index b76eac435bd..6af68d3fa90 100644
--- a/libstdc++-v3/include/bits/locale_facets_nonio.h
+++ b/libstdc++-v3/include/bits/locale_facets_nonio.h
@@ -1566,7 +1566,7 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11
        */
       // XXX GLIBCXX_ABI Deprecated
 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ \
-      && _GLIBCXX_USE_CXX11_ABI == 0
+      && (_GLIBCXX_USE_CXX11_ABI == 0 || defined __LONG_DOUBLE_IEEE128__)
       virtual iter_type
       __do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
 	       ios_base::iostate& __err, double& __units) const;
@@ -1587,9 +1587,17 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11
       do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
 	     ios_base::iostate& __err, string_type& __digits) const;
 
+      // XXX GLIBCXX_ABI Deprecated
+#if defined _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT \
+      && defined __LONG_DOUBLE_IEEE128__
+      virtual iter_type
+      __do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
+	       ios_base::iostate& __err, __ibm128& __units) const;
+#endif
+
       // XXX GLIBCXX_ABI Deprecated
 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ \
-      && _GLIBCXX_USE_CXX11_ABI == 0
+      && (_GLIBCXX_USE_CXX11_ABI == 0 || defined __LONG_DOUBLE_IEEE128__)
       virtual iter_type
       do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
 	     ios_base::iostate& __err, long double& __units) const;
@@ -1711,7 +1719,7 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11
        */
       // XXX GLIBCXX_ABI Deprecated
 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ \
-      && _GLIBCXX_USE_CXX11_ABI == 0
+      && (_GLIBCXX_USE_CXX11_ABI == 0 || defined __LONG_DOUBLE_IEEE128__)
       virtual iter_type
       __do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
 	       double __units) const;
@@ -1744,9 +1752,17 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11
       do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
 	     const string_type& __digits) const;
 
+      // XXX GLIBCXX_ABI Deprecated
+#if defined _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT \
+      && defined __LONG_DOUBLE_IEEE128__
+      virtual iter_type
+      __do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
+	       __ibm128 __units) const;
+#endif
+
       // XXX GLIBCXX_ABI Deprecated
 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ \
-      && _GLIBCXX_USE_CXX11_ABI == 0
+      && (_GLIBCXX_USE_CXX11_ABI == 0 || defined __LONG_DOUBLE_IEEE128__)
       virtual iter_type
       do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
 	     long double __units) const;
diff --git a/libstdc++-v3/include/bits/locale_facets_nonio.tcc b/libstdc++-v3/include/bits/locale_facets_nonio.tcc
index a8639f6ba28..9e2b6577969 100644
--- a/libstdc++-v3/include/bits/locale_facets_nonio.tcc
+++ b/libstdc++-v3/include/bits/locale_facets_nonio.tcc
@@ -350,7 +350,7 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11
       }
 
 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ \
-      && _GLIBCXX_USE_CXX11_ABI == 0
+      && (_GLIBCXX_USE_CXX11_ABI == 0 || defined __LONG_DOUBLE_IEEE128__)
   template<typename _CharT, typename _InIter>
     _InIter
     money_get<_CharT, _InIter>::
@@ -401,6 +401,22 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11
       return __beg;
     }
 
+#if defined _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT \
+      && defined __LONG_DOUBLE_IEEE128__
+  template<typename _CharT, typename _InIter>
+    _InIter
+    money_get<_CharT, _InIter>::
+    __do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io,
+	     ios_base::iostate& __err, __ibm128& __units) const
+    {
+      string __str;
+      __beg = __intl ? _M_extract<true>(__beg, __end, __io, __err, __str)
+	             : _M_extract<false>(__beg, __end, __io, __err, __str);
+      std::__convert_to_v(__str.c_str(), __units, __err, _S_get_c_locale());
+      return __beg;
+    }
+#endif
+
   template<typename _CharT, typename _OutIter>
     template<bool _Intl>
       _OutIter
@@ -562,7 +578,7 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11
       }
 
 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ \
-      && _GLIBCXX_USE_CXX11_ABI == 0
+      && (_GLIBCXX_USE_CXX11_ABI == 0 || defined __LONG_DOUBLE_IEEE128__)
   template<typename _CharT, typename _OutIter>
     _OutIter
     money_put<_CharT, _OutIter>::
@@ -617,6 +633,47 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11
     { return __intl ? _M_insert<true>(__s, __io, __fill, __digits)
 	            : _M_insert<false>(__s, __io, __fill, __digits); }
 
+#if defined _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT \
+      && defined __LONG_DOUBLE_IEEE128__
+  template<typename _CharT, typename _OutIter>
+    _OutIter
+    money_put<_CharT, _OutIter>::
+    __do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
+	     __ibm128 __units) const
+    {
+      const locale __loc = __io.getloc();
+      const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
+#if _GLIBCXX_USE_C99_STDIO
+      // First try a buffer perhaps big enough.
+      int __cs_size = 64;
+      char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // 328. Bad sprintf format modifier in money_put<>::do_put()
+      int __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size,
+					"%.*Lf", 0, __units);
+      // If the buffer was not large enough, try again with the correct size.
+      if (__len >= __cs_size)
+	{
+	  __cs_size = __len + 1;
+	  __cs = static_cast<char*>(__builtin_alloca(__cs_size));
+	  __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size,
+					"%.*Lf", 0, __units);
+	}
+#else
+      // max_exponent10 + 1 for the integer part, + 2 for sign and '\0'.
+      const int __cs_size =
+	__gnu_cxx::__numeric_traits<long double>::__max_exponent10 + 3;
+      char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
+      int __len = std::__convert_from_v(_S_get_c_locale(), __cs, 0, "%.*Lf", 
+					0, __units);
+#endif
+      string_type __digits(__len, char_type());
+      __ctype.widen(__cs, __cs + __len, &__digits[0]);
+      return __intl ? _M_insert<true>(__s, __io, __fill, __digits)
+	            : _M_insert<false>(__s, __io, __fill, __digits);
+    }
+#endif
+
 _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11
 
   // NB: Not especially useful. Without an ios_base object or some
diff --git a/libstdc++-v3/src/Makefile.am b/libstdc++-v3/src/Makefile.am
index 21b6db7fb1c..739d15d2ccb 100644
--- a/libstdc++-v3/src/Makefile.am
+++ b/libstdc++-v3/src/Makefile.am
@@ -71,6 +71,20 @@ else
 ldbl_compat_sources =
 endif
 
+if GLIBCXX_LDBL_ALT128_COMPAT
+if ENABLE_DUAL_ABI
+ldbl_alt128_compat_cxx11_sources = \
+	compatibility-ldbl-alt128-cxx11.cc
+else
+ldbl_alt128_compat_cxx11_sources =
+endif
+ldbl_alt128_compat_sources = \
+	compatibility-ldbl-alt128.cc \
+	${ldbl_alt128_compat_cxx11_sources}
+else
+ldbl_alt128_compat_sources =
+endif
+
 
 parallel_compat_sources = \
 	compatibility-parallel_list.cc  compatibility-parallel_list-2.cc
@@ -87,7 +101,8 @@ cxx11_sources = \
 	compatibility-atomic-c++0x.cc \
 	compatibility-thread-c++0x.cc \
 	compatibility-chrono.cc \
-	compatibility-condvar.cc
+	compatibility-condvar.cc \
+	${ldbl_alt128_compat_sources}
 
 libstdc___la_SOURCES = $(cxx98_sources) $(cxx11_sources)
 
@@ -121,6 +136,21 @@ compatibility-ldbl.o: compatibility-ldbl.cc
 	$(CXXCOMPILE) $(LONG_DOUBLE_COMPAT_FLAGS) -c $<
 endif
 
+# Use special rules for compatibility-ldbl-alt128.cc compilation, as we need to
+# ensure it is compiled with the correct flag.
+if GLIBCXX_LDBL_ALT128_COMPAT
+compatibility-ldbl-alt128.lo: compatibility-ldbl-alt128.cc
+	$(LTCXXCOMPILE) $(LONG_DOUBLE_ALT128_COMPAT_FLAGS) -std=gnu++11 -c $<
+compatibility-ldbl-alt128.o: compatibility-ldbl-alt128.cc
+	$(CXXCOMPILE) $(LONG_DOUBLE_ALT128_COMPAT_FLAGS) -std=gnu++11 -c $<
+if ENABLE_DUAL_ABI
+compatibility-ldbl-alt128-cxx11.lo: compatibility-ldbl-alt128-cxx11.cc
+	$(LTCXXCOMPILE) $(LONG_DOUBLE_ALT128_COMPAT_FLAGS) -std=gnu++11 -c $<
+compatibility-ldbl-alt128-cxx11.o: compatibility-ldbl-alt128-cxx11.cc
+	$(CXXCOMPILE) $(LONG_DOUBLE_ALT128_COMPAT_FLAGS) -std=gnu++11 -c $<
+endif
+endif
+
 # Use special rules for C++11 files/objects.
 compatibility-c++0x.lo: compatibility-c++0x.cc
 	$(LTCXXCOMPILE) -std=gnu++11 -c $<
diff --git a/libstdc++-v3/src/c++11/compatibility-ldbl-alt128-cxx11.cc b/libstdc++-v3/src/c++11/compatibility-ldbl-alt128-cxx11.cc
new file mode 100644
index 00000000000..21d5a6ca421
--- /dev/null
+++ b/libstdc++-v3/src/c++11/compatibility-ldbl-alt128-cxx11.cc
@@ -0,0 +1,102 @@
+// Compatibility symbols for alternate 128-bit long-double format -*- C++ -*-
+
+// Copyright (C) 2018 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library 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.
+
+// This 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 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/>.
+
+#define _GLIBCXX_USE_CXX11_ABI 1
+#include <locale>
+
+#ifdef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT
+
+#if !defined(_GLIBCXX_USE_DUAL_ABI)
+#error "compatibility-ldbl-alt128-cxx11.cc must only be compiled when dual ABI is enabled"
+#endif
+
+#ifndef __LONG_DOUBLE_IBM128__
+#error "compatibility-ldbl-alt128.cc must be compiled with -mabi=ibmlongdouble"
+#endif
+
+#define C char
+#define C_is_char
+#include "locale-inst-monetary.h"
+
+#ifdef _GLIBCXX_USE_WCHAR_T
+# undef C
+# undef C_is_char
+# define C wchar_t
+# include "locale-inst-monetary.h"
+#endif
+
+#include <functional>
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  namespace
+  {
+    alignas(money_get<char>) char money_get_c[sizeof(money_get<char>)];
+    alignas(money_put<char>) char money_put_c[sizeof(money_put<char>)];
+#ifdef _GLIBCXX_USE_WCHAR_T
+    alignas(money_get<wchar_t>) char money_get_w[sizeof(money_get<wchar_t>)];
+    alignas(money_put<wchar_t>) char money_put_w[sizeof(money_put<wchar_t>)];
+#endif
+
+  template<typename Facet>
+    void
+    init_facet(function<void(const locale::id*, const locale::facet*)>& func,
+	       Facet* facet)
+    {
+      func(&Facet::id, facet);
+    }
+
+  } // namespace
+
+  template class function<void(const locale::id*, const locale::facet*)>;
+
+  void
+  __locale_Impl_init_extra_ldbl128(
+      function<void(const locale::id*, const locale::facet*)> f,
+      bool classic)
+  {
+    if (classic)
+      {
+	init_facet(f, new (&money_get_c) money_get<char>(1));
+	init_facet(f, new (&money_put_c) money_put<char>(1));
+#ifdef _GLIBCXX_USE_WCHAR_T
+	init_facet(f, new (&money_get_w) money_get<wchar_t>(1));
+	init_facet(f, new (&money_put_w) money_put<wchar_t>(1));
+#endif
+      }
+    else
+      {
+	init_facet(f, new money_get<char>);
+	init_facet(f, new money_put<char>);
+#ifdef _GLIBCXX_USE_WCHAR_T
+	init_facet(f, new money_get<wchar_t>);
+	init_facet(f, new money_put<wchar_t>);
+#endif
+      }
+  }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
+#endif
diff --git a/libstdc++-v3/src/c++11/compatibility-ldbl-alt128.cc b/libstdc++-v3/src/c++11/compatibility-ldbl-alt128.cc
new file mode 100644
index 00000000000..27852f6e271
--- /dev/null
+++ b/libstdc++-v3/src/c++11/compatibility-ldbl-alt128.cc
@@ -0,0 +1,234 @@
+// Compatibility symbols for alternate 128-bit long-double format -*- C++ -*-
+
+// Copyright (C) 2018 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library 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.
+
+// This 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 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/>.
+
+#define _GLIBCXX_USE_CXX11_ABI 0
+#include <locale>
+
+#ifdef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT
+
+#ifndef __LONG_DOUBLE_IBM128__
+#error "compatibility-ldbl-alt128.cc must be compiled with -mabi=ibmlongdouble"
+#endif
+
+#define C char
+#define C_is_char
+#include "locale-inst-numeric.h"
+#include "locale-inst-monetary.h"
+#include "compatibility-ldbl-facets-aliases.h"
+
+#ifdef _GLIBCXX_USE_WCHAR_T
+# undef C
+# undef C_is_char
+# define C wchar_t
+# include "locale-inst-numeric.h"
+# include "locale-inst-monetary.h"
+# include "compatibility-ldbl-facets-aliases.h"
+# undef C
+#endif
+
+#include <limits>
+#include <functional>
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  // long double
+  const bool numeric_limits<long double>::is_specialized;
+  const int  numeric_limits<long double>::digits;
+  const int  numeric_limits<long double>::digits10;
+  const int  numeric_limits<long double>::max_digits10;
+  const bool numeric_limits<long double>::is_signed;
+  const bool numeric_limits<long double>::is_integer;
+  const bool numeric_limits<long double>::is_exact;
+  const int  numeric_limits<long double>::radix;
+  const int  numeric_limits<long double>::min_exponent;
+  const int  numeric_limits<long double>::min_exponent10;
+  const int  numeric_limits<long double>::max_exponent;
+  const int  numeric_limits<long double>::max_exponent10;
+  const bool numeric_limits<long double>::has_infinity;
+  const bool numeric_limits<long double>::has_quiet_NaN;
+  const bool numeric_limits<long double>::has_signaling_NaN;
+  const float_denorm_style numeric_limits<long double>::has_denorm;
+  const bool numeric_limits<long double>::has_denorm_loss;
+  const bool numeric_limits<long double>::is_iec559;
+  const bool numeric_limits<long double>::is_bounded;
+  const bool numeric_limits<long double>::is_modulo;
+  const bool numeric_limits<long double>::traps;
+  const bool numeric_limits<long double>::tinyness_before;
+  const float_round_style numeric_limits<long double>::round_style;
+
+  template<>
+    void
+    __convert_to_v(const char* __s, long double& __v, ios_base::iostate& __err,
+		   const __c_locale& __cloc) throw()
+    {
+      char* __sanity;
+#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
+      // Prefer strtold_l, as __strtold_l isn't prototyped in more recent
+      // glibc versions.
+      __v = strtold_l(__s, &__sanity, __cloc);
+#else
+      __v = __strtold_l(__s, &__sanity, __cloc);
+#endif
+
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // 23. Num_get overflow result.
+      if (__sanity == __s || *__sanity != '\0')
+	{
+	  __v = 0.0l;
+	  __err = ios_base::failbit;
+	}
+      else if (__v == numeric_limits<long double>::infinity())
+	{
+	  __v = numeric_limits<long double>::max();
+	  __err = ios_base::failbit;
+	}
+      else if (__v == -numeric_limits<long double>::infinity())
+	{
+	  __v = -numeric_limits<long double>::max();
+	  __err = ios_base::failbit;
+	}
+    }
+
+  namespace
+  {
+    alignas(money_get<char>) char money_get_c[sizeof(money_get<char>)];
+    alignas(money_put<char>) char money_put_c[sizeof(money_put<char>)];
+    alignas(num_get<char>) char num_get_c[sizeof(num_get<char>)];
+    alignas(num_put<char>) char num_put_c[sizeof(num_put<char>)];
+#ifdef _GLIBCXX_USE_WCHAR_T
+    alignas(money_get<wchar_t>) char money_get_w[sizeof(money_get<wchar_t>)];
+    alignas(money_put<wchar_t>) char money_put_w[sizeof(money_put<wchar_t>)];
+    alignas(num_get<wchar_t>) char num_get_w[sizeof(num_get<wchar_t>)];
+    alignas(num_put<wchar_t>) char num_put_w[sizeof(num_put<wchar_t>)];
+#endif
+  }
+
+  extern void
+  __locale_Impl_init_extra_ldbl128(
+      function<void(const locale::id*, const locale::facet*)>,
+      bool);
+
+  void
+  locale::_Impl::_M_init_extra_ldbl128(bool classic)
+  {
+    if (classic)
+      {
+	_M_init_facet(new (&money_get_c) money_get<char>(1));
+	_M_init_facet(new (&money_put_c) money_put<char>(1));
+	_M_init_facet(new (&num_get_c) num_get<char>(1));
+	_M_init_facet(new (&num_put_c) num_put<char>(1));
+#ifdef _GLIBCXX_USE_WCHAR_T
+	_M_init_facet(new (&money_get_w) money_get<wchar_t>(1));
+	_M_init_facet(new (&money_put_w) money_put<wchar_t>(1));
+	_M_init_facet(new (&num_get_w) num_get<wchar_t>(1));
+	_M_init_facet(new (&num_put_w) num_put<wchar_t>(1));
+#endif
+      }
+    else
+      {
+	_M_init_facet(new money_get<char>);
+	_M_init_facet(new money_put<char>);
+	_M_init_facet(new num_get<char>);
+	_M_init_facet(new num_put<char>);
+#ifdef _GLIBCXX_USE_WCHAR_T
+	_M_init_facet(new money_get<wchar_t>);
+	_M_init_facet(new money_put<wchar_t>);
+	_M_init_facet(new num_get<wchar_t>);
+	_M_init_facet(new num_put<wchar_t>);
+#endif
+      }
+
+#if _GLIBCXX_USE_DUAL_ABI
+    __locale_Impl_init_extra_ldbl128(
+	[this](const locale::id* i, const facet* f) {
+	    _M_install_facet(i, f);
+	},
+	classic);
+#endif
+  }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
+
+#include <istream>
+#include <ostream>
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+  template istream& istream::operator>>(long double&);
+  template istream& istream::_M_extract(long double&);
+  template ostream& ostream::operator<<(long double);
+  template ostream& ostream::_M_insert(long double);
+#ifdef _GLIBCXX_USE_WCHAR_T
+  template wistream& wistream::operator>>(long double&);
+  template wistream& wistream::_M_extract(long double&);
+  template wostream& wostream::operator<<(long double);
+  template wostream& wostream::_M_insert(long double);
+#endif
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
+
+#include <complex>
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+  template
+    basic_istream<char, char_traits<char> >&
+    operator>>(basic_istream<char, char_traits<char> >&,
+	       complex<long double>&);
+  template
+    basic_ostream<char, char_traits<char> >&
+    operator<<(basic_ostream<char, char_traits<char> >&,
+               const complex<long double>&);
+#ifdef _GLIBCXX_USE_WCHAR_T
+  template
+    basic_istream<wchar_t, char_traits<wchar_t> >&
+    operator>>(basic_istream<wchar_t, char_traits<wchar_t> >&,
+               complex<long double>&);
+  template
+    basic_ostream<wchar_t, char_traits<wchar_t> >&
+    operator<<(basic_ostream<wchar_t, char_traits<wchar_t> >&,
+               const complex<long double>&);
+#endif
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
+
+#include <cmath>
+#include <tr1/functional>
+
+// For std::tr1::hash<long double>::operator()
+#include "../c++98/hash-long-double-tr1-aux.cc"
+
+// std::tr1::hash<long double>::operator()
+// and std::hash<long double>::operator()
+// are the same, no need to duplicate them.
+extern "C" void
+_ZNKSt4hashIgEclEg (void)
+  __attribute__((alias ("_ZNKSt3tr14hashIgEclEg")));
+
+#endif
diff --git a/libstdc++-v3/src/c++11/compatibility-ldbl-facets-aliases.h b/libstdc++-v3/src/c++11/compatibility-ldbl-facets-aliases.h
new file mode 100644
index 00000000000..7bdf9810d0e
--- /dev/null
+++ b/libstdc++-v3/src/c++11/compatibility-ldbl-facets-aliases.h
@@ -0,0 +1,128 @@
+// Compatibility aliases for long double support in locales -*- C++ -*-
+
+// Copyright (C) 1999-2018 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library 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.
+
+// This 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 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/>.
+
+#ifndef C
+#define "This file should not be compiled directly, only included"
+#endif
+
+#ifndef _GLIBCXX_LONG_DOUBLE_COMPAT
+#define "This file should only be used for _GLIBCXX_LONG_DOUBLE_COMPAT builds"
+#endif
+
+// XXX GLIBCXX_ABI Deprecated
+#if defined __LONG_DOUBLE_128__ && ! defined __LONG_DOUBLE_IEEE128__
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wattribute-alias"
+
+#define _GLIBCXX_LDBL_COMPAT(dbl, ldbl) \
+  extern "C" void ldbl (void) __attribute__ ((alias (#dbl), weak))
+
+// Define members of std::num_get and std::num_put as aliases for
+// members of __gnu_cxx_ldbl128::num_get and __gnu_cxx_ldbl128::num_put
+#ifdef C_is_char
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIjEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
+		     _ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIjEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIlEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
+		     _ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIlEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intImEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
+		     _ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intImEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intItEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
+		     _ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intItEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIxEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
+		     _ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIxEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIyEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
+		     _ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIyEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intIlEES4_S4_RSt8ios_basecT_,
+		     _ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intIlEES3_S3_RSt8ios_basecT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intImEES4_S4_RSt8ios_basecT_,
+		     _ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intImEES3_S3_RSt8ios_basecT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intIxEES4_S4_RSt8ios_basecT_,
+		     _ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intIxEES3_S3_RSt8ios_basecT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intIyEES4_S4_RSt8ios_basecT_,
+		     _ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intIyEES3_S3_RSt8ios_basecT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES4_S4_RSt8ios_baseccT_,
+		     _ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_,
+		     _ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIeEES3_S3_RSt8ios_baseccT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1289money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE10_M_extractILb0EEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRSs,
+		     _ZNKSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE10_M_extractILb0EEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRSs);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1289money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE10_M_extractILb1EEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRSs,
+		     _ZNKSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE10_M_extractILb1EEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRSs);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1289money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE9_M_insertILb0EEES4_S4_RSt8ios_basecRKSs,
+		     _ZNKSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE9_M_insertILb0EEES3_S3_RSt8ios_basecRKSs);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1289money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE9_M_insertILb1EEES4_S4_RSt8ios_basecRKSs,
+		     _ZNKSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE9_M_insertILb1EEES3_S3_RSt8ios_basecRKSs);
+#else // ! C_is_char
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIjEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
+		     _ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIjEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIlEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
+		     _ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIlEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intImEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
+		     _ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intImEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intItEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
+		     _ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intItEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIxEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
+		     _ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIxEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIyEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
+		     _ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIyEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intIlEES4_S4_RSt8ios_basewT_,
+		     _ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intIlEES3_S3_RSt8ios_basewT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intImEES4_S4_RSt8ios_basewT_,
+		     _ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intImEES3_S3_RSt8ios_basewT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intIxEES4_S4_RSt8ios_basewT_,
+		     _ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intIxEES3_S3_RSt8ios_basewT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intIyEES4_S4_RSt8ios_basewT_,
+		     _ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intIyEES3_S3_RSt8ios_basewT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE15_M_insert_floatIdEES4_S4_RSt8ios_basewcT_,
+		     _ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE15_M_insert_floatIdEES3_S3_RSt8ios_basewcT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE15_M_insert_floatIdEES3_S3_RSt8ios_basewcT_,
+		     _ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE15_M_insert_floatIeEES3_S3_RSt8ios_basewcT_);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1289money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE10_M_extractILb0EEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRSs,
+		     _ZNKSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE10_M_extractILb0EEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRSs);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1289money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE10_M_extractILb1EEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRSs,
+		     _ZNKSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE10_M_extractILb1EEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRSs);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1289money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE9_M_insertILb0EEES4_S4_RSt8ios_basewRKSbIwS3_SaIwEE,
+		     _ZNKSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE9_M_insertILb0EEES3_S3_RSt8ios_basewRKSbIwS2_SaIwEE);
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1289money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE9_M_insertILb1EEES4_S4_RSt8ios_basewRKSbIwS3_SaIwEE,
+		     _ZNKSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE9_M_insertILb1EEES3_S3_RSt8ios_basewRKSbIwS2_SaIwEE);
+#endif // C_is_char
+
+
+#if defined _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT
+// Define __gnu_cxx_ieee128::num_put<>::_M_insert_float(..., __ibm128) as
+// alias of __gnu_cxx_ldbl128::num_put<>::_M_insert_float(..., __ibm128)
+# ifdef C_is_char
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIgEES4_S4_RSt8ios_baseccT_,
+		     _ZNKSt17__gnu_cxx_ieee1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIgEES4_S4_RSt8ios_baseccT_);
+# else
+_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE15_M_insert_floatIgEES4_S4_RSt8ios_basewcT_,
+		     _ZNKSt17__gnu_cxx_ieee1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE15_M_insert_floatIgEES4_S4_RSt8ios_basewcT_);
+# endif
+#endif // _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT
+
+#undef _GLIBCXX_LDBL_COMPAT
+#pragma GCC diagnostic pop
+
+#endif  // __LONG_DOUBLE_128__ && ! __LONG_DOUBLE_IEEE128__
diff --git a/libstdc++-v3/src/c++11/cow-locale_init.cc b/libstdc++-v3/src/c++11/cow-locale_init.cc
index 98a2ef41f56..bf270712e47 100644
--- a/libstdc++-v3/src/c++11/cow-locale_init.cc
+++ b/libstdc++-v3/src/c++11/cow-locale_init.cc
@@ -125,6 +125,7 @@ namespace
     _M_init_facet_unchecked(new (&messages_w) std::messages<wchar_t>(1));
 #endif
 
+    // The caches must be populated last, after creating all facets.
     _M_caches[numpunct<char>::id._M_id()] = __npc;
     _M_caches[moneypunct<char, false>::id._M_id()] = __mpcf;
     _M_caches[moneypunct<char, true>::id._M_id()] = __mpct;
diff --git a/libstdc++-v3/src/c++11/cxx11-locale-inst.cc b/libstdc++-v3/src/c++11/cxx11-locale-inst.cc
index 7b132a748bf..9378550124f 100644
--- a/libstdc++-v3/src/c++11/cxx11-locale-inst.cc
+++ b/libstdc++-v3/src/c++11/cxx11-locale-inst.cc
@@ -32,8 +32,6 @@
 # error This file should not be compiled for this configuration.
 #endif
 
-#ifndef C
-# define C char
-# define C_is_char
-#endif
+#define C char
+#define C_is_char
 # include "locale-inst.cc"
diff --git a/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc b/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc
index cf3d6dc7e34..07eb6008361 100644
--- a/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc
+++ b/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc
@@ -24,9 +24,15 @@
 // ISO C++ 14882: 22.1  Locales
 //
 
+// Facet wchar_t instantiations using new ABI strings.
+
 #define _GLIBCXX_USE_CXX11_ABI 1
 #include <bits/c++config.h>
+#if ! _GLIBCXX_USE_DUAL_ABI
+# error This file should not be compiled for this configuration.
+#endif
+
 #ifdef _GLIBCXX_USE_WCHAR_T
 #define C wchar_t
-#include "cxx11-locale-inst.cc"
+#include "locale-inst.cc"
 #endif
diff --git a/libstdc++-v3/src/c++11/locale-inst-monetary.h b/libstdc++-v3/src/c++11/locale-inst-monetary.h
new file mode 100644
index 00000000000..e9b3e7c4e0c
--- /dev/null
+++ b/libstdc++-v3/src/c++11/locale-inst-monetary.h
@@ -0,0 +1,69 @@
+// Explicit instantantiations for monetary facets -*- C++ -*-
+
+// Copyright (C) 2018 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library 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.
+
+// This 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 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/>.
+
+#ifndef C
+#define "This file should not be compiled directly, only included"
+#endif
+
+// This header is included multiple times, to instantiate these symbols
+// for char/wchar_t and for both std::string ABIs,
+// and (depending on the target) for two long double formats.
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+  template const money_put<C>& use_facet<money_put<C> >(const locale&);
+  template const money_get<C>& use_facet<money_get<C> >(const locale&);
+
+  template bool has_facet<money_put<C> >(const locale&);
+  template bool has_facet<money_get<C> >(const locale&);
+
+_GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11
+  template class money_get<C, istreambuf_iterator<C> >;
+  template class money_put<C, ostreambuf_iterator<C> >;
+
+  template
+    istreambuf_iterator<C>
+    money_get<C, istreambuf_iterator<C> >::
+    _M_extract<true>(istreambuf_iterator<C>, istreambuf_iterator<C>,
+		     ios_base&, ios_base::iostate&, string&) const;
+
+  template
+    istreambuf_iterator<C>
+    money_get<C, istreambuf_iterator<C> >::
+    _M_extract<false>(istreambuf_iterator<C>, istreambuf_iterator<C>,
+		      ios_base&, ios_base::iostate&, string&) const;
+
+  template
+    ostreambuf_iterator<C>
+    money_put<C, ostreambuf_iterator<C> >::
+    _M_insert<true>(ostreambuf_iterator<C>, ios_base&, C,
+		    const string_type&) const;
+
+  template
+    ostreambuf_iterator<C>
+    money_put<C, ostreambuf_iterator<C> >::
+    _M_insert<false>(ostreambuf_iterator<C>, ios_base&, C,
+		     const string_type&) const;
+_GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11
+} // namespace std
diff --git a/libstdc++-v3/src/c++11/locale-inst-numeric.h b/libstdc++-v3/src/c++11/locale-inst-numeric.h
new file mode 100644
index 00000000000..0ec93e27937
--- /dev/null
+++ b/libstdc++-v3/src/c++11/locale-inst-numeric.h
@@ -0,0 +1,133 @@
+// Explicit instantantiations for numeric facets -*- C++ -*-
+
+// Copyright (C) 2018 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library 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.
+
+// This 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 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/>.
+
+#ifndef C
+#define "This file should not be compiled directly, only included"
+#endif
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+#if ! _GLIBCXX_USE_CXX11_ABI
+  template const num_get<C>& use_facet<num_get<C> >(const locale&);
+  template const num_put<C>& use_facet<num_put<C> >(const locale&);
+
+  template bool has_facet<num_get<C> >(const locale&);
+  template bool has_facet<num_put<C> >(const locale&);
+#endif
+
+_GLIBCXX_BEGIN_NAMESPACE_LDBL
+
+#if ! _GLIBCXX_USE_CXX11_ABI
+  template class num_get<C, istreambuf_iterator<C> >;
+  template class num_put<C, ostreambuf_iterator<C> >;
+#endif
+
+  // num_get member function templates
+  template
+    istreambuf_iterator<C>
+    num_get<C, istreambuf_iterator<C> >::
+    _M_extract_int(istreambuf_iterator<C>, istreambuf_iterator<C>,
+		   ios_base&, ios_base::iostate&,
+		   long&) const;
+
+  template
+    istreambuf_iterator<C>
+    num_get<C, istreambuf_iterator<C> >::
+    _M_extract_int(istreambuf_iterator<C>, istreambuf_iterator<C>,
+		   ios_base&, ios_base::iostate&,
+		   unsigned short&) const;
+
+  template
+    istreambuf_iterator<C>
+    num_get<C, istreambuf_iterator<C> >::
+    _M_extract_int(istreambuf_iterator<C>, istreambuf_iterator<C>,
+		   ios_base&, ios_base::iostate&,
+		   unsigned int&) const;
+
+  template
+    istreambuf_iterator<C>
+    num_get<C, istreambuf_iterator<C> >::
+    _M_extract_int(istreambuf_iterator<C>, istreambuf_iterator<C>,
+		   ios_base&, ios_base::iostate&,
+		   unsigned long&) const;
+
+#ifdef _GLIBCXX_USE_LONG_LONG
+  template
+    istreambuf_iterator<C>
+    num_get<C, istreambuf_iterator<C> >::
+    _M_extract_int(istreambuf_iterator<C>, istreambuf_iterator<C>,
+		   ios_base&, ios_base::iostate&,
+		   long long&) const;
+
+  template
+    istreambuf_iterator<C>
+    num_get<C, istreambuf_iterator<C> >::
+    _M_extract_int(istreambuf_iterator<C>, istreambuf_iterator<C>,
+		   ios_base&, ios_base::iostate&,
+		   unsigned long long&) const;
+#endif
+
+#if ! _GLIBCXX_USE_CXX11_ABI
+  // num_put member function templates
+  template
+    ostreambuf_iterator<C>
+    num_put<C, ostreambuf_iterator<C> >::
+    _M_insert_int(ostreambuf_iterator<C>, ios_base&, C,
+		  long) const;
+
+  template
+    ostreambuf_iterator<C>
+    num_put<C, ostreambuf_iterator<C> >::
+    _M_insert_int(ostreambuf_iterator<C>, ios_base&, C,
+		  unsigned long) const;
+
+#ifdef _GLIBCXX_USE_LONG_LONG
+  template
+    ostreambuf_iterator<C>
+    num_put<C, ostreambuf_iterator<C> >::
+    _M_insert_int(ostreambuf_iterator<C>, ios_base&, C,
+		  long long) const;
+
+  template
+    ostreambuf_iterator<C>
+    num_put<C, ostreambuf_iterator<C> >::
+    _M_insert_int(ostreambuf_iterator<C>, ios_base&, C,
+		  unsigned long long) const;
+#endif
+
+  template
+    ostreambuf_iterator<C>
+    num_put<C, ostreambuf_iterator<C> >::
+    _M_insert_float(ostreambuf_iterator<C>, ios_base&, C, char,
+		    double) const;
+
+  template
+    ostreambuf_iterator<C>
+    num_put<C, ostreambuf_iterator<C> >::
+    _M_insert_float(ostreambuf_iterator<C>, ios_base&, C, char,
+		    long double) const;
+#endif
+
+_GLIBCXX_END_NAMESPACE_LDBL
+} // namespace std
diff --git a/libstdc++-v3/src/c++11/locale-inst.cc b/libstdc++-v3/src/c++11/locale-inst.cc
index 4dc7f5c0780..cd99648e8f6 100644
--- a/libstdc++-v3/src/c++11/locale-inst.cc
+++ b/libstdc++-v3/src/c++11/locale-inst.cc
@@ -43,6 +43,9 @@
 # define C_is_char
 #endif
 
+#include "locale-inst-numeric.h"
+#include "locale-inst-monetary.h"
+
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -58,33 +61,6 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
   template class moneypunct_byname<C, false>;
   template class moneypunct_byname<C, true>;
 _GLIBCXX_END_NAMESPACE_CXX11
-_GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11
-  template class money_get<C, istreambuf_iterator<C> >;
-  template class money_put<C, ostreambuf_iterator<C> >;
-  template
-    istreambuf_iterator<C>
-    money_get<C, istreambuf_iterator<C> >::
-    _M_extract<true>(istreambuf_iterator<C>, istreambuf_iterator<C>,
-		     ios_base&, ios_base::iostate&, string&) const;
-
-  template
-    istreambuf_iterator<C>
-    money_get<C, istreambuf_iterator<C> >::
-    _M_extract<false>(istreambuf_iterator<C>, istreambuf_iterator<C>,
-		      ios_base&, ios_base::iostate&, string&) const;
-
-  template
-    ostreambuf_iterator<C>
-    money_put<C, ostreambuf_iterator<C> >::
-    _M_insert<true>(ostreambuf_iterator<C>, ios_base&, C,
-		    const string_type&) const;
-
-  template
-    ostreambuf_iterator<C>
-    money_put<C, ostreambuf_iterator<C> >::
-    _M_insert<false>(ostreambuf_iterator<C>, ios_base&, C,
-		     const string_type&) const;
-_GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11
 
   // numpunct, numpunct_byname, num_get, and num_put
 #if ! _GLIBCXX_USE_CXX11_ABI
@@ -94,97 +70,6 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
   template class numpunct<C>;
   template class numpunct_byname<C>;
 _GLIBCXX_END_NAMESPACE_CXX11
-_GLIBCXX_BEGIN_NAMESPACE_LDBL
-#if ! _GLIBCXX_USE_CXX11_ABI
-  template class num_get<C, istreambuf_iterator<C> >;
-#endif
-
-  template
-    istreambuf_iterator<C>
-    num_get<C, istreambuf_iterator<C> >::
-    _M_extract_int(istreambuf_iterator<C>, istreambuf_iterator<C>,
-		   ios_base&, ios_base::iostate&,
-		   long&) const;
-
-  template
-    istreambuf_iterator<C>
-    num_get<C, istreambuf_iterator<C> >::
-    _M_extract_int(istreambuf_iterator<C>, istreambuf_iterator<C>,
-		   ios_base&, ios_base::iostate&,
-		   unsigned short&) const;
-
-  template
-    istreambuf_iterator<C>
-    num_get<C, istreambuf_iterator<C> >::
-    _M_extract_int(istreambuf_iterator<C>, istreambuf_iterator<C>,
-		   ios_base&, ios_base::iostate&,
-		   unsigned int&) const;
-
-  template
-    istreambuf_iterator<C>
-    num_get<C, istreambuf_iterator<C> >::
-    _M_extract_int(istreambuf_iterator<C>, istreambuf_iterator<C>,
-		   ios_base&, ios_base::iostate&,
-		   unsigned long&) const;
-
-#ifdef _GLIBCXX_USE_LONG_LONG
-  template
-    istreambuf_iterator<C>
-    num_get<C, istreambuf_iterator<C> >::
-    _M_extract_int(istreambuf_iterator<C>, istreambuf_iterator<C>,
-		   ios_base&, ios_base::iostate&,
-		   long long&) const;
-
-  template
-    istreambuf_iterator<C>
-    num_get<C, istreambuf_iterator<C> >::
-    _M_extract_int(istreambuf_iterator<C>, istreambuf_iterator<C>,
-		   ios_base&, ios_base::iostate&,
-		   unsigned long long&) const;
-#endif
-
-#if ! _GLIBCXX_USE_CXX11_ABI
-  template class num_put<C, ostreambuf_iterator<C> >;
-
-  template
-    ostreambuf_iterator<C>
-    num_put<C, ostreambuf_iterator<C> >::
-    _M_insert_int(ostreambuf_iterator<C>, ios_base&, C,
-		  long) const;
-
-  template
-    ostreambuf_iterator<C>
-    num_put<C, ostreambuf_iterator<C> >::
-    _M_insert_int(ostreambuf_iterator<C>, ios_base&, C,
-		  unsigned long) const;
-
-#ifdef _GLIBCXX_USE_LONG_LONG
-  template
-    ostreambuf_iterator<C>
-    num_put<C, ostreambuf_iterator<C> >::
-    _M_insert_int(ostreambuf_iterator<C>, ios_base&, C,
-		  long long) const;
-
-  template
-    ostreambuf_iterator<C>
-    num_put<C, ostreambuf_iterator<C> >::
-    _M_insert_int(ostreambuf_iterator<C>, ios_base&, C,
-		  unsigned long long) const;
-#endif
-
-  template
-    ostreambuf_iterator<C>
-    num_put<C, ostreambuf_iterator<C> >::
-    _M_insert_float(ostreambuf_iterator<C>, ios_base&, C, char,
-		    double) const;
-
-  template
-    ostreambuf_iterator<C>
-    num_put<C, ostreambuf_iterator<C> >::
-    _M_insert_float(ostreambuf_iterator<C>, ios_base&, C, char,
-		    long double) const;
-#endif
-_GLIBCXX_END_NAMESPACE_LDBL
 
   // time_get and time_put
 #if ! _GLIBCXX_USE_CXX11_ABI
@@ -250,16 +135,6 @@ _GLIBCXX_END_NAMESPACE_CXX11
     const numpunct<C>&
     use_facet<numpunct<C> >(const locale&);
 
-#if ! _GLIBCXX_USE_CXX11_ABI
-  template
-    const num_put<C>&
-    use_facet<num_put<C> >(const locale&);
-
-  template
-    const num_get<C>&
-    use_facet<num_get<C> >(const locale&);
-#endif
-
   template
     const moneypunct<C, true>&
     use_facet<moneypunct<C, true> >(const locale&);
@@ -268,14 +143,6 @@ _GLIBCXX_END_NAMESPACE_CXX11
     const moneypunct<C, false>&
     use_facet<moneypunct<C, false> >(const locale&);
 
-  template
-    const money_put<C>&
-    use_facet<money_put<C> >(const locale&);
-
-  template
-    const money_get<C>&
-    use_facet<money_get<C> >(const locale&);
-
 #if ! _GLIBCXX_USE_CXX11_ABI
   template
     const __timepunct<C>&
@@ -313,28 +180,10 @@ _GLIBCXX_END_NAMESPACE_CXX11
     bool
     has_facet<numpunct<C> >(const locale&);
 
-#if ! _GLIBCXX_USE_CXX11_ABI
-  template
-    bool
-    has_facet<num_put<C> >(const locale&);
-
-  template
-    bool
-    has_facet<num_get<C> >(const locale&);
-#endif
-
   template
     bool
     has_facet<moneypunct<C> >(const locale&);
 
-  template
-    bool
-    has_facet<money_put<C> >(const locale&);
-
-  template
-    bool
-    has_facet<money_get<C> >(const locale&);
-
 #if ! _GLIBCXX_USE_CXX11_ABI
   template
     bool
@@ -380,45 +229,6 @@ _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
 
 // XXX GLIBCXX_ABI Deprecated
-#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined C_is_char \
-      && _GLIBCXX_USE_CXX11_ABI == 0
-
-#pragma GCC diagnostic ignored "-Wattribute-alias"
-
-#define _GLIBCXX_LDBL_COMPAT(dbl, ldbl) \
-  extern "C" void ldbl (void) __attribute__ ((alias (#dbl), weak))
-
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIjEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
-		     _ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIjEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIlEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
-		     _ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIlEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intImEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
-		     _ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intImEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intItEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
-		     _ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intItEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIxEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
-		     _ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIxEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIyEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
-		     _ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIyEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intIlEES4_S4_RSt8ios_basecT_,
-		     _ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intIlEES3_S3_RSt8ios_basecT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intImEES4_S4_RSt8ios_basecT_,
-		     _ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intImEES3_S3_RSt8ios_basecT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intIxEES4_S4_RSt8ios_basecT_,
-		     _ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intIxEES3_S3_RSt8ios_basecT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intIyEES4_S4_RSt8ios_basecT_,
-		     _ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intIyEES3_S3_RSt8ios_basecT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES4_S4_RSt8ios_baseccT_,
-		     _ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_,
-		     _ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIeEES3_S3_RSt8ios_baseccT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1289money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE10_M_extractILb0EEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRSs,
-		     _ZNKSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE10_M_extractILb0EEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRSs);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1289money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE10_M_extractILb1EEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRSs,
-		     _ZNKSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE10_M_extractILb1EEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRSs);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1289money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE9_M_insertILb0EEES4_S4_RSt8ios_basecRKSs,
-		     _ZNKSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE9_M_insertILb0EEES3_S3_RSt8ios_basecRKSs);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1289money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE9_M_insertILb1EEES4_S4_RSt8ios_basecRKSs,
-		     _ZNKSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE9_M_insertILb1EEES3_S3_RSt8ios_basecRKSs);
-
+#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && ! _GLIBCXX_USE_CXX11_ABI
+#include "compatibility-ldbl-facets-aliases.h"
 #endif // _GLIBCXX_LONG_DOUBLE_COMPAT
diff --git a/libstdc++-v3/src/c++11/wlocale-inst.cc b/libstdc++-v3/src/c++11/wlocale-inst.cc
index 3a54fb51aab..a9a246f8f97 100644
--- a/libstdc++-v3/src/c++11/wlocale-inst.cc
+++ b/libstdc++-v3/src/c++11/wlocale-inst.cc
@@ -33,47 +33,4 @@
 #ifdef _GLIBCXX_USE_WCHAR_T
 #define C wchar_t
 #include "locale-inst.cc"
-
-// XXX GLIBCXX_ABI Deprecated
-#if defined _GLIBCXX_LONG_DOUBLE_COMPAT
-
-#pragma GCC diagnostic ignored "-Wattribute-alias"
-
-#define _GLIBCXX_LDBL_COMPAT(dbl, ldbl) \
-  extern "C" void ldbl (void) __attribute__ ((alias (#dbl), weak))
-
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIjEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
-		     _ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIjEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIlEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
-		     _ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIlEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intImEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
-		     _ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intImEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intItEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
-		     _ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intItEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIxEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
-		     _ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIxEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIyEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_,
-		     _ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIyEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intIlEES4_S4_RSt8ios_basewT_,
-		     _ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intIlEES3_S3_RSt8ios_basewT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intImEES4_S4_RSt8ios_basewT_,
-		     _ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intImEES3_S3_RSt8ios_basewT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intIxEES4_S4_RSt8ios_basewT_,
-		     _ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intIxEES3_S3_RSt8ios_basewT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intIyEES4_S4_RSt8ios_basewT_,
-		     _ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intIyEES3_S3_RSt8ios_basewT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE15_M_insert_floatIdEES4_S4_RSt8ios_basewcT_,
-		     _ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE15_M_insert_floatIdEES3_S3_RSt8ios_basewcT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE15_M_insert_floatIdEES3_S3_RSt8ios_basewcT_,
-		     _ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE15_M_insert_floatIeEES3_S3_RSt8ios_basewcT_);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1289money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE10_M_extractILb0EEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRSs,
-		     _ZNKSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE10_M_extractILb0EEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRSs);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1289money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE10_M_extractILb1EEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRSs,
-		     _ZNKSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE10_M_extractILb1EEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRSs);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1289money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE9_M_insertILb0EEES4_S4_RSt8ios_basewRKSbIwS3_SaIwEE,
-		     _ZNKSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE9_M_insertILb0EEES3_S3_RSt8ios_basewRKSbIwS2_SaIwEE);
-_GLIBCXX_LDBL_COMPAT(_ZNKSt17__gnu_cxx_ldbl1289money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE9_M_insertILb1EEES4_S4_RSt8ios_basewRKSbIwS3_SaIwEE,
-		     _ZNKSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE9_M_insertILb1EEES3_S3_RSt8ios_basewRKSbIwS2_SaIwEE);
-
-#endif // _GLIBCXX_LONG_DOUBLE_COMPAT
-#endif
+#endif // _GLIBCXX_USE_WCHAR_T
diff --git a/libstdc++-v3/src/c++98/locale_init.cc b/libstdc++-v3/src/c++98/locale_init.cc
index c3841ccbd3c..77c6eecc1a3 100644
--- a/libstdc++-v3/src/c++98/locale_init.cc
+++ b/libstdc++-v3/src/c++98/locale_init.cc
@@ -57,8 +57,16 @@ _GLIBCXX_LOC_ID(_ZNSt8messagesIwE2idE);
 
 namespace
 {
-  const int num_facets = _GLIBCXX_NUM_FACETS + _GLIBCXX_NUM_UNICODE_FACETS
-    + (_GLIBCXX_USE_DUAL_ABI ? _GLIBCXX_NUM_CXX11_FACETS : 0);
+  const int num_facets = (
+      _GLIBCXX_NUM_FACETS + _GLIBCXX_NUM_CXX11_FACETS
+#ifdef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT
+      + _GLIBCXX_NUM_LBDL_ALT128_FACETS
+#endif
+      )
+#ifdef _GLIBCXX_USE_WCHAR_T
+    * 2
+#endif
+    + _GLIBCXX_NUM_UNICODE_FACETS;
 
   __gnu_cxx::__mutex&
   get_locale_mutex()
@@ -559,6 +567,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 #endif
 
+#ifdef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT
+    _M_init_extra_ldbl128(true);
+#endif
+
 #if _GLIBCXX_USE_DUAL_ABI
     facet* extra[] = { __npc, __mpcf, __mpct
 # ifdef  _GLIBCXX_USE_WCHAR_T
@@ -566,6 +578,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 # endif
     };
 
+    // This call must be after creating all facets, as it sets caches.
     _M_init_extra(extra);
 #endif
 
diff --git a/libstdc++-v3/src/c++98/localename.cc b/libstdc++-v3/src/c++98/localename.cc
index 243acce164c..29f439ffa9a 100644
--- a/libstdc++-v3/src/c++98/localename.cc
+++ b/libstdc++-v3/src/c++98/localename.cc
@@ -171,8 +171,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
   }
 
-const int num_facets = _GLIBCXX_NUM_FACETS + _GLIBCXX_NUM_UNICODE_FACETS
-  + (_GLIBCXX_USE_DUAL_ABI ? _GLIBCXX_NUM_CXX11_FACETS : 0);
+const int num_facets = (
+    _GLIBCXX_NUM_FACETS + _GLIBCXX_NUM_CXX11_FACETS
+#ifdef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT
+    + _GLIBCXX_NUM_LBDL_ALT128_FACETS
+#endif
+    )
+#ifdef _GLIBCXX_USE_WCHAR_T
+  * 2
+#endif
+  + _GLIBCXX_NUM_UNICODE_FACETS;
 
   // Construct named _Impl.
   locale::_Impl::
@@ -284,6 +292,10 @@ const int num_facets = _GLIBCXX_NUM_FACETS + _GLIBCXX_NUM_UNICODE_FACETS
         _M_init_extra(&__cloc, &__clocm, __s, __smon);
 #endif
 
+#ifdef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT
+	_M_init_extra_ldbl128(false);
+#endif
+
 	locale::facet::_S_destroy_c_locale(__cloc);
 	if (__clocm != __cloc)
 	  locale::facet::_S_destroy_c_locale(__clocm);
diff --git a/libstdc++-v3/testsuite/util/testsuite_abi.cc b/libstdc++-v3/testsuite/util/testsuite_abi.cc
index 33b9ec15935..bbe397ae8a4 100644
--- a/libstdc++-v3/testsuite/util/testsuite_abi.cc
+++ b/libstdc++-v3/testsuite/util/testsuite_abi.cc
@@ -207,6 +207,7 @@ check_version(symbol& test, bool added)
       known_versions.push_back("GLIBCXX_3.4.24");
       known_versions.push_back("GLIBCXX_3.4.25");
       known_versions.push_back("GLIBCXX_3.4.26");
+      known_versions.push_back("GLIBCXX_IEEE128_3.4.26");
       known_versions.push_back("GLIBCXX_3.4.27");
       known_versions.push_back("GLIBCXX_3.4.28");
       known_versions.push_back("GLIBCXX_3.4.29");
@@ -225,6 +226,7 @@ check_version(symbol& test, bool added)
       known_versions.push_back("CXXABI_1.3.10");
       known_versions.push_back("CXXABI_1.3.11");
       known_versions.push_back("CXXABI_1.3.12");
+      known_versions.push_back("CXXABI_IEEE128_1.3.12");
       known_versions.push_back("CXXABI_1.3.13");
       known_versions.push_back("CXXABI_TM_1");
       known_versions.push_back("CXXABI_FLOAT128");
@@ -260,7 +262,17 @@ check_version(symbol& test, bool added)
 	  && test.demangled_name.find("std::__cxx11::") != 0)
 	{
 	  if (test.version_name.find("_LDBL_") == std::string::npos
-	      && test.version_name.find("_FLOAT128") == std::string::npos)
+	      && test.version_name.find("_FLOAT128") == std::string::npos
+	      && test.version_name.find("_IEEE128") == std::string::npos)
+	    test.version_status = symbol::incompatible;
+	}
+
+      // Check that IEEE128 long double compatibility symbols demangled as
+      // __ieee128 are put into some _LDBL_IEEE version name.
+      // XXX is this right? might not want *everything* for __ieee128 in here.
+      if (added && test.demangled_name.find("__ieee128") != std::string::npos)
+	{
+	  if (test.version_name.find("_IEEE128") == std::string::npos)
 	    test.version_status = symbol::incompatible;
 	}


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2020-11-30 19:06 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-30 18:59 [gcc(refs/users/meissner/heads/work029)] Add C++ runtime support for new 128-bit long double format Michael Meissner
2020-11-30 19:06 Michael Meissner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).