From 0ecb606cb6cf65de1d9fc8a919bceb4be476c602 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 12 Jul 2007 18:26:36 +0000 Subject: 2.5-18.1 --- sysdeps/powerpc/fpu/Dist | 4 - sysdeps/powerpc/fpu/bits/fenvinline.h | 8 +- sysdeps/powerpc/fpu/bits/mathdef.h | 69 ----- sysdeps/powerpc/fpu/bits/mathinline.h | 20 +- sysdeps/powerpc/fpu/e_sqrt.c | 5 +- sysdeps/powerpc/fpu/e_sqrtf.c | 5 +- sysdeps/powerpc/fpu/fegetround.c | 4 +- sysdeps/powerpc/fpu/feholdexcpt.c | 3 +- sysdeps/powerpc/fpu/fenv_libc.h | 37 ++- sysdeps/powerpc/fpu/fesetround.c | 19 +- sysdeps/powerpc/fpu/libm-test-ulps | 549 +++++++++++++++++++++++++++++++--- sysdeps/powerpc/fpu/math_ldbl.h | 189 ++++++++++++ sysdeps/powerpc/fpu/s_fabs.S | 8 +- sysdeps/powerpc/fpu/s_fmax.S | 8 +- sysdeps/powerpc/fpu/s_fmin.S | 8 +- sysdeps/powerpc/fpu/s_isnan.c | 3 +- sysdeps/powerpc/fpu/w_sqrtf.c | 1 - 17 files changed, 777 insertions(+), 163 deletions(-) delete mode 100644 sysdeps/powerpc/fpu/Dist delete mode 100644 sysdeps/powerpc/fpu/bits/mathdef.h create mode 100644 sysdeps/powerpc/fpu/math_ldbl.h (limited to 'sysdeps/powerpc/fpu') diff --git a/sysdeps/powerpc/fpu/Dist b/sysdeps/powerpc/fpu/Dist deleted file mode 100644 index 948b04a2b3..0000000000 --- a/sysdeps/powerpc/fpu/Dist +++ /dev/null @@ -1,4 +0,0 @@ -fe_nomask.c -fenv_const.c -fenv_libc.h -t_sqrt.c diff --git a/sysdeps/powerpc/fpu/bits/fenvinline.h b/sysdeps/powerpc/fpu/bits/fenvinline.h index 552c8c9db7..f7700a49e7 100644 --- a/sysdeps/powerpc/fpu/bits/fenvinline.h +++ b/sysdeps/powerpc/fpu/bits/fenvinline.h @@ -1,5 +1,6 @@ /* Inline floating-point environment handling functions for powerpc. - Copyright (C) 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 1997, 1998, 1999, 2006 + Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -22,8 +23,9 @@ /* Inline definition for fegetround. */ # define fegetround() \ (__extension__ ({ int __fegetround_result; \ - __asm__ ("mcrfs 7,7 ; mfcr %0" \ - : "=r"(__fegetround_result) : : "cr7"); \ + __asm__ __volatile__ \ + ("mcrfs 7,7 ; mfcr %0" \ + : "=r"(__fegetround_result) : : "cr7"); \ __fegetround_result & 3; })) /* The weird 'i#*X' constraints on the following suppress a gcc diff --git a/sysdeps/powerpc/fpu/bits/mathdef.h b/sysdeps/powerpc/fpu/bits/mathdef.h deleted file mode 100644 index 3a9d538ee4..0000000000 --- a/sysdeps/powerpc/fpu/bits/mathdef.h +++ /dev/null @@ -1,69 +0,0 @@ -/* Copyright (C) 1997,1998,1999,2000,2003,2004 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#if !defined _MATH_H && !defined _COMPLEX_H -# error "Never use directly; include instead" -#endif - - -/* FIXME! This file describes properties of the compiler, not the machine; - it should not be part of libc! - - FIXME! This file does not deal with the -fshort-double option of - gcc! */ - -#if defined __USE_ISOC99 && defined _MATH_H && !defined _MATH_H_MATHDEF -# define _MATH_H_MATHDEF 1 - -# ifdef __GNUC__ -# if __STDC__ == 1 - -/* In GNU or ANSI mode, gcc leaves `float' expressions as-is. */ -typedef float float_t; /* `float' expressions are evaluated as - `float'. */ -typedef double double_t; /* `double' expressions are evaluated as - `double'. */ - -# else - -/* For `gcc -traditional', `float' expressions are evaluated as `double'. */ -typedef double float_t; /* `float' expressions are evaluated as - `double'. */ -typedef double double_t; /* `double' expressions are evaluated as - `double'. */ - -# endif -# else - -/* Wild guess at types for float_t and double_t. */ -typedef double float_t; -typedef double double_t; - -# endif - -/* The values returned by `ilogb' for 0 and NaN respectively. */ -# define FP_ILOGB0 (-2147483647) -# define FP_ILOGBNAN (2147483647) - -#endif /* ISO C99 */ - -#ifndef __NO_LONG_DOUBLE_MATH -/* Signal that we do not really have a `long double'. The disables the - declaration of all the `long double' function variants. */ -# define __NO_LONG_DOUBLE_MATH 1 -#endif diff --git a/sysdeps/powerpc/fpu/bits/mathinline.h b/sysdeps/powerpc/fpu/bits/mathinline.h index 44f7dbec52..aed899e882 100644 --- a/sysdeps/powerpc/fpu/bits/mathinline.h +++ b/sysdeps/powerpc/fpu/bits/mathinline.h @@ -1,5 +1,5 @@ /* Inline math functions for powerpc. - Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2004 + Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2004, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -123,20 +123,26 @@ __NTH (fdimf (float __x, float __y)) #endif /* !__NO_MATH_INLINES && __OPTIMIZE__ */ /* This code is used internally in the GNU libc. */ -# ifdef __LIBC_INTERNAL_MATH_INLINES +#ifdef __LIBC_INTERNAL_MATH_INLINES #include #include #include +# if __WORDSIZE == 64 || defined _ARCH_PWR4 +# define __CPU_HAS_FSQRT 1 +# else +# define __CPU_HAS_FSQRT ((GLRO(dl_hwcap) & PPC_FEATURE_64) != 0) +# endif + extern double __slow_ieee754_sqrt (double); __MATH_INLINE double __NTH (__ieee754_sqrt (double __x)) { double __z; - /* If the CPU is 64-bit we can use the optional FP instructions we. */ - if ((GLRO(dl_hwcap) & PPC_FEATURE_64) != 0) + /* If the CPU is 64-bit we can use the optional FP instructions. */ + if (__CPU_HAS_FSQRT) { /* Volatile is required to prevent the compiler from moving the fsqrt instruction above the branch. */ @@ -157,8 +163,8 @@ __NTH (__ieee754_sqrtf (float __x)) { float __z; - /* If the CPU is 64-bit we can use the optional FP instructions we. */ - if ((GLRO(dl_hwcap) & PPC_FEATURE_64) != 0) + /* If the CPU is 64-bit we can use the optional FP instructions. */ + if (__CPU_HAS_FSQRT) { /* Volatile is required to prevent the compiler from moving the fsqrts instruction above the branch. */ @@ -172,5 +178,5 @@ __NTH (__ieee754_sqrtf (float __x)) return __z; } -# endif /* __LIBC_INTERNAL_MATH_INLINES */ +#endif /* __LIBC_INTERNAL_MATH_INLINES */ #endif /* __GNUC__ && !_SOFT_FLOAT */ diff --git a/sysdeps/powerpc/fpu/e_sqrt.c b/sysdeps/powerpc/fpu/e_sqrt.c index eb9984d0a1..540b924656 100644 --- a/sysdeps/powerpc/fpu/e_sqrt.c +++ b/sysdeps/powerpc/fpu/e_sqrt.c @@ -24,7 +24,6 @@ #include #include -#include static const double almost_half = 0.5000000000000001; /* 0.5 + 2^-53 */ static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; @@ -170,8 +169,8 @@ __ieee754_sqrt (x) { double z; - /* If the CPU is 64-bit we can use the optional FP instructions we. */ - if ((GLRO (dl_hwcap) & PPC_FEATURE_64) != 0) + /* If the CPU is 64-bit we can use the optional FP instructions. */ + if (__CPU_HAS_FSQRT) { /* Volatile is required to prevent the compiler from moving the fsqrt instruction above the branch. */ diff --git a/sysdeps/powerpc/fpu/e_sqrtf.c b/sysdeps/powerpc/fpu/e_sqrtf.c index 9b701012af..b63d31472b 100644 --- a/sysdeps/powerpc/fpu/e_sqrtf.c +++ b/sysdeps/powerpc/fpu/e_sqrtf.c @@ -24,7 +24,6 @@ #include #include -#include static const float almost_half = 0.50000006; /* 0.5 + 2^-24 */ static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; @@ -147,8 +146,8 @@ __ieee754_sqrtf (x) { double z; - /* If the CPU is 64-bit we can use the optional FP instructions we. */ - if ((GLRO (dl_hwcap) & PPC_FEATURE_64) != 0) + /* If the CPU is 64-bit we can use the optional FP instructions. */ + if (__CPU_HAS_FSQRT) { /* Volatile is required to prevent the compiler from moving the fsqrt instruction above the branch. */ diff --git a/sysdeps/powerpc/fpu/fegetround.c b/sysdeps/powerpc/fpu/fegetround.c index ae521fdf10..93663ad546 100644 --- a/sysdeps/powerpc/fpu/fegetround.c +++ b/sysdeps/powerpc/fpu/fegetround.c @@ -23,7 +23,5 @@ int fegetround (void) { - int result; - asm ("mcrfs 7,7 ; mfcr %0" : "=r"(result) : : "cr7"); \ - return result & 3; + return __fegetround(); } diff --git a/sysdeps/powerpc/fpu/feholdexcpt.c b/sysdeps/powerpc/fpu/feholdexcpt.c index 8ac875cc72..150becd678 100644 --- a/sysdeps/powerpc/fpu/feholdexcpt.c +++ b/sysdeps/powerpc/fpu/feholdexcpt.c @@ -1,5 +1,5 @@ /* Store current floating-point environment and clear exceptions. - Copyright (C) 1997 Free Software Foundation, Inc. + Copyright (C) 1997, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -36,3 +36,4 @@ feholdexcept (fenv_t *envp) return 0; } +libm_hidden_def (feholdexcept) diff --git a/sysdeps/powerpc/fpu/fenv_libc.h b/sysdeps/powerpc/fpu/fenv_libc.h index 7ae12a7d2b..fd5fc0c767 100644 --- a/sysdeps/powerpc/fpu/fenv_libc.h +++ b/sysdeps/powerpc/fpu/fenv_libc.h @@ -1,5 +1,5 @@ /* Internal libc stuff for floating point environment routines. - Copyright (C) 1997 Free Software Foundation, Inc. + Copyright (C) 1997, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -54,6 +54,41 @@ typedef union unsigned int l[2]; } fenv_union_t; + +static inline int +__fegetround (void) +{ + int result; + asm volatile ("mcrfs 7,7\n\t" + "mfcr %0" : "=r"(result) : : "cr7"); + return result & 3; +} +#define fegetround() __fegetround() + +static inline int +__fesetround (int round) +{ + if ((unsigned int) round < 2) + { + asm volatile ("mtfsb0 30"); + if ((unsigned int) round == 0) + asm volatile ("mtfsb0 31"); + else + asm volatile ("mtfsb1 31"); + } + else + { + asm volatile ("mtfsb1 30"); + if ((unsigned int) round == 2) + asm volatile ("mtfsb0 31"); + else + asm volatile ("mtfsb1 31"); + } + + return 0; +} +#define fesetround(mode) __fesetround(mode) + /* Definitions of all the FPSCR bit numbers */ enum { FPSCR_FX = 0, /* exception summary */ diff --git a/sysdeps/powerpc/fpu/fesetround.c b/sysdeps/powerpc/fpu/fesetround.c index f7cd6af135..a7efa3bbb0 100644 --- a/sysdeps/powerpc/fpu/fesetround.c +++ b/sysdeps/powerpc/fpu/fesetround.c @@ -1,5 +1,5 @@ /* Set current rounding direction. - Copyright (C) 1997 Free Software Foundation, Inc. + Copyright (C) 1997, 2005, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1997. @@ -20,22 +20,13 @@ #include +#undef fesetround int fesetround (int round) { - fenv_union_t u; - if ((unsigned int) round > 3) return 1; - - /* Get the current state. */ - u.fenv = fegetenv_register (); - - /* Set the relevant bits. */ - u.l[1] = (u.l[1] & ~3) | (round & 3); - - /* Put the new state in effect. */ - fesetenv_register (u.fenv); - - return 0; + else + return __fesetround(round); } +libm_hidden_def (fesetround) diff --git a/sysdeps/powerpc/fpu/libm-test-ulps b/sysdeps/powerpc/fpu/libm-test-ulps index 6dd3940d22..8516e915e7 100644 --- a/sysdeps/powerpc/fpu/libm-test-ulps +++ b/sysdeps/powerpc/fpu/libm-test-ulps @@ -1,37 +1,57 @@ # Begin of automatic generation +# acos +Test "acos (2e-17) == 1.57079632679489659923132169163975144": +ildouble: 1 +ldouble: 1 + +# asin +Test "asin (0.75) == 0.848062078981481008052944338998418080": +ildouble: 2 +ldouble: 2 + # atan2 +Test "atan2 (-0.00756827042671106339, -.001792735857538728036) == -1.80338464113663849327153994379639112": +ildouble: 1 +ldouble: 1 Test "atan2 (-0.75, -1.0) == -2.49809154479650885165983415456218025": -float: 3 -ifloat: 3 +float: 1 +ifloat: 1 Test "atan2 (0.75, -1.0) == 2.49809154479650885165983415456218025": -float: 3 -ifloat: 3 +float: 1 +ifloat: 1 Test "atan2 (1.390625, 0.9296875) == 0.981498387184244311516296577615519772": float: 1 ifloat: 1 -Test "atan2 (-0.00756827042671106339, -.001792735857538728036) == -1.80338464113663849327153994379639112": -float: 6 -ifloat: 6 +ildouble: 1 +ldouble: 1 # atanh Test "atanh (0.75) == 0.972955074527656652552676371721589865": float: 1 ifloat: 1 +# cabs +Test "cabs (0.75 + 1.25 i) == 1.45773797371132511771853821938639577": +ildouble: 1 +ldouble: 1 + # cacosh -Test "Real part of: cacosh (-2 - 3 i) == -1.9833870299165354323470769028940395 + 2.1414491111159960199416055713254211 i": +Test "Real part of: cacosh (-2 - 3 i) == 1.9833870299165354323470769028940395 - 2.1414491111159960199416055713254211 i": double: 1 float: 7 idouble: 1 ifloat: 7 -Test "Imaginary part of: cacosh (-2 - 3 i) == -1.9833870299165354323470769028940395 + 2.1414491111159960199416055713254211 i": +Test "Imaginary part of: cacosh (-2 - 3 i) == 1.9833870299165354323470769028940395 - 2.1414491111159960199416055713254211 i": double: 1 float: 3 idouble: 1 ifloat: 3 # casin +Test "Real part of: casin (-2 - 3 i) == -0.57065278432109940071028387968566963 - 1.9833870299165354323470769028940395 i": +ildouble: 1 +ldouble: 1 Test "Real part of: casin (0.75 + 1.25 i) == 0.453276177638793913448921196101971749 + 1.13239363160530819522266333696834467 i": double: 1 float: 1 @@ -44,11 +64,15 @@ double: 5 float: 1 idouble: 5 ifloat: 1 +ildouble: 4 +ldouble: 4 Test "Imaginary part of: casinh (-2 - 3 i) == -1.9686379257930962917886650952454982 - 0.96465850440760279204541105949953237 i": double: 3 float: 6 idouble: 3 ifloat: 6 +ildouble: 1 +ldouble: 1 Test "Real part of: casinh (0.75 + 1.25 i) == 1.03171853444778027336364058631006594 + 0.911738290968487636358489564316731207 i": float: 1 ifloat: 1 @@ -62,6 +86,8 @@ ifloat: 1 Test "Real part of: catan (-2 - 3 i) == -1.4099210495965755225306193844604208 - 0.22907268296853876629588180294200276 i": float: 3 ifloat: 3 +ildouble: 1 +ldouble: 1 Test "Imaginary part of: catan (-2 - 3 i) == -1.4099210495965755225306193844604208 - 0.22907268296853876629588180294200276 i": double: 1 float: 1 @@ -118,9 +144,13 @@ double: 1 float: 1 idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Test "Imaginary part of: ccosh (0.75 + 1.25 i) == 0.408242591877968807788852146397499084 + 0.780365930845853240391326216300863152 i": float: 1 ifloat: 1 +ildouble: 2 +ldouble: 2 # cexp Test "Imaginary part of: cexp (-2.0 - 3.0 i) == -0.13398091492954261346140525546115575 - 0.019098516261135196432576240858800925 i": @@ -129,66 +159,141 @@ ifloat: 1 Test "Real part of: cexp (0.75 + 1.25 i) == 0.667537446429131586942201977015932112 + 2.00900045494094876258347228145863909 i": float: 1 ifloat: 1 +ildouble: 2 +ldouble: 2 +Test "Imaginary part of: cexp (0.75 + 1.25 i) == 0.667537446429131586942201977015932112 + 2.00900045494094876258347228145863909 i": +ildouble: 1 +ldouble: 1 # clog Test "Imaginary part of: clog (-2 - 3 i) == 1.2824746787307683680267437207826593 - 2.1587989303424641704769327722648368 i": float: 3 ifloat: 3 +ildouble: 1 +ldouble: 1 Test "Real part of: clog (0.75 + 1.25 i) == 0.376885901188190075998919126749298416 + 1.03037682652431246378774332703115153 i": float: 1 ifloat: 1 +ildouble: 2 +ldouble: 2 +Test "Imaginary part of: clog (0.75 + 1.25 i) == 0.376885901188190075998919126749298416 + 1.03037682652431246378774332703115153 i": +ildouble: 1 +ldouble: 1 # clog10 Test "Imaginary part of: clog10 (-0 + inf i) == inf + pi/2*log10(e) i": +double: 1 float: 1 +idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Test "Imaginary part of: clog10 (-0 - inf i) == inf - pi/2*log10(e) i": +double: 1 float: 1 +idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Test "Imaginary part of: clog10 (-2 - 3 i) == 0.556971676153418384603252578971164214 - 0.937554462986374708541507952140189646 i": double: 1 float: 5 idouble: 1 ifloat: 5 +ildouble: 1 +ldouble: 1 Test "Imaginary part of: clog10 (-3 + inf i) == inf + pi/2*log10(e) i": +double: 1 float: 1 +idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Test "Imaginary part of: clog10 (-3 - inf i) == inf - pi/2*log10(e) i": +double: 1 float: 1 +idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Test "Imaginary part of: clog10 (-inf + 0 i) == inf + pi*log10(e) i": +double: 1 float: 1 +idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Test "Imaginary part of: clog10 (-inf + 1 i) == inf + pi*log10(e) i": +double: 1 float: 1 +idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog10 (-inf + inf i) == inf + 3/4 pi*log10(e) i": +double: 1 +idouble: 1 Test "Imaginary part of: clog10 (-inf - 0 i) == inf - pi*log10(e) i": +double: 1 float: 1 +idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Test "Imaginary part of: clog10 (-inf - 1 i) == inf - pi*log10(e) i": +double: 1 float: 1 +idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Test "Imaginary part of: clog10 (0 + inf i) == inf + pi/2*log10(e) i": +double: 1 float: 1 +idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Test "Imaginary part of: clog10 (0 - inf i) == inf - pi/2*log10(e) i": +double: 1 float: 1 +idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Test "Real part of: clog10 (0.75 + 1.25 i) == 0.163679467193165171449476605077428975 + 0.447486970040493067069984724340855636 i": float: 1 ifloat: 1 +ildouble: 3 +ldouble: 3 Test "Imaginary part of: clog10 (3 + inf i) == inf + pi/2*log10(e) i": +double: 1 float: 1 +idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Test "Imaginary part of: clog10 (3 - inf i) == inf - pi/2*log10(e) i": +double: 1 float: 1 +idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Test "Imaginary part of: clog10 (inf + inf i) == inf + pi/4*log10(e) i": +double: 1 float: 1 +idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Test "Imaginary part of: clog10 (inf - inf i) == inf - pi/4*log10(e) i": +double: 1 float: 1 +idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 # cos Test "cos (M_PI_6l * 2.0) == 0.5": @@ -206,48 +311,71 @@ double: 1 float: 1 idouble: 1 ifloat: 1 +Test "cos (16.0) == -0.9576594803233846418996372326511034717803" +ildouble: 2 +ldouble: 2 # cpow Test "Real part of: cpow (0.75 + 1.25 i, 0.0 + 1.0 i) == 0.331825439177608832276067945276730566 + 0.131338600281188544930936345230903032 i": float: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Test "Imaginary part of: cpow (0.75 + 1.25 i, 0.0 + 1.0 i) == 0.331825439177608832276067945276730566 + 0.131338600281188544930936345230903032 i": float: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Test "Real part of: cpow (0.75 + 1.25 i, 0.75 + 1.25 i) == 0.117506293914473555420279832210420483 + 0.346552747708338676483025352060418001 i": double: 1 float: 4 idouble: 1 ifloat: 4 +Test "Real part of: cpow (0.75 + 1.25 i, 1.0 + 0.0 i) == 0.75 + 1.25 i": +ildouble: 2 +ldouble: 2 Test "Real part of: cpow (0.75 + 1.25 i, 1.0 + 1.0 i) == 0.0846958290317209430433805274189191353 + 0.513285749182902449043287190519090481 i": double: 2 float: 3 idouble: 2 ifloat: 3 +Test "Real part of: cpow (2 + 0 i, 10 + 0 i) == 1024.0 + 0.0 i": +ildouble: 1 +ldouble: 1 Test "Real part of: cpow (2 + 3 i, 4 + 0 i) == -119.0 - 120.0 i": double: 1 -float: 4 +float: 5 idouble: 1 -ifloat: 4 +ifloat: 5 Test "Imaginary part of: cpow (2 + 3 i, 4 + 0 i) == -119.0 - 120.0 i": float: 2 ifloat: 2 +ildouble: 2 +ldouble: 2 Test "Imaginary part of: cpow (e + 0 i, 0 + 2 * M_PIl i) == 1.0 + 0.0 i": double: 2 float: 2 idouble: 2 ifloat: 2 +ildouble: 2 +ldouble: 2 # csinh Test "Imaginary part of: csinh (-2 - 3 i) == 3.59056458998577995201256544779481679 - 0.530921086248519805267040090660676560 i": double: 1 idouble: 1 +ildouble: 1 +ldouble: 1 Test "Real part of: csinh (0.75 + 1.25 i) == 0.259294854551162779153349830618433028 + 1.22863452409509552219214606515777594 i": float: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Test "Imaginary part of: csinh (0.75 + 1.25 i) == 0.259294854551162779153349830618433028 + 1.22863452409509552219214606515777594 i": float: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 # csqrt Test "Real part of: csqrt (-2 + 3 i) == 0.89597747612983812471573375529004348 + 1.6741492280355400404480393008490519 i": @@ -261,6 +389,9 @@ ifloat: 1 Test "Real part of: ctan (-2 - 3 i) == 0.376402564150424829275122113032269084e-2 - 1.00323862735360980144635859782192726 i": double: 1 idouble: 1 +Test "Imaginary part of: ctan (-2 - 3 i) == 0.376402564150424829275122113032269084e-2 - 1.00323862735360980144635859782192726 i": +ildouble: 1 +ldouble: 1 Test "Imaginary part of: ctan (0.75 + 1.25 i) == 0.160807785916206426725166058173438663 + 0.975363285031235646193581759755216379 i": double: 1 idouble: 1 @@ -277,6 +408,8 @@ ifloat: 1 Test "Real part of: ctanh (0.75 + 1.25 i) == 1.37260757053378320258048606571226857 + 0.385795952609750664177596760720790220 i": double: 1 idouble: 1 +ildouble: 1 +ldouble: 1 # erf Test "erf (1.25) == 0.922900128256458230136523481197281140": @@ -294,29 +427,50 @@ Test "erfc (4.125) == 0.542340079956506600531223408575531062e-8": double: 1 idouble: 1 +# exp +Test "exp (0.75) == 2.11700001661267466854536981983709561": +ildouble: 1 +ldouble: 1 +Test "exp (50.0) == 5184705528587072464087.45332293348538": +ildouble: 1 +ldouble: 1 + # exp10 Test "exp10 (-1) == 0.1": double: 2 float: 1 idouble: 2 ifloat: 1 +ildouble: 1 +ldouble: 1 Test "exp10 (0.75) == 5.62341325190349080394951039776481231": double: 1 float: 1 idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Test "exp10 (3) == 1000": double: 6 float: 2 idouble: 6 ifloat: 2 +ildouble: 8 +ldouble: 8 + +# exp2 +Test "exp2 (10) == 1024": +ildouble: 2 +ldouble: 2 # expm1 Test "expm1 (0.75) == 1.11700001661267466854536981983709561": double: 1 idouble: 1 Test "expm1 (1) == M_El - 1.0": +double: 1 float: 1 +idouble: 1 ifloat: 1 # hypot @@ -338,6 +492,9 @@ ifloat: 1 Test "hypot (0.7, 12.4) == 12.419742348374220601176836866763271": float: 1 ifloat: 1 +Test "hypot (0.75, 1.25) == 1.45773797371132511771853821938639577": +ildouble: 1 +ldouble: 1 Test "hypot (12.4, -0.7) == 12.419742348374220601176836866763271": float: 1 ifloat: 1 @@ -348,78 +505,121 @@ ifloat: 1 # j0 Test "j0 (-4.0) == -3.9714980986384737228659076845169804197562E-1": double: 1 -float: 1 +float: 2 idouble: 1 -ifloat: 1 +ifloat: 2 +ildouble: 1 +ldouble: 1 Test "j0 (10.0) == -0.245935764451348335197760862485328754": -double: 2 +double: 3 float: 1 -idouble: 2 +idouble: 3 ifloat: 1 +ildouble: 1 +ldouble: 1 +Test "j0 (2.0) == 0.223890779141235668051827454649948626": +float: 2 +ifloat: 2 Test "j0 (4.0) == -3.9714980986384737228659076845169804197562E-1": double: 1 -float: 1 +float: 2 idouble: 1 -ifloat: 1 +ifloat: 2 +ildouble: 1 +ldouble: 1 Test "j0 (8.0) == 0.171650807137553906090869407851972001": float: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 # j1 Test "j1 (10.0) == 0.0434727461688614366697487680258592883": float: 2 ifloat: 2 +ildouble: 1 +ldouble: 1 Test "j1 (2.0) == 0.576724807756873387202448242269137087": double: 1 idouble: 1 Test "j1 (8.0) == 0.234636346853914624381276651590454612": double: 1 idouble: 1 +ildouble: 1 +ldouble: 1 # jn Test "jn (0, -4.0) == -3.9714980986384737228659076845169804197562E-1": double: 1 -float: 1 +float: 2 idouble: 1 -ifloat: 1 +ifloat: 2 +ildouble: 1 +ldouble: 1 Test "jn (0, 10.0) == -0.245935764451348335197760862485328754": -double: 2 +double: 3 float: 1 -idouble: 2 +idouble: 3 ifloat: 1 +ildouble: 1 +ldouble: 1 +Test "jn (0, 2.0) == 0.223890779141235668051827454649948626": +float: 2 +ifloat: 2 Test "jn (0, 4.0) == -3.9714980986384737228659076845169804197562E-1": double: 1 -float: 1 +float: 2 idouble: 1 -ifloat: 1 +ifloat: 2 +ildouble: 1 +ldouble: 1 Test "jn (0, 8.0) == 0.171650807137553906090869407851972001": float: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Test "jn (1, 10.0) == 0.0434727461688614366697487680258592883": float: 2 ifloat: 2 +ildouble: 1 +ldouble: 1 Test "jn (1, 2.0) == 0.576724807756873387202448242269137087": double: 1 idouble: 1 Test "jn (1, 8.0) == 0.234636346853914624381276651590454612": double: 1 idouble: 1 +ildouble: 1 +ldouble: 1 +Test "jn (10, -1.0) == 0.263061512368745320699785368779050294e-9": +ildouble: 1 +ldouble: 1 Test "jn (10, 0.125) == 0.250543369809369890173993791865771547e-18": double: 1 float: 1 idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Test "jn (10, 0.75) == 0.149621713117596814698712483621682835e-10": double: 1 float: 1 idouble: 1 ifloat: 1 +Test "jn (10, 1.0) == 0.263061512368745320699785368779050294e-9": +ildouble: 1 +ldouble: 1 Test "jn (10, 10.0) == 0.207486106633358857697278723518753428": float: 1 ifloat: 1 +ildouble: 4 +ldouble: 4 Test "jn (10, 2.0) == 0.251538628271673670963516093751820639e-6": -float: 3 -ifloat: 3 +float: 4 +ifloat: 4 +Test "jn (3, -1.0) == -0.0195633539826684059189053216217515083": +ildouble: 1 +ldouble: 1 Test "jn (3, 0.125) == 0.406503832554912875023029337653442868e-4": double: 1 float: 1 @@ -428,16 +628,23 @@ ifloat: 1 Test "jn (3, 0.75) == 0.848438342327410884392755236884386804e-2": double: 1 idouble: 1 +Test "jn (3, 1.0) == 0.0195633539826684059189053216217515083": +ildouble: 1 +ldouble: 1 Test "jn (3, 10.0) == 0.0583793793051868123429354784103409563": double: 3 -float: 1 +float: 2 idouble: 3 -ifloat: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 Test "jn (3, 2.0) == 0.128943249474402051098793332969239835": double: 1 -float: 1 +float: 2 idouble: 1 -ifloat: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 # lgamma Test "lgamma (0.7) == 0.260867246531666514385732417016759578": @@ -450,6 +657,8 @@ double: 1 float: 2 idouble: 1 ifloat: 2 +ildouble: 3 +ldouble: 3 # log10 Test "log10 (0.75) == -0.124938736608299953132449886193870744": @@ -466,6 +675,16 @@ Test "log1p (-0.25) == -0.287682072451780927439219005993827432": float: 1 ifloat: 1 +# log2 +Test "log2 (e) == M_LOG2El": +ildouble: 1 +ldouble: 1 + +# sin +Test "sin (16.0) == -0.2879033166650652947844562482186175296207" +ildouble: 2 +ldouble: 2 + # sincos Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.5 in cos_res": double: 1 @@ -486,10 +705,25 @@ Test "sincos (pi/6, &sin_res, &cos_res) puts 0.866025403784438646763723170752936 float: 1 ifloat: 1 +# sinh +Test "sinh (0.75) == 0.822316731935829980703661634446913849": +ildouble: 1 +ldouble: 1 + # tan Test "tan (pi/4) == 1": double: 1 idouble: 1 +ildouble: 1 +ldouble: 1 + +# tanh +Test "tanh (-0.75) == -0.635148952387287319214434357312496495": +ildouble: 1 +ldouble: 1 +Test "tanh (0.75) == 0.635148952387287319214434357312496495": +ildouble: 1 +ldouble: 1 # tgamma Test "tgamma (-0.5) == -2 sqrt (pi)": @@ -507,11 +741,19 @@ idouble: 1 ifloat: 1 # y0 +Test "y0 (0.125) == -1.38968062514384052915582277745018693": +ildouble: 1 +ldouble: 1 +Test "y0 (0.75) == -0.137172769385772397522814379396581855": +ildouble: 1 +ldouble: 1 Test "y0 (1.0) == 0.0882569642156769579829267660235151628": double: 2 float: 1 idouble: 2 ifloat: 1 +ildouble: 1 +ldouble: 1 Test "y0 (1.5) == 0.382448923797758843955068554978089862": double: 2 float: 1 @@ -522,6 +764,8 @@ double: 1 float: 1 idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Test "y0 (2.0) == 0.510375672649745119596606592727157873": double: 1 idouble: 1 @@ -530,30 +774,50 @@ double: 1 float: 1 idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 # y1 +Test "y1 (0.125) == -5.19993611253477499595928744876579921": +double: 1 +idouble: 1 +Test "y1 (1.5) == -0.412308626973911295952829820633445323": +float: 1 +ifloat: 1 Test "y1 (10.0) == 0.249015424206953883923283474663222803": double: 3 float: 1 idouble: 3 ifloat: 1 +ildouble: 2 +ldouble: 2 Test "y1 (2.0) == -0.107032431540937546888370772277476637": double: 1 float: 1 -idouble: 1 -ifloat: 1 +idouble: 2 +ifloat: 2 Test "y1 (8.0) == -0.158060461731247494255555266187483550": double: 1 float: 2 idouble: 1 ifloat: 2 +ildouble: 2 +ldouble: 2 # yn +Test "yn (0, 0.125) == -1.38968062514384052915582277745018693": +ildouble: 1 +ldouble: 1 +Test "yn (0, 0.75) == -0.137172769385772397522814379396581855": +ildouble: 1 +ldouble: 1 Test "yn (0, 1.0) == 0.0882569642156769579829267660235151628": double: 2 float: 1 idouble: 2 ifloat: 1 +ildouble: 2 +ldouble: 2 Test "yn (0, 1.5) == 0.382448923797758843955068554978089862": double: 2 float: 1 @@ -564,6 +828,8 @@ double: 1 float: 1 idouble: 1 ifloat: 1 +ildouble: 2 +ldouble: 2 Test "yn (0, 2.0) == 0.510375672649745119596606592727157873": double: 1 idouble: 1 @@ -572,11 +838,21 @@ double: 1 float: 1 idouble: 1 ifloat: 1 +ildouble: 2 +ldouble: 2 +Test "yn (1, 0.125) == -5.19993611253477499595928744876579921": +double: 1 +idouble: 1 +Test "yn (1, 1.5) == -0.412308626973911295952829820633445323": +float: 2 +ifloat: 2 Test "yn (1, 10.0) == 0.249015424206953883923283474663222803": double: 3 float: 1 idouble: 3 ifloat: 1 +ildouble: 2 +ldouble: 2 Test "yn (1, 2.0) == -0.107032431540937546888370772277476637": double: 1 float: 1 @@ -587,6 +863,14 @@ double: 1 float: 2 idouble: 1 ifloat: 2 +ildouble: 2 +ldouble: 2 +Test "yn (3, 0.125) == -2612.69757350066712600220955744091741": +double: 1 +idouble: 1 +Test "yn (10, 0.125) == -127057845771019398.252538486899753195": +double: 1 +idouble: 1 Test "yn (10, 0.75) == -2133501638.90573424452445412893839236": double: 1 float: 2 @@ -597,12 +881,21 @@ float: 2 ifloat: 2 Test "yn (10, 10.0) == -0.359814152183402722051986577343560609": double: 2 +float: 2 idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 Test "yn (10, 2.0) == -129184.542208039282635913145923304214": double: 3 float: 1 idouble: 3 ifloat: 1 +ildouble: 2 +ldouble: 2 +Test "yn (3, 0.125) == -2612.69757350066712600220955744091741": +double: 1 +idouble: 1 Test "yn (3, 0.75) == -12.9877176234475433186319774484809207": float: 1 ifloat: 1 @@ -611,24 +904,58 @@ double: 1 float: 1 idouble: 1 ifloat: 1 +ildouble: 2 +ldouble: 2 Test "yn (3, 2.0) == -1.12778377684042778608158395773179238": double: 1 idouble: 1 # Maximal error of functions: +Function: "acos": +ildouble: 1 +ldouble: 1 + +Function: "acosh": +ildouble: 1 +ldouble: 1 + +Function: "asin": +ildouble: 2 +ldouble: 2 + +Function: "asinh": +ildouble: 1 +ldouble: 1 + Function: "atan2": -float: 6 -ifloat: 6 +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 Function: "atanh": float: 1 ifloat: 1 +Function: "cabs": +ildouble: 1 +ldouble: 1 + +Function: Real part of "cacos": +ildouble: 1 +ldouble: 1 + +Function: Imaginary part of "cacos": +ildouble: 1 +ldouble: 1 + Function: Real part of "cacosh": double: 1 float: 7 idouble: 1 ifloat: 7 +ildouble: 1 +ldouble: 1 Function: Imaginary part of "cacosh": double: 1 @@ -641,28 +968,42 @@ double: 1 float: 1 idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Imaginary part of "casin": +ildouble: 1 +ldouble: 1 Function: Real part of "casinh": double: 5 float: 1 idouble: 5 ifloat: 1 +ildouble: 4 +ldouble: 4 Function: Imaginary part of "casinh": double: 3 float: 6 idouble: 3 ifloat: 6 +ildouble: 1 +ldouble: 1 Function: Real part of "catan": float: 4 ifloat: 4 +ildouble: 1 +ldouble: 1 Function: Imaginary part of "catan": double: 1 float: 1 idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Function: Real part of "catanh": double: 4 @@ -675,118 +1016,190 @@ ifloat: 6 Function: "cbrt": double: 1 idouble: 1 +ildouble: 1 +ldouble: 1 Function: Real part of "ccos": double: 1 float: 1 idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Function: Imaginary part of "ccos": float: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Function: Real part of "ccosh": double: 1 float: 1 idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Function: Imaginary part of "ccosh": float: 1 ifloat: 1 +ildouble: 2 +ldouble: 2 Function: Real part of "cexp": float: 1 ifloat: 1 +ildouble: 2 +ldouble: 2 Function: Imaginary part of "cexp": float: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Function: Real part of "clog": float: 1 ifloat: 1 +ildouble: 2 +ldouble: 2 Function: Imaginary part of "clog": float: 3 ifloat: 3 +ildouble: 1 +ldouble: 1 Function: Real part of "clog10": float: 1 ifloat: 1 +ildouble: 3 +ldouble: 3 Function: Imaginary part of "clog10": double: 1 float: 5 idouble: 1 ifloat: 5 +ildouble: 1 +ldouble: 1 Function: "cos": double: 2 float: 1 idouble: 2 ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "cosh": +ildouble: 1 +ldouble: 1 Function: Real part of "cpow": double: 2 -float: 4 +float: 5 idouble: 2 -ifloat: 4 +ifloat: 5 +ildouble: 2 +ldouble: 2 Function: Imaginary part of "cpow": double: 2 float: 2 idouble: 2 ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "cproj": +ildouble: 1 +ldouble: 1 + +Function: Real part of "csin": +ildouble: 1 +ldouble: 1 Function: Real part of "csinh": float: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Function: Imaginary part of "csinh": double: 1 float: 1 idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Function: Real part of "csqrt": float: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Imaginary part of "csqrt": +ildouble: 1 +ldouble: 1 Function: Real part of "ctan": double: 1 idouble: 1 +ildouble: 1 +ldouble: 1 Function: Imaginary part of "ctan": double: 1 idouble: 1 +ildouble: 1 +ldouble: 1 Function: Real part of "ctanh": double: 1 float: 2 idouble: 1 ifloat: 2 +ildouble: 1 +ldouble: 1 Function: Imaginary part of "ctanh": float: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Function: "erf": double: 1 idouble: 1 +ildouble: 1 +ldouble: 1 Function: "erfc": double: 1 float: 1 idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "exp": +ildouble: 1 +ldouble: 1 Function: "exp10": double: 6 float: 2 idouble: 6 ifloat: 2 +ildouble: 8 +ldouble: 8 + +Function: "exp2": +ildouble: 2 +ldouble: 2 Function: "expm1": double: 1 @@ -794,76 +1207,130 @@ float: 1 idouble: 1 ifloat: 1 +Function: "gamma": +ildouble: 1 +ldouble: 1 + Function: "hypot": float: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Function: "j0": -double: 2 -float: 1 -idouble: 2 -ifloat: 1 +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 1 +ldouble: 1 Function: "j1": double: 1 float: 2 idouble: 1 ifloat: 2 +ildouble: 1 +ldouble: 1 Function: "jn": double: 3 -float: 3 +float: 4 idouble: 3 -ifloat: 3 +ifloat: 4 +ildouble: 4 +ldouble: 4 Function: "lgamma": double: 1 float: 2 idouble: 1 ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: "log": +ildouble: 1 +ldouble: 1 Function: "log10": double: 1 float: 2 idouble: 1 ifloat: 2 +ildouble: 1 +ldouble: 1 Function: "log1p": float: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "log2": +ildouble: 1 +ldouble: 1 + +Function: "pow": +ildouble: 1 +ldouble: 1 + +Function: "sin": +ildouble: 1 +ldouble: 1 Function: "sincos": double: 1 float: 1 idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "sinh": +ildouble: 1 +ldouble: 1 Function: "tan": double: 1 idouble: 1 +ildouble: 1 +ldouble: 1 + +Function: "tanh": +ildouble: 1 +ldouble: 1 Function: "tgamma": double: 1 float: 1 idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Function: "y0": double: 2 float: 1 idouble: 2 ifloat: 1 +ildouble: 1 +ldouble: 1 Function: "y1": double: 3 float: 2 idouble: 3 ifloat: 2 +ildouble: 2 +ldouble: 2 Function: "yn": double: 3 float: 2 idouble: 3 ifloat: 2 +ildouble: 2 +ldouble: 2 # end of automatic generation diff --git a/sysdeps/powerpc/fpu/math_ldbl.h b/sysdeps/powerpc/fpu/math_ldbl.h new file mode 100644 index 0000000000..6cd6d0bdfe --- /dev/null +++ b/sysdeps/powerpc/fpu/math_ldbl.h @@ -0,0 +1,189 @@ +#ifndef _MATH_PRIVATE_H_ +#error "Never use directly; include instead." +#endif + +#include +#include + +static inline void +ldbl_extract_mantissa (int64_t *hi64, u_int64_t *lo64, int *exp, long double x) +{ + /* We have 105 bits of mantissa plus one implicit digit. Since + 106 bits are representable we use the first implicit digit for + the number before the decimal point and the second implicit bit + as bit 53 of the mantissa. */ + unsigned long long hi, lo; + int ediff; + union ibm_extended_long_double eldbl; + eldbl.d = x; + *exp = eldbl.ieee.exponent - IBM_EXTENDED_LONG_DOUBLE_BIAS; + + lo = ((long long)eldbl.ieee.mantissa2 << 32) | eldbl.ieee.mantissa3; + hi = ((long long)eldbl.ieee.mantissa0 << 32) | eldbl.ieee.mantissa1; + /* If the lower double is not a denomal or zero then set the hidden + 53rd bit. */ + if (eldbl.ieee.exponent2 > 0x001) + { + lo |= (1ULL << 52); + lo = lo << 7; /* pre-shift lo to match ieee854. */ + /* The lower double is normalized separately from the upper. We + may need to adjust the lower manitissa to reflect this. */ + ediff = eldbl.ieee.exponent - eldbl.ieee.exponent2; + if (ediff > 53) + lo = lo >> (ediff-53); + } + hi |= (1ULL << 52); + + if ((eldbl.ieee.negative != eldbl.ieee.negative2) + && ((eldbl.ieee.exponent2 != 0) && (lo != 0LL))) + { + hi--; + lo = (1ULL << 60) - lo; + if (hi < (1ULL << 52)) + { + /* we have a borrow from the hidden bit, so shift left 1. */ + hi = (hi << 1) | (lo >> 59); + lo = 0xfffffffffffffffLL & (lo << 1); + *exp = *exp - 1; + } + } + *lo64 = (hi << 60) | lo; + *hi64 = hi >> 4; +} + +static inline long double +ldbl_insert_mantissa (int sign, int exp, int64_t hi64, u_int64_t lo64) +{ + union ibm_extended_long_double u; + unsigned long hidden2, lzcount; + unsigned long long hi, lo; + + u.ieee.negative = sign; + u.ieee.negative2 = sign; + u.ieee.exponent = exp + IBM_EXTENDED_LONG_DOUBLE_BIAS; + u.ieee.exponent2 = exp-53 + IBM_EXTENDED_LONG_DOUBLE_BIAS; + /* Expect 113 bits (112 bits + hidden) right justified in two longs. + The low order 53 bits (52 + hidden) go into the lower double */ + lo = (lo64 >> 7)& ((1ULL << 53) - 1); + hidden2 = (lo64 >> 59) & 1ULL; + /* The high order 53 bits (52 + hidden) go into the upper double */ + hi = (lo64 >> 60) & ((1ULL << 11) - 1); + hi |= (hi64 << 4); + + if (lo != 0LL) + { + /* hidden2 bit of low double controls rounding of the high double. + If hidden2 is '1' then round up hi and adjust lo (2nd mantissa) + plus change the sign of the low double to compensate. */ + if (hidden2) + { + hi++; + u.ieee.negative2 = !sign; + lo = (1ULL << 53) - lo; + } + /* The hidden bit of the lo mantissa is zero so we need to + normalize the it for the low double. Shift it left until the + hidden bit is '1' then adjust the 2nd exponent accordingly. */ + + if (sizeof (lo) == sizeof (long)) + lzcount = __builtin_clzl (lo); + else if ((lo >> 32) != 0) + lzcount = __builtin_clzl ((long) (lo >> 32)); + else + lzcount = __builtin_clzl ((long) lo) + 32; + lzcount = lzcount - 11; + if (lzcount > 0) + { + int expnt2 = u.ieee.exponent2 - lzcount; + if (expnt2 >= 1) + { + /* Not denormal. Normalize and set low exponent. */ + lo = lo << lzcount; + u.ieee.exponent2 = expnt2; + } + else + { + /* Is denormal. */ + lo = lo << (lzcount + expnt2); + u.ieee.exponent2 = 0; + } + } + } + else + { + u.ieee.negative2 = 0; + u.ieee.exponent2 = 0; + } + + u.ieee.mantissa3 = lo & ((1ULL << 32) - 1); + u.ieee.mantissa2 = (lo >> 32) & ((1ULL << 20) - 1); + u.ieee.mantissa1 = hi & ((1ULL << 32) - 1); + u.ieee.mantissa0 = (hi >> 32) & ((1ULL << 20) - 1); + return u.d; +} + +/* gcc generates disgusting code to pack and unpack long doubles. + This tells gcc that pack/unpack is really a nop. We use fr1/fr2 + because those are the regs used to pass/return a single + long double arg. */ +static inline long double +ldbl_pack (double a, double aa) +{ + register long double x __asm__ ("fr1"); + register double xh __asm__ ("fr1"); + register double xl __asm__ ("fr2"); + xh = a; + xl = aa; + __asm__ ("" : "=f" (x) : "f" (xh), "f" (xl)); + return x; +} + +static inline void +ldbl_unpack (long double l, double *a, double *aa) +{ + register long double x __asm__ ("fr1"); + register double xh __asm__ ("fr1"); + register double xl __asm__ ("fr2"); + x = l; + __asm__ ("" : "=f" (xh), "=f" (xl) : "f" (x)); + *a = xh; + *aa = xl; +} + + +/* Convert a finite long double to canonical form. + Does not handle +/-Inf properly. */ +static inline void +ldbl_canonicalize (double *a, double *aa) +{ + double xh, xl; + + xh = *a + *aa; + xl = (*a - xh) + *aa; + *a = xh; + *aa = xl; +} + +/* Simple inline nearbyint (double) function . + Only works in the default rounding mode + but is useful in long double rounding functions. */ +static inline double +ldbl_nearbyint (double a) +{ + double two52 = 0x10000000000000LL; + + if (__builtin_expect ((__builtin_fabs (a) < two52), 1)) + { + if (__builtin_expect ((a > 0.0), 1)) + { + a += two52; + a -= two52; + } + else if (__builtin_expect ((a < 0.0), 1)) + { + a = two52 - a; + a = -(a - two52); + } + } + return a; +} diff --git a/sysdeps/powerpc/fpu/s_fabs.S b/sysdeps/powerpc/fpu/s_fabs.S index 157ef09507..ab9a3a99bb 100644 --- a/sysdeps/powerpc/fpu/s_fabs.S +++ b/sysdeps/powerpc/fpu/s_fabs.S @@ -25,13 +25,13 @@ ENTRY(__fabs) blr END(__fabs) -weak_alias(__fabs,fabs) +weak_alias (__fabs,fabs) /* It turns out that it's safe to use this code even for single-precision. */ strong_alias(__fabs,__fabsf) -weak_alias(__fabs,fabsf) +weak_alias (__fabs,fabsf) #ifdef NO_LONG_DOUBLE -weak_alias(__fabs,__fabsl) -weak_alias(__fabs,fabsl) +weak_alias (__fabs,__fabsl) +weak_alias (__fabs,fabsl) #endif diff --git a/sysdeps/powerpc/fpu/s_fmax.S b/sysdeps/powerpc/fpu/s_fmax.S index 5666cdd079..8502c863b2 100644 --- a/sysdeps/powerpc/fpu/s_fmax.S +++ b/sysdeps/powerpc/fpu/s_fmax.S @@ -31,13 +31,13 @@ ENTRY(__fmax) blr END(__fmax) -weak_alias(__fmax,fmax) +weak_alias (__fmax,fmax) /* It turns out that it's safe to use this code even for single-precision. */ strong_alias(__fmax,__fmaxf) -weak_alias(__fmax,fmaxf) +weak_alias (__fmax,fmaxf) #ifdef NO_LONG_DOUBLE -weak_alias(__fmax,__fmaxl) -weak_alias(__fmax,fmaxl) +weak_alias (__fmax,__fmaxl) +weak_alias (__fmax,fmaxl) #endif diff --git a/sysdeps/powerpc/fpu/s_fmin.S b/sysdeps/powerpc/fpu/s_fmin.S index 96387d9ae1..5f788d06f3 100644 --- a/sysdeps/powerpc/fpu/s_fmin.S +++ b/sysdeps/powerpc/fpu/s_fmin.S @@ -31,13 +31,13 @@ ENTRY(__fmin) blr END(__fmin) -weak_alias(__fmin,fmin) +weak_alias (__fmin,fmin) /* It turns out that it's safe to use this code even for single-precision. */ strong_alias(__fmin,__fminf) -weak_alias(__fmin,fminf) +weak_alias (__fmin,fminf) #ifdef NO_LONG_DOUBLE -weak_alias(__fmin,__fminl) -weak_alias(__fmin,fminl) +weak_alias (__fmin,__fminl) +weak_alias (__fmin,fminl) #endif diff --git a/sysdeps/powerpc/fpu/s_isnan.c b/sysdeps/powerpc/fpu/s_isnan.c index 38ec821cc3..f3313c7b08 100644 --- a/sysdeps/powerpc/fpu/s_isnan.c +++ b/sysdeps/powerpc/fpu/s_isnan.c @@ -1,5 +1,5 @@ /* Return 1 if argument is a NaN, else 0. - Copyright (C) 1997, 2000, 2002 Free Software Foundation, Inc. + Copyright (C) 1997, 2000, 2002, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -23,6 +23,7 @@ #define __GI___isnanf __GI___Xisnanf #include "math.h" +#include #include #undef __isnanf diff --git a/sysdeps/powerpc/fpu/w_sqrtf.c b/sysdeps/powerpc/fpu/w_sqrtf.c index e3f3c995e8..54b4f3be7f 100644 --- a/sysdeps/powerpc/fpu/w_sqrtf.c +++ b/sysdeps/powerpc/fpu/w_sqrtf.c @@ -23,7 +23,6 @@ #include #include -#include #ifdef __STDC__ float -- cgit v1.2.3