This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [RFC PATCH] Optionally use -mlong-double-128 by default on {powerpc{,64},s390{,x},sparc,alpha}-linux
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Benjamin Kosnik <bkoz at redhat dot com>, Roland McGrath <roland at redhat dot com>
- Cc: rth at redhat dot com, gcc-patches at gcc dot gnu dot org, libstdc++ at gcc dot gnu dot org
- Date: Mon, 30 Jan 2006 13:39:00 -0500
- Subject: Re: [RFC PATCH] Optionally use -mlong-double-128 by default on {powerpc{,64},s390{,x},sparc,alpha}-linux
- References: <20060127165807.GV32233@devserv.devel.redhat.com> <20060128155146.677ac5a4.bkoz@redhat.com>
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
On Sat, Jan 28, 2006 at 03:51:46PM -0600, Benjamin Kosnik wrote:
> > * src/complex_io.cc [_GLIBCXX_LONG_DOUBLE_COMPAT]: Add compatibility
> > symbols.
> > * src/istream-inst.cc [_GLIBCXX_LONG_DOUBLE_COMPAT]: Likewise.
> > * src/limits.cc [_GLIBCXX_LONG_DOUBLE_COMPAT]: Likewise.
> > * src/locale-inst.cc [_GLIBCXX_LONG_DOUBLE_COMPAT]: Likewise.
> > * src/ostream-inst.cc [_GLIBCXX_LONG_DOUBLE_COMPAT]: Likewise.
> > * src/wlocale-inst.cc [_GLIBCXX_LONG_DOUBLE_COMPAT]: Likewise.
> > * config/locale/generic/c_locale.cc [_GLIBCXX_LONG_DOUBLE_COMPAT]:
> > Likewise.
> > * config/locale/gnu/c_locale.cc [_GLIBCXX_LONG_DOUBLE_COMPAT]: Likewise.
> > * libmath/stubs.c []: Likewise.
>
> I would like to move the _GLIBCXX_LONG_DOUBLE_COMPAT bits into src/compatibility.cc.
In some cases that's not possible (libsupc++ typeinfo), the rest is probably
possible but would require moving some instantiations into compatibility.cc
together with the symver stuff. Anyway, I'd like to have a working stuff
first, then do cleanups.
> I'm having problems applying this patch to mainline.
I was doing this on gcc-4_1-branch.
> > Also, there is another problem I haven't thought of before.
> > 8 virtual tables contain pointers to methods with long double
> > arguments:
> > _ZTVSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE
> > _ZTVSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE
> > _ZTVSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE
> > _ZTVSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE
> > _ZTVSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE
> > _ZTVSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE
> > _ZTVSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE
> > _ZTVSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE
> >
> > Are any objects of those classes ever created inside of libstdc++.so.6
> > or just in user code and passed over to libstdc++ routines?
>
> Created inside libstdc++.
Unfortunately, as I figured out today, versioning everything that
(transitively) references those virtual tables is almost impossible.
With a script and -ffunction-section -fdata-section compiled libstdc++.a
I was tracing the the relocation dependence graphs and it would mean
versioning half of libstdc++.so.
So, I believe we need to just use different vtable slot for the long double
methods on the architectures that are switching, have a dummy method
(that has a double argument rather than long double) in the place where
we used to have long double method before and add a new long double method
to the end of vtable. Then via asm magic (not working yet, but works in
glibc, so I think I must get it working), we'll have two different symbols
at the same address, e.g.
_ZTVSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE@GLIBCXX_3.4
with size 48 and
_ZTVSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_LDBL_3.4
with size 56.
Unfortunately this means uglification of the installed headers, but I don't
see how else to avoid that.
--- libstdc++-v3/src/locale-inst.cc 2006-01-27 16:40:01.000000000 +0100
+++ libstdc++-v3/src/locale-inst.cc 2006-01-30 19:22:07.000000000 +0100
@@ -38,6 +38,7 @@
#ifndef C
# define C char
# define Cc "c"
+# define Cs c
#endif
namespace std
@@ -49,6 +50,30 @@
template struct __moneypunct_cache<C, true>;
template class moneypunct_byname<C, false>;
template class moneypunct_byname<C, true>;
+#ifdef _GLIBCXX_LONG_DOUBLE_COMPAT
+ 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, double& __units) const
+ {
+ string __str;
+ if (__intl)
+ __beg = _M_extract<true>(__beg, __end, __io, __err, __str);
+ else
+ __beg = _M_extract<false>(__beg, __end, __io, __err, __str);
+ std::__convert_to_v(__str.c_str(), __units, __err, _S_get_c_locale());
+ return __beg;
+ }
+ template<typename _CharT, typename _OutIter>
+ _OutIter
+ money_put<_CharT, _OutIter>::
+ __do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
+ double __units) const
+ {
+ return this->do_put(__s, __intl, __io, __fill, (long double) __units);
+ }
+#endif
template class money_get<C, istreambuf_iterator<C> >;
template class money_put<C, ostreambuf_iterator<C> >;
template
@@ -79,6 +104,26 @@
template class numpunct<C>;
template struct __numpunct_cache<C>;
template class numpunct_byname<C>;
+#ifdef _GLIBCXX_LONG_DOUBLE_COMPAT
+ 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, double& __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());
+ return __beg;
+ }
+
+ template<typename _CharT, typename _OutIter>
+ _OutIter
+ num_put<_CharT, _OutIter>::
+ __do_put(iter_type __s, ios_base& __io, char_type __fill, double __v) const
+ { return _M_insert_float(__s, __io, __fill, char(), __v); }
+#endif
template class num_get<C, istreambuf_iterator<C> >;
template class num_put<C, ostreambuf_iterator<C> >;
template
@@ -322,6 +367,36 @@
#define _GLIBCXX_LDBLS_SYMVER(dbl, ldbl) \
asm (".symver " dbl "," ldbl "@GLIBCXX_3.4"); \
asm (".symver " ldbl "," ldbl "@@GLIBCXX_LDBL_3.4")
+#define _GLIBCXX_LDBL_SYM_1(ldbl) \
+ extern "C" void \
+ _Y##ldbl() \
+ __attribute__ ((alias(#ldbl))); \
+ asm (".symver " "_Y" #ldbl "," #ldbl "@@GLIBCXX_LDBL_3.4")
+#define _GLIBCXX_LDBL_SYM(ldbl) _GLIBCXX_LDBL_SYM_1 (ldbl)
+#define _GLIBCXX_LDBL_SYM4(part1, part2, part3, part4) \
+ _GLIBCXX_LDBL_SYM (part1 ## Cs ## part2 ## Cs ## part3 \
+ ## Cs ## part4)
+#define _GLIBCXX_LDBL_SYM5(part1, part2, part3, part4, part5) \
+ _GLIBCXX_LDBL_SYM (part1 ## Cs ## part2 ## Cs ## part3 \
+ ## Cs ## part4 ## Cs ## part5)
+#if __LONG_MAX__ == 2147483647L
+#define _GLIBCXX_LDBL_VTABLE(ldbl, size32, size64) \
+ asm (".globl _V" ldbl); \
+ asm (".set _V" ldbl ", " ldbl); \
+ asm (".size _V" ldbl ", " #size32); \
+ asm (".symver _V" ldbl ", " ldbl "@GLIBCXX_3.4"); \
+ asm (".symver " ldbl ", " ldbl "@@GLIBCXX_LDBL_3.4"); \
+ asm (".type " ldbl ", @object")
+#else
+#define _GLIBCXX_LDBL_VTABLE(ldbl, size32, size64) \
+ asm (".globl _V" ldbl); \
+ asm (".set _V" ldbl ", " ldbl); \
+ asm (".size _V" ldbl ", " #size64); \
+ asm (".symver _V" ldbl ", " ldbl "@GLIBCXX_3.4"); \
+ asm (".symver " ldbl ", " ldbl "@@GLIBCXX_LDBL_3.4"); \
+ asm (".type " ldbl ", @object")
+#endif
+
_GLIBCXX_LDBLS_SYMVER ("_ZNKSt7num_getI"Cc"St19istreambuf_iteratorI"Cc"St11char_traitsI"Cc"EEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRd",
"_ZNKSt7num_getI"Cc"St19istreambuf_iteratorI"Cc"St11char_traitsI"Cc"EEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRe");
_GLIBCXX_LDBLS_SYMVER ("_ZNKSt7num_getI"Cc"St19istreambuf_iteratorI"Cc"St11char_traitsI"Cc"EEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRd",
@@ -333,17 +408,22 @@
_GLIBCXX_LDBLS_SYMVER ("_ZNKSt7num_putI"Cc"St19ostreambuf_iteratorI"Cc"St11char_traitsI"Cc"EEE6do_putES3_RSt8ios_base"Cc"d",
"_ZNKSt7num_putI"Cc"St19ostreambuf_iteratorI"Cc"St11char_traitsI"Cc"EEE6do_putES3_RSt8ios_base"Cc"e");
-// FIXME: The following 4 can't be done this way, as there are no money_get/money_put members with
-// double arguments, only long double. So we need something like a wrapper function (or method?)
-// that just calls the long double method (though through an non-exported alias) and
-// afterwards converts the long double temporary to the double reference (money_get) resp.
-// before the call converts the long double argument to double.
-_GLIBCXX_LDBLS_SYMVER ("_ZNKSt9money_getI"Cc"St19istreambuf_iteratorI"Cc"St11char_traitsI"Cc"EEE3getES3_S3_bRSt8ios_baseRSt12_Ios_IostateRd",
+_GLIBCXX_LDBLS_SYMVER ("_ZNKSt9money_getI"Cc"St19istreambuf_iteratorI"Cc"St11char_traitsI"Cc"EEE5__getES3_S3_bRSt8ios_baseRSt12_Ios_IostateRd",
"_ZNKSt9money_getI"Cc"St19istreambuf_iteratorI"Cc"St11char_traitsI"Cc"EEE3getES3_S3_bRSt8ios_baseRSt12_Ios_IostateRe");
-_GLIBCXX_LDBLS_SYMVER ("_ZNKSt9money_getI"Cc"St19istreambuf_iteratorI"Cc"St11char_traitsI"Cc"EEE6do_getES3_S3_bRSt8ios_baseRSt12_Ios_IostateRd",
+_GLIBCXX_LDBLS_SYMVER ("_ZNKSt9money_getI"Cc"St19istreambuf_iteratorI"Cc"St11char_traitsI"Cc"EEE8__do_getES3_S3_bRSt8ios_baseRSt12_Ios_IostateRd",
"_ZNKSt9money_getI"Cc"St19istreambuf_iteratorI"Cc"St11char_traitsI"Cc"EEE6do_getES3_S3_bRSt8ios_baseRSt12_Ios_IostateRe");
-_GLIBCXX_LDBLS_SYMVER ("_ZNKSt9money_putI"Cc"St19ostreambuf_iteratorI"Cc"St11char_traitsI"Cc"EEE3putES3_bRSt8ios_base"Cc"d",
+_GLIBCXX_LDBLS_SYMVER ("_ZNKSt9money_putI"Cc"St19ostreambuf_iteratorI"Cc"St11char_traitsI"Cc"EEE5__putES3_bRSt8ios_base"Cc"d",
"_ZNKSt9money_putI"Cc"St19ostreambuf_iteratorI"Cc"St11char_traitsI"Cc"EEE3putES3_bRSt8ios_base"Cc"e");
-_GLIBCXX_LDBLS_SYMVER ("_ZNKSt9money_putI"Cc"St19ostreambuf_iteratorI"Cc"St11char_traitsI"Cc"EEE6do_putES3_bRSt8ios_base"Cc"d",
+_GLIBCXX_LDBLS_SYMVER ("_ZNKSt9money_putI"Cc"St19ostreambuf_iteratorI"Cc"St11char_traitsI"Cc"EEE8__do_putES3_bRSt8ios_base"Cc"d",
"_ZNKSt9money_putI"Cc"St19ostreambuf_iteratorI"Cc"St11char_traitsI"Cc"EEE6do_putES3_bRSt8ios_base"Cc"e");
+#if 0
+_GLIBCXX_LDBL_SYM4 (_ZNKSt9money_getI, St19istreambuf_iteratorI, St11char_traitsI, EEE5__getES3_S3_bRSt8ios_baseRSt12_Ios_IostateRd);
+_GLIBCXX_LDBL_SYM4 (_ZNKSt9money_getI, St19istreambuf_iteratorI, St11char_traitsI, EEE8__do_getES3_S3_bRSt8ios_baseRSt12_Ios_IostateRd);
+_GLIBCXX_LDBL_SYM5 (_ZNKSt9money_putI, St19ostreambuf_iteratorI, St11char_traitsI, EEE5__putES3_bRSt8ios_base, d);
+_GLIBCXX_LDBL_SYM5 (_ZNKSt9money_putI, St19ostreambuf_iteratorI, St11char_traitsI, EEE8__do_putES3_bRSt8ios_base, d);
+#endif
+_GLIBCXX_LDBL_VTABLE ("_ZTVSt7num_getI"Cc"St19istreambuf_iteratorI"Cc"St11char_traitsI"Cc"EEE", 60, 120);
+_GLIBCXX_LDBL_VTABLE ("_ZTVSt7num_putI"Cc"St19ostreambuf_iteratorI"Cc"St11char_traitsI"Cc"EEE", 48, 96);
+_GLIBCXX_LDBL_VTABLE ("_ZTVSt9money_getI"Cc"St19istreambuf_iteratorI"Cc"St11char_traitsI"Cc"EEE", 24, 48);
+_GLIBCXX_LDBL_VTABLE ("_ZTVSt9money_putI"Cc"St19ostreambuf_iteratorI"Cc"St11char_traitsI"Cc"EEE", 24, 48);
#endif // _GLIBCXX_LONG_DOUBLE_COMPAT
--- libstdc++-v3/src/wlocale-inst.cc 2006-01-27 15:57:05.000000000 +0100
+++ libstdc++-v3/src/wlocale-inst.cc 2006-01-30 19:24:28.000000000 +0100
@@ -37,4 +37,5 @@
#define C wchar_t
#define Cc "w"
+#define Cs w
#include "locale-inst.cc"
#endif
--- libstdc++-v3/include/bits/locale_facets.h.jj 2006-01-07 18:34:01.000000000 +0100
+++ libstdc++-v3/include/bits/locale_facets.h 2006-01-30 18:27:55.000000000 +0100
@@ -2111,6 +2111,14 @@ namespace std
ios_base::iostate& __err, void*& __v) const
{ return this->do_get(__in, __end, __io, __err, __v); }
+#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
+ private:
+ iter_type
+ __get(iter_type __in, iter_type __end, ios_base& __io,
+ ios_base::iostate& __err, double& __v) const
+ { return this->__do_get(__in, __end, __io, __err, __v); }
+#endif
+
protected:
/// Destructor.
virtual ~num_get() { }
@@ -2176,13 +2184,25 @@ namespace std
do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
double&) const;
+#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
+ virtual iter_type
+ __do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
+ double&) const;
+#else
virtual iter_type
do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
long double&) const;
+#endif
virtual iter_type
do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
void*&) const;
+
+#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
+ virtual iter_type
+ do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
+ long double&) const;
+#endif
//@}
};
@@ -2375,6 +2395,13 @@ namespace std
const void* __v) const
{ return this->do_put(__s, __f, __fill, __v); }
+#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
+ private:
+ iter_type
+ __put(iter_type __s, ios_base& __f, char_type __fill, double __v) const
+ { return this->__do_put(__s, __f, __fill, __v); }
+#endif
+
protected:
template<typename _ValueT>
iter_type
@@ -2438,11 +2465,21 @@ namespace std
virtual iter_type
do_put(iter_type, ios_base&, char_type __fill, double __v) const;
+#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
+ virtual iter_type
+ __do_put(iter_type, ios_base&, char_type __fill, double __v) const;
+#else
virtual iter_type
do_put(iter_type, ios_base&, char_type __fill, long double __v) const;
+#endif
virtual iter_type
do_put(iter_type, ios_base&, char_type __fill, const void* __v) const;
+
+#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
+ virtual iter_type
+ do_put(iter_type, ios_base&, char_type __fill, long double __v) const;
+#endif
//@}
};
@@ -4052,6 +4089,14 @@ namespace std
ios_base::iostate& __err, string_type& __digits) const
{ return this->do_get(__s, __end, __intl, __io, __err, __digits); }
+#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
+ private:
+ iter_type
+ __get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
+ ios_base::iostate& __err, double& __units) const
+ { return this->__do_get(__s, __end, __intl, __io, __err, __units); }
+#endif
+
protected:
/// Destructor.
virtual
@@ -4064,9 +4109,15 @@ namespace std
* value. This function is a hook for derived classes to change the
* value returned. @see get() for details.
*/
+#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
+ virtual iter_type
+ __do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
+ ios_base::iostate& __err, double& __units) const;
+#else
virtual iter_type
do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
ios_base::iostate& __err, long double& __units) const;
+#endif
/**
* @brief Read and parse a monetary value.
@@ -4079,6 +4130,12 @@ namespace std
do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
ios_base::iostate& __err, string_type& __digits) const;
+#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
+ virtual iter_type
+ do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
+ ios_base::iostate& __err, long double& __units) const;
+#endif
+
template<bool _Intl>
iter_type
_M_extract(iter_type __s, iter_type __end, ios_base& __io,
@@ -4168,6 +4225,14 @@ namespace std
char_type __fill, const string_type& __digits) const
{ return this->do_put(__s, __intl, __io, __fill, __digits); }
+#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
+ private:
+ iter_type
+ __put(iter_type __s, bool __intl, ios_base& __io,
+ char_type __fill, double __units) const
+ { return this->__do_put(__s, __intl, __io, __fill, __units); }
+#endif
+
protected:
/// Destructor.
virtual
@@ -4191,9 +4256,15 @@ namespace std
* @param units Place to store result of parsing.
* @return Iterator after writing.
*/
+#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
+ virtual iter_type
+ __do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
+ double __units) const;
+#else
virtual iter_type
do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
long double __units) const;
+#endif
/**
* @brief Format and output a monetary value.
@@ -4217,6 +4288,12 @@ namespace std
do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
const string_type& __digits) const;
+#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
+ virtual iter_type
+ do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
+ long double __units) const;
+#endif
+
template<bool _Intl>
iter_type
_M_insert(iter_type __s, ios_base& __io, char_type __fill,
Jakub
- References:
- [RFC PATCH] Optionally use -mlong-double-128 by default on {powerpc{,64},s390{,x},sparc,alpha}-linux
- Re: [RFC PATCH] Optionally use -mlong-double-128 by default on {powerpc{,64},s390{,x},sparc,alpha}-linux