This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Add C++ runtime support for new 128-bit long double format


This adds support for the new 128-bit long double format on powerpc64,
see https://fedoraproject.org/wiki/Changes/PPC64LE_Float128_Transition
for more details.

Most of the required changes are to the locale facets that parse and
print long doubles, as used by iostreams for reading/writing numbers.

I followed the same design as is used for the existing
-mlong-double-64 compatibility, i.e. adding extra virtual functions to
the facet classes so that they are capable of handling the old and new
formats, using different virtual functions. For example, std::num_get
only handles 64-bit long double, and has only the virtual functions
described by the standard. For floating point types these are the
following:

iter_type do_get( iter_type in, iter_type end, std::ios_base& str,
                 std::ios_base::iostate& err, float& v ) const;

iter_type do_get( iter_type in, iter_type end, std::ios_base& str,
                 std::ios_base::iostate& err, double& v ) const;

iter_type do_get( iter_type in, iter_type end, std::ios_base& str,
                 std::ios_base::iostate& err, long double& v ) const;


The __gnu_cxx_ldbl128::num_get class has an extra virtual function:

iter_type do_get( iter_type in, iter_type end, std::ios_base& str,
                 std::ios_base::iostate& err, float& v ) const;

iter_type do_get( iter_type in, iter_type end, std::ios_base& str,
                 std::ios_base::iostate& err, double& v ) const;

// Handles 64-bit long double, which has the same representation as
// double:
iter_type __do_get( iter_type in, iter_type end, std::ios_base& str,
                   std::ios_base::iostate& err, double& v ) const;

// Handles 128-bit long double:
iter_type do_get( iter_type in, iter_type end, std::ios_base& str,
                 std::ios_base::iostate& err, long double& v ) const;


The __gnu_cxx_ieee128::num_get class added by this patch has another
extra virtual function:

iter_type do_get( iter_type in, iter_type end, std::ios_base& str,
                 std::ios_base::iostate& err, float& v ) const;

iter_type do_get( iter_type in, iter_type end, std::ios_base& str,
                 std::ios_base::iostate& err, double& v ) const;

// Handles 64-bit long double, which has the same representation as
// double:
iter_type __do_get( iter_type in, iter_type end, std::ios_base& str,
                   std::ios_base::iostate& err, double& v ) const;

// Handles old IBM 128-bit long double:
iter_type __do_get( iter_type in, iter_type end, std::ios_base& str,
                   std::ios_base::iostate& err, __ibm128& v ) const;

// Handles new IEEE 128-bit long double:
iter_type do_get( iter_type in, iter_type end, std::ios_base& str,
                 std::ios_base::iostate& err, long double& v ) const;

However, I'm not really sure if we want to do this. I don't understand
the purpose of having a new facet type that has virtual functions for
handling alternative long double formats. The facet can never be used
because std::use_facet<std::num_get> will resolve to std::num_get when
-mlong-double-64 is used, and that facet isn't installed in any
locales by default (only __gnu_cxx_ldbl128::num_get is).

Maybe I should not have bothered to copy this technique this for the
new long double formats. I'm not sure.

Currently this patch causes a few regressions, due to the facets for
the IBM 128-bit long double format no longer being installed in the
locales. That means that 100% conforming behaviour is only possible
for the new IEEE 128-bit long double. I'm not sure what the migration
plan is for that type, and whether both formats need to work
equivalently. That would require installing both the
__gnu_cxx_ldbl128::num_get and __gnu_cxx_ieee128::num_get facets (and
similarly for num_put, money_get and money_put).

So this patch probably isn't in its final form, but I'm posting it now
to make the stage 1 deadline, and will complete it ASAP.

	* 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.


Attachment: patch.txt
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]