This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ 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]

Re: [RFC PATCH] Optionally use -mlong-double-128 by default on {powerpc{,64},s390{,x},sparc,alpha}-linux


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


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