diff options
Diffstat (limited to 'sysdeps')
31 files changed, 1169 insertions, 11 deletions
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. + 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..c094a04 --- /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 |