diff options
Diffstat (limited to 'sysdeps/powerpc/fpu')
-rw-r--r-- | sysdeps/powerpc/fpu/Makefile | 1 | ||||
-rw-r--r-- | sysdeps/powerpc/fpu/bits/fenvinline.h | 60 | ||||
-rw-r--r-- | sysdeps/powerpc/fpu/bits/mathinline.h | 130 | ||||
-rw-r--r-- | sysdeps/powerpc/fpu/fegetenv.c | 5 | ||||
-rw-r--r-- | sysdeps/powerpc/fpu/fenv_libc.h | 4 | ||||
-rw-r--r-- | sysdeps/powerpc/fpu/fesetenv.c | 5 | ||||
-rw-r--r-- | sysdeps/powerpc/fpu/feupdateenv.c | 5 | ||||
-rw-r--r-- | sysdeps/powerpc/fpu/fgetexcptflg.c | 5 | ||||
-rw-r--r-- | sysdeps/powerpc/fpu/fpu_control.h | 81 | ||||
-rw-r--r-- | sysdeps/powerpc/fpu/fraiseexcpt.c | 5 | ||||
-rw-r--r-- | sysdeps/powerpc/fpu/fsetexcptflg.c | 5 | ||||
-rw-r--r-- | sysdeps/powerpc/fpu/libm-test-ulps | 6 | ||||
-rw-r--r-- | sysdeps/powerpc/fpu/math_ldbl.h | 171 | ||||
-rw-r--r-- | sysdeps/powerpc/fpu/s_llround.c | 4 | ||||
-rw-r--r-- | sysdeps/powerpc/fpu/test-powerpc-snan.c | 382 | ||||
-rw-r--r-- | sysdeps/powerpc/fpu/w_sqrt.c | 4 |
16 files changed, 37 insertions, 836 deletions
diff --git a/sysdeps/powerpc/fpu/Makefile b/sysdeps/powerpc/fpu/Makefile index ffacf1a754..fda59f9fa4 100644 --- a/sysdeps/powerpc/fpu/Makefile +++ b/sysdeps/powerpc/fpu/Makefile @@ -1,6 +1,5 @@ ifeq ($(subdir),math) libm-support += fenv_const fe_nomask fe_mask t_sqrt -libm-tests += test-powerpc-snan # libm needs ld.so to access dl_hwcap $(objpfx)libm.so: $(elfobjdir)/ld.so diff --git a/sysdeps/powerpc/fpu/bits/fenvinline.h b/sysdeps/powerpc/fpu/bits/fenvinline.h deleted file mode 100644 index 0720795d54..0000000000 --- a/sysdeps/powerpc/fpu/bits/fenvinline.h +++ /dev/null @@ -1,60 +0,0 @@ -/* Inline floating-point environment handling functions for powerpc. - Copyright (C) 1995-2013 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, see - <http://www.gnu.org/licenses/>. */ - -#if (defined __GNUC__ && !defined _SOFT_FLOAT && !defined __NO_FPRS__ \ - && !defined __NO_MATH_INLINES) - -/* Inline definition for fegetround. */ -# define fegetround() \ - (__extension__ ({ int __fegetround_result; \ - __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 - warning when __excepts is not a constant. Otherwise, they mean the - same as just plain 'i'. */ - -/* Inline definition for feraiseexcept. */ -# define feraiseexcept(__excepts) \ - ((__builtin_constant_p (__excepts) \ - && ((__excepts) & ((__excepts)-1)) == 0 \ - && (__excepts) != FE_INVALID) \ - ? ((__excepts) != 0 \ - ? (__extension__ ({ __asm__ __volatile__ \ - ("mtfsb1 %s0" \ - : : "i#*X"(__builtin_ffs (__excepts))); \ - 0; })) \ - : 0) \ - : (feraiseexcept) (__excepts)) - -/* Inline definition for feclearexcept. */ -# define feclearexcept(__excepts) \ - ((__builtin_constant_p (__excepts) \ - && ((__excepts) & ((__excepts)-1)) == 0 \ - && (__excepts) != FE_INVALID) \ - ? ((__excepts) != 0 \ - ? (__extension__ ({ __asm__ __volatile__ \ - ("mtfsb0 %s0" \ - : : "i#*X"(__builtin_ffs (__excepts))); \ - 0; })) \ - : 0) \ - : (feclearexcept) (__excepts)) - -#endif /* __GNUC__ && !_SOFT_FLOAT && !__NO_FPRS__ */ diff --git a/sysdeps/powerpc/fpu/bits/mathinline.h b/sysdeps/powerpc/fpu/bits/mathinline.h deleted file mode 100644 index 140fff08ef..0000000000 --- a/sysdeps/powerpc/fpu/bits/mathinline.h +++ /dev/null @@ -1,130 +0,0 @@ -/* Inline math functions for powerpc. - Copyright (C) 1995-2013 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, see - <http://www.gnu.org/licenses/>. */ - -#ifndef _MATH_H -# error "Never use <bits/mathinline.h> directly; include <math.h> instead." -#endif - -#ifndef __extern_inline -# define __MATH_INLINE __inline -#else -# define __MATH_INLINE __extern_inline -#endif /* __cplusplus */ - -#if defined __GNUC__ && !defined _SOFT_FLOAT && !defined __NO_FPRS__ - -#ifdef __USE_ISOC99 -# if !__GNUC_PREREQ (2,97) -# define __unordered_cmp(x, y) \ - (__extension__ \ - ({ __typeof__(x) __x = (x); __typeof__(y) __y = (y); \ - unsigned __r; \ - __asm__("fcmpu 7,%1,%2 ; mfcr %0" : "=r" (__r) : "f" (__x), "f"(__y) \ - : "cr7"); \ - __r; })) - -# undef isgreater -# undef isgreaterequal -# undef isless -# undef islessequal -# undef islessgreater -# undef isunordered - -# define isgreater(x, y) (__unordered_cmp (x, y) >> 2 & 1) -# define isgreaterequal(x, y) ((__unordered_cmp (x, y) & 6) != 0) -# define isless(x, y) (__unordered_cmp (x, y) >> 3 & 1) -# define islessequal(x, y) ((__unordered_cmp (x, y) & 0xA) != 0) -# define islessgreater(x, y) ((__unordered_cmp (x, y) & 0xC) != 0) -# define isunordered(x, y) (__unordered_cmp (x, y) & 1) - -# endif /* __GNUC_PREREQ (2,97) */ - -/* The gcc, version 2.7 or below, has problems with all this inlining - code. So disable it for this version of the compiler. */ -# if __GNUC_PREREQ (2, 8) -/* Test for negative number. Used in the signbit() macro. */ -__MATH_INLINE int -__NTH (__signbitf (float __x)) -{ - __extension__ union { float __f; int __i; } __u = { __f: __x }; - return __u.__i < 0; -} -__MATH_INLINE int -__NTH (__signbit (double __x)) -{ - __extension__ union { double __d; int __i[2]; } __u = { __d: __x }; - return __u.__i[0] < 0; -} -# ifdef __LONG_DOUBLE_128__ -__MATH_INLINE int -__NTH (__signbitl (long double __x)) -{ - __extension__ union { long double __d; int __i[4]; } __u = { __d: __x }; - return __u.__i[0] < 0; -} -# endif -# endif -#endif /* __USE_ISOC99 */ - -#if !defined __NO_MATH_INLINES && defined __OPTIMIZE__ - -#ifdef __USE_ISOC99 - -# ifndef __powerpc64__ -__MATH_INLINE long int lrint (double __x) __THROW; -__MATH_INLINE long int -__NTH (lrint (double __x)) -{ - union { - double __d; - int __ll[2]; - } __u; - __asm__ ("fctiw %0,%1" : "=f"(__u.__d) : "f"(__x)); - return __u.__ll[1]; -} - -__MATH_INLINE long int lrintf (float __x) __THROW; -__MATH_INLINE long int -__NTH (lrintf (float __x)) -{ - union { - double __d; - int __ll[2]; - } __u; - __asm__ ("fctiw %0,%1" : "=f"(__u.__d) : "f"(__x)); - return __u.__ll[1]; -} -# endif - -__MATH_INLINE double fdim (double __x, double __y) __THROW; -__MATH_INLINE double -__NTH (fdim (double __x, double __y)) -{ - return __x <= __y ? 0 : __x - __y; -} - -__MATH_INLINE float fdimf (float __x, float __y) __THROW; -__MATH_INLINE float -__NTH (fdimf (float __x, float __y)) -{ - return __x <= __y ? 0 : __x - __y; -} - -#endif /* __USE_ISOC99 */ -#endif /* !__NO_MATH_INLINES && __OPTIMIZE__ */ -#endif /* __GNUC__ && !_SOFT_FLOAT && !__NO_FPRS__ */ diff --git a/sysdeps/powerpc/fpu/fegetenv.c b/sysdeps/powerpc/fpu/fegetenv.c index ee60e6df12..a512a91a4e 100644 --- a/sysdeps/powerpc/fpu/fegetenv.c +++ b/sysdeps/powerpc/fpu/fegetenv.c @@ -17,7 +17,6 @@ <http://www.gnu.org/licenses/>. */ #include <fenv_libc.h> -#include <bp-sym.h> int __fegetenv (fenv_t *envp) @@ -31,8 +30,8 @@ __fegetenv (fenv_t *envp) #include <shlib-compat.h> #if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2) strong_alias (__fegetenv, __old_fegetenv) -compat_symbol (libm, BP_SYM (__old_fegetenv), BP_SYM (fegetenv), GLIBC_2_1); +compat_symbol (libm, __old_fegetenv, fegetenv, GLIBC_2_1); #endif libm_hidden_ver (__fegetenv, fegetenv) -versioned_symbol (libm, BP_SYM (__fegetenv), BP_SYM (fegetenv), GLIBC_2_2); +versioned_symbol (libm, __fegetenv, fegetenv, GLIBC_2_2); diff --git a/sysdeps/powerpc/fpu/fenv_libc.h b/sysdeps/powerpc/fpu/fenv_libc.h index abae2f3dfb..1910951568 100644 --- a/sysdeps/powerpc/fpu/fenv_libc.h +++ b/sysdeps/powerpc/fpu/fenv_libc.h @@ -116,7 +116,7 @@ enum { FPSCR_UX, /* underflow */ FPSCR_ZX, /* zero divide */ FPSCR_XX, /* inexact */ - FPSCR_VXSNAN, /* invalid operation for SNaN */ + FPSCR_VXSNAN, /* invalid operation for sNaN */ FPSCR_VXISI, /* invalid operation for Inf-Inf */ FPSCR_VXIDI, /* invalid operation for Inf/Inf */ FPSCR_VXZDZ, /* invalid operation for 0/0 */ @@ -152,7 +152,7 @@ enum { #endif /* _ARCH_PWR6 */ /* This operation (i) sets the appropriate FPSCR bits for its - parameter, (ii) converts SNaN to the corresponding NaN, and (iii) + parameter, (ii) converts sNaN to the corresponding qNaN, and (iii) otherwise passes its parameter through unchanged (in particular, -0 and +0 stay as they were). The `obvious' way to do this is optimised out by gcc. */ diff --git a/sysdeps/powerpc/fpu/fesetenv.c b/sysdeps/powerpc/fpu/fesetenv.c index 72989c476d..953af5ddc7 100644 --- a/sysdeps/powerpc/fpu/fesetenv.c +++ b/sysdeps/powerpc/fpu/fesetenv.c @@ -18,7 +18,6 @@ #include <fenv_libc.h> #include <fpu_control.h> -#include <bp-sym.h> #define _FPU_MASK_ALL (_FPU_MASK_ZM | _FPU_MASK_OM | _FPU_MASK_UM | _FPU_MASK_XM | _FPU_MASK_IM) @@ -54,8 +53,8 @@ __fesetenv (const fenv_t *envp) #include <shlib-compat.h> #if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2) strong_alias (__fesetenv, __old_fesetenv) -compat_symbol (libm, BP_SYM (__old_fesetenv), BP_SYM (fesetenv), GLIBC_2_1); +compat_symbol (libm, __old_fesetenv, fesetenv, GLIBC_2_1); #endif libm_hidden_ver (__fesetenv, fesetenv) -versioned_symbol (libm, BP_SYM (__fesetenv), BP_SYM (fesetenv), GLIBC_2_2); +versioned_symbol (libm, __fesetenv, fesetenv, GLIBC_2_2); diff --git a/sysdeps/powerpc/fpu/feupdateenv.c b/sysdeps/powerpc/fpu/feupdateenv.c index 66f2826398..9faf930f36 100644 --- a/sysdeps/powerpc/fpu/feupdateenv.c +++ b/sysdeps/powerpc/fpu/feupdateenv.c @@ -19,7 +19,6 @@ #include <fenv_libc.h> #include <fpu_control.h> -#include <bp-sym.h> #define _FPU_MASK_ALL (_FPU_MASK_ZM | _FPU_MASK_OM | _FPU_MASK_UM | _FPU_MASK_XM | _FPU_MASK_IM) @@ -61,8 +60,8 @@ __feupdateenv (const fenv_t *envp) #include <shlib-compat.h> #if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2) strong_alias (__feupdateenv, __old_feupdateenv) -compat_symbol (libm, BP_SYM (__old_feupdateenv), BP_SYM (feupdateenv), GLIBC_2_1); +compat_symbol (libm, __old_feupdateenv, feupdateenv, GLIBC_2_1); #endif libm_hidden_ver (__feupdateenv, feupdateenv) -versioned_symbol (libm, BP_SYM (__feupdateenv), BP_SYM (feupdateenv), GLIBC_2_2); +versioned_symbol (libm, __feupdateenv, feupdateenv, GLIBC_2_2); diff --git a/sysdeps/powerpc/fpu/fgetexcptflg.c b/sysdeps/powerpc/fpu/fgetexcptflg.c index 987a205472..f6327ce170 100644 --- a/sysdeps/powerpc/fpu/fgetexcptflg.c +++ b/sysdeps/powerpc/fpu/fgetexcptflg.c @@ -17,7 +17,6 @@ <http://www.gnu.org/licenses/>. */ #include <fenv_libc.h> -#include <bp-sym.h> int __fegetexceptflag (fexcept_t *flagp, int excepts) @@ -37,7 +36,7 @@ __fegetexceptflag (fexcept_t *flagp, int excepts) #include <shlib-compat.h> #if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2) strong_alias (__fegetexceptflag, __old_fegetexceptflag) -compat_symbol (libm, BP_SYM (__old_fegetexceptflag), BP_SYM (fegetexceptflag), GLIBC_2_1); +compat_symbol (libm, __old_fegetexceptflag, fegetexceptflag, GLIBC_2_1); #endif -versioned_symbol (libm, BP_SYM (__fegetexceptflag), BP_SYM (fegetexceptflag), GLIBC_2_2); +versioned_symbol (libm, __fegetexceptflag, fegetexceptflag, GLIBC_2_2); diff --git a/sysdeps/powerpc/fpu/fpu_control.h b/sysdeps/powerpc/fpu/fpu_control.h deleted file mode 100644 index 159543beed..0000000000 --- a/sysdeps/powerpc/fpu/fpu_control.h +++ /dev/null @@ -1,81 +0,0 @@ -/* FPU control word definitions. PowerPC version. - Copyright (C) 1996-2013 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, see - <http://www.gnu.org/licenses/>. */ - -#ifndef _FPU_CONTROL_H -#define _FPU_CONTROL_H - -#if defined _SOFT_FLOAT || defined __NO_FPRS__ - -# define _FPU_RESERVED 0xffffffff -# define _FPU_DEFAULT 0x00000000 /* Default value. */ -typedef unsigned int fpu_control_t; -# define _FPU_GETCW(cw) (cw) = 0 -# define _FPU_SETCW(cw) (void) (cw) -extern fpu_control_t __fpu_control; - -#else /* PowerPC 6xx floating-point. */ - -/* rounding control */ -# define _FPU_RC_NEAREST 0x00 /* RECOMMENDED */ -# define _FPU_RC_DOWN 0x03 -# define _FPU_RC_UP 0x02 -# define _FPU_RC_ZERO 0x01 - -# define _FPU_MASK_NI 0x04 /* non-ieee mode */ - -/* masking of interrupts */ -# define _FPU_MASK_ZM 0x10 /* zero divide */ -# define _FPU_MASK_OM 0x40 /* overflow */ -# define _FPU_MASK_UM 0x20 /* underflow */ -# define _FPU_MASK_XM 0x08 /* inexact */ -# define _FPU_MASK_IM 0x80 /* invalid operation */ - -# define _FPU_RESERVED 0xffffff00 /* These bits are reserved are not changed. */ - -/* The fdlibm code requires no interrupts for exceptions. */ -# define _FPU_DEFAULT 0x00000000 /* Default value. */ - -/* IEEE: same as above, but (some) exceptions; - we leave the 'inexact' exception off. - */ -# define _FPU_IEEE 0x000000f0 - -/* Type of the control word. */ -typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__SI__))); - -/* Macros for accessing the hardware control word. */ -# define _FPU_GETCW(__cw) ( { \ - union { double d; fpu_control_t cw[2]; } \ - tmp __attribute__ ((__aligned__(8))); \ - __asm__ ("mffs 0; stfd%U0 0,%0" : "=m" (tmp.d) : : "fr0"); \ - (__cw)=tmp.cw[1]; \ - tmp.cw[1]; } ) -# define _FPU_SETCW(__cw) { \ - union { double d; fpu_control_t cw[2]; } \ - tmp __attribute__ ((__aligned__(8))); \ - tmp.cw[0] = 0xFFF80000; /* More-or-less arbitrary; this is a QNaN. */ \ - tmp.cw[1] = __cw; \ - __asm__ ("lfd%U0 0,%0; mtfsf 255,0" : : "m" (tmp.d) : "fr0"); \ -} - -/* Default control word set at startup. */ -extern fpu_control_t __fpu_control; - -#endif /* PowerPC 6xx floating-point. */ - -#endif /* _FPU_CONTROL_H */ diff --git a/sysdeps/powerpc/fpu/fraiseexcpt.c b/sysdeps/powerpc/fpu/fraiseexcpt.c index 88d1844768..9118c1954a 100644 --- a/sysdeps/powerpc/fpu/fraiseexcpt.c +++ b/sysdeps/powerpc/fpu/fraiseexcpt.c @@ -17,7 +17,6 @@ <http://www.gnu.org/licenses/>. */ #include <fenv_libc.h> -#include <bp-sym.h> #undef feraiseexcept int @@ -61,8 +60,8 @@ __feraiseexcept (int excepts) #include <shlib-compat.h> #if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2) strong_alias (__feraiseexcept, __old_feraiseexcept) -compat_symbol (libm, BP_SYM (__old_feraiseexcept), BP_SYM (feraiseexcept), GLIBC_2_1); +compat_symbol (libm, __old_feraiseexcept, feraiseexcept, GLIBC_2_1); #endif libm_hidden_ver (__feraiseexcept, feraiseexcept) -versioned_symbol (libm, BP_SYM (__feraiseexcept), BP_SYM (feraiseexcept), GLIBC_2_2); +versioned_symbol (libm, __feraiseexcept, feraiseexcept, GLIBC_2_2); diff --git a/sysdeps/powerpc/fpu/fsetexcptflg.c b/sysdeps/powerpc/fpu/fsetexcptflg.c index 588fb6a0d7..c050d4022b 100644 --- a/sysdeps/powerpc/fpu/fsetexcptflg.c +++ b/sysdeps/powerpc/fpu/fsetexcptflg.c @@ -17,7 +17,6 @@ <http://www.gnu.org/licenses/>. */ #include <fenv_libc.h> -#include <bp-sym.h> int __fesetexceptflag (const fexcept_t *flagp, int excepts) @@ -53,7 +52,7 @@ __fesetexceptflag (const fexcept_t *flagp, int excepts) #include <shlib-compat.h> #if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2) strong_alias (__fesetexceptflag, __old_fesetexceptflag) -compat_symbol (libm, BP_SYM (__old_fesetexceptflag), BP_SYM (fesetexceptflag), GLIBC_2_1); +compat_symbol (libm, __old_fesetexceptflag, fesetexceptflag, GLIBC_2_1); #endif -versioned_symbol (libm, BP_SYM (__fesetexceptflag), BP_SYM (fesetexceptflag), GLIBC_2_2); +versioned_symbol (libm, __fesetexceptflag, fesetexceptflag, GLIBC_2_2); diff --git a/sysdeps/powerpc/fpu/libm-test-ulps b/sysdeps/powerpc/fpu/libm-test-ulps index 4221967c46..5072190fd7 100644 --- a/sysdeps/powerpc/fpu/libm-test-ulps +++ b/sysdeps/powerpc/fpu/libm-test-ulps @@ -243,9 +243,11 @@ idouble: 1 Test "Real part of: cacos (-0.5 + +0 i) == 2.094395102393195492308428922186335256131 - 0 i": double: 1 idouble: 1 +ldouble: 1 Test "Real part of: cacos (-0.5 - 0 i) == 2.094395102393195492308428922186335256131 + +0 i": double: 1 idouble: 1 +ldouble: 1 Test "Imaginary part of: cacos (-1.5 + +0 i) == pi - 0.9624236501192068949955178268487368462704 i": double: 1 float: 1 @@ -265,6 +267,10 @@ double: 1 float: 1 idouble: 1 ifloat: 1 +Test "Imaginary part of: cacos (0x1.fp1023 + 0x1.fp1023 i) == 7.853981633974483096156608458198757210493e-1 - 7.107906849659093345062145442726115449315e2 i": +ldouble: 1 +Test "Imaginary part of: cacos (0x1.fp127 + 0x1.fp127 i) == 7.853981633974483096156608458198757210493e-1 - 8.973081118419833726837456344608533993585e1 i": +ldouble: 1 # cacosh Test "Real part of: cacosh (+0 + 0.5 i) == 0.4812118250596034474977589134243684231352 + pi/2 i": diff --git a/sysdeps/powerpc/fpu/math_ldbl.h b/sysdeps/powerpc/fpu/math_ldbl.h index 20224e6646..36378c0239 100644 --- a/sysdeps/powerpc/fpu/math_ldbl.h +++ b/sysdeps/powerpc/fpu/math_ldbl.h @@ -2,132 +2,12 @@ #error "Never use <math_ldbl.h> directly; include <math_private.h> instead." #endif -#include <sysdeps/ieee754/ldbl-128/math_ldbl.h> -#include <ieee754.h> - -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 mantissa 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. */ +/* GCC does not optimize the default ldbl_pack code to not spill register + in the stack. The following optimization 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) +ldbl_pack_ppc (double a, double aa) { register long double x __asm__ ("fr1"); register double xh __asm__ ("fr1"); @@ -139,7 +19,7 @@ ldbl_pack (double a, double aa) } static inline void -ldbl_unpack (long double l, double *a, double *aa) +ldbl_unpack_ppc (long double l, double *a, double *aa) { register long double x __asm__ ("fr1"); register double xh __asm__ ("fr1"); @@ -150,40 +30,7 @@ ldbl_unpack (long double l, double *a, double *aa) *aa = xl; } +#define ldbl_pack ldbl_pack_ppc +#define ldbl_unpack ldbl_unpack_ppc -/* 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; -} +#include <sysdeps/ieee754/ldbl-128ibm/math_ldbl.h> diff --git a/sysdeps/powerpc/fpu/s_llround.c b/sysdeps/powerpc/fpu/s_llround.c index b53d6eed8f..9a01826539 100644 --- a/sysdeps/powerpc/fpu/s_llround.c +++ b/sysdeps/powerpc/fpu/s_llround.c @@ -17,6 +17,7 @@ <http://www.gnu.org/licenses/>. */ #include <math.h> +#include <math_ldbl_opt.h> /* I think that what this routine is supposed to do is round a value to the nearest integer, with values exactly on the boundary rounded @@ -47,3 +48,6 @@ weak_alias (__llround, llround) strong_alias (__llround, __llroundl) weak_alias (__llround, llroundl) #endif +#if LONG_DOUBLE_COMPAT (libm, GLIBC_2_1) +compat_symbol (libm, __llround, llroundl, GLIBC_2_1); +#endif diff --git a/sysdeps/powerpc/fpu/test-powerpc-snan.c b/sysdeps/powerpc/fpu/test-powerpc-snan.c deleted file mode 100644 index e3bd47abaf..0000000000 --- a/sysdeps/powerpc/fpu/test-powerpc-snan.c +++ /dev/null @@ -1,382 +0,0 @@ -/* Test Signalling NaN in isnan, isinf etc functions. - Copyright (C) 2008-2013 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Andreas Jaeger <aj@suse.de>, 2005. - - 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, see - <http://www.gnu.org/licenses/>. */ - -#define _GNU_SOURCE 1 -#include <stdio.h> -#include <stdlib.h> -#include <sys/time.h> -#include <string.h> -#include <math.h> -#include <float.h> -#include <fenv.h> -#include <signal.h> -#include <setjmp.h> -#include <errno.h> - -int dest_offset; -char *dest_address; -double value = 123.456; -double zero = 0.0; - -float SNANf; -double SNAN; -long double SNANl; - -static sigjmp_buf sigfpe_buf; - -void -init_signaling_nan (void) -{ - union { - double _ld16; - double _d8; - unsigned int _ui4[4]; - float _f4; - } nan_temp; - - nan_temp._ui4[0] = 0x7fa00000; - SNANf = nan_temp._f4; - - nan_temp._ui4[0] = 0x7ff40000; - nan_temp._ui4[1] = 0x00000000; - SNAN = nan_temp._d8; - - nan_temp._ui4[0] = 0x7ff40000; - nan_temp._ui4[1] = 0x00000000; - nan_temp._ui4[2] = 0x00000000; - nan_temp._ui4[3] = 0x00000000; - SNANl = nan_temp._ld16; -} - -static float -snan_float (void) -{ - return SNANf; -} - -static double -snan_double (void) -{ - return SNAN; -} - -typedef long double ldouble; - -static ldouble -snan_ldouble (void) -{ - return SNANl; -} - - -void -myFPsighandler(int signal, - siginfo_t *info, - void *context) -{ - siglongjmp(sigfpe_buf, 0); -} - -int -set_sigaction_FP(void) -{ - struct sigaction sa; - /* register RT signal handler via sigaction */ - sa.sa_flags = SA_SIGINFO; - sa.sa_sigaction = &myFPsighandler; - sigemptyset(&sa.sa_mask); - sigaction(SIGFPE, &sa, NULL); - - return 0; -} - -int -remove_sigaction_FP(void) -{ - struct sigaction sa; - /* restore default RT signal handler via sigaction */ - sa.sa_flags = SA_SIGINFO; - sa.sa_handler = SIG_DFL; - sigemptyset(&sa.sa_mask); - sigaction(SIGFPE, &sa, NULL); - - return 0; -} - -static int errors = 0; - -static void -check (const char *testname, int result) -{ - if (!result) { - printf ("Failure: %s\n", testname); - errors++; - } -} - -#define TEST_FUNC(NAME, FLOAT) \ -static void \ -NAME (void) \ -{ \ - /* Variables are declared volatile to forbid some compiler \ - optimizations. */ \ - volatile FLOAT Inf_var, NaN_var, zero_var, one_var, SNaN_var; \ - fenv_t saved_fenv; \ - \ - zero_var = 0.0; \ - one_var = 1.0; \ - NaN_var = zero_var / zero_var; \ - SNaN_var = snan_##FLOAT (); \ - Inf_var = one_var / zero_var; \ - \ - (void) &zero_var; \ - (void) &one_var; \ - (void) &NaN_var; \ - (void) &SNaN_var; \ - (void) &Inf_var; \ - \ - set_sigaction_FP (); \ - fegetenv(&saved_fenv); \ - \ - feclearexcept(FE_ALL_EXCEPT); \ - feenableexcept (FE_ALL_EXCEPT); \ - if (sigsetjmp(sigfpe_buf, 0)) \ - { \ - printf (#FLOAT " isnan(NaN) raised SIGFPE\n"); \ - errors++; \ - } else { \ - check (#FLOAT " isnan (NaN)", isnan (NaN_var)); \ - } \ - \ - feclearexcept(FE_ALL_EXCEPT); \ - feenableexcept (FE_ALL_EXCEPT); \ - if (sigsetjmp(sigfpe_buf, 0)) \ - { \ - printf (#FLOAT " isnan(-NaN) raised SIGFPE\n"); \ - errors++; \ - } else { \ - check (#FLOAT " isnan (-NaN)", isnan (-NaN_var)); \ - } \ - \ - feclearexcept(FE_ALL_EXCEPT); \ - feenableexcept (FE_ALL_EXCEPT); \ - if (sigsetjmp(sigfpe_buf, 0)) \ - { \ - printf (#FLOAT " isnan(SNaN) raised SIGFPE\n"); \ - errors++; \ - } else { \ - check (#FLOAT " isnan (SNaN)", isnan (SNaN_var)); \ - } \ - \ - feclearexcept(FE_ALL_EXCEPT); \ - feenableexcept (FE_ALL_EXCEPT); \ - if (sigsetjmp(sigfpe_buf, 0)) \ - { \ - printf (#FLOAT " isnan(-SNaN) raised SIGFPE\n"); \ - errors++; \ - } else { \ - check (#FLOAT " isnan (-SNaN)", isnan (-SNaN_var)); \ - } \ - \ - feclearexcept(FE_ALL_EXCEPT); \ - feenableexcept (FE_ALL_EXCEPT); \ - if (sigsetjmp(sigfpe_buf, 0)) \ - { \ - printf (#FLOAT " isinf(NaN) raised SIGFPE\n"); \ - errors++; \ - } else { \ - check (#FLOAT " isinf (NaN)", !isinf (NaN_var)); \ - } \ - \ - feclearexcept(FE_ALL_EXCEPT); \ - feenableexcept (FE_ALL_EXCEPT); \ - if (sigsetjmp(sigfpe_buf, 0)) \ - { \ - printf (#FLOAT " isinf(-NaN) raised SIGFPE\n"); \ - errors++; \ - } else { \ - check (#FLOAT " isinf (-NaN)", !isinf (-NaN_var)); \ - } \ - \ - feclearexcept(FE_ALL_EXCEPT); \ - feenableexcept (FE_ALL_EXCEPT); \ - if (sigsetjmp(sigfpe_buf, 0)) \ - { \ - printf (#FLOAT " isinf(SNaN) raised SIGFPE\n"); \ - errors++; \ - } else { \ - check (#FLOAT " isinf (SNaN)", !isinf (SNaN_var)); \ - } \ - \ - feclearexcept(FE_ALL_EXCEPT); \ - feenableexcept (FE_ALL_EXCEPT); \ - if (sigsetjmp(sigfpe_buf, 0)) \ - { \ - printf (#FLOAT " isinf(-SNaN) raised SIGFPE\n"); \ - errors++; \ - } else { \ - check (#FLOAT " isinf (-SNaN)", !isinf (-SNaN_var)); \ - } \ - \ - feclearexcept(FE_ALL_EXCEPT); \ - feenableexcept (FE_ALL_EXCEPT); \ - if (sigsetjmp(sigfpe_buf, 0)) \ - { \ - printf (#FLOAT " isfinite(NaN) raised SIGFPE\n"); \ - errors++; \ - } else { \ - check (#FLOAT " isfinite (NaN)", !isfinite (NaN_var)); \ - } \ - \ - feclearexcept(FE_ALL_EXCEPT); \ - feenableexcept (FE_ALL_EXCEPT); \ - if (sigsetjmp(sigfpe_buf, 0)) \ - { \ - printf (#FLOAT " isfinite(-NaN) raised SIGFPE\n"); \ - errors++; \ - } else { \ - check (#FLOAT " isfinite (-NaN)", !isfinite (-NaN_var)); \ - } \ - \ - feclearexcept(FE_ALL_EXCEPT); \ - feenableexcept (FE_ALL_EXCEPT); \ - if (sigsetjmp(sigfpe_buf, 0)) \ - { \ - printf (#FLOAT " isfinite(SNaN) raised SIGFPE\n"); \ - errors++; \ - } else { \ - check (#FLOAT " isfinite (SNaN)", !isfinite (SNaN_var)); \ - } \ - \ - feclearexcept(FE_ALL_EXCEPT); \ - feenableexcept (FE_ALL_EXCEPT); \ - if (sigsetjmp(sigfpe_buf, 0)) \ - { \ - printf (#FLOAT " isfinite(-SNaN) raised SIGFPE\n"); \ - errors++; \ - } else { \ - check (#FLOAT " isfinite (-SNaN)", !isfinite (-SNaN_var)); \ - } \ - \ - feclearexcept(FE_ALL_EXCEPT); \ - feenableexcept (FE_ALL_EXCEPT); \ - if (sigsetjmp(sigfpe_buf, 0)) \ - { \ - printf (#FLOAT " isnormal(NaN) raised SIGFPE\n"); \ - errors++; \ - } else { \ - check (#FLOAT " isnormal (NaN)", !isnormal (NaN_var)); \ - } \ - \ - feclearexcept(FE_ALL_EXCEPT); \ - feenableexcept (FE_ALL_EXCEPT); \ - if (sigsetjmp(sigfpe_buf, 0)) \ - { \ - printf (#FLOAT " isnormal(-NaN) raised SIGFPE\n"); \ - errors++; \ - } else { \ - check (#FLOAT " isnormal (-NaN)", !isnormal (-NaN_var)); \ - } \ - \ - feclearexcept(FE_ALL_EXCEPT); \ - feenableexcept (FE_ALL_EXCEPT); \ - if (sigsetjmp(sigfpe_buf, 0)) \ - { \ - printf (#FLOAT " isnormal(SNaN) isnormal SIGFPE\n"); \ - errors++; \ - } else { \ - check (#FLOAT " isnormal (SNaN)", !isnormal (SNaN_var)); \ - } \ - \ - feclearexcept(FE_ALL_EXCEPT); \ - feenableexcept (FE_ALL_EXCEPT); \ - if (sigsetjmp(sigfpe_buf, 0)) \ - { \ - printf (#FLOAT " isnormal(-SNaN) raised SIGFPE\n"); \ - errors++; \ - } else { \ - check (#FLOAT " isnormal (-SNaN)", !isnormal (-SNaN_var)); \ - } \ - \ - feclearexcept(FE_ALL_EXCEPT); \ - feenableexcept (FE_ALL_EXCEPT); \ - if (sigsetjmp(sigfpe_buf, 0)) \ - { \ - printf (#FLOAT " fpclassify(NaN) raised SIGFPE\n"); \ - errors++; \ - } else { \ - check (#FLOAT " fpclassify (NaN)", (fpclassify (NaN_var)==FP_NAN)); \ - } \ - \ - feclearexcept(FE_ALL_EXCEPT); \ - feenableexcept (FE_ALL_EXCEPT); \ - if (sigsetjmp(sigfpe_buf, 0)) \ - { \ - printf (#FLOAT " fpclassify(-NaN) raised SIGFPE\n"); \ - errors++; \ - } else { \ - check (#FLOAT " fpclassify (-NaN)", (fpclassify (-NaN_var)==FP_NAN)); \ - } \ - \ - feclearexcept(FE_ALL_EXCEPT); \ - feenableexcept (FE_ALL_EXCEPT); \ - if (sigsetjmp(sigfpe_buf, 0)) \ - { \ - printf (#FLOAT " fpclassify(SNaN) isnormal SIGFPE\n"); \ - errors++; \ - } else { \ - check (#FLOAT " fpclassify (SNaN)", (fpclassify (SNaN_var)==FP_NAN)); \ - } \ - \ - feclearexcept(FE_ALL_EXCEPT); \ - feenableexcept (FE_ALL_EXCEPT); \ - if (sigsetjmp(sigfpe_buf, 0)) \ - { \ - printf (#FLOAT " fpclassify(-SNaN) raised SIGFPE\n"); \ - errors++; \ - } else { \ - check (#FLOAT " fpclassify (-SNaN)", (fpclassify (-SNaN_var)==FP_NAN)); \ - } \ - \ - fesetenv(&saved_fenv); /* restore saved fenv */ \ - remove_sigaction_FP(); \ -} - -TEST_FUNC (float_test, float) -TEST_FUNC (double_test, double) -#ifndef NO_LONG_DOUBLE -TEST_FUNC (ldouble_test, ldouble) -#endif - -static int -do_test (void) -{ - init_signaling_nan(); - - float_test(); - double_test(); -#ifndef NO_LONG_DOUBLE - ldouble_test(); -#endif - - return errors != 0; -} - -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" diff --git a/sysdeps/powerpc/fpu/w_sqrt.c b/sysdeps/powerpc/fpu/w_sqrt.c index 2488ad9b97..70f28dd4df 100644 --- a/sysdeps/powerpc/fpu/w_sqrt.c +++ b/sysdeps/powerpc/fpu/w_sqrt.c @@ -19,6 +19,7 @@ #include <math.h> #include <math_private.h> #include <fenv_libc.h> +#include <math_ldbl_opt.h> double __sqrt (double x) /* wrapper sqrt */ @@ -42,3 +43,6 @@ weak_alias (__sqrt, sqrt) #ifdef NO_LONG_DOUBLE strong_alias (__sqrt, __sqrtl) weak_alias (__sqrt, sqrtl) #endif +#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0) +compat_symbol (libm, __sqrt, sqrtl, GLIBC_2_0); +#endif |