Add e500 port.

This commit is contained in:
Joseph Myers 2013-10-18 21:03:40 +00:00
parent 289528850d
commit 3c8325fb47
32 changed files with 1226 additions and 10 deletions

View File

@ -1,3 +1,61 @@
2013-10-18 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.
2013-10-18 Richard Sandiford <richard@codesourcery.com>
Joseph Myers <joseph@codesourcery.com

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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)

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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)

View File

@ -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;

View File

@ -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 */

View File

@ -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);

View File

@ -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)

View File

@ -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);

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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);

View File

@ -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)

View File

@ -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);

View File

@ -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);

View File

@ -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)

View File

@ -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>

View File

@ -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)

View File

@ -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;
}

View File

@ -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

View File

@ -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_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_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

View File

@ -0,0 +1,3 @@
powerpc/powerpc32/e500/nofpu
powerpc/nofpu
powerpc/soft-fp

View File

@ -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