| Submitter | Matthew McClintock |
|---|---|
| Date | Sept. 18, 2012, 10:08 p.m. |
| Message ID | <1348006091-14992-1-git-send-email-msm@freescale.com> |
| Download | mbox | patch |
| Permalink | /patch/36855/ |
| State | New |
| Headers | show |
Comments
Err this was supposed to be a series but I used the wrong format-patch commands, patches in my tree here: http://git.yoctoproject.org/cgit/cgit.cgi/poky-contrib/log/?h=mattsm/master -M On Tue, Sep 18, 2012 at 5:08 PM, Matthew McClintock <msm@freescale.com> wrote: > Signed-off-by: Matthew McClintock <msm@freescale.com> > --- > .../eglibc/eglibc-2.16/glibc.fix_sqrt2.patch | 1488 ++++++++++++++++++++ > .../recipes-core/eglibc/eglibc-2.16/ppc-sqrt.patch | 538 ------- > meta/recipes-core/eglibc/eglibc_2.16.bb | 4 +- > 3 files changed, 1490 insertions(+), 540 deletions(-) > create mode 100644 meta/recipes-core/eglibc/eglibc-2.16/glibc.fix_sqrt2.patch > delete mode 100644 meta/recipes-core/eglibc/eglibc-2.16/ppc-sqrt.patch > > diff --git a/meta/recipes-core/eglibc/eglibc-2.16/glibc.fix_sqrt2.patch b/meta/recipes-core/eglibc/eglibc-2.16/glibc.fix_sqrt2.patch > new file mode 100644 > index 0000000..e098192 > --- /dev/null > +++ b/meta/recipes-core/eglibc/eglibc-2.16/glibc.fix_sqrt2.patch > @@ -0,0 +1,1488 @@ > +diff -ruN libc-orig/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c > +--- libc-orig/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c 1969-12-31 18:00:00.000000000 -0600 > ++++ libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c 2012-06-14 14:51:50.452001745 -0500 > +@@ -0,0 +1,134 @@ > ++/* Double-precision floating point square root. > ++ Copyright (C) 2010 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. */ > ++ > ++#include <math.h> > ++#include <math_private.h> > ++#include <fenv_libc.h> > ++#include <inttypes.h> > ++ > ++#include <sysdep.h> > ++#include <ldsodefs.h> > ++ > ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; > ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; > ++static const float two108 = 3.245185536584267269e+32; > ++static const float twom54 = 5.551115123125782702e-17; > ++static const float half = 0.5; > ++ > ++/* The method is based on the descriptions in: > ++ > ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; > ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 > ++ > ++ We find the actual square root and half of its reciprocal > ++ simultaneously. */ > ++ > ++#ifdef __STDC__ > ++double > ++__ieee754_sqrt (double b) > ++#else > ++double > ++__ieee754_sqrt (b) > ++ double b; > ++#endif > ++{ > ++ if (__builtin_expect (b > 0, 1)) > ++ { > ++ double y, g, h, d, r; > ++ ieee_double_shape_type u; > ++ > ++ if (__builtin_expect (b != a_inf.value, 1)) > ++ { > ++ fenv_t fe; > ++ > ++ fe = fegetenv_register (); > ++ > ++ u.value = b; > ++ > ++ relax_fenv_state (); > ++ > ++ __asm__ ("frsqrte %[estimate], %[x]\n" > ++ : [estimate] "=f" (y) : [x] "f" (b)); > ++ > ++ /* Following Muller et al, page 168, equation 5.20. > ++ > ++ h goes to 1/(2*sqrt(b)) > ++ g goes to sqrt(b). > ++ > ++ We need three iterations to get within 1ulp. */ > ++ > ++ /* Indicate that these can be performed prior to the branch. GCC > ++ insists on sinking them below the branch, however; it seems like > ++ they'd be better before the branch so that we can cover any latency > ++ from storing the argument and loading its high word. Oh well. */ > ++ > ++ g = b * y; > ++ h = 0.5 * y; > ++ > ++ /* Handle small numbers by scaling. */ > ++ if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0)) > ++ return __ieee754_sqrt (b * two108) * twom54; > ++ > ++#define FMADD(a_, c_, b_) \ > ++ ({ double __r; \ > ++ __asm__ ("fmadd %[r], %[a], %[c], %[b]\n" \ > ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ > ++ __r;}) > ++#define FNMSUB(a_, c_, b_) \ > ++ ({ double __r; \ > ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ > ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ > ++ __r;}) > ++ > ++ r = FNMSUB (g, h, half); > ++ g = FMADD (g, r, g); > ++ h = FMADD (h, r, h); > ++ > ++ r = FNMSUB (g, h, half); > ++ g = FMADD (g, r, g); > ++ h = FMADD (h, r, h); > ++ > ++ r = FNMSUB (g, h, half); > ++ g = FMADD (g, r, g); > ++ h = FMADD (h, r, h); > ++ > ++ /* g is now +/- 1ulp, or exactly equal to, the square root of b. */ > ++ > ++ /* Final refinement. */ > ++ d = FNMSUB (g, g, b); > ++ > ++ fesetenv_register (fe); > ++ return FMADD (d, h, g); > ++ } > ++ } > ++ else if (b < 0) > ++ { > ++ /* For some reason, some PowerPC32 processors don't implement > ++ FE_INVALID_SQRT. */ > ++#ifdef FE_INVALID_SQRT > ++ feraiseexcept (FE_INVALID_SQRT); > ++ > ++ fenv_union_t u = { .fenv = fegetenv_register () }; > ++ if ((u.l[1] & FE_INVALID) == 0) > ++#endif > ++ feraiseexcept (FE_INVALID); > ++ b = a_nan.value; > ++ } > ++ return f_wash (b); > ++} > +diff -ruN libc-orig/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c > +--- libc-orig/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c 1969-12-31 18:00:00.000000000 -0600 > ++++ libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c 2012-06-14 14:51:50.452001745 -0500 > +@@ -0,0 +1,101 @@ > ++/* Single-precision floating point square root. > ++ Copyright (C) 2010 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. */ > ++ > ++#include <math.h> > ++#include <math_private.h> > ++#include <fenv_libc.h> > ++#include <inttypes.h> > ++ > ++#include <sysdep.h> > ++#include <ldsodefs.h> > ++ > ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; > ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; > ++static const float threehalf = 1.5; > ++ > ++/* The method is based on the descriptions in: > ++ > ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; > ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 > ++ > ++ We find the reciprocal square root and use that to compute the actual > ++ square root. */ > ++ > ++#ifdef __STDC__ > ++float > ++__ieee754_sqrtf (float b) > ++#else > ++float > ++__ieee754_sqrtf (b) > ++ float b; > ++#endif > ++{ > ++ if (__builtin_expect (b > 0, 1)) > ++ { > ++#define FMSUB(a_, c_, b_) \ > ++ ({ double __r; \ > ++ __asm__ ("fmsub %[r], %[a], %[c], %[b]\n" \ > ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ > ++ __r;}) > ++#define FNMSUB(a_, c_, b_) \ > ++ ({ double __r; \ > ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ > ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ > ++ __r;}) > ++ > ++ if (__builtin_expect (b != a_inf.value, 1)) > ++ { > ++ double y, x; > ++ fenv_t fe; > ++ > ++ fe = fegetenv_register (); > ++ > ++ relax_fenv_state (); > ++ > ++ /* Compute y = 1.5 * b - b. Uses fewer constants than y = 0.5 * b. */ > ++ y = FMSUB (threehalf, b, b); > ++ > ++ /* Initial estimate. */ > ++ __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b)); > ++ > ++ /* Iterate. x_{n+1} = x_n * (1.5 - y * (x_n * x_n)). */ > ++ x = x * FNMSUB (y, x * x, threehalf); > ++ x = x * FNMSUB (y, x * x, threehalf); > ++ x = x * FNMSUB (y, x * x, threehalf); > ++ > ++ /* All done. */ > ++ fesetenv_register (fe); > ++ return x * b; > ++ } > ++ } > ++ else if (b < 0) > ++ { > ++ /* For some reason, some PowerPC32 processors don't implement > ++ FE_INVALID_SQRT. */ > ++#ifdef FE_INVALID_SQRT > ++ feraiseexcept (FE_INVALID_SQRT); > ++ > ++ fenv_union_t u = { .fenv = fegetenv_register () }; > ++ if ((u.l[1] & FE_INVALID) == 0) > ++#endif > ++ feraiseexcept (FE_INVALID); > ++ b = a_nan.value; > ++ } > ++ return f_washf (b); > ++} > +diff -ruN libc-orig/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c libc/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c > +--- libc-orig/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c 1969-12-31 18:00:00.000000000 -0600 > ++++ libc/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c 2012-06-14 14:55:14.749001061 -0500 > +@@ -0,0 +1,134 @@ > ++/* Double-precision floating point square root. > ++ Copyright (C) 2010 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. */ > ++ > ++#include <math.h> > ++#include <math_private.h> > ++#include <fenv_libc.h> > ++#include <inttypes.h> > ++ > ++#include <sysdep.h> > ++#include <ldsodefs.h> > ++ > ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; > ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; > ++static const float two108 = 3.245185536584267269e+32; > ++static const float twom54 = 5.551115123125782702e-17; > ++static const float half = 0.5; > ++ > ++/* The method is based on the descriptions in: > ++ > ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; > ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 > ++ > ++ We find the actual square root and half of its reciprocal > ++ simultaneously. */ > ++ > ++#ifdef __STDC__ > ++double > ++__ieee754_sqrt (double b) > ++#else > ++double > ++__ieee754_sqrt (b) > ++ double b; > ++#endif > ++{ > ++ if (__builtin_expect (b > 0, 1)) > ++ { > ++ double y, g, h, d, r; > ++ ieee_double_shape_type u; > ++ > ++ if (__builtin_expect (b != a_inf.value, 1)) > ++ { > ++ fenv_t fe; > ++ > ++ fe = fegetenv_register (); > ++ > ++ u.value = b; > ++ > ++ relax_fenv_state (); > ++ > ++ __asm__ ("frsqrte %[estimate], %[x]\n" > ++ : [estimate] "=f" (y) : [x] "f" (b)); > ++ > ++ /* Following Muller et al, page 168, equation 5.20. > ++ > ++ h goes to 1/(2*sqrt(b)) > ++ g goes to sqrt(b). > ++ > ++ We need three iterations to get within 1ulp. */ > ++ > ++ /* Indicate that these can be performed prior to the branch. GCC > ++ insists on sinking them below the branch, however; it seems like > ++ they'd be better before the branch so that we can cover any latency > ++ from storing the argument and loading its high word. Oh well. */ > ++ > ++ g = b * y; > ++ h = 0.5 * y; > ++ > ++ /* Handle small numbers by scaling. */ > ++ if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0)) > ++ return __ieee754_sqrt (b * two108) * twom54; > ++ > ++#define FMADD(a_, c_, b_) \ > ++ ({ double __r; \ > ++ __asm__ ("fmadd %[r], %[a], %[c], %[b]\n" \ > ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ > ++ __r;}) > ++#define FNMSUB(a_, c_, b_) \ > ++ ({ double __r; \ > ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ > ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ > ++ __r;}) > ++ > ++ r = FNMSUB (g, h, half); > ++ g = FMADD (g, r, g); > ++ h = FMADD (h, r, h); > ++ > ++ r = FNMSUB (g, h, half); > ++ g = FMADD (g, r, g); > ++ h = FMADD (h, r, h); > ++ > ++ r = FNMSUB (g, h, half); > ++ g = FMADD (g, r, g); > ++ h = FMADD (h, r, h); > ++ > ++ /* g is now +/- 1ulp, or exactly equal to, the square root of b. */ > ++ > ++ /* Final refinement. */ > ++ d = FNMSUB (g, g, b); > ++ > ++ fesetenv_register (fe); > ++ return FMADD (d, h, g); > ++ } > ++ } > ++ else if (b < 0) > ++ { > ++ /* For some reason, some PowerPC32 processors don't implement > ++ FE_INVALID_SQRT. */ > ++#ifdef FE_INVALID_SQRT > ++ feraiseexcept (FE_INVALID_SQRT); > ++ > ++ fenv_union_t u = { .fenv = fegetenv_register () }; > ++ if ((u.l[1] & FE_INVALID) == 0) > ++#endif > ++ feraiseexcept (FE_INVALID); > ++ b = a_nan.value; > ++ } > ++ return f_wash (b); > ++} > +diff -ruN libc-orig/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c libc/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c > +--- libc-orig/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c 1969-12-31 18:00:00.000000000 -0600 > ++++ libc/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c 2012-06-14 14:55:14.749001061 -0500 > +@@ -0,0 +1,101 @@ > ++/* Single-precision floating point square root. > ++ Copyright (C) 2010 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. */ > ++ > ++#include <math.h> > ++#include <math_private.h> > ++#include <fenv_libc.h> > ++#include <inttypes.h> > ++ > ++#include <sysdep.h> > ++#include <ldsodefs.h> > ++ > ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; > ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; > ++static const float threehalf = 1.5; > ++ > ++/* The method is based on the descriptions in: > ++ > ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; > ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 > ++ > ++ We find the reciprocal square root and use that to compute the actual > ++ square root. */ > ++ > ++#ifdef __STDC__ > ++float > ++__ieee754_sqrtf (float b) > ++#else > ++float > ++__ieee754_sqrtf (b) > ++ float b; > ++#endif > ++{ > ++ if (__builtin_expect (b > 0, 1)) > ++ { > ++#define FMSUB(a_, c_, b_) \ > ++ ({ double __r; \ > ++ __asm__ ("fmsub %[r], %[a], %[c], %[b]\n" \ > ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ > ++ __r;}) > ++#define FNMSUB(a_, c_, b_) \ > ++ ({ double __r; \ > ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ > ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ > ++ __r;}) > ++ > ++ if (__builtin_expect (b != a_inf.value, 1)) > ++ { > ++ double y, x; > ++ fenv_t fe; > ++ > ++ fe = fegetenv_register (); > ++ > ++ relax_fenv_state (); > ++ > ++ /* Compute y = 1.5 * b - b. Uses fewer constants than y = 0.5 * b. */ > ++ y = FMSUB (threehalf, b, b); > ++ > ++ /* Initial estimate. */ > ++ __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b)); > ++ > ++ /* Iterate. x_{n+1} = x_n * (1.5 - y * (x_n * x_n)). */ > ++ x = x * FNMSUB (y, x * x, threehalf); > ++ x = x * FNMSUB (y, x * x, threehalf); > ++ x = x * FNMSUB (y, x * x, threehalf); > ++ > ++ /* All done. */ > ++ fesetenv_register (fe); > ++ return x * b; > ++ } > ++ } > ++ else if (b < 0) > ++ { > ++ /* For some reason, some PowerPC32 processors don't implement > ++ FE_INVALID_SQRT. */ > ++#ifdef FE_INVALID_SQRT > ++ feraiseexcept (FE_INVALID_SQRT); > ++ > ++ fenv_union_t u = { .fenv = fegetenv_register () }; > ++ if ((u.l[1] & FE_INVALID) == 0) > ++#endif > ++ feraiseexcept (FE_INVALID); > ++ b = a_nan.value; > ++ } > ++ return f_washf (b); > ++} > +diff -ruN libc-orig/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c libc/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c > +--- libc-orig/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c 1969-12-31 18:00:00.000000000 -0600 > ++++ libc/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c 2012-06-14 14:55:21.812002270 -0500 > +@@ -0,0 +1,134 @@ > ++/* Double-precision floating point square root. > ++ Copyright (C) 2010 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. */ > ++ > ++#include <math.h> > ++#include <math_private.h> > ++#include <fenv_libc.h> > ++#include <inttypes.h> > ++ > ++#include <sysdep.h> > ++#include <ldsodefs.h> > ++ > ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; > ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; > ++static const float two108 = 3.245185536584267269e+32; > ++static const float twom54 = 5.551115123125782702e-17; > ++static const float half = 0.5; > ++ > ++/* The method is based on the descriptions in: > ++ > ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; > ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 > ++ > ++ We find the actual square root and half of its reciprocal > ++ simultaneously. */ > ++ > ++#ifdef __STDC__ > ++double > ++__ieee754_sqrt (double b) > ++#else > ++double > ++__ieee754_sqrt (b) > ++ double b; > ++#endif > ++{ > ++ if (__builtin_expect (b > 0, 1)) > ++ { > ++ double y, g, h, d, r; > ++ ieee_double_shape_type u; > ++ > ++ if (__builtin_expect (b != a_inf.value, 1)) > ++ { > ++ fenv_t fe; > ++ > ++ fe = fegetenv_register (); > ++ > ++ u.value = b; > ++ > ++ relax_fenv_state (); > ++ > ++ __asm__ ("frsqrte %[estimate], %[x]\n" > ++ : [estimate] "=f" (y) : [x] "f" (b)); > ++ > ++ /* Following Muller et al, page 168, equation 5.20. > ++ > ++ h goes to 1/(2*sqrt(b)) > ++ g goes to sqrt(b). > ++ > ++ We need three iterations to get within 1ulp. */ > ++ > ++ /* Indicate that these can be performed prior to the branch. GCC > ++ insists on sinking them below the branch, however; it seems like > ++ they'd be better before the branch so that we can cover any latency > ++ from storing the argument and loading its high word. Oh well. */ > ++ > ++ g = b * y; > ++ h = 0.5 * y; > ++ > ++ /* Handle small numbers by scaling. */ > ++ if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0)) > ++ return __ieee754_sqrt (b * two108) * twom54; > ++ > ++#define FMADD(a_, c_, b_) \ > ++ ({ double __r; \ > ++ __asm__ ("fmadd %[r], %[a], %[c], %[b]\n" \ > ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ > ++ __r;}) > ++#define FNMSUB(a_, c_, b_) \ > ++ ({ double __r; \ > ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ > ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ > ++ __r;}) > ++ > ++ r = FNMSUB (g, h, half); > ++ g = FMADD (g, r, g); > ++ h = FMADD (h, r, h); > ++ > ++ r = FNMSUB (g, h, half); > ++ g = FMADD (g, r, g); > ++ h = FMADD (h, r, h); > ++ > ++ r = FNMSUB (g, h, half); > ++ g = FMADD (g, r, g); > ++ h = FMADD (h, r, h); > ++ > ++ /* g is now +/- 1ulp, or exactly equal to, the square root of b. */ > ++ > ++ /* Final refinement. */ > ++ d = FNMSUB (g, g, b); > ++ > ++ fesetenv_register (fe); > ++ return FMADD (d, h, g); > ++ } > ++ } > ++ else if (b < 0) > ++ { > ++ /* For some reason, some PowerPC32 processors don't implement > ++ FE_INVALID_SQRT. */ > ++#ifdef FE_INVALID_SQRT > ++ feraiseexcept (FE_INVALID_SQRT); > ++ > ++ fenv_union_t u = { .fenv = fegetenv_register () }; > ++ if ((u.l[1] & FE_INVALID) == 0) > ++#endif > ++ feraiseexcept (FE_INVALID); > ++ b = a_nan.value; > ++ } > ++ return f_wash (b); > ++} > +diff -ruN libc-orig/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c libc/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c > +--- libc-orig/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c 1969-12-31 18:00:00.000000000 -0600 > ++++ libc/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c 2012-06-14 14:55:21.812002270 -0500 > +@@ -0,0 +1,101 @@ > ++/* Single-precision floating point square root. > ++ Copyright (C) 2010 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. */ > ++ > ++#include <math.h> > ++#include <math_private.h> > ++#include <fenv_libc.h> > ++#include <inttypes.h> > ++ > ++#include <sysdep.h> > ++#include <ldsodefs.h> > ++ > ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; > ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; > ++static const float threehalf = 1.5; > ++ > ++/* The method is based on the descriptions in: > ++ > ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; > ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 > ++ > ++ We find the reciprocal square root and use that to compute the actual > ++ square root. */ > ++ > ++#ifdef __STDC__ > ++float > ++__ieee754_sqrtf (float b) > ++#else > ++float > ++__ieee754_sqrtf (b) > ++ float b; > ++#endif > ++{ > ++ if (__builtin_expect (b > 0, 1)) > ++ { > ++#define FMSUB(a_, c_, b_) \ > ++ ({ double __r; \ > ++ __asm__ ("fmsub %[r], %[a], %[c], %[b]\n" \ > ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ > ++ __r;}) > ++#define FNMSUB(a_, c_, b_) \ > ++ ({ double __r; \ > ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ > ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ > ++ __r;}) > ++ > ++ if (__builtin_expect (b != a_inf.value, 1)) > ++ { > ++ double y, x; > ++ fenv_t fe; > ++ > ++ fe = fegetenv_register (); > ++ > ++ relax_fenv_state (); > ++ > ++ /* Compute y = 1.5 * b - b. Uses fewer constants than y = 0.5 * b. */ > ++ y = FMSUB (threehalf, b, b); > ++ > ++ /* Initial estimate. */ > ++ __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b)); > ++ > ++ /* Iterate. x_{n+1} = x_n * (1.5 - y * (x_n * x_n)). */ > ++ x = x * FNMSUB (y, x * x, threehalf); > ++ x = x * FNMSUB (y, x * x, threehalf); > ++ x = x * FNMSUB (y, x * x, threehalf); > ++ > ++ /* All done. */ > ++ fesetenv_register (fe); > ++ return x * b; > ++ } > ++ } > ++ else if (b < 0) > ++ { > ++ /* For some reason, some PowerPC32 processors don't implement > ++ FE_INVALID_SQRT. */ > ++#ifdef FE_INVALID_SQRT > ++ feraiseexcept (FE_INVALID_SQRT); > ++ > ++ fenv_union_t u = { .fenv = fegetenv_register () }; > ++ if ((u.l[1] & FE_INVALID) == 0) > ++#endif > ++ feraiseexcept (FE_INVALID); > ++ b = a_nan.value; > ++ } > ++ return f_washf (b); > ++} > +diff -ruN libc-orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c > +--- libc-orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c 1969-12-31 18:00:00.000000000 -0600 > ++++ libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c 2012-06-14 14:55:24.620001266 -0500 > +@@ -0,0 +1,134 @@ > ++/* Double-precision floating point square root. > ++ Copyright (C) 2010 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. */ > ++ > ++#include <math.h> > ++#include <math_private.h> > ++#include <fenv_libc.h> > ++#include <inttypes.h> > ++ > ++#include <sysdep.h> > ++#include <ldsodefs.h> > ++ > ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; > ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; > ++static const float two108 = 3.245185536584267269e+32; > ++static const float twom54 = 5.551115123125782702e-17; > ++static const float half = 0.5; > ++ > ++/* The method is based on the descriptions in: > ++ > ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; > ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 > ++ > ++ We find the actual square root and half of its reciprocal > ++ simultaneously. */ > ++ > ++#ifdef __STDC__ > ++double > ++__ieee754_sqrt (double b) > ++#else > ++double > ++__ieee754_sqrt (b) > ++ double b; > ++#endif > ++{ > ++ if (__builtin_expect (b > 0, 1)) > ++ { > ++ double y, g, h, d, r; > ++ ieee_double_shape_type u; > ++ > ++ if (__builtin_expect (b != a_inf.value, 1)) > ++ { > ++ fenv_t fe; > ++ > ++ fe = fegetenv_register (); > ++ > ++ u.value = b; > ++ > ++ relax_fenv_state (); > ++ > ++ __asm__ ("frsqrte %[estimate], %[x]\n" > ++ : [estimate] "=f" (y) : [x] "f" (b)); > ++ > ++ /* Following Muller et al, page 168, equation 5.20. > ++ > ++ h goes to 1/(2*sqrt(b)) > ++ g goes to sqrt(b). > ++ > ++ We need three iterations to get within 1ulp. */ > ++ > ++ /* Indicate that these can be performed prior to the branch. GCC > ++ insists on sinking them below the branch, however; it seems like > ++ they'd be better before the branch so that we can cover any latency > ++ from storing the argument and loading its high word. Oh well. */ > ++ > ++ g = b * y; > ++ h = 0.5 * y; > ++ > ++ /* Handle small numbers by scaling. */ > ++ if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0)) > ++ return __ieee754_sqrt (b * two108) * twom54; > ++ > ++#define FMADD(a_, c_, b_) \ > ++ ({ double __r; \ > ++ __asm__ ("fmadd %[r], %[a], %[c], %[b]\n" \ > ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ > ++ __r;}) > ++#define FNMSUB(a_, c_, b_) \ > ++ ({ double __r; \ > ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ > ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ > ++ __r;}) > ++ > ++ r = FNMSUB (g, h, half); > ++ g = FMADD (g, r, g); > ++ h = FMADD (h, r, h); > ++ > ++ r = FNMSUB (g, h, half); > ++ g = FMADD (g, r, g); > ++ h = FMADD (h, r, h); > ++ > ++ r = FNMSUB (g, h, half); > ++ g = FMADD (g, r, g); > ++ h = FMADD (h, r, h); > ++ > ++ /* g is now +/- 1ulp, or exactly equal to, the square root of b. */ > ++ > ++ /* Final refinement. */ > ++ d = FNMSUB (g, g, b); > ++ > ++ fesetenv_register (fe); > ++ return FMADD (d, h, g); > ++ } > ++ } > ++ else if (b < 0) > ++ { > ++ /* For some reason, some PowerPC32 processors don't implement > ++ FE_INVALID_SQRT. */ > ++#ifdef FE_INVALID_SQRT > ++ feraiseexcept (FE_INVALID_SQRT); > ++ > ++ fenv_union_t u = { .fenv = fegetenv_register () }; > ++ if ((u.l[1] & FE_INVALID) == 0) > ++#endif > ++ feraiseexcept (FE_INVALID); > ++ b = a_nan.value; > ++ } > ++ return f_wash (b); > ++} > +diff -ruN libc-orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c > +--- libc-orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c 1969-12-31 18:00:00.000000000 -0600 > ++++ libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c 2012-06-14 14:55:24.620001266 -0500 > +@@ -0,0 +1,101 @@ > ++/* Single-precision floating point square root. > ++ Copyright (C) 2010 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. */ > ++ > ++#include <math.h> > ++#include <math_private.h> > ++#include <fenv_libc.h> > ++#include <inttypes.h> > ++ > ++#include <sysdep.h> > ++#include <ldsodefs.h> > ++ > ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; > ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; > ++static const float threehalf = 1.5; > ++ > ++/* The method is based on the descriptions in: > ++ > ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; > ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 > ++ > ++ We find the reciprocal square root and use that to compute the actual > ++ square root. */ > ++ > ++#ifdef __STDC__ > ++float > ++__ieee754_sqrtf (float b) > ++#else > ++float > ++__ieee754_sqrtf (b) > ++ float b; > ++#endif > ++{ > ++ if (__builtin_expect (b > 0, 1)) > ++ { > ++#define FMSUB(a_, c_, b_) \ > ++ ({ double __r; \ > ++ __asm__ ("fmsub %[r], %[a], %[c], %[b]\n" \ > ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ > ++ __r;}) > ++#define FNMSUB(a_, c_, b_) \ > ++ ({ double __r; \ > ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ > ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ > ++ __r;}) > ++ > ++ if (__builtin_expect (b != a_inf.value, 1)) > ++ { > ++ double y, x; > ++ fenv_t fe; > ++ > ++ fe = fegetenv_register (); > ++ > ++ relax_fenv_state (); > ++ > ++ /* Compute y = 1.5 * b - b. Uses fewer constants than y = 0.5 * b. */ > ++ y = FMSUB (threehalf, b, b); > ++ > ++ /* Initial estimate. */ > ++ __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b)); > ++ > ++ /* Iterate. x_{n+1} = x_n * (1.5 - y * (x_n * x_n)). */ > ++ x = x * FNMSUB (y, x * x, threehalf); > ++ x = x * FNMSUB (y, x * x, threehalf); > ++ x = x * FNMSUB (y, x * x, threehalf); > ++ > ++ /* All done. */ > ++ fesetenv_register (fe); > ++ return x * b; > ++ } > ++ } > ++ else if (b < 0) > ++ { > ++ /* For some reason, some PowerPC32 processors don't implement > ++ FE_INVALID_SQRT. */ > ++#ifdef FE_INVALID_SQRT > ++ feraiseexcept (FE_INVALID_SQRT); > ++ > ++ fenv_union_t u = { .fenv = fegetenv_register () }; > ++ if ((u.l[1] & FE_INVALID) == 0) > ++#endif > ++ feraiseexcept (FE_INVALID); > ++ b = a_nan.value; > ++ } > ++ return f_washf (b); > ++} > +diff -ruN libc-orig/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c > +--- libc-orig/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c 1969-12-31 18:00:00.000000000 -0600 > ++++ libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c 2012-06-14 14:51:50.452001745 -0500 > +@@ -0,0 +1,134 @@ > ++/* Double-precision floating point square root. > ++ Copyright (C) 2010 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. */ > ++ > ++#include <math.h> > ++#include <math_private.h> > ++#include <fenv_libc.h> > ++#include <inttypes.h> > ++ > ++#include <sysdep.h> > ++#include <ldsodefs.h> > ++ > ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; > ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; > ++static const float two108 = 3.245185536584267269e+32; > ++static const float twom54 = 5.551115123125782702e-17; > ++static const float half = 0.5; > ++ > ++/* The method is based on the descriptions in: > ++ > ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; > ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 > ++ > ++ We find the actual square root and half of its reciprocal > ++ simultaneously. */ > ++ > ++#ifdef __STDC__ > ++double > ++__ieee754_sqrt (double b) > ++#else > ++double > ++__ieee754_sqrt (b) > ++ double b; > ++#endif > ++{ > ++ if (__builtin_expect (b > 0, 1)) > ++ { > ++ double y, g, h, d, r; > ++ ieee_double_shape_type u; > ++ > ++ if (__builtin_expect (b != a_inf.value, 1)) > ++ { > ++ fenv_t fe; > ++ > ++ fe = fegetenv_register (); > ++ > ++ u.value = b; > ++ > ++ relax_fenv_state (); > ++ > ++ __asm__ ("frsqrte %[estimate], %[x]\n" > ++ : [estimate] "=f" (y) : [x] "f" (b)); > ++ > ++ /* Following Muller et al, page 168, equation 5.20. > ++ > ++ h goes to 1/(2*sqrt(b)) > ++ g goes to sqrt(b). > ++ > ++ We need three iterations to get within 1ulp. */ > ++ > ++ /* Indicate that these can be performed prior to the branch. GCC > ++ insists on sinking them below the branch, however; it seems like > ++ they'd be better before the branch so that we can cover any latency > ++ from storing the argument and loading its high word. Oh well. */ > ++ > ++ g = b * y; > ++ h = 0.5 * y; > ++ > ++ /* Handle small numbers by scaling. */ > ++ if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0)) > ++ return __ieee754_sqrt (b * two108) * twom54; > ++ > ++#define FMADD(a_, c_, b_) \ > ++ ({ double __r; \ > ++ __asm__ ("fmadd %[r], %[a], %[c], %[b]\n" \ > ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ > ++ __r;}) > ++#define FNMSUB(a_, c_, b_) \ > ++ ({ double __r; \ > ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ > ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ > ++ __r;}) > ++ > ++ r = FNMSUB (g, h, half); > ++ g = FMADD (g, r, g); > ++ h = FMADD (h, r, h); > ++ > ++ r = FNMSUB (g, h, half); > ++ g = FMADD (g, r, g); > ++ h = FMADD (h, r, h); > ++ > ++ r = FNMSUB (g, h, half); > ++ g = FMADD (g, r, g); > ++ h = FMADD (h, r, h); > ++ > ++ /* g is now +/- 1ulp, or exactly equal to, the square root of b. */ > ++ > ++ /* Final refinement. */ > ++ d = FNMSUB (g, g, b); > ++ > ++ fesetenv_register (fe); > ++ return FMADD (d, h, g); > ++ } > ++ } > ++ else if (b < 0) > ++ { > ++ /* For some reason, some PowerPC32 processors don't implement > ++ FE_INVALID_SQRT. */ > ++#ifdef FE_INVALID_SQRT > ++ feraiseexcept (FE_INVALID_SQRT); > ++ > ++ fenv_union_t u = { .fenv = fegetenv_register () }; > ++ if ((u.l[1] & FE_INVALID) == 0) > ++#endif > ++ feraiseexcept (FE_INVALID); > ++ b = a_nan.value; > ++ } > ++ return f_wash (b); > ++} > +diff -ruN libc-orig/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c > +--- libc-orig/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c 1969-12-31 18:00:00.000000000 -0600 > ++++ libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c 2012-06-14 14:51:50.452001745 -0500 > +@@ -0,0 +1,101 @@ > ++/* Single-precision floating point square root. > ++ Copyright (C) 2010 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. */ > ++ > ++#include <math.h> > ++#include <math_private.h> > ++#include <fenv_libc.h> > ++#include <inttypes.h> > ++ > ++#include <sysdep.h> > ++#include <ldsodefs.h> > ++ > ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; > ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; > ++static const float threehalf = 1.5; > ++ > ++/* The method is based on the descriptions in: > ++ > ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; > ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 > ++ > ++ We find the reciprocal square root and use that to compute the actual > ++ square root. */ > ++ > ++#ifdef __STDC__ > ++float > ++__ieee754_sqrtf (float b) > ++#else > ++float > ++__ieee754_sqrtf (b) > ++ float b; > ++#endif > ++{ > ++ if (__builtin_expect (b > 0, 1)) > ++ { > ++#define FMSUB(a_, c_, b_) \ > ++ ({ double __r; \ > ++ __asm__ ("fmsub %[r], %[a], %[c], %[b]\n" \ > ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ > ++ __r;}) > ++#define FNMSUB(a_, c_, b_) \ > ++ ({ double __r; \ > ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ > ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ > ++ __r;}) > ++ > ++ if (__builtin_expect (b != a_inf.value, 1)) > ++ { > ++ double y, x; > ++ fenv_t fe; > ++ > ++ fe = fegetenv_register (); > ++ > ++ relax_fenv_state (); > ++ > ++ /* Compute y = 1.5 * b - b. Uses fewer constants than y = 0.5 * b. */ > ++ y = FMSUB (threehalf, b, b); > ++ > ++ /* Initial estimate. */ > ++ __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b)); > ++ > ++ /* Iterate. x_{n+1} = x_n * (1.5 - y * (x_n * x_n)). */ > ++ x = x * FNMSUB (y, x * x, threehalf); > ++ x = x * FNMSUB (y, x * x, threehalf); > ++ x = x * FNMSUB (y, x * x, threehalf); > ++ > ++ /* All done. */ > ++ fesetenv_register (fe); > ++ return x * b; > ++ } > ++ } > ++ else if (b < 0) > ++ { > ++ /* For some reason, some PowerPC32 processors don't implement > ++ FE_INVALID_SQRT. */ > ++#ifdef FE_INVALID_SQRT > ++ feraiseexcept (FE_INVALID_SQRT); > ++ > ++ fenv_union_t u = { .fenv = fegetenv_register () }; > ++ if ((u.l[1] & FE_INVALID) == 0) > ++#endif > ++ feraiseexcept (FE_INVALID); > ++ b = a_nan.value; > ++ } > ++ return f_washf (b); > ++} > +diff -ruN libc-orig/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c libc/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c > +--- libc-orig/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c 1969-12-31 18:00:00.000000000 -0600 > ++++ libc/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c 2012-06-14 14:56:02.080000985 -0500 > +@@ -0,0 +1,134 @@ > ++/* Double-precision floating point square root. > ++ Copyright (C) 2010 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. */ > ++ > ++#include <math.h> > ++#include <math_private.h> > ++#include <fenv_libc.h> > ++#include <inttypes.h> > ++ > ++#include <sysdep.h> > ++#include <ldsodefs.h> > ++ > ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; > ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; > ++static const float two108 = 3.245185536584267269e+32; > ++static const float twom54 = 5.551115123125782702e-17; > ++static const float half = 0.5; > ++ > ++/* The method is based on the descriptions in: > ++ > ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; > ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 > ++ > ++ We find the actual square root and half of its reciprocal > ++ simultaneously. */ > ++ > ++#ifdef __STDC__ > ++double > ++__ieee754_sqrt (double b) > ++#else > ++double > ++__ieee754_sqrt (b) > ++ double b; > ++#endif > ++{ > ++ if (__builtin_expect (b > 0, 1)) > ++ { > ++ double y, g, h, d, r; > ++ ieee_double_shape_type u; > ++ > ++ if (__builtin_expect (b != a_inf.value, 1)) > ++ { > ++ fenv_t fe; > ++ > ++ fe = fegetenv_register (); > ++ > ++ u.value = b; > ++ > ++ relax_fenv_state (); > ++ > ++ __asm__ ("frsqrte %[estimate], %[x]\n" > ++ : [estimate] "=f" (y) : [x] "f" (b)); > ++ > ++ /* Following Muller et al, page 168, equation 5.20. > ++ > ++ h goes to 1/(2*sqrt(b)) > ++ g goes to sqrt(b). > ++ > ++ We need three iterations to get within 1ulp. */ > ++ > ++ /* Indicate that these can be performed prior to the branch. GCC > ++ insists on sinking them below the branch, however; it seems like > ++ they'd be better before the branch so that we can cover any latency > ++ from storing the argument and loading its high word. Oh well. */ > ++ > ++ g = b * y; > ++ h = 0.5 * y; > ++ > ++ /* Handle small numbers by scaling. */ > ++ if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0)) > ++ return __ieee754_sqrt (b * two108) * twom54; > ++ > ++#define FMADD(a_, c_, b_) \ > ++ ({ double __r; \ > ++ __asm__ ("fmadd %[r], %[a], %[c], %[b]\n" \ > ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ > ++ __r;}) > ++#define FNMSUB(a_, c_, b_) \ > ++ ({ double __r; \ > ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ > ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ > ++ __r;}) > ++ > ++ r = FNMSUB (g, h, half); > ++ g = FMADD (g, r, g); > ++ h = FMADD (h, r, h); > ++ > ++ r = FNMSUB (g, h, half); > ++ g = FMADD (g, r, g); > ++ h = FMADD (h, r, h); > ++ > ++ r = FNMSUB (g, h, half); > ++ g = FMADD (g, r, g); > ++ h = FMADD (h, r, h); > ++ > ++ /* g is now +/- 1ulp, or exactly equal to, the square root of b. */ > ++ > ++ /* Final refinement. */ > ++ d = FNMSUB (g, g, b); > ++ > ++ fesetenv_register (fe); > ++ return FMADD (d, h, g); > ++ } > ++ } > ++ else if (b < 0) > ++ { > ++ /* For some reason, some PowerPC32 processors don't implement > ++ FE_INVALID_SQRT. */ > ++#ifdef FE_INVALID_SQRT > ++ feraiseexcept (FE_INVALID_SQRT); > ++ > ++ fenv_union_t u = { .fenv = fegetenv_register () }; > ++ if ((u.l[1] & FE_INVALID) == 0) > ++#endif > ++ feraiseexcept (FE_INVALID); > ++ b = a_nan.value; > ++ } > ++ return f_wash (b); > ++} > +diff -ruN libc-orig/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c libc/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c > +--- libc-orig/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c 1969-12-31 18:00:00.000000000 -0600 > ++++ libc/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c 2012-06-14 14:56:02.080000985 -0500 > +@@ -0,0 +1,101 @@ > ++/* Single-precision floating point square root. > ++ Copyright (C) 2010 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. */ > ++ > ++#include <math.h> > ++#include <math_private.h> > ++#include <fenv_libc.h> > ++#include <inttypes.h> > ++ > ++#include <sysdep.h> > ++#include <ldsodefs.h> > ++ > ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; > ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; > ++static const float threehalf = 1.5; > ++ > ++/* The method is based on the descriptions in: > ++ > ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; > ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 > ++ > ++ We find the reciprocal square root and use that to compute the actual > ++ square root. */ > ++ > ++#ifdef __STDC__ > ++float > ++__ieee754_sqrtf (float b) > ++#else > ++float > ++__ieee754_sqrtf (b) > ++ float b; > ++#endif > ++{ > ++ if (__builtin_expect (b > 0, 1)) > ++ { > ++#define FMSUB(a_, c_, b_) \ > ++ ({ double __r; \ > ++ __asm__ ("fmsub %[r], %[a], %[c], %[b]\n" \ > ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ > ++ __r;}) > ++#define FNMSUB(a_, c_, b_) \ > ++ ({ double __r; \ > ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ > ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ > ++ __r;}) > ++ > ++ if (__builtin_expect (b != a_inf.value, 1)) > ++ { > ++ double y, x; > ++ fenv_t fe; > ++ > ++ fe = fegetenv_register (); > ++ > ++ relax_fenv_state (); > ++ > ++ /* Compute y = 1.5 * b - b. Uses fewer constants than y = 0.5 * b. */ > ++ y = FMSUB (threehalf, b, b); > ++ > ++ /* Initial estimate. */ > ++ __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b)); > ++ > ++ /* Iterate. x_{n+1} = x_n * (1.5 - y * (x_n * x_n)). */ > ++ x = x * FNMSUB (y, x * x, threehalf); > ++ x = x * FNMSUB (y, x * x, threehalf); > ++ x = x * FNMSUB (y, x * x, threehalf); > ++ > ++ /* All done. */ > ++ fesetenv_register (fe); > ++ return x * b; > ++ } > ++ } > ++ else if (b < 0) > ++ { > ++ /* For some reason, some PowerPC32 processors don't implement > ++ FE_INVALID_SQRT. */ > ++#ifdef FE_INVALID_SQRT > ++ feraiseexcept (FE_INVALID_SQRT); > ++ > ++ fenv_union_t u = { .fenv = fegetenv_register () }; > ++ if ((u.l[1] & FE_INVALID) == 0) > ++#endif > ++ feraiseexcept (FE_INVALID); > ++ b = a_nan.value; > ++ } > ++ return f_washf (b); > ++} > +diff -ruN libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/603e/fpu/Implies libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/603e/fpu/Implies > +--- libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/603e/fpu/Implies 1969-12-31 18:00:00.000000000 -0600 > ++++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/603e/fpu/Implies 2012-06-14 14:51:50.452001745 -0500 > +@@ -0,0 +1 @@ > ++powerpc/powerpc32/603e/fpu > +diff -ruN libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/e500mc/fpu/Implies libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e500mc/fpu/Implies > +--- libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/e500mc/fpu/Implies 1969-12-31 18:00:00.000000000 -0600 > ++++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e500mc/fpu/Implies 2012-06-14 14:54:00.481000876 -0500 > +@@ -0,0 +1 @@ > ++powerpc/powerpc32/e500mc/fpu > +diff -ruN libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/e5500/fpu/Implies libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e5500/fpu/Implies > +--- libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/e5500/fpu/Implies 1969-12-31 18:00:00.000000000 -0600 > ++++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e5500/fpu/Implies 2012-06-14 14:54:17.000001007 -0500 > +@@ -0,0 +1 @@ > ++powerpc/powerpc32/e5500/fpu > +diff -ruN libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/e6500/fpu/Implies libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e6500/fpu/Implies > +--- libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/e6500/fpu/Implies 1969-12-31 18:00:00.000000000 -0600 > ++++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e6500/fpu/Implies 2012-06-14 14:54:31.054001299 -0500 > +@@ -0,0 +1 @@ > ++powerpc/powerpc32/e6500/fpu > +diff -ruN libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/e5500/fpu/Implies libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/e5500/fpu/Implies > +--- libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/e5500/fpu/Implies 1969-12-31 18:00:00.000000000 -0600 > ++++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/e5500/fpu/Implies 2012-06-14 14:51:50.453001709 -0500 > +@@ -0,0 +1 @@ > ++powerpc/powerpc64/e5500/fpu > +diff -ruN libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/e6500/fpu/Implies libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/e6500/fpu/Implies > +--- libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/e6500/fpu/Implies 1969-12-31 18:00:00.000000000 -0600 > ++++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/e6500/fpu/Implies 2012-06-14 14:58:14.298001288 -0500 > +@@ -0,0 +1 @@ > ++powerpc/powerpc64/e6500/fpu > diff --git a/meta/recipes-core/eglibc/eglibc-2.16/ppc-sqrt.patch b/meta/recipes-core/eglibc/eglibc-2.16/ppc-sqrt.patch > deleted file mode 100644 > index 203040c..0000000 > --- a/meta/recipes-core/eglibc/eglibc-2.16/ppc-sqrt.patch > +++ /dev/null > @@ -1,538 +0,0 @@ > -Upstream-Status: Pending > - > -2011-03-22 Joseph Myers <joseph@codesourcery.com> > - > - Merge from SG++ 2.11: > - > - 2010-10-05 Nathan Froyd <froydnj@codesourcery.com> > - > - Issue #9382 > - > - * sysdeps/powerpc/powerpc32/603e/: New directory. > - * sysdeps/unix/sysv/linux/powerpc/powerpc32/e500mc/: New directory. > - * sysdeps/unix/sysv/linux/powerpc/powerpc32/603e/: New directory. > - * sysdeps/unix/sysv/linux/powerpc/powerpc32/7400/: New directory. > - * sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c: Update. > - * sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c: Update. > - * sysdeps/powerpc/powerpc64/e5500/fpu/Implies: New file. > - > -Index: libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c > -=================================================================== > ---- /dev/null > -+++ libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c > -@@ -0,0 +1,134 @@ > -+/* Double-precision floating point square root. > -+ Copyright (C) 2010 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. */ > -+ > -+#include <math.h> > -+#include <math_private.h> > -+#include <fenv_libc.h> > -+#include <inttypes.h> > -+ > -+#include <sysdep.h> > -+#include <ldsodefs.h> > -+ > -+static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; > -+static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; > -+static const float two108 = 3.245185536584267269e+32; > -+static const float twom54 = 5.551115123125782702e-17; > -+static const float half = 0.5; > -+ > -+/* The method is based on the descriptions in: > -+ > -+ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; > -+ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 > -+ > -+ We find the actual square root and half of its reciprocal > -+ simultaneously. */ > -+ > -+#ifdef __STDC__ > -+double > -+__ieee754_sqrt (double b) > -+#else > -+double > -+__ieee754_sqrt (b) > -+ double b; > -+#endif > -+{ > -+ if (__builtin_expect (b > 0, 1)) > -+ { > -+ double y, g, h, d, r; > -+ ieee_double_shape_type u; > -+ > -+ if (__builtin_expect (b != a_inf.value, 1)) > -+ { > -+ fenv_t fe; > -+ > -+ fe = fegetenv_register (); > -+ > -+ u.value = b; > -+ > -+ relax_fenv_state (); > -+ > -+ __asm__ ("frsqrte %[estimate], %[x]\n" > -+ : [estimate] "=f" (y) : [x] "f" (b)); > -+ > -+ /* Following Muller et al, page 168, equation 5.20. > -+ > -+ h goes to 1/(2*sqrt(b)) > -+ g goes to sqrt(b). > -+ > -+ We need three iterations to get within 1ulp. */ > -+ > -+ /* Indicate that these can be performed prior to the branch. GCC > -+ insists on sinking them below the branch, however; it seems like > -+ they'd be better before the branch so that we can cover any latency > -+ from storing the argument and loading its high word. Oh well. */ > -+ > -+ g = b * y; > -+ h = 0.5 * y; > -+ > -+ /* Handle small numbers by scaling. */ > -+ if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0)) > -+ return __ieee754_sqrt (b * two108) * twom54; > -+ > -+#define FMADD(a_, c_, b_) \ > -+ ({ double __r; \ > -+ __asm__ ("fmadd %[r], %[a], %[c], %[b]\n" \ > -+ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ > -+ __r;}) > -+#define FNMSUB(a_, c_, b_) \ > -+ ({ double __r; \ > -+ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ > -+ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ > -+ __r;}) > -+ > -+ r = FNMSUB (g, h, half); > -+ g = FMADD (g, r, g); > -+ h = FMADD (h, r, h); > -+ > -+ r = FNMSUB (g, h, half); > -+ g = FMADD (g, r, g); > -+ h = FMADD (h, r, h); > -+ > -+ r = FNMSUB (g, h, half); > -+ g = FMADD (g, r, g); > -+ h = FMADD (h, r, h); > -+ > -+ /* g is now +/- 1ulp, or exactly equal to, the square root of b. */ > -+ > -+ /* Final refinement. */ > -+ d = FNMSUB (g, g, b); > -+ > -+ fesetenv_register (fe); > -+ return FMADD (d, h, g); > -+ } > -+ } > -+ else if (b < 0) > -+ { > -+ /* For some reason, some PowerPC32 processors don't implement > -+ FE_INVALID_SQRT. */ > -+#ifdef FE_INVALID_SQRT > -+ feraiseexcept (FE_INVALID_SQRT); > -+ > -+ fenv_union_t u = { .fenv = fegetenv_register () }; > -+ if ((u.l[1] & FE_INVALID) == 0) > -+#endif > -+ feraiseexcept (FE_INVALID); > -+ b = a_nan.value; > -+ } > -+ return f_wash (b); > -+} > -Index: libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c > -=================================================================== > ---- /dev/null > -+++ libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c > -@@ -0,0 +1,101 @@ > -+/* Single-precision floating point square root. > -+ Copyright (C) 2010 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. */ > -+ > -+#include <math.h> > -+#include <math_private.h> > -+#include <fenv_libc.h> > -+#include <inttypes.h> > -+ > -+#include <sysdep.h> > -+#include <ldsodefs.h> > -+ > -+static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; > -+static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; > -+static const float threehalf = 1.5; > -+ > -+/* The method is based on the descriptions in: > -+ > -+ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; > -+ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 > -+ > -+ We find the reciprocal square root and use that to compute the actual > -+ square root. */ > -+ > -+#ifdef __STDC__ > -+float > -+__ieee754_sqrtf (float b) > -+#else > -+float > -+__ieee754_sqrtf (b) > -+ float b; > -+#endif > -+{ > -+ if (__builtin_expect (b > 0, 1)) > -+ { > -+#define FMSUB(a_, c_, b_) \ > -+ ({ double __r; \ > -+ __asm__ ("fmsub %[r], %[a], %[c], %[b]\n" \ > -+ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ > -+ __r;}) > -+#define FNMSUB(a_, c_, b_) \ > -+ ({ double __r; \ > -+ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ > -+ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ > -+ __r;}) > -+ > -+ if (__builtin_expect (b != a_inf.value, 1)) > -+ { > -+ double y, x; > -+ fenv_t fe; > -+ > -+ fe = fegetenv_register (); > -+ > -+ relax_fenv_state (); > -+ > -+ /* Compute y = 1.5 * b - b. Uses fewer constants than y = 0.5 * b. */ > -+ y = FMSUB (threehalf, b, b); > -+ > -+ /* Initial estimate. */ > -+ __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b)); > -+ > -+ /* Iterate. x_{n+1} = x_n * (1.5 - y * (x_n * x_n)). */ > -+ x = x * FNMSUB (y, x * x, threehalf); > -+ x = x * FNMSUB (y, x * x, threehalf); > -+ x = x * FNMSUB (y, x * x, threehalf); > -+ > -+ /* All done. */ > -+ fesetenv_register (fe); > -+ return x * b; > -+ } > -+ } > -+ else if (b < 0) > -+ { > -+ /* For some reason, some PowerPC32 processors don't implement > -+ FE_INVALID_SQRT. */ > -+#ifdef FE_INVALID_SQRT > -+ feraiseexcept (FE_INVALID_SQRT); > -+ > -+ fenv_union_t u = { .fenv = fegetenv_register () }; > -+ if ((u.l[1] & FE_INVALID) == 0) > -+#endif > -+ feraiseexcept (FE_INVALID); > -+ b = a_nan.value; > -+ } > -+ return f_washf (b); > -+} > -Index: libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c > -=================================================================== > ---- /dev/null > -+++ libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c > -@@ -0,0 +1,134 @@ > -+/* Double-precision floating point square root. > -+ Copyright (C) 2010 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. */ > -+ > -+#include <math.h> > -+#include <math_private.h> > -+#include <fenv_libc.h> > -+#include <inttypes.h> > -+ > -+#include <sysdep.h> > -+#include <ldsodefs.h> > -+ > -+static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; > -+static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; > -+static const float two108 = 3.245185536584267269e+32; > -+static const float twom54 = 5.551115123125782702e-17; > -+static const float half = 0.5; > -+ > -+/* The method is based on the descriptions in: > -+ > -+ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; > -+ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 > -+ > -+ We find the actual square root and half of its reciprocal > -+ simultaneously. */ > -+ > -+#ifdef __STDC__ > -+double > -+__ieee754_sqrt (double b) > -+#else > -+double > -+__ieee754_sqrt (b) > -+ double b; > -+#endif > -+{ > -+ if (__builtin_expect (b > 0, 1)) > -+ { > -+ double y, g, h, d, r; > -+ ieee_double_shape_type u; > -+ > -+ if (__builtin_expect (b != a_inf.value, 1)) > -+ { > -+ fenv_t fe; > -+ > -+ fe = fegetenv_register (); > -+ > -+ u.value = b; > -+ > -+ relax_fenv_state (); > -+ > -+ __asm__ ("frsqrte %[estimate], %[x]\n" > -+ : [estimate] "=f" (y) : [x] "f" (b)); > -+ > -+ /* Following Muller et al, page 168, equation 5.20. > -+ > -+ h goes to 1/(2*sqrt(b)) > -+ g goes to sqrt(b). > -+ > -+ We need three iterations to get within 1ulp. */ > -+ > -+ /* Indicate that these can be performed prior to the branch. GCC > -+ insists on sinking them below the branch, however; it seems like > -+ they'd be better before the branch so that we can cover any latency > -+ from storing the argument and loading its high word. Oh well. */ > -+ > -+ g = b * y; > -+ h = 0.5 * y; > -+ > -+ /* Handle small numbers by scaling. */ > -+ if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0)) > -+ return __ieee754_sqrt (b * two108) * twom54; > -+ > -+#define FMADD(a_, c_, b_) \ > -+ ({ double __r; \ > -+ __asm__ ("fmadd %[r], %[a], %[c], %[b]\n" \ > -+ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ > -+ __r;}) > -+#define FNMSUB(a_, c_, b_) \ > -+ ({ double __r; \ > -+ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ > -+ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ > -+ __r;}) > -+ > -+ r = FNMSUB (g, h, half); > -+ g = FMADD (g, r, g); > -+ h = FMADD (h, r, h); > -+ > -+ r = FNMSUB (g, h, half); > -+ g = FMADD (g, r, g); > -+ h = FMADD (h, r, h); > -+ > -+ r = FNMSUB (g, h, half); > -+ g = FMADD (g, r, g); > -+ h = FMADD (h, r, h); > -+ > -+ /* g is now +/- 1ulp, or exactly equal to, the square root of b. */ > -+ > -+ /* Final refinement. */ > -+ d = FNMSUB (g, g, b); > -+ > -+ fesetenv_register (fe); > -+ return FMADD (d, h, g); > -+ } > -+ } > -+ else if (b < 0) > -+ { > -+ /* For some reason, some PowerPC32 processors don't implement > -+ FE_INVALID_SQRT. */ > -+#ifdef FE_INVALID_SQRT > -+ feraiseexcept (FE_INVALID_SQRT); > -+ > -+ fenv_union_t u = { .fenv = fegetenv_register () }; > -+ if ((u.l[1] & FE_INVALID) == 0) > -+#endif > -+ feraiseexcept (FE_INVALID); > -+ b = a_nan.value; > -+ } > -+ return f_wash (b); > -+} > -Index: libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c > -=================================================================== > ---- /dev/null > -+++ libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c > -@@ -0,0 +1,101 @@ > -+/* Single-precision floating point square root. > -+ Copyright (C) 2010 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. */ > -+ > -+#include <math.h> > -+#include <math_private.h> > -+#include <fenv_libc.h> > -+#include <inttypes.h> > -+ > -+#include <sysdep.h> > -+#include <ldsodefs.h> > -+ > -+static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; > -+static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; > -+static const float threehalf = 1.5; > -+ > -+/* The method is based on the descriptions in: > -+ > -+ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; > -+ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 > -+ > -+ We find the reciprocal square root and use that to compute the actual > -+ square root. */ > -+ > -+#ifdef __STDC__ > -+float > -+__ieee754_sqrtf (float b) > -+#else > -+float > -+__ieee754_sqrtf (b) > -+ float b; > -+#endif > -+{ > -+ if (__builtin_expect (b > 0, 1)) > -+ { > -+#define FMSUB(a_, c_, b_) \ > -+ ({ double __r; \ > -+ __asm__ ("fmsub %[r], %[a], %[c], %[b]\n" \ > -+ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ > -+ __r;}) > -+#define FNMSUB(a_, c_, b_) \ > -+ ({ double __r; \ > -+ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ > -+ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ > -+ __r;}) > -+ > -+ if (__builtin_expect (b != a_inf.value, 1)) > -+ { > -+ double y, x; > -+ fenv_t fe; > -+ > -+ fe = fegetenv_register (); > -+ > -+ relax_fenv_state (); > -+ > -+ /* Compute y = 1.5 * b - b. Uses fewer constants than y = 0.5 * b. */ > -+ y = FMSUB (threehalf, b, b); > -+ > -+ /* Initial estimate. */ > -+ __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b)); > -+ > -+ /* Iterate. x_{n+1} = x_n * (1.5 - y * (x_n * x_n)). */ > -+ x = x * FNMSUB (y, x * x, threehalf); > -+ x = x * FNMSUB (y, x * x, threehalf); > -+ x = x * FNMSUB (y, x * x, threehalf); > -+ > -+ /* All done. */ > -+ fesetenv_register (fe); > -+ return x * b; > -+ } > -+ } > -+ else if (b < 0) > -+ { > -+ /* For some reason, some PowerPC32 processors don't implement > -+ FE_INVALID_SQRT. */ > -+#ifdef FE_INVALID_SQRT > -+ feraiseexcept (FE_INVALID_SQRT); > -+ > -+ fenv_union_t u = { .fenv = fegetenv_register () }; > -+ if ((u.l[1] & FE_INVALID) == 0) > -+#endif > -+ feraiseexcept (FE_INVALID); > -+ b = a_nan.value; > -+ } > -+ return f_washf (b); > -+} > -Index: libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/603e/fpu/Implies > -=================================================================== > ---- /dev/null > -+++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/603e/fpu/Implies > -@@ -0,0 +1 @@ > -+powerpc/powerpc32/603e/fpu > -Index: libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/7400/fpu/Implies > -=================================================================== > ---- /dev/null > -+++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/7400/fpu/Implies > -@@ -0,0 +1 @@ > -+powerpc/powerpc32/603e/fpu > -Index: libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e500mc/fpu/Implies > -=================================================================== > ---- /dev/null > -+++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e500mc/fpu/Implies > -@@ -0,0 +1 @@ > -+powerpc/powerpc32/603e/fpu > -Index: libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/e5500/fpu/Implies > -=================================================================== > ---- /dev/null > -+++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/e5500/fpu/Implies > -@@ -0,0 +1 @@ > -+powerpc/powerpc64/e5500/fpu > -Index: libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e5500/fpu/Implies > -=================================================================== > ---- /dev/null > -+++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e5500/fpu/Implies > -@@ -0,0 +1 @@ > -+powerpc/powerpc32/603e/fpu > diff --git a/meta/recipes-core/eglibc/eglibc_2.16.bb b/meta/recipes-core/eglibc/eglibc_2.16.bb > index 78dc44a..a753882 100644 > --- a/meta/recipes-core/eglibc/eglibc_2.16.bb > +++ b/meta/recipes-core/eglibc/eglibc_2.16.bb > @@ -3,7 +3,7 @@ require eglibc.inc > SRCREV = "20393" > > DEPENDS += "gperf-native kconfig-frontends-native" > -PR = "r9" > +PR = "r10" > PR_append = "+svnr${SRCPV}" > > EGLIBC_BRANCH="eglibc-2_16" > @@ -13,7 +13,7 @@ SRC_URI = "svn://www.eglibc.org/svn/branches/;module=${EGLIBC_BRANCH};protocol=h > file://mips-rld-map-check.patch \ > file://etc/ld.so.conf \ > file://generate-supported.mk \ > - file://ppc-sqrt.patch \ > + file://glibc.fix_sqrt2.patch \ > file://multilib_readlib.patch \ > file://use-sysroot-cxx-headers.patch \ > file://ppc-sqrt_finite.patch \ > -- > 1.7.9.7 > > > > _______________________________________________ > Openembedded-core mailing list > Openembedded-core@lists.openembedded.org > http://lists.linuxtogo.org/cgi-bin/mailman/listinfo/openembedded-core
On Tue, Sep 18, 2012 at 3:12 PM, McClintock Matthew-B29882 <B29882@freescale.com> wrote: > Err this was supposed to be a series but I used the wrong format-patch > commands, patches in my tree here: > > http://git.yoctoproject.org/cgit/cgit.cgi/poky-contrib/log/?h=mattsm/master > what changes are needed for e6500 ? can these files be shadowed from e5500 ? I am confused with the two patches > -M > > On Tue, Sep 18, 2012 at 5:08 PM, Matthew McClintock <msm@freescale.com> wrote: >> Signed-off-by: Matthew McClintock <msm@freescale.com> >> --- >> .../eglibc/eglibc-2.16/glibc.fix_sqrt2.patch | 1488 ++++++++++++++++++++ >> .../recipes-core/eglibc/eglibc-2.16/ppc-sqrt.patch | 538 ------- >> meta/recipes-core/eglibc/eglibc_2.16.bb | 4 +- >> 3 files changed, 1490 insertions(+), 540 deletions(-) >> create mode 100644 meta/recipes-core/eglibc/eglibc-2.16/glibc.fix_sqrt2.patch >> delete mode 100644 meta/recipes-core/eglibc/eglibc-2.16/ppc-sqrt.patch >> >> diff --git a/meta/recipes-core/eglibc/eglibc-2.16/glibc.fix_sqrt2.patch b/meta/recipes-core/eglibc/eglibc-2.16/glibc.fix_sqrt2.patch >> new file mode 100644 >> index 0000000..e098192 >> --- /dev/null >> +++ b/meta/recipes-core/eglibc/eglibc-2.16/glibc.fix_sqrt2.patch >> @@ -0,0 +1,1488 @@ >> +diff -ruN libc-orig/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c >> +--- libc-orig/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c 1969-12-31 18:00:00.000000000 -0600 >> ++++ libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c 2012-06-14 14:51:50.452001745 -0500 >> +@@ -0,0 +1,134 @@ >> ++/* Double-precision floating point square root. >> ++ Copyright (C) 2010 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. */ >> ++ >> ++#include <math.h> >> ++#include <math_private.h> >> ++#include <fenv_libc.h> >> ++#include <inttypes.h> >> ++ >> ++#include <sysdep.h> >> ++#include <ldsodefs.h> >> ++ >> ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; >> ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; >> ++static const float two108 = 3.245185536584267269e+32; >> ++static const float twom54 = 5.551115123125782702e-17; >> ++static const float half = 0.5; >> ++ >> ++/* The method is based on the descriptions in: >> ++ >> ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; >> ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 >> ++ >> ++ We find the actual square root and half of its reciprocal >> ++ simultaneously. */ >> ++ >> ++#ifdef __STDC__ >> ++double >> ++__ieee754_sqrt (double b) >> ++#else >> ++double >> ++__ieee754_sqrt (b) >> ++ double b; >> ++#endif >> ++{ >> ++ if (__builtin_expect (b > 0, 1)) >> ++ { >> ++ double y, g, h, d, r; >> ++ ieee_double_shape_type u; >> ++ >> ++ if (__builtin_expect (b != a_inf.value, 1)) >> ++ { >> ++ fenv_t fe; >> ++ >> ++ fe = fegetenv_register (); >> ++ >> ++ u.value = b; >> ++ >> ++ relax_fenv_state (); >> ++ >> ++ __asm__ ("frsqrte %[estimate], %[x]\n" >> ++ : [estimate] "=f" (y) : [x] "f" (b)); >> ++ >> ++ /* Following Muller et al, page 168, equation 5.20. >> ++ >> ++ h goes to 1/(2*sqrt(b)) >> ++ g goes to sqrt(b). >> ++ >> ++ We need three iterations to get within 1ulp. */ >> ++ >> ++ /* Indicate that these can be performed prior to the branch. GCC >> ++ insists on sinking them below the branch, however; it seems like >> ++ they'd be better before the branch so that we can cover any latency >> ++ from storing the argument and loading its high word. Oh well. */ >> ++ >> ++ g = b * y; >> ++ h = 0.5 * y; >> ++ >> ++ /* Handle small numbers by scaling. */ >> ++ if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0)) >> ++ return __ieee754_sqrt (b * two108) * twom54; >> ++ >> ++#define FMADD(a_, c_, b_) \ >> ++ ({ double __r; \ >> ++ __asm__ ("fmadd %[r], %[a], %[c], %[b]\n" \ >> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >> ++ __r;}) >> ++#define FNMSUB(a_, c_, b_) \ >> ++ ({ double __r; \ >> ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ >> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >> ++ __r;}) >> ++ >> ++ r = FNMSUB (g, h, half); >> ++ g = FMADD (g, r, g); >> ++ h = FMADD (h, r, h); >> ++ >> ++ r = FNMSUB (g, h, half); >> ++ g = FMADD (g, r, g); >> ++ h = FMADD (h, r, h); >> ++ >> ++ r = FNMSUB (g, h, half); >> ++ g = FMADD (g, r, g); >> ++ h = FMADD (h, r, h); >> ++ >> ++ /* g is now +/- 1ulp, or exactly equal to, the square root of b. */ >> ++ >> ++ /* Final refinement. */ >> ++ d = FNMSUB (g, g, b); >> ++ >> ++ fesetenv_register (fe); >> ++ return FMADD (d, h, g); >> ++ } >> ++ } >> ++ else if (b < 0) >> ++ { >> ++ /* For some reason, some PowerPC32 processors don't implement >> ++ FE_INVALID_SQRT. */ >> ++#ifdef FE_INVALID_SQRT >> ++ feraiseexcept (FE_INVALID_SQRT); >> ++ >> ++ fenv_union_t u = { .fenv = fegetenv_register () }; >> ++ if ((u.l[1] & FE_INVALID) == 0) >> ++#endif >> ++ feraiseexcept (FE_INVALID); >> ++ b = a_nan.value; >> ++ } >> ++ return f_wash (b); >> ++} >> +diff -ruN libc-orig/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c >> +--- libc-orig/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c 1969-12-31 18:00:00.000000000 -0600 >> ++++ libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c 2012-06-14 14:51:50.452001745 -0500 >> +@@ -0,0 +1,101 @@ >> ++/* Single-precision floating point square root. >> ++ Copyright (C) 2010 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. */ >> ++ >> ++#include <math.h> >> ++#include <math_private.h> >> ++#include <fenv_libc.h> >> ++#include <inttypes.h> >> ++ >> ++#include <sysdep.h> >> ++#include <ldsodefs.h> >> ++ >> ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; >> ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; >> ++static const float threehalf = 1.5; >> ++ >> ++/* The method is based on the descriptions in: >> ++ >> ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; >> ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 >> ++ >> ++ We find the reciprocal square root and use that to compute the actual >> ++ square root. */ >> ++ >> ++#ifdef __STDC__ >> ++float >> ++__ieee754_sqrtf (float b) >> ++#else >> ++float >> ++__ieee754_sqrtf (b) >> ++ float b; >> ++#endif >> ++{ >> ++ if (__builtin_expect (b > 0, 1)) >> ++ { >> ++#define FMSUB(a_, c_, b_) \ >> ++ ({ double __r; \ >> ++ __asm__ ("fmsub %[r], %[a], %[c], %[b]\n" \ >> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >> ++ __r;}) >> ++#define FNMSUB(a_, c_, b_) \ >> ++ ({ double __r; \ >> ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ >> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >> ++ __r;}) >> ++ >> ++ if (__builtin_expect (b != a_inf.value, 1)) >> ++ { >> ++ double y, x; >> ++ fenv_t fe; >> ++ >> ++ fe = fegetenv_register (); >> ++ >> ++ relax_fenv_state (); >> ++ >> ++ /* Compute y = 1.5 * b - b. Uses fewer constants than y = 0.5 * b. */ >> ++ y = FMSUB (threehalf, b, b); >> ++ >> ++ /* Initial estimate. */ >> ++ __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b)); >> ++ >> ++ /* Iterate. x_{n+1} = x_n * (1.5 - y * (x_n * x_n)). */ >> ++ x = x * FNMSUB (y, x * x, threehalf); >> ++ x = x * FNMSUB (y, x * x, threehalf); >> ++ x = x * FNMSUB (y, x * x, threehalf); >> ++ >> ++ /* All done. */ >> ++ fesetenv_register (fe); >> ++ return x * b; >> ++ } >> ++ } >> ++ else if (b < 0) >> ++ { >> ++ /* For some reason, some PowerPC32 processors don't implement >> ++ FE_INVALID_SQRT. */ >> ++#ifdef FE_INVALID_SQRT >> ++ feraiseexcept (FE_INVALID_SQRT); >> ++ >> ++ fenv_union_t u = { .fenv = fegetenv_register () }; >> ++ if ((u.l[1] & FE_INVALID) == 0) >> ++#endif >> ++ feraiseexcept (FE_INVALID); >> ++ b = a_nan.value; >> ++ } >> ++ return f_washf (b); >> ++} >> +diff -ruN libc-orig/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c libc/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c >> +--- libc-orig/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c 1969-12-31 18:00:00.000000000 -0600 >> ++++ libc/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c 2012-06-14 14:55:14.749001061 -0500 >> +@@ -0,0 +1,134 @@ >> ++/* Double-precision floating point square root. >> ++ Copyright (C) 2010 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. */ >> ++ >> ++#include <math.h> >> ++#include <math_private.h> >> ++#include <fenv_libc.h> >> ++#include <inttypes.h> >> ++ >> ++#include <sysdep.h> >> ++#include <ldsodefs.h> >> ++ >> ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; >> ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; >> ++static const float two108 = 3.245185536584267269e+32; >> ++static const float twom54 = 5.551115123125782702e-17; >> ++static const float half = 0.5; >> ++ >> ++/* The method is based on the descriptions in: >> ++ >> ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; >> ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 >> ++ >> ++ We find the actual square root and half of its reciprocal >> ++ simultaneously. */ >> ++ >> ++#ifdef __STDC__ >> ++double >> ++__ieee754_sqrt (double b) >> ++#else >> ++double >> ++__ieee754_sqrt (b) >> ++ double b; >> ++#endif >> ++{ >> ++ if (__builtin_expect (b > 0, 1)) >> ++ { >> ++ double y, g, h, d, r; >> ++ ieee_double_shape_type u; >> ++ >> ++ if (__builtin_expect (b != a_inf.value, 1)) >> ++ { >> ++ fenv_t fe; >> ++ >> ++ fe = fegetenv_register (); >> ++ >> ++ u.value = b; >> ++ >> ++ relax_fenv_state (); >> ++ >> ++ __asm__ ("frsqrte %[estimate], %[x]\n" >> ++ : [estimate] "=f" (y) : [x] "f" (b)); >> ++ >> ++ /* Following Muller et al, page 168, equation 5.20. >> ++ >> ++ h goes to 1/(2*sqrt(b)) >> ++ g goes to sqrt(b). >> ++ >> ++ We need three iterations to get within 1ulp. */ >> ++ >> ++ /* Indicate that these can be performed prior to the branch. GCC >> ++ insists on sinking them below the branch, however; it seems like >> ++ they'd be better before the branch so that we can cover any latency >> ++ from storing the argument and loading its high word. Oh well. */ >> ++ >> ++ g = b * y; >> ++ h = 0.5 * y; >> ++ >> ++ /* Handle small numbers by scaling. */ >> ++ if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0)) >> ++ return __ieee754_sqrt (b * two108) * twom54; >> ++ >> ++#define FMADD(a_, c_, b_) \ >> ++ ({ double __r; \ >> ++ __asm__ ("fmadd %[r], %[a], %[c], %[b]\n" \ >> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >> ++ __r;}) >> ++#define FNMSUB(a_, c_, b_) \ >> ++ ({ double __r; \ >> ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ >> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >> ++ __r;}) >> ++ >> ++ r = FNMSUB (g, h, half); >> ++ g = FMADD (g, r, g); >> ++ h = FMADD (h, r, h); >> ++ >> ++ r = FNMSUB (g, h, half); >> ++ g = FMADD (g, r, g); >> ++ h = FMADD (h, r, h); >> ++ >> ++ r = FNMSUB (g, h, half); >> ++ g = FMADD (g, r, g); >> ++ h = FMADD (h, r, h); >> ++ >> ++ /* g is now +/- 1ulp, or exactly equal to, the square root of b. */ >> ++ >> ++ /* Final refinement. */ >> ++ d = FNMSUB (g, g, b); >> ++ >> ++ fesetenv_register (fe); >> ++ return FMADD (d, h, g); >> ++ } >> ++ } >> ++ else if (b < 0) >> ++ { >> ++ /* For some reason, some PowerPC32 processors don't implement >> ++ FE_INVALID_SQRT. */ >> ++#ifdef FE_INVALID_SQRT >> ++ feraiseexcept (FE_INVALID_SQRT); >> ++ >> ++ fenv_union_t u = { .fenv = fegetenv_register () }; >> ++ if ((u.l[1] & FE_INVALID) == 0) >> ++#endif >> ++ feraiseexcept (FE_INVALID); >> ++ b = a_nan.value; >> ++ } >> ++ return f_wash (b); >> ++} >> +diff -ruN libc-orig/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c libc/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c >> +--- libc-orig/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c 1969-12-31 18:00:00.000000000 -0600 >> ++++ libc/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c 2012-06-14 14:55:14.749001061 -0500 >> +@@ -0,0 +1,101 @@ >> ++/* Single-precision floating point square root. >> ++ Copyright (C) 2010 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. */ >> ++ >> ++#include <math.h> >> ++#include <math_private.h> >> ++#include <fenv_libc.h> >> ++#include <inttypes.h> >> ++ >> ++#include <sysdep.h> >> ++#include <ldsodefs.h> >> ++ >> ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; >> ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; >> ++static const float threehalf = 1.5; >> ++ >> ++/* The method is based on the descriptions in: >> ++ >> ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; >> ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 >> ++ >> ++ We find the reciprocal square root and use that to compute the actual >> ++ square root. */ >> ++ >> ++#ifdef __STDC__ >> ++float >> ++__ieee754_sqrtf (float b) >> ++#else >> ++float >> ++__ieee754_sqrtf (b) >> ++ float b; >> ++#endif >> ++{ >> ++ if (__builtin_expect (b > 0, 1)) >> ++ { >> ++#define FMSUB(a_, c_, b_) \ >> ++ ({ double __r; \ >> ++ __asm__ ("fmsub %[r], %[a], %[c], %[b]\n" \ >> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >> ++ __r;}) >> ++#define FNMSUB(a_, c_, b_) \ >> ++ ({ double __r; \ >> ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ >> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >> ++ __r;}) >> ++ >> ++ if (__builtin_expect (b != a_inf.value, 1)) >> ++ { >> ++ double y, x; >> ++ fenv_t fe; >> ++ >> ++ fe = fegetenv_register (); >> ++ >> ++ relax_fenv_state (); >> ++ >> ++ /* Compute y = 1.5 * b - b. Uses fewer constants than y = 0.5 * b. */ >> ++ y = FMSUB (threehalf, b, b); >> ++ >> ++ /* Initial estimate. */ >> ++ __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b)); >> ++ >> ++ /* Iterate. x_{n+1} = x_n * (1.5 - y * (x_n * x_n)). */ >> ++ x = x * FNMSUB (y, x * x, threehalf); >> ++ x = x * FNMSUB (y, x * x, threehalf); >> ++ x = x * FNMSUB (y, x * x, threehalf); >> ++ >> ++ /* All done. */ >> ++ fesetenv_register (fe); >> ++ return x * b; >> ++ } >> ++ } >> ++ else if (b < 0) >> ++ { >> ++ /* For some reason, some PowerPC32 processors don't implement >> ++ FE_INVALID_SQRT. */ >> ++#ifdef FE_INVALID_SQRT >> ++ feraiseexcept (FE_INVALID_SQRT); >> ++ >> ++ fenv_union_t u = { .fenv = fegetenv_register () }; >> ++ if ((u.l[1] & FE_INVALID) == 0) >> ++#endif >> ++ feraiseexcept (FE_INVALID); >> ++ b = a_nan.value; >> ++ } >> ++ return f_washf (b); >> ++} >> +diff -ruN libc-orig/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c libc/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c >> +--- libc-orig/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c 1969-12-31 18:00:00.000000000 -0600 >> ++++ libc/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c 2012-06-14 14:55:21.812002270 -0500 >> +@@ -0,0 +1,134 @@ >> ++/* Double-precision floating point square root. >> ++ Copyright (C) 2010 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. */ >> ++ >> ++#include <math.h> >> ++#include <math_private.h> >> ++#include <fenv_libc.h> >> ++#include <inttypes.h> >> ++ >> ++#include <sysdep.h> >> ++#include <ldsodefs.h> >> ++ >> ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; >> ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; >> ++static const float two108 = 3.245185536584267269e+32; >> ++static const float twom54 = 5.551115123125782702e-17; >> ++static const float half = 0.5; >> ++ >> ++/* The method is based on the descriptions in: >> ++ >> ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; >> ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 >> ++ >> ++ We find the actual square root and half of its reciprocal >> ++ simultaneously. */ >> ++ >> ++#ifdef __STDC__ >> ++double >> ++__ieee754_sqrt (double b) >> ++#else >> ++double >> ++__ieee754_sqrt (b) >> ++ double b; >> ++#endif >> ++{ >> ++ if (__builtin_expect (b > 0, 1)) >> ++ { >> ++ double y, g, h, d, r; >> ++ ieee_double_shape_type u; >> ++ >> ++ if (__builtin_expect (b != a_inf.value, 1)) >> ++ { >> ++ fenv_t fe; >> ++ >> ++ fe = fegetenv_register (); >> ++ >> ++ u.value = b; >> ++ >> ++ relax_fenv_state (); >> ++ >> ++ __asm__ ("frsqrte %[estimate], %[x]\n" >> ++ : [estimate] "=f" (y) : [x] "f" (b)); >> ++ >> ++ /* Following Muller et al, page 168, equation 5.20. >> ++ >> ++ h goes to 1/(2*sqrt(b)) >> ++ g goes to sqrt(b). >> ++ >> ++ We need three iterations to get within 1ulp. */ >> ++ >> ++ /* Indicate that these can be performed prior to the branch. GCC >> ++ insists on sinking them below the branch, however; it seems like >> ++ they'd be better before the branch so that we can cover any latency >> ++ from storing the argument and loading its high word. Oh well. */ >> ++ >> ++ g = b * y; >> ++ h = 0.5 * y; >> ++ >> ++ /* Handle small numbers by scaling. */ >> ++ if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0)) >> ++ return __ieee754_sqrt (b * two108) * twom54; >> ++ >> ++#define FMADD(a_, c_, b_) \ >> ++ ({ double __r; \ >> ++ __asm__ ("fmadd %[r], %[a], %[c], %[b]\n" \ >> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >> ++ __r;}) >> ++#define FNMSUB(a_, c_, b_) \ >> ++ ({ double __r; \ >> ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ >> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >> ++ __r;}) >> ++ >> ++ r = FNMSUB (g, h, half); >> ++ g = FMADD (g, r, g); >> ++ h = FMADD (h, r, h); >> ++ >> ++ r = FNMSUB (g, h, half); >> ++ g = FMADD (g, r, g); >> ++ h = FMADD (h, r, h); >> ++ >> ++ r = FNMSUB (g, h, half); >> ++ g = FMADD (g, r, g); >> ++ h = FMADD (h, r, h); >> ++ >> ++ /* g is now +/- 1ulp, or exactly equal to, the square root of b. */ >> ++ >> ++ /* Final refinement. */ >> ++ d = FNMSUB (g, g, b); >> ++ >> ++ fesetenv_register (fe); >> ++ return FMADD (d, h, g); >> ++ } >> ++ } >> ++ else if (b < 0) >> ++ { >> ++ /* For some reason, some PowerPC32 processors don't implement >> ++ FE_INVALID_SQRT. */ >> ++#ifdef FE_INVALID_SQRT >> ++ feraiseexcept (FE_INVALID_SQRT); >> ++ >> ++ fenv_union_t u = { .fenv = fegetenv_register () }; >> ++ if ((u.l[1] & FE_INVALID) == 0) >> ++#endif >> ++ feraiseexcept (FE_INVALID); >> ++ b = a_nan.value; >> ++ } >> ++ return f_wash (b); >> ++} >> +diff -ruN libc-orig/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c libc/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c >> +--- libc-orig/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c 1969-12-31 18:00:00.000000000 -0600 >> ++++ libc/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c 2012-06-14 14:55:21.812002270 -0500 >> +@@ -0,0 +1,101 @@ >> ++/* Single-precision floating point square root. >> ++ Copyright (C) 2010 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. */ >> ++ >> ++#include <math.h> >> ++#include <math_private.h> >> ++#include <fenv_libc.h> >> ++#include <inttypes.h> >> ++ >> ++#include <sysdep.h> >> ++#include <ldsodefs.h> >> ++ >> ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; >> ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; >> ++static const float threehalf = 1.5; >> ++ >> ++/* The method is based on the descriptions in: >> ++ >> ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; >> ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 >> ++ >> ++ We find the reciprocal square root and use that to compute the actual >> ++ square root. */ >> ++ >> ++#ifdef __STDC__ >> ++float >> ++__ieee754_sqrtf (float b) >> ++#else >> ++float >> ++__ieee754_sqrtf (b) >> ++ float b; >> ++#endif >> ++{ >> ++ if (__builtin_expect (b > 0, 1)) >> ++ { >> ++#define FMSUB(a_, c_, b_) \ >> ++ ({ double __r; \ >> ++ __asm__ ("fmsub %[r], %[a], %[c], %[b]\n" \ >> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >> ++ __r;}) >> ++#define FNMSUB(a_, c_, b_) \ >> ++ ({ double __r; \ >> ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ >> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >> ++ __r;}) >> ++ >> ++ if (__builtin_expect (b != a_inf.value, 1)) >> ++ { >> ++ double y, x; >> ++ fenv_t fe; >> ++ >> ++ fe = fegetenv_register (); >> ++ >> ++ relax_fenv_state (); >> ++ >> ++ /* Compute y = 1.5 * b - b. Uses fewer constants than y = 0.5 * b. */ >> ++ y = FMSUB (threehalf, b, b); >> ++ >> ++ /* Initial estimate. */ >> ++ __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b)); >> ++ >> ++ /* Iterate. x_{n+1} = x_n * (1.5 - y * (x_n * x_n)). */ >> ++ x = x * FNMSUB (y, x * x, threehalf); >> ++ x = x * FNMSUB (y, x * x, threehalf); >> ++ x = x * FNMSUB (y, x * x, threehalf); >> ++ >> ++ /* All done. */ >> ++ fesetenv_register (fe); >> ++ return x * b; >> ++ } >> ++ } >> ++ else if (b < 0) >> ++ { >> ++ /* For some reason, some PowerPC32 processors don't implement >> ++ FE_INVALID_SQRT. */ >> ++#ifdef FE_INVALID_SQRT >> ++ feraiseexcept (FE_INVALID_SQRT); >> ++ >> ++ fenv_union_t u = { .fenv = fegetenv_register () }; >> ++ if ((u.l[1] & FE_INVALID) == 0) >> ++#endif >> ++ feraiseexcept (FE_INVALID); >> ++ b = a_nan.value; >> ++ } >> ++ return f_washf (b); >> ++} >> +diff -ruN libc-orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c >> +--- libc-orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c 1969-12-31 18:00:00.000000000 -0600 >> ++++ libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c 2012-06-14 14:55:24.620001266 -0500 >> +@@ -0,0 +1,134 @@ >> ++/* Double-precision floating point square root. >> ++ Copyright (C) 2010 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. */ >> ++ >> ++#include <math.h> >> ++#include <math_private.h> >> ++#include <fenv_libc.h> >> ++#include <inttypes.h> >> ++ >> ++#include <sysdep.h> >> ++#include <ldsodefs.h> >> ++ >> ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; >> ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; >> ++static const float two108 = 3.245185536584267269e+32; >> ++static const float twom54 = 5.551115123125782702e-17; >> ++static const float half = 0.5; >> ++ >> ++/* The method is based on the descriptions in: >> ++ >> ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; >> ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 >> ++ >> ++ We find the actual square root and half of its reciprocal >> ++ simultaneously. */ >> ++ >> ++#ifdef __STDC__ >> ++double >> ++__ieee754_sqrt (double b) >> ++#else >> ++double >> ++__ieee754_sqrt (b) >> ++ double b; >> ++#endif >> ++{ >> ++ if (__builtin_expect (b > 0, 1)) >> ++ { >> ++ double y, g, h, d, r; >> ++ ieee_double_shape_type u; >> ++ >> ++ if (__builtin_expect (b != a_inf.value, 1)) >> ++ { >> ++ fenv_t fe; >> ++ >> ++ fe = fegetenv_register (); >> ++ >> ++ u.value = b; >> ++ >> ++ relax_fenv_state (); >> ++ >> ++ __asm__ ("frsqrte %[estimate], %[x]\n" >> ++ : [estimate] "=f" (y) : [x] "f" (b)); >> ++ >> ++ /* Following Muller et al, page 168, equation 5.20. >> ++ >> ++ h goes to 1/(2*sqrt(b)) >> ++ g goes to sqrt(b). >> ++ >> ++ We need three iterations to get within 1ulp. */ >> ++ >> ++ /* Indicate that these can be performed prior to the branch. GCC >> ++ insists on sinking them below the branch, however; it seems like >> ++ they'd be better before the branch so that we can cover any latency >> ++ from storing the argument and loading its high word. Oh well. */ >> ++ >> ++ g = b * y; >> ++ h = 0.5 * y; >> ++ >> ++ /* Handle small numbers by scaling. */ >> ++ if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0)) >> ++ return __ieee754_sqrt (b * two108) * twom54; >> ++ >> ++#define FMADD(a_, c_, b_) \ >> ++ ({ double __r; \ >> ++ __asm__ ("fmadd %[r], %[a], %[c], %[b]\n" \ >> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >> ++ __r;}) >> ++#define FNMSUB(a_, c_, b_) \ >> ++ ({ double __r; \ >> ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ >> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >> ++ __r;}) >> ++ >> ++ r = FNMSUB (g, h, half); >> ++ g = FMADD (g, r, g); >> ++ h = FMADD (h, r, h); >> ++ >> ++ r = FNMSUB (g, h, half); >> ++ g = FMADD (g, r, g); >> ++ h = FMADD (h, r, h); >> ++ >> ++ r = FNMSUB (g, h, half); >> ++ g = FMADD (g, r, g); >> ++ h = FMADD (h, r, h); >> ++ >> ++ /* g is now +/- 1ulp, or exactly equal to, the square root of b. */ >> ++ >> ++ /* Final refinement. */ >> ++ d = FNMSUB (g, g, b); >> ++ >> ++ fesetenv_register (fe); >> ++ return FMADD (d, h, g); >> ++ } >> ++ } >> ++ else if (b < 0) >> ++ { >> ++ /* For some reason, some PowerPC32 processors don't implement >> ++ FE_INVALID_SQRT. */ >> ++#ifdef FE_INVALID_SQRT >> ++ feraiseexcept (FE_INVALID_SQRT); >> ++ >> ++ fenv_union_t u = { .fenv = fegetenv_register () }; >> ++ if ((u.l[1] & FE_INVALID) == 0) >> ++#endif >> ++ feraiseexcept (FE_INVALID); >> ++ b = a_nan.value; >> ++ } >> ++ return f_wash (b); >> ++} >> +diff -ruN libc-orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c >> +--- libc-orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c 1969-12-31 18:00:00.000000000 -0600 >> ++++ libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c 2012-06-14 14:55:24.620001266 -0500 >> +@@ -0,0 +1,101 @@ >> ++/* Single-precision floating point square root. >> ++ Copyright (C) 2010 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. */ >> ++ >> ++#include <math.h> >> ++#include <math_private.h> >> ++#include <fenv_libc.h> >> ++#include <inttypes.h> >> ++ >> ++#include <sysdep.h> >> ++#include <ldsodefs.h> >> ++ >> ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; >> ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; >> ++static const float threehalf = 1.5; >> ++ >> ++/* The method is based on the descriptions in: >> ++ >> ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; >> ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 >> ++ >> ++ We find the reciprocal square root and use that to compute the actual >> ++ square root. */ >> ++ >> ++#ifdef __STDC__ >> ++float >> ++__ieee754_sqrtf (float b) >> ++#else >> ++float >> ++__ieee754_sqrtf (b) >> ++ float b; >> ++#endif >> ++{ >> ++ if (__builtin_expect (b > 0, 1)) >> ++ { >> ++#define FMSUB(a_, c_, b_) \ >> ++ ({ double __r; \ >> ++ __asm__ ("fmsub %[r], %[a], %[c], %[b]\n" \ >> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >> ++ __r;}) >> ++#define FNMSUB(a_, c_, b_) \ >> ++ ({ double __r; \ >> ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ >> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >> ++ __r;}) >> ++ >> ++ if (__builtin_expect (b != a_inf.value, 1)) >> ++ { >> ++ double y, x; >> ++ fenv_t fe; >> ++ >> ++ fe = fegetenv_register (); >> ++ >> ++ relax_fenv_state (); >> ++ >> ++ /* Compute y = 1.5 * b - b. Uses fewer constants than y = 0.5 * b. */ >> ++ y = FMSUB (threehalf, b, b); >> ++ >> ++ /* Initial estimate. */ >> ++ __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b)); >> ++ >> ++ /* Iterate. x_{n+1} = x_n * (1.5 - y * (x_n * x_n)). */ >> ++ x = x * FNMSUB (y, x * x, threehalf); >> ++ x = x * FNMSUB (y, x * x, threehalf); >> ++ x = x * FNMSUB (y, x * x, threehalf); >> ++ >> ++ /* All done. */ >> ++ fesetenv_register (fe); >> ++ return x * b; >> ++ } >> ++ } >> ++ else if (b < 0) >> ++ { >> ++ /* For some reason, some PowerPC32 processors don't implement >> ++ FE_INVALID_SQRT. */ >> ++#ifdef FE_INVALID_SQRT >> ++ feraiseexcept (FE_INVALID_SQRT); >> ++ >> ++ fenv_union_t u = { .fenv = fegetenv_register () }; >> ++ if ((u.l[1] & FE_INVALID) == 0) >> ++#endif >> ++ feraiseexcept (FE_INVALID); >> ++ b = a_nan.value; >> ++ } >> ++ return f_washf (b); >> ++} >> +diff -ruN libc-orig/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c >> +--- libc-orig/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c 1969-12-31 18:00:00.000000000 -0600 >> ++++ libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c 2012-06-14 14:51:50.452001745 -0500 >> +@@ -0,0 +1,134 @@ >> ++/* Double-precision floating point square root. >> ++ Copyright (C) 2010 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. */ >> ++ >> ++#include <math.h> >> ++#include <math_private.h> >> ++#include <fenv_libc.h> >> ++#include <inttypes.h> >> ++ >> ++#include <sysdep.h> >> ++#include <ldsodefs.h> >> ++ >> ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; >> ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; >> ++static const float two108 = 3.245185536584267269e+32; >> ++static const float twom54 = 5.551115123125782702e-17; >> ++static const float half = 0.5; >> ++ >> ++/* The method is based on the descriptions in: >> ++ >> ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; >> ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 >> ++ >> ++ We find the actual square root and half of its reciprocal >> ++ simultaneously. */ >> ++ >> ++#ifdef __STDC__ >> ++double >> ++__ieee754_sqrt (double b) >> ++#else >> ++double >> ++__ieee754_sqrt (b) >> ++ double b; >> ++#endif >> ++{ >> ++ if (__builtin_expect (b > 0, 1)) >> ++ { >> ++ double y, g, h, d, r; >> ++ ieee_double_shape_type u; >> ++ >> ++ if (__builtin_expect (b != a_inf.value, 1)) >> ++ { >> ++ fenv_t fe; >> ++ >> ++ fe = fegetenv_register (); >> ++ >> ++ u.value = b; >> ++ >> ++ relax_fenv_state (); >> ++ >> ++ __asm__ ("frsqrte %[estimate], %[x]\n" >> ++ : [estimate] "=f" (y) : [x] "f" (b)); >> ++ >> ++ /* Following Muller et al, page 168, equation 5.20. >> ++ >> ++ h goes to 1/(2*sqrt(b)) >> ++ g goes to sqrt(b). >> ++ >> ++ We need three iterations to get within 1ulp. */ >> ++ >> ++ /* Indicate that these can be performed prior to the branch. GCC >> ++ insists on sinking them below the branch, however; it seems like >> ++ they'd be better before the branch so that we can cover any latency >> ++ from storing the argument and loading its high word. Oh well. */ >> ++ >> ++ g = b * y; >> ++ h = 0.5 * y; >> ++ >> ++ /* Handle small numbers by scaling. */ >> ++ if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0)) >> ++ return __ieee754_sqrt (b * two108) * twom54; >> ++ >> ++#define FMADD(a_, c_, b_) \ >> ++ ({ double __r; \ >> ++ __asm__ ("fmadd %[r], %[a], %[c], %[b]\n" \ >> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >> ++ __r;}) >> ++#define FNMSUB(a_, c_, b_) \ >> ++ ({ double __r; \ >> ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ >> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >> ++ __r;}) >> ++ >> ++ r = FNMSUB (g, h, half); >> ++ g = FMADD (g, r, g); >> ++ h = FMADD (h, r, h); >> ++ >> ++ r = FNMSUB (g, h, half); >> ++ g = FMADD (g, r, g); >> ++ h = FMADD (h, r, h); >> ++ >> ++ r = FNMSUB (g, h, half); >> ++ g = FMADD (g, r, g); >> ++ h = FMADD (h, r, h); >> ++ >> ++ /* g is now +/- 1ulp, or exactly equal to, the square root of b. */ >> ++ >> ++ /* Final refinement. */ >> ++ d = FNMSUB (g, g, b); >> ++ >> ++ fesetenv_register (fe); >> ++ return FMADD (d, h, g); >> ++ } >> ++ } >> ++ else if (b < 0) >> ++ { >> ++ /* For some reason, some PowerPC32 processors don't implement >> ++ FE_INVALID_SQRT. */ >> ++#ifdef FE_INVALID_SQRT >> ++ feraiseexcept (FE_INVALID_SQRT); >> ++ >> ++ fenv_union_t u = { .fenv = fegetenv_register () }; >> ++ if ((u.l[1] & FE_INVALID) == 0) >> ++#endif >> ++ feraiseexcept (FE_INVALID); >> ++ b = a_nan.value; >> ++ } >> ++ return f_wash (b); >> ++} >> +diff -ruN libc-orig/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c >> +--- libc-orig/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c 1969-12-31 18:00:00.000000000 -0600 >> ++++ libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c 2012-06-14 14:51:50.452001745 -0500 >> +@@ -0,0 +1,101 @@ >> ++/* Single-precision floating point square root. >> ++ Copyright (C) 2010 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. */ >> ++ >> ++#include <math.h> >> ++#include <math_private.h> >> ++#include <fenv_libc.h> >> ++#include <inttypes.h> >> ++ >> ++#include <sysdep.h> >> ++#include <ldsodefs.h> >> ++ >> ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; >> ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; >> ++static const float threehalf = 1.5; >> ++ >> ++/* The method is based on the descriptions in: >> ++ >> ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; >> ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 >> ++ >> ++ We find the reciprocal square root and use that to compute the actual >> ++ square root. */ >> ++ >> ++#ifdef __STDC__ >> ++float >> ++__ieee754_sqrtf (float b) >> ++#else >> ++float >> ++__ieee754_sqrtf (b) >> ++ float b; >> ++#endif >> ++{ >> ++ if (__builtin_expect (b > 0, 1)) >> ++ { >> ++#define FMSUB(a_, c_, b_) \ >> ++ ({ double __r; \ >> ++ __asm__ ("fmsub %[r], %[a], %[c], %[b]\n" \ >> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >> ++ __r;}) >> ++#define FNMSUB(a_, c_, b_) \ >> ++ ({ double __r; \ >> ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ >> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >> ++ __r;}) >> ++ >> ++ if (__builtin_expect (b != a_inf.value, 1)) >> ++ { >> ++ double y, x; >> ++ fenv_t fe; >> ++ >> ++ fe = fegetenv_register (); >> ++ >> ++ relax_fenv_state (); >> ++ >> ++ /* Compute y = 1.5 * b - b. Uses fewer constants than y = 0.5 * b. */ >> ++ y = FMSUB (threehalf, b, b); >> ++ >> ++ /* Initial estimate. */ >> ++ __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b)); >> ++ >> ++ /* Iterate. x_{n+1} = x_n * (1.5 - y * (x_n * x_n)). */ >> ++ x = x * FNMSUB (y, x * x, threehalf); >> ++ x = x * FNMSUB (y, x * x, threehalf); >> ++ x = x * FNMSUB (y, x * x, threehalf); >> ++ >> ++ /* All done. */ >> ++ fesetenv_register (fe); >> ++ return x * b; >> ++ } >> ++ } >> ++ else if (b < 0) >> ++ { >> ++ /* For some reason, some PowerPC32 processors don't implement >> ++ FE_INVALID_SQRT. */ >> ++#ifdef FE_INVALID_SQRT >> ++ feraiseexcept (FE_INVALID_SQRT); >> ++ >> ++ fenv_union_t u = { .fenv = fegetenv_register () }; >> ++ if ((u.l[1] & FE_INVALID) == 0) >> ++#endif >> ++ feraiseexcept (FE_INVALID); >> ++ b = a_nan.value; >> ++ } >> ++ return f_washf (b); >> ++} >> +diff -ruN libc-orig/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c libc/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c >> +--- libc-orig/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c 1969-12-31 18:00:00.000000000 -0600 >> ++++ libc/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c 2012-06-14 14:56:02.080000985 -0500 >> +@@ -0,0 +1,134 @@ >> ++/* Double-precision floating point square root. >> ++ Copyright (C) 2010 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. */ >> ++ >> ++#include <math.h> >> ++#include <math_private.h> >> ++#include <fenv_libc.h> >> ++#include <inttypes.h> >> ++ >> ++#include <sysdep.h> >> ++#include <ldsodefs.h> >> ++ >> ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; >> ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; >> ++static const float two108 = 3.245185536584267269e+32; >> ++static const float twom54 = 5.551115123125782702e-17; >> ++static const float half = 0.5; >> ++ >> ++/* The method is based on the descriptions in: >> ++ >> ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; >> ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 >> ++ >> ++ We find the actual square root and half of its reciprocal >> ++ simultaneously. */ >> ++ >> ++#ifdef __STDC__ >> ++double >> ++__ieee754_sqrt (double b) >> ++#else >> ++double >> ++__ieee754_sqrt (b) >> ++ double b; >> ++#endif >> ++{ >> ++ if (__builtin_expect (b > 0, 1)) >> ++ { >> ++ double y, g, h, d, r; >> ++ ieee_double_shape_type u; >> ++ >> ++ if (__builtin_expect (b != a_inf.value, 1)) >> ++ { >> ++ fenv_t fe; >> ++ >> ++ fe = fegetenv_register (); >> ++ >> ++ u.value = b; >> ++ >> ++ relax_fenv_state (); >> ++ >> ++ __asm__ ("frsqrte %[estimate], %[x]\n" >> ++ : [estimate] "=f" (y) : [x] "f" (b)); >> ++ >> ++ /* Following Muller et al, page 168, equation 5.20. >> ++ >> ++ h goes to 1/(2*sqrt(b)) >> ++ g goes to sqrt(b). >> ++ >> ++ We need three iterations to get within 1ulp. */ >> ++ >> ++ /* Indicate that these can be performed prior to the branch. GCC >> ++ insists on sinking them below the branch, however; it seems like >> ++ they'd be better before the branch so that we can cover any latency >> ++ from storing the argument and loading its high word. Oh well. */ >> ++ >> ++ g = b * y; >> ++ h = 0.5 * y; >> ++ >> ++ /* Handle small numbers by scaling. */ >> ++ if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0)) >> ++ return __ieee754_sqrt (b * two108) * twom54; >> ++ >> ++#define FMADD(a_, c_, b_) \ >> ++ ({ double __r; \ >> ++ __asm__ ("fmadd %[r], %[a], %[c], %[b]\n" \ >> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >> ++ __r;}) >> ++#define FNMSUB(a_, c_, b_) \ >> ++ ({ double __r; \ >> ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ >> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >> ++ __r;}) >> ++ >> ++ r = FNMSUB (g, h, half); >> ++ g = FMADD (g, r, g); >> ++ h = FMADD (h, r, h); >> ++ >> ++ r = FNMSUB (g, h, half); >> ++ g = FMADD (g, r, g); >> ++ h = FMADD (h, r, h); >> ++ >> ++ r = FNMSUB (g, h, half); >> ++ g = FMADD (g, r, g); >> ++ h = FMADD (h, r, h); >> ++ >> ++ /* g is now +/- 1ulp, or exactly equal to, the square root of b. */ >> ++ >> ++ /* Final refinement. */ >> ++ d = FNMSUB (g, g, b); >> ++ >> ++ fesetenv_register (fe); >> ++ return FMADD (d, h, g); >> ++ } >> ++ } >> ++ else if (b < 0) >> ++ { >> ++ /* For some reason, some PowerPC32 processors don't implement >> ++ FE_INVALID_SQRT. */ >> ++#ifdef FE_INVALID_SQRT >> ++ feraiseexcept (FE_INVALID_SQRT); >> ++ >> ++ fenv_union_t u = { .fenv = fegetenv_register () }; >> ++ if ((u.l[1] & FE_INVALID) == 0) >> ++#endif >> ++ feraiseexcept (FE_INVALID); >> ++ b = a_nan.value; >> ++ } >> ++ return f_wash (b); >> ++} >> +diff -ruN libc-orig/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c libc/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c >> +--- libc-orig/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c 1969-12-31 18:00:00.000000000 -0600 >> ++++ libc/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c 2012-06-14 14:56:02.080000985 -0500 >> +@@ -0,0 +1,101 @@ >> ++/* Single-precision floating point square root. >> ++ Copyright (C) 2010 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. */ >> ++ >> ++#include <math.h> >> ++#include <math_private.h> >> ++#include <fenv_libc.h> >> ++#include <inttypes.h> >> ++ >> ++#include <sysdep.h> >> ++#include <ldsodefs.h> >> ++ >> ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; >> ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; >> ++static const float threehalf = 1.5; >> ++ >> ++/* The method is based on the descriptions in: >> ++ >> ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; >> ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 >> ++ >> ++ We find the reciprocal square root and use that to compute the actual >> ++ square root. */ >> ++ >> ++#ifdef __STDC__ >> ++float >> ++__ieee754_sqrtf (float b) >> ++#else >> ++float >> ++__ieee754_sqrtf (b) >> ++ float b; >> ++#endif >> ++{ >> ++ if (__builtin_expect (b > 0, 1)) >> ++ { >> ++#define FMSUB(a_, c_, b_) \ >> ++ ({ double __r; \ >> ++ __asm__ ("fmsub %[r], %[a], %[c], %[b]\n" \ >> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >> ++ __r;}) >> ++#define FNMSUB(a_, c_, b_) \ >> ++ ({ double __r; \ >> ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ >> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >> ++ __r;}) >> ++ >> ++ if (__builtin_expect (b != a_inf.value, 1)) >> ++ { >> ++ double y, x; >> ++ fenv_t fe; >> ++ >> ++ fe = fegetenv_register (); >> ++ >> ++ relax_fenv_state (); >> ++ >> ++ /* Compute y = 1.5 * b - b. Uses fewer constants than y = 0.5 * b. */ >> ++ y = FMSUB (threehalf, b, b); >> ++ >> ++ /* Initial estimate. */ >> ++ __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b)); >> ++ >> ++ /* Iterate. x_{n+1} = x_n * (1.5 - y * (x_n * x_n)). */ >> ++ x = x * FNMSUB (y, x * x, threehalf); >> ++ x = x * FNMSUB (y, x * x, threehalf); >> ++ x = x * FNMSUB (y, x * x, threehalf); >> ++ >> ++ /* All done. */ >> ++ fesetenv_register (fe); >> ++ return x * b; >> ++ } >> ++ } >> ++ else if (b < 0) >> ++ { >> ++ /* For some reason, some PowerPC32 processors don't implement >> ++ FE_INVALID_SQRT. */ >> ++#ifdef FE_INVALID_SQRT >> ++ feraiseexcept (FE_INVALID_SQRT); >> ++ >> ++ fenv_union_t u = { .fenv = fegetenv_register () }; >> ++ if ((u.l[1] & FE_INVALID) == 0) >> ++#endif >> ++ feraiseexcept (FE_INVALID); >> ++ b = a_nan.value; >> ++ } >> ++ return f_washf (b); >> ++} >> +diff -ruN libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/603e/fpu/Implies libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/603e/fpu/Implies >> +--- libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/603e/fpu/Implies 1969-12-31 18:00:00.000000000 -0600 >> ++++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/603e/fpu/Implies 2012-06-14 14:51:50.452001745 -0500 >> +@@ -0,0 +1 @@ >> ++powerpc/powerpc32/603e/fpu >> +diff -ruN libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/e500mc/fpu/Implies libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e500mc/fpu/Implies >> +--- libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/e500mc/fpu/Implies 1969-12-31 18:00:00.000000000 -0600 >> ++++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e500mc/fpu/Implies 2012-06-14 14:54:00.481000876 -0500 >> +@@ -0,0 +1 @@ >> ++powerpc/powerpc32/e500mc/fpu >> +diff -ruN libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/e5500/fpu/Implies libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e5500/fpu/Implies >> +--- libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/e5500/fpu/Implies 1969-12-31 18:00:00.000000000 -0600 >> ++++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e5500/fpu/Implies 2012-06-14 14:54:17.000001007 -0500 >> +@@ -0,0 +1 @@ >> ++powerpc/powerpc32/e5500/fpu >> +diff -ruN libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/e6500/fpu/Implies libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e6500/fpu/Implies >> +--- libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/e6500/fpu/Implies 1969-12-31 18:00:00.000000000 -0600 >> ++++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e6500/fpu/Implies 2012-06-14 14:54:31.054001299 -0500 >> +@@ -0,0 +1 @@ >> ++powerpc/powerpc32/e6500/fpu >> +diff -ruN libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/e5500/fpu/Implies libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/e5500/fpu/Implies >> +--- libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/e5500/fpu/Implies 1969-12-31 18:00:00.000000000 -0600 >> ++++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/e5500/fpu/Implies 2012-06-14 14:51:50.453001709 -0500 >> +@@ -0,0 +1 @@ >> ++powerpc/powerpc64/e5500/fpu >> +diff -ruN libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/e6500/fpu/Implies libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/e6500/fpu/Implies >> +--- libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/e6500/fpu/Implies 1969-12-31 18:00:00.000000000 -0600 >> ++++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/e6500/fpu/Implies 2012-06-14 14:58:14.298001288 -0500 >> +@@ -0,0 +1 @@ >> ++powerpc/powerpc64/e6500/fpu >> diff --git a/meta/recipes-core/eglibc/eglibc-2.16/ppc-sqrt.patch b/meta/recipes-core/eglibc/eglibc-2.16/ppc-sqrt.patch >> deleted file mode 100644 >> index 203040c..0000000 >> --- a/meta/recipes-core/eglibc/eglibc-2.16/ppc-sqrt.patch >> +++ /dev/null >> @@ -1,538 +0,0 @@ >> -Upstream-Status: Pending >> - >> -2011-03-22 Joseph Myers <joseph@codesourcery.com> >> - >> - Merge from SG++ 2.11: >> - >> - 2010-10-05 Nathan Froyd <froydnj@codesourcery.com> >> - >> - Issue #9382 >> - >> - * sysdeps/powerpc/powerpc32/603e/: New directory. >> - * sysdeps/unix/sysv/linux/powerpc/powerpc32/e500mc/: New directory. >> - * sysdeps/unix/sysv/linux/powerpc/powerpc32/603e/: New directory. >> - * sysdeps/unix/sysv/linux/powerpc/powerpc32/7400/: New directory. >> - * sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c: Update. >> - * sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c: Update. >> - * sysdeps/powerpc/powerpc64/e5500/fpu/Implies: New file. >> - >> -Index: libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c >> -=================================================================== >> ---- /dev/null >> -+++ libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c >> -@@ -0,0 +1,134 @@ >> -+/* Double-precision floating point square root. >> -+ Copyright (C) 2010 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. */ >> -+ >> -+#include <math.h> >> -+#include <math_private.h> >> -+#include <fenv_libc.h> >> -+#include <inttypes.h> >> -+ >> -+#include <sysdep.h> >> -+#include <ldsodefs.h> >> -+ >> -+static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; >> -+static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; >> -+static const float two108 = 3.245185536584267269e+32; >> -+static const float twom54 = 5.551115123125782702e-17; >> -+static const float half = 0.5; >> -+ >> -+/* The method is based on the descriptions in: >> -+ >> -+ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; >> -+ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 >> -+ >> -+ We find the actual square root and half of its reciprocal >> -+ simultaneously. */ >> -+ >> -+#ifdef __STDC__ >> -+double >> -+__ieee754_sqrt (double b) >> -+#else >> -+double >> -+__ieee754_sqrt (b) >> -+ double b; >> -+#endif >> -+{ >> -+ if (__builtin_expect (b > 0, 1)) >> -+ { >> -+ double y, g, h, d, r; >> -+ ieee_double_shape_type u; >> -+ >> -+ if (__builtin_expect (b != a_inf.value, 1)) >> -+ { >> -+ fenv_t fe; >> -+ >> -+ fe = fegetenv_register (); >> -+ >> -+ u.value = b; >> -+ >> -+ relax_fenv_state (); >> -+ >> -+ __asm__ ("frsqrte %[estimate], %[x]\n" >> -+ : [estimate] "=f" (y) : [x] "f" (b)); >> -+ >> -+ /* Following Muller et al, page 168, equation 5.20. >> -+ >> -+ h goes to 1/(2*sqrt(b)) >> -+ g goes to sqrt(b). >> -+ >> -+ We need three iterations to get within 1ulp. */ >> -+ >> -+ /* Indicate that these can be performed prior to the branch. GCC >> -+ insists on sinking them below the branch, however; it seems like >> -+ they'd be better before the branch so that we can cover any latency >> -+ from storing the argument and loading its high word. Oh well. */ >> -+ >> -+ g = b * y; >> -+ h = 0.5 * y; >> -+ >> -+ /* Handle small numbers by scaling. */ >> -+ if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0)) >> -+ return __ieee754_sqrt (b * two108) * twom54; >> -+ >> -+#define FMADD(a_, c_, b_) \ >> -+ ({ double __r; \ >> -+ __asm__ ("fmadd %[r], %[a], %[c], %[b]\n" \ >> -+ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >> -+ __r;}) >> -+#define FNMSUB(a_, c_, b_) \ >> -+ ({ double __r; \ >> -+ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ >> -+ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >> -+ __r;}) >> -+ >> -+ r = FNMSUB (g, h, half); >> -+ g = FMADD (g, r, g); >> -+ h = FMADD (h, r, h); >> -+ >> -+ r = FNMSUB (g, h, half); >> -+ g = FMADD (g, r, g); >> -+ h = FMADD (h, r, h); >> -+ >> -+ r = FNMSUB (g, h, half); >> -+ g = FMADD (g, r, g); >> -+ h = FMADD (h, r, h); >> -+ >> -+ /* g is now +/- 1ulp, or exactly equal to, the square root of b. */ >> -+ >> -+ /* Final refinement. */ >> -+ d = FNMSUB (g, g, b); >> -+ >> -+ fesetenv_register (fe); >> -+ return FMADD (d, h, g); >> -+ } >> -+ } >> -+ else if (b < 0) >> -+ { >> -+ /* For some reason, some PowerPC32 processors don't implement >> -+ FE_INVALID_SQRT. */ >> -+#ifdef FE_INVALID_SQRT >> -+ feraiseexcept (FE_INVALID_SQRT); >> -+ >> -+ fenv_union_t u = { .fenv = fegetenv_register () }; >> -+ if ((u.l[1] & FE_INVALID) == 0) >> -+#endif >> -+ feraiseexcept (FE_INVALID); >> -+ b = a_nan.value; >> -+ } >> -+ return f_wash (b); >> -+} >> -Index: libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c >> -=================================================================== >> ---- /dev/null >> -+++ libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c >> -@@ -0,0 +1,101 @@ >> -+/* Single-precision floating point square root. >> -+ Copyright (C) 2010 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. */ >> -+ >> -+#include <math.h> >> -+#include <math_private.h> >> -+#include <fenv_libc.h> >> -+#include <inttypes.h> >> -+ >> -+#include <sysdep.h> >> -+#include <ldsodefs.h> >> -+ >> -+static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; >> -+static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; >> -+static const float threehalf = 1.5; >> -+ >> -+/* The method is based on the descriptions in: >> -+ >> -+ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; >> -+ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 >> -+ >> -+ We find the reciprocal square root and use that to compute the actual >> -+ square root. */ >> -+ >> -+#ifdef __STDC__ >> -+float >> -+__ieee754_sqrtf (float b) >> -+#else >> -+float >> -+__ieee754_sqrtf (b) >> -+ float b; >> -+#endif >> -+{ >> -+ if (__builtin_expect (b > 0, 1)) >> -+ { >> -+#define FMSUB(a_, c_, b_) \ >> -+ ({ double __r; \ >> -+ __asm__ ("fmsub %[r], %[a], %[c], %[b]\n" \ >> -+ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >> -+ __r;}) >> -+#define FNMSUB(a_, c_, b_) \ >> -+ ({ double __r; \ >> -+ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ >> -+ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >> -+ __r;}) >> -+ >> -+ if (__builtin_expect (b != a_inf.value, 1)) >> -+ { >> -+ double y, x; >> -+ fenv_t fe; >> -+ >> -+ fe = fegetenv_register (); >> -+ >> -+ relax_fenv_state (); >> -+ >> -+ /* Compute y = 1.5 * b - b. Uses fewer constants than y = 0.5 * b. */ >> -+ y = FMSUB (threehalf, b, b); >> -+ >> -+ /* Initial estimate. */ >> -+ __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b)); >> -+ >> -+ /* Iterate. x_{n+1} = x_n * (1.5 - y * (x_n * x_n)). */ >> -+ x = x * FNMSUB (y, x * x, threehalf); >> -+ x = x * FNMSUB (y, x * x, threehalf); >> -+ x = x * FNMSUB (y, x * x, threehalf); >> -+ >> -+ /* All done. */ >> -+ fesetenv_register (fe); >> -+ return x * b; >> -+ } >> -+ } >> -+ else if (b < 0) >> -+ { >> -+ /* For some reason, some PowerPC32 processors don't implement >> -+ FE_INVALID_SQRT. */ >> -+#ifdef FE_INVALID_SQRT >> -+ feraiseexcept (FE_INVALID_SQRT); >> -+ >> -+ fenv_union_t u = { .fenv = fegetenv_register () }; >> -+ if ((u.l[1] & FE_INVALID) == 0) >> -+#endif >> -+ feraiseexcept (FE_INVALID); >> -+ b = a_nan.value; >> -+ } >> -+ return f_washf (b); >> -+} >> -Index: libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c >> -=================================================================== >> ---- /dev/null >> -+++ libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c >> -@@ -0,0 +1,134 @@ >> -+/* Double-precision floating point square root. >> -+ Copyright (C) 2010 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. */ >> -+ >> -+#include <math.h> >> -+#include <math_private.h> >> -+#include <fenv_libc.h> >> -+#include <inttypes.h> >> -+ >> -+#include <sysdep.h> >> -+#include <ldsodefs.h> >> -+ >> -+static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; >> -+static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; >> -+static const float two108 = 3.245185536584267269e+32; >> -+static const float twom54 = 5.551115123125782702e-17; >> -+static const float half = 0.5; >> -+ >> -+/* The method is based on the descriptions in: >> -+ >> -+ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; >> -+ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 >> -+ >> -+ We find the actual square root and half of its reciprocal >> -+ simultaneously. */ >> -+ >> -+#ifdef __STDC__ >> -+double >> -+__ieee754_sqrt (double b) >> -+#else >> -+double >> -+__ieee754_sqrt (b) >> -+ double b; >> -+#endif >> -+{ >> -+ if (__builtin_expect (b > 0, 1)) >> -+ { >> -+ double y, g, h, d, r; >> -+ ieee_double_shape_type u; >> -+ >> -+ if (__builtin_expect (b != a_inf.value, 1)) >> -+ { >> -+ fenv_t fe; >> -+ >> -+ fe = fegetenv_register (); >> -+ >> -+ u.value = b; >> -+ >> -+ relax_fenv_state (); >> -+ >> -+ __asm__ ("frsqrte %[estimate], %[x]\n" >> -+ : [estimate] "=f" (y) : [x] "f" (b)); >> -+ >> -+ /* Following Muller et al, page 168, equation 5.20. >> -+ >> -+ h goes to 1/(2*sqrt(b)) >> -+ g goes to sqrt(b). >> -+ >> -+ We need three iterations to get within 1ulp. */ >> -+ >> -+ /* Indicate that these can be performed prior to the branch. GCC >> -+ insists on sinking them below the branch, however; it seems like >> -+ they'd be better before the branch so that we can cover any latency >> -+ from storing the argument and loading its high word. Oh well. */ >> -+ >> -+ g = b * y; >> -+ h = 0.5 * y; >> -+ >> -+ /* Handle small numbers by scaling. */ >> -+ if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0)) >> -+ return __ieee754_sqrt (b * two108) * twom54; >> -+ >> -+#define FMADD(a_, c_, b_) \ >> -+ ({ double __r; \ >> -+ __asm__ ("fmadd %[r], %[a], %[c], %[b]\n" \ >> -+ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >> -+ __r;}) >> -+#define FNMSUB(a_, c_, b_) \ >> -+ ({ double __r; \ >> -+ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ >> -+ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >> -+ __r;}) >> -+ >> -+ r = FNMSUB (g, h, half); >> -+ g = FMADD (g, r, g); >> -+ h = FMADD (h, r, h); >> -+ >> -+ r = FNMSUB (g, h, half); >> -+ g = FMADD (g, r, g); >> -+ h = FMADD (h, r, h); >> -+ >> -+ r = FNMSUB (g, h, half); >> -+ g = FMADD (g, r, g); >> -+ h = FMADD (h, r, h); >> -+ >> -+ /* g is now +/- 1ulp, or exactly equal to, the square root of b. */ >> -+ >> -+ /* Final refinement. */ >> -+ d = FNMSUB (g, g, b); >> -+ >> -+ fesetenv_register (fe); >> -+ return FMADD (d, h, g); >> -+ } >> -+ } >> -+ else if (b < 0) >> -+ { >> -+ /* For some reason, some PowerPC32 processors don't implement >> -+ FE_INVALID_SQRT. */ >> -+#ifdef FE_INVALID_SQRT >> -+ feraiseexcept (FE_INVALID_SQRT); >> -+ >> -+ fenv_union_t u = { .fenv = fegetenv_register () }; >> -+ if ((u.l[1] & FE_INVALID) == 0) >> -+#endif >> -+ feraiseexcept (FE_INVALID); >> -+ b = a_nan.value; >> -+ } >> -+ return f_wash (b); >> -+} >> -Index: libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c >> -=================================================================== >> ---- /dev/null >> -+++ libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c >> -@@ -0,0 +1,101 @@ >> -+/* Single-precision floating point square root. >> -+ Copyright (C) 2010 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. */ >> -+ >> -+#include <math.h> >> -+#include <math_private.h> >> -+#include <fenv_libc.h> >> -+#include <inttypes.h> >> -+ >> -+#include <sysdep.h> >> -+#include <ldsodefs.h> >> -+ >> -+static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; >> -+static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; >> -+static const float threehalf = 1.5; >> -+ >> -+/* The method is based on the descriptions in: >> -+ >> -+ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; >> -+ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 >> -+ >> -+ We find the reciprocal square root and use that to compute the actual >> -+ square root. */ >> -+ >> -+#ifdef __STDC__ >> -+float >> -+__ieee754_sqrtf (float b) >> -+#else >> -+float >> -+__ieee754_sqrtf (b) >> -+ float b; >> -+#endif >> -+{ >> -+ if (__builtin_expect (b > 0, 1)) >> -+ { >> -+#define FMSUB(a_, c_, b_) \ >> -+ ({ double __r; \ >> -+ __asm__ ("fmsub %[r], %[a], %[c], %[b]\n" \ >> -+ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >> -+ __r;}) >> -+#define FNMSUB(a_, c_, b_) \ >> -+ ({ double __r; \ >> -+ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ >> -+ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >> -+ __r;}) >> -+ >> -+ if (__builtin_expect (b != a_inf.value, 1)) >> -+ { >> -+ double y, x; >> -+ fenv_t fe; >> -+ >> -+ fe = fegetenv_register (); >> -+ >> -+ relax_fenv_state (); >> -+ >> -+ /* Compute y = 1.5 * b - b. Uses fewer constants than y = 0.5 * b. */ >> -+ y = FMSUB (threehalf, b, b); >> -+ >> -+ /* Initial estimate. */ >> -+ __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b)); >> -+ >> -+ /* Iterate. x_{n+1} = x_n * (1.5 - y * (x_n * x_n)). */ >> -+ x = x * FNMSUB (y, x * x, threehalf); >> -+ x = x * FNMSUB (y, x * x, threehalf); >> -+ x = x * FNMSUB (y, x * x, threehalf); >> -+ >> -+ /* All done. */ >> -+ fesetenv_register (fe); >> -+ return x * b; >> -+ } >> -+ } >> -+ else if (b < 0) >> -+ { >> -+ /* For some reason, some PowerPC32 processors don't implement >> -+ FE_INVALID_SQRT. */ >> -+#ifdef FE_INVALID_SQRT >> -+ feraiseexcept (FE_INVALID_SQRT); >> -+ >> -+ fenv_union_t u = { .fenv = fegetenv_register () }; >> -+ if ((u.l[1] & FE_INVALID) == 0) >> -+#endif >> -+ feraiseexcept (FE_INVALID); >> -+ b = a_nan.value; >> -+ } >> -+ return f_washf (b); >> -+} >> -Index: libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/603e/fpu/Implies >> -=================================================================== >> ---- /dev/null >> -+++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/603e/fpu/Implies >> -@@ -0,0 +1 @@ >> -+powerpc/powerpc32/603e/fpu >> -Index: libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/7400/fpu/Implies >> -=================================================================== >> ---- /dev/null >> -+++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/7400/fpu/Implies >> -@@ -0,0 +1 @@ >> -+powerpc/powerpc32/603e/fpu >> -Index: libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e500mc/fpu/Implies >> -=================================================================== >> ---- /dev/null >> -+++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e500mc/fpu/Implies >> -@@ -0,0 +1 @@ >> -+powerpc/powerpc32/603e/fpu >> -Index: libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/e5500/fpu/Implies >> -=================================================================== >> ---- /dev/null >> -+++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/e5500/fpu/Implies >> -@@ -0,0 +1 @@ >> -+powerpc/powerpc64/e5500/fpu >> -Index: libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e5500/fpu/Implies >> -=================================================================== >> ---- /dev/null >> -+++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e5500/fpu/Implies >> -@@ -0,0 +1 @@ >> -+powerpc/powerpc32/603e/fpu >> diff --git a/meta/recipes-core/eglibc/eglibc_2.16.bb b/meta/recipes-core/eglibc/eglibc_2.16.bb >> index 78dc44a..a753882 100644 >> --- a/meta/recipes-core/eglibc/eglibc_2.16.bb >> +++ b/meta/recipes-core/eglibc/eglibc_2.16.bb >> @@ -3,7 +3,7 @@ require eglibc.inc >> SRCREV = "20393" >> >> DEPENDS += "gperf-native kconfig-frontends-native" >> -PR = "r9" >> +PR = "r10" >> PR_append = "+svnr${SRCPV}" >> >> EGLIBC_BRANCH="eglibc-2_16" >> @@ -13,7 +13,7 @@ SRC_URI = "svn://www.eglibc.org/svn/branches/;module=${EGLIBC_BRANCH};protocol=h >> file://mips-rld-map-check.patch \ >> file://etc/ld.so.conf \ >> file://generate-supported.mk \ >> - file://ppc-sqrt.patch \ >> + file://glibc.fix_sqrt2.patch \ >> file://multilib_readlib.patch \ >> file://use-sysroot-cxx-headers.patch \ >> file://ppc-sqrt_finite.patch \ >> -- >> 1.7.9.7 >> >> >> >> _______________________________________________ >> Openembedded-core mailing list >> Openembedded-core@lists.openembedded.org >> http://lists.linuxtogo.org/cgi-bin/mailman/listinfo/openembedded-core > > _______________________________________________ > Openembedded-core mailing list > Openembedded-core@lists.openembedded.org > http://lists.linuxtogo.org/cgi-bin/mailman/listinfo/openembedded-core
On Tue, Sep 18, 2012 at 5:16 PM, Khem Raj <raj.khem@gmail.com> wrote: > On Tue, Sep 18, 2012 at 3:12 PM, McClintock Matthew-B29882 > <B29882@freescale.com> wrote: >> Err this was supposed to be a series but I used the wrong format-patch >> commands, patches in my tree here: >> >> http://git.yoctoproject.org/cgit/cgit.cgi/poky-contrib/log/?h=mattsm/master >> > > what changes are needed for e6500 ? can these files be shadowed from e5500 ? > I am confused with the two patches It's just renaming the patch, so it's replacing ppc-sqrt.patch with glibc.fix_sqrt2.patch - and these are not authored by me... which I realize I forgot to add upstream-status as well. Back to the patches themselves, ppc-sqrt seemed to be a subset of glibc.fix_sqrt2.patch or am I wrong? As far as shadowing I'm not sure, I'd rather not spend time testing that, these patches are used/tested internally. -M > > >> -M >> >> On Tue, Sep 18, 2012 at 5:08 PM, Matthew McClintock <msm@freescale.com> wrote: >>> Signed-off-by: Matthew McClintock <msm@freescale.com> >>> --- >>> .../eglibc/eglibc-2.16/glibc.fix_sqrt2.patch | 1488 ++++++++++++++++++++ >>> .../recipes-core/eglibc/eglibc-2.16/ppc-sqrt.patch | 538 ------- >>> meta/recipes-core/eglibc/eglibc_2.16.bb | 4 +- >>> 3 files changed, 1490 insertions(+), 540 deletions(-) >>> create mode 100644 meta/recipes-core/eglibc/eglibc-2.16/glibc.fix_sqrt2.patch >>> delete mode 100644 meta/recipes-core/eglibc/eglibc-2.16/ppc-sqrt.patch >>> >>> diff --git a/meta/recipes-core/eglibc/eglibc-2.16/glibc.fix_sqrt2.patch b/meta/recipes-core/eglibc/eglibc-2.16/glibc.fix_sqrt2.patch >>> new file mode 100644 >>> index 0000000..e098192 >>> --- /dev/null >>> +++ b/meta/recipes-core/eglibc/eglibc-2.16/glibc.fix_sqrt2.patch >>> @@ -0,0 +1,1488 @@ >>> +diff -ruN libc-orig/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c >>> +--- libc-orig/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c 1969-12-31 18:00:00.000000000 -0600 >>> ++++ libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c 2012-06-14 14:51:50.452001745 -0500 >>> +@@ -0,0 +1,134 @@ >>> ++/* Double-precision floating point square root. >>> ++ Copyright (C) 2010 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. */ >>> ++ >>> ++#include <math.h> >>> ++#include <math_private.h> >>> ++#include <fenv_libc.h> >>> ++#include <inttypes.h> >>> ++ >>> ++#include <sysdep.h> >>> ++#include <ldsodefs.h> >>> ++ >>> ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; >>> ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; >>> ++static const float two108 = 3.245185536584267269e+32; >>> ++static const float twom54 = 5.551115123125782702e-17; >>> ++static const float half = 0.5; >>> ++ >>> ++/* The method is based on the descriptions in: >>> ++ >>> ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; >>> ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 >>> ++ >>> ++ We find the actual square root and half of its reciprocal >>> ++ simultaneously. */ >>> ++ >>> ++#ifdef __STDC__ >>> ++double >>> ++__ieee754_sqrt (double b) >>> ++#else >>> ++double >>> ++__ieee754_sqrt (b) >>> ++ double b; >>> ++#endif >>> ++{ >>> ++ if (__builtin_expect (b > 0, 1)) >>> ++ { >>> ++ double y, g, h, d, r; >>> ++ ieee_double_shape_type u; >>> ++ >>> ++ if (__builtin_expect (b != a_inf.value, 1)) >>> ++ { >>> ++ fenv_t fe; >>> ++ >>> ++ fe = fegetenv_register (); >>> ++ >>> ++ u.value = b; >>> ++ >>> ++ relax_fenv_state (); >>> ++ >>> ++ __asm__ ("frsqrte %[estimate], %[x]\n" >>> ++ : [estimate] "=f" (y) : [x] "f" (b)); >>> ++ >>> ++ /* Following Muller et al, page 168, equation 5.20. >>> ++ >>> ++ h goes to 1/(2*sqrt(b)) >>> ++ g goes to sqrt(b). >>> ++ >>> ++ We need three iterations to get within 1ulp. */ >>> ++ >>> ++ /* Indicate that these can be performed prior to the branch. GCC >>> ++ insists on sinking them below the branch, however; it seems like >>> ++ they'd be better before the branch so that we can cover any latency >>> ++ from storing the argument and loading its high word. Oh well. */ >>> ++ >>> ++ g = b * y; >>> ++ h = 0.5 * y; >>> ++ >>> ++ /* Handle small numbers by scaling. */ >>> ++ if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0)) >>> ++ return __ieee754_sqrt (b * two108) * twom54; >>> ++ >>> ++#define FMADD(a_, c_, b_) \ >>> ++ ({ double __r; \ >>> ++ __asm__ ("fmadd %[r], %[a], %[c], %[b]\n" \ >>> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >>> ++ __r;}) >>> ++#define FNMSUB(a_, c_, b_) \ >>> ++ ({ double __r; \ >>> ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ >>> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >>> ++ __r;}) >>> ++ >>> ++ r = FNMSUB (g, h, half); >>> ++ g = FMADD (g, r, g); >>> ++ h = FMADD (h, r, h); >>> ++ >>> ++ r = FNMSUB (g, h, half); >>> ++ g = FMADD (g, r, g); >>> ++ h = FMADD (h, r, h); >>> ++ >>> ++ r = FNMSUB (g, h, half); >>> ++ g = FMADD (g, r, g); >>> ++ h = FMADD (h, r, h); >>> ++ >>> ++ /* g is now +/- 1ulp, or exactly equal to, the square root of b. */ >>> ++ >>> ++ /* Final refinement. */ >>> ++ d = FNMSUB (g, g, b); >>> ++ >>> ++ fesetenv_register (fe); >>> ++ return FMADD (d, h, g); >>> ++ } >>> ++ } >>> ++ else if (b < 0) >>> ++ { >>> ++ /* For some reason, some PowerPC32 processors don't implement >>> ++ FE_INVALID_SQRT. */ >>> ++#ifdef FE_INVALID_SQRT >>> ++ feraiseexcept (FE_INVALID_SQRT); >>> ++ >>> ++ fenv_union_t u = { .fenv = fegetenv_register () }; >>> ++ if ((u.l[1] & FE_INVALID) == 0) >>> ++#endif >>> ++ feraiseexcept (FE_INVALID); >>> ++ b = a_nan.value; >>> ++ } >>> ++ return f_wash (b); >>> ++} >>> +diff -ruN libc-orig/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c >>> +--- libc-orig/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c 1969-12-31 18:00:00.000000000 -0600 >>> ++++ libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c 2012-06-14 14:51:50.452001745 -0500 >>> +@@ -0,0 +1,101 @@ >>> ++/* Single-precision floating point square root. >>> ++ Copyright (C) 2010 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. */ >>> ++ >>> ++#include <math.h> >>> ++#include <math_private.h> >>> ++#include <fenv_libc.h> >>> ++#include <inttypes.h> >>> ++ >>> ++#include <sysdep.h> >>> ++#include <ldsodefs.h> >>> ++ >>> ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; >>> ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; >>> ++static const float threehalf = 1.5; >>> ++ >>> ++/* The method is based on the descriptions in: >>> ++ >>> ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; >>> ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 >>> ++ >>> ++ We find the reciprocal square root and use that to compute the actual >>> ++ square root. */ >>> ++ >>> ++#ifdef __STDC__ >>> ++float >>> ++__ieee754_sqrtf (float b) >>> ++#else >>> ++float >>> ++__ieee754_sqrtf (b) >>> ++ float b; >>> ++#endif >>> ++{ >>> ++ if (__builtin_expect (b > 0, 1)) >>> ++ { >>> ++#define FMSUB(a_, c_, b_) \ >>> ++ ({ double __r; \ >>> ++ __asm__ ("fmsub %[r], %[a], %[c], %[b]\n" \ >>> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >>> ++ __r;}) >>> ++#define FNMSUB(a_, c_, b_) \ >>> ++ ({ double __r; \ >>> ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ >>> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >>> ++ __r;}) >>> ++ >>> ++ if (__builtin_expect (b != a_inf.value, 1)) >>> ++ { >>> ++ double y, x; >>> ++ fenv_t fe; >>> ++ >>> ++ fe = fegetenv_register (); >>> ++ >>> ++ relax_fenv_state (); >>> ++ >>> ++ /* Compute y = 1.5 * b - b. Uses fewer constants than y = 0.5 * b. */ >>> ++ y = FMSUB (threehalf, b, b); >>> ++ >>> ++ /* Initial estimate. */ >>> ++ __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b)); >>> ++ >>> ++ /* Iterate. x_{n+1} = x_n * (1.5 - y * (x_n * x_n)). */ >>> ++ x = x * FNMSUB (y, x * x, threehalf); >>> ++ x = x * FNMSUB (y, x * x, threehalf); >>> ++ x = x * FNMSUB (y, x * x, threehalf); >>> ++ >>> ++ /* All done. */ >>> ++ fesetenv_register (fe); >>> ++ return x * b; >>> ++ } >>> ++ } >>> ++ else if (b < 0) >>> ++ { >>> ++ /* For some reason, some PowerPC32 processors don't implement >>> ++ FE_INVALID_SQRT. */ >>> ++#ifdef FE_INVALID_SQRT >>> ++ feraiseexcept (FE_INVALID_SQRT); >>> ++ >>> ++ fenv_union_t u = { .fenv = fegetenv_register () }; >>> ++ if ((u.l[1] & FE_INVALID) == 0) >>> ++#endif >>> ++ feraiseexcept (FE_INVALID); >>> ++ b = a_nan.value; >>> ++ } >>> ++ return f_washf (b); >>> ++} >>> +diff -ruN libc-orig/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c libc/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c >>> +--- libc-orig/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c 1969-12-31 18:00:00.000000000 -0600 >>> ++++ libc/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c 2012-06-14 14:55:14.749001061 -0500 >>> +@@ -0,0 +1,134 @@ >>> ++/* Double-precision floating point square root. >>> ++ Copyright (C) 2010 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. */ >>> ++ >>> ++#include <math.h> >>> ++#include <math_private.h> >>> ++#include <fenv_libc.h> >>> ++#include <inttypes.h> >>> ++ >>> ++#include <sysdep.h> >>> ++#include <ldsodefs.h> >>> ++ >>> ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; >>> ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; >>> ++static const float two108 = 3.245185536584267269e+32; >>> ++static const float twom54 = 5.551115123125782702e-17; >>> ++static const float half = 0.5; >>> ++ >>> ++/* The method is based on the descriptions in: >>> ++ >>> ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; >>> ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 >>> ++ >>> ++ We find the actual square root and half of its reciprocal >>> ++ simultaneously. */ >>> ++ >>> ++#ifdef __STDC__ >>> ++double >>> ++__ieee754_sqrt (double b) >>> ++#else >>> ++double >>> ++__ieee754_sqrt (b) >>> ++ double b; >>> ++#endif >>> ++{ >>> ++ if (__builtin_expect (b > 0, 1)) >>> ++ { >>> ++ double y, g, h, d, r; >>> ++ ieee_double_shape_type u; >>> ++ >>> ++ if (__builtin_expect (b != a_inf.value, 1)) >>> ++ { >>> ++ fenv_t fe; >>> ++ >>> ++ fe = fegetenv_register (); >>> ++ >>> ++ u.value = b; >>> ++ >>> ++ relax_fenv_state (); >>> ++ >>> ++ __asm__ ("frsqrte %[estimate], %[x]\n" >>> ++ : [estimate] "=f" (y) : [x] "f" (b)); >>> ++ >>> ++ /* Following Muller et al, page 168, equation 5.20. >>> ++ >>> ++ h goes to 1/(2*sqrt(b)) >>> ++ g goes to sqrt(b). >>> ++ >>> ++ We need three iterations to get within 1ulp. */ >>> ++ >>> ++ /* Indicate that these can be performed prior to the branch. GCC >>> ++ insists on sinking them below the branch, however; it seems like >>> ++ they'd be better before the branch so that we can cover any latency >>> ++ from storing the argument and loading its high word. Oh well. */ >>> ++ >>> ++ g = b * y; >>> ++ h = 0.5 * y; >>> ++ >>> ++ /* Handle small numbers by scaling. */ >>> ++ if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0)) >>> ++ return __ieee754_sqrt (b * two108) * twom54; >>> ++ >>> ++#define FMADD(a_, c_, b_) \ >>> ++ ({ double __r; \ >>> ++ __asm__ ("fmadd %[r], %[a], %[c], %[b]\n" \ >>> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >>> ++ __r;}) >>> ++#define FNMSUB(a_, c_, b_) \ >>> ++ ({ double __r; \ >>> ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ >>> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >>> ++ __r;}) >>> ++ >>> ++ r = FNMSUB (g, h, half); >>> ++ g = FMADD (g, r, g); >>> ++ h = FMADD (h, r, h); >>> ++ >>> ++ r = FNMSUB (g, h, half); >>> ++ g = FMADD (g, r, g); >>> ++ h = FMADD (h, r, h); >>> ++ >>> ++ r = FNMSUB (g, h, half); >>> ++ g = FMADD (g, r, g); >>> ++ h = FMADD (h, r, h); >>> ++ >>> ++ /* g is now +/- 1ulp, or exactly equal to, the square root of b. */ >>> ++ >>> ++ /* Final refinement. */ >>> ++ d = FNMSUB (g, g, b); >>> ++ >>> ++ fesetenv_register (fe); >>> ++ return FMADD (d, h, g); >>> ++ } >>> ++ } >>> ++ else if (b < 0) >>> ++ { >>> ++ /* For some reason, some PowerPC32 processors don't implement >>> ++ FE_INVALID_SQRT. */ >>> ++#ifdef FE_INVALID_SQRT >>> ++ feraiseexcept (FE_INVALID_SQRT); >>> ++ >>> ++ fenv_union_t u = { .fenv = fegetenv_register () }; >>> ++ if ((u.l[1] & FE_INVALID) == 0) >>> ++#endif >>> ++ feraiseexcept (FE_INVALID); >>> ++ b = a_nan.value; >>> ++ } >>> ++ return f_wash (b); >>> ++} >>> +diff -ruN libc-orig/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c libc/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c >>> +--- libc-orig/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c 1969-12-31 18:00:00.000000000 -0600 >>> ++++ libc/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c 2012-06-14 14:55:14.749001061 -0500 >>> +@@ -0,0 +1,101 @@ >>> ++/* Single-precision floating point square root. >>> ++ Copyright (C) 2010 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. */ >>> ++ >>> ++#include <math.h> >>> ++#include <math_private.h> >>> ++#include <fenv_libc.h> >>> ++#include <inttypes.h> >>> ++ >>> ++#include <sysdep.h> >>> ++#include <ldsodefs.h> >>> ++ >>> ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; >>> ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; >>> ++static const float threehalf = 1.5; >>> ++ >>> ++/* The method is based on the descriptions in: >>> ++ >>> ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; >>> ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 >>> ++ >>> ++ We find the reciprocal square root and use that to compute the actual >>> ++ square root. */ >>> ++ >>> ++#ifdef __STDC__ >>> ++float >>> ++__ieee754_sqrtf (float b) >>> ++#else >>> ++float >>> ++__ieee754_sqrtf (b) >>> ++ float b; >>> ++#endif >>> ++{ >>> ++ if (__builtin_expect (b > 0, 1)) >>> ++ { >>> ++#define FMSUB(a_, c_, b_) \ >>> ++ ({ double __r; \ >>> ++ __asm__ ("fmsub %[r], %[a], %[c], %[b]\n" \ >>> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >>> ++ __r;}) >>> ++#define FNMSUB(a_, c_, b_) \ >>> ++ ({ double __r; \ >>> ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ >>> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >>> ++ __r;}) >>> ++ >>> ++ if (__builtin_expect (b != a_inf.value, 1)) >>> ++ { >>> ++ double y, x; >>> ++ fenv_t fe; >>> ++ >>> ++ fe = fegetenv_register (); >>> ++ >>> ++ relax_fenv_state (); >>> ++ >>> ++ /* Compute y = 1.5 * b - b. Uses fewer constants than y = 0.5 * b. */ >>> ++ y = FMSUB (threehalf, b, b); >>> ++ >>> ++ /* Initial estimate. */ >>> ++ __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b)); >>> ++ >>> ++ /* Iterate. x_{n+1} = x_n * (1.5 - y * (x_n * x_n)). */ >>> ++ x = x * FNMSUB (y, x * x, threehalf); >>> ++ x = x * FNMSUB (y, x * x, threehalf); >>> ++ x = x * FNMSUB (y, x * x, threehalf); >>> ++ >>> ++ /* All done. */ >>> ++ fesetenv_register (fe); >>> ++ return x * b; >>> ++ } >>> ++ } >>> ++ else if (b < 0) >>> ++ { >>> ++ /* For some reason, some PowerPC32 processors don't implement >>> ++ FE_INVALID_SQRT. */ >>> ++#ifdef FE_INVALID_SQRT >>> ++ feraiseexcept (FE_INVALID_SQRT); >>> ++ >>> ++ fenv_union_t u = { .fenv = fegetenv_register () }; >>> ++ if ((u.l[1] & FE_INVALID) == 0) >>> ++#endif >>> ++ feraiseexcept (FE_INVALID); >>> ++ b = a_nan.value; >>> ++ } >>> ++ return f_washf (b); >>> ++} >>> +diff -ruN libc-orig/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c libc/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c >>> +--- libc-orig/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c 1969-12-31 18:00:00.000000000 -0600 >>> ++++ libc/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c 2012-06-14 14:55:21.812002270 -0500 >>> +@@ -0,0 +1,134 @@ >>> ++/* Double-precision floating point square root. >>> ++ Copyright (C) 2010 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. */ >>> ++ >>> ++#include <math.h> >>> ++#include <math_private.h> >>> ++#include <fenv_libc.h> >>> ++#include <inttypes.h> >>> ++ >>> ++#include <sysdep.h> >>> ++#include <ldsodefs.h> >>> ++ >>> ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; >>> ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; >>> ++static const float two108 = 3.245185536584267269e+32; >>> ++static const float twom54 = 5.551115123125782702e-17; >>> ++static const float half = 0.5; >>> ++ >>> ++/* The method is based on the descriptions in: >>> ++ >>> ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; >>> ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 >>> ++ >>> ++ We find the actual square root and half of its reciprocal >>> ++ simultaneously. */ >>> ++ >>> ++#ifdef __STDC__ >>> ++double >>> ++__ieee754_sqrt (double b) >>> ++#else >>> ++double >>> ++__ieee754_sqrt (b) >>> ++ double b; >>> ++#endif >>> ++{ >>> ++ if (__builtin_expect (b > 0, 1)) >>> ++ { >>> ++ double y, g, h, d, r; >>> ++ ieee_double_shape_type u; >>> ++ >>> ++ if (__builtin_expect (b != a_inf.value, 1)) >>> ++ { >>> ++ fenv_t fe; >>> ++ >>> ++ fe = fegetenv_register (); >>> ++ >>> ++ u.value = b; >>> ++ >>> ++ relax_fenv_state (); >>> ++ >>> ++ __asm__ ("frsqrte %[estimate], %[x]\n" >>> ++ : [estimate] "=f" (y) : [x] "f" (b)); >>> ++ >>> ++ /* Following Muller et al, page 168, equation 5.20. >>> ++ >>> ++ h goes to 1/(2*sqrt(b)) >>> ++ g goes to sqrt(b). >>> ++ >>> ++ We need three iterations to get within 1ulp. */ >>> ++ >>> ++ /* Indicate that these can be performed prior to the branch. GCC >>> ++ insists on sinking them below the branch, however; it seems like >>> ++ they'd be better before the branch so that we can cover any latency >>> ++ from storing the argument and loading its high word. Oh well. */ >>> ++ >>> ++ g = b * y; >>> ++ h = 0.5 * y; >>> ++ >>> ++ /* Handle small numbers by scaling. */ >>> ++ if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0)) >>> ++ return __ieee754_sqrt (b * two108) * twom54; >>> ++ >>> ++#define FMADD(a_, c_, b_) \ >>> ++ ({ double __r; \ >>> ++ __asm__ ("fmadd %[r], %[a], %[c], %[b]\n" \ >>> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >>> ++ __r;}) >>> ++#define FNMSUB(a_, c_, b_) \ >>> ++ ({ double __r; \ >>> ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ >>> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >>> ++ __r;}) >>> ++ >>> ++ r = FNMSUB (g, h, half); >>> ++ g = FMADD (g, r, g); >>> ++ h = FMADD (h, r, h); >>> ++ >>> ++ r = FNMSUB (g, h, half); >>> ++ g = FMADD (g, r, g); >>> ++ h = FMADD (h, r, h); >>> ++ >>> ++ r = FNMSUB (g, h, half); >>> ++ g = FMADD (g, r, g); >>> ++ h = FMADD (h, r, h); >>> ++ >>> ++ /* g is now +/- 1ulp, or exactly equal to, the square root of b. */ >>> ++ >>> ++ /* Final refinement. */ >>> ++ d = FNMSUB (g, g, b); >>> ++ >>> ++ fesetenv_register (fe); >>> ++ return FMADD (d, h, g); >>> ++ } >>> ++ } >>> ++ else if (b < 0) >>> ++ { >>> ++ /* For some reason, some PowerPC32 processors don't implement >>> ++ FE_INVALID_SQRT. */ >>> ++#ifdef FE_INVALID_SQRT >>> ++ feraiseexcept (FE_INVALID_SQRT); >>> ++ >>> ++ fenv_union_t u = { .fenv = fegetenv_register () }; >>> ++ if ((u.l[1] & FE_INVALID) == 0) >>> ++#endif >>> ++ feraiseexcept (FE_INVALID); >>> ++ b = a_nan.value; >>> ++ } >>> ++ return f_wash (b); >>> ++} >>> +diff -ruN libc-orig/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c libc/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c >>> +--- libc-orig/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c 1969-12-31 18:00:00.000000000 -0600 >>> ++++ libc/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c 2012-06-14 14:55:21.812002270 -0500 >>> +@@ -0,0 +1,101 @@ >>> ++/* Single-precision floating point square root. >>> ++ Copyright (C) 2010 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. */ >>> ++ >>> ++#include <math.h> >>> ++#include <math_private.h> >>> ++#include <fenv_libc.h> >>> ++#include <inttypes.h> >>> ++ >>> ++#include <sysdep.h> >>> ++#include <ldsodefs.h> >>> ++ >>> ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; >>> ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; >>> ++static const float threehalf = 1.5; >>> ++ >>> ++/* The method is based on the descriptions in: >>> ++ >>> ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; >>> ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 >>> ++ >>> ++ We find the reciprocal square root and use that to compute the actual >>> ++ square root. */ >>> ++ >>> ++#ifdef __STDC__ >>> ++float >>> ++__ieee754_sqrtf (float b) >>> ++#else >>> ++float >>> ++__ieee754_sqrtf (b) >>> ++ float b; >>> ++#endif >>> ++{ >>> ++ if (__builtin_expect (b > 0, 1)) >>> ++ { >>> ++#define FMSUB(a_, c_, b_) \ >>> ++ ({ double __r; \ >>> ++ __asm__ ("fmsub %[r], %[a], %[c], %[b]\n" \ >>> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >>> ++ __r;}) >>> ++#define FNMSUB(a_, c_, b_) \ >>> ++ ({ double __r; \ >>> ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ >>> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >>> ++ __r;}) >>> ++ >>> ++ if (__builtin_expect (b != a_inf.value, 1)) >>> ++ { >>> ++ double y, x; >>> ++ fenv_t fe; >>> ++ >>> ++ fe = fegetenv_register (); >>> ++ >>> ++ relax_fenv_state (); >>> ++ >>> ++ /* Compute y = 1.5 * b - b. Uses fewer constants than y = 0.5 * b. */ >>> ++ y = FMSUB (threehalf, b, b); >>> ++ >>> ++ /* Initial estimate. */ >>> ++ __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b)); >>> ++ >>> ++ /* Iterate. x_{n+1} = x_n * (1.5 - y * (x_n * x_n)). */ >>> ++ x = x * FNMSUB (y, x * x, threehalf); >>> ++ x = x * FNMSUB (y, x * x, threehalf); >>> ++ x = x * FNMSUB (y, x * x, threehalf); >>> ++ >>> ++ /* All done. */ >>> ++ fesetenv_register (fe); >>> ++ return x * b; >>> ++ } >>> ++ } >>> ++ else if (b < 0) >>> ++ { >>> ++ /* For some reason, some PowerPC32 processors don't implement >>> ++ FE_INVALID_SQRT. */ >>> ++#ifdef FE_INVALID_SQRT >>> ++ feraiseexcept (FE_INVALID_SQRT); >>> ++ >>> ++ fenv_union_t u = { .fenv = fegetenv_register () }; >>> ++ if ((u.l[1] & FE_INVALID) == 0) >>> ++#endif >>> ++ feraiseexcept (FE_INVALID); >>> ++ b = a_nan.value; >>> ++ } >>> ++ return f_washf (b); >>> ++} >>> +diff -ruN libc-orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c >>> +--- libc-orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c 1969-12-31 18:00:00.000000000 -0600 >>> ++++ libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c 2012-06-14 14:55:24.620001266 -0500 >>> +@@ -0,0 +1,134 @@ >>> ++/* Double-precision floating point square root. >>> ++ Copyright (C) 2010 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. */ >>> ++ >>> ++#include <math.h> >>> ++#include <math_private.h> >>> ++#include <fenv_libc.h> >>> ++#include <inttypes.h> >>> ++ >>> ++#include <sysdep.h> >>> ++#include <ldsodefs.h> >>> ++ >>> ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; >>> ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; >>> ++static const float two108 = 3.245185536584267269e+32; >>> ++static const float twom54 = 5.551115123125782702e-17; >>> ++static const float half = 0.5; >>> ++ >>> ++/* The method is based on the descriptions in: >>> ++ >>> ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; >>> ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 >>> ++ >>> ++ We find the actual square root and half of its reciprocal >>> ++ simultaneously. */ >>> ++ >>> ++#ifdef __STDC__ >>> ++double >>> ++__ieee754_sqrt (double b) >>> ++#else >>> ++double >>> ++__ieee754_sqrt (b) >>> ++ double b; >>> ++#endif >>> ++{ >>> ++ if (__builtin_expect (b > 0, 1)) >>> ++ { >>> ++ double y, g, h, d, r; >>> ++ ieee_double_shape_type u; >>> ++ >>> ++ if (__builtin_expect (b != a_inf.value, 1)) >>> ++ { >>> ++ fenv_t fe; >>> ++ >>> ++ fe = fegetenv_register (); >>> ++ >>> ++ u.value = b; >>> ++ >>> ++ relax_fenv_state (); >>> ++ >>> ++ __asm__ ("frsqrte %[estimate], %[x]\n" >>> ++ : [estimate] "=f" (y) : [x] "f" (b)); >>> ++ >>> ++ /* Following Muller et al, page 168, equation 5.20. >>> ++ >>> ++ h goes to 1/(2*sqrt(b)) >>> ++ g goes to sqrt(b). >>> ++ >>> ++ We need three iterations to get within 1ulp. */ >>> ++ >>> ++ /* Indicate that these can be performed prior to the branch. GCC >>> ++ insists on sinking them below the branch, however; it seems like >>> ++ they'd be better before the branch so that we can cover any latency >>> ++ from storing the argument and loading its high word. Oh well. */ >>> ++ >>> ++ g = b * y; >>> ++ h = 0.5 * y; >>> ++ >>> ++ /* Handle small numbers by scaling. */ >>> ++ if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0)) >>> ++ return __ieee754_sqrt (b * two108) * twom54; >>> ++ >>> ++#define FMADD(a_, c_, b_) \ >>> ++ ({ double __r; \ >>> ++ __asm__ ("fmadd %[r], %[a], %[c], %[b]\n" \ >>> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >>> ++ __r;}) >>> ++#define FNMSUB(a_, c_, b_) \ >>> ++ ({ double __r; \ >>> ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ >>> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >>> ++ __r;}) >>> ++ >>> ++ r = FNMSUB (g, h, half); >>> ++ g = FMADD (g, r, g); >>> ++ h = FMADD (h, r, h); >>> ++ >>> ++ r = FNMSUB (g, h, half); >>> ++ g = FMADD (g, r, g); >>> ++ h = FMADD (h, r, h); >>> ++ >>> ++ r = FNMSUB (g, h, half); >>> ++ g = FMADD (g, r, g); >>> ++ h = FMADD (h, r, h); >>> ++ >>> ++ /* g is now +/- 1ulp, or exactly equal to, the square root of b. */ >>> ++ >>> ++ /* Final refinement. */ >>> ++ d = FNMSUB (g, g, b); >>> ++ >>> ++ fesetenv_register (fe); >>> ++ return FMADD (d, h, g); >>> ++ } >>> ++ } >>> ++ else if (b < 0) >>> ++ { >>> ++ /* For some reason, some PowerPC32 processors don't implement >>> ++ FE_INVALID_SQRT. */ >>> ++#ifdef FE_INVALID_SQRT >>> ++ feraiseexcept (FE_INVALID_SQRT); >>> ++ >>> ++ fenv_union_t u = { .fenv = fegetenv_register () }; >>> ++ if ((u.l[1] & FE_INVALID) == 0) >>> ++#endif >>> ++ feraiseexcept (FE_INVALID); >>> ++ b = a_nan.value; >>> ++ } >>> ++ return f_wash (b); >>> ++} >>> +diff -ruN libc-orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c >>> +--- libc-orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c 1969-12-31 18:00:00.000000000 -0600 >>> ++++ libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c 2012-06-14 14:55:24.620001266 -0500 >>> +@@ -0,0 +1,101 @@ >>> ++/* Single-precision floating point square root. >>> ++ Copyright (C) 2010 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. */ >>> ++ >>> ++#include <math.h> >>> ++#include <math_private.h> >>> ++#include <fenv_libc.h> >>> ++#include <inttypes.h> >>> ++ >>> ++#include <sysdep.h> >>> ++#include <ldsodefs.h> >>> ++ >>> ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; >>> ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; >>> ++static const float threehalf = 1.5; >>> ++ >>> ++/* The method is based on the descriptions in: >>> ++ >>> ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; >>> ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 >>> ++ >>> ++ We find the reciprocal square root and use that to compute the actual >>> ++ square root. */ >>> ++ >>> ++#ifdef __STDC__ >>> ++float >>> ++__ieee754_sqrtf (float b) >>> ++#else >>> ++float >>> ++__ieee754_sqrtf (b) >>> ++ float b; >>> ++#endif >>> ++{ >>> ++ if (__builtin_expect (b > 0, 1)) >>> ++ { >>> ++#define FMSUB(a_, c_, b_) \ >>> ++ ({ double __r; \ >>> ++ __asm__ ("fmsub %[r], %[a], %[c], %[b]\n" \ >>> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >>> ++ __r;}) >>> ++#define FNMSUB(a_, c_, b_) \ >>> ++ ({ double __r; \ >>> ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ >>> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >>> ++ __r;}) >>> ++ >>> ++ if (__builtin_expect (b != a_inf.value, 1)) >>> ++ { >>> ++ double y, x; >>> ++ fenv_t fe; >>> ++ >>> ++ fe = fegetenv_register (); >>> ++ >>> ++ relax_fenv_state (); >>> ++ >>> ++ /* Compute y = 1.5 * b - b. Uses fewer constants than y = 0.5 * b. */ >>> ++ y = FMSUB (threehalf, b, b); >>> ++ >>> ++ /* Initial estimate. */ >>> ++ __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b)); >>> ++ >>> ++ /* Iterate. x_{n+1} = x_n * (1.5 - y * (x_n * x_n)). */ >>> ++ x = x * FNMSUB (y, x * x, threehalf); >>> ++ x = x * FNMSUB (y, x * x, threehalf); >>> ++ x = x * FNMSUB (y, x * x, threehalf); >>> ++ >>> ++ /* All done. */ >>> ++ fesetenv_register (fe); >>> ++ return x * b; >>> ++ } >>> ++ } >>> ++ else if (b < 0) >>> ++ { >>> ++ /* For some reason, some PowerPC32 processors don't implement >>> ++ FE_INVALID_SQRT. */ >>> ++#ifdef FE_INVALID_SQRT >>> ++ feraiseexcept (FE_INVALID_SQRT); >>> ++ >>> ++ fenv_union_t u = { .fenv = fegetenv_register () }; >>> ++ if ((u.l[1] & FE_INVALID) == 0) >>> ++#endif >>> ++ feraiseexcept (FE_INVALID); >>> ++ b = a_nan.value; >>> ++ } >>> ++ return f_washf (b); >>> ++} >>> +diff -ruN libc-orig/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c >>> +--- libc-orig/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c 1969-12-31 18:00:00.000000000 -0600 >>> ++++ libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c 2012-06-14 14:51:50.452001745 -0500 >>> +@@ -0,0 +1,134 @@ >>> ++/* Double-precision floating point square root. >>> ++ Copyright (C) 2010 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. */ >>> ++ >>> ++#include <math.h> >>> ++#include <math_private.h> >>> ++#include <fenv_libc.h> >>> ++#include <inttypes.h> >>> ++ >>> ++#include <sysdep.h> >>> ++#include <ldsodefs.h> >>> ++ >>> ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; >>> ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; >>> ++static const float two108 = 3.245185536584267269e+32; >>> ++static const float twom54 = 5.551115123125782702e-17; >>> ++static const float half = 0.5; >>> ++ >>> ++/* The method is based on the descriptions in: >>> ++ >>> ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; >>> ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 >>> ++ >>> ++ We find the actual square root and half of its reciprocal >>> ++ simultaneously. */ >>> ++ >>> ++#ifdef __STDC__ >>> ++double >>> ++__ieee754_sqrt (double b) >>> ++#else >>> ++double >>> ++__ieee754_sqrt (b) >>> ++ double b; >>> ++#endif >>> ++{ >>> ++ if (__builtin_expect (b > 0, 1)) >>> ++ { >>> ++ double y, g, h, d, r; >>> ++ ieee_double_shape_type u; >>> ++ >>> ++ if (__builtin_expect (b != a_inf.value, 1)) >>> ++ { >>> ++ fenv_t fe; >>> ++ >>> ++ fe = fegetenv_register (); >>> ++ >>> ++ u.value = b; >>> ++ >>> ++ relax_fenv_state (); >>> ++ >>> ++ __asm__ ("frsqrte %[estimate], %[x]\n" >>> ++ : [estimate] "=f" (y) : [x] "f" (b)); >>> ++ >>> ++ /* Following Muller et al, page 168, equation 5.20. >>> ++ >>> ++ h goes to 1/(2*sqrt(b)) >>> ++ g goes to sqrt(b). >>> ++ >>> ++ We need three iterations to get within 1ulp. */ >>> ++ >>> ++ /* Indicate that these can be performed prior to the branch. GCC >>> ++ insists on sinking them below the branch, however; it seems like >>> ++ they'd be better before the branch so that we can cover any latency >>> ++ from storing the argument and loading its high word. Oh well. */ >>> ++ >>> ++ g = b * y; >>> ++ h = 0.5 * y; >>> ++ >>> ++ /* Handle small numbers by scaling. */ >>> ++ if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0)) >>> ++ return __ieee754_sqrt (b * two108) * twom54; >>> ++ >>> ++#define FMADD(a_, c_, b_) \ >>> ++ ({ double __r; \ >>> ++ __asm__ ("fmadd %[r], %[a], %[c], %[b]\n" \ >>> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >>> ++ __r;}) >>> ++#define FNMSUB(a_, c_, b_) \ >>> ++ ({ double __r; \ >>> ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ >>> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >>> ++ __r;}) >>> ++ >>> ++ r = FNMSUB (g, h, half); >>> ++ g = FMADD (g, r, g); >>> ++ h = FMADD (h, r, h); >>> ++ >>> ++ r = FNMSUB (g, h, half); >>> ++ g = FMADD (g, r, g); >>> ++ h = FMADD (h, r, h); >>> ++ >>> ++ r = FNMSUB (g, h, half); >>> ++ g = FMADD (g, r, g); >>> ++ h = FMADD (h, r, h); >>> ++ >>> ++ /* g is now +/- 1ulp, or exactly equal to, the square root of b. */ >>> ++ >>> ++ /* Final refinement. */ >>> ++ d = FNMSUB (g, g, b); >>> ++ >>> ++ fesetenv_register (fe); >>> ++ return FMADD (d, h, g); >>> ++ } >>> ++ } >>> ++ else if (b < 0) >>> ++ { >>> ++ /* For some reason, some PowerPC32 processors don't implement >>> ++ FE_INVALID_SQRT. */ >>> ++#ifdef FE_INVALID_SQRT >>> ++ feraiseexcept (FE_INVALID_SQRT); >>> ++ >>> ++ fenv_union_t u = { .fenv = fegetenv_register () }; >>> ++ if ((u.l[1] & FE_INVALID) == 0) >>> ++#endif >>> ++ feraiseexcept (FE_INVALID); >>> ++ b = a_nan.value; >>> ++ } >>> ++ return f_wash (b); >>> ++} >>> +diff -ruN libc-orig/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c >>> +--- libc-orig/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c 1969-12-31 18:00:00.000000000 -0600 >>> ++++ libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c 2012-06-14 14:51:50.452001745 -0500 >>> +@@ -0,0 +1,101 @@ >>> ++/* Single-precision floating point square root. >>> ++ Copyright (C) 2010 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. */ >>> ++ >>> ++#include <math.h> >>> ++#include <math_private.h> >>> ++#include <fenv_libc.h> >>> ++#include <inttypes.h> >>> ++ >>> ++#include <sysdep.h> >>> ++#include <ldsodefs.h> >>> ++ >>> ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; >>> ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; >>> ++static const float threehalf = 1.5; >>> ++ >>> ++/* The method is based on the descriptions in: >>> ++ >>> ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; >>> ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 >>> ++ >>> ++ We find the reciprocal square root and use that to compute the actual >>> ++ square root. */ >>> ++ >>> ++#ifdef __STDC__ >>> ++float >>> ++__ieee754_sqrtf (float b) >>> ++#else >>> ++float >>> ++__ieee754_sqrtf (b) >>> ++ float b; >>> ++#endif >>> ++{ >>> ++ if (__builtin_expect (b > 0, 1)) >>> ++ { >>> ++#define FMSUB(a_, c_, b_) \ >>> ++ ({ double __r; \ >>> ++ __asm__ ("fmsub %[r], %[a], %[c], %[b]\n" \ >>> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >>> ++ __r;}) >>> ++#define FNMSUB(a_, c_, b_) \ >>> ++ ({ double __r; \ >>> ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ >>> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >>> ++ __r;}) >>> ++ >>> ++ if (__builtin_expect (b != a_inf.value, 1)) >>> ++ { >>> ++ double y, x; >>> ++ fenv_t fe; >>> ++ >>> ++ fe = fegetenv_register (); >>> ++ >>> ++ relax_fenv_state (); >>> ++ >>> ++ /* Compute y = 1.5 * b - b. Uses fewer constants than y = 0.5 * b. */ >>> ++ y = FMSUB (threehalf, b, b); >>> ++ >>> ++ /* Initial estimate. */ >>> ++ __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b)); >>> ++ >>> ++ /* Iterate. x_{n+1} = x_n * (1.5 - y * (x_n * x_n)). */ >>> ++ x = x * FNMSUB (y, x * x, threehalf); >>> ++ x = x * FNMSUB (y, x * x, threehalf); >>> ++ x = x * FNMSUB (y, x * x, threehalf); >>> ++ >>> ++ /* All done. */ >>> ++ fesetenv_register (fe); >>> ++ return x * b; >>> ++ } >>> ++ } >>> ++ else if (b < 0) >>> ++ { >>> ++ /* For some reason, some PowerPC32 processors don't implement >>> ++ FE_INVALID_SQRT. */ >>> ++#ifdef FE_INVALID_SQRT >>> ++ feraiseexcept (FE_INVALID_SQRT); >>> ++ >>> ++ fenv_union_t u = { .fenv = fegetenv_register () }; >>> ++ if ((u.l[1] & FE_INVALID) == 0) >>> ++#endif >>> ++ feraiseexcept (FE_INVALID); >>> ++ b = a_nan.value; >>> ++ } >>> ++ return f_washf (b); >>> ++} >>> +diff -ruN libc-orig/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c libc/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c >>> +--- libc-orig/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c 1969-12-31 18:00:00.000000000 -0600 >>> ++++ libc/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c 2012-06-14 14:56:02.080000985 -0500 >>> +@@ -0,0 +1,134 @@ >>> ++/* Double-precision floating point square root. >>> ++ Copyright (C) 2010 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. */ >>> ++ >>> ++#include <math.h> >>> ++#include <math_private.h> >>> ++#include <fenv_libc.h> >>> ++#include <inttypes.h> >>> ++ >>> ++#include <sysdep.h> >>> ++#include <ldsodefs.h> >>> ++ >>> ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; >>> ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; >>> ++static const float two108 = 3.245185536584267269e+32; >>> ++static const float twom54 = 5.551115123125782702e-17; >>> ++static const float half = 0.5; >>> ++ >>> ++/* The method is based on the descriptions in: >>> ++ >>> ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; >>> ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 >>> ++ >>> ++ We find the actual square root and half of its reciprocal >>> ++ simultaneously. */ >>> ++ >>> ++#ifdef __STDC__ >>> ++double >>> ++__ieee754_sqrt (double b) >>> ++#else >>> ++double >>> ++__ieee754_sqrt (b) >>> ++ double b; >>> ++#endif >>> ++{ >>> ++ if (__builtin_expect (b > 0, 1)) >>> ++ { >>> ++ double y, g, h, d, r; >>> ++ ieee_double_shape_type u; >>> ++ >>> ++ if (__builtin_expect (b != a_inf.value, 1)) >>> ++ { >>> ++ fenv_t fe; >>> ++ >>> ++ fe = fegetenv_register (); >>> ++ >>> ++ u.value = b; >>> ++ >>> ++ relax_fenv_state (); >>> ++ >>> ++ __asm__ ("frsqrte %[estimate], %[x]\n" >>> ++ : [estimate] "=f" (y) : [x] "f" (b)); >>> ++ >>> ++ /* Following Muller et al, page 168, equation 5.20. >>> ++ >>> ++ h goes to 1/(2*sqrt(b)) >>> ++ g goes to sqrt(b). >>> ++ >>> ++ We need three iterations to get within 1ulp. */ >>> ++ >>> ++ /* Indicate that these can be performed prior to the branch. GCC >>> ++ insists on sinking them below the branch, however; it seems like >>> ++ they'd be better before the branch so that we can cover any latency >>> ++ from storing the argument and loading its high word. Oh well. */ >>> ++ >>> ++ g = b * y; >>> ++ h = 0.5 * y; >>> ++ >>> ++ /* Handle small numbers by scaling. */ >>> ++ if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0)) >>> ++ return __ieee754_sqrt (b * two108) * twom54; >>> ++ >>> ++#define FMADD(a_, c_, b_) \ >>> ++ ({ double __r; \ >>> ++ __asm__ ("fmadd %[r], %[a], %[c], %[b]\n" \ >>> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >>> ++ __r;}) >>> ++#define FNMSUB(a_, c_, b_) \ >>> ++ ({ double __r; \ >>> ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ >>> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >>> ++ __r;}) >>> ++ >>> ++ r = FNMSUB (g, h, half); >>> ++ g = FMADD (g, r, g); >>> ++ h = FMADD (h, r, h); >>> ++ >>> ++ r = FNMSUB (g, h, half); >>> ++ g = FMADD (g, r, g); >>> ++ h = FMADD (h, r, h); >>> ++ >>> ++ r = FNMSUB (g, h, half); >>> ++ g = FMADD (g, r, g); >>> ++ h = FMADD (h, r, h); >>> ++ >>> ++ /* g is now +/- 1ulp, or exactly equal to, the square root of b. */ >>> ++ >>> ++ /* Final refinement. */ >>> ++ d = FNMSUB (g, g, b); >>> ++ >>> ++ fesetenv_register (fe); >>> ++ return FMADD (d, h, g); >>> ++ } >>> ++ } >>> ++ else if (b < 0) >>> ++ { >>> ++ /* For some reason, some PowerPC32 processors don't implement >>> ++ FE_INVALID_SQRT. */ >>> ++#ifdef FE_INVALID_SQRT >>> ++ feraiseexcept (FE_INVALID_SQRT); >>> ++ >>> ++ fenv_union_t u = { .fenv = fegetenv_register () }; >>> ++ if ((u.l[1] & FE_INVALID) == 0) >>> ++#endif >>> ++ feraiseexcept (FE_INVALID); >>> ++ b = a_nan.value; >>> ++ } >>> ++ return f_wash (b); >>> ++} >>> +diff -ruN libc-orig/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c libc/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c >>> +--- libc-orig/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c 1969-12-31 18:00:00.000000000 -0600 >>> ++++ libc/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c 2012-06-14 14:56:02.080000985 -0500 >>> +@@ -0,0 +1,101 @@ >>> ++/* Single-precision floating point square root. >>> ++ Copyright (C) 2010 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. */ >>> ++ >>> ++#include <math.h> >>> ++#include <math_private.h> >>> ++#include <fenv_libc.h> >>> ++#include <inttypes.h> >>> ++ >>> ++#include <sysdep.h> >>> ++#include <ldsodefs.h> >>> ++ >>> ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; >>> ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; >>> ++static const float threehalf = 1.5; >>> ++ >>> ++/* The method is based on the descriptions in: >>> ++ >>> ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; >>> ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 >>> ++ >>> ++ We find the reciprocal square root and use that to compute the actual >>> ++ square root. */ >>> ++ >>> ++#ifdef __STDC__ >>> ++float >>> ++__ieee754_sqrtf (float b) >>> ++#else >>> ++float >>> ++__ieee754_sqrtf (b) >>> ++ float b; >>> ++#endif >>> ++{ >>> ++ if (__builtin_expect (b > 0, 1)) >>> ++ { >>> ++#define FMSUB(a_, c_, b_) \ >>> ++ ({ double __r; \ >>> ++ __asm__ ("fmsub %[r], %[a], %[c], %[b]\n" \ >>> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >>> ++ __r;}) >>> ++#define FNMSUB(a_, c_, b_) \ >>> ++ ({ double __r; \ >>> ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ >>> ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >>> ++ __r;}) >>> ++ >>> ++ if (__builtin_expect (b != a_inf.value, 1)) >>> ++ { >>> ++ double y, x; >>> ++ fenv_t fe; >>> ++ >>> ++ fe = fegetenv_register (); >>> ++ >>> ++ relax_fenv_state (); >>> ++ >>> ++ /* Compute y = 1.5 * b - b. Uses fewer constants than y = 0.5 * b. */ >>> ++ y = FMSUB (threehalf, b, b); >>> ++ >>> ++ /* Initial estimate. */ >>> ++ __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b)); >>> ++ >>> ++ /* Iterate. x_{n+1} = x_n * (1.5 - y * (x_n * x_n)). */ >>> ++ x = x * FNMSUB (y, x * x, threehalf); >>> ++ x = x * FNMSUB (y, x * x, threehalf); >>> ++ x = x * FNMSUB (y, x * x, threehalf); >>> ++ >>> ++ /* All done. */ >>> ++ fesetenv_register (fe); >>> ++ return x * b; >>> ++ } >>> ++ } >>> ++ else if (b < 0) >>> ++ { >>> ++ /* For some reason, some PowerPC32 processors don't implement >>> ++ FE_INVALID_SQRT. */ >>> ++#ifdef FE_INVALID_SQRT >>> ++ feraiseexcept (FE_INVALID_SQRT); >>> ++ >>> ++ fenv_union_t u = { .fenv = fegetenv_register () }; >>> ++ if ((u.l[1] & FE_INVALID) == 0) >>> ++#endif >>> ++ feraiseexcept (FE_INVALID); >>> ++ b = a_nan.value; >>> ++ } >>> ++ return f_washf (b); >>> ++} >>> +diff -ruN libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/603e/fpu/Implies libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/603e/fpu/Implies >>> +--- libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/603e/fpu/Implies 1969-12-31 18:00:00.000000000 -0600 >>> ++++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/603e/fpu/Implies 2012-06-14 14:51:50.452001745 -0500 >>> +@@ -0,0 +1 @@ >>> ++powerpc/powerpc32/603e/fpu >>> +diff -ruN libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/e500mc/fpu/Implies libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e500mc/fpu/Implies >>> +--- libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/e500mc/fpu/Implies 1969-12-31 18:00:00.000000000 -0600 >>> ++++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e500mc/fpu/Implies 2012-06-14 14:54:00.481000876 -0500 >>> +@@ -0,0 +1 @@ >>> ++powerpc/powerpc32/e500mc/fpu >>> +diff -ruN libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/e5500/fpu/Implies libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e5500/fpu/Implies >>> +--- libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/e5500/fpu/Implies 1969-12-31 18:00:00.000000000 -0600 >>> ++++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e5500/fpu/Implies 2012-06-14 14:54:17.000001007 -0500 >>> +@@ -0,0 +1 @@ >>> ++powerpc/powerpc32/e5500/fpu >>> +diff -ruN libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/e6500/fpu/Implies libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e6500/fpu/Implies >>> +--- libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/e6500/fpu/Implies 1969-12-31 18:00:00.000000000 -0600 >>> ++++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e6500/fpu/Implies 2012-06-14 14:54:31.054001299 -0500 >>> +@@ -0,0 +1 @@ >>> ++powerpc/powerpc32/e6500/fpu >>> +diff -ruN libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/e5500/fpu/Implies libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/e5500/fpu/Implies >>> +--- libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/e5500/fpu/Implies 1969-12-31 18:00:00.000000000 -0600 >>> ++++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/e5500/fpu/Implies 2012-06-14 14:51:50.453001709 -0500 >>> +@@ -0,0 +1 @@ >>> ++powerpc/powerpc64/e5500/fpu >>> +diff -ruN libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/e6500/fpu/Implies libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/e6500/fpu/Implies >>> +--- libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/e6500/fpu/Implies 1969-12-31 18:00:00.000000000 -0600 >>> ++++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/e6500/fpu/Implies 2012-06-14 14:58:14.298001288 -0500 >>> +@@ -0,0 +1 @@ >>> ++powerpc/powerpc64/e6500/fpu >>> diff --git a/meta/recipes-core/eglibc/eglibc-2.16/ppc-sqrt.patch b/meta/recipes-core/eglibc/eglibc-2.16/ppc-sqrt.patch >>> deleted file mode 100644 >>> index 203040c..0000000 >>> --- a/meta/recipes-core/eglibc/eglibc-2.16/ppc-sqrt.patch >>> +++ /dev/null >>> @@ -1,538 +0,0 @@ >>> -Upstream-Status: Pending >>> - >>> -2011-03-22 Joseph Myers <joseph@codesourcery.com> >>> - >>> - Merge from SG++ 2.11: >>> - >>> - 2010-10-05 Nathan Froyd <froydnj@codesourcery.com> >>> - >>> - Issue #9382 >>> - >>> - * sysdeps/powerpc/powerpc32/603e/: New directory. >>> - * sysdeps/unix/sysv/linux/powerpc/powerpc32/e500mc/: New directory. >>> - * sysdeps/unix/sysv/linux/powerpc/powerpc32/603e/: New directory. >>> - * sysdeps/unix/sysv/linux/powerpc/powerpc32/7400/: New directory. >>> - * sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c: Update. >>> - * sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c: Update. >>> - * sysdeps/powerpc/powerpc64/e5500/fpu/Implies: New file. >>> - >>> -Index: libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c >>> -=================================================================== >>> ---- /dev/null >>> -+++ libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c >>> -@@ -0,0 +1,134 @@ >>> -+/* Double-precision floating point square root. >>> -+ Copyright (C) 2010 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. */ >>> -+ >>> -+#include <math.h> >>> -+#include <math_private.h> >>> -+#include <fenv_libc.h> >>> -+#include <inttypes.h> >>> -+ >>> -+#include <sysdep.h> >>> -+#include <ldsodefs.h> >>> -+ >>> -+static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; >>> -+static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; >>> -+static const float two108 = 3.245185536584267269e+32; >>> -+static const float twom54 = 5.551115123125782702e-17; >>> -+static const float half = 0.5; >>> -+ >>> -+/* The method is based on the descriptions in: >>> -+ >>> -+ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; >>> -+ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 >>> -+ >>> -+ We find the actual square root and half of its reciprocal >>> -+ simultaneously. */ >>> -+ >>> -+#ifdef __STDC__ >>> -+double >>> -+__ieee754_sqrt (double b) >>> -+#else >>> -+double >>> -+__ieee754_sqrt (b) >>> -+ double b; >>> -+#endif >>> -+{ >>> -+ if (__builtin_expect (b > 0, 1)) >>> -+ { >>> -+ double y, g, h, d, r; >>> -+ ieee_double_shape_type u; >>> -+ >>> -+ if (__builtin_expect (b != a_inf.value, 1)) >>> -+ { >>> -+ fenv_t fe; >>> -+ >>> -+ fe = fegetenv_register (); >>> -+ >>> -+ u.value = b; >>> -+ >>> -+ relax_fenv_state (); >>> -+ >>> -+ __asm__ ("frsqrte %[estimate], %[x]\n" >>> -+ : [estimate] "=f" (y) : [x] "f" (b)); >>> -+ >>> -+ /* Following Muller et al, page 168, equation 5.20. >>> -+ >>> -+ h goes to 1/(2*sqrt(b)) >>> -+ g goes to sqrt(b). >>> -+ >>> -+ We need three iterations to get within 1ulp. */ >>> -+ >>> -+ /* Indicate that these can be performed prior to the branch. GCC >>> -+ insists on sinking them below the branch, however; it seems like >>> -+ they'd be better before the branch so that we can cover any latency >>> -+ from storing the argument and loading its high word. Oh well. */ >>> -+ >>> -+ g = b * y; >>> -+ h = 0.5 * y; >>> -+ >>> -+ /* Handle small numbers by scaling. */ >>> -+ if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0)) >>> -+ return __ieee754_sqrt (b * two108) * twom54; >>> -+ >>> -+#define FMADD(a_, c_, b_) \ >>> -+ ({ double __r; \ >>> -+ __asm__ ("fmadd %[r], %[a], %[c], %[b]\n" \ >>> -+ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >>> -+ __r;}) >>> -+#define FNMSUB(a_, c_, b_) \ >>> -+ ({ double __r; \ >>> -+ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ >>> -+ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >>> -+ __r;}) >>> -+ >>> -+ r = FNMSUB (g, h, half); >>> -+ g = FMADD (g, r, g); >>> -+ h = FMADD (h, r, h); >>> -+ >>> -+ r = FNMSUB (g, h, half); >>> -+ g = FMADD (g, r, g); >>> -+ h = FMADD (h, r, h); >>> -+ >>> -+ r = FNMSUB (g, h, half); >>> -+ g = FMADD (g, r, g); >>> -+ h = FMADD (h, r, h); >>> -+ >>> -+ /* g is now +/- 1ulp, or exactly equal to, the square root of b. */ >>> -+ >>> -+ /* Final refinement. */ >>> -+ d = FNMSUB (g, g, b); >>> -+ >>> -+ fesetenv_register (fe); >>> -+ return FMADD (d, h, g); >>> -+ } >>> -+ } >>> -+ else if (b < 0) >>> -+ { >>> -+ /* For some reason, some PowerPC32 processors don't implement >>> -+ FE_INVALID_SQRT. */ >>> -+#ifdef FE_INVALID_SQRT >>> -+ feraiseexcept (FE_INVALID_SQRT); >>> -+ >>> -+ fenv_union_t u = { .fenv = fegetenv_register () }; >>> -+ if ((u.l[1] & FE_INVALID) == 0) >>> -+#endif >>> -+ feraiseexcept (FE_INVALID); >>> -+ b = a_nan.value; >>> -+ } >>> -+ return f_wash (b); >>> -+} >>> -Index: libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c >>> -=================================================================== >>> ---- /dev/null >>> -+++ libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c >>> -@@ -0,0 +1,101 @@ >>> -+/* Single-precision floating point square root. >>> -+ Copyright (C) 2010 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. */ >>> -+ >>> -+#include <math.h> >>> -+#include <math_private.h> >>> -+#include <fenv_libc.h> >>> -+#include <inttypes.h> >>> -+ >>> -+#include <sysdep.h> >>> -+#include <ldsodefs.h> >>> -+ >>> -+static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; >>> -+static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; >>> -+static const float threehalf = 1.5; >>> -+ >>> -+/* The method is based on the descriptions in: >>> -+ >>> -+ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; >>> -+ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 >>> -+ >>> -+ We find the reciprocal square root and use that to compute the actual >>> -+ square root. */ >>> -+ >>> -+#ifdef __STDC__ >>> -+float >>> -+__ieee754_sqrtf (float b) >>> -+#else >>> -+float >>> -+__ieee754_sqrtf (b) >>> -+ float b; >>> -+#endif >>> -+{ >>> -+ if (__builtin_expect (b > 0, 1)) >>> -+ { >>> -+#define FMSUB(a_, c_, b_) \ >>> -+ ({ double __r; \ >>> -+ __asm__ ("fmsub %[r], %[a], %[c], %[b]\n" \ >>> -+ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >>> -+ __r;}) >>> -+#define FNMSUB(a_, c_, b_) \ >>> -+ ({ double __r; \ >>> -+ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ >>> -+ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >>> -+ __r;}) >>> -+ >>> -+ if (__builtin_expect (b != a_inf.value, 1)) >>> -+ { >>> -+ double y, x; >>> -+ fenv_t fe; >>> -+ >>> -+ fe = fegetenv_register (); >>> -+ >>> -+ relax_fenv_state (); >>> -+ >>> -+ /* Compute y = 1.5 * b - b. Uses fewer constants than y = 0.5 * b. */ >>> -+ y = FMSUB (threehalf, b, b); >>> -+ >>> -+ /* Initial estimate. */ >>> -+ __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b)); >>> -+ >>> -+ /* Iterate. x_{n+1} = x_n * (1.5 - y * (x_n * x_n)). */ >>> -+ x = x * FNMSUB (y, x * x, threehalf); >>> -+ x = x * FNMSUB (y, x * x, threehalf); >>> -+ x = x * FNMSUB (y, x * x, threehalf); >>> -+ >>> -+ /* All done. */ >>> -+ fesetenv_register (fe); >>> -+ return x * b; >>> -+ } >>> -+ } >>> -+ else if (b < 0) >>> -+ { >>> -+ /* For some reason, some PowerPC32 processors don't implement >>> -+ FE_INVALID_SQRT. */ >>> -+#ifdef FE_INVALID_SQRT >>> -+ feraiseexcept (FE_INVALID_SQRT); >>> -+ >>> -+ fenv_union_t u = { .fenv = fegetenv_register () }; >>> -+ if ((u.l[1] & FE_INVALID) == 0) >>> -+#endif >>> -+ feraiseexcept (FE_INVALID); >>> -+ b = a_nan.value; >>> -+ } >>> -+ return f_washf (b); >>> -+} >>> -Index: libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c >>> -=================================================================== >>> ---- /dev/null >>> -+++ libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c >>> -@@ -0,0 +1,134 @@ >>> -+/* Double-precision floating point square root. >>> -+ Copyright (C) 2010 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. */ >>> -+ >>> -+#include <math.h> >>> -+#include <math_private.h> >>> -+#include <fenv_libc.h> >>> -+#include <inttypes.h> >>> -+ >>> -+#include <sysdep.h> >>> -+#include <ldsodefs.h> >>> -+ >>> -+static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; >>> -+static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; >>> -+static const float two108 = 3.245185536584267269e+32; >>> -+static const float twom54 = 5.551115123125782702e-17; >>> -+static const float half = 0.5; >>> -+ >>> -+/* The method is based on the descriptions in: >>> -+ >>> -+ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; >>> -+ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 >>> -+ >>> -+ We find the actual square root and half of its reciprocal >>> -+ simultaneously. */ >>> -+ >>> -+#ifdef __STDC__ >>> -+double >>> -+__ieee754_sqrt (double b) >>> -+#else >>> -+double >>> -+__ieee754_sqrt (b) >>> -+ double b; >>> -+#endif >>> -+{ >>> -+ if (__builtin_expect (b > 0, 1)) >>> -+ { >>> -+ double y, g, h, d, r; >>> -+ ieee_double_shape_type u; >>> -+ >>> -+ if (__builtin_expect (b != a_inf.value, 1)) >>> -+ { >>> -+ fenv_t fe; >>> -+ >>> -+ fe = fegetenv_register (); >>> -+ >>> -+ u.value = b; >>> -+ >>> -+ relax_fenv_state (); >>> -+ >>> -+ __asm__ ("frsqrte %[estimate], %[x]\n" >>> -+ : [estimate] "=f" (y) : [x] "f" (b)); >>> -+ >>> -+ /* Following Muller et al, page 168, equation 5.20. >>> -+ >>> -+ h goes to 1/(2*sqrt(b)) >>> -+ g goes to sqrt(b). >>> -+ >>> -+ We need three iterations to get within 1ulp. */ >>> -+ >>> -+ /* Indicate that these can be performed prior to the branch. GCC >>> -+ insists on sinking them below the branch, however; it seems like >>> -+ they'd be better before the branch so that we can cover any latency >>> -+ from storing the argument and loading its high word. Oh well. */ >>> -+ >>> -+ g = b * y; >>> -+ h = 0.5 * y; >>> -+ >>> -+ /* Handle small numbers by scaling. */ >>> -+ if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0)) >>> -+ return __ieee754_sqrt (b * two108) * twom54; >>> -+ >>> -+#define FMADD(a_, c_, b_) \ >>> -+ ({ double __r; \ >>> -+ __asm__ ("fmadd %[r], %[a], %[c], %[b]\n" \ >>> -+ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >>> -+ __r;}) >>> -+#define FNMSUB(a_, c_, b_) \ >>> -+ ({ double __r; \ >>> -+ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ >>> -+ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >>> -+ __r;}) >>> -+ >>> -+ r = FNMSUB (g, h, half); >>> -+ g = FMADD (g, r, g); >>> -+ h = FMADD (h, r, h); >>> -+ >>> -+ r = FNMSUB (g, h, half); >>> -+ g = FMADD (g, r, g); >>> -+ h = FMADD (h, r, h); >>> -+ >>> -+ r = FNMSUB (g, h, half); >>> -+ g = FMADD (g, r, g); >>> -+ h = FMADD (h, r, h); >>> -+ >>> -+ /* g is now +/- 1ulp, or exactly equal to, the square root of b. */ >>> -+ >>> -+ /* Final refinement. */ >>> -+ d = FNMSUB (g, g, b); >>> -+ >>> -+ fesetenv_register (fe); >>> -+ return FMADD (d, h, g); >>> -+ } >>> -+ } >>> -+ else if (b < 0) >>> -+ { >>> -+ /* For some reason, some PowerPC32 processors don't implement >>> -+ FE_INVALID_SQRT. */ >>> -+#ifdef FE_INVALID_SQRT >>> -+ feraiseexcept (FE_INVALID_SQRT); >>> -+ >>> -+ fenv_union_t u = { .fenv = fegetenv_register () }; >>> -+ if ((u.l[1] & FE_INVALID) == 0) >>> -+#endif >>> -+ feraiseexcept (FE_INVALID); >>> -+ b = a_nan.value; >>> -+ } >>> -+ return f_wash (b); >>> -+} >>> -Index: libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c >>> -=================================================================== >>> ---- /dev/null >>> -+++ libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c >>> -@@ -0,0 +1,101 @@ >>> -+/* Single-precision floating point square root. >>> -+ Copyright (C) 2010 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. */ >>> -+ >>> -+#include <math.h> >>> -+#include <math_private.h> >>> -+#include <fenv_libc.h> >>> -+#include <inttypes.h> >>> -+ >>> -+#include <sysdep.h> >>> -+#include <ldsodefs.h> >>> -+ >>> -+static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; >>> -+static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; >>> -+static const float threehalf = 1.5; >>> -+ >>> -+/* The method is based on the descriptions in: >>> -+ >>> -+ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; >>> -+ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 >>> -+ >>> -+ We find the reciprocal square root and use that to compute the actual >>> -+ square root. */ >>> -+ >>> -+#ifdef __STDC__ >>> -+float >>> -+__ieee754_sqrtf (float b) >>> -+#else >>> -+float >>> -+__ieee754_sqrtf (b) >>> -+ float b; >>> -+#endif >>> -+{ >>> -+ if (__builtin_expect (b > 0, 1)) >>> -+ { >>> -+#define FMSUB(a_, c_, b_) \ >>> -+ ({ double __r; \ >>> -+ __asm__ ("fmsub %[r], %[a], %[c], %[b]\n" \ >>> -+ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >>> -+ __r;}) >>> -+#define FNMSUB(a_, c_, b_) \ >>> -+ ({ double __r; \ >>> -+ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ >>> -+ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ >>> -+ __r;}) >>> -+ >>> -+ if (__builtin_expect (b != a_inf.value, 1)) >>> -+ { >>> -+ double y, x; >>> -+ fenv_t fe; >>> -+ >>> -+ fe = fegetenv_register (); >>> -+ >>> -+ relax_fenv_state (); >>> -+ >>> -+ /* Compute y = 1.5 * b - b. Uses fewer constants than y = 0.5 * b. */ >>> -+ y = FMSUB (threehalf, b, b); >>> -+ >>> -+ /* Initial estimate. */ >>> -+ __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b)); >>> -+ >>> -+ /* Iterate. x_{n+1} = x_n * (1.5 - y * (x_n * x_n)). */ >>> -+ x = x * FNMSUB (y, x * x, threehalf); >>> -+ x = x * FNMSUB (y, x * x, threehalf); >>> -+ x = x * FNMSUB (y, x * x, threehalf); >>> -+ >>> -+ /* All done. */ >>> -+ fesetenv_register (fe); >>> -+ return x * b; >>> -+ } >>> -+ } >>> -+ else if (b < 0) >>> -+ { >>> -+ /* For some reason, some PowerPC32 processors don't implement >>> -+ FE_INVALID_SQRT. */ >>> -+#ifdef FE_INVALID_SQRT >>> -+ feraiseexcept (FE_INVALID_SQRT); >>> -+ >>> -+ fenv_union_t u = { .fenv = fegetenv_register () }; >>> -+ if ((u.l[1] & FE_INVALID) == 0) >>> -+#endif >>> -+ feraiseexcept (FE_INVALID); >>> -+ b = a_nan.value; >>> -+ } >>> -+ return f_washf (b); >>> -+} >>> -Index: libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/603e/fpu/Implies >>> -=================================================================== >>> ---- /dev/null >>> -+++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/603e/fpu/Implies >>> -@@ -0,0 +1 @@ >>> -+powerpc/powerpc32/603e/fpu >>> -Index: libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/7400/fpu/Implies >>> -=================================================================== >>> ---- /dev/null >>> -+++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/7400/fpu/Implies >>> -@@ -0,0 +1 @@ >>> -+powerpc/powerpc32/603e/fpu >>> -Index: libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e500mc/fpu/Implies >>> -=================================================================== >>> ---- /dev/null >>> -+++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e500mc/fpu/Implies >>> -@@ -0,0 +1 @@ >>> -+powerpc/powerpc32/603e/fpu >>> -Index: libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/e5500/fpu/Implies >>> -=================================================================== >>> ---- /dev/null >>> -+++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/e5500/fpu/Implies >>> -@@ -0,0 +1 @@ >>> -+powerpc/powerpc64/e5500/fpu >>> -Index: libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e5500/fpu/Implies >>> -=================================================================== >>> ---- /dev/null >>> -+++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e5500/fpu/Implies >>> -@@ -0,0 +1 @@ >>> -+powerpc/powerpc32/603e/fpu >>> diff --git a/meta/recipes-core/eglibc/eglibc_2.16.bb b/meta/recipes-core/eglibc/eglibc_2.16.bb >>> index 78dc44a..a753882 100644 >>> --- a/meta/recipes-core/eglibc/eglibc_2.16.bb >>> +++ b/meta/recipes-core/eglibc/eglibc_2.16.bb >>> @@ -3,7 +3,7 @@ require eglibc.inc >>> SRCREV = "20393" >>> >>> DEPENDS += "gperf-native kconfig-frontends-native" >>> -PR = "r9" >>> +PR = "r10" >>> PR_append = "+svnr${SRCPV}" >>> >>> EGLIBC_BRANCH="eglibc-2_16" >>> @@ -13,7 +13,7 @@ SRC_URI = "svn://www.eglibc.org/svn/branches/;module=${EGLIBC_BRANCH};protocol=h >>> file://mips-rld-map-check.patch \ >>> file://etc/ld.so.conf \ >>> file://generate-supported.mk \ >>> - file://ppc-sqrt.patch \ >>> + file://glibc.fix_sqrt2.patch \ >>> file://multilib_readlib.patch \ >>> file://use-sysroot-cxx-headers.patch \ >>> file://ppc-sqrt_finite.patch \ >>> -- >>> 1.7.9.7 >>> >>> >>> >>> _______________________________________________ >>> Openembedded-core mailing list >>> Openembedded-core@lists.openembedded.org >>> http://lists.linuxtogo.org/cgi-bin/mailman/listinfo/openembedded-core >> >> _______________________________________________ >> Openembedded-core mailing list >> Openembedded-core@lists.openembedded.org >> http://lists.linuxtogo.org/cgi-bin/mailman/listinfo/openembedded-core > > _______________________________________________ > Openembedded-core mailing list > Openembedded-core@lists.openembedded.org > http://lists.linuxtogo.org/cgi-bin/mailman/listinfo/openembedded-core
On Tue, Sep 18, 2012 at 3:23 PM, McClintock Matthew-B29882 <B29882@freescale.com> wrote: > > It's just renaming the patch, so it's replacing ppc-sqrt.patch with > glibc.fix_sqrt2.patch - and these are not authored by me... which I > realize I forgot to add upstream-status as well. > OK now I see. The shadowing is there. I dont like renaming the patch. Is there any reason why its renamed to glibc.fix_sqrt2.patch ? its easy to spot changes if it was not renamed > Back to the patches themselves, ppc-sqrt seemed to be a subset of > glibc.fix_sqrt2.patch or am I wrong? As far as shadowing I'm not sure, > I'd rather not spend time testing that, these patches are used/tested > internally. Thats fine
On Tue, Sep 18, 2012 at 5:30 PM, Khem Raj <raj.khem@gmail.com> wrote: > On Tue, Sep 18, 2012 at 3:23 PM, McClintock Matthew-B29882 > <B29882@freescale.com> wrote: >> >> It's just renaming the patch, so it's replacing ppc-sqrt.patch with >> glibc.fix_sqrt2.patch - and these are not authored by me... which I >> realize I forgot to add upstream-status as well. >> > > OK now I see. The shadowing is there. I dont like renaming the patch. > Is there any reason > why its renamed to glibc.fix_sqrt2.patch ? its easy to spot changes if > it was not renamed Internal patch name. I can change it if needed. But, then I have to track patch names differences between internal and external. -M
On Tue, Sep 18, 2012 at 3:32 PM, McClintock Matthew-B29882 <B29882@freescale.com> wrote: > > Internal patch name. I can change it if needed. But, then I have to > track patch names differences between internal and external. Not that I am opposed to it but its hard to review as I said. cant internal be changed ?
On Tue, Sep 18, 2012 at 5:33 PM, Khem Raj <raj.khem@gmail.com> wrote: > On Tue, Sep 18, 2012 at 3:32 PM, McClintock Matthew-B29882 > <B29882@freescale.com> wrote: >> >> Internal patch name. I can change it if needed. But, then I have to >> track patch names differences between internal and external. > > Not that I am opposed to it but its hard to review as I said. > cant internal be changed ? Ha ha ha... ;) -M
On Tue, Sep 18, 2012 at 5:35 PM, Matthew McClintock <msm@freescale.com> wrote: > On Tue, Sep 18, 2012 at 5:33 PM, Khem Raj <raj.khem@gmail.com> wrote: >> On Tue, Sep 18, 2012 at 3:32 PM, McClintock Matthew-B29882 >> <B29882@freescale.com> wrote: >>> >>> Internal patch name. I can change it if needed. But, then I have to >>> track patch names differences between internal and external. >> >> Not that I am opposed to it but its hard to review as I said. >> cant internal be changed ? > > Ha ha ha... Please hold off on this patch - I believe I've found some more issues (besides the sign-off and upstream-status on the patch) -M > > ;) > > -M
Patch
diff --git a/meta/recipes-core/eglibc/eglibc-2.16/glibc.fix_sqrt2.patch b/meta/recipes-core/eglibc/eglibc-2.16/glibc.fix_sqrt2.patch new file mode 100644 index 0000000..e098192 --- /dev/null +++ b/meta/recipes-core/eglibc/eglibc-2.16/glibc.fix_sqrt2.patch @@ -0,0 +1,1488 @@ +diff -ruN libc-orig/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c +--- libc-orig/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c 1969-12-31 18:00:00.000000000 -0600 ++++ libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c 2012-06-14 14:51:50.452001745 -0500 +@@ -0,0 +1,134 @@ ++/* Double-precision floating point square root. ++ Copyright (C) 2010 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. */ ++ ++#include <math.h> ++#include <math_private.h> ++#include <fenv_libc.h> ++#include <inttypes.h> ++ ++#include <sysdep.h> ++#include <ldsodefs.h> ++ ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; ++static const float two108 = 3.245185536584267269e+32; ++static const float twom54 = 5.551115123125782702e-17; ++static const float half = 0.5; ++ ++/* The method is based on the descriptions in: ++ ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 ++ ++ We find the actual square root and half of its reciprocal ++ simultaneously. */ ++ ++#ifdef __STDC__ ++double ++__ieee754_sqrt (double b) ++#else ++double ++__ieee754_sqrt (b) ++ double b; ++#endif ++{ ++ if (__builtin_expect (b > 0, 1)) ++ { ++ double y, g, h, d, r; ++ ieee_double_shape_type u; ++ ++ if (__builtin_expect (b != a_inf.value, 1)) ++ { ++ fenv_t fe; ++ ++ fe = fegetenv_register (); ++ ++ u.value = b; ++ ++ relax_fenv_state (); ++ ++ __asm__ ("frsqrte %[estimate], %[x]\n" ++ : [estimate] "=f" (y) : [x] "f" (b)); ++ ++ /* Following Muller et al, page 168, equation 5.20. ++ ++ h goes to 1/(2*sqrt(b)) ++ g goes to sqrt(b). ++ ++ We need three iterations to get within 1ulp. */ ++ ++ /* Indicate that these can be performed prior to the branch. GCC ++ insists on sinking them below the branch, however; it seems like ++ they'd be better before the branch so that we can cover any latency ++ from storing the argument and loading its high word. Oh well. */ ++ ++ g = b * y; ++ h = 0.5 * y; ++ ++ /* Handle small numbers by scaling. */ ++ if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0)) ++ return __ieee754_sqrt (b * two108) * twom54; ++ ++#define FMADD(a_, c_, b_) \ ++ ({ double __r; \ ++ __asm__ ("fmadd %[r], %[a], %[c], %[b]\n" \ ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ ++ __r;}) ++#define FNMSUB(a_, c_, b_) \ ++ ({ double __r; \ ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ ++ __r;}) ++ ++ r = FNMSUB (g, h, half); ++ g = FMADD (g, r, g); ++ h = FMADD (h, r, h); ++ ++ r = FNMSUB (g, h, half); ++ g = FMADD (g, r, g); ++ h = FMADD (h, r, h); ++ ++ r = FNMSUB (g, h, half); ++ g = FMADD (g, r, g); ++ h = FMADD (h, r, h); ++ ++ /* g is now +/- 1ulp, or exactly equal to, the square root of b. */ ++ ++ /* Final refinement. */ ++ d = FNMSUB (g, g, b); ++ ++ fesetenv_register (fe); ++ return FMADD (d, h, g); ++ } ++ } ++ else if (b < 0) ++ { ++ /* For some reason, some PowerPC32 processors don't implement ++ FE_INVALID_SQRT. */ ++#ifdef FE_INVALID_SQRT ++ feraiseexcept (FE_INVALID_SQRT); ++ ++ fenv_union_t u = { .fenv = fegetenv_register () }; ++ if ((u.l[1] & FE_INVALID) == 0) ++#endif ++ feraiseexcept (FE_INVALID); ++ b = a_nan.value; ++ } ++ return f_wash (b); ++} +diff -ruN libc-orig/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c +--- libc-orig/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c 1969-12-31 18:00:00.000000000 -0600 ++++ libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c 2012-06-14 14:51:50.452001745 -0500 +@@ -0,0 +1,101 @@ ++/* Single-precision floating point square root. ++ Copyright (C) 2010 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. */ ++ ++#include <math.h> ++#include <math_private.h> ++#include <fenv_libc.h> ++#include <inttypes.h> ++ ++#include <sysdep.h> ++#include <ldsodefs.h> ++ ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; ++static const float threehalf = 1.5; ++ ++/* The method is based on the descriptions in: ++ ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 ++ ++ We find the reciprocal square root and use that to compute the actual ++ square root. */ ++ ++#ifdef __STDC__ ++float ++__ieee754_sqrtf (float b) ++#else ++float ++__ieee754_sqrtf (b) ++ float b; ++#endif ++{ ++ if (__builtin_expect (b > 0, 1)) ++ { ++#define FMSUB(a_, c_, b_) \ ++ ({ double __r; \ ++ __asm__ ("fmsub %[r], %[a], %[c], %[b]\n" \ ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ ++ __r;}) ++#define FNMSUB(a_, c_, b_) \ ++ ({ double __r; \ ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ ++ __r;}) ++ ++ if (__builtin_expect (b != a_inf.value, 1)) ++ { ++ double y, x; ++ fenv_t fe; ++ ++ fe = fegetenv_register (); ++ ++ relax_fenv_state (); ++ ++ /* Compute y = 1.5 * b - b. Uses fewer constants than y = 0.5 * b. */ ++ y = FMSUB (threehalf, b, b); ++ ++ /* Initial estimate. */ ++ __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b)); ++ ++ /* Iterate. x_{n+1} = x_n * (1.5 - y * (x_n * x_n)). */ ++ x = x * FNMSUB (y, x * x, threehalf); ++ x = x * FNMSUB (y, x * x, threehalf); ++ x = x * FNMSUB (y, x * x, threehalf); ++ ++ /* All done. */ ++ fesetenv_register (fe); ++ return x * b; ++ } ++ } ++ else if (b < 0) ++ { ++ /* For some reason, some PowerPC32 processors don't implement ++ FE_INVALID_SQRT. */ ++#ifdef FE_INVALID_SQRT ++ feraiseexcept (FE_INVALID_SQRT); ++ ++ fenv_union_t u = { .fenv = fegetenv_register () }; ++ if ((u.l[1] & FE_INVALID) == 0) ++#endif ++ feraiseexcept (FE_INVALID); ++ b = a_nan.value; ++ } ++ return f_washf (b); ++} +diff -ruN libc-orig/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c libc/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c +--- libc-orig/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c 1969-12-31 18:00:00.000000000 -0600 ++++ libc/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c 2012-06-14 14:55:14.749001061 -0500 +@@ -0,0 +1,134 @@ ++/* Double-precision floating point square root. ++ Copyright (C) 2010 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. */ ++ ++#include <math.h> ++#include <math_private.h> ++#include <fenv_libc.h> ++#include <inttypes.h> ++ ++#include <sysdep.h> ++#include <ldsodefs.h> ++ ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; ++static const float two108 = 3.245185536584267269e+32; ++static const float twom54 = 5.551115123125782702e-17; ++static const float half = 0.5; ++ ++/* The method is based on the descriptions in: ++ ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 ++ ++ We find the actual square root and half of its reciprocal ++ simultaneously. */ ++ ++#ifdef __STDC__ ++double ++__ieee754_sqrt (double b) ++#else ++double ++__ieee754_sqrt (b) ++ double b; ++#endif ++{ ++ if (__builtin_expect (b > 0, 1)) ++ { ++ double y, g, h, d, r; ++ ieee_double_shape_type u; ++ ++ if (__builtin_expect (b != a_inf.value, 1)) ++ { ++ fenv_t fe; ++ ++ fe = fegetenv_register (); ++ ++ u.value = b; ++ ++ relax_fenv_state (); ++ ++ __asm__ ("frsqrte %[estimate], %[x]\n" ++ : [estimate] "=f" (y) : [x] "f" (b)); ++ ++ /* Following Muller et al, page 168, equation 5.20. ++ ++ h goes to 1/(2*sqrt(b)) ++ g goes to sqrt(b). ++ ++ We need three iterations to get within 1ulp. */ ++ ++ /* Indicate that these can be performed prior to the branch. GCC ++ insists on sinking them below the branch, however; it seems like ++ they'd be better before the branch so that we can cover any latency ++ from storing the argument and loading its high word. Oh well. */ ++ ++ g = b * y; ++ h = 0.5 * y; ++ ++ /* Handle small numbers by scaling. */ ++ if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0)) ++ return __ieee754_sqrt (b * two108) * twom54; ++ ++#define FMADD(a_, c_, b_) \ ++ ({ double __r; \ ++ __asm__ ("fmadd %[r], %[a], %[c], %[b]\n" \ ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ ++ __r;}) ++#define FNMSUB(a_, c_, b_) \ ++ ({ double __r; \ ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ ++ __r;}) ++ ++ r = FNMSUB (g, h, half); ++ g = FMADD (g, r, g); ++ h = FMADD (h, r, h); ++ ++ r = FNMSUB (g, h, half); ++ g = FMADD (g, r, g); ++ h = FMADD (h, r, h); ++ ++ r = FNMSUB (g, h, half); ++ g = FMADD (g, r, g); ++ h = FMADD (h, r, h); ++ ++ /* g is now +/- 1ulp, or exactly equal to, the square root of b. */ ++ ++ /* Final refinement. */ ++ d = FNMSUB (g, g, b); ++ ++ fesetenv_register (fe); ++ return FMADD (d, h, g); ++ } ++ } ++ else if (b < 0) ++ { ++ /* For some reason, some PowerPC32 processors don't implement ++ FE_INVALID_SQRT. */ ++#ifdef FE_INVALID_SQRT ++ feraiseexcept (FE_INVALID_SQRT); ++ ++ fenv_union_t u = { .fenv = fegetenv_register () }; ++ if ((u.l[1] & FE_INVALID) == 0) ++#endif ++ feraiseexcept (FE_INVALID); ++ b = a_nan.value; ++ } ++ return f_wash (b); ++} +diff -ruN libc-orig/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c libc/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c +--- libc-orig/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c 1969-12-31 18:00:00.000000000 -0600 ++++ libc/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c 2012-06-14 14:55:14.749001061 -0500 +@@ -0,0 +1,101 @@ ++/* Single-precision floating point square root. ++ Copyright (C) 2010 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. */ ++ ++#include <math.h> ++#include <math_private.h> ++#include <fenv_libc.h> ++#include <inttypes.h> ++ ++#include <sysdep.h> ++#include <ldsodefs.h> ++ ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; ++static const float threehalf = 1.5; ++ ++/* The method is based on the descriptions in: ++ ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 ++ ++ We find the reciprocal square root and use that to compute the actual ++ square root. */ ++ ++#ifdef __STDC__ ++float ++__ieee754_sqrtf (float b) ++#else ++float ++__ieee754_sqrtf (b) ++ float b; ++#endif ++{ ++ if (__builtin_expect (b > 0, 1)) ++ { ++#define FMSUB(a_, c_, b_) \ ++ ({ double __r; \ ++ __asm__ ("fmsub %[r], %[a], %[c], %[b]\n" \ ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ ++ __r;}) ++#define FNMSUB(a_, c_, b_) \ ++ ({ double __r; \ ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ ++ __r;}) ++ ++ if (__builtin_expect (b != a_inf.value, 1)) ++ { ++ double y, x; ++ fenv_t fe; ++ ++ fe = fegetenv_register (); ++ ++ relax_fenv_state (); ++ ++ /* Compute y = 1.5 * b - b. Uses fewer constants than y = 0.5 * b. */ ++ y = FMSUB (threehalf, b, b); ++ ++ /* Initial estimate. */ ++ __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b)); ++ ++ /* Iterate. x_{n+1} = x_n * (1.5 - y * (x_n * x_n)). */ ++ x = x * FNMSUB (y, x * x, threehalf); ++ x = x * FNMSUB (y, x * x, threehalf); ++ x = x * FNMSUB (y, x * x, threehalf); ++ ++ /* All done. */ ++ fesetenv_register (fe); ++ return x * b; ++ } ++ } ++ else if (b < 0) ++ { ++ /* For some reason, some PowerPC32 processors don't implement ++ FE_INVALID_SQRT. */ ++#ifdef FE_INVALID_SQRT ++ feraiseexcept (FE_INVALID_SQRT); ++ ++ fenv_union_t u = { .fenv = fegetenv_register () }; ++ if ((u.l[1] & FE_INVALID) == 0) ++#endif ++ feraiseexcept (FE_INVALID); ++ b = a_nan.value; ++ } ++ return f_washf (b); ++} +diff -ruN libc-orig/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c libc/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c +--- libc-orig/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c 1969-12-31 18:00:00.000000000 -0600 ++++ libc/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c 2012-06-14 14:55:21.812002270 -0500 +@@ -0,0 +1,134 @@ ++/* Double-precision floating point square root. ++ Copyright (C) 2010 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. */ ++ ++#include <math.h> ++#include <math_private.h> ++#include <fenv_libc.h> ++#include <inttypes.h> ++ ++#include <sysdep.h> ++#include <ldsodefs.h> ++ ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; ++static const float two108 = 3.245185536584267269e+32; ++static const float twom54 = 5.551115123125782702e-17; ++static const float half = 0.5; ++ ++/* The method is based on the descriptions in: ++ ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 ++ ++ We find the actual square root and half of its reciprocal ++ simultaneously. */ ++ ++#ifdef __STDC__ ++double ++__ieee754_sqrt (double b) ++#else ++double ++__ieee754_sqrt (b) ++ double b; ++#endif ++{ ++ if (__builtin_expect (b > 0, 1)) ++ { ++ double y, g, h, d, r; ++ ieee_double_shape_type u; ++ ++ if (__builtin_expect (b != a_inf.value, 1)) ++ { ++ fenv_t fe; ++ ++ fe = fegetenv_register (); ++ ++ u.value = b; ++ ++ relax_fenv_state (); ++ ++ __asm__ ("frsqrte %[estimate], %[x]\n" ++ : [estimate] "=f" (y) : [x] "f" (b)); ++ ++ /* Following Muller et al, page 168, equation 5.20. ++ ++ h goes to 1/(2*sqrt(b)) ++ g goes to sqrt(b). ++ ++ We need three iterations to get within 1ulp. */ ++ ++ /* Indicate that these can be performed prior to the branch. GCC ++ insists on sinking them below the branch, however; it seems like ++ they'd be better before the branch so that we can cover any latency ++ from storing the argument and loading its high word. Oh well. */ ++ ++ g = b * y; ++ h = 0.5 * y; ++ ++ /* Handle small numbers by scaling. */ ++ if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0)) ++ return __ieee754_sqrt (b * two108) * twom54; ++ ++#define FMADD(a_, c_, b_) \ ++ ({ double __r; \ ++ __asm__ ("fmadd %[r], %[a], %[c], %[b]\n" \ ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ ++ __r;}) ++#define FNMSUB(a_, c_, b_) \ ++ ({ double __r; \ ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ ++ __r;}) ++ ++ r = FNMSUB (g, h, half); ++ g = FMADD (g, r, g); ++ h = FMADD (h, r, h); ++ ++ r = FNMSUB (g, h, half); ++ g = FMADD (g, r, g); ++ h = FMADD (h, r, h); ++ ++ r = FNMSUB (g, h, half); ++ g = FMADD (g, r, g); ++ h = FMADD (h, r, h); ++ ++ /* g is now +/- 1ulp, or exactly equal to, the square root of b. */ ++ ++ /* Final refinement. */ ++ d = FNMSUB (g, g, b); ++ ++ fesetenv_register (fe); ++ return FMADD (d, h, g); ++ } ++ } ++ else if (b < 0) ++ { ++ /* For some reason, some PowerPC32 processors don't implement ++ FE_INVALID_SQRT. */ ++#ifdef FE_INVALID_SQRT ++ feraiseexcept (FE_INVALID_SQRT); ++ ++ fenv_union_t u = { .fenv = fegetenv_register () }; ++ if ((u.l[1] & FE_INVALID) == 0) ++#endif ++ feraiseexcept (FE_INVALID); ++ b = a_nan.value; ++ } ++ return f_wash (b); ++} +diff -ruN libc-orig/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c libc/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c +--- libc-orig/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c 1969-12-31 18:00:00.000000000 -0600 ++++ libc/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c 2012-06-14 14:55:21.812002270 -0500 +@@ -0,0 +1,101 @@ ++/* Single-precision floating point square root. ++ Copyright (C) 2010 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. */ ++ ++#include <math.h> ++#include <math_private.h> ++#include <fenv_libc.h> ++#include <inttypes.h> ++ ++#include <sysdep.h> ++#include <ldsodefs.h> ++ ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; ++static const float threehalf = 1.5; ++ ++/* The method is based on the descriptions in: ++ ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 ++ ++ We find the reciprocal square root and use that to compute the actual ++ square root. */ ++ ++#ifdef __STDC__ ++float ++__ieee754_sqrtf (float b) ++#else ++float ++__ieee754_sqrtf (b) ++ float b; ++#endif ++{ ++ if (__builtin_expect (b > 0, 1)) ++ { ++#define FMSUB(a_, c_, b_) \ ++ ({ double __r; \ ++ __asm__ ("fmsub %[r], %[a], %[c], %[b]\n" \ ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ ++ __r;}) ++#define FNMSUB(a_, c_, b_) \ ++ ({ double __r; \ ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ ++ __r;}) ++ ++ if (__builtin_expect (b != a_inf.value, 1)) ++ { ++ double y, x; ++ fenv_t fe; ++ ++ fe = fegetenv_register (); ++ ++ relax_fenv_state (); ++ ++ /* Compute y = 1.5 * b - b. Uses fewer constants than y = 0.5 * b. */ ++ y = FMSUB (threehalf, b, b); ++ ++ /* Initial estimate. */ ++ __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b)); ++ ++ /* Iterate. x_{n+1} = x_n * (1.5 - y * (x_n * x_n)). */ ++ x = x * FNMSUB (y, x * x, threehalf); ++ x = x * FNMSUB (y, x * x, threehalf); ++ x = x * FNMSUB (y, x * x, threehalf); ++ ++ /* All done. */ ++ fesetenv_register (fe); ++ return x * b; ++ } ++ } ++ else if (b < 0) ++ { ++ /* For some reason, some PowerPC32 processors don't implement ++ FE_INVALID_SQRT. */ ++#ifdef FE_INVALID_SQRT ++ feraiseexcept (FE_INVALID_SQRT); ++ ++ fenv_union_t u = { .fenv = fegetenv_register () }; ++ if ((u.l[1] & FE_INVALID) == 0) ++#endif ++ feraiseexcept (FE_INVALID); ++ b = a_nan.value; ++ } ++ return f_washf (b); ++} +diff -ruN libc-orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c +--- libc-orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c 1969-12-31 18:00:00.000000000 -0600 ++++ libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c 2012-06-14 14:55:24.620001266 -0500 +@@ -0,0 +1,134 @@ ++/* Double-precision floating point square root. ++ Copyright (C) 2010 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. */ ++ ++#include <math.h> ++#include <math_private.h> ++#include <fenv_libc.h> ++#include <inttypes.h> ++ ++#include <sysdep.h> ++#include <ldsodefs.h> ++ ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; ++static const float two108 = 3.245185536584267269e+32; ++static const float twom54 = 5.551115123125782702e-17; ++static const float half = 0.5; ++ ++/* The method is based on the descriptions in: ++ ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 ++ ++ We find the actual square root and half of its reciprocal ++ simultaneously. */ ++ ++#ifdef __STDC__ ++double ++__ieee754_sqrt (double b) ++#else ++double ++__ieee754_sqrt (b) ++ double b; ++#endif ++{ ++ if (__builtin_expect (b > 0, 1)) ++ { ++ double y, g, h, d, r; ++ ieee_double_shape_type u; ++ ++ if (__builtin_expect (b != a_inf.value, 1)) ++ { ++ fenv_t fe; ++ ++ fe = fegetenv_register (); ++ ++ u.value = b; ++ ++ relax_fenv_state (); ++ ++ __asm__ ("frsqrte %[estimate], %[x]\n" ++ : [estimate] "=f" (y) : [x] "f" (b)); ++ ++ /* Following Muller et al, page 168, equation 5.20. ++ ++ h goes to 1/(2*sqrt(b)) ++ g goes to sqrt(b). ++ ++ We need three iterations to get within 1ulp. */ ++ ++ /* Indicate that these can be performed prior to the branch. GCC ++ insists on sinking them below the branch, however; it seems like ++ they'd be better before the branch so that we can cover any latency ++ from storing the argument and loading its high word. Oh well. */ ++ ++ g = b * y; ++ h = 0.5 * y; ++ ++ /* Handle small numbers by scaling. */ ++ if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0)) ++ return __ieee754_sqrt (b * two108) * twom54; ++ ++#define FMADD(a_, c_, b_) \ ++ ({ double __r; \ ++ __asm__ ("fmadd %[r], %[a], %[c], %[b]\n" \ ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ ++ __r;}) ++#define FNMSUB(a_, c_, b_) \ ++ ({ double __r; \ ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ ++ __r;}) ++ ++ r = FNMSUB (g, h, half); ++ g = FMADD (g, r, g); ++ h = FMADD (h, r, h); ++ ++ r = FNMSUB (g, h, half); ++ g = FMADD (g, r, g); ++ h = FMADD (h, r, h); ++ ++ r = FNMSUB (g, h, half); ++ g = FMADD (g, r, g); ++ h = FMADD (h, r, h); ++ ++ /* g is now +/- 1ulp, or exactly equal to, the square root of b. */ ++ ++ /* Final refinement. */ ++ d = FNMSUB (g, g, b); ++ ++ fesetenv_register (fe); ++ return FMADD (d, h, g); ++ } ++ } ++ else if (b < 0) ++ { ++ /* For some reason, some PowerPC32 processors don't implement ++ FE_INVALID_SQRT. */ ++#ifdef FE_INVALID_SQRT ++ feraiseexcept (FE_INVALID_SQRT); ++ ++ fenv_union_t u = { .fenv = fegetenv_register () }; ++ if ((u.l[1] & FE_INVALID) == 0) ++#endif ++ feraiseexcept (FE_INVALID); ++ b = a_nan.value; ++ } ++ return f_wash (b); ++} +diff -ruN libc-orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c +--- libc-orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c 1969-12-31 18:00:00.000000000 -0600 ++++ libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c 2012-06-14 14:55:24.620001266 -0500 +@@ -0,0 +1,101 @@ ++/* Single-precision floating point square root. ++ Copyright (C) 2010 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. */ ++ ++#include <math.h> ++#include <math_private.h> ++#include <fenv_libc.h> ++#include <inttypes.h> ++ ++#include <sysdep.h> ++#include <ldsodefs.h> ++ ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; ++static const float threehalf = 1.5; ++ ++/* The method is based on the descriptions in: ++ ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 ++ ++ We find the reciprocal square root and use that to compute the actual ++ square root. */ ++ ++#ifdef __STDC__ ++float ++__ieee754_sqrtf (float b) ++#else ++float ++__ieee754_sqrtf (b) ++ float b; ++#endif ++{ ++ if (__builtin_expect (b > 0, 1)) ++ { ++#define FMSUB(a_, c_, b_) \ ++ ({ double __r; \ ++ __asm__ ("fmsub %[r], %[a], %[c], %[b]\n" \ ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ ++ __r;}) ++#define FNMSUB(a_, c_, b_) \ ++ ({ double __r; \ ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ ++ __r;}) ++ ++ if (__builtin_expect (b != a_inf.value, 1)) ++ { ++ double y, x; ++ fenv_t fe; ++ ++ fe = fegetenv_register (); ++ ++ relax_fenv_state (); ++ ++ /* Compute y = 1.5 * b - b. Uses fewer constants than y = 0.5 * b. */ ++ y = FMSUB (threehalf, b, b); ++ ++ /* Initial estimate. */ ++ __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b)); ++ ++ /* Iterate. x_{n+1} = x_n * (1.5 - y * (x_n * x_n)). */ ++ x = x * FNMSUB (y, x * x, threehalf); ++ x = x * FNMSUB (y, x * x, threehalf); ++ x = x * FNMSUB (y, x * x, threehalf); ++ ++ /* All done. */ ++ fesetenv_register (fe); ++ return x * b; ++ } ++ } ++ else if (b < 0) ++ { ++ /* For some reason, some PowerPC32 processors don't implement ++ FE_INVALID_SQRT. */ ++#ifdef FE_INVALID_SQRT ++ feraiseexcept (FE_INVALID_SQRT); ++ ++ fenv_union_t u = { .fenv = fegetenv_register () }; ++ if ((u.l[1] & FE_INVALID) == 0) ++#endif ++ feraiseexcept (FE_INVALID); ++ b = a_nan.value; ++ } ++ return f_washf (b); ++} +diff -ruN libc-orig/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c +--- libc-orig/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c 1969-12-31 18:00:00.000000000 -0600 ++++ libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c 2012-06-14 14:51:50.452001745 -0500 +@@ -0,0 +1,134 @@ ++/* Double-precision floating point square root. ++ Copyright (C) 2010 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. */ ++ ++#include <math.h> ++#include <math_private.h> ++#include <fenv_libc.h> ++#include <inttypes.h> ++ ++#include <sysdep.h> ++#include <ldsodefs.h> ++ ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; ++static const float two108 = 3.245185536584267269e+32; ++static const float twom54 = 5.551115123125782702e-17; ++static const float half = 0.5; ++ ++/* The method is based on the descriptions in: ++ ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 ++ ++ We find the actual square root and half of its reciprocal ++ simultaneously. */ ++ ++#ifdef __STDC__ ++double ++__ieee754_sqrt (double b) ++#else ++double ++__ieee754_sqrt (b) ++ double b; ++#endif ++{ ++ if (__builtin_expect (b > 0, 1)) ++ { ++ double y, g, h, d, r; ++ ieee_double_shape_type u; ++ ++ if (__builtin_expect (b != a_inf.value, 1)) ++ { ++ fenv_t fe; ++ ++ fe = fegetenv_register (); ++ ++ u.value = b; ++ ++ relax_fenv_state (); ++ ++ __asm__ ("frsqrte %[estimate], %[x]\n" ++ : [estimate] "=f" (y) : [x] "f" (b)); ++ ++ /* Following Muller et al, page 168, equation 5.20. ++ ++ h goes to 1/(2*sqrt(b)) ++ g goes to sqrt(b). ++ ++ We need three iterations to get within 1ulp. */ ++ ++ /* Indicate that these can be performed prior to the branch. GCC ++ insists on sinking them below the branch, however; it seems like ++ they'd be better before the branch so that we can cover any latency ++ from storing the argument and loading its high word. Oh well. */ ++ ++ g = b * y; ++ h = 0.5 * y; ++ ++ /* Handle small numbers by scaling. */ ++ if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0)) ++ return __ieee754_sqrt (b * two108) * twom54; ++ ++#define FMADD(a_, c_, b_) \ ++ ({ double __r; \ ++ __asm__ ("fmadd %[r], %[a], %[c], %[b]\n" \ ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ ++ __r;}) ++#define FNMSUB(a_, c_, b_) \ ++ ({ double __r; \ ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ ++ __r;}) ++ ++ r = FNMSUB (g, h, half); ++ g = FMADD (g, r, g); ++ h = FMADD (h, r, h); ++ ++ r = FNMSUB (g, h, half); ++ g = FMADD (g, r, g); ++ h = FMADD (h, r, h); ++ ++ r = FNMSUB (g, h, half); ++ g = FMADD (g, r, g); ++ h = FMADD (h, r, h); ++ ++ /* g is now +/- 1ulp, or exactly equal to, the square root of b. */ ++ ++ /* Final refinement. */ ++ d = FNMSUB (g, g, b); ++ ++ fesetenv_register (fe); ++ return FMADD (d, h, g); ++ } ++ } ++ else if (b < 0) ++ { ++ /* For some reason, some PowerPC32 processors don't implement ++ FE_INVALID_SQRT. */ ++#ifdef FE_INVALID_SQRT ++ feraiseexcept (FE_INVALID_SQRT); ++ ++ fenv_union_t u = { .fenv = fegetenv_register () }; ++ if ((u.l[1] & FE_INVALID) == 0) ++#endif ++ feraiseexcept (FE_INVALID); ++ b = a_nan.value; ++ } ++ return f_wash (b); ++} +diff -ruN libc-orig/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c +--- libc-orig/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c 1969-12-31 18:00:00.000000000 -0600 ++++ libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c 2012-06-14 14:51:50.452001745 -0500 +@@ -0,0 +1,101 @@ ++/* Single-precision floating point square root. ++ Copyright (C) 2010 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. */ ++ ++#include <math.h> ++#include <math_private.h> ++#include <fenv_libc.h> ++#include <inttypes.h> ++ ++#include <sysdep.h> ++#include <ldsodefs.h> ++ ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; ++static const float threehalf = 1.5; ++ ++/* The method is based on the descriptions in: ++ ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 ++ ++ We find the reciprocal square root and use that to compute the actual ++ square root. */ ++ ++#ifdef __STDC__ ++float ++__ieee754_sqrtf (float b) ++#else ++float ++__ieee754_sqrtf (b) ++ float b; ++#endif ++{ ++ if (__builtin_expect (b > 0, 1)) ++ { ++#define FMSUB(a_, c_, b_) \ ++ ({ double __r; \ ++ __asm__ ("fmsub %[r], %[a], %[c], %[b]\n" \ ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ ++ __r;}) ++#define FNMSUB(a_, c_, b_) \ ++ ({ double __r; \ ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ ++ __r;}) ++ ++ if (__builtin_expect (b != a_inf.value, 1)) ++ { ++ double y, x; ++ fenv_t fe; ++ ++ fe = fegetenv_register (); ++ ++ relax_fenv_state (); ++ ++ /* Compute y = 1.5 * b - b. Uses fewer constants than y = 0.5 * b. */ ++ y = FMSUB (threehalf, b, b); ++ ++ /* Initial estimate. */ ++ __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b)); ++ ++ /* Iterate. x_{n+1} = x_n * (1.5 - y * (x_n * x_n)). */ ++ x = x * FNMSUB (y, x * x, threehalf); ++ x = x * FNMSUB (y, x * x, threehalf); ++ x = x * FNMSUB (y, x * x, threehalf); ++ ++ /* All done. */ ++ fesetenv_register (fe); ++ return x * b; ++ } ++ } ++ else if (b < 0) ++ { ++ /* For some reason, some PowerPC32 processors don't implement ++ FE_INVALID_SQRT. */ ++#ifdef FE_INVALID_SQRT ++ feraiseexcept (FE_INVALID_SQRT); ++ ++ fenv_union_t u = { .fenv = fegetenv_register () }; ++ if ((u.l[1] & FE_INVALID) == 0) ++#endif ++ feraiseexcept (FE_INVALID); ++ b = a_nan.value; ++ } ++ return f_washf (b); ++} +diff -ruN libc-orig/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c libc/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c +--- libc-orig/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c 1969-12-31 18:00:00.000000000 -0600 ++++ libc/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c 2012-06-14 14:56:02.080000985 -0500 +@@ -0,0 +1,134 @@ ++/* Double-precision floating point square root. ++ Copyright (C) 2010 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. */ ++ ++#include <math.h> ++#include <math_private.h> ++#include <fenv_libc.h> ++#include <inttypes.h> ++ ++#include <sysdep.h> ++#include <ldsodefs.h> ++ ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; ++static const float two108 = 3.245185536584267269e+32; ++static const float twom54 = 5.551115123125782702e-17; ++static const float half = 0.5; ++ ++/* The method is based on the descriptions in: ++ ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 ++ ++ We find the actual square root and half of its reciprocal ++ simultaneously. */ ++ ++#ifdef __STDC__ ++double ++__ieee754_sqrt (double b) ++#else ++double ++__ieee754_sqrt (b) ++ double b; ++#endif ++{ ++ if (__builtin_expect (b > 0, 1)) ++ { ++ double y, g, h, d, r; ++ ieee_double_shape_type u; ++ ++ if (__builtin_expect (b != a_inf.value, 1)) ++ { ++ fenv_t fe; ++ ++ fe = fegetenv_register (); ++ ++ u.value = b; ++ ++ relax_fenv_state (); ++ ++ __asm__ ("frsqrte %[estimate], %[x]\n" ++ : [estimate] "=f" (y) : [x] "f" (b)); ++ ++ /* Following Muller et al, page 168, equation 5.20. ++ ++ h goes to 1/(2*sqrt(b)) ++ g goes to sqrt(b). ++ ++ We need three iterations to get within 1ulp. */ ++ ++ /* Indicate that these can be performed prior to the branch. GCC ++ insists on sinking them below the branch, however; it seems like ++ they'd be better before the branch so that we can cover any latency ++ from storing the argument and loading its high word. Oh well. */ ++ ++ g = b * y; ++ h = 0.5 * y; ++ ++ /* Handle small numbers by scaling. */ ++ if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0)) ++ return __ieee754_sqrt (b * two108) * twom54; ++ ++#define FMADD(a_, c_, b_) \ ++ ({ double __r; \ ++ __asm__ ("fmadd %[r], %[a], %[c], %[b]\n" \ ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ ++ __r;}) ++#define FNMSUB(a_, c_, b_) \ ++ ({ double __r; \ ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ ++ __r;}) ++ ++ r = FNMSUB (g, h, half); ++ g = FMADD (g, r, g); ++ h = FMADD (h, r, h); ++ ++ r = FNMSUB (g, h, half); ++ g = FMADD (g, r, g); ++ h = FMADD (h, r, h); ++ ++ r = FNMSUB (g, h, half); ++ g = FMADD (g, r, g); ++ h = FMADD (h, r, h); ++ ++ /* g is now +/- 1ulp, or exactly equal to, the square root of b. */ ++ ++ /* Final refinement. */ ++ d = FNMSUB (g, g, b); ++ ++ fesetenv_register (fe); ++ return FMADD (d, h, g); ++ } ++ } ++ else if (b < 0) ++ { ++ /* For some reason, some PowerPC32 processors don't implement ++ FE_INVALID_SQRT. */ ++#ifdef FE_INVALID_SQRT ++ feraiseexcept (FE_INVALID_SQRT); ++ ++ fenv_union_t u = { .fenv = fegetenv_register () }; ++ if ((u.l[1] & FE_INVALID) == 0) ++#endif ++ feraiseexcept (FE_INVALID); ++ b = a_nan.value; ++ } ++ return f_wash (b); ++} +diff -ruN libc-orig/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c libc/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c +--- libc-orig/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c 1969-12-31 18:00:00.000000000 -0600 ++++ libc/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c 2012-06-14 14:56:02.080000985 -0500 +@@ -0,0 +1,101 @@ ++/* Single-precision floating point square root. ++ Copyright (C) 2010 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. */ ++ ++#include <math.h> ++#include <math_private.h> ++#include <fenv_libc.h> ++#include <inttypes.h> ++ ++#include <sysdep.h> ++#include <ldsodefs.h> ++ ++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; ++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; ++static const float threehalf = 1.5; ++ ++/* The method is based on the descriptions in: ++ ++ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; ++ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 ++ ++ We find the reciprocal square root and use that to compute the actual ++ square root. */ ++ ++#ifdef __STDC__ ++float ++__ieee754_sqrtf (float b) ++#else ++float ++__ieee754_sqrtf (b) ++ float b; ++#endif ++{ ++ if (__builtin_expect (b > 0, 1)) ++ { ++#define FMSUB(a_, c_, b_) \ ++ ({ double __r; \ ++ __asm__ ("fmsub %[r], %[a], %[c], %[b]\n" \ ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ ++ __r;}) ++#define FNMSUB(a_, c_, b_) \ ++ ({ double __r; \ ++ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ ++ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ ++ __r;}) ++ ++ if (__builtin_expect (b != a_inf.value, 1)) ++ { ++ double y, x; ++ fenv_t fe; ++ ++ fe = fegetenv_register (); ++ ++ relax_fenv_state (); ++ ++ /* Compute y = 1.5 * b - b. Uses fewer constants than y = 0.5 * b. */ ++ y = FMSUB (threehalf, b, b); ++ ++ /* Initial estimate. */ ++ __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b)); ++ ++ /* Iterate. x_{n+1} = x_n * (1.5 - y * (x_n * x_n)). */ ++ x = x * FNMSUB (y, x * x, threehalf); ++ x = x * FNMSUB (y, x * x, threehalf); ++ x = x * FNMSUB (y, x * x, threehalf); ++ ++ /* All done. */ ++ fesetenv_register (fe); ++ return x * b; ++ } ++ } ++ else if (b < 0) ++ { ++ /* For some reason, some PowerPC32 processors don't implement ++ FE_INVALID_SQRT. */ ++#ifdef FE_INVALID_SQRT ++ feraiseexcept (FE_INVALID_SQRT); ++ ++ fenv_union_t u = { .fenv = fegetenv_register () }; ++ if ((u.l[1] & FE_INVALID) == 0) ++#endif ++ feraiseexcept (FE_INVALID); ++ b = a_nan.value; ++ } ++ return f_washf (b); ++} +diff -ruN libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/603e/fpu/Implies libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/603e/fpu/Implies +--- libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/603e/fpu/Implies 1969-12-31 18:00:00.000000000 -0600 ++++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/603e/fpu/Implies 2012-06-14 14:51:50.452001745 -0500 +@@ -0,0 +1 @@ ++powerpc/powerpc32/603e/fpu +diff -ruN libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/e500mc/fpu/Implies libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e500mc/fpu/Implies +--- libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/e500mc/fpu/Implies 1969-12-31 18:00:00.000000000 -0600 ++++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e500mc/fpu/Implies 2012-06-14 14:54:00.481000876 -0500 +@@ -0,0 +1 @@ ++powerpc/powerpc32/e500mc/fpu +diff -ruN libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/e5500/fpu/Implies libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e5500/fpu/Implies +--- libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/e5500/fpu/Implies 1969-12-31 18:00:00.000000000 -0600 ++++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e5500/fpu/Implies 2012-06-14 14:54:17.000001007 -0500 +@@ -0,0 +1 @@ ++powerpc/powerpc32/e5500/fpu +diff -ruN libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/e6500/fpu/Implies libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e6500/fpu/Implies +--- libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/e6500/fpu/Implies 1969-12-31 18:00:00.000000000 -0600 ++++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e6500/fpu/Implies 2012-06-14 14:54:31.054001299 -0500 +@@ -0,0 +1 @@ ++powerpc/powerpc32/e6500/fpu +diff -ruN libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/e5500/fpu/Implies libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/e5500/fpu/Implies +--- libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/e5500/fpu/Implies 1969-12-31 18:00:00.000000000 -0600 ++++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/e5500/fpu/Implies 2012-06-14 14:51:50.453001709 -0500 +@@ -0,0 +1 @@ ++powerpc/powerpc64/e5500/fpu +diff -ruN libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/e6500/fpu/Implies libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/e6500/fpu/Implies +--- libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/e6500/fpu/Implies 1969-12-31 18:00:00.000000000 -0600 ++++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/e6500/fpu/Implies 2012-06-14 14:58:14.298001288 -0500 +@@ -0,0 +1 @@ ++powerpc/powerpc64/e6500/fpu diff --git a/meta/recipes-core/eglibc/eglibc-2.16/ppc-sqrt.patch b/meta/recipes-core/eglibc/eglibc-2.16/ppc-sqrt.patch deleted file mode 100644 index 203040c..0000000 --- a/meta/recipes-core/eglibc/eglibc-2.16/ppc-sqrt.patch +++ /dev/null @@ -1,538 +0,0 @@ -Upstream-Status: Pending - -2011-03-22 Joseph Myers <joseph@codesourcery.com> - - Merge from SG++ 2.11: - - 2010-10-05 Nathan Froyd <froydnj@codesourcery.com> - - Issue #9382 - - * sysdeps/powerpc/powerpc32/603e/: New directory. - * sysdeps/unix/sysv/linux/powerpc/powerpc32/e500mc/: New directory. - * sysdeps/unix/sysv/linux/powerpc/powerpc32/603e/: New directory. - * sysdeps/unix/sysv/linux/powerpc/powerpc32/7400/: New directory. - * sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c: Update. - * sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c: Update. - * sysdeps/powerpc/powerpc64/e5500/fpu/Implies: New file. - -Index: libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c -=================================================================== ---- /dev/null -+++ libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c -@@ -0,0 +1,134 @@ -+/* Double-precision floating point square root. -+ Copyright (C) 2010 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. */ -+ -+#include <math.h> -+#include <math_private.h> -+#include <fenv_libc.h> -+#include <inttypes.h> -+ -+#include <sysdep.h> -+#include <ldsodefs.h> -+ -+static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; -+static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; -+static const float two108 = 3.245185536584267269e+32; -+static const float twom54 = 5.551115123125782702e-17; -+static const float half = 0.5; -+ -+/* The method is based on the descriptions in: -+ -+ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; -+ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 -+ -+ We find the actual square root and half of its reciprocal -+ simultaneously. */ -+ -+#ifdef __STDC__ -+double -+__ieee754_sqrt (double b) -+#else -+double -+__ieee754_sqrt (b) -+ double b; -+#endif -+{ -+ if (__builtin_expect (b > 0, 1)) -+ { -+ double y, g, h, d, r; -+ ieee_double_shape_type u; -+ -+ if (__builtin_expect (b != a_inf.value, 1)) -+ { -+ fenv_t fe; -+ -+ fe = fegetenv_register (); -+ -+ u.value = b; -+ -+ relax_fenv_state (); -+ -+ __asm__ ("frsqrte %[estimate], %[x]\n" -+ : [estimate] "=f" (y) : [x] "f" (b)); -+ -+ /* Following Muller et al, page 168, equation 5.20. -+ -+ h goes to 1/(2*sqrt(b)) -+ g goes to sqrt(b). -+ -+ We need three iterations to get within 1ulp. */ -+ -+ /* Indicate that these can be performed prior to the branch. GCC -+ insists on sinking them below the branch, however; it seems like -+ they'd be better before the branch so that we can cover any latency -+ from storing the argument and loading its high word. Oh well. */ -+ -+ g = b * y; -+ h = 0.5 * y; -+ -+ /* Handle small numbers by scaling. */ -+ if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0)) -+ return __ieee754_sqrt (b * two108) * twom54; -+ -+#define FMADD(a_, c_, b_) \ -+ ({ double __r; \ -+ __asm__ ("fmadd %[r], %[a], %[c], %[b]\n" \ -+ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ -+ __r;}) -+#define FNMSUB(a_, c_, b_) \ -+ ({ double __r; \ -+ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ -+ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ -+ __r;}) -+ -+ r = FNMSUB (g, h, half); -+ g = FMADD (g, r, g); -+ h = FMADD (h, r, h); -+ -+ r = FNMSUB (g, h, half); -+ g = FMADD (g, r, g); -+ h = FMADD (h, r, h); -+ -+ r = FNMSUB (g, h, half); -+ g = FMADD (g, r, g); -+ h = FMADD (h, r, h); -+ -+ /* g is now +/- 1ulp, or exactly equal to, the square root of b. */ -+ -+ /* Final refinement. */ -+ d = FNMSUB (g, g, b); -+ -+ fesetenv_register (fe); -+ return FMADD (d, h, g); -+ } -+ } -+ else if (b < 0) -+ { -+ /* For some reason, some PowerPC32 processors don't implement -+ FE_INVALID_SQRT. */ -+#ifdef FE_INVALID_SQRT -+ feraiseexcept (FE_INVALID_SQRT); -+ -+ fenv_union_t u = { .fenv = fegetenv_register () }; -+ if ((u.l[1] & FE_INVALID) == 0) -+#endif -+ feraiseexcept (FE_INVALID); -+ b = a_nan.value; -+ } -+ return f_wash (b); -+} -Index: libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c -=================================================================== ---- /dev/null -+++ libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c -@@ -0,0 +1,101 @@ -+/* Single-precision floating point square root. -+ Copyright (C) 2010 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. */ -+ -+#include <math.h> -+#include <math_private.h> -+#include <fenv_libc.h> -+#include <inttypes.h> -+ -+#include <sysdep.h> -+#include <ldsodefs.h> -+ -+static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; -+static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; -+static const float threehalf = 1.5; -+ -+/* The method is based on the descriptions in: -+ -+ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; -+ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 -+ -+ We find the reciprocal square root and use that to compute the actual -+ square root. */ -+ -+#ifdef __STDC__ -+float -+__ieee754_sqrtf (float b) -+#else -+float -+__ieee754_sqrtf (b) -+ float b; -+#endif -+{ -+ if (__builtin_expect (b > 0, 1)) -+ { -+#define FMSUB(a_, c_, b_) \ -+ ({ double __r; \ -+ __asm__ ("fmsub %[r], %[a], %[c], %[b]\n" \ -+ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ -+ __r;}) -+#define FNMSUB(a_, c_, b_) \ -+ ({ double __r; \ -+ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ -+ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ -+ __r;}) -+ -+ if (__builtin_expect (b != a_inf.value, 1)) -+ { -+ double y, x; -+ fenv_t fe; -+ -+ fe = fegetenv_register (); -+ -+ relax_fenv_state (); -+ -+ /* Compute y = 1.5 * b - b. Uses fewer constants than y = 0.5 * b. */ -+ y = FMSUB (threehalf, b, b); -+ -+ /* Initial estimate. */ -+ __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b)); -+ -+ /* Iterate. x_{n+1} = x_n * (1.5 - y * (x_n * x_n)). */ -+ x = x * FNMSUB (y, x * x, threehalf); -+ x = x * FNMSUB (y, x * x, threehalf); -+ x = x * FNMSUB (y, x * x, threehalf); -+ -+ /* All done. */ -+ fesetenv_register (fe); -+ return x * b; -+ } -+ } -+ else if (b < 0) -+ { -+ /* For some reason, some PowerPC32 processors don't implement -+ FE_INVALID_SQRT. */ -+#ifdef FE_INVALID_SQRT -+ feraiseexcept (FE_INVALID_SQRT); -+ -+ fenv_union_t u = { .fenv = fegetenv_register () }; -+ if ((u.l[1] & FE_INVALID) == 0) -+#endif -+ feraiseexcept (FE_INVALID); -+ b = a_nan.value; -+ } -+ return f_washf (b); -+} -Index: libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c -=================================================================== ---- /dev/null -+++ libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c -@@ -0,0 +1,134 @@ -+/* Double-precision floating point square root. -+ Copyright (C) 2010 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. */ -+ -+#include <math.h> -+#include <math_private.h> -+#include <fenv_libc.h> -+#include <inttypes.h> -+ -+#include <sysdep.h> -+#include <ldsodefs.h> -+ -+static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; -+static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; -+static const float two108 = 3.245185536584267269e+32; -+static const float twom54 = 5.551115123125782702e-17; -+static const float half = 0.5; -+ -+/* The method is based on the descriptions in: -+ -+ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; -+ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 -+ -+ We find the actual square root and half of its reciprocal -+ simultaneously. */ -+ -+#ifdef __STDC__ -+double -+__ieee754_sqrt (double b) -+#else -+double -+__ieee754_sqrt (b) -+ double b; -+#endif -+{ -+ if (__builtin_expect (b > 0, 1)) -+ { -+ double y, g, h, d, r; -+ ieee_double_shape_type u; -+ -+ if (__builtin_expect (b != a_inf.value, 1)) -+ { -+ fenv_t fe; -+ -+ fe = fegetenv_register (); -+ -+ u.value = b; -+ -+ relax_fenv_state (); -+ -+ __asm__ ("frsqrte %[estimate], %[x]\n" -+ : [estimate] "=f" (y) : [x] "f" (b)); -+ -+ /* Following Muller et al, page 168, equation 5.20. -+ -+ h goes to 1/(2*sqrt(b)) -+ g goes to sqrt(b). -+ -+ We need three iterations to get within 1ulp. */ -+ -+ /* Indicate that these can be performed prior to the branch. GCC -+ insists on sinking them below the branch, however; it seems like -+ they'd be better before the branch so that we can cover any latency -+ from storing the argument and loading its high word. Oh well. */ -+ -+ g = b * y; -+ h = 0.5 * y; -+ -+ /* Handle small numbers by scaling. */ -+ if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0)) -+ return __ieee754_sqrt (b * two108) * twom54; -+ -+#define FMADD(a_, c_, b_) \ -+ ({ double __r; \ -+ __asm__ ("fmadd %[r], %[a], %[c], %[b]\n" \ -+ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ -+ __r;}) -+#define FNMSUB(a_, c_, b_) \ -+ ({ double __r; \ -+ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ -+ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ -+ __r;}) -+ -+ r = FNMSUB (g, h, half); -+ g = FMADD (g, r, g); -+ h = FMADD (h, r, h); -+ -+ r = FNMSUB (g, h, half); -+ g = FMADD (g, r, g); -+ h = FMADD (h, r, h); -+ -+ r = FNMSUB (g, h, half); -+ g = FMADD (g, r, g); -+ h = FMADD (h, r, h); -+ -+ /* g is now +/- 1ulp, or exactly equal to, the square root of b. */ -+ -+ /* Final refinement. */ -+ d = FNMSUB (g, g, b); -+ -+ fesetenv_register (fe); -+ return FMADD (d, h, g); -+ } -+ } -+ else if (b < 0) -+ { -+ /* For some reason, some PowerPC32 processors don't implement -+ FE_INVALID_SQRT. */ -+#ifdef FE_INVALID_SQRT -+ feraiseexcept (FE_INVALID_SQRT); -+ -+ fenv_union_t u = { .fenv = fegetenv_register () }; -+ if ((u.l[1] & FE_INVALID) == 0) -+#endif -+ feraiseexcept (FE_INVALID); -+ b = a_nan.value; -+ } -+ return f_wash (b); -+} -Index: libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c -=================================================================== ---- /dev/null -+++ libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c -@@ -0,0 +1,101 @@ -+/* Single-precision floating point square root. -+ Copyright (C) 2010 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. */ -+ -+#include <math.h> -+#include <math_private.h> -+#include <fenv_libc.h> -+#include <inttypes.h> -+ -+#include <sysdep.h> -+#include <ldsodefs.h> -+ -+static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; -+static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; -+static const float threehalf = 1.5; -+ -+/* The method is based on the descriptions in: -+ -+ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; -+ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 -+ -+ We find the reciprocal square root and use that to compute the actual -+ square root. */ -+ -+#ifdef __STDC__ -+float -+__ieee754_sqrtf (float b) -+#else -+float -+__ieee754_sqrtf (b) -+ float b; -+#endif -+{ -+ if (__builtin_expect (b > 0, 1)) -+ { -+#define FMSUB(a_, c_, b_) \ -+ ({ double __r; \ -+ __asm__ ("fmsub %[r], %[a], %[c], %[b]\n" \ -+ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ -+ __r;}) -+#define FNMSUB(a_, c_, b_) \ -+ ({ double __r; \ -+ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ -+ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ -+ __r;}) -+ -+ if (__builtin_expect (b != a_inf.value, 1)) -+ { -+ double y, x; -+ fenv_t fe; -+ -+ fe = fegetenv_register (); -+ -+ relax_fenv_state (); -+ -+ /* Compute y = 1.5 * b - b. Uses fewer constants than y = 0.5 * b. */ -+ y = FMSUB (threehalf, b, b); -+ -+ /* Initial estimate. */ -+ __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b)); -+ -+ /* Iterate. x_{n+1} = x_n * (1.5 - y * (x_n * x_n)). */ -+ x = x * FNMSUB (y, x * x, threehalf); -+ x = x * FNMSUB (y, x * x, threehalf); -+ x = x * FNMSUB (y, x * x, threehalf); -+ -+ /* All done. */ -+ fesetenv_register (fe); -+ return x * b; -+ } -+ } -+ else if (b < 0) -+ { -+ /* For some reason, some PowerPC32 processors don't implement -+ FE_INVALID_SQRT. */ -+#ifdef FE_INVALID_SQRT -+ feraiseexcept (FE_INVALID_SQRT); -+ -+ fenv_union_t u = { .fenv = fegetenv_register () }; -+ if ((u.l[1] & FE_INVALID) == 0) -+#endif -+ feraiseexcept (FE_INVALID); -+ b = a_nan.value; -+ } -+ return f_washf (b); -+} -Index: libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/603e/fpu/Implies -=================================================================== ---- /dev/null -+++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/603e/fpu/Implies -@@ -0,0 +1 @@ -+powerpc/powerpc32/603e/fpu -Index: libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/7400/fpu/Implies -=================================================================== ---- /dev/null -+++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/7400/fpu/Implies -@@ -0,0 +1 @@ -+powerpc/powerpc32/603e/fpu -Index: libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e500mc/fpu/Implies -=================================================================== ---- /dev/null -+++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e500mc/fpu/Implies -@@ -0,0 +1 @@ -+powerpc/powerpc32/603e/fpu -Index: libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/e5500/fpu/Implies -=================================================================== ---- /dev/null -+++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/e5500/fpu/Implies -@@ -0,0 +1 @@ -+powerpc/powerpc64/e5500/fpu -Index: libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e5500/fpu/Implies -=================================================================== ---- /dev/null -+++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e5500/fpu/Implies -@@ -0,0 +1 @@ -+powerpc/powerpc32/603e/fpu diff --git a/meta/recipes-core/eglibc/eglibc_2.16.bb b/meta/recipes-core/eglibc/eglibc_2.16.bb index 78dc44a..a753882 100644 --- a/meta/recipes-core/eglibc/eglibc_2.16.bb +++ b/meta/recipes-core/eglibc/eglibc_2.16.bb @@ -3,7 +3,7 @@ require eglibc.inc SRCREV = "20393" DEPENDS += "gperf-native kconfig-frontends-native" -PR = "r9" +PR = "r10" PR_append = "+svnr${SRCPV}" EGLIBC_BRANCH="eglibc-2_16" @@ -13,7 +13,7 @@ SRC_URI = "svn://www.eglibc.org/svn/branches/;module=${EGLIBC_BRANCH};protocol=h file://mips-rld-map-check.patch \ file://etc/ld.so.conf \ file://generate-supported.mk \ - file://ppc-sqrt.patch \ + file://glibc.fix_sqrt2.patch \ file://multilib_readlib.patch \ file://use-sysroot-cxx-headers.patch \ file://ppc-sqrt_finite.patch \
Signed-off-by: Matthew McClintock <msm@freescale.com> --- .../eglibc/eglibc-2.16/glibc.fix_sqrt2.patch | 1488 ++++++++++++++++++++ .../recipes-core/eglibc/eglibc-2.16/ppc-sqrt.patch | 538 ------- meta/recipes-core/eglibc/eglibc_2.16.bb | 4 +- 3 files changed, 1490 insertions(+), 540 deletions(-) create mode 100644 meta/recipes-core/eglibc/eglibc-2.16/glibc.fix_sqrt2.patch delete mode 100644 meta/recipes-core/eglibc/eglibc-2.16/ppc-sqrt.patch