diff options
Diffstat (limited to 'REORG.TODO/sysdeps/powerpc/fpu')
50 files changed, 6026 insertions, 0 deletions
diff --git a/REORG.TODO/sysdeps/powerpc/fpu/Makefile b/REORG.TODO/sysdeps/powerpc/fpu/Makefile new file mode 100644 index 0000000000..53470a9cf2 --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/Makefile @@ -0,0 +1,7 @@ +ifeq ($(subdir),math) +libm-support += fenv_const fe_nomask fe_mask t_sqrt +endif + +ifeq ($(subdir),stdlib) +tests += tst-setcontext-fpscr +endif diff --git a/REORG.TODO/sysdeps/powerpc/fpu/e_hypot.c b/REORG.TODO/sysdeps/powerpc/fpu/e_hypot.c new file mode 100644 index 0000000000..2685ca6ba0 --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/e_hypot.c @@ -0,0 +1,134 @@ +/* Pythagorean addition using doubles + Copyright (C) 2011-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library + Contributed by Adhemerval Zanella <azanella@br.ibm.com>, 2011 + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If + not, see <http://www.gnu.org/licenses/>. */ + +#include <math.h> +#include <math_private.h> +#include <stdint.h> + +static const double two60 = 1.152921504606847e+18; +static const double two500 = 3.2733906078961419e+150; +static const double two600 = 4.149515568880993e+180; +static const double two1022 = 4.49423283715579e+307; +static const double twoM500 = 3.054936363499605e-151; +static const double twoM600 = 2.4099198651028841e-181; +static const double two60factor = 1.5592502418239997e+290; +static const double pdnum = 2.225073858507201e-308; + +/* __ieee754_hypot(x,y) + * + * This a FP only version without any FP->INT conversion. + * It is similar to default C version, making appropriates + * overflow and underflows checks as well scaling when it + * is needed. + */ + +#ifdef _ARCH_PWR7 +/* POWER7 isinf and isnan optimization are fast. */ +# define TEST_INF_NAN(x, y) \ + if ((isinf(x) || isinf(y)) \ + && !issignaling (x) && !issignaling (y)) \ + return INFINITY; \ + if (isnan(x) || isnan(y)) \ + return x + y; +# else +/* For POWER6 and below isinf/isnan triggers LHS and PLT calls are + * costly (especially for POWER6). */ +# define GET_TW0_HIGH_WORD(d1,d2,i1,i2) \ + do { \ + ieee_double_shape_type gh_u1; \ + ieee_double_shape_type gh_u2; \ + gh_u1.value = (d1); \ + gh_u2.value = (d2); \ + (i1) = gh_u1.parts.msw & 0x7fffffff; \ + (i2) = gh_u2.parts.msw & 0x7fffffff; \ + } while (0) + +# define TEST_INF_NAN(x, y) \ + do { \ + uint32_t hx, hy; \ + GET_TW0_HIGH_WORD(x, y, hx, hy); \ + if (hy > hx) { \ + uint32_t ht = hx; hx = hy; hy = ht; \ + } \ + if (hx >= 0x7ff00000) { \ + if ((hx == 0x7ff00000 || hy == 0x7ff00000) \ + && !issignaling (x) && !issignaling (y)) \ + return INFINITY; \ + return x + y; \ + } \ + } while (0) + +#endif + + +double +__ieee754_hypot (double x, double y) +{ + x = fabs (x); + y = fabs (y); + + TEST_INF_NAN (x, y); + + if (y > x) + { + double t = x; + x = y; + y = t; + } + if (y == 0.0) + return x; + /* if y is higher enough, y * 2^60 might overflow. The tests if + y >= 1.7976931348623157e+308/2^60 (two60factor) and uses the + appropriate check to avoid the overflow exception generation. */ + if (y > two60factor) + { + if ((x / y) > two60) + return x + y; + } + else + { + if (x > (y * two60)) + return x + y; + } + if (x > two500) + { + x *= twoM600; + y *= twoM600; + return __ieee754_sqrt (x * x + y * y) / twoM600; + } + if (y < twoM500) + { + if (y <= pdnum) + { + x *= two1022; + y *= two1022; + double ret = __ieee754_sqrt (x * x + y * y) / two1022; + math_check_force_underflow_nonneg (ret); + return ret; + } + else + { + x *= two600; + y *= two600; + return __ieee754_sqrt (x * x + y * y) / two600; + } + } + return __ieee754_sqrt (x * x + y * y); +} +strong_alias (__ieee754_hypot, __hypot_finite) diff --git a/REORG.TODO/sysdeps/powerpc/fpu/e_hypotf.c b/REORG.TODO/sysdeps/powerpc/fpu/e_hypotf.c new file mode 100644 index 0000000000..8502ca962a --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/e_hypotf.c @@ -0,0 +1,76 @@ +/* Pythagorean addition using floats + Copyright (C) 2011-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Adhemerval Zanella <azanella@br.ibm.com>, 2011 + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If + not, see <http://www.gnu.org/licenses/>. */ + +#include <math.h> +#include <math_private.h> +#include <stdint.h> + +/* __ieee754_hypotf(x,y) + + This a FP only version without any FP->INT conversion. + It is similar to default C version, making appropriates + overflow and underflows checks as using double precision + instead of scaling. */ + +#ifdef _ARCH_PWR7 +/* POWER7 isinf and isnan optimizations are fast. */ +# define TEST_INF_NAN(x, y) \ + if ((isinff(x) || isinff(y)) \ + && !issignaling (x) && !issignaling (y)) \ + return INFINITY; \ + if (isnanf(x) || isnanf(y)) \ + return x + y; +# else +/* For POWER6 and below isinf/isnan triggers LHS and PLT calls are + * costly (especially for POWER6). */ +# define GET_TWO_FLOAT_WORD(f1,f2,i1,i2) \ + do { \ + ieee_float_shape_type gf_u1; \ + ieee_float_shape_type gf_u2; \ + gf_u1.value = (f1); \ + gf_u2.value = (f2); \ + (i1) = gf_u1.word & 0x7fffffff; \ + (i2) = gf_u2.word & 0x7fffffff; \ + } while (0) + +# define TEST_INF_NAN(x, y) \ + do { \ + uint32_t hx, hy; \ + GET_TWO_FLOAT_WORD(x, y, hx, hy); \ + if (hy > hx) { \ + uint32_t ht = hx; hx = hy; hy = ht; \ + } \ + if (hx >= 0x7f800000) { \ + if ((hx == 0x7f800000 || hy == 0x7f800000) \ + && !issignaling (x) && !issignaling (y)) \ + return INFINITY; \ + return x + y; \ + } \ + } while (0) +#endif + + +float +__ieee754_hypotf (float x, float y) +{ + TEST_INF_NAN (x, y); + + return __ieee754_sqrt ((double) x * x + (double) y * y); +} +strong_alias (__ieee754_hypotf, __hypotf_finite) diff --git a/REORG.TODO/sysdeps/powerpc/fpu/e_rem_pio2f.c b/REORG.TODO/sysdeps/powerpc/fpu/e_rem_pio2f.c new file mode 100644 index 0000000000..8563e7c5e4 --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/e_rem_pio2f.c @@ -0,0 +1,188 @@ +/* e_rem_pio2f.c -- float version of e_rem_pio2.c + Copyright (C) 2011-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Adhemerval Zanella <azanella@br.ibm.com>, 2011 + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If + not, see <http://www.gnu.org/licenses/>. */ + +#include <math.h> + +#include <math_private.h> +#include "s_float_bitwise.h" + +/* defined in sysdeps/powerpc/fpu/k_rem_pio2f.c */ +int __fp_kernel_rem_pio2f (float *x, float *y, float e0, int32_t nx); + +/* __ieee754_rem_pio2f(x,y) + * + * return the remainder of x rem pi/2 in y[0]+y[1] + */ + +static const float npio2_hw[] = { + 1.57077026e+00, 3.14154053e+00, 4.71228027e+00, 6.28308105e+00, + 7.85388184e+00, 9.42456055e+00, 1.09953613e+01, 1.25661621e+01, + 1.41369629e+01, 1.57077637e+01, 1.72783203e+01, 1.88491211e+01, + 2.04199219e+01, 2.19907227e+01, 2.35615234e+01, 2.51323242e+01, + 2.67031250e+01, 2.82739258e+01, 2.98447266e+01, 3.14155273e+01, + 3.29863281e+01, 3.45566406e+01, 3.61279297e+01, 3.76982422e+01, + 3.92695312e+01, 4.08398438e+01, 4.24111328e+01, 4.39814453e+01, + 4.55527344e+01, 4.71230469e+01, 4.86943359e+01, 5.02646484e+01 +}; + + +static const float zero = 0.0000000000e+00; +static const float two8 = 2.5600000000e+02; + +static const float half = 5.0000000000e-01; +static const float invpio2 = 6.3661980629e-01; +static const float pio2_1 = 1.5707855225e+00; +static const float pio2_1t = 1.0804334124e-05; +static const float pio2_2 = 1.0804273188e-05; +static const float pio2_2t = 6.0770999344e-11; +static const float pio2_3 = 6.0770943833e-11; +static const float pio2_3t = 6.1232342629e-17; + +static const float pio4 = 7.8539801e-01; +static const float pio3_4 = 2.3561945e+00; +static const float pio2_24b = 1.5707951e+00; +static const float pio2_2e7 = 2.0106054e+02; + + +int32_t +__ieee754_rem_pio2f (float x, float *y) +{ + float ax, z, n, r, w, t, e0; + float tx[3]; + int32_t i, nx; + + ax = __builtin_fabsf (x); + if (ax <= pio4) + { + y[0] = x; + y[1] = 0; + return 0; + } + if (ax < pio3_4) + { + if (x > 0) + { + z = x - pio2_1; + if (!__float_and_test28 (ax, pio2_24b)) + { + y[0] = z - pio2_1t; + y[1] = (z - y[0]) - pio2_1t; + } + else + { + z -= pio2_2; + y[0] = z - pio2_2t; + y[1] = (z - y[0]) - pio2_2t; + } + return 1; + } + else + { + z = x + pio2_1; + if (!__float_and_test28 (ax, pio2_24b)) + { + y[0] = z + pio2_1t; + y[1] = (z - y[0]) + pio2_1t; + } + else + { + z += pio2_2; + y[0] = z + pio2_2t; + y[1] = (z - y[0]) + pio2_2t; + } + return -1; + } + } + if (ax <= pio2_2e7) + { + n = __floorf (ax * invpio2 + half); + i = (int32_t) n; + r = ax - n * pio2_1; + w = n * pio2_1t; /* 1st round good to 40 bit */ + if (i < 32 && !__float_and_test24 (ax, npio2_hw[i - 1])) + { + y[0] = r - w; + } + else + { + float i, j; + j = __float_and8 (ax); + y[0] = r - w; + i = __float_and8 (y[0]); + if (j / i > 256.0 || j / i < 3.9062500e-3) + { /* 2nd iterations needed, good to 57 */ + t = r; + w = n * pio2_2; + r = t - w; + w = n * pio2_2t - ((t - r) - w); + y[0] = r - w; + i = __float_and8 (y[0]); + if (j / i > 33554432 || j / i < 2.9802322e-8) + { /* 3rd iteration needed, 74 bits acc */ + t = r; + w = n * pio2_3; + r = t - w; + w = n * pio2_3t - ((t - r) - w); + y[0] = r - w; + } + } + } + y[1] = (r - y[0]) - w; + if (x < 0) + { + y[0] = -y[0]; + y[1] = -y[1]; + return -i; + } + else + { + return i; + } + } + + /* all other (large) arguments */ + if (isnanf (x) || isinff (x)) + { + y[0] = y[1] = x - x; + return 0; + } + + /* set z = scalbn(|x|,ilogb(x)-7) */ + e0 = __float_and8 (ax / 128.0); + z = ax / e0; + + tx[0] = __floorf (z); + z = (z - tx[0]) * two8; + tx[1] = __floorf (z); + z = (z - tx[1]) * two8; + tx[2] = __floorf (z); + + nx = 3; + while (tx[nx - 1] == zero) + nx--; + + i = __fp_kernel_rem_pio2f (tx, y, e0, nx); + if (x < 0) + { + y[0] = -y[0]; + y[1] = -y[1]; + return -i; + } + return i; +} diff --git a/REORG.TODO/sysdeps/powerpc/fpu/e_sqrt.c b/REORG.TODO/sysdeps/powerpc/fpu/e_sqrt.c new file mode 100644 index 0000000000..1c8977d6ad --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/e_sqrt.c @@ -0,0 +1,175 @@ +/* Double-precision floating point square root. + Copyright (C) 1997-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <math.h> +#include <math_private.h> +#include <fenv_libc.h> +#include <inttypes.h> +#include <stdint.h> +#include <sysdep.h> +#include <ldsodefs.h> + +#ifndef _ARCH_PPCSQ +static const double almost_half = 0.5000000000000001; /* 0.5 + 2^-53 */ +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; +extern const float __t_sqrt[1024]; + +/* The method is based on a description in + Computation of elementary functions on the IBM RISC System/6000 processor, + P. W. Markstein, IBM J. Res. Develop, 34(1) 1990. + Basically, it consists of two interleaved Newton-Raphson approximations, + one to find the actual square root, and one to find its reciprocal + without the expense of a division operation. The tricky bit here + is the use of the POWER/PowerPC multiply-add operation to get the + required accuracy with high speed. + + The argument reduction works by a combination of table lookup to + obtain the initial guesses, and some careful modification of the + generated guesses (which mostly runs on the integer unit, while the + Newton-Raphson is running on the FPU). */ + +double +__slow_ieee754_sqrt (double x) +{ + const float inf = a_inf.value; + + if (x > 0) + { + /* schedule the EXTRACT_WORDS to get separation between the store + and the load. */ + ieee_double_shape_type ew_u; + ieee_double_shape_type iw_u; + ew_u.value = (x); + if (x != inf) + { + /* Variables named starting with 's' exist in the + argument-reduced space, so that 2 > sx >= 0.5, + 1.41... > sg >= 0.70.., 0.70.. >= sy > 0.35... . + Variables named ending with 'i' are integer versions of + floating-point values. */ + double sx; /* The value of which we're trying to find the + square root. */ + double sg, g; /* Guess of the square root of x. */ + double sd, d; /* Difference between the square of the guess and x. */ + double sy; /* Estimate of 1/2g (overestimated by 1ulp). */ + double sy2; /* 2*sy */ + double e; /* Difference between y*g and 1/2 (se = e * fsy). */ + double shx; /* == sx * fsg */ + double fsg; /* sg*fsg == g. */ + fenv_t fe; /* Saved floating-point environment (stores rounding + mode and whether the inexact exception is + enabled). */ + uint32_t xi0, xi1, sxi, fsgi; + const float *t_sqrt; + + fe = fegetenv_register (); + /* complete the EXTRACT_WORDS (xi0,xi1,x) operation. */ + xi0 = ew_u.parts.msw; + xi1 = ew_u.parts.lsw; + relax_fenv_state (); + sxi = (xi0 & 0x3fffffff) | 0x3fe00000; + /* schedule the INSERT_WORDS (sx, sxi, xi1) to get separation + between the store and the load. */ + iw_u.parts.msw = sxi; + iw_u.parts.lsw = xi1; + t_sqrt = __t_sqrt + (xi0 >> (52 - 32 - 8 - 1) & 0x3fe); + sg = t_sqrt[0]; + sy = t_sqrt[1]; + /* complete the INSERT_WORDS (sx, sxi, xi1) operation. */ + sx = iw_u.value; + + /* Here we have three Newton-Raphson iterations each of a + division and a square root and the remainder of the + argument reduction, all interleaved. */ + sd = -__builtin_fma (sg, sg, -sx); + fsgi = (xi0 + 0x40000000) >> 1 & 0x7ff00000; + sy2 = sy + sy; + sg = __builtin_fma (sy, sd, sg); /* 16-bit approximation to + sqrt(sx). */ + + /* schedule the INSERT_WORDS (fsg, fsgi, 0) to get separation + between the store and the load. */ + INSERT_WORDS (fsg, fsgi, 0); + iw_u.parts.msw = fsgi; + iw_u.parts.lsw = (0); + e = -__builtin_fma (sy, sg, -almost_half); + sd = -__builtin_fma (sg, sg, -sx); + if ((xi0 & 0x7ff00000) == 0) + goto denorm; + sy = __builtin_fma (e, sy2, sy); + sg = __builtin_fma (sy, sd, sg); /* 32-bit approximation to + sqrt(sx). */ + sy2 = sy + sy; + /* complete the INSERT_WORDS (fsg, fsgi, 0) operation. */ + fsg = iw_u.value; + e = -__builtin_fma (sy, sg, -almost_half); + sd = -__builtin_fma (sg, sg, -sx); + sy = __builtin_fma (e, sy2, sy); + shx = sx * fsg; + sg = __builtin_fma (sy, sd, sg); /* 64-bit approximation to + sqrt(sx), but perhaps + rounded incorrectly. */ + sy2 = sy + sy; + g = sg * fsg; + e = -__builtin_fma (sy, sg, -almost_half); + d = -__builtin_fma (g, sg, -shx); + sy = __builtin_fma (e, sy2, sy); + fesetenv_register (fe); + return __builtin_fma (sy, d, g); + denorm: + /* For denormalised numbers, we normalise, calculate the + square root, and return an adjusted result. */ + fesetenv_register (fe); + return __slow_ieee754_sqrt (x * two108) * twom54; + } + } + else if (x < 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 & FE_INVALID) == 0) +#endif + __feraiseexcept (FE_INVALID); + x = a_nan.value; + } + return f_wash (x); +} +#endif /* _ARCH_PPCSQ */ + +#undef __ieee754_sqrt +double +__ieee754_sqrt (double x) +{ + double z; + +#ifdef _ARCH_PPCSQ + asm ("fsqrt %0,%1\n" :"=f" (z):"f" (x)); +#else + z = __slow_ieee754_sqrt (x); +#endif + + return z; +} +strong_alias (__ieee754_sqrt, __sqrt_finite) diff --git a/REORG.TODO/sysdeps/powerpc/fpu/e_sqrtf.c b/REORG.TODO/sysdeps/powerpc/fpu/e_sqrtf.c new file mode 100644 index 0000000000..65d27b4d42 --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/e_sqrtf.c @@ -0,0 +1,150 @@ +/* Single-precision floating point square root. + Copyright (C) 1997-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <math.h> +#include <math_private.h> +#include <fenv_libc.h> +#include <inttypes.h> +#include <stdint.h> +#include <sysdep.h> +#include <ldsodefs.h> + +#ifndef _ARCH_PPCSQ +static const float almost_half = 0.50000006; /* 0.5 + 2^-24 */ +static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; +static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; +static const float two48 = 281474976710656.0; +static const float twom24 = 5.9604644775390625e-8; +extern const float __t_sqrt[1024]; + +/* The method is based on a description in + Computation of elementary functions on the IBM RISC System/6000 processor, + P. W. Markstein, IBM J. Res. Develop, 34(1) 1990. + Basically, it consists of two interleaved Newton-Raphson approximations, + one to find the actual square root, and one to find its reciprocal + without the expense of a division operation. The tricky bit here + is the use of the POWER/PowerPC multiply-add operation to get the + required accuracy with high speed. + + The argument reduction works by a combination of table lookup to + obtain the initial guesses, and some careful modification of the + generated guesses (which mostly runs on the integer unit, while the + Newton-Raphson is running on the FPU). */ + +float +__slow_ieee754_sqrtf (float x) +{ + const float inf = a_inf.value; + + if (x > 0) + { + if (x != inf) + { + /* Variables named starting with 's' exist in the + argument-reduced space, so that 2 > sx >= 0.5, + 1.41... > sg >= 0.70.., 0.70.. >= sy > 0.35... . + Variables named ending with 'i' are integer versions of + floating-point values. */ + float sx; /* The value of which we're trying to find the square + root. */ + float sg, g; /* Guess of the square root of x. */ + float sd, d; /* Difference between the square of the guess and x. */ + float sy; /* Estimate of 1/2g (overestimated by 1ulp). */ + float sy2; /* 2*sy */ + float e; /* Difference between y*g and 1/2 (note that e==se). */ + float shx; /* == sx * fsg */ + float fsg; /* sg*fsg == g. */ + fenv_t fe; /* Saved floating-point environment (stores rounding + mode and whether the inexact exception is + enabled). */ + uint32_t xi, sxi, fsgi; + const float *t_sqrt; + + GET_FLOAT_WORD (xi, x); + fe = fegetenv_register (); + relax_fenv_state (); + sxi = (xi & 0x3fffffff) | 0x3f000000; + SET_FLOAT_WORD (sx, sxi); + t_sqrt = __t_sqrt + (xi >> (23 - 8 - 1) & 0x3fe); + sg = t_sqrt[0]; + sy = t_sqrt[1]; + + /* Here we have three Newton-Raphson iterations each of a + division and a square root and the remainder of the + argument reduction, all interleaved. */ + sd = -__builtin_fmaf (sg, sg, -sx); + fsgi = (xi + 0x40000000) >> 1 & 0x7f800000; + sy2 = sy + sy; + sg = __builtin_fmaf (sy, sd, sg); /* 16-bit approximation to + sqrt(sx). */ + e = -__builtin_fmaf (sy, sg, -almost_half); + SET_FLOAT_WORD (fsg, fsgi); + sd = -__builtin_fmaf (sg, sg, -sx); + sy = __builtin_fmaf (e, sy2, sy); + if ((xi & 0x7f800000) == 0) + goto denorm; + shx = sx * fsg; + sg = __builtin_fmaf (sy, sd, sg); /* 32-bit approximation to + sqrt(sx), but perhaps + rounded incorrectly. */ + sy2 = sy + sy; + g = sg * fsg; + e = -__builtin_fmaf (sy, sg, -almost_half); + d = -__builtin_fmaf (g, sg, -shx); + sy = __builtin_fmaf (e, sy2, sy); + fesetenv_register (fe); + return __builtin_fmaf (sy, d, g); + denorm: + /* For denormalised numbers, we normalise, calculate the + square root, and return an adjusted result. */ + fesetenv_register (fe); + return __slow_ieee754_sqrtf (x * two48) * twom24; + } + } + else if (x < 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 & FE_INVALID) == 0) +#endif + feraiseexcept (FE_INVALID); + x = a_nan.value; + } + return f_washf (x); +} +#endif /* _ARCH_PPCSQ */ + +#undef __ieee754_sqrtf +float +__ieee754_sqrtf (float x) +{ + double z; + +#ifdef _ARCH_PPCSQ + asm ("fsqrts %0,%1\n" :"=f" (z):"f" (x)); +#else + z = __slow_ieee754_sqrtf (x); +#endif + + return z; +} +strong_alias (__ieee754_sqrtf, __sqrtf_finite) diff --git a/REORG.TODO/sysdeps/powerpc/fpu/fclrexcpt.c b/REORG.TODO/sysdeps/powerpc/fpu/fclrexcpt.c new file mode 100644 index 0000000000..2ee9547833 --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/fclrexcpt.c @@ -0,0 +1,49 @@ +/* Clear given exceptions in current floating-point environment. + Copyright (C) 1997-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <fenv_libc.h> + +#undef feclearexcept +int +__feclearexcept (int excepts) +{ + fenv_union_t u, n; + + /* Get the current state. */ + u.fenv = fegetenv_register (); + + /* Clear the relevant bits. */ + n.l = u.l & ~((-(excepts >> (31 - FPSCR_VX) & 1) & FE_ALL_INVALID) + | (excepts & FPSCR_STICKY_BITS)); + + /* Put the new state in effect. */ + if (u.l != n.l) + fesetenv_register (n.fenv); + + /* Success. */ + return 0; +} + +#include <shlib-compat.h> +#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2) +strong_alias (__feclearexcept, __old_feclearexcept) +compat_symbol (libm, __old_feclearexcept, feclearexcept, GLIBC_2_1); +#endif + +libm_hidden_ver (__feclearexcept, feclearexcept) +versioned_symbol (libm, __feclearexcept, feclearexcept, GLIBC_2_2); diff --git a/REORG.TODO/sysdeps/powerpc/fpu/fe_mask.c b/REORG.TODO/sysdeps/powerpc/fpu/fe_mask.c new file mode 100644 index 0000000000..bbe41a9d92 --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/fe_mask.c @@ -0,0 +1,32 @@ +/* Procedure definition for FE_MASK_ENV. + Copyright (C) 2007-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <fenv.h> +#include <errno.h> + +/* This is a generic stub. An OS specific override is required to clear + the FE0/FE1 bits in the MSR. MSR update is privileged, so this will + normally involve a syscall. */ + +const fenv_t * +__fe_mask_env(void) +{ + __set_errno (ENOSYS); + return FE_DFL_ENV; +} +stub_warning (__fe_mask_env) diff --git a/REORG.TODO/sysdeps/powerpc/fpu/fe_nomask.c b/REORG.TODO/sysdeps/powerpc/fpu/fe_nomask.c new file mode 100644 index 0000000000..3b42aedd15 --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/fe_nomask.c @@ -0,0 +1,32 @@ +/* Procedure definition for FE_NOMASK_ENV. + Copyright (C) 1997-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <fenv_libc.h> +#include <errno.h> + +/* This is a generic stub. An OS specific override is required to set + the FE0/FE1 bits in the MSR. MSR update is privileged, so this will + normally involve a syscall. */ + +const fenv_t * +__fe_nomask_env_priv (void) +{ + __set_errno (ENOSYS); + return FE_ENABLED_ENV; +} +stub_warning (__fe_nomask_env_priv) diff --git a/REORG.TODO/sysdeps/powerpc/fpu/fedisblxcpt.c b/REORG.TODO/sysdeps/powerpc/fpu/fedisblxcpt.c new file mode 100644 index 0000000000..bb10b4701a --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/fedisblxcpt.c @@ -0,0 +1,57 @@ +/* Disable floating-point exceptions. + Copyright (C) 2000-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Geoffrey Keating <geoffk@geoffk.org>, 2000. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <fenv_libc.h> + +int +fedisableexcept (int excepts) +{ + fenv_union_t fe, curr; + int result, new; + + /* Get current exception mask to return. */ + fe.fenv = curr.fenv = fegetenv_register (); + result = fenv_reg_to_exceptions (fe.l); + + if ((excepts & FE_ALL_INVALID) == FE_ALL_INVALID) + excepts = (excepts | FE_INVALID) & ~ FE_ALL_INVALID; + + /* Sets the new exception mask. */ + if (excepts & FE_INEXACT) + fe.l &= ~(1 << (31 - FPSCR_XE)); + if (excepts & FE_DIVBYZERO) + fe.l &= ~(1 << (31 - FPSCR_ZE)); + if (excepts & FE_UNDERFLOW) + fe.l &= ~(1 << (31 - FPSCR_UE)); + if (excepts & FE_OVERFLOW) + fe.l &= ~(1 << (31 - FPSCR_OE)); + if (excepts & FE_INVALID) + fe.l &= ~(1 << (31 - FPSCR_VE)); + + if (fe.l != curr.l) + fesetenv_register (fe.fenv); + + new = __fegetexcept (); + if (new == 0 && result != 0) + (void)__fe_mask_env (); + + if ((new & excepts) != 0) + result = -1; + return result; +} diff --git a/REORG.TODO/sysdeps/powerpc/fpu/feenablxcpt.c b/REORG.TODO/sysdeps/powerpc/fpu/feenablxcpt.c new file mode 100644 index 0000000000..7f0b333fc6 --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/feenablxcpt.c @@ -0,0 +1,58 @@ +/* Enable floating-point exceptions. + Copyright (C) 2000-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Geoffrey Keating <geoffk@geoffk.org>, 2000. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <fenv_libc.h> + +int +feenableexcept (int excepts) +{ + fenv_union_t fe, curr; + int result, new; + + /* Get current exception mask to return. */ + fe.fenv = curr.fenv = fegetenv_register (); + result = fenv_reg_to_exceptions (fe.l); + + if ((excepts & FE_ALL_INVALID) == FE_ALL_INVALID) + excepts = (excepts | FE_INVALID) & ~ FE_ALL_INVALID; + + /* Sets the new exception mask. */ + if (excepts & FE_INEXACT) + fe.l |= (1 << (31 - FPSCR_XE)); + if (excepts & FE_DIVBYZERO) + fe.l |= (1 << (31 - FPSCR_ZE)); + if (excepts & FE_UNDERFLOW) + fe.l |= (1 << (31 - FPSCR_UE)); + if (excepts & FE_OVERFLOW) + fe.l |= (1 << (31 - FPSCR_OE)); + if (excepts & FE_INVALID) + fe.l |= (1 << (31 - FPSCR_VE)); + + if (fe.l != curr.l) + fesetenv_register (fe.fenv); + + new = __fegetexcept (); + if (new != 0 && result == 0) + (void) __fe_nomask_env_priv (); + + if ((new & excepts) != excepts) + result = -1; + + return result; +} diff --git a/REORG.TODO/sysdeps/powerpc/fpu/fegetenv.c b/REORG.TODO/sysdeps/powerpc/fpu/fegetenv.c new file mode 100644 index 0000000000..251977beba --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/fegetenv.c @@ -0,0 +1,38 @@ +/* Store current floating-point environment. + Copyright (C) 1997-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <fenv_libc.h> + +int +__fegetenv (fenv_t *envp) +{ + *envp = fegetenv_register (); + + /* Success. */ + return 0; +} + +#include <shlib-compat.h> +#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2) +strong_alias (__fegetenv, __old_fegetenv) +compat_symbol (libm, __old_fegetenv, fegetenv, GLIBC_2_1); +#endif + +libm_hidden_def (__fegetenv) +libm_hidden_ver (__fegetenv, fegetenv) +versioned_symbol (libm, __fegetenv, fegetenv, GLIBC_2_2); diff --git a/REORG.TODO/sysdeps/powerpc/fpu/fegetexcept.c b/REORG.TODO/sysdeps/powerpc/fpu/fegetexcept.c new file mode 100644 index 0000000000..2b9899abe2 --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/fegetexcept.c @@ -0,0 +1,43 @@ +/* Get floating-point exceptions. + Copyright (C) 2000-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Geoffrey Keating <geoffk@geoffk.org>, 2000. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <fenv_libc.h> + +int +__fegetexcept (void) +{ + fenv_union_t fe; + int result = 0; + + fe.fenv = fegetenv_register (); + + if (fe.l & (1 << (31 - FPSCR_XE))) + result |= FE_INEXACT; + if (fe.l & (1 << (31 - FPSCR_ZE))) + result |= FE_DIVBYZERO; + if (fe.l & (1 << (31 - FPSCR_UE))) + result |= FE_UNDERFLOW; + if (fe.l & (1 << (31 - FPSCR_OE))) + result |= FE_OVERFLOW; + if (fe.l & (1 << (31 - FPSCR_VE))) + result |= FE_INVALID; + + return result; +} +weak_alias (__fegetexcept, fegetexcept) diff --git a/REORG.TODO/sysdeps/powerpc/fpu/fegetmode.c b/REORG.TODO/sysdeps/powerpc/fpu/fegetmode.c new file mode 100644 index 0000000000..5597000a4b --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/fegetmode.c @@ -0,0 +1,26 @@ +/* Store current floating-point control modes. PowerPC version. + Copyright (C) 2016-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <fenv_libc.h> + +int +fegetmode (femode_t *modep) +{ + *modep = fegetenv_register (); + return 0; +} diff --git a/REORG.TODO/sysdeps/powerpc/fpu/fegetround.c b/REORG.TODO/sysdeps/powerpc/fpu/fegetround.c new file mode 100644 index 0000000000..bedb02f0e5 --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/fegetround.c @@ -0,0 +1,30 @@ +/* Return current rounding direction. + Copyright (C) 1997-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <fenv_libc.h> + +int +(__fegetround) (void) +{ + return __fegetround(); +} +#undef fegetround +#undef __fegetround +libm_hidden_def (__fegetround) +weak_alias (__fegetround, fegetround) +libm_hidden_weak (fegetround) diff --git a/REORG.TODO/sysdeps/powerpc/fpu/feholdexcpt.c b/REORG.TODO/sysdeps/powerpc/fpu/feholdexcpt.c new file mode 100644 index 0000000000..fef49c33a9 --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/feholdexcpt.c @@ -0,0 +1,51 @@ +/* Store current floating-point environment and clear exceptions. + Copyright (C) 1997-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <fenv_libc.h> +#include <fpu_control.h> +#define _FPU_MASK_ALL (_FPU_MASK_ZM | _FPU_MASK_OM | _FPU_MASK_UM | _FPU_MASK_XM | _FPU_MASK_IM) + +int +__feholdexcept (fenv_t *envp) +{ + fenv_union_t old, new; + + /* Save the currently set exceptions. */ + old.fenv = *envp = fegetenv_register (); + + /* Clear everything except for the rounding modes and non-IEEE arithmetic + flag. */ + new.l = old.l & 0xffffffff00000007LL; + + if (new.l == old.l) + return 0; + + /* If the old env had any enabled exceptions, then mask SIGFPE in the + MSR FE0/FE1 bits. This may allow the FPU to run faster because it + always takes the default action and can not generate SIGFPE. */ + if ((old.l & _FPU_MASK_ALL) != 0) + (void)__fe_mask_env (); + + /* Put the new state in effect. */ + fesetenv_register (new.fenv); + + return 0; +} +libm_hidden_def (__feholdexcept) +weak_alias (__feholdexcept, feholdexcept) +libm_hidden_weak (feholdexcept) diff --git a/REORG.TODO/sysdeps/powerpc/fpu/fenv_const.c b/REORG.TODO/sysdeps/powerpc/fpu/fenv_const.c new file mode 100644 index 0000000000..c5e088c98e --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/fenv_const.c @@ -0,0 +1,36 @@ +/* Constants for fenv_bits.h. + Copyright (C) 1997-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +/* We want to specify the bit pattern of the __fe_*_env constants, so + pretend they're really `long long' instead of `double'. */ + +/* If the default argument is used we use this value. */ +const unsigned long long __fe_dfl_env __attribute__ ((aligned (8))) = +0xfff8000000000000ULL; + +/* The same representation is used for femode_t. */ +extern const unsigned long long __fe_dfl_mode + __attribute__ ((aligned (8), alias ("__fe_dfl_env"))); + +/* Floating-point environment where none of the exceptions are masked. */ +const unsigned long long __fe_enabled_env __attribute__ ((aligned (8))) = +0xfff80000000000f8ULL; + +/* Floating-point environment with the NI bit set. */ +const unsigned long long __fe_nonieee_env __attribute__ ((aligned (8))) = +0xfff8000000000004ULL; diff --git a/REORG.TODO/sysdeps/powerpc/fpu/fenv_libc.h b/REORG.TODO/sysdeps/powerpc/fpu/fenv_libc.h new file mode 100644 index 0000000000..500ac042b4 --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/fenv_libc.h @@ -0,0 +1,176 @@ +/* Internal libc stuff for floating point environment routines. + Copyright (C) 1997-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _FENV_LIBC_H +#define _FENV_LIBC_H 1 + +#include <fenv.h> +#include <ldsodefs.h> +#include <sysdep.h> + +extern const fenv_t *__fe_nomask_env_priv (void); + +extern const fenv_t *__fe_mask_env (void) attribute_hidden; + +/* The sticky bits in the FPSCR indicating exceptions have occurred. */ +#define FPSCR_STICKY_BITS ((FE_ALL_EXCEPT | FE_ALL_INVALID) & ~FE_INVALID) + +/* Equivalent to fegetenv, but returns a fenv_t instead of taking a + pointer. */ +#define fegetenv_register() \ + ({ fenv_t env; asm volatile ("mffs %0" : "=f" (env)); env; }) + +/* Equivalent to fesetenv, but takes a fenv_t instead of a pointer. */ +#define fesetenv_register(env) \ + do { \ + double d = (env); \ + if(GLRO(dl_hwcap) & PPC_FEATURE_HAS_DFP) \ + asm volatile (".machine push; " \ + ".machine \"power6\"; " \ + "mtfsf 0xff,%0,1,0; " \ + ".machine pop" : : "f" (d)); \ + else \ + asm volatile ("mtfsf 0xff,%0" : : "f" (d)); \ + } while(0) + +/* This very handy macro: + - Sets the rounding mode to 'round to nearest'; + - Sets the processor into IEEE mode; and + - Prevents exceptions from being raised for inexact results. + These things happen to be exactly what you need for typical elementary + functions. */ +#define relax_fenv_state() \ + do { \ + if (GLRO(dl_hwcap) & PPC_FEATURE_HAS_DFP) \ + asm (".machine push; .machine \"power6\"; " \ + "mtfsfi 7,0,1; .machine pop"); \ + asm ("mtfsfi 7,0"); \ + } while(0) + +/* Set/clear a particular FPSCR bit (for instance, + reset_fpscr_bit(FPSCR_VE); + prevents INVALID exceptions from being raised). */ +#define set_fpscr_bit(x) asm volatile ("mtfsb1 %0" : : "i"(x)) +#define reset_fpscr_bit(x) asm volatile ("mtfsb0 %0" : : "i"(x)) + +typedef union +{ + fenv_t fenv; + unsigned long long l; +} fenv_union_t; + + +static inline int +__fesetround_inline (int round) +{ + if ((unsigned int) round < 2) + { + asm volatile ("mtfsb0 30"); + if ((unsigned int) round == 0) + asm volatile ("mtfsb0 31"); + else + asm volatile ("mtfsb1 31"); + } + else + { + asm volatile ("mtfsb1 30"); + if ((unsigned int) round == 2) + asm volatile ("mtfsb0 31"); + else + asm volatile ("mtfsb1 31"); + } + + return 0; +} + +/* Definitions of all the FPSCR bit numbers */ +enum { + FPSCR_FX = 0, /* exception summary */ + FPSCR_FEX, /* enabled exception summary */ + FPSCR_VX, /* invalid operation summary */ + FPSCR_OX, /* overflow */ + FPSCR_UX, /* underflow */ + FPSCR_ZX, /* zero divide */ + FPSCR_XX, /* inexact */ + FPSCR_VXSNAN, /* invalid operation for sNaN */ + FPSCR_VXISI, /* invalid operation for Inf-Inf */ + FPSCR_VXIDI, /* invalid operation for Inf/Inf */ + FPSCR_VXZDZ, /* invalid operation for 0/0 */ + FPSCR_VXIMZ, /* invalid operation for Inf*0 */ + FPSCR_VXVC, /* invalid operation for invalid compare */ + FPSCR_FR, /* fraction rounded [fraction was incremented by round] */ + FPSCR_FI, /* fraction inexact */ + FPSCR_FPRF_C, /* result class descriptor */ + FPSCR_FPRF_FL, /* result less than (usually, less than 0) */ + FPSCR_FPRF_FG, /* result greater than */ + FPSCR_FPRF_FE, /* result equal to */ + FPSCR_FPRF_FU, /* result unordered */ + FPSCR_20, /* reserved */ + FPSCR_VXSOFT, /* invalid operation set by software */ + FPSCR_VXSQRT, /* invalid operation for square root */ + FPSCR_VXCVI, /* invalid operation for invalid integer convert */ + FPSCR_VE, /* invalid operation exception enable */ + FPSCR_OE, /* overflow exception enable */ + FPSCR_UE, /* underflow exception enable */ + FPSCR_ZE, /* zero divide exception enable */ + FPSCR_XE, /* inexact exception enable */ +#ifdef _ARCH_PWR6 + FPSCR_29, /* Reserved in ISA 2.05 */ +#else + FPSCR_NI /* non-IEEE mode (typically, no denormalised numbers) */ +#endif /* _ARCH_PWR6 */ + /* the remaining two least-significant bits keep the rounding mode */ +}; + +static inline int +fenv_reg_to_exceptions (unsigned long long l) +{ + int result = 0; + if (l & (1 << (31 - FPSCR_XE))) + result |= FE_INEXACT; + if (l & (1 << (31 - FPSCR_ZE))) + result |= FE_DIVBYZERO; + if (l & (1 << (31 - FPSCR_UE))) + result |= FE_UNDERFLOW; + if (l & (1 << (31 - FPSCR_OE))) + result |= FE_OVERFLOW; + if (l & (1 << (31 - FPSCR_VE))) + result |= FE_INVALID; + return result; +} + +#ifdef _ARCH_PWR6 + /* Not supported in ISA 2.05. Provided for source compat only. */ +# define FPSCR_NI 29 +#endif /* _ARCH_PWR6 */ + +/* This operation (i) sets the appropriate FPSCR bits for its + parameter, (ii) converts sNaN to the corresponding qNaN, and (iii) + otherwise passes its parameter through unchanged (in particular, -0 + and +0 stay as they were). The `obvious' way to do this is optimised + out by gcc. */ +#define f_wash(x) \ + ({ double d; asm volatile ("fmul %0,%1,%2" \ + : "=f"(d) \ + : "f" (x), "f"((float)1.0)); d; }) +#define f_washf(x) \ + ({ float f; asm volatile ("fmuls %0,%1,%2" \ + : "=f"(f) \ + : "f" (x), "f"((float)1.0)); f; }) + +#endif /* fenv_libc.h */ diff --git a/REORG.TODO/sysdeps/powerpc/fpu/fenv_private.h b/REORG.TODO/sysdeps/powerpc/fpu/fenv_private.h new file mode 100644 index 0000000000..877f25bcf2 --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/fenv_private.h @@ -0,0 +1,229 @@ +/* Private floating point rounding and exceptions handling. PowerPC version. + Copyright (C) 2013-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef FENV_PRIVATE_H +#define FENV_PRIVATE_H 1 + +#include <fenv.h> +#include <fenv_libc.h> +#include <fpu_control.h> + +/* Mask for the exception enable bits. */ +#define _FPU_ALL_TRAPS (_FPU_MASK_ZM | _FPU_MASK_OM | _FPU_MASK_UM \ + | _FPU_MASK_XM | _FPU_MASK_IM) + +/* Mask the rounding mode bits. */ +#define _FPU_MASK_RN (~0x3) + +/* Mask everything but the rounding moded and non-IEEE arithmetic flags. */ +#define _FPU_MASK_NOT_RN_NI 0xffffffff00000007LL + +/* Mask restore rounding mode and exception enabled. */ +#define _FPU_MASK_TRAPS_RN 0xffffffff1fffff00LL + +/* Mask exception enable but fraction rounded/inexact and FP result/CC + bits. */ +#define _FPU_MASK_FRAC_INEX_RET_CC 0xffffffff1ff80fff + +static __always_inline void +__libc_feholdbits_ppc (fenv_t *envp, unsigned long long mask, + unsigned long long bits) +{ + fenv_union_t old, new; + + old.fenv = *envp = fegetenv_register (); + + new.l = (old.l & mask) | bits; + + /* If the old env had any enabled exceptions, then mask SIGFPE in the + MSR FE0/FE1 bits. This may allow the FPU to run faster because it + always takes the default action and can not generate SIGFPE. */ + if ((old.l & _FPU_ALL_TRAPS) != 0) + (void) __fe_mask_env (); + + fesetenv_register (new.fenv); +} + +static __always_inline void +libc_feholdexcept_ppc (fenv_t *envp) +{ + __libc_feholdbits_ppc (envp, _FPU_MASK_NOT_RN_NI, 0LL); +} + +static __always_inline void +libc_feholdexcept_setround_ppc (fenv_t *envp, int r) +{ + __libc_feholdbits_ppc (envp, _FPU_MASK_NOT_RN_NI & _FPU_MASK_RN, r); +} + +static __always_inline void +libc_fesetround_ppc (int r) +{ + __fesetround_inline (r); +} + +static __always_inline int +libc_fetestexcept_ppc (int e) +{ + fenv_union_t u; + u.fenv = fegetenv_register (); + return u.l & e; +} + +static __always_inline void +libc_feholdsetround_ppc (fenv_t *e, int r) +{ + __libc_feholdbits_ppc (e, _FPU_MASK_TRAPS_RN, r); +} + +static __always_inline unsigned long long +__libc_femergeenv_ppc (const fenv_t *envp, unsigned long long old_mask, + unsigned long long new_mask) +{ + fenv_union_t old, new; + + new.fenv = *envp; + old.fenv = fegetenv_register (); + + /* Merge bits while masking unwanted bits from new and old env. */ + new.l = (old.l & old_mask) | (new.l & new_mask); + + /* If the old env has no enabled exceptions and the new env has any enabled + exceptions, then unmask SIGFPE in the MSR FE0/FE1 bits. This will put the + hardware into "precise mode" and may cause the FPU to run slower on some + hardware. */ + if ((old.l & _FPU_ALL_TRAPS) == 0 && (new.l & _FPU_ALL_TRAPS) != 0) + (void) __fe_nomask_env_priv (); + + /* If the old env had any enabled exceptions and the new env has no enabled + exceptions, then mask SIGFPE in the MSR FE0/FE1 bits. This may allow the + FPU to run faster because it always takes the default action and can not + generate SIGFPE. */ + if ((old.l & _FPU_ALL_TRAPS) != 0 && (new.l & _FPU_ALL_TRAPS) == 0) + (void) __fe_mask_env (); + + /* Atomically enable and raise (if appropriate) exceptions set in `new'. */ + fesetenv_register (new.fenv); + + return old.l; +} + +static __always_inline void +libc_fesetenv_ppc (const fenv_t *envp) +{ + /* Replace the entire environment. */ + __libc_femergeenv_ppc (envp, 0LL, -1LL); +} + +static __always_inline void +libc_feresetround_ppc (fenv_t *envp) +{ + __libc_femergeenv_ppc (envp, _FPU_MASK_TRAPS_RN, _FPU_MASK_FRAC_INEX_RET_CC); +} + +static __always_inline int +libc_feupdateenv_test_ppc (fenv_t *envp, int ex) +{ + return __libc_femergeenv_ppc (envp, _FPU_MASK_TRAPS_RN, + _FPU_MASK_FRAC_INEX_RET_CC) & ex; +} + +static __always_inline void +libc_feupdateenv_ppc (fenv_t *e) +{ + libc_feupdateenv_test_ppc (e, 0); +} + +#define libc_feholdexceptf libc_feholdexcept_ppc +#define libc_feholdexcept libc_feholdexcept_ppc +#define libc_feholdexcept_setroundf libc_feholdexcept_setround_ppc +#define libc_feholdexcept_setround libc_feholdexcept_setround_ppc +#define libc_fetestexceptf libc_fetestexcept_ppc +#define libc_fetestexcept libc_fetestexcept_ppc +#define libc_fesetroundf libc_fesetround_ppc +#define libc_fesetround libc_fesetround_ppc +#define libc_fesetenvf libc_fesetenv_ppc +#define libc_fesetenv libc_fesetenv_ppc +#define libc_feupdateenv_testf libc_feupdateenv_test_ppc +#define libc_feupdateenv_test libc_feupdateenv_test_ppc +#define libc_feupdateenvf libc_feupdateenv_ppc +#define libc_feupdateenv libc_feupdateenv_ppc +#define libc_feholdsetroundf libc_feholdsetround_ppc +#define libc_feholdsetround libc_feholdsetround_ppc +#define libc_feresetroundf libc_feresetround_ppc +#define libc_feresetround libc_feresetround_ppc + + +/* We have support for rounding mode context. */ +#define HAVE_RM_CTX 1 + +static __always_inline void +libc_feholdsetround_ppc_ctx (struct rm_ctx *ctx, int r) +{ + fenv_union_t old, new; + + old.fenv = fegetenv_register (); + + new.l = (old.l & _FPU_MASK_TRAPS_RN) | r; + + ctx->env = old.fenv; + if (__glibc_unlikely (new.l != old.l)) + { + if ((old.l & _FPU_ALL_TRAPS) != 0) + (void) __fe_mask_env (); + fesetenv_register (new.fenv); + ctx->updated_status = true; + } + else + ctx->updated_status = false; +} + +static __always_inline void +libc_fesetenv_ppc_ctx (struct rm_ctx *ctx) +{ + libc_fesetenv_ppc (&ctx->env); +} + +static __always_inline void +libc_feupdateenv_ppc_ctx (struct rm_ctx *ctx) +{ + if (__glibc_unlikely (ctx->updated_status)) + libc_feresetround_ppc (&ctx->env); +} + +static __always_inline void +libc_feresetround_ppc_ctx (struct rm_ctx *ctx) +{ + if (__glibc_unlikely (ctx->updated_status)) + libc_feresetround_ppc (&ctx->env); +} + +#define libc_fesetenv_ctx libc_fesetenv_ppc_ctx +#define libc_fesetenvf_ctx libc_fesetenv_ppc_ctx +#define libc_fesetenvl_ctx libc_fesetenv_ppc_ctx +#define libc_feholdsetround_ctx libc_feholdsetround_ppc_ctx +#define libc_feholdsetroundf_ctx libc_feholdsetround_ppc_ctx +#define libc_feholdsetroundl_ctx libc_feholdsetround_ppc_ctx +#define libc_feresetround_ctx libc_feresetround_ppc_ctx +#define libc_feresetroundf_ctx libc_feresetround_ppc_ctx +#define libc_feresetroundl_ctx libc_feresetround_ppc_ctx +#define libc_feupdateenv_ctx libc_feupdateenv_ppc_ctx +#define libc_feupdateenvf_ctx libc_feupdateenv_ppc_ctx +#define libc_feupdateenvl_ctx libc_feupdateenv_ppc_ctx + +#endif diff --git a/REORG.TODO/sysdeps/powerpc/fpu/fesetenv.c b/REORG.TODO/sysdeps/powerpc/fpu/fesetenv.c new file mode 100644 index 0000000000..7208ab455a --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/fesetenv.c @@ -0,0 +1,63 @@ +/* Install given floating-point environment. + Copyright (C) 1997-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <fenv_libc.h> +#include <fpu_control.h> + +#define _FPU_MASK_ALL (_FPU_MASK_ZM | _FPU_MASK_OM | _FPU_MASK_UM | _FPU_MASK_XM | _FPU_MASK_IM) + +int +__fesetenv (const fenv_t *envp) +{ + fenv_union_t old, new; + + /* get the currently set exceptions. */ + new.fenv = *envp; + old.fenv = fegetenv_register (); + if (old.l == new.l) + return 0; + + /* If the old env has no enabled exceptions and the new env has any enabled + exceptions, then unmask SIGFPE in the MSR FE0/FE1 bits. This will put the + hardware into "precise mode" and may cause the FPU to run slower on some + hardware. */ + if ((old.l & _FPU_MASK_ALL) == 0 && (new.l & _FPU_MASK_ALL) != 0) + (void) __fe_nomask_env_priv (); + + /* If the old env had any enabled exceptions and the new env has no enabled + exceptions, then mask SIGFPE in the MSR FE0/FE1 bits. This may allow the + FPU to run faster because it always takes the default action and can not + generate SIGFPE. */ + if ((old.l & _FPU_MASK_ALL) != 0 && (new.l & _FPU_MASK_ALL) == 0) + (void)__fe_mask_env (); + + fesetenv_register (*envp); + + /* Success. */ + return 0; +} + +#include <shlib-compat.h> +#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2) +strong_alias (__fesetenv, __old_fesetenv) +compat_symbol (libm, __old_fesetenv, fesetenv, GLIBC_2_1); +#endif + +libm_hidden_def (__fesetenv) +libm_hidden_ver (__fesetenv, fesetenv) +versioned_symbol (libm, __fesetenv, fesetenv, GLIBC_2_2); diff --git a/REORG.TODO/sysdeps/powerpc/fpu/fesetexcept.c b/REORG.TODO/sysdeps/powerpc/fpu/fesetexcept.c new file mode 100644 index 0000000000..47ea8e499d --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/fesetexcept.c @@ -0,0 +1,42 @@ +/* Set given exception flags. PowerPC version. + Copyright (C) 2016-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <fenv_libc.h> + +int +fesetexcept (int excepts) +{ + fenv_union_t u, n; + + u.fenv = fegetenv_register (); + n.l = (u.l + | (excepts & FPSCR_STICKY_BITS) + /* Turn FE_INVALID into FE_INVALID_SOFTWARE. */ + | (excepts >> ((31 - FPSCR_VX) - (31 - FPSCR_VXSOFT)) + & FE_INVALID_SOFTWARE)); + if (n.l != u.l) + { + fesetenv_register (n.fenv); + + /* Deal with FE_INVALID_SOFTWARE not being implemented on some chips. */ + if (excepts & FE_INVALID) + feraiseexcept (FE_INVALID); + } + + return 0; +} diff --git a/REORG.TODO/sysdeps/powerpc/fpu/fesetmode.c b/REORG.TODO/sysdeps/powerpc/fpu/fesetmode.c new file mode 100644 index 0000000000..794f762898 --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/fesetmode.c @@ -0,0 +1,49 @@ +/* Install given floating-point control modes. PowerPC version. + Copyright (C) 2016-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <fenv_libc.h> +#include <fpu_control.h> + +#define _FPU_MASK_ALL (_FPU_MASK_ZM | _FPU_MASK_OM | _FPU_MASK_UM \ + | _FPU_MASK_XM | _FPU_MASK_IM) + +#define FPU_STATUS 0xbffff700ULL + +int +fesetmode (const femode_t *modep) +{ + fenv_union_t old, new; + + /* Logic regarding enabled exceptions as in fesetenv. */ + + new.fenv = *modep; + old.fenv = fegetenv_register (); + new.l = (new.l & ~FPU_STATUS) | (old.l & FPU_STATUS); + + if (old.l == new.l) + return 0; + + if ((old.l & _FPU_MASK_ALL) == 0 && (new.l & _FPU_MASK_ALL) != 0) + (void) __fe_nomask_env_priv (); + + if ((old.l & _FPU_MASK_ALL) != 0 && (new.l & _FPU_MASK_ALL) == 0) + (void) __fe_mask_env (); + + fesetenv_register (new.fenv); + return 0; +} diff --git a/REORG.TODO/sysdeps/powerpc/fpu/fesetround.c b/REORG.TODO/sysdeps/powerpc/fpu/fesetround.c new file mode 100644 index 0000000000..a041f1add9 --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/fesetround.c @@ -0,0 +1,33 @@ +/* Set current rounding direction. + Copyright (C) 1997-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <fenv_libc.h> + +#undef fesetround +int +__fesetround (int round) +{ + if ((unsigned int) round > 3) + return 1; + else + return __fesetround_inline(round); +} +libm_hidden_def (__fesetround) +weak_alias (__fesetround, fesetround) +libm_hidden_weak (fesetround) diff --git a/REORG.TODO/sysdeps/powerpc/fpu/feupdateenv.c b/REORG.TODO/sysdeps/powerpc/fpu/feupdateenv.c new file mode 100644 index 0000000000..551cc1734d --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/feupdateenv.c @@ -0,0 +1,68 @@ +/* Install given floating-point environment and raise exceptions. + Copyright (C) 1997-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <fenv_libc.h> +#include <fpu_control.h> + +#define _FPU_MASK_ALL (_FPU_MASK_ZM | _FPU_MASK_OM | _FPU_MASK_UM | _FPU_MASK_XM | _FPU_MASK_IM) + +int +__feupdateenv (const fenv_t *envp) +{ + fenv_union_t old, new; + + /* Save the currently set exceptions. */ + new.fenv = *envp; + old.fenv = fegetenv_register (); + + /* Restore rounding mode and exception enable from *envp and merge + exceptions. Leave fraction rounded/inexact and FP result/CC bits + unchanged. */ + new.l = (old.l & 0xffffffff1fffff00LL) | (new.l & 0x1ff80fff); + + /* If the old env has no enabled exceptions and the new env has any enabled + exceptions, then unmask SIGFPE in the MSR FE0/FE1 bits. This will put + the hardware into "precise mode" and may cause the FPU to run slower on + some hardware. */ + if ((old.l & _FPU_MASK_ALL) == 0 && (new.l & _FPU_MASK_ALL) != 0) + (void) __fe_nomask_env_priv (); + + /* If the old env had any enabled exceptions and the new env has no enabled + exceptions, then mask SIGFPE in the MSR FE0/FE1 bits. This may allow the + FPU to run faster because it always takes the default action and can not + generate SIGFPE. */ + if ((old.l & _FPU_MASK_ALL) != 0 && (new.l & _FPU_MASK_ALL) == 0) + (void)__fe_mask_env (); + + /* Atomically enable and raise (if appropriate) exceptions set in `new'. */ + fesetenv_register (new.fenv); + + /* Success. */ + return 0; +} + +#include <shlib-compat.h> +#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2) +strong_alias (__feupdateenv, __old_feupdateenv) +compat_symbol (libm, __old_feupdateenv, feupdateenv, GLIBC_2_1); +#endif + +libm_hidden_def (__feupdateenv) +libm_hidden_ver (__feupdateenv, feupdateenv) +versioned_symbol (libm, __feupdateenv, feupdateenv, GLIBC_2_2); diff --git a/REORG.TODO/sysdeps/powerpc/fpu/fgetexcptflg.c b/REORG.TODO/sysdeps/powerpc/fpu/fgetexcptflg.c new file mode 100644 index 0000000000..a11b8f3323 --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/fgetexcptflg.c @@ -0,0 +1,42 @@ +/* Store current representation for exceptions. + Copyright (C) 1997-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <fenv_libc.h> + +int +__fegetexceptflag (fexcept_t *flagp, int excepts) +{ + fenv_union_t u; + + /* Get the current state. */ + u.fenv = fegetenv_register (); + + /* Return (all of) it. */ + *flagp = u.l & excepts & FE_ALL_EXCEPT; + + /* Success. */ + return 0; +} + +#include <shlib-compat.h> +#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2) +strong_alias (__fegetexceptflag, __old_fegetexceptflag) +compat_symbol (libm, __old_fegetexceptflag, fegetexceptflag, GLIBC_2_1); +#endif + +versioned_symbol (libm, __fegetexceptflag, fegetexceptflag, GLIBC_2_2); diff --git a/REORG.TODO/sysdeps/powerpc/fpu/fix-fp-int-compare-invalid.h b/REORG.TODO/sysdeps/powerpc/fpu/fix-fp-int-compare-invalid.h new file mode 100644 index 0000000000..17ac1d2c83 --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/fix-fp-int-compare-invalid.h @@ -0,0 +1,28 @@ +/* Fix for missing "invalid" exceptions from floating-point + comparisons. PowerPC version. + Copyright (C) 2016-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef FIX_FP_INT_COMPARE_INVALID_H +#define FIX_FP_INT_COMPARE_INVALID_H 1 + +/* As of GCC 5, comparisons use unordered comparison instructions when + they should use ordered comparisons + <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58684>. */ +#define FIX_COMPARE_INVALID 1 + +#endif /* fix-fp-int-compare-invalid.h */ diff --git a/REORG.TODO/sysdeps/powerpc/fpu/fraiseexcpt.c b/REORG.TODO/sysdeps/powerpc/fpu/fraiseexcpt.c new file mode 100644 index 0000000000..05f5cb6309 --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/fraiseexcpt.c @@ -0,0 +1,68 @@ +/* Raise given exceptions. + Copyright (C) 1997-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <fenv_libc.h> + +#undef feraiseexcept +int +__feraiseexcept (int excepts) +{ + fenv_union_t u; + + /* Raise exceptions represented by EXCEPTS. It is the responsibility of + the OS to ensure that if multiple exceptions occur they are fed back + to this process in the proper way; this can happen in hardware, + anyway (in particular, inexact with overflow or underflow). */ + + /* Get the current state. */ + u.fenv = fegetenv_register (); + + /* Add the exceptions */ + u.l = (u.l + | (excepts & FPSCR_STICKY_BITS) + /* Turn FE_INVALID into FE_INVALID_SOFTWARE. */ + | (excepts >> ((31 - FPSCR_VX) - (31 - FPSCR_VXSOFT)) + & FE_INVALID_SOFTWARE)); + + /* Store the new status word (along with the rest of the environment), + triggering any appropriate exceptions. */ + fesetenv_register (u.fenv); + + if ((excepts & FE_INVALID)) + { + /* For some reason, some PowerPC chips (the 601, in particular) + don't have FE_INVALID_SOFTWARE implemented. Detect this + case and raise FE_INVALID_SNAN instead. */ + u.fenv = fegetenv_register (); + if ((u.l & FE_INVALID) == 0) + set_fpscr_bit (FPSCR_VXSNAN); + } + + /* Success. */ + return 0; +} + +#include <shlib-compat.h> +#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2) +strong_alias (__feraiseexcept, __old_feraiseexcept) +compat_symbol (libm, __old_feraiseexcept, feraiseexcept, GLIBC_2_1); +#endif + +libm_hidden_def (__feraiseexcept) +libm_hidden_ver (__feraiseexcept, feraiseexcept) +versioned_symbol (libm, __feraiseexcept, feraiseexcept, GLIBC_2_2); diff --git a/REORG.TODO/sysdeps/powerpc/fpu/fsetexcptflg.c b/REORG.TODO/sysdeps/powerpc/fpu/fsetexcptflg.c new file mode 100644 index 0000000000..d5c0963688 --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/fsetexcptflg.c @@ -0,0 +1,63 @@ +/* Set floating-point environment exception handling. + Copyright (C) 1997-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <fenv_libc.h> + +int +__fesetexceptflag (const fexcept_t *flagp, int excepts) +{ + fenv_union_t u, n; + fexcept_t flag; + + /* Get the current state. */ + u.fenv = fegetenv_register (); + + /* Ignore exceptions not listed in 'excepts'. */ + flag = *flagp & excepts; + + /* Replace the exception status */ + int excepts_mask = FPSCR_STICKY_BITS & excepts; + if ((excepts & FE_INVALID) != 0) + excepts_mask |= FE_ALL_INVALID; + n.l = ((u.l & ~excepts_mask) + | (flag & FPSCR_STICKY_BITS) + /* Turn FE_INVALID into FE_INVALID_SOFTWARE. */ + | (flag >> ((31 - FPSCR_VX) - (31 - FPSCR_VXSOFT)) + & FE_INVALID_SOFTWARE)); + + /* Store the new status word (along with the rest of the environment). + This may cause floating-point exceptions if the restored state + requests it. */ + if (n.l != u.l) + fesetenv_register (n.fenv); + + /* Deal with FE_INVALID_SOFTWARE not being implemented on some chips. */ + if (flag & FE_INVALID) + feraiseexcept(FE_INVALID); + + /* Success. */ + return 0; +} + +#include <shlib-compat.h> +#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2) +strong_alias (__fesetexceptflag, __old_fesetexceptflag) +compat_symbol (libm, __old_fesetexceptflag, fesetexceptflag, GLIBC_2_1); +#endif + +versioned_symbol (libm, __fesetexceptflag, fesetexceptflag, GLIBC_2_2); diff --git a/REORG.TODO/sysdeps/powerpc/fpu/ftestexcept.c b/REORG.TODO/sysdeps/powerpc/fpu/ftestexcept.c new file mode 100644 index 0000000000..8f2ecad509 --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/ftestexcept.c @@ -0,0 +1,33 @@ +/* Test exception in current environment. + Copyright (C) 1997-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <fenv_libc.h> + +int +fetestexcept (int excepts) +{ + fenv_union_t u; + + /* Get the current state. */ + u.fenv = fegetenv_register (); + + /* The FE_INVALID bit is dealt with correctly by the hardware, so we can + just: */ + return u.l & excepts; +} +libm_hidden_def (fetestexcept) diff --git a/REORG.TODO/sysdeps/powerpc/fpu/k_cosf.c b/REORG.TODO/sysdeps/powerpc/fpu/k_cosf.c new file mode 100644 index 0000000000..b9e31dc64d --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/k_cosf.c @@ -0,0 +1,65 @@ +/* k_cosf.c -- float version of k_cos.c + Copyright (C) 2011-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Adhemerval Zanella <azanella@br.ibm.com>, 2011 + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If + not, see <http://www.gnu.org/licenses/>. */ + +#include <math.h> +#include <fenv.h> +#include <math_private.h> + +static const float twom27 = 7.4505806e-09; +static const float dot3 = 3.0000001e-01; +static const float dot78125 = 7.8125000e-01; + +static const float one = 1.0000000000e+00; +static const float C1 = 4.1666667908e-02; +static const float C2 = -1.3888889225e-03; +static const float C3 = 2.4801587642e-05; +static const float C4 = -2.7557314297e-07; +static const float C5 = 2.0875723372e-09; +static const float C6 = -1.1359647598e-11; + +float +__kernel_cosf (float x, float y) +{ + float a, hz, z, r, qx; + float ix; + ix = __builtin_fabsf (x); + if (ix < twom27) + { /* |x| < 2**-27 */ + __feraiseexcept (FE_INEXACT); + return one; + } + z = x * x; + r = z * (C1 + z * (C2 + z * (C3 + z * (C4 + z * (C5 + z * C6))))); + if (ix < dot3) /* if |x| < 0.3 */ + return one - ((float) 0.5 * z - (z * r - x * y)); + else + { + if (ix > dot78125) + { /* x > 0.78125 */ + qx = (float) 0.28125; + } + else + { + qx = ix / 4.0; + } + hz = (float) 0.5 *z - qx; + a = one - qx; + return a - (hz - (z * r - x * y)); + } +} diff --git a/REORG.TODO/sysdeps/powerpc/fpu/k_rem_pio2f.c b/REORG.TODO/sysdeps/powerpc/fpu/k_rem_pio2f.c new file mode 100644 index 0000000000..04ed62055a --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/k_rem_pio2f.c @@ -0,0 +1,273 @@ +/* k_rem_pio2f.c -- float version of e_rem_pio2.c + Copyright (C) 2011-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Adhemerval Zanella <azanella@br.ibm.com>, 2011 + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If + not, see <http://www.gnu.org/licenses/>. */ + +#include <math.h> + +#include <math_private.h> +#include "s_float_bitwise.h" + + +static const float two_over_pi[] = { + 1.62000000e+02, 2.49000000e+02, 1.31000000e+02, 1.10000000e+02, + 7.80000000e+01, 6.80000000e+01, 2.10000000e+01, 4.10000000e+01, + 2.52000000e+02, 3.90000000e+01, 8.70000000e+01, 2.09000000e+02, + 2.45000000e+02, 5.20000000e+01, 2.21000000e+02, 1.92000000e+02, + 2.19000000e+02, 9.80000000e+01, 1.49000000e+02, 1.53000000e+02, + 6.00000000e+01, 6.70000000e+01, 1.44000000e+02, 6.50000000e+01, + 2.54000000e+02, 8.10000000e+01, 9.90000000e+01, 1.71000000e+02, + 2.22000000e+02, 1.87000000e+02, 1.97000000e+02, 9.70000000e+01, + 1.83000000e+02, 3.60000000e+01, 1.10000000e+02, 5.80000000e+01, + 6.60000000e+01, 7.70000000e+01, 2.10000000e+02, 2.24000000e+02, + 6.00000000e+00, 7.30000000e+01, 4.60000000e+01, 2.34000000e+02, + 9.00000000e+00, 2.09000000e+02, 1.46000000e+02, 2.80000000e+01, + 2.54000000e+02, 2.90000000e+01, 2.35000000e+02, 2.80000000e+01, + 1.77000000e+02, 4.10000000e+01, 1.67000000e+02, 6.20000000e+01, + 2.32000000e+02, 1.30000000e+02, 5.30000000e+01, 2.45000000e+02, + 4.60000000e+01, 1.87000000e+02, 6.80000000e+01, 1.32000000e+02, + 2.33000000e+02, 1.56000000e+02, 1.12000000e+02, 3.80000000e+01, + 1.80000000e+02, 9.50000000e+01, 1.26000000e+02, 6.50000000e+01, + 5.70000000e+01, 1.45000000e+02, 2.14000000e+02, 5.70000000e+01, + 1.31000000e+02, 8.30000000e+01, 5.70000000e+01, 2.44000000e+02, + 1.56000000e+02, 1.32000000e+02, 9.50000000e+01, 1.39000000e+02, + 1.89000000e+02, 2.49000000e+02, 4.00000000e+01, 5.90000000e+01, + 3.10000000e+01, 2.48000000e+02, 1.51000000e+02, 2.55000000e+02, + 2.22000000e+02, 5.00000000e+00, 1.52000000e+02, 1.50000000e+01, + 2.39000000e+02, 4.70000000e+01, 1.70000000e+01, 1.39000000e+02, + 9.00000000e+01, 1.00000000e+01, 1.09000000e+02, 3.10000000e+01, + 1.09000000e+02, 5.40000000e+01, 1.26000000e+02, 2.07000000e+02, + 3.90000000e+01, 2.03000000e+02, 9.00000000e+00, 1.83000000e+02, + 7.90000000e+01, 7.00000000e+01, 6.30000000e+01, 1.02000000e+02, + 1.58000000e+02, 9.50000000e+01, 2.34000000e+02, 4.50000000e+01, + 1.17000000e+02, 3.90000000e+01, 1.86000000e+02, 1.99000000e+02, + 2.35000000e+02, 2.29000000e+02, 2.41000000e+02, 1.23000000e+02, + 6.10000000e+01, 7.00000000e+00, 5.70000000e+01, 2.47000000e+02, + 1.38000000e+02, 8.20000000e+01, 1.46000000e+02, 2.34000000e+02, + 1.07000000e+02, 2.51000000e+02, 9.50000000e+01, 1.77000000e+02, + 3.10000000e+01, 1.41000000e+02, 9.30000000e+01, 8.00000000e+00, + 8.60000000e+01, 3.00000000e+00, 4.80000000e+01, 7.00000000e+01, + 2.52000000e+02, 1.23000000e+02, 1.07000000e+02, 1.71000000e+02, + 2.40000000e+02, 2.07000000e+02, 1.88000000e+02, 3.20000000e+01, + 1.54000000e+02, 2.44000000e+02, 5.40000000e+01, 2.90000000e+01, + 1.69000000e+02, 2.27000000e+02, 1.45000000e+02, 9.70000000e+01, + 9.40000000e+01, 2.30000000e+02, 2.70000000e+01, 8.00000000e+00, + 1.01000000e+02, 1.53000000e+02, 1.33000000e+02, 9.50000000e+01, + 2.00000000e+01, 1.60000000e+02, 1.04000000e+02, 6.40000000e+01, + 1.41000000e+02, 2.55000000e+02, 2.16000000e+02, 1.28000000e+02, + 7.70000000e+01, 1.15000000e+02, 3.90000000e+01, 4.90000000e+01, + 6.00000000e+00, 6.00000000e+00, 2.10000000e+01, 8.60000000e+01, + 2.02000000e+02, 1.15000000e+02, 1.68000000e+02, 2.01000000e+02, + 9.60000000e+01, 2.26000000e+02, 1.23000000e+02, 1.92000000e+02, + 1.40000000e+02, 1.07000000e+02 +}; + + +static const float PIo2[] = { + 1.5703125000e+00, /* 0x3fc90000 */ + 4.5776367188e-04, /* 0x39f00000 */ + 2.5987625122e-05, /* 0x37da0000 */ + 7.5437128544e-08, /* 0x33a20000 */ + 6.0026650317e-11, /* 0x2e840000 */ + 7.3896444519e-13, /* 0x2b500000 */ + 5.3845816694e-15, /* 0x27c20000 */ + 5.6378512969e-18, /* 0x22d00000 */ + 8.3009228831e-20, /* 0x1fc40000 */ + 3.2756352257e-22, /* 0x1bc60000 */ + 6.3331015649e-25, /* 0x17440000 */ +}; + + +static const float zero = 0.0000000000e+00; +static const float one = 1.0000000000; +static const float twon8 = 3.9062500000e-03; +static const float two8 = 2.5600000000e+02; + + +int32_t +__fp_kernel_rem_pio2f (float *x, float *y, float e0, int32_t nx) +{ + int32_t jz, jx, jv, jp, jk, carry, n, iq[20], i, j, k, m, q0, ih, exp; + float z, fw, f[20], fq[20], q[20]; + + /* initialize jk */ + jp = jk = 9; + + /* determine jx,jv,q0, note that 3>q0 */ + jx = nx - 1; + exp = __float_get_exp (e0) - 127; + jv = (exp - 3) / 8; + if (jv < 0) + jv = 0; + q0 = exp - 8 * (jv + 1); + + /* set up f[0] to f[jx+jk] where f[jx+jk] = two_over_pi[jv+jk] */ + j = jv - jx; + m = jx + jk; + for (i = 0; i <= m; i++, j++) + f[i] = (j < 0) ? zero : two_over_pi[j]; + + /* compute q[0],q[1],...q[jk] */ + for (i = 0; i <= jk; i++) + { + for (j = 0, fw = 0.0; j <= jx; j++) + fw += x[j] * f[jx + i - j]; + q[i] = fw; + } + + jz = jk; +recompute: + /* distill q[] into iq[] reversingly */ + for (i = 0, j = jz, z = q[jz]; j > 0; i++, j--) + { + fw = __truncf (twon8 * z); + iq[i] = (int32_t) (z - two8 * fw); + z = q[j - 1] + fw; + } + + /* compute n */ + z = __scalbnf (z, q0); /* actual value of z */ + z -= 8.0 * __floorf (z * 0.125); /* trim off integer >= 8 */ + n = (int32_t) z; + z -= __truncf (z); + ih = 0; + if (q0 > 0) + { /* need iq[jz-1] to determine n */ + i = (iq[jz - 1] >> (8 - q0)); + n += i; + iq[jz - 1] -= i << (8 - q0); + ih = iq[jz - 1] >> (7 - q0); + } + else if (q0 == 0) + ih = iq[jz - 1] >> 7; + else if (z >= 0.5) + ih = 2; + + if (ih > 0) + { /* q > 0.5 */ + n += 1; + carry = 0; + for (i = 0; i < jz; i++) + { /* compute 1-q */ + j = iq[i]; + if (carry == 0) + { + if (j != 0) + { + carry = 1; + iq[i] = 0x100 - j; + } + } + else + iq[i] = 0xff - j; + } + if (q0 > 0) + { /* rare case: chance is 1 in 12 */ + switch (q0) + { + case 1: + iq[jz - 1] &= 0x7f; + break; + case 2: + iq[jz - 1] &= 0x3f; + break; + } + } + if (ih == 2) + { + z = one - z; + if (carry != 0) + z -= __scalbnf (one, q0); + } + } + + /* check if recomputation is needed */ + if (z == zero) + { + j = 0; + for (i = jz - 1; i >= jk; i--) + j |= iq[i]; + if (j == 0) + { /* need recomputation */ + for (k = 1; iq[jk - k] == 0; k++); /* k = no. of terms needed */ + + for (i = jz + 1; i <= jz + k; i++) + { /* add q[jz+1] to q[jz+k] */ + f[jx + i] = two_over_pi[jv + i]; + for (j = 0, fw = 0.0; j <= jx; j++) + fw += x[j] * f[jx + i - j]; + q[i] = fw; + } + jz += k; + goto recompute; + } + } + + /* chop off zero terms */ + if (z == 0.0) + { + jz -= 1; + q0 -= 8; + while (iq[jz] == 0) + { + jz--; + q0 -= 8; + } + } + else + { /* break z into 8-bit if necessary */ + z = __scalbnf (z, -q0); + if (z >= two8) + { + fw = __truncf (twon8 * z); + iq[jz] = (int32_t) (z - two8 * fw); + jz += 1; + q0 += 8; + iq[jz] = (int32_t) fw; + } + else + iq[jz] = (int32_t) z; + } + + /* convert integer "bit" chunk to floating-point value */ + fw = __scalbnf (one, q0); + for (i = jz; i >= 0; i--) + { + q[i] = fw * (float) iq[i]; + fw *= twon8; + } + + /* compute PIo2[0,...,jp]*q[jz,...,0] */ + for (i = jz; i >= 0; i--) + { + for (fw = 0.0, k = 0; k <= jp && k <= jz - i; k++) + fw += PIo2[k] * q[i + k]; + fq[jz - i] = fw; + } + + /* compress fq[] into y[] */ + fw = 0.0; + for (i = jz; i >= 0; i--) + fw += fq[i]; + y[0] = (ih == 0) ? fw : -fw; + fw = fq[0] - fw; + for (i = 1; i <= jz; i++) + fw += fq[i]; + y[1] = (ih == 0) ? fw : -fw; + + return n & 7; +} diff --git a/REORG.TODO/sysdeps/powerpc/fpu/k_sinf.c b/REORG.TODO/sysdeps/powerpc/fpu/k_sinf.c new file mode 100644 index 0000000000..251633dc30 --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/k_sinf.c @@ -0,0 +1,57 @@ +/* k_sinf.c -- float version of k_sin.c + Copyright (C) 2011-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Adhemerval Zanella <azanella@br.ibm.com>, 2011 + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If + not, see <http://www.gnu.org/licenses/>. */ + +#include <float.h> +#include <math.h> +#include <fenv.h> +#include <math_private.h> + + +static const float twom27 = 7.4505806000e-09; +static const float half = 5.0000000000e-01; +static const float S1 = -1.6666667163e-01; +static const float S2 = 8.3333337680e-03; +static const float S3 = -1.9841270114e-04; +static const float S4 = 2.7557314297e-06; +static const float S5 = -2.5050759689e-08; +static const float S6 = 1.5896910177e-10; + + +float +__kernel_sinf (float x, float y, int iy) +{ + float z, r, v; + float ix; + ix = __builtin_fabsf (x); + if (ix < twom27) + { /* |x| < 2**-27 */ + if (ix < FLT_MIN && ix != 0.0f) + __feraiseexcept (FE_UNDERFLOW|FE_INEXACT); + else + __feraiseexcept (FE_INEXACT); + return x; + } + z = x * x; + v = z * x; + r = S2 + z * (S3 + z * (S4 + z * (S5 + z * S6))); + if (iy == 0) + return x + v * (S1 + z * r); + else + return x - ((z * (half * y - v * r) - y) - v * S1); +} diff --git a/REORG.TODO/sysdeps/powerpc/fpu/libm-test-ulps b/REORG.TODO/sysdeps/powerpc/fpu/libm-test-ulps new file mode 100644 index 0000000000..72eb2b1e5a --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/libm-test-ulps @@ -0,0 +1,2342 @@ +# Begin of automatic generation + +# Maximal error of functions: +Function: "acos": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "acos_downward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 3 +ldouble: 3 + +Function: "acos_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 3 +ldouble: 3 + +Function: "acos_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "acosh": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "acosh_downward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: "acosh_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 4 +ldouble: 4 + +Function: "acosh_upward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 3 +ldouble: 4 + +Function: "asin": +float: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "asin_downward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "asin_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "asin_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "asinh": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "asinh_downward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 5 +ldouble: 5 + +Function: "asinh_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 5 +ldouble: 5 + +Function: "asinh_upward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 7 +ldouble: 7 + +Function: "atan": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "atan2": +float: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "atan2_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 5 +ldouble: 5 + +Function: "atan2_towardzero": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 6 +ldouble: 6 + +Function: "atan2_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 3 +ldouble: 3 + +Function: "atan_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 1 +ldouble: 1 + +Function: "atan_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "atan_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "atanh": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "atanh_downward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 3 +ldouble: 3 + +Function: "atanh_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "atanh_upward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 4 +ldouble: 4 + +Function: "cabs": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 + +Function: "cabs_downward": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 + +Function: "cabs_towardzero": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 + +Function: "cabs_upward": +double: 1 +idouble: 1 +ildouble: 2 +ldouble: 2 + +Function: Real part of "cacos": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 1 +ldouble: 1 + +Function: Imaginary part of "cacos": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Real part of "cacos_downward": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 6 +ldouble: 6 + +Function: Imaginary part of "cacos_downward": +double: 5 +float: 3 +idouble: 5 +ifloat: 3 +ildouble: 8 +ldouble: 8 + +Function: Real part of "cacos_towardzero": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 7 +ldouble: 7 + +Function: Imaginary part of "cacos_towardzero": +double: 5 +float: 3 +idouble: 5 +ifloat: 3 +ildouble: 8 +ldouble: 8 + +Function: Real part of "cacos_upward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 7 +ldouble: 7 + +Function: Imaginary part of "cacos_upward": +double: 5 +float: 5 +idouble: 5 +ifloat: 5 +ildouble: 13 +ldouble: 13 + +Function: Real part of "cacosh": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "cacosh": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 1 +ldouble: 1 + +Function: Real part of "cacosh_downward": +double: 5 +float: 3 +idouble: 5 +ifloat: 3 +ildouble: 8 +ldouble: 8 + +Function: Imaginary part of "cacosh_downward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 6 +ldouble: 6 + +Function: Real part of "cacosh_towardzero": +double: 5 +float: 3 +idouble: 5 +ifloat: 3 +ildouble: 8 +ldouble: 8 + +Function: Imaginary part of "cacosh_towardzero": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 7 +ldouble: 7 + +Function: Real part of "cacosh_upward": +double: 4 +float: 4 +idouble: 4 +ifloat: 4 +ildouble: 12 +ldouble: 12 + +Function: Imaginary part of "cacosh_upward": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 8 +ldouble: 8 + +Function: "carg": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "carg_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 5 +ldouble: 5 + +Function: "carg_towardzero": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 6 +ldouble: 6 + +Function: "carg_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 3 +ldouble: 3 + +Function: Real part of "casin": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Imaginary part of "casin": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Real part of "casin_downward": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 4 +ldouble: 4 + +Function: Imaginary part of "casin_downward": +double: 5 +float: 3 +idouble: 5 +ifloat: 3 +ildouble: 8 +ldouble: 8 + +Function: Real part of "casin_towardzero": +double: 3 +float: 1 +idouble: 3 +ifloat: 1 +ildouble: 5 +ldouble: 5 + +Function: Imaginary part of "casin_towardzero": +double: 5 +float: 3 +idouble: 5 +ifloat: 3 +ildouble: 8 +ldouble: 8 + +Function: Real part of "casin_upward": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 6 +ldouble: 6 + +Function: Imaginary part of "casin_upward": +double: 5 +float: 5 +idouble: 5 +ifloat: 5 +ildouble: 13 +ldouble: 13 + +Function: Real part of "casinh": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "casinh": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Real part of "casinh_downward": +double: 5 +float: 3 +idouble: 5 +ifloat: 3 +ildouble: 8 +ldouble: 8 + +Function: Imaginary part of "casinh_downward": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 4 +ldouble: 4 + +Function: Real part of "casinh_towardzero": +double: 5 +float: 3 +idouble: 5 +ifloat: 3 +ildouble: 8 +ldouble: 8 + +Function: Imaginary part of "casinh_towardzero": +double: 3 +float: 1 +idouble: 3 +ifloat: 1 +ildouble: 5 +ldouble: 5 + +Function: Real part of "casinh_upward": +double: 5 +float: 5 +idouble: 5 +ifloat: 5 +ildouble: 13 +ldouble: 13 + +Function: Imaginary part of "casinh_upward": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 6 +ldouble: 6 + +Function: Real part of "catan": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "catan": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: Real part of "catan_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 6 +ldouble: 6 + +Function: Imaginary part of "catan_downward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 7 +ldouble: 7 + +Function: Real part of "catan_towardzero": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 7 +ldouble: 7 + +Function: Imaginary part of "catan_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Real part of "catan_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 6 +ldouble: 6 + +Function: Imaginary part of "catan_upward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 8 +ldouble: 8 + +Function: Real part of "catanh": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "catanh": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 3 +ldouble: 3 + +Function: Real part of "catanh_downward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 5 +ldouble: 5 + +Function: Imaginary part of "catanh_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 6 +ldouble: 6 + +Function: Real part of "catanh_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "catanh_towardzero": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 7 +ldouble: 7 + +Function: Real part of "catanh_upward": +double: 4 +float: 4 +idouble: 4 +ifloat: 4 +ildouble: 8 +ldouble: 8 + +Function: Imaginary part of "catanh_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 6 +ldouble: 6 + +Function: "cbrt": +double: 3 +float: 1 +idouble: 3 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "cbrt_downward": +double: 4 +float: 1 +idouble: 4 +ifloat: 1 +ildouble: 5 +ldouble: 5 + +Function: "cbrt_towardzero": +double: 3 +float: 1 +idouble: 3 +ifloat: 1 +ildouble: 3 +ldouble: 3 + +Function: "cbrt_upward": +double: 5 +float: 1 +idouble: 5 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: Real part of "ccos": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Imaginary part of "ccos": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: Real part of "ccos_downward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 6 +ldouble: 6 + +Function: Imaginary part of "ccos_downward": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 +ildouble: 6 +ldouble: 6 + +Function: Real part of "ccos_towardzero": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 6 +ldouble: 6 + +Function: Imaginary part of "ccos_towardzero": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 +ildouble: 6 +ldouble: 6 + +Function: Real part of "ccos_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "ccos_upward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 4 +ldouble: 4 + +Function: Real part of "ccosh": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Imaginary part of "ccosh": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: Real part of "ccosh_downward": +double: 1 +float: 3 +idouble: 1 +ifloat: 3 +ildouble: 6 +ldouble: 6 + +Function: Imaginary part of "ccosh_downward": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 +ildouble: 6 +ldouble: 6 + +Function: Real part of "ccosh_towardzero": +double: 1 +float: 3 +idouble: 1 +ifloat: 3 +ildouble: 6 +ldouble: 6 + +Function: Imaginary part of "ccosh_towardzero": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 +ildouble: 6 +ldouble: 6 + +Function: Real part of "ccosh_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "ccosh_upward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 4 +ldouble: 4 + +Function: Real part of "cexp": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "cexp": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Real part of "cexp_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 11 +ldouble: 11 + +Function: Imaginary part of "cexp_downward": +double: 1 +float: 3 +idouble: 1 +ifloat: 3 +ildouble: 11 +ldouble: 11 + +Function: Real part of "cexp_towardzero": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 11 +ldouble: 11 + +Function: Imaginary part of "cexp_towardzero": +double: 1 +float: 3 +idouble: 1 +ifloat: 3 +ildouble: 11 +ldouble: 11 + +Function: Real part of "cexp_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "cexp_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Real part of "clog": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 5 +ldouble: 5 + +Function: Imaginary part of "clog": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: Real part of "clog10": +double: 3 +float: 4 +idouble: 3 +ifloat: 4 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "clog10": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Real part of "clog10_downward": +double: 6 +float: 6 +idouble: 6 +ifloat: 6 +ildouble: 10 +ldouble: 10 + +Function: Imaginary part of "clog10_downward": +double: 2 +float: 4 +idouble: 2 +ifloat: 4 +ildouble: 7 +ldouble: 7 + +Function: Real part of "clog10_towardzero": +double: 5 +float: 5 +idouble: 5 +ifloat: 5 +ildouble: 9 +ldouble: 9 + +Function: Imaginary part of "clog10_towardzero": +double: 2 +float: 4 +idouble: 2 +ifloat: 4 +ildouble: 8 +ldouble: 8 + +Function: Real part of "clog10_upward": +double: 8 +float: 5 +idouble: 8 +ifloat: 5 +ildouble: 10 +ldouble: 10 + +Function: Imaginary part of "clog10_upward": +double: 2 +float: 4 +idouble: 2 +ifloat: 4 +ildouble: 7 +ldouble: 7 + +Function: Real part of "clog_downward": +double: 7 +float: 5 +idouble: 7 +ifloat: 5 +ildouble: 11 +ldouble: 11 + +Function: Imaginary part of "clog_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 5 +ldouble: 5 + +Function: Real part of "clog_towardzero": +double: 7 +float: 5 +idouble: 7 +ifloat: 5 +ildouble: 10 +ldouble: 10 + +Function: Imaginary part of "clog_towardzero": +double: 1 +float: 3 +idouble: 1 +ifloat: 3 +ildouble: 7 +ldouble: 7 + +Function: Real part of "clog_upward": +double: 8 +float: 5 +idouble: 8 +ifloat: 5 +ildouble: 10 +ldouble: 10 + +Function: Imaginary part of "clog_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 4 +ldouble: 4 + +Function: "cos": +float: 3 +ifloat: 3 +ildouble: 4 +ldouble: 4 + +Function: "cos_downward": +double: 1 +float: 4 +idouble: 1 +ifloat: 4 +ildouble: 5 +ldouble: 5 + +Function: "cos_towardzero": +double: 1 +float: 3 +idouble: 1 +ifloat: 3 +ildouble: 4 +ldouble: 4 + +Function: "cos_upward": +double: 1 +float: 3 +idouble: 1 +ifloat: 3 +ildouble: 5 +ldouble: 5 + +Function: "cosh": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 3 +ldouble: 3 + +Function: "cosh_downward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "cosh_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "cosh_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Real part of "cpow": +double: 2 +float: 5 +idouble: 2 +ifloat: 5 +ildouble: 4 +ldouble: 4 + +Function: Imaginary part of "cpow": +float: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Real part of "cpow_downward": +double: 4 +float: 8 +idouble: 4 +ifloat: 8 +ildouble: 7 +ldouble: 7 + +Function: Imaginary part of "cpow_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 4 +ldouble: 4 + +Function: Real part of "cpow_towardzero": +double: 4 +float: 8 +idouble: 4 +ifloat: 8 +ildouble: 8 +ldouble: 8 + +Function: Imaginary part of "cpow_towardzero": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 4 +ldouble: 4 + +Function: Real part of "cpow_upward": +double: 4 +float: 1 +idouble: 4 +ifloat: 1 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "cpow_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Real part of "csin": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "csin": +ildouble: 1 +ldouble: 1 + +Function: Real part of "csin_downward": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 +ildouble: 6 +ldouble: 6 + +Function: Imaginary part of "csin_downward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 6 +ldouble: 6 + +Function: Real part of "csin_towardzero": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 +ildouble: 6 +ldouble: 6 + +Function: Imaginary part of "csin_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 6 +ldouble: 6 + +Function: Real part of "csin_upward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "csin_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Real part of "csinh": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Imaginary part of "csinh": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: Real part of "csinh_downward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 6 +ldouble: 6 + +Function: Imaginary part of "csinh_downward": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 +ildouble: 6 +ldouble: 6 + +Function: Real part of "csinh_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 6 +ldouble: 6 + +Function: Imaginary part of "csinh_towardzero": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 +ildouble: 6 +ldouble: 6 + +Function: Real part of "csinh_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "csinh_upward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Real part of "csqrt": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 1 +ldouble: 1 + +Function: Imaginary part of "csqrt": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 1 +ldouble: 1 + +Function: Real part of "csqrt_downward": +double: 5 +float: 4 +idouble: 5 +ifloat: 4 +ildouble: 4 +ldouble: 4 + +Function: Imaginary part of "csqrt_downward": +double: 4 +float: 3 +idouble: 4 +ifloat: 3 +ildouble: 5 +ldouble: 5 + +Function: Real part of "csqrt_towardzero": +double: 4 +float: 3 +idouble: 4 +ifloat: 3 +ildouble: 5 +ldouble: 5 + +Function: Imaginary part of "csqrt_towardzero": +double: 4 +float: 3 +idouble: 4 +ifloat: 3 +ildouble: 5 +ldouble: 5 + +Function: Real part of "csqrt_upward": +double: 5 +float: 4 +idouble: 5 +ifloat: 4 +ildouble: 12 +ldouble: 12 + +Function: Imaginary part of "csqrt_upward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 8 +ldouble: 8 + +Function: Real part of "ctan": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "ctan": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: Real part of "ctan_downward": +double: 6 +float: 5 +idouble: 6 +ifloat: 5 +ildouble: 6 +ldouble: 6 + +Function: Imaginary part of "ctan_downward": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +ildouble: 9 +ldouble: 9 + +Function: Real part of "ctan_towardzero": +double: 5 +float: 3 +idouble: 5 +ifloat: 3 +ildouble: 6 +ldouble: 6 + +Function: Imaginary part of "ctan_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 13 +ldouble: 13 + +Function: Real part of "ctan_upward": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 +ildouble: 7 +ldouble: 7 + +Function: Imaginary part of "ctan_upward": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 +ildouble: 10 +ldouble: 10 + +Function: Real part of "ctanh": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "ctanh": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +ildouble: 3 +ldouble: 3 + +Function: Real part of "ctanh_downward": +double: 4 +float: 1 +idouble: 4 +ifloat: 1 +ildouble: 9 +ldouble: 9 + +Function: Imaginary part of "ctanh_downward": +double: 6 +float: 5 +idouble: 6 +ifloat: 5 +ildouble: 6 +ldouble: 6 + +Function: Real part of "ctanh_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 13 +ldouble: 13 + +Function: Imaginary part of "ctanh_towardzero": +double: 5 +float: 2 +idouble: 5 +ifloat: 2 +ildouble: 10 +ldouble: 10 + +Function: Real part of "ctanh_upward": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 +ildouble: 10 +ldouble: 10 + +Function: Imaginary part of "ctanh_upward": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 +ildouble: 10 +ldouble: 10 + +Function: "erf": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "erf_downward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "erf_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "erf_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 3 +ldouble: 3 + +Function: "erfc": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: "erfc_downward": +double: 3 +float: 4 +idouble: 3 +ifloat: 4 +ildouble: 10 +ldouble: 10 + +Function: "erfc_towardzero": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 9 +ldouble: 9 + +Function: "erfc_upward": +double: 3 +float: 4 +idouble: 3 +ifloat: 4 +ildouble: 7 +ldouble: 7 + +Function: "exp": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "exp10": +double: 2 +idouble: 2 +ildouble: 1 +ldouble: 1 + +Function: "exp10_downward": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +ildouble: 9 +ldouble: 9 + +Function: "exp10_towardzero": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +ildouble: 9 +ldouble: 9 + +Function: "exp10_upward": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +ildouble: 4 +ldouble: 4 + +Function: "exp2": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "exp2_downward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "exp2_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "exp2_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "exp_downward": +double: 1 +idouble: 1 +ildouble: 2 +ldouble: 2 + +Function: "exp_towardzero": +double: 1 +idouble: 1 +ildouble: 2 +ldouble: 2 + +Function: "exp_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "expm1": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "expm1_downward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 3 +ldouble: 3 + +Function: "expm1_towardzero": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 5 +ldouble: 5 + +Function: "expm1_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 6 +ldouble: 6 + +Function: "fma": +ildouble: 1 +ldouble: 1 + +Function: "fma_downward": +ildouble: 1 +ldouble: 1 + +Function: "fma_towardzero": +ildouble: 2 +ldouble: 2 + +Function: "fma_upward": +ildouble: 3 +ldouble: 3 + +Function: "fmod": +ildouble: 1 +ldouble: 1 + +Function: "fmod_downward": +ildouble: 1 +ldouble: 1 + +Function: "fmod_towardzero": +ildouble: 1 +ldouble: 1 + +Function: "fmod_upward": +ildouble: 1 +ldouble: 1 + +Function: "gamma": +double: 3 +float: 4 +idouble: 3 +ifloat: 4 +ildouble: 3 +ldouble: 3 + +Function: "gamma_downward": +double: 4 +float: 4 +idouble: 4 +ifloat: 4 +ildouble: 15 +ldouble: 15 + +Function: "gamma_towardzero": +double: 4 +float: 3 +idouble: 4 +ifloat: 3 +ildouble: 16 +ldouble: 16 + +Function: "gamma_upward": +double: 4 +float: 5 +idouble: 4 +ifloat: 5 +ildouble: 11 +ldouble: 11 + +Function: "hypot": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 + +Function: "hypot_downward": +double: 1 +idouble: 1 +ildouble: 2 +ldouble: 2 + +Function: "hypot_towardzero": +double: 1 +idouble: 1 +ildouble: 2 +ldouble: 2 + +Function: "hypot_upward": +double: 1 +idouble: 1 +ildouble: 3 +ldouble: 3 + +Function: "j0": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "j0_downward": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 +ildouble: 11 +ldouble: 11 + +Function: "j0_towardzero": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +ildouble: 8 +ldouble: 8 + +Function: "j0_upward": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 6 +ldouble: 6 + +Function: "j1": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "j1_downward": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 7 +ldouble: 7 + +Function: "j1_towardzero": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 7 +ldouble: 7 + +Function: "j1_upward": +double: 3 +float: 4 +idouble: 3 +ifloat: 4 +ildouble: 6 +ldouble: 6 + +Function: "jn": +double: 4 +float: 4 +idouble: 4 +ifloat: 4 +ildouble: 4 +ldouble: 4 + +Function: "jn_downward": +double: 4 +float: 5 +idouble: 4 +ifloat: 5 +ildouble: 7 +ldouble: 7 + +Function: "jn_towardzero": +double: 4 +float: 5 +idouble: 4 +ifloat: 5 +ildouble: 7 +ldouble: 7 + +Function: "jn_upward": +double: 5 +float: 4 +idouble: 5 +ifloat: 4 +ildouble: 5 +ldouble: 5 + +Function: "lgamma": +double: 3 +float: 4 +idouble: 3 +ifloat: 4 +ildouble: 3 +ldouble: 3 + +Function: "lgamma_downward": +double: 4 +float: 4 +idouble: 4 +ifloat: 4 +ildouble: 15 +ldouble: 15 + +Function: "lgamma_towardzero": +double: 4 +float: 3 +idouble: 4 +ifloat: 3 +ildouble: 16 +ldouble: 16 + +Function: "lgamma_upward": +double: 4 +float: 5 +idouble: 4 +ifloat: 5 +ildouble: 11 +ldouble: 11 + +Function: "log": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "log10": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 1 +ldouble: 1 + +Function: "log10_downward": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 +ildouble: 1 +ldouble: 1 + +Function: "log10_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "log10_upward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 1 +ldouble: 1 + +Function: "log1p": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "log1p_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "log1p_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: "log1p_upward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: "log2": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "log2_downward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 2 +ldouble: 2 + +Function: "log2_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 4 +ldouble: 4 + +Function: "log2_upward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 4 +ldouble: 4 + +Function: "log_downward": +float: 2 +ifloat: 2 +ildouble: 1 +ldouble: 1 + +Function: "log_towardzero": +float: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "log_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 1 +ldouble: 1 + +Function: "nextafter_downward": +ildouble: 1 +ldouble: 1 + +Function: "nextafter_upward": +ildouble: 1 +ldouble: 1 + +Function: "pow": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "pow10": +double: 2 +idouble: 2 +ildouble: 1 +ldouble: 1 + +Function: "pow10_downward": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +ildouble: 9 +ldouble: 9 + +Function: "pow10_towardzero": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +ildouble: 9 +ldouble: 9 + +Function: "pow10_upward": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +ildouble: 4 +ldouble: 4 + +Function: "pow_downward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "pow_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "pow_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "sin": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "sin_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 4 +ldouble: 4 + +Function: "sin_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 4 +ldouble: 4 + +Function: "sin_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 5 +ldouble: 5 + +Function: "sincos": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "sincos_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 4 +ldouble: 4 + +Function: "sincos_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 7 +ldouble: 7 + +Function: "sincos_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 7 +ldouble: 7 + +Function: "sinh": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: "sinh_downward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 6 +ldouble: 6 + +Function: "sinh_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 6 +ldouble: 6 + +Function: "sinh_upward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 6 +ldouble: 6 + +Function: "sqrt": +ildouble: 1 +ldouble: 1 + +Function: "sqrt_downward": +ildouble: 1 +ldouble: 1 + +Function: "sqrt_towardzero": +ildouble: 1 +ldouble: 1 + +Function: "sqrt_upward": +ildouble: 1 +ldouble: 1 + +Function: "tan": +float: 3 +ifloat: 3 +ildouble: 2 +ldouble: 2 + +Function: "tan_downward": +double: 1 +float: 3 +idouble: 1 +ifloat: 3 +ildouble: 3 +ldouble: 3 + +Function: "tan_towardzero": +double: 1 +float: 3 +idouble: 1 +ifloat: 3 +ildouble: 2 +ldouble: 2 + +Function: "tan_upward": +double: 1 +float: 3 +idouble: 1 +ifloat: 3 +ildouble: 3 +ldouble: 3 + +Function: "tanh": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 1 +ldouble: 1 + +Function: "tanh_downward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 4 +ldouble: 4 + +Function: "tanh_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 4 +ldouble: 4 + +Function: "tanh_upward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 6 +ldouble: 6 + +Function: "tgamma": +double: 5 +float: 4 +idouble: 5 +ifloat: 4 +ildouble: 5 +ldouble: 5 + +Function: "tgamma_downward": +double: 5 +float: 5 +idouble: 5 +ifloat: 5 +ildouble: 6 +ldouble: 6 + +Function: "tgamma_towardzero": +double: 5 +float: 4 +idouble: 5 +ifloat: 4 +ildouble: 5 +ldouble: 5 + +Function: "tgamma_upward": +double: 4 +float: 4 +idouble: 4 +ifloat: 4 +ildouble: 5 +ldouble: 5 + +Function: "y0": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "y0_downward": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 10 +ldouble: 10 + +Function: "y0_towardzero": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 8 +ldouble: 8 + +Function: "y0_upward": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 +ildouble: 9 +ldouble: 9 + +Function: "y1": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "y1_downward": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 7 +ldouble: 7 + +Function: "y1_towardzero": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 9 +ldouble: 9 + +Function: "y1_upward": +double: 5 +float: 2 +idouble: 5 +ifloat: 2 +ildouble: 9 +ldouble: 9 + +Function: "yn": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "yn_downward": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 10 +ldouble: 10 + +Function: "yn_towardzero": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 8 +ldouble: 8 + +Function: "yn_upward": +double: 4 +float: 3 +idouble: 4 +ifloat: 3 +ildouble: 9 +ldouble: 9 + +# end of automatic generation diff --git a/REORG.TODO/sysdeps/powerpc/fpu/libm-test-ulps-name b/REORG.TODO/sysdeps/powerpc/fpu/libm-test-ulps-name new file mode 100644 index 0000000000..8c5f7fa2ab --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/libm-test-ulps-name @@ -0,0 +1 @@ +PowerPC diff --git a/REORG.TODO/sysdeps/powerpc/fpu/math_ldbl.h b/REORG.TODO/sysdeps/powerpc/fpu/math_ldbl.h new file mode 100644 index 0000000000..05f51217bf --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/math_ldbl.h @@ -0,0 +1,55 @@ +/* Manipulation of the bit representation of 'long double' quantities. + Copyright (C) 2006-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _MATH_LDBL_H_PPC_ +#define _MATH_LDBL_H_PPC_ 1 + +/* GCC does not optimize the default ldbl_pack code to not spill register + in the stack. The following optimization tells gcc that pack/unpack + is really a nop. We use fr1/fr2 because those are the regs used to + pass/return a single long double arg. */ +static inline long double +ldbl_pack_ppc (double a, double aa) +{ + register long double x __asm__ ("fr1"); + register double xh __asm__ ("fr1"); + register double xl __asm__ ("fr2"); + xh = a; + xl = aa; + __asm__ ("" : "=f" (x) : "f" (xh), "f" (xl)); + return x; +} + +static inline void +ldbl_unpack_ppc (long double l, double *a, double *aa) +{ + register long double x __asm__ ("fr1"); + register double xh __asm__ ("fr1"); + register double xl __asm__ ("fr2"); + x = l; + __asm__ ("" : "=f" (xh), "=f" (xl) : "f" (x)); + *a = xh; + *aa = xl; +} + +#define ldbl_pack ldbl_pack_ppc +#define ldbl_unpack ldbl_unpack_ppc + +#include <sysdeps/ieee754/ldbl-128ibm/math_ldbl.h> + +#endif /* math_ldbl.h */ diff --git a/REORG.TODO/sysdeps/powerpc/fpu/math_private.h b/REORG.TODO/sysdeps/powerpc/fpu/math_private.h new file mode 100644 index 0000000000..3c71275392 --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/math_private.h @@ -0,0 +1,142 @@ +/* Private inline math functions for powerpc. + Copyright (C) 2006-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _PPC_MATH_PRIVATE_H_ +#define _PPC_MATH_PRIVATE_H_ + +#include <sysdep.h> +#include <ldsodefs.h> +#include <dl-procinfo.h> +#include <fenv_private.h> +#include_next <math_private.h> + +extern double __slow_ieee754_sqrt (double); +extern __always_inline double +__ieee754_sqrt (double __x) +{ + double __z; + +#ifdef _ARCH_PPCSQ + asm ("fsqrt %0,%1" : "=f" (__z) : "f" (__x)); +#else + __z = __slow_ieee754_sqrt(__x); +#endif + + return __z; +} + +extern float __slow_ieee754_sqrtf (float); +extern __always_inline float +__ieee754_sqrtf (float __x) +{ + float __z; + +#ifdef _ARCH_PPCSQ + asm ("fsqrts %0,%1" : "=f" (__z) : "f" (__x)); +#else + __z = __slow_ieee754_sqrtf(__x); +#endif + + return __z; +} + +#if defined _ARCH_PWR5X + +# ifndef __round +# define __round(x) \ + ({ double __z; \ + __asm __volatile ( \ + " frin %0,%1\n" \ + : "=f" (__z) \ + : "f" (x)); \ + __z; }) +# endif +# ifndef __roundf +# define __roundf(x) \ + ({ float __z; \ + __asm __volatile ( \ + " frin %0,%1\n" \ + " frsp %0,%0\n" \ + : "=f" (__z) \ + : "f" (x)); \ + __z; }) +# endif + +# ifndef __trunc +# define __trunc(x) \ + ({ double __z; \ + __asm __volatile ( \ + " friz %0,%1\n" \ + : "=f" (__z) \ + : "f" (x)); \ + __z; }) +# endif +# ifndef __truncf +# define __truncf(x) \ + ({ float __z; \ + __asm __volatile ( \ + " friz %0,%1\n" \ + " frsp %0,%0\n" \ + : "=f" (__z) \ + : "f" (x)); \ + __z; }) +# endif + +# ifndef __ceil +# define __ceil(x) \ + ({ double __z; \ + __asm __volatile ( \ + " frip %0,%1\n" \ + : "=f" (__z) \ + : "f" (x)); \ + __z; }) +# endif +# ifndef __ceilf +# define __ceilf(x) \ + ({ float __z; \ + __asm __volatile ( \ + " frip %0,%1\n" \ + " frsp %0,%0\n" \ + : "=f" (__z) \ + : "f" (x)); \ + __z; }) +# endif + +# ifndef __floor +# define __floor(x) \ + ({ double __z; \ + __asm __volatile ( \ + " frim %0,%1\n" \ + : "=f" (__z) \ + : "f" (x)); \ + __z; }) +# endif +# ifndef __floorf +# define __floorf(x) \ + ({ float __z; \ + __asm __volatile ( \ + " frim %0,%1\n" \ + " frsp %0,%0\n" \ + : "=f" (__z) \ + : "f" (x)); \ + __z; }) +# endif + +#endif /* defined _ARCH_PWR5X */ + +#endif /* _PPC_MATH_PRIVATE_H_ */ diff --git a/REORG.TODO/sysdeps/powerpc/fpu/s_cosf.c b/REORG.TODO/sysdeps/powerpc/fpu/s_cosf.c new file mode 100644 index 0000000000..772b138ac3 --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/s_cosf.c @@ -0,0 +1,69 @@ +/* s_cosf.c -- float version of s_cos.c. + Copyright (C) 2011-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Adhemerval Zanella <azanella@br.ibm.com>, 2011 + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If + not, see <http://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <math.h> +#include <math_private.h> + +static const float pio4 = 7.8539801e-1; + +float +__cosf (float x) +{ + float y[2], z = 0.0; + float ix; + int32_t n; + + ix = __builtin_fabsf (x); + + /* |x| ~< pi/4 */ + if (ix <= pio4) + { + return __kernel_cosf (x, z); + /* cos(Inf or NaN) is NaN */ + } + else if (isnanf (ix)) + { + return x - x; + } + else if (isinff (ix)) + { + __set_errno (EDOM); + return x - x; + } + + /* argument reduction needed */ + else + { + n = __ieee754_rem_pio2f (x, y); + switch (n & 3) + { + case 0: + return __kernel_cosf (y[0], y[1]); + case 1: + return -__kernel_sinf (y[0], y[1], 1); + case 2: + return -__kernel_cosf (y[0], y[1]); + default: + return __kernel_sinf (y[0], y[1], 1); + } + } +} + +weak_alias (__cosf, cosf) diff --git a/REORG.TODO/sysdeps/powerpc/fpu/s_fabs.S b/REORG.TODO/sysdeps/powerpc/fpu/s_fabs.S new file mode 100644 index 0000000000..87dc82eb28 --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/s_fabs.S @@ -0,0 +1,36 @@ +/* Floating-point absolute value. PowerPC version. + Copyright (C) 1997-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <sysdep.h> + +ENTRY(__fabs) +/* double [f1] fabs (double [f1] x); */ + fabs fp1,fp1 + blr +END(__fabs) + +weak_alias (__fabs,fabs) + +/* It turns out that it's safe to use this code even for single-precision. */ +strong_alias(__fabs,__fabsf) +weak_alias (__fabs,fabsf) + +#ifdef NO_LONG_DOUBLE +weak_alias (__fabs,__fabsl) +weak_alias (__fabs,fabsl) +#endif diff --git a/REORG.TODO/sysdeps/powerpc/fpu/s_fabsf.S b/REORG.TODO/sysdeps/powerpc/fpu/s_fabsf.S new file mode 100644 index 0000000000..877c710ce8 --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/s_fabsf.S @@ -0,0 +1 @@ +/* __fabsf is in s_fabs.S */ diff --git a/REORG.TODO/sysdeps/powerpc/fpu/s_float_bitwise.h b/REORG.TODO/sysdeps/powerpc/fpu/s_float_bitwise.h new file mode 100644 index 0000000000..8e63fb253b --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/s_float_bitwise.h @@ -0,0 +1,115 @@ +/* Bitwise manipulation over float. Function prototypes. + Copyright (C) 2011-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Adhemerval Zanella <azanella@br.ibm.com>, 2011 + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _FLOAT_BITWISE_ +#define _FLOAT_BITWISE_ 1 + +#include <math_private.h> + +/* Returns (int)(num & 0x7FFFFFF0 == value) */ +static inline int +__float_and_test28 (float num, float value) +{ + float ret; +#ifdef _ARCH_PWR7 + union { + int i; + float f; + } mask = { .i = 0x7ffffff0 }; + __asm__ ( + /* the 'f' constraint is used on mask because we just need + * to compare floats, not full vector */ + "xxland %x0,%x1,%x2" : "=f" (ret) : "f" (num), "f" (mask.f) + ); +#else + int32_t inum; + GET_FLOAT_WORD(inum, num); + inum = (inum & 0x7ffffff0); + SET_FLOAT_WORD(ret, inum); +#endif + return (ret == value); +} + +/* Returns (int)(num & 0x7FFFFF00 == value) */ +static inline int +__float_and_test24 (float num, float value) +{ + float ret; +#ifdef _ARCH_PWR7 + union { + int i; + float f; + } mask = { .i = 0x7fffff00 }; + __asm__ ( + "xxland %x0,%x1,%x2" : "=f" (ret) : "f" (num), "f" (mask.f) + ); +#else + int32_t inum; + GET_FLOAT_WORD(inum, num); + inum = (inum & 0x7fffff00); + SET_FLOAT_WORD(ret, inum); +#endif + return (ret == value); +} + +/* Returns (float)(num & 0x7F800000) */ +static inline float +__float_and8 (float num) +{ + float ret; +#ifdef _ARCH_PWR7 + union { + int i; + float f; + } mask = { .i = 0x7f800000 }; + __asm__ ( + "xxland %x0,%x1,%x2" : "=f" (ret) : "f" (num), "f" (mask.f) + ); +#else + int32_t inum; + GET_FLOAT_WORD(inum, num); + inum = (inum & 0x7f800000); + SET_FLOAT_WORD(ret, inum); +#endif + return ret; +} + +/* Returns ((int32_t)(num & 0x7F800000) >> 23) */ +static inline int32_t +__float_get_exp (float num) +{ + int32_t inum; +#ifdef _ARCH_PWR7 + float ret; + union { + int i; + float f; + } mask = { .i = 0x7f800000 }; + __asm__ ( + "xxland %x0,%x1,%x2" : "=f" (ret) : "f" (num), "f" (mask.f) + ); + GET_FLOAT_WORD(inum, ret); +#else + GET_FLOAT_WORD(inum, num); + inum = inum & 0x7f800000; +#endif + return inum >> 23; +} + +#endif /* s_float_bitwise.h */ diff --git a/REORG.TODO/sysdeps/powerpc/fpu/s_fma.S b/REORG.TODO/sysdeps/powerpc/fpu/s_fma.S new file mode 100644 index 0000000000..e101f374bf --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/s_fma.S @@ -0,0 +1,32 @@ +/* Compute x * y + z as ternary operation. PowerPC version. + Copyright (C) 2010-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <sysdep.h> + +ENTRY(__fma) +/* double [f1] fma (double [f1] x, double [f2] y, double [f3] z); */ + fmadd fp1,fp1,fp2,fp3 + blr +END(__fma) + +weak_alias (__fma,fma) + +#ifdef NO_LONG_DOUBLE +weak_alias (__fma,__fmal) +weak_alias (__fma,fmal) +#endif diff --git a/REORG.TODO/sysdeps/powerpc/fpu/s_fmaf.S b/REORG.TODO/sysdeps/powerpc/fpu/s_fmaf.S new file mode 100644 index 0000000000..49ea298707 --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/s_fmaf.S @@ -0,0 +1,27 @@ +/* Compute x * y + z as ternary operation. PowerPC version. + Copyright (C) 2010-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <sysdep.h> + +ENTRY(__fmaf) +/* float [f1] fmaf (float [f1] x, float [f2] y, float [f3] z); */ + fmadds fp1,fp1,fp2,fp3 + blr +END(__fmaf) + +weak_alias (__fmaf,fmaf) diff --git a/REORG.TODO/sysdeps/powerpc/fpu/s_isnan.c b/REORG.TODO/sysdeps/powerpc/fpu/s_isnan.c new file mode 100644 index 0000000000..f75391fa80 --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/s_isnan.c @@ -0,0 +1,62 @@ +/* Return 1 if argument is a NaN, else 0. + Copyright (C) 1997-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +/* Ugly kludge to avoid declarations. */ +#define __isnanf __Xisnanf +#define isnanf Xisnanf +#define __GI___isnanf __GI___Xisnanf + +#include <math.h> +#include <math_ldbl_opt.h> +#include <fenv_libc.h> + +#undef __isnanf +#undef isnanf +#undef __GI___isnanf + + +/* The hidden_proto in include/math.h was obscured by the macro hackery. */ +__typeof (__isnan) __isnanf; +hidden_proto (__isnanf) + + +int +__isnan (double x) +{ + fenv_t savedstate; + int result; + savedstate = fegetenv_register (); + reset_fpscr_bit (FPSCR_VE); + result = !(x == x); + fesetenv_register (savedstate); + return result; +} +hidden_def (__isnan) +weak_alias (__isnan, isnan) + + +/* It turns out that the 'double' version will also always work for + single-precision. */ +strong_alias (__isnan, __isnanf) +hidden_def (__isnanf) +weak_alias (__isnanf, isnanf) + +#ifdef NO_LONG_DOUBLE +strong_alias (__isnan, __isnanl) +weak_alias (__isnan, isnanl) +#endif diff --git a/REORG.TODO/sysdeps/powerpc/fpu/s_isnanf.S b/REORG.TODO/sysdeps/powerpc/fpu/s_isnanf.S new file mode 100644 index 0000000000..fc22f678a1 --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/s_isnanf.S @@ -0,0 +1 @@ +/* __isnanf is in s_isnan.c */ diff --git a/REORG.TODO/sysdeps/powerpc/fpu/s_lrintf.S b/REORG.TODO/sysdeps/powerpc/fpu/s_lrintf.S new file mode 100644 index 0000000000..e24766535f --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/s_lrintf.S @@ -0,0 +1 @@ +/* __lrintf is in s_lrint.c */ diff --git a/REORG.TODO/sysdeps/powerpc/fpu/s_rint.c b/REORG.TODO/sysdeps/powerpc/fpu/s_rint.c new file mode 100644 index 0000000000..a96140b2c9 --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/s_rint.c @@ -0,0 +1,46 @@ +/* Round a 64-bit floating point value to the nearest integer. + Copyright (C) 1997-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <math.h> + +double +__rint (double x) +{ + static const float TWO52 = 4503599627370496.0; + + if (fabs (x) < TWO52) + { + if (x > 0.0) + { + x += TWO52; + x -= TWO52; + } + else if (x < 0.0) + { + x = TWO52 - x; + x = -(x - TWO52); + } + } + + return x; +} +weak_alias (__rint, rint) +#ifdef NO_LONG_DOUBLE +strong_alias (__rint, __rintl) +weak_alias (__rint, rintl) +#endif diff --git a/REORG.TODO/sysdeps/powerpc/fpu/s_rintf.c b/REORG.TODO/sysdeps/powerpc/fpu/s_rintf.c new file mode 100644 index 0000000000..6b16c7bec4 --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/s_rintf.c @@ -0,0 +1,42 @@ +/* Round a 32-bit floating point value to the nearest integer. + Copyright (C) 1997-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <math.h> + +float +__rintf (float x) +{ + static const float TWO23 = 8388608.0; + + if (fabsf (x) < TWO23) + { + if (x > 0.0) + { + x += TWO23; + x -= TWO23; + } + else if (x < 0.0) + { + x = TWO23 - x; + x = -(x - TWO23); + } + } + + return x; +} +weak_alias (__rintf, rintf) diff --git a/REORG.TODO/sysdeps/powerpc/fpu/s_sinf.c b/REORG.TODO/sysdeps/powerpc/fpu/s_sinf.c new file mode 100644 index 0000000000..54a428e68a --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/s_sinf.c @@ -0,0 +1,69 @@ +/* s_sinf.c -- float version of s_sin.c. + Copyright (C) 2011-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Adhemerval Zanella <azanella@br.ibm.com>, 2011 + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If + not, see <http://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <math.h> +#include <math_private.h> + +static const float pio4 = 7.8539801e-1; + +float +__sinf (float x) +{ + float y[2], z = 0.0; + float ix; + int32_t n; + + ix = __builtin_fabsf (x); + + /* |x| ~< pi/4 */ + if (ix <= pio4) + { + return __kernel_sinf (x, z, 0); + /* sin(Inf or NaN) is NaN */ + } + else if (isnanf (ix)) + { + return x - x; + } + else if (isinff (ix)) + { + __set_errno (EDOM); + return x - x; + } + + /* argument reduction needed */ + else + { + n = __ieee754_rem_pio2f (x, y); + switch (n & 3) + { + case 0: + return __kernel_sinf (y[0], y[1], 1); + case 1: + return __kernel_cosf (y[0], y[1]); + case 2: + return -__kernel_sinf (y[0], y[1], 1); + default: + return -__kernel_cosf (y[0], y[1]); + } + } +} + +weak_alias (__sinf, sinf) diff --git a/REORG.TODO/sysdeps/powerpc/fpu/t_sqrt.c b/REORG.TODO/sysdeps/powerpc/fpu/t_sqrt.c new file mode 100644 index 0000000000..9ed7436ae6 --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/t_sqrt.c @@ -0,0 +1,144 @@ +const float __t_sqrt[1024] = { +0.7078,0.7064, 0.7092,0.7050, 0.7106,0.7037, 0.7119,0.7023, 0.7133,0.7010, +0.7147,0.6996, 0.7160,0.6983, 0.7174,0.6970, 0.7187,0.6957, 0.7201,0.6943, +0.7215,0.6930, 0.7228,0.6917, 0.7242,0.6905, 0.7255,0.6892, 0.7269,0.6879, +0.7282,0.6866, 0.7295,0.6854, 0.7309,0.6841, 0.7322,0.6829, 0.7335,0.6816, +0.7349,0.6804, 0.7362,0.6792, 0.7375,0.6779, 0.7388,0.6767, 0.7402,0.6755, +0.7415,0.6743, 0.7428,0.6731, 0.7441,0.6719, 0.7454,0.6708, 0.7467,0.6696, +0.7480,0.6684, 0.7493,0.6672, 0.7507,0.6661, 0.7520,0.6649, 0.7532,0.6638, +0.7545,0.6627, 0.7558,0.6615, 0.7571,0.6604, 0.7584,0.6593, 0.7597,0.6582, +0.7610,0.6570, 0.7623,0.6559, 0.7635,0.6548, 0.7648,0.6537, 0.7661,0.6527, +0.7674,0.6516, 0.7686,0.6505, 0.7699,0.6494, 0.7712,0.6484, 0.7725,0.6473, +0.7737,0.6462, 0.7750,0.6452, 0.7762,0.6441, 0.7775,0.6431, 0.7787,0.6421, +0.7800,0.6410, 0.7812,0.6400, 0.7825,0.6390, 0.7837,0.6380, 0.7850,0.6370, +0.7862,0.6359, 0.7875,0.6349, 0.7887,0.6339, 0.7900,0.6330, 0.7912,0.6320, +0.7924,0.6310, 0.7937,0.6300, 0.7949,0.6290, 0.7961,0.6281, 0.7973,0.6271, +0.7986,0.6261, 0.7998,0.6252, 0.8010,0.6242, 0.8022,0.6233, 0.8034,0.6223, +0.8046,0.6214, 0.8059,0.6205, 0.8071,0.6195, 0.8083,0.6186, 0.8095,0.6177, +0.8107,0.6168, 0.8119,0.6158, 0.8131,0.6149, 0.8143,0.6140, 0.8155,0.6131, +0.8167,0.6122, 0.8179,0.6113, 0.8191,0.6104, 0.8203,0.6096, 0.8215,0.6087, +0.8227,0.6078, 0.8238,0.6069, 0.8250,0.6060, 0.8262,0.6052, 0.8274,0.6043, +0.8286,0.6035, 0.8297,0.6026, 0.8309,0.6017, 0.8321,0.6009, 0.8333,0.6000, +0.8344,0.5992, 0.8356,0.5984, 0.8368,0.5975, 0.8379,0.5967, 0.8391,0.5959, +0.8403,0.5950, 0.8414,0.5942, 0.8426,0.5934, 0.8437,0.5926, 0.8449,0.5918, +0.8461,0.5910, 0.8472,0.5902, 0.8484,0.5894, 0.8495,0.5886, 0.8507,0.5878, +0.8518,0.5870, 0.8530,0.5862, 0.8541,0.5854, 0.8552,0.5846, 0.8564,0.5838, +0.8575,0.5831, 0.8587,0.5823, 0.8598,0.5815, 0.8609,0.5808, 0.8621,0.5800, +0.8632,0.5792, 0.8643,0.5785, 0.8655,0.5777, 0.8666,0.5770, 0.8677,0.5762, +0.8688,0.5755, 0.8700,0.5747, 0.8711,0.5740, 0.8722,0.5733, 0.8733,0.5725, +0.8744,0.5718, 0.8756,0.5711, 0.8767,0.5703, 0.8778,0.5696, 0.8789,0.5689, +0.8800,0.5682, 0.8811,0.5675, 0.8822,0.5667, 0.8833,0.5660, 0.8844,0.5653, +0.8855,0.5646, 0.8866,0.5639, 0.8877,0.5632, 0.8888,0.5625, 0.8899,0.5618, +0.8910,0.5611, 0.8921,0.5605, 0.8932,0.5598, 0.8943,0.5591, 0.8954,0.5584, +0.8965,0.5577, 0.8976,0.5570, 0.8987,0.5564, 0.8998,0.5557, 0.9008,0.5550, +0.9019,0.5544, 0.9030,0.5537, 0.9041,0.5530, 0.9052,0.5524, 0.9062,0.5517, +0.9073,0.5511, 0.9084,0.5504, 0.9095,0.5498, 0.9105,0.5491, 0.9116,0.5485, +0.9127,0.5478, 0.9138,0.5472, 0.9148,0.5465, 0.9159,0.5459, 0.9170,0.5453, +0.9180,0.5446, 0.9191,0.5440, 0.9202,0.5434, 0.9212,0.5428, 0.9223,0.5421, +0.9233,0.5415, 0.9244,0.5409, 0.9254,0.5403, 0.9265,0.5397, 0.9276,0.5391, +0.9286,0.5384, 0.9297,0.5378, 0.9307,0.5372, 0.9318,0.5366, 0.9328,0.5360, +0.9338,0.5354, 0.9349,0.5348, 0.9359,0.5342, 0.9370,0.5336, 0.9380,0.5330, +0.9391,0.5324, 0.9401,0.5319, 0.9411,0.5313, 0.9422,0.5307, 0.9432,0.5301, +0.9442,0.5295, 0.9453,0.5289, 0.9463,0.5284, 0.9473,0.5278, 0.9484,0.5272, +0.9494,0.5266, 0.9504,0.5261, 0.9515,0.5255, 0.9525,0.5249, 0.9535,0.5244, +0.9545,0.5238, 0.9556,0.5233, 0.9566,0.5227, 0.9576,0.5221, 0.9586,0.5216, +0.9596,0.5210, 0.9607,0.5205, 0.9617,0.5199, 0.9627,0.5194, 0.9637,0.5188, +0.9647,0.5183, 0.9657,0.5177, 0.9667,0.5172, 0.9677,0.5167, 0.9687,0.5161, +0.9698,0.5156, 0.9708,0.5151, 0.9718,0.5145, 0.9728,0.5140, 0.9738,0.5135, +0.9748,0.5129, 0.9758,0.5124, 0.9768,0.5119, 0.9778,0.5114, 0.9788,0.5108, +0.9798,0.5103, 0.9808,0.5098, 0.9818,0.5093, 0.9828,0.5088, 0.9838,0.5083, +0.9847,0.5077, 0.9857,0.5072, 0.9867,0.5067, 0.9877,0.5062, 0.9887,0.5057, +0.9897,0.5052, 0.9907,0.5047, 0.9917,0.5042, 0.9926,0.5037, 0.9936,0.5032, +0.9946,0.5027, 0.9956,0.5022, 0.9966,0.5017, 0.9976,0.5012, 0.9985,0.5007, +0.9995,0.5002, +1.0010,0.4995, 1.0029,0.4985, 1.0049,0.4976, 1.0068,0.4966, 1.0088,0.4957, +1.0107,0.4947, 1.0126,0.4938, 1.0145,0.4928, 1.0165,0.4919, 1.0184,0.4910, +1.0203,0.4901, 1.0222,0.4891, 1.0241,0.4882, 1.0260,0.4873, 1.0279,0.4864, +1.0298,0.4855, 1.0317,0.4846, 1.0336,0.4837, 1.0355,0.4829, 1.0374,0.4820, +1.0393,0.4811, 1.0411,0.4802, 1.0430,0.4794, 1.0449,0.4785, 1.0468,0.4777, +1.0486,0.4768, 1.0505,0.4760, 1.0523,0.4751, 1.0542,0.4743, 1.0560,0.4735, +1.0579,0.4726, 1.0597,0.4718, 1.0616,0.4710, 1.0634,0.4702, 1.0653,0.4694, +1.0671,0.4686, 1.0689,0.4678, 1.0707,0.4670, 1.0726,0.4662, 1.0744,0.4654, +1.0762,0.4646, 1.0780,0.4638, 1.0798,0.4630, 1.0816,0.4623, 1.0834,0.4615, +1.0852,0.4607, 1.0870,0.4600, 1.0888,0.4592, 1.0906,0.4585, 1.0924,0.4577, +1.0942,0.4570, 1.0960,0.4562, 1.0978,0.4555, 1.0995,0.4547, 1.1013,0.4540, +1.1031,0.4533, 1.1049,0.4525, 1.1066,0.4518, 1.1084,0.4511, 1.1101,0.4504, +1.1119,0.4497, 1.1137,0.4490, 1.1154,0.4483, 1.1172,0.4476, 1.1189,0.4469, +1.1207,0.4462, 1.1224,0.4455, 1.1241,0.4448, 1.1259,0.4441, 1.1276,0.4434, +1.1293,0.4427, 1.1311,0.4421, 1.1328,0.4414, 1.1345,0.4407, 1.1362,0.4401, +1.1379,0.4394, 1.1397,0.4387, 1.1414,0.4381, 1.1431,0.4374, 1.1448,0.4368, +1.1465,0.4361, 1.1482,0.4355, 1.1499,0.4348, 1.1516,0.4342, 1.1533,0.4335, +1.1550,0.4329, 1.1567,0.4323, 1.1584,0.4316, 1.1600,0.4310, 1.1617,0.4304, +1.1634,0.4298, 1.1651,0.4292, 1.1668,0.4285, 1.1684,0.4279, 1.1701,0.4273, +1.1718,0.4267, 1.1734,0.4261, 1.1751,0.4255, 1.1768,0.4249, 1.1784,0.4243, +1.1801,0.4237, 1.1817,0.4231, 1.1834,0.4225, 1.1850,0.4219, 1.1867,0.4213, +1.1883,0.4208, 1.1900,0.4202, 1.1916,0.4196, 1.1932,0.4190, 1.1949,0.4185, +1.1965,0.4179, 1.1981,0.4173, 1.1998,0.4167, 1.2014,0.4162, 1.2030,0.4156, +1.2046,0.4151, 1.2063,0.4145, 1.2079,0.4139, 1.2095,0.4134, 1.2111,0.4128, +1.2127,0.4123, 1.2143,0.4117, 1.2159,0.4112, 1.2175,0.4107, 1.2192,0.4101, +1.2208,0.4096, 1.2224,0.4090, 1.2239,0.4085, 1.2255,0.4080, 1.2271,0.4075, +1.2287,0.4069, 1.2303,0.4064, 1.2319,0.4059, 1.2335,0.4054, 1.2351,0.4048, +1.2366,0.4043, 1.2382,0.4038, 1.2398,0.4033, 1.2414,0.4028, 1.2429,0.4023, +1.2445,0.4018, 1.2461,0.4013, 1.2477,0.4008, 1.2492,0.4003, 1.2508,0.3998, +1.2523,0.3993, 1.2539,0.3988, 1.2555,0.3983, 1.2570,0.3978, 1.2586,0.3973, +1.2601,0.3968, 1.2617,0.3963, 1.2632,0.3958, 1.2648,0.3953, 1.2663,0.3949, +1.2678,0.3944, 1.2694,0.3939, 1.2709,0.3934, 1.2725,0.3929, 1.2740,0.3925, +1.2755,0.3920, 1.2771,0.3915, 1.2786,0.3911, 1.2801,0.3906, 1.2816,0.3901, +1.2832,0.3897, 1.2847,0.3892, 1.2862,0.3887, 1.2877,0.3883, 1.2892,0.3878, +1.2907,0.3874, 1.2923,0.3869, 1.2938,0.3865, 1.2953,0.3860, 1.2968,0.3856, +1.2983,0.3851, 1.2998,0.3847, 1.3013,0.3842, 1.3028,0.3838, 1.3043,0.3834, +1.3058,0.3829, 1.3073,0.3825, 1.3088,0.3820, 1.3103,0.3816, 1.3118,0.3812, +1.3132,0.3807, 1.3147,0.3803, 1.3162,0.3799, 1.3177,0.3794, 1.3192,0.3790, +1.3207,0.3786, 1.3221,0.3782, 1.3236,0.3778, 1.3251,0.3773, 1.3266,0.3769, +1.3280,0.3765, 1.3295,0.3761, 1.3310,0.3757, 1.3324,0.3753, 1.3339,0.3748, +1.3354,0.3744, 1.3368,0.3740, 1.3383,0.3736, 1.3397,0.3732, 1.3412,0.3728, +1.3427,0.3724, 1.3441,0.3720, 1.3456,0.3716, 1.3470,0.3712, 1.3485,0.3708, +1.3499,0.3704, 1.3514,0.3700, 1.3528,0.3696, 1.3542,0.3692, 1.3557,0.3688, +1.3571,0.3684, 1.3586,0.3680, 1.3600,0.3676, 1.3614,0.3673, 1.3629,0.3669, +1.3643,0.3665, 1.3657,0.3661, 1.3672,0.3657, 1.3686,0.3653, 1.3700,0.3650, +1.3714,0.3646, 1.3729,0.3642, 1.3743,0.3638, 1.3757,0.3634, 1.3771,0.3631, +1.3785,0.3627, 1.3800,0.3623, 1.3814,0.3620, 1.3828,0.3616, 1.3842,0.3612, +1.3856,0.3609, 1.3870,0.3605, 1.3884,0.3601, 1.3898,0.3598, 1.3912,0.3594, +1.3926,0.3590, 1.3940,0.3587, 1.3954,0.3583, 1.3968,0.3580, 1.3982,0.3576, +1.3996,0.3572, 1.4010,0.3569, 1.4024,0.3565, 1.4038,0.3562, 1.4052,0.3558, +1.4066,0.3555, 1.4080,0.3551, 1.4094,0.3548, 1.4108,0.3544, 1.4121,0.3541, +1.4135,0.3537 +}; + + +/* Generated by: */ +#if 0 +#include <math.h> +#include <stdio.h> +#include <assert.h> + +int +main(int argc, char **argv) +{ + int i, j; + + printf ("const float __t_sqrt[1024] = {"); + for (i = 0; i < 2; i++) + { + putchar('\n'); + for (j = 0; j < 256; j++) + { + double mval = j/512.0 + 0.5; + double eval = i==0 ? 1.0 : 2.0; + double ls = sqrt(mval*eval); + double hs = sqrt((mval+1/512.0)*eval); + double as = (ls+hs)*0.5; + double lx = 1/(2.0*ls); + double hx = 1/(2.0*hs); + double ax = (lx+hx)*0.5; + + printf("%.4f,%.4f%s",as,ax, + i*j==255 ? "\n" : j % 5 == 4 ? ",\n" : ", "); + assert((hs-ls)/as < 1/256.0); + assert((hx-lx)/ax < 1/256.0); + } + } + printf ("};\n"); + return 0; +} +#endif /* 0 */ diff --git a/REORG.TODO/sysdeps/powerpc/fpu/tst-setcontext-fpscr.c b/REORG.TODO/sysdeps/powerpc/fpu/tst-setcontext-fpscr.c new file mode 100644 index 0000000000..4e3f90d4d3 --- /dev/null +++ b/REORG.TODO/sysdeps/powerpc/fpu/tst-setcontext-fpscr.c @@ -0,0 +1,370 @@ +/* Copyright (C) 2001-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ryan S. Arnold <rsa@us.ibm.com> + Sean Curry <spcurry@us.ibm.com> + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ucontext.h> +#include <unistd.h> +#include <malloc.h> +#include <link.h> +#include <elf.h> +#include <fpu_control.h> +#include <sys/auxv.h> + +static ucontext_t ctx[3]; + + +volatile int global; + + +static int back_in_main; + + +volatile static ElfW(auxv_t) *auxv = NULL; + +ElfW(Addr) query_auxv(int type) +{ + FILE *auxv_f; + ElfW(auxv_t) auxv_struct; + ElfW(auxv_t) *auxv_temp; + int i = 0; + + /* if the /proc/self/auxv file has not been manually copied into the heap + yet, then do it */ + + if(auxv == NULL) + { + auxv_f = fopen("/proc/self/auxv", "r"); + + if(auxv_f == 0) + { + perror("Error opening file for reading"); + return 0; + } + auxv = (ElfW(auxv_t) *)malloc(getpagesize()); + + do + { + fread(&auxv_struct, sizeof(ElfW(auxv_t)), 1, auxv_f); + auxv[i] = auxv_struct; + i++; + } while(auxv_struct.a_type != AT_NULL); + } + + auxv_temp = (ElfW(auxv_t) *)auxv; + i = 0; + do + { + if(auxv_temp[i].a_type == type) + { + return auxv_temp[i].a_un.a_val; + } + i++; + } while (auxv_temp[i].a_type != AT_NULL); + + return 0; +} + +typedef unsigned int di_fpscr_t __attribute__ ((__mode__ (__DI__))); +typedef unsigned int si_fpscr_t __attribute__ ((__mode__ (__SI__))); + +#define _FPSCR_RESERVED 0xfffffff8ffffff04ULL + +#define _FPSCR_TEST0_DRN 0x0000000400000000ULL +#define _FPSCR_TEST0_RN 0x0000000000000003ULL + +#define _FPSCR_TEST1_DRN 0x0000000300000000ULL +#define _FPSCR_TEST1_RN 0x0000000000000002ULL + +/* Macros for accessing the hardware control word on Power6[x]. */ +#define _GET_DI_FPSCR(__fpscr) \ + ({union { double d; di_fpscr_t fpscr; } u; \ + register double fr; \ + __asm__ ("mffs %0" : "=f" (fr)); \ + u.d = fr; \ + (__fpscr) = u.fpscr; \ + u.fpscr; \ + }) + +/* We make sure to zero fp after we use it in order to prevent stale data + in an fp register from making a test-case pass erroneously. */ +# define _SET_DI_FPSCR(__fpscr) \ + { union { double d; di_fpscr_t fpscr; } u; \ + register double fr; \ + u.fpscr = __fpscr; \ + fr = u.d; \ + /* Set the entire 64-bit FPSCR. */ \ + __asm__ (".machine push; " \ + ".machine \"power6\"; " \ + "mtfsf 255,%0,1,0; " \ + ".machine pop" : : "f" (fr)); \ + fr = 0.0; \ + } + +# define _GET_SI_FPSCR(__fpscr) \ + ({union { double d; di_fpscr_t fpscr; } u; \ + register double fr; \ + __asm__ ("mffs %0" : "=f" (fr)); \ + u.d = fr; \ + (__fpscr) = (si_fpscr_t) u.fpscr; \ + (si_fpscr_t) u.fpscr; \ + }) + +/* We make sure to zero fp after we use it in order to prevent stale data + in an fp register from making a test-case pass erroneously. */ +# define _SET_SI_FPSCR(__fpscr) \ + { union { double d; di_fpscr_t fpscr; } u; \ + register double fr; \ + /* More-or-less arbitrary; this is a QNaN. */ \ + u.fpscr = 0xfff80000ULL << 32; \ + u.fpscr |= __fpscr & 0xffffffffULL; \ + fr = u.d; \ + __asm__ ("mtfsf 255,%0" : : "f" (fr)); \ + fr = 0.0; \ + } + +void prime_special_regs(int which) +{ + ElfW(Addr) a_val; + + di_fpscr_t di_fpscr __attribute__ ((__aligned__(8))); + + a_val = query_auxv(AT_HWCAP); + if(a_val == -1) + { + puts ("querying the auxv for the hwcap failed"); + _exit (1); + } + + /* Indicates a 64-bit FPSCR. */ + if (a_val & PPC_FEATURE_HAS_DFP) + { + _GET_DI_FPSCR(di_fpscr); + + /* Overwrite the existing DRN and RN if there is one. */ + if (which == 0) + di_fpscr = ((di_fpscr & _FPSCR_RESERVED) | (_FPSCR_TEST0_DRN | _FPSCR_TEST0_RN)); + else + di_fpscr = ((di_fpscr & _FPSCR_RESERVED) | (_FPSCR_TEST1_DRN | _FPSCR_TEST1_RN)); + puts ("Priming 64-bit FPSCR with:"); + printf("0x%.16llx\n",(unsigned long long int)di_fpscr); + + _SET_DI_FPSCR(di_fpscr); + } + else + { + puts ("32-bit FPSCR found and will be tested."); + _GET_SI_FPSCR(di_fpscr); + + /* Overwrite the existing RN if there is one. */ + if (which == 0) + di_fpscr = ((di_fpscr & _FPSCR_RESERVED) | (_FPSCR_TEST0_RN)); + else + di_fpscr = ((di_fpscr & _FPSCR_RESERVED) | (_FPSCR_TEST1_RN)); + puts ("Priming 32-bit FPSCR with:"); + printf("0x%.8lx\n",(unsigned long int) di_fpscr); + + _SET_SI_FPSCR(di_fpscr); + } +} + +void clear_special_regs(void) +{ + ElfW(Addr) a_val; + + di_fpscr_t di_fpscr __attribute__ ((__aligned__(8))); + + union { + double d; + unsigned long long int lli; + unsigned int li[2]; + } dlli; + + a_val = query_auxv(AT_HWCAP); + if(a_val == -1) + { + puts ("querying the auxv for the hwcap failed"); + _exit (1); + } + +#if __WORDSIZE == 32 + dlli.d = ctx[0].uc_mcontext.uc_regs->fpregs.fpscr; +#else + dlli.d = ctx[0].uc_mcontext.fp_regs[32]; +#endif + + puts("The FPSCR value saved in the ucontext_t is:"); + + /* Indicates a 64-bit FPSCR. */ + if (a_val & PPC_FEATURE_HAS_DFP) + { + printf("0x%.16llx\n",dlli.lli); + di_fpscr = 0x0; + puts ("Clearing the 64-bit FPSCR to:"); + printf("0x%.16llx\n",(unsigned long long int) di_fpscr); + + _SET_DI_FPSCR(di_fpscr); + } + else + { + printf("0x%.8x\n",(unsigned int) dlli.li[1]); + di_fpscr = 0x0; + puts ("Clearing the 32-bit FPSCR to:"); + printf("0x%.8lx\n",(unsigned long int) di_fpscr); + + _SET_SI_FPSCR(di_fpscr); + } +} + +void test_special_regs(int which) +{ + ElfW(Addr) a_val; + unsigned long long int test; + + di_fpscr_t di_fpscr __attribute__ ((__aligned__(8))); + + a_val = query_auxv(AT_HWCAP); + if(a_val == -1) + { + puts ("querying the auxv for the hwcap failed"); + _exit (2); + } + + /* Indicates a 64-bit FPSCR. */ + if (a_val & PPC_FEATURE_HAS_DFP) + { + _GET_DI_FPSCR(di_fpscr); + + if (which == 0) + puts ("After setcontext the 64-bit FPSCR contains:"); + else + puts ("After swapcontext the 64-bit FPSCR contains:"); + + printf("0x%.16llx\n",(unsigned long long int) di_fpscr); + test = (_FPSCR_TEST0_DRN | _FPSCR_TEST0_RN); + if((di_fpscr & (test)) != (test)) + { + printf ("%s: DRN and RN bits set before getcontext were not preserved across [set|swap]context call: %m",__FUNCTION__); + _exit (3); + } + } + else + { + _GET_SI_FPSCR(di_fpscr); + if (which == 0) + puts ("After setcontext the 32-bit FPSCR contains:"); + else + puts ("After swapcontext the 32-bit FPSCR contains:"); + + printf("0x%.8lx\n",(unsigned long int) di_fpscr); + test = _FPSCR_TEST0_RN; + if((di_fpscr & test) != test) + { + printf ("%s: RN bit set before getcontext was not preserved across [set|swap]context call: %m",__FUNCTION__); + _exit (4); + } + } +} + + +static void +check_called (void) +{ + if (back_in_main == 0) + { + puts ("program did not reach main again"); + _exit (5); + } +} + + +int +main (void) +{ + atexit (check_called); + + puts ("priming the FPSCR with a marker"); + prime_special_regs (0); + + puts ("making contexts"); + if (getcontext (&ctx[0]) != 0) + { + if (errno == ENOSYS) + { + back_in_main = 1; + exit (0); + } + + printf ("%s: getcontext: %m\n", __FUNCTION__); + exit (6); + } + + /* Play some tricks with this context. */ + if (++global == 1) + { + clear_special_regs ( ); + if (setcontext (&ctx[0]) != 0) + { + printf ("%s: setcontext: %m\n", __FUNCTION__); + exit (7); + } + } + if (global != 2) + { + printf ("%s: 'global' not incremented twice\n", __FUNCTION__); + exit (8); + } + + test_special_regs (0); + + global = 0; + if (getcontext (&ctx[0]) != 0) + { + printf ("%s: getcontext: %m\n", __FUNCTION__); + exit (9); + } + + if (++global == 1) + { + puts ("priming the FPSCR with a marker"); + prime_special_regs (1); + + puts ("swapping contexts"); + if (swapcontext (&ctx[1], &ctx[0]) != 0) + { + printf ("%s: swapcontext: %m\n", __FUNCTION__); + exit (9); + } + } + if (global != 2) + { + printf ("%s: 'global' not incremented twice\n", __FUNCTION__); + exit (10); + } + + test_special_regs (1); + + puts ("back at main program"); + back_in_main = 1; + + puts ("test succeeded"); + return 0; +} |