# DP: Proposed patch for PR libstdc++/39491. 2009-04-16 Benjamin Kosnik * src/math_stubs_long_double.cc (__signbitl): Add for hppa linux only. Index: a/src/libstdc++-v3/src/math_stubs_long_double.cc =================================================================== --- a/src/libstdc++-v3/src/math_stubs_long_double.cc (revision 146216) +++ b/src/libstdc++-v3/src/math_stubs_long_double.cc (working copy) @@ -213,4 +221,111 @@ return tanh((double) x); } #endif + + // From libmath/signbitl.c + // XXX ABI mistakenly exported +#if defined (__hppa__) && defined (__linux__) +# include +# include + +typedef unsigned int U_int32_t __attribute ((mode (SI))); +typedef int Int32_t __attribute ((mode (SI))); +typedef unsigned int U_int64_t __attribute ((mode (DI))); +typedef int Int64_t __attribute ((mode (DI))); + +#if BYTE_ORDER == BIG_ENDIAN +typedef union +{ + long double value; + struct + { + unsigned int sign_exponent:16; + unsigned int empty:16; + U_int32_t msw; + U_int32_t lsw; + } parts; +} ieee_long_double_shape_type; +#endif +#if BYTE_ORDER == LITTLE_ENDIAN +typedef union +{ + long double value; + struct + { + U_int32_t lsw; + U_int32_t msw; + unsigned int sign_exponent:16; + unsigned int empty:16; + } parts; +} ieee_long_double_shape_type; +#endif + +/* Get int from the exponent of a long double. */ +#define GET_LDOUBLE_EXP(exp,d) \ +do { \ + ieee_long_double_shape_type ge_u; \ + ge_u.value = (d); \ + (exp) = ge_u.parts.sign_exponent; \ +} while (0) + +#if BYTE_ORDER == BIG_ENDIAN +typedef union +{ + long double value; + struct + { + U_int64_t msw; + U_int64_t lsw; + } parts64; + struct + { + U_int32_t w0, w1, w2, w3; + } parts32; +} ieee_quad_double_shape_type; +#endif + +#if BYTE_ORDER == LITTLE_ENDIAN +typedef union +{ + long double value; + struct + { + U_int64_t lsw; + U_int64_t msw; + } parts64; + struct + { + U_int32_t w3, w2, w1, w0; + } parts32; +} ieee_quad_double_shape_type; +#endif + +/* Get most significant 64 bit int from a quad long double. */ +#define GET_LDOUBLE_MSW64(msw,d) \ +do { \ + ieee_quad_double_shape_type qw_u; \ + qw_u.value = (d); \ + (msw) = qw_u.parts64.msw; \ +} while (0) + +int +__signbitl (long double x) +{ +#if LDBL_MANT_DIG == 113 + Int64_t msw; + + GET_LDOUBLE_MSW64 (msw, x); + return msw < 0; +#else + Int32_t e; + + GET_LDOUBLE_EXP (e, x); + return e & 0x8000; +#endif +} +#endif + +#ifndef _GLIBCXX_HAVE___SIGNBITL + +#endif } // extern "C" --- a/src/libstdc++-v3/config/abi/pre/gnu.ver~ 2009-04-10 01:23:07.000000000 +0200 +++ b/src/libstdc++-v3/config/abi/pre/gnu.ver 2009-04-21 16:24:24.000000000 +0200 @@ -635,6 +635,7 @@ sqrtf; sqrtl; copysignf; + __signbitl; # GLIBCXX_ABI compatibility only. # std::string