This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: e500 port: the port itself


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
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]