summaryrefslogtreecommitdiffstats
path: root/meta/recipes-core/eglibc/eglibc-2.15/ppc-sqrt.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-core/eglibc/eglibc-2.15/ppc-sqrt.patch')
-rw-r--r--meta/recipes-core/eglibc/eglibc-2.15/ppc-sqrt.patch538
1 files changed, 538 insertions, 0 deletions
diff --git a/meta/recipes-core/eglibc/eglibc-2.15/ppc-sqrt.patch b/meta/recipes-core/eglibc/eglibc-2.15/ppc-sqrt.patch
new file mode 100644
index 0000000000..203040c15c
--- /dev/null
+++ b/meta/recipes-core/eglibc/eglibc-2.15/ppc-sqrt.patch
@@ -0,0 +1,538 @@
1Upstream-Status: Pending
2
32011-03-22 Joseph Myers <joseph@codesourcery.com>
4
5 Merge from SG++ 2.11:
6
7 2010-10-05 Nathan Froyd <froydnj@codesourcery.com>
8
9 Issue #9382
10
11 * sysdeps/powerpc/powerpc32/603e/: New directory.
12 * sysdeps/unix/sysv/linux/powerpc/powerpc32/e500mc/: New directory.
13 * sysdeps/unix/sysv/linux/powerpc/powerpc32/603e/: New directory.
14 * sysdeps/unix/sysv/linux/powerpc/powerpc32/7400/: New directory.
15 * sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c: Update.
16 * sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c: Update.
17 * sysdeps/powerpc/powerpc64/e5500/fpu/Implies: New file.
18
19Index: libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c
20===================================================================
21--- /dev/null
22+++ libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c
23@@ -0,0 +1,134 @@
24+/* Double-precision floating point square root.
25+ Copyright (C) 2010 Free Software Foundation, Inc.
26+ This file is part of the GNU C Library.
27+
28+ The GNU C Library is free software; you can redistribute it and/or
29+ modify it under the terms of the GNU Lesser General Public
30+ License as published by the Free Software Foundation; either
31+ version 2.1 of the License, or (at your option) any later version.
32+
33+ The GNU C Library is distributed in the hope that it will be useful,
34+ but WITHOUT ANY WARRANTY; without even the implied warranty of
35+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
36+ Lesser General Public License for more details.
37+
38+ You should have received a copy of the GNU Lesser General Public
39+ License along with the GNU C Library; if not, write to the Free
40+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
41+ 02111-1307 USA. */
42+
43+#include <math.h>
44+#include <math_private.h>
45+#include <fenv_libc.h>
46+#include <inttypes.h>
47+
48+#include <sysdep.h>
49+#include <ldsodefs.h>
50+
51+static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 };
52+static const ieee_float_shape_type a_inf = {.word = 0x7f800000 };
53+static const float two108 = 3.245185536584267269e+32;
54+static const float twom54 = 5.551115123125782702e-17;
55+static const float half = 0.5;
56+
57+/* The method is based on the descriptions in:
58+
59+ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5;
60+ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9
61+
62+ We find the actual square root and half of its reciprocal
63+ simultaneously. */
64+
65+#ifdef __STDC__
66+double
67+__ieee754_sqrt (double b)
68+#else
69+double
70+__ieee754_sqrt (b)
71+ double b;
72+#endif
73+{
74+ if (__builtin_expect (b > 0, 1))
75+ {
76+ double y, g, h, d, r;
77+ ieee_double_shape_type u;
78+
79+ if (__builtin_expect (b != a_inf.value, 1))
80+ {
81+ fenv_t fe;
82+
83+ fe = fegetenv_register ();
84+
85+ u.value = b;
86+
87+ relax_fenv_state ();
88+
89+ __asm__ ("frsqrte %[estimate], %[x]\n"
90+ : [estimate] "=f" (y) : [x] "f" (b));
91+
92+ /* Following Muller et al, page 168, equation 5.20.
93+
94+ h goes to 1/(2*sqrt(b))
95+ g goes to sqrt(b).
96+
97+ We need three iterations to get within 1ulp. */
98+
99+ /* Indicate that these can be performed prior to the branch. GCC
100+ insists on sinking them below the branch, however; it seems like
101+ they'd be better before the branch so that we can cover any latency
102+ from storing the argument and loading its high word. Oh well. */
103+
104+ g = b * y;
105+ h = 0.5 * y;
106+
107+ /* Handle small numbers by scaling. */
108+ if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0))
109+ return __ieee754_sqrt (b * two108) * twom54;
110+
111+#define FMADD(a_, c_, b_) \
112+ ({ double __r; \
113+ __asm__ ("fmadd %[r], %[a], %[c], %[b]\n" \
114+ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
115+ __r;})
116+#define FNMSUB(a_, c_, b_) \
117+ ({ double __r; \
118+ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \
119+ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
120+ __r;})
121+
122+ r = FNMSUB (g, h, half);
123+ g = FMADD (g, r, g);
124+ h = FMADD (h, r, h);
125+
126+ r = FNMSUB (g, h, half);
127+ g = FMADD (g, r, g);
128+ h = FMADD (h, r, h);
129+
130+ r = FNMSUB (g, h, half);
131+ g = FMADD (g, r, g);
132+ h = FMADD (h, r, h);
133+
134+ /* g is now +/- 1ulp, or exactly equal to, the square root of b. */
135+
136+ /* Final refinement. */
137+ d = FNMSUB (g, g, b);
138+
139+ fesetenv_register (fe);
140+ return FMADD (d, h, g);
141+ }
142+ }
143+ else if (b < 0)
144+ {
145+ /* For some reason, some PowerPC32 processors don't implement
146+ FE_INVALID_SQRT. */
147+#ifdef FE_INVALID_SQRT
148+ feraiseexcept (FE_INVALID_SQRT);
149+
150+ fenv_union_t u = { .fenv = fegetenv_register () };
151+ if ((u.l[1] & FE_INVALID) == 0)
152+#endif
153+ feraiseexcept (FE_INVALID);
154+ b = a_nan.value;
155+ }
156+ return f_wash (b);
157+}
158Index: libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c
159===================================================================
160--- /dev/null
161+++ libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c
162@@ -0,0 +1,101 @@
163+/* Single-precision floating point square root.
164+ Copyright (C) 2010 Free Software Foundation, Inc.
165+ This file is part of the GNU C Library.
166+
167+ The GNU C Library is free software; you can redistribute it and/or
168+ modify it under the terms of the GNU Lesser General Public
169+ License as published by the Free Software Foundation; either
170+ version 2.1 of the License, or (at your option) any later version.
171+
172+ The GNU C Library is distributed in the hope that it will be useful,
173+ but WITHOUT ANY WARRANTY; without even the implied warranty of
174+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
175+ Lesser General Public License for more details.
176+
177+ You should have received a copy of the GNU Lesser General Public
178+ License along with the GNU C Library; if not, write to the Free
179+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
180+ 02111-1307 USA. */
181+
182+#include <math.h>
183+#include <math_private.h>
184+#include <fenv_libc.h>
185+#include <inttypes.h>
186+
187+#include <sysdep.h>
188+#include <ldsodefs.h>
189+
190+static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 };
191+static const ieee_float_shape_type a_inf = {.word = 0x7f800000 };
192+static const float threehalf = 1.5;
193+
194+/* The method is based on the descriptions in:
195+
196+ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5;
197+ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9
198+
199+ We find the reciprocal square root and use that to compute the actual
200+ square root. */
201+
202+#ifdef __STDC__
203+float
204+__ieee754_sqrtf (float b)
205+#else
206+float
207+__ieee754_sqrtf (b)
208+ float b;
209+#endif
210+{
211+ if (__builtin_expect (b > 0, 1))
212+ {
213+#define FMSUB(a_, c_, b_) \
214+ ({ double __r; \
215+ __asm__ ("fmsub %[r], %[a], %[c], %[b]\n" \
216+ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
217+ __r;})
218+#define FNMSUB(a_, c_, b_) \
219+ ({ double __r; \
220+ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \
221+ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
222+ __r;})
223+
224+ if (__builtin_expect (b != a_inf.value, 1))
225+ {
226+ double y, x;
227+ fenv_t fe;
228+
229+ fe = fegetenv_register ();
230+
231+ relax_fenv_state ();
232+
233+ /* Compute y = 1.5 * b - b. Uses fewer constants than y = 0.5 * b. */
234+ y = FMSUB (threehalf, b, b);
235+
236+ /* Initial estimate. */
237+ __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b));
238+
239+ /* Iterate. x_{n+1} = x_n * (1.5 - y * (x_n * x_n)). */
240+ x = x * FNMSUB (y, x * x, threehalf);
241+ x = x * FNMSUB (y, x * x, threehalf);
242+ x = x * FNMSUB (y, x * x, threehalf);
243+
244+ /* All done. */
245+ fesetenv_register (fe);
246+ return x * b;
247+ }
248+ }
249+ else if (b < 0)
250+ {
251+ /* For some reason, some PowerPC32 processors don't implement
252+ FE_INVALID_SQRT. */
253+#ifdef FE_INVALID_SQRT
254+ feraiseexcept (FE_INVALID_SQRT);
255+
256+ fenv_union_t u = { .fenv = fegetenv_register () };
257+ if ((u.l[1] & FE_INVALID) == 0)
258+#endif
259+ feraiseexcept (FE_INVALID);
260+ b = a_nan.value;
261+ }
262+ return f_washf (b);
263+}
264Index: libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c
265===================================================================
266--- /dev/null
267+++ libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c
268@@ -0,0 +1,134 @@
269+/* Double-precision floating point square root.
270+ Copyright (C) 2010 Free Software Foundation, Inc.
271+ This file is part of the GNU C Library.
272+
273+ The GNU C Library is free software; you can redistribute it and/or
274+ modify it under the terms of the GNU Lesser General Public
275+ License as published by the Free Software Foundation; either
276+ version 2.1 of the License, or (at your option) any later version.
277+
278+ The GNU C Library is distributed in the hope that it will be useful,
279+ but WITHOUT ANY WARRANTY; without even the implied warranty of
280+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
281+ Lesser General Public License for more details.
282+
283+ You should have received a copy of the GNU Lesser General Public
284+ License along with the GNU C Library; if not, write to the Free
285+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
286+ 02111-1307 USA. */
287+
288+#include <math.h>
289+#include <math_private.h>
290+#include <fenv_libc.h>
291+#include <inttypes.h>
292+
293+#include <sysdep.h>
294+#include <ldsodefs.h>
295+
296+static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 };
297+static const ieee_float_shape_type a_inf = {.word = 0x7f800000 };
298+static const float two108 = 3.245185536584267269e+32;
299+static const float twom54 = 5.551115123125782702e-17;
300+static const float half = 0.5;
301+
302+/* The method is based on the descriptions in:
303+
304+ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5;
305+ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9
306+
307+ We find the actual square root and half of its reciprocal
308+ simultaneously. */
309+
310+#ifdef __STDC__
311+double
312+__ieee754_sqrt (double b)
313+#else
314+double
315+__ieee754_sqrt (b)
316+ double b;
317+#endif
318+{
319+ if (__builtin_expect (b > 0, 1))
320+ {
321+ double y, g, h, d, r;
322+ ieee_double_shape_type u;
323+
324+ if (__builtin_expect (b != a_inf.value, 1))
325+ {
326+ fenv_t fe;
327+
328+ fe = fegetenv_register ();
329+
330+ u.value = b;
331+
332+ relax_fenv_state ();
333+
334+ __asm__ ("frsqrte %[estimate], %[x]\n"
335+ : [estimate] "=f" (y) : [x] "f" (b));
336+
337+ /* Following Muller et al, page 168, equation 5.20.
338+
339+ h goes to 1/(2*sqrt(b))
340+ g goes to sqrt(b).
341+
342+ We need three iterations to get within 1ulp. */
343+
344+ /* Indicate that these can be performed prior to the branch. GCC
345+ insists on sinking them below the branch, however; it seems like
346+ they'd be better before the branch so that we can cover any latency
347+ from storing the argument and loading its high word. Oh well. */
348+
349+ g = b * y;
350+ h = 0.5 * y;
351+
352+ /* Handle small numbers by scaling. */
353+ if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0))
354+ return __ieee754_sqrt (b * two108) * twom54;
355+
356+#define FMADD(a_, c_, b_) \
357+ ({ double __r; \
358+ __asm__ ("fmadd %[r], %[a], %[c], %[b]\n" \
359+ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
360+ __r;})
361+#define FNMSUB(a_, c_, b_) \
362+ ({ double __r; \
363+ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \
364+ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
365+ __r;})
366+
367+ r = FNMSUB (g, h, half);
368+ g = FMADD (g, r, g);
369+ h = FMADD (h, r, h);
370+
371+ r = FNMSUB (g, h, half);
372+ g = FMADD (g, r, g);
373+ h = FMADD (h, r, h);
374+
375+ r = FNMSUB (g, h, half);
376+ g = FMADD (g, r, g);
377+ h = FMADD (h, r, h);
378+
379+ /* g is now +/- 1ulp, or exactly equal to, the square root of b. */
380+
381+ /* Final refinement. */
382+ d = FNMSUB (g, g, b);
383+
384+ fesetenv_register (fe);
385+ return FMADD (d, h, g);
386+ }
387+ }
388+ else if (b < 0)
389+ {
390+ /* For some reason, some PowerPC32 processors don't implement
391+ FE_INVALID_SQRT. */
392+#ifdef FE_INVALID_SQRT
393+ feraiseexcept (FE_INVALID_SQRT);
394+
395+ fenv_union_t u = { .fenv = fegetenv_register () };
396+ if ((u.l[1] & FE_INVALID) == 0)
397+#endif
398+ feraiseexcept (FE_INVALID);
399+ b = a_nan.value;
400+ }
401+ return f_wash (b);
402+}
403Index: libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c
404===================================================================
405--- /dev/null
406+++ libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c
407@@ -0,0 +1,101 @@
408+/* Single-precision floating point square root.
409+ Copyright (C) 2010 Free Software Foundation, Inc.
410+ This file is part of the GNU C Library.
411+
412+ The GNU C Library is free software; you can redistribute it and/or
413+ modify it under the terms of the GNU Lesser General Public
414+ License as published by the Free Software Foundation; either
415+ version 2.1 of the License, or (at your option) any later version.
416+
417+ The GNU C Library is distributed in the hope that it will be useful,
418+ but WITHOUT ANY WARRANTY; without even the implied warranty of
419+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
420+ Lesser General Public License for more details.
421+
422+ You should have received a copy of the GNU Lesser General Public
423+ License along with the GNU C Library; if not, write to the Free
424+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
425+ 02111-1307 USA. */
426+
427+#include <math.h>
428+#include <math_private.h>
429+#include <fenv_libc.h>
430+#include <inttypes.h>
431+
432+#include <sysdep.h>
433+#include <ldsodefs.h>
434+
435+static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 };
436+static const ieee_float_shape_type a_inf = {.word = 0x7f800000 };
437+static const float threehalf = 1.5;
438+
439+/* The method is based on the descriptions in:
440+
441+ _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5;
442+ _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9
443+
444+ We find the reciprocal square root and use that to compute the actual
445+ square root. */
446+
447+#ifdef __STDC__
448+float
449+__ieee754_sqrtf (float b)
450+#else
451+float
452+__ieee754_sqrtf (b)
453+ float b;
454+#endif
455+{
456+ if (__builtin_expect (b > 0, 1))
457+ {
458+#define FMSUB(a_, c_, b_) \
459+ ({ double __r; \
460+ __asm__ ("fmsub %[r], %[a], %[c], %[b]\n" \
461+ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
462+ __r;})
463+#define FNMSUB(a_, c_, b_) \
464+ ({ double __r; \
465+ __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \
466+ : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
467+ __r;})
468+
469+ if (__builtin_expect (b != a_inf.value, 1))
470+ {
471+ double y, x;
472+ fenv_t fe;
473+
474+ fe = fegetenv_register ();
475+
476+ relax_fenv_state ();
477+
478+ /* Compute y = 1.5 * b - b. Uses fewer constants than y = 0.5 * b. */
479+ y = FMSUB (threehalf, b, b);
480+
481+ /* Initial estimate. */
482+ __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b));
483+
484+ /* Iterate. x_{n+1} = x_n * (1.5 - y * (x_n * x_n)). */
485+ x = x * FNMSUB (y, x * x, threehalf);
486+ x = x * FNMSUB (y, x * x, threehalf);
487+ x = x * FNMSUB (y, x * x, threehalf);
488+
489+ /* All done. */
490+ fesetenv_register (fe);
491+ return x * b;
492+ }
493+ }
494+ else if (b < 0)
495+ {
496+ /* For some reason, some PowerPC32 processors don't implement
497+ FE_INVALID_SQRT. */
498+#ifdef FE_INVALID_SQRT
499+ feraiseexcept (FE_INVALID_SQRT);
500+
501+ fenv_union_t u = { .fenv = fegetenv_register () };
502+ if ((u.l[1] & FE_INVALID) == 0)
503+#endif
504+ feraiseexcept (FE_INVALID);
505+ b = a_nan.value;
506+ }
507+ return f_washf (b);
508+}
509Index: libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/603e/fpu/Implies
510===================================================================
511--- /dev/null
512+++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/603e/fpu/Implies
513@@ -0,0 +1 @@
514+powerpc/powerpc32/603e/fpu
515Index: libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/7400/fpu/Implies
516===================================================================
517--- /dev/null
518+++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/7400/fpu/Implies
519@@ -0,0 +1 @@
520+powerpc/powerpc32/603e/fpu
521Index: libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e500mc/fpu/Implies
522===================================================================
523--- /dev/null
524+++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e500mc/fpu/Implies
525@@ -0,0 +1 @@
526+powerpc/powerpc32/603e/fpu
527Index: libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/e5500/fpu/Implies
528===================================================================
529--- /dev/null
530+++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/e5500/fpu/Implies
531@@ -0,0 +1 @@
532+powerpc/powerpc64/e5500/fpu
533Index: libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e5500/fpu/Implies
534===================================================================
535--- /dev/null
536+++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e5500/fpu/Implies
537@@ -0,0 +1 @@
538+powerpc/powerpc32/603e/fpu