summaryrefslogtreecommitdiff
path: root/sysdeps/powerpc/fpu
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/powerpc/fpu')
-rw-r--r--sysdeps/powerpc/fpu/Makefile1
-rw-r--r--sysdeps/powerpc/fpu/bits/fenvinline.h60
-rw-r--r--sysdeps/powerpc/fpu/bits/mathinline.h130
-rw-r--r--sysdeps/powerpc/fpu/fegetenv.c5
-rw-r--r--sysdeps/powerpc/fpu/fenv_libc.h4
-rw-r--r--sysdeps/powerpc/fpu/fesetenv.c5
-rw-r--r--sysdeps/powerpc/fpu/feupdateenv.c5
-rw-r--r--sysdeps/powerpc/fpu/fgetexcptflg.c5
-rw-r--r--sysdeps/powerpc/fpu/fpu_control.h81
-rw-r--r--sysdeps/powerpc/fpu/fraiseexcpt.c5
-rw-r--r--sysdeps/powerpc/fpu/fsetexcptflg.c5
-rw-r--r--sysdeps/powerpc/fpu/libm-test-ulps6
-rw-r--r--sysdeps/powerpc/fpu/math_ldbl.h171
-rw-r--r--sysdeps/powerpc/fpu/s_llround.c4
-rw-r--r--sysdeps/powerpc/fpu/test-powerpc-snan.c382
-rw-r--r--sysdeps/powerpc/fpu/w_sqrt.c4
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