This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: e500 port: the port itself
- From: Adhemerval Zanella <azanella at linux dot vnet dot ibm dot com>
- To: "Joseph S. Myers" <joseph at codesourcery dot com>, libc-alpha at sourceware dot org
- Date: Fri, 18 Oct 2013 14:35:59 -0300
- Subject: Re: e500 port: the port itself
- Authentication-results: sourceware.org; auth=none
- References: <Pine dot LNX dot 4 dot 64 dot 1310042321150 dot 27874 at digraph dot polyomino dot org dot uk> <Pine dot LNX dot 4 dot 64 dot 1310102055470 dot 11458 at digraph dot polyomino dot org dot uk>
Hi Joseph, thanks for the patch. As you suggested, I'll focus the review
in the non-e500 specific parts. Aside to the Copysights nits, the patch
looks ok. Any reason in particular to the missing copysignl PLT?
copysignl
On 10-10-2013 17:57, Joseph S. Myers wrote:
> This version of the port is updated to define FP_INIT_EXCEPTIONS as
> well as FP_INIT_ROUNDMODE. It also has some refinements to the code
> ensuring the kernel can know about changes to the set of sticky
> exceptions, so as to fix some more spurious and missing exceptions.
> The associated set of pending kernel patches to improve test results
> with this port is <http://lkml.org/lkml/2013/10/4/495>,
> <http://lkml.org/lkml/2013/10/4/497>,
> <http://lkml.org/lkml/2013/10/8/694>,
> <http://lkml.org/lkml/2013/10/8/700>,
> <http://lkml.org/lkml/2013/10/8/705> and
> <http://lkml.org/lkml/2013/10/10/626>.
>
> I believe the remaining libm test failures, where not generic to
> powerpc, arise from processor errata. There's a documented erratum
> for e500v1 that some instructions producing a result of zero may
> produce it with an incorrect sign, and empirically this seems to be
> happening for float (but not double) operations on e500v2 as well. At
> least for conversions from double to float as used in fmaf, the
> processor does not appear to properly implement the before-rounding
> tininess detection specified by the architecture (that is, if the
> infinite-precision float result is smaller in magnitude than the least
> positive normal, but the result of rounding has magnitude equal to the
> last positive normal, then the underflow exception is not raised, and
> so the trap handlers have no chance to correct for this).
>
> 2013-10-10 Joseph Myers <joseph@codesourcery.com>
> Aldy Hernandez <aldyh@redhat.com>
>
> * sysdeps/powerpc/powerpc32/e500/nofpu/Makefile: New file.
> * sysdeps/powerpc/powerpc32/e500/nofpu/fclrexcpt.c: Likewise.
> * sysdeps/powerpc/powerpc32/e500/nofpu/fe_note_change.c: Likewise.
> * sysdeps/powerpc/powerpc32/e500/nofpu/fedisblxcpt.c: Likewise.
> * sysdeps/powerpc/powerpc32/e500/nofpu/feenablxcpt.c: Likewise.
> * sysdeps/powerpc/powerpc32/e500/nofpu/fegetenv.c: Likewise.
> * sysdeps/powerpc/powerpc32/e500/nofpu/fegetexcept.c: Likewise.
> * sysdeps/powerpc/powerpc32/e500/nofpu/fegetround.c: Likewise.
> * sysdeps/powerpc/powerpc32/e500/nofpu/feholdexcpt.c: Likewise.
> * sysdeps/powerpc/powerpc32/e500/nofpu/fenv_const.c: Likewise.
> * sysdeps/powerpc/powerpc32/e500/nofpu/fenv_libc.h: Likewise.
> * sysdeps/powerpc/powerpc32/e500/nofpu/fesetenv.c: Likewise.
> * sysdeps/powerpc/powerpc32/e500/nofpu/fesetround.c: Likewise.
> * sysdeps/powerpc/powerpc32/e500/nofpu/feupdateenv.c: Likewise.
> * sysdeps/powerpc/powerpc32/e500/nofpu/fexcepts_from_prctl.c:
> Likewise.
> * sysdeps/powerpc/powerpc32/e500/nofpu/fexcepts_from_spe.c:
> Likewise.
> * sysdeps/powerpc/powerpc32/e500/nofpu/fexcepts_to_prctl.c:
> Likewise.
> * sysdeps/powerpc/powerpc32/e500/nofpu/fexcepts_to_spe.c:
> Likewise.
> * sysdeps/powerpc/powerpc32/e500/nofpu/fgetexcptflg.c: Likewise.
> * sysdeps/powerpc/powerpc32/e500/nofpu/fraiseexcept-soft.c:
> Likewise.
> * sysdeps/powerpc/powerpc32/e500/nofpu/fraiseexcpt.c: Likewise.
> * sysdeps/powerpc/powerpc32/e500/nofpu/fsetexcptflg.c: Likewise.
> * sysdeps/powerpc/powerpc32/e500/nofpu/ftestexcept.c: Likewise.
> * sysdeps/powerpc/powerpc32/e500/nofpu/get-rounding-mode.h:
> Likewise.
> * sysdeps/powerpc/powerpc32/e500/nofpu/s_fabsf.S: Likewise.
> * sysdeps/powerpc/powerpc32/e500/nofpu/spe-raise.c: Likewise.
> * sysdeps/powerpc/preconfigure: Likewise.
> * sysdeps/unix/sysv/linux/powerpc/powerpc32/e500/nofpu/Implies:
> Likewise.
> * sysdeps/powerpc/nofpu/soft-supp.h [__NO_FPRS__ && !_SOFT_FLOAT]:
> Replace contents of file by #include of <fenv_libc.h>.
> * sysdeps/powerpc/soft-fp/sfp-machine.h
> [__NO_FPRS__ && !_SOFT_FLOAT]: Include <fenv_libc.h>, <sysdep.h>
> and <sys/prctl.h>.
> [__NO_FPRS__ && !_SOFT_FLOAT] (__feraiseexcept_soft): Declare.
> [__NO_FPRS__ && !_SOFT_FLOAT] (FP_EX_INEXACT): Define macro.
> [__NO_FPRS__ && !_SOFT_FLOAT] (FP_EX_INVALID): Likewise.
> [__NO_FPRS__ && !_SOFT_FLOAT] (FP_EX_DIVZERO): Likewise.
> [__NO_FPRS__ && !_SOFT_FLOAT] (FP_EX_UNDERFLOW): Likewise.
> [__NO_FPRS__ && !_SOFT_FLOAT] (FP_EX_OVERFLOW): Likewise.
> [__NO_FPRS__ && !_SOFT_FLOAT] (_FP_DECL_EX): Likewise.
> [__NO_FPRS__ && !_SOFT_FLOAT] (FP_INIT_ROUNDMODE): Likewise.
> [__NO_FPRS__ && !_SOFT_FLOAT] (FP_INIT_EXCEPTIONS): Likewise.
> [__NO_FPRS__ && !_SOFT_FLOAT] (FP_HANDLE_EXCEPTIONS): Likewise.
> [__NO_FPRS__ && !_SOFT_FLOAT] (FP_ROUNDMODE): Likewise.
> [__NO_FPRS__ && !_SOFT_FLOAT] (FP_TRAPPING_EXCEPTIONS): Likewise.
> * sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/nptl/localplt.data:
> Allow copysignl PLT reference to be missing.
>
> diff --git a/sysdeps/powerpc/nofpu/soft-supp.h b/sysdeps/powerpc/nofpu/soft-supp.h
> index 64a3d2a..18b4550 100644
> --- a/sysdeps/powerpc/nofpu/soft-supp.h
> +++ b/sysdeps/powerpc/nofpu/soft-supp.h
> @@ -17,7 +17,13 @@
> License along with the GNU C Library. If not, see
> <http://www.gnu.org/licenses/>. */
>
> -#include <fenv.h>
> +#if defined __NO_FPRS__ && !defined _SOFT_FLOAT
> +
> +# include <fenv_libc.h>
> +
> +#else
> +
> +# include <fenv.h>
>
> typedef union
> {
> @@ -25,6 +31,7 @@ typedef union
> unsigned int l[2];
> } fenv_union_t;
>
> +#endif
>
> /* FIXME: these variables should be thread specific (see bugzilla bug
> 15483) and ideally preserved across signal handlers, like hardware
> diff --git a/sysdeps/powerpc/powerpc32/e500/nofpu/Makefile b/sysdeps/powerpc/powerpc32/e500/nofpu/Makefile
> new file mode 100644
> index 0000000..adf5568
> --- /dev/null
> +++ b/sysdeps/powerpc/powerpc32/e500/nofpu/Makefile
> @@ -0,0 +1,9 @@
> +ifeq ($(subdir),math)
> +libm-routines += fexcepts_to_spe fexcepts_from_spe
> +libm-routines += fexcepts_to_prctl fexcepts_from_prctl
> +libm-routines += fe_note_change
> +endif
> +
> +ifeq ($(subdir),soft-fp)
> +sysdep_routines += fraiseexcept-soft
> +endif
> diff --git a/sysdeps/powerpc/powerpc32/e500/nofpu/fclrexcpt.c b/sysdeps/powerpc/powerpc32/e500/nofpu/fclrexcpt.c
> new file mode 100644
> index 0000000..92a7dd1
> --- /dev/null
> +++ b/sysdeps/powerpc/powerpc32/e500/nofpu/fclrexcpt.c
> @@ -0,0 +1,53 @@
> +/* Clear given exceptions in current floating-point environment. e500 version.
> + Copyright (C) 2004-2013 Free Software Foundation, Inc.
Shouldn't be just 2013? This is also applies for other Copyright dates for new files.
> + 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)
> +{
> + unsigned int fpescr;
> + int excepts_spe = __fexcepts_to_spe (excepts);
> +
> + /* Get the current state. */
> + fpescr = fegetenv_register ();
> +
> + /* Clear the relevant bits. */
> + fpescr &= ~excepts_spe;
> +
> + /* Put the new state in effect. */
> + fesetenv_register (fpescr);
> +
> + /* Let the kernel know if the "invalid" or "underflow" bit was
> + cleared. */
> + if (excepts & (FE_INVALID | FE_UNDERFLOW))
> + __fe_note_change ();
> +
> + /* 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/sysdeps/powerpc/powerpc32/e500/nofpu/fe_note_change.c b/sysdeps/powerpc/powerpc32/e500/nofpu/fe_note_change.c
> new file mode 100644
> index 0000000..43a5706
> --- /dev/null
> +++ b/sysdeps/powerpc/powerpc32/e500/nofpu/fe_note_change.c
> @@ -0,0 +1,39 @@
> +/* Note a change to floating-point exceptions.
> + Copyright (C) 2013 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <http://www.gnu.org/licenses/>. */
> +
> +#include <fenv_libc.h>
> +#include <sysdep.h>
> +#include <sys/prctl.h>
> +
> +/* Inform the kernel of a change to floating-point exceptions. */
> +
> +void
> +__fe_note_change (void)
> +{
> + int pflags, r;
> + INTERNAL_SYSCALL_DECL (err);
> +
> + r = INTERNAL_SYSCALL (prctl, err, 2, PR_GET_FPEXC, &pflags);
> + if (INTERNAL_SYSCALL_ERROR_P (r, err))
> + return;
> + if ((pflags & PR_FP_EXC_SW_ENABLE) == 0)
> + INTERNAL_SYSCALL (prctl, err, 2, PR_SET_FPEXC,
> + pflags | PR_FP_EXC_SW_ENABLE);
> +}
> +
> +libm_hidden_def (__fe_note_change)
> diff --git a/sysdeps/powerpc/powerpc32/e500/nofpu/fedisblxcpt.c b/sysdeps/powerpc/powerpc32/e500/nofpu/fedisblxcpt.c
> new file mode 100644
> index 0000000..7cc963c
> --- /dev/null
> +++ b/sysdeps/powerpc/powerpc32/e500/nofpu/fedisblxcpt.c
> @@ -0,0 +1,54 @@
> +/* Disable floating-point exceptions. e500 version.
> + Copyright (C) 2004-2013 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <http://www.gnu.org/licenses/>. */
> +
> +#include <fenv_libc.h>
> +#include <sysdep.h>
> +#include <sys/prctl.h>
> +
> +int
> +fedisableexcept (int excepts)
> +{
> + int result = 0, pflags, r;
> + INTERNAL_SYSCALL_DECL (err);
> +
> + r = INTERNAL_SYSCALL (prctl, err, 2, PR_GET_FPEXC, &pflags);
> + if (INTERNAL_SYSCALL_ERROR_P (r, err))
> + return -1;
> +
> + /* Save old enable bits. */
> + result = __fexcepts_from_prctl (pflags);
> +
> + pflags &= ~__fexcepts_to_prctl (excepts);
> + r = INTERNAL_SYSCALL (prctl, err, 2, PR_SET_FPEXC,
> + pflags | PR_FP_EXC_SW_ENABLE);
> + if (INTERNAL_SYSCALL_ERROR_P (r, err))
> + return -1;
> +
> + /* If disabling signals for "inexact", also disable trapping to the
> + kernel. */
> + if ((excepts & FE_INEXACT) != 0)
> + {
> + unsigned long fpescr;
> +
> + fpescr = fegetenv_register ();
> + fpescr &= ~SPEFSCR_FINXE;
> + fesetenv_register (fpescr);
> + }
> +
> + return result;
> +}
> diff --git a/sysdeps/powerpc/powerpc32/e500/nofpu/feenablxcpt.c b/sysdeps/powerpc/powerpc32/e500/nofpu/feenablxcpt.c
> new file mode 100644
> index 0000000..133dde7
> --- /dev/null
> +++ b/sysdeps/powerpc/powerpc32/e500/nofpu/feenablxcpt.c
> @@ -0,0 +1,54 @@
> +/* Enable floating-point exceptions. e500 version.
> + Copyright (C) 2004-2013 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <http://www.gnu.org/licenses/>. */
> +
> +#include <fenv_libc.h>
> +#include <sysdep.h>
> +#include <sys/prctl.h>
> +
> +int
> +feenableexcept (int excepts)
> +{
> + unsigned int result = 0, pflags, r;
> + INTERNAL_SYSCALL_DECL (err);
> +
> + r = INTERNAL_SYSCALL (prctl, err, 2, PR_GET_FPEXC, &pflags);
> + if (INTERNAL_SYSCALL_ERROR_P (r, err))
> + return -1;
> +
> + /* Save old enable bits. */
> + result = __fexcepts_from_prctl (pflags);
> +
> + pflags |= __fexcepts_to_prctl (excepts);
> + r = INTERNAL_SYSCALL (prctl, err, 2, PR_SET_FPEXC,
> + pflags | PR_FP_EXC_SW_ENABLE);
> + if (INTERNAL_SYSCALL_ERROR_P (r, err))
> + return -1;
> +
> + /* If enabling signals for "inexact", also enable trapping to the
> + kernel. */
> + if ((excepts & FE_INEXACT) != 0)
> + {
> + unsigned long fpescr;
> +
> + fpescr = fegetenv_register ();
> + fpescr |= SPEFSCR_FINXE;
> + fesetenv_register (fpescr);
> + }
> +
> + return result;
> +}
> diff --git a/sysdeps/powerpc/powerpc32/e500/nofpu/fegetenv.c b/sysdeps/powerpc/powerpc32/e500/nofpu/fegetenv.c
> new file mode 100644
> index 0000000..bfcbca2
> --- /dev/null
> +++ b/sysdeps/powerpc/powerpc32/e500/nofpu/fegetenv.c
> @@ -0,0 +1,47 @@
> +/* Store current floating-point environment. e500 version.
> + Copyright (C) 2004-2013 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <http://www.gnu.org/licenses/>. */
> +
> +#include <fenv_libc.h>
> +#include <sysdep.h>
> +#include <sys/prctl.h>
> +
> +int
> +__fegetenv (fenv_t *envp)
> +{
> + fenv_union_t u;
> + INTERNAL_SYSCALL_DECL (err);
> + int r;
> +
> + r = INTERNAL_SYSCALL (prctl, err, 2, PR_GET_FPEXC, &u.l[0]);
> + if (INTERNAL_SYSCALL_ERROR_P (r, err))
> + return -1;
> +
> + u.l[1] = fegetenv_register ();
> + *envp = u.fenv;
> +
> + /* 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
> +
> +versioned_symbol (libm, __fegetenv, fegetenv, GLIBC_2_2);
> diff --git a/sysdeps/powerpc/powerpc32/e500/nofpu/fegetexcept.c b/sysdeps/powerpc/powerpc32/e500/nofpu/fegetexcept.c
> new file mode 100644
> index 0000000..9c7afc7
> --- /dev/null
> +++ b/sysdeps/powerpc/powerpc32/e500/nofpu/fegetexcept.c
> @@ -0,0 +1,36 @@
> +/* Get floating-point exceptions. e500 version.
> + Copyright (C) 2004-2013 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <http://www.gnu.org/licenses/>. */
> +
> +#include <fenv_libc.h>
> +#include <sysdep.h>
> +#include <sys/prctl.h>
> +
> +int
> +fegetexcept (void)
> +{
> + int result = 0, pflags, r;
> + INTERNAL_SYSCALL_DECL (err);
> +
> + r = INTERNAL_SYSCALL (prctl, err, 2, PR_GET_FPEXC, &pflags);
> + if (INTERNAL_SYSCALL_ERROR_P (r, err))
> + return -1;
> +
> + result = __fexcepts_from_prctl (pflags);
> +
> + return result;
> +}
> diff --git a/sysdeps/powerpc/powerpc32/e500/nofpu/fegetround.c b/sysdeps/powerpc/powerpc32/e500/nofpu/fegetround.c
> new file mode 100644
> index 0000000..f69e9a5
> --- /dev/null
> +++ b/sysdeps/powerpc/powerpc32/e500/nofpu/fegetround.c
> @@ -0,0 +1,29 @@
> +/* Return current rounding direction. e500 version.
> + Copyright (C) 2004-2013 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <http://www.gnu.org/licenses/>. */
> +
> +#include <fenv_libc.h>
> +
> +#undef fegetround
> +int
> +fegetround (void)
> +{
> + unsigned long fpescr;
> +
> + fpescr = fegetenv_register ();
> + return fpescr & 3;
> +}
> diff --git a/sysdeps/powerpc/powerpc32/e500/nofpu/feholdexcpt.c b/sysdeps/powerpc/powerpc32/e500/nofpu/feholdexcpt.c
> new file mode 100644
> index 0000000..bd05ebd
> --- /dev/null
> +++ b/sysdeps/powerpc/powerpc32/e500/nofpu/feholdexcpt.c
> @@ -0,0 +1,57 @@
> +/* Store current floating-point environment and clear exceptions.
> + e500 version.
> + Copyright (C) 2004-2013 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <http://www.gnu.org/licenses/>. */
> +
> +#include <fenv_libc.h>
> +#include <sysdep.h>
> +#include <sys/prctl.h>
> +
> +int
> +feholdexcept (fenv_t *envp)
> +{
> + fenv_union_t u;
> + INTERNAL_SYSCALL_DECL (err);
> + int r;
> +
> + /* Get the current state. */
> + r = INTERNAL_SYSCALL (prctl, err, 2, PR_GET_FPEXC, &u.l[0]);
> + if (INTERNAL_SYSCALL_ERROR_P (r, err))
> + return -1;
> +
> + u.l[1] = fegetenv_register ();
> + *envp = u.fenv;
> +
> + /* Clear everything except for the rounding mode and trapping to the
> + kernel. */
> + u.l[0] &= ~(PR_FP_EXC_DIV
> + | PR_FP_EXC_OVF
> + | PR_FP_EXC_UND
> + | PR_FP_EXC_RES
> + | PR_FP_EXC_INV);
> + u.l[1] &= SPEFSCR_FRMC | (SPEFSCR_ALL_EXCEPT_ENABLE & ~SPEFSCR_FINXE);
> +
> + /* Put the new state in effect. */
> + fesetenv_register (u.l[1]);
> + r = INTERNAL_SYSCALL (prctl, err, 2, PR_SET_FPEXC,
> + u.l[0] | PR_FP_EXC_SW_ENABLE);
> + if (INTERNAL_SYSCALL_ERROR_P (r, err))
> + return -1;
> +
> + return 0;
> +}
> +libm_hidden_def (feholdexcept)
> diff --git a/sysdeps/powerpc/powerpc32/e500/nofpu/fenv_const.c b/sysdeps/powerpc/powerpc32/e500/nofpu/fenv_const.c
> new file mode 100644
> index 0000000..3a85f18
> --- /dev/null
> +++ b/sysdeps/powerpc/powerpc32/e500/nofpu/fenv_const.c
> @@ -0,0 +1,41 @@
> +/* Constant floating-point environments for e500.
> + Copyright (C) 2004-2013 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <http://www.gnu.org/licenses/>. */
> +
> +/* The use of "unsigned long long" as the type to define the
> + bit-pattern explicitly, rather than the type "double" used in
> + <bits/fenv.h>, means that we cannot include <fenv_libc.h> here to
> + get the enum constants for the SPEFSCR bits to enable
> + exceptions. */
> +
> +#include <sys/prctl.h>
> +
> +/* If the default argument is used we use this value. */
> +const unsigned long long __fe_dfl_env __attribute__ ((aligned (8))) =
> + 0x3cULL;
> +
> +/* Floating-point environment where none of the exceptions are masked. */
> +const unsigned long long __fe_enabled_env __attribute__ ((aligned (8))) =
> + (((unsigned long long) (PR_FP_EXC_DIV
> + | PR_FP_EXC_OVF
> + | PR_FP_EXC_UND
> + | PR_FP_EXC_RES
> + | PR_FP_EXC_INV)) << 32) | 0x7cULL;
> +
> +/* Non-IEEE mode. */
> +const unsigned long long __fe_nonieee_env __attribute__ ((aligned (8))) =
> + 0x0ULL;
> diff --git a/sysdeps/powerpc/powerpc32/e500/nofpu/fenv_libc.h b/sysdeps/powerpc/powerpc32/e500/nofpu/fenv_libc.h
> new file mode 100644
> index 0000000..9637580
> --- /dev/null
> +++ b/sysdeps/powerpc/powerpc32/e500/nofpu/fenv_libc.h
> @@ -0,0 +1,96 @@
> +/* Internal libc stuff for floating point environment routines. e500 version.
> + Copyright (C) 2004-2013 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <http://www.gnu.org/licenses/>. */
> +
> +#ifndef _FENV_LIBC_H
> +#define _FENV_LIBC_H 1
> +
> +#include <fenv.h>
> +
> +int __feraiseexcept_spe (int);
> +libm_hidden_proto (__feraiseexcept_spe)
> +
> +int __fexcepts_to_spe (int);
> +libm_hidden_proto (__fexcepts_to_spe)
> +
> +int __fexcepts_from_spe (int);
> +libm_hidden_proto (__fexcepts_from_spe)
> +
> +int __fexcepts_to_prctl (int);
> +libm_hidden_proto (__fexcepts_to_prctl)
> +
> +int __fexcepts_from_prctl (int);
> +libm_hidden_proto (__fexcepts_from_prctl)
> +
> +void __fe_note_change (void);
> +libm_hidden_proto (__fe_note_change)
> +
> +/* Equivalent to fegetenv, but returns an unsigned int instead of
> + taking a pointer. */
> +#define fegetenv_register() \
> + ({ unsigned int fscr; asm volatile ("mfspefscr %0" : "=r" (fscr)); fscr; })
> +
> +/* Equivalent to fesetenv, but takes an unsigned int instead of a
> + pointer. */
> +#define fesetenv_register(fscr) \
> + ({ asm volatile ("mtspefscr %0" : : "r" (fscr)); })
> +
> +typedef union
> +{
> + fenv_t fenv;
> + unsigned int l[2];
> +} fenv_union_t;
> +
> +/* Definitions of all the SPEFSCR bit numbers. */
> +enum {
> + SPEFSCR_SOVH = 0x80000000,
> + SPEFSCR_OVH = 0x40000000,
> + SPEFSCR_FGH = 0x20000000,
> + SPEFSCR_FXH = 0x10000000,
> + SPEFSCR_FINVH = 0x08000000,
> + SPEFSCR_FDBZH = 0x04000000,
> + SPEFSCR_FUNFH = 0x02000000,
> + SPEFSCR_FOVFH = 0x01000000,
> + /* 2 unused bits. */
> + SPEFSCR_FINXS = 0x00200000,
> + SPEFSCR_FINVS = 0x00100000,
> + SPEFSCR_FDBZS = 0x00080000,
> + SPEFSCR_FUNFS = 0x00040000,
> + SPEFSCR_FOVFS = 0x00020000,
> + /* Combination of the exception bits. */
> + SPEFSCR_ALL_EXCEPT = 0x003e0000,
> + SPEFSCR_MODE = 0x00010000,
> + SPEFSCR_SOV = 0x00008000,
> + SPEFSCR_OV = 0x00004000,
> + SPEFSCR_FG = 0x00002000,
> + SPEFSCR_FX = 0x00001000,
> + SPEFSCR_FINV = 0x00000800,
> + SPEFSCR_FDBZ = 0x00000400,
> + SPEFSCR_FUNF = 0x00000200,
> + SPEFSCR_FOVF = 0x00000100,
> + /* 1 unused bit. */
> + SPEFSCR_FINXE = 0x00000040,
> + SPEFSCR_FINVE = 0x00000020,
> + SPEFSCR_FDBZE = 0x00000010,
> + SPEFSCR_FUNFE = 0x00000008,
> + SPEFSCR_FOVFE = 0x00000004,
> + /* Combination of the exception trap enable bits. */
> + SPEFSCR_ALL_EXCEPT_ENABLE = 0x0000007c,
> + SPEFSCR_FRMC = 0x00000003
> +};
> +
> +#endif /* fenv_libc.h */
> diff --git a/sysdeps/powerpc/powerpc32/e500/nofpu/fesetenv.c b/sysdeps/powerpc/powerpc32/e500/nofpu/fesetenv.c
> new file mode 100644
> index 0000000..411e6be
> --- /dev/null
> +++ b/sysdeps/powerpc/powerpc32/e500/nofpu/fesetenv.c
> @@ -0,0 +1,49 @@
> +/* Install given floating-point environment. e500 version.
> + Copyright (C) 1997-2013 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <http://www.gnu.org/licenses/>. */
> +
> +#include <fenv_libc.h>
> +#include <sysdep.h>
> +#include <sys/prctl.h>
> +
> +int
> +__fesetenv (const fenv_t *envp)
> +{
> + fenv_union_t u;
> + INTERNAL_SYSCALL_DECL (err);
> + int r;
> +
> + u.fenv = *envp;
> +
> + fesetenv_register (u.l[1]);
> + r = INTERNAL_SYSCALL (prctl, err, 2, PR_SET_FPEXC,
> + u.l[0] | PR_FP_EXC_SW_ENABLE);
> + if (INTERNAL_SYSCALL_ERROR_P (r, err))
> + return -1;
> +
> + /* 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_ver (__fesetenv, fesetenv)
> +versioned_symbol (libm, __fesetenv, fesetenv, GLIBC_2_2);
> diff --git a/sysdeps/powerpc/powerpc32/e500/nofpu/fesetround.c b/sysdeps/powerpc/powerpc32/e500/nofpu/fesetround.c
> new file mode 100644
> index 0000000..805008e
> --- /dev/null
> +++ b/sysdeps/powerpc/powerpc32/e500/nofpu/fesetround.c
> @@ -0,0 +1,35 @@
> +/* Set current rounding direction. e500 version.
> + Copyright (C) 2004-2013 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <http://www.gnu.org/licenses/>. */
> +
> +#include <fenv_libc.h>
> +
> +int
> +fesetround (int round)
> +{
> + unsigned long fpescr;
> +
> + if ((unsigned int) round > 3)
> + return 1;
> +
> + fpescr = fegetenv_register ();
> + fpescr = (fpescr & ~SPEFSCR_FRMC) | (round & 3);
> + fesetenv_register (fpescr);
> +
> + return 0;
> +}
> +libm_hidden_def (fesetround)
> diff --git a/sysdeps/powerpc/powerpc32/e500/nofpu/feupdateenv.c b/sysdeps/powerpc/powerpc32/e500/nofpu/feupdateenv.c
> new file mode 100644
> index 0000000..505c923
> --- /dev/null
> +++ b/sysdeps/powerpc/powerpc32/e500/nofpu/feupdateenv.c
> @@ -0,0 +1,47 @@
> +/* Install given floating-point environment and raise exceptions.
> + e500 version.
> + Copyright (C) 2004-2013 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <http://www.gnu.org/licenses/>. */
> +
> +#include <fenv_libc.h>
> +
> +int
> +__feupdateenv (const fenv_t *envp)
> +{
> + int exc;
> +
> + /* Save the currently set exceptions. */
> + exc = fegetenv_register () & SPEFSCR_ALL_EXCEPT;
> +
> + /* Install new environment. */
> + fesetenv (envp);
> +
> + /* Raise (if appropriate) saved exceptions. */
> + __feraiseexcept_spe (exc);
> +
> + /* 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_ver (__feupdateenv, feupdateenv)
> +versioned_symbol (libm, __feupdateenv, feupdateenv, GLIBC_2_2);
> diff --git a/sysdeps/powerpc/powerpc32/e500/nofpu/fexcepts_from_prctl.c b/sysdeps/powerpc/powerpc32/e500/nofpu/fexcepts_from_prctl.c
> new file mode 100644
> index 0000000..c6448ae
> --- /dev/null
> +++ b/sysdeps/powerpc/powerpc32/e500/nofpu/fexcepts_from_prctl.c
> @@ -0,0 +1,42 @@
> +/* Convert floating-point exceptions from prctl form.
> + Copyright (C) 2013 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <http://www.gnu.org/licenses/>. */
> +
> +#include <fenv_libc.h>
> +#include <sys/prctl.h>
> +
> +/* Convert EXCEPTS from prctl bits to FE_* form, returning the
> + converted value. */
> +
> +int
> +__fexcepts_from_prctl (int excepts)
> +{
> + int result = 0;
> + if (excepts & PR_FP_EXC_OVF)
> + result |= FE_OVERFLOW;
> + if (excepts & PR_FP_EXC_UND)
> + result |= FE_UNDERFLOW;
> + if (excepts & PR_FP_EXC_INV)
> + result |= FE_INVALID;
> + if (excepts & PR_FP_EXC_DIV)
> + result |= FE_DIVBYZERO;
> + if (excepts & PR_FP_EXC_RES)
> + result |= FE_INEXACT;
> + return result;
> +}
> +
> +libm_hidden_def (__fexcepts_from_prctl)
> diff --git a/sysdeps/powerpc/powerpc32/e500/nofpu/fexcepts_from_spe.c b/sysdeps/powerpc/powerpc32/e500/nofpu/fexcepts_from_spe.c
> new file mode 100644
> index 0000000..3ec939d
> --- /dev/null
> +++ b/sysdeps/powerpc/powerpc32/e500/nofpu/fexcepts_from_spe.c
> @@ -0,0 +1,41 @@
> +/* Convert floating-point exceptions from SPEFSCR form.
> + Copyright (C) 2013 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <http://www.gnu.org/licenses/>. */
> +
> +#include <fenv_libc.h>
> +
> +/* Convert EXCEPTS from SPEFSCR bits to FE_* form, returning the
> + converted value. */
> +
> +int
> +__fexcepts_from_spe (int excepts)
> +{
> + int result = 0;
> + if (excepts & SPEFSCR_FINXS)
> + result |= FE_INEXACT;
> + if (excepts & SPEFSCR_FDBZS)
> + result |= FE_DIVBYZERO;
> + if (excepts & SPEFSCR_FUNFS)
> + result |= FE_UNDERFLOW;
> + if (excepts & SPEFSCR_FOVFS)
> + result |= FE_OVERFLOW;
> + if (excepts & SPEFSCR_FINVS)
> + result |= FE_INVALID;
> + return result;
> +}
> +
> +libm_hidden_def (__fexcepts_from_spe)
> diff --git a/sysdeps/powerpc/powerpc32/e500/nofpu/fexcepts_to_prctl.c b/sysdeps/powerpc/powerpc32/e500/nofpu/fexcepts_to_prctl.c
> new file mode 100644
> index 0000000..b9c51b1
> --- /dev/null
> +++ b/sysdeps/powerpc/powerpc32/e500/nofpu/fexcepts_to_prctl.c
> @@ -0,0 +1,42 @@
> +/* Convert floating-point exceptions to prctl form.
> + Copyright (C) 2013 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <http://www.gnu.org/licenses/>. */
> +
> +#include <fenv_libc.h>
> +#include <sys/prctl.h>
> +
> +/* Convert EXCEPTS from FE_* form to prctl bits, returning the
> + converted value. */
> +
> +int
> +__fexcepts_to_prctl (int excepts)
> +{
> + int result = 0;
> + if (excepts & FE_INEXACT)
> + result |= PR_FP_EXC_RES;
> + if (excepts & FE_DIVBYZERO)
> + result |= PR_FP_EXC_DIV;
> + if (excepts & FE_UNDERFLOW)
> + result |= PR_FP_EXC_UND;
> + if (excepts & FE_OVERFLOW)
> + result |= PR_FP_EXC_OVF;
> + if (excepts & FE_INVALID)
> + result |= PR_FP_EXC_INV;
> + return result;
> +}
> +
> +libm_hidden_def (__fexcepts_to_prctl)
> diff --git a/sysdeps/powerpc/powerpc32/e500/nofpu/fexcepts_to_spe.c b/sysdeps/powerpc/powerpc32/e500/nofpu/fexcepts_to_spe.c
> new file mode 100644
> index 0000000..570934d
> --- /dev/null
> +++ b/sysdeps/powerpc/powerpc32/e500/nofpu/fexcepts_to_spe.c
> @@ -0,0 +1,41 @@
> +/* Convert floating-point exceptions to SPEFSCR form.
> + Copyright (C) 2013 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <http://www.gnu.org/licenses/>. */
> +
> +#include <fenv_libc.h>
> +
> +/* Convert EXCEPTS from FE_* form to SPEFSCR bits, returning the
> + converted value. */
> +
> +int
> +__fexcepts_to_spe (int excepts)
> +{
> + int result = 0;
> + if (excepts & FE_INEXACT)
> + result |= SPEFSCR_FINXS;
> + if (excepts & FE_DIVBYZERO)
> + result |= SPEFSCR_FDBZS;
> + if (excepts & FE_UNDERFLOW)
> + result |= SPEFSCR_FUNFS;
> + if (excepts & FE_OVERFLOW)
> + result |= SPEFSCR_FOVFS;
> + if (excepts & FE_INVALID)
> + result |= SPEFSCR_FINVS;
> + return result;
> +}
> +
> +libm_hidden_def (__fexcepts_to_spe)
> diff --git a/sysdeps/powerpc/powerpc32/e500/nofpu/fgetexcptflg.c b/sysdeps/powerpc/powerpc32/e500/nofpu/fgetexcptflg.c
> new file mode 100644
> index 0000000..b01cade
> --- /dev/null
> +++ b/sysdeps/powerpc/powerpc32/e500/nofpu/fgetexcptflg.c
> @@ -0,0 +1,41 @@
> +/* Store current representation for exceptions. e500 version.
> + Copyright (C) 2004-2013 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <http://www.gnu.org/licenses/>. */
> +
> +#include <fenv_libc.h>
> +
> +int
> +__fegetexceptflag (fexcept_t *flagp, int excepts)
> +{
> + unsigned long fpescr;
> +
> + /* Get the current state. */
> + fpescr = fegetenv_register ();
> +
> + *flagp = fpescr & SPEFSCR_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/sysdeps/powerpc/powerpc32/e500/nofpu/fraiseexcept-soft.c b/sysdeps/powerpc/powerpc32/e500/nofpu/fraiseexcept-soft.c
> new file mode 100644
> index 0000000..0aed72f
> --- /dev/null
> +++ b/sysdeps/powerpc/powerpc32/e500/nofpu/fraiseexcept-soft.c
> @@ -0,0 +1,28 @@
> +/* Raise given exceptions. e500 version for use from soft-fp.
> + Copyright (C) 2004-2013 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> + Contributed by Aldy Hernandez <aldyh@redhat.com>, 2004.
> +
> + 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 <libc-symbols.h>
> +
> +int __feraiseexcept_soft (int);
> +libc_hidden_proto (__feraiseexcept_soft)
> +
> +#define __FERAISEEXCEPT_INTERNAL __feraiseexcept_soft
> +#include "spe-raise.c"
> +libc_hidden_def (__feraiseexcept_soft)
> diff --git a/sysdeps/powerpc/powerpc32/e500/nofpu/fraiseexcpt.c b/sysdeps/powerpc/powerpc32/e500/nofpu/fraiseexcpt.c
> new file mode 100644
> index 0000000..0eca9ff
> --- /dev/null
> +++ b/sysdeps/powerpc/powerpc32/e500/nofpu/fraiseexcpt.c
> @@ -0,0 +1,40 @@
> +/* Raise given exceptions. e500 version.
> + Copyright (C) 2004-2013 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <http://www.gnu.org/licenses/>. */
> +
> +#include <fenv_libc.h>
> +
> +#define __FERAISEEXCEPT_INTERNAL __feraiseexcept_spe
> +#include "spe-raise.c"
> +
> +libm_hidden_def (__feraiseexcept_spe)
> +
> +#undef feraiseexcept
> +int
> +__feraiseexcept (int excepts)
> +{
> + return __feraiseexcept_spe (__fexcepts_to_spe (excepts));
> +}
> +
> +#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_ver (__feraiseexcept, feraiseexcept)
> +versioned_symbol (libm, __feraiseexcept, feraiseexcept, GLIBC_2_2);
> diff --git a/sysdeps/powerpc/powerpc32/e500/nofpu/fsetexcptflg.c b/sysdeps/powerpc/powerpc32/e500/nofpu/fsetexcptflg.c
> new file mode 100644
> index 0000000..43f2d19
> --- /dev/null
> +++ b/sysdeps/powerpc/powerpc32/e500/nofpu/fsetexcptflg.c
> @@ -0,0 +1,55 @@
> +/* Set floating-point environment exception handling. e500 version.
> + Copyright (C) 1997-2013 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <http://www.gnu.org/licenses/>. */
> +
> +#include <fenv_libc.h>
> +
> +int
> +__fesetexceptflag (const fexcept_t *flagp, int excepts)
> +{
> + unsigned long old_spefscr, spefscr;
> + fexcept_t flag;
> + int excepts_spe = __fexcepts_to_spe (excepts);
> +
> + /* Get the current state. */
> + old_spefscr = fegetenv_register ();
> +
> + /* Ignore exceptions not listed in 'excepts'. */
> + flag = *flagp & excepts_spe;
> +
> + /* Replace the exception status */
> + spefscr = (old_spefscr & ~excepts_spe) | flag;
> +
> + /* Store the new status word (along with the rest of the environment). */
> + fesetenv_register (spefscr);
> +
> + /* If the state of the "invalid" or "underflow" flag has changed,
> + inform the kernel. */
> + if (((spefscr ^ old_spefscr) & (SPEFSCR_FINVS | SPEFSCR_FUNFS)) != 0)
> + __fe_note_change ();
> +
> + /* 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/sysdeps/powerpc/powerpc32/e500/nofpu/ftestexcept.c b/sysdeps/powerpc/powerpc32/e500/nofpu/ftestexcept.c
> new file mode 100644
> index 0000000..f4f547d
> --- /dev/null
> +++ b/sysdeps/powerpc/powerpc32/e500/nofpu/ftestexcept.c
> @@ -0,0 +1,31 @@
> +/* Test exception in current environment. e500 version.
> + Copyright (C) 2004-2013 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <http://www.gnu.org/licenses/>. */
> +
> +#include <fenv_libc.h>
> +
> +int
> +fetestexcept (int excepts)
> +{
> + unsigned long f;
> +
> + /* Get the current state. */
> + f = fegetenv_register ();
> +
> + return __fexcepts_from_spe (f) & excepts;
> +}
> +libm_hidden_def (fetestexcept)
> diff --git a/sysdeps/powerpc/powerpc32/e500/nofpu/get-rounding-mode.h b/sysdeps/powerpc/powerpc32/e500/nofpu/get-rounding-mode.h
> new file mode 100644
> index 0000000..117e733
> --- /dev/null
> +++ b/sysdeps/powerpc/powerpc32/e500/nofpu/get-rounding-mode.h
> @@ -0,0 +1,4 @@
> +/* The generic version of get-rounding-mode.h using fpu_control.h, not
> + the one using the software rounding mode, is correct for e500. */
> +
> +#include <sysdeps/generic/get-rounding-mode.h>
> diff --git a/sysdeps/powerpc/powerpc32/e500/nofpu/s_fabsf.S b/sysdeps/powerpc/powerpc32/e500/nofpu/s_fabsf.S
> new file mode 100644
> index 0000000..823f748
> --- /dev/null
> +++ b/sysdeps/powerpc/powerpc32/e500/nofpu/s_fabsf.S
> @@ -0,0 +1,27 @@
> +/* Floating-point absolute value. e500 version.
> + Copyright (C) 2004-2013 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <http://www.gnu.org/licenses/>. */
> +
> +#include <sysdep.h>
> +
> +ENTRY (__fabsf)
> +/* float [r3] fabsf (float [r3] x) ; */
> + efsabs r3,r3
> + blr
> +END (__fabsf)
> +
> +weak_alias (__fabsf, fabsf)
> diff --git a/sysdeps/powerpc/powerpc32/e500/nofpu/spe-raise.c b/sysdeps/powerpc/powerpc32/e500/nofpu/spe-raise.c
> new file mode 100644
> index 0000000..4394ddc
> --- /dev/null
> +++ b/sysdeps/powerpc/powerpc32/e500/nofpu/spe-raise.c
> @@ -0,0 +1,53 @@
> +/* Raise given exceptions, given the SPEFSCR bits for those exceptions.
> + Copyright (C) 1997-2013 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <http://www.gnu.org/licenses/>. */
> +
> +#include <fenv_libc.h>
> +
> +int
> +__FERAISEEXCEPT_INTERNAL (int excepts)
> +{
> + unsigned long f;
> +
> + f = fegetenv_register ();
> + f |= (excepts & SPEFSCR_ALL_EXCEPT);
> + fesetenv_register (f);
> +
> + /* Force the operations that cause the exceptions. */
> + if ((SPEFSCR_FINVS & excepts) != 0)
> + /* 0 / 0 */
> + asm volatile ("efsdiv %0,%0,%1" : : "r" (0), "r" (0));
> +
> + if ((SPEFSCR_FDBZS & excepts) != 0)
> + /* 1.0 / 0.0 */
> + asm volatile ("efsdiv %0,%0,%1" : : "r" (1.0F), "r" (0));
> +
> + if ((SPEFSCR_FOVFS & excepts) != 0)
> + /* Largest normalized number plus itself. */
> + asm volatile ("efsadd %0,%0,%1" : : "r" (0x7f7fffff), "r" (0x7f7fffff));
> +
> + if ((SPEFSCR_FUNFS & excepts) != 0)
> + /* Smallest normalized number times itself. */
> + asm volatile ("efsmul %0,%0,%1" : : "r" (0x800000), "r" (0x800000));
> +
> + if ((SPEFSCR_FINXS & excepts) != 0)
> + /* Smallest normalized minus 1.0 raises the inexact flag. */
> + asm volatile ("efssub %0,%0,%1" : : "r" (0x00800000), "r" (1.0F));
> +
> + /* Success. */
> + return 0;
> +}
> diff --git a/sysdeps/powerpc/preconfigure b/sysdeps/powerpc/preconfigure
> new file mode 100644
> index 0000000..1741c25
> --- /dev/null
> +++ b/sysdeps/powerpc/preconfigure
> @@ -0,0 +1,11 @@
> +# Check for e500.
> +
> +case "$machine" in
> +powerpc)
> + $CC $CFLAGS $CPPFLAGS -E -dM -xc /dev/null > conftest.i
> + if grep -q __NO_FPRS__ conftest.i && ! grep -q _SOFT_FLOAT conftest.i; then
> + base_machine=powerpc machine=powerpc/powerpc32/e500
> + fi
> + rm -f conftest.i
> + ;;
> +esac
> diff --git a/sysdeps/powerpc/soft-fp/sfp-machine.h b/sysdeps/powerpc/soft-fp/sfp-machine.h
> index 508d869..0411878 100644
> --- a/sysdeps/powerpc/soft-fp/sfp-machine.h
> +++ b/sysdeps/powerpc/soft-fp/sfp-machine.h
> @@ -41,18 +41,64 @@
> R##_c = FP_CLS_NAN; \
> } while (0)
>
> +#if defined __NO_FPRS__ && !defined _SOFT_FLOAT
> +
> +/* Exception flags. We use the bit positions of the appropriate bits
> + in the FPEFSCR. */
> +
> +# include <fenv_libc.h>
> +# include <sysdep.h>
> +# include <sys/prctl.h>
> +
> +int __feraiseexcept_soft (int);
> +libc_hidden_proto (__feraiseexcept_soft)
> +
> +# define FP_EX_INEXACT SPEFSCR_FINXS
> +# define FP_EX_INVALID SPEFSCR_FINVS
> +# define FP_EX_DIVZERO SPEFSCR_FDBZS
> +# define FP_EX_UNDERFLOW SPEFSCR_FUNFS
> +# define FP_EX_OVERFLOW SPEFSCR_FOVFS
> +
> +# define _FP_DECL_EX \
> + int _spefscr __attribute__ ((unused)), _ftrapex __attribute__ ((unused)) = 0
> +# define FP_INIT_ROUNDMODE \
> + do \
> + { \
> + int _r; \
> + INTERNAL_SYSCALL_DECL (_err); \
> + \
> + _spefscr = fegetenv_register (); \
> + _r = INTERNAL_SYSCALL (prctl, _err, 2, PR_GET_FPEXC, &_ftrapex); \
> + if (INTERNAL_SYSCALL_ERROR_P (_r, _err)) \
> + _ftrapex = 0; \
> + } \
> + while (0)
> +# define FP_INIT_EXCEPTIONS /* Empty. */
> +
> +# define FP_HANDLE_EXCEPTIONS __feraiseexcept_soft (_fex)
> +# define FP_ROUNDMODE (_spefscr & 0x3)
> +
> +/* Not correct in general, but sufficient for the uses in soft-fp. */
> +# define FP_TRAPPING_EXCEPTIONS (_ftrapex & PR_FP_EXC_UND \
> + ? FP_EX_UNDERFLOW \
> + : 0)
> +
> +#else
> +
> /* Exception flags. We use the bit positions of the appropriate bits
> in the FPSCR, which also correspond to the FE_* bits. This makes
> everything easier ;-). */
> -#define FP_EX_INVALID (1 << (31 - 2))
> -#define FP_EX_OVERFLOW (1 << (31 - 3))
> -#define FP_EX_UNDERFLOW (1 << (31 - 4))
> -#define FP_EX_DIVZERO (1 << (31 - 5))
> -#define FP_EX_INEXACT (1 << (31 - 6))
> -
> -#define FP_HANDLE_EXCEPTIONS __simulate_exceptions (_fex)
> -#define FP_ROUNDMODE __sim_round_mode
> -#define FP_TRAPPING_EXCEPTIONS (~__sim_disabled_exceptions & 0x3e000000)
> +# define FP_EX_INVALID (1 << (31 - 2))
> +# define FP_EX_OVERFLOW (1 << (31 - 3))
> +# define FP_EX_UNDERFLOW (1 << (31 - 4))
> +# define FP_EX_DIVZERO (1 << (31 - 5))
> +# define FP_EX_INEXACT (1 << (31 - 6))
> +
> +# define FP_HANDLE_EXCEPTIONS __simulate_exceptions (_fex)
> +# define FP_ROUNDMODE __sim_round_mode
> +# define FP_TRAPPING_EXCEPTIONS (~__sim_disabled_exceptions & 0x3e000000)
> +
> +#endif
>
> /* FIXME: these variables should be thread specific (see bugzilla bug
> 15483) and ideally preserved across signal handlers, like hardware
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/e500/nofpu/Implies b/sysdeps/unix/sysv/linux/powerpc/powerpc32/e500/nofpu/Implies
> new file mode 100644
> index 0000000..00365c1
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/e500/nofpu/Implies
> @@ -0,0 +1,3 @@
> +powerpc/powerpc32/e500/nofpu
> +powerpc/nofpu
> +powerpc/soft-fp
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/nptl/localplt.data b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/nptl/localplt.data
> index 0743b08..b87936c 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/nptl/localplt.data
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/nptl/localplt.data
> @@ -35,7 +35,7 @@ libc.so: realloc
> libm.so: __signbit
> libm.so: __signbitf
> libm.so: __signbitl
> -libm.so: copysignl
> +libm.so: copysignl ?
> libm.so: fabsl
> libm.so: fegetround
> libm.so: matherr
>