summaryrefslogtreecommitdiff
path: root/libm
diff options
context:
space:
mode:
authorJoakim Tjernlund <joakim.tjernlund@transmode.se>2007-03-31 13:28:15 +0000
committerJoakim Tjernlund <joakim.tjernlund@transmode.se>2007-03-31 13:28:15 +0000
commite7bcf43b6440ac9fc61a0eef5591393810daafb5 (patch)
treeb72c3fb15e030b47b2eb02d13169b4548382e855 /libm
parent7a40ba19c86e4d2fc7e35f14a0e629ee843b96a9 (diff)
From Steve Papacharalambous:
Add math support for PowerPC e500.
Diffstat (limited to 'libm')
-rw-r--r--libm/Makefile.in21
-rw-r--r--libm/powerpc/classic/Makefile.arch (renamed from libm/powerpc/Makefile.arch)0
-rw-r--r--libm/powerpc/classic/s_ceil.c (renamed from libm/powerpc/s_ceil.c)0
-rw-r--r--libm/powerpc/classic/s_copysign.c (renamed from libm/powerpc/s_copysign.c)0
-rw-r--r--libm/powerpc/classic/s_floor.c (renamed from libm/powerpc/s_floor.c)0
-rw-r--r--libm/powerpc/classic/s_frexp.c (renamed from libm/powerpc/s_frexp.c)0
-rw-r--r--libm/powerpc/classic/s_ldexp.c (renamed from libm/powerpc/s_ldexp.c)0
-rw-r--r--libm/powerpc/classic/s_logb.c (renamed from libm/powerpc/s_logb.c)0
-rw-r--r--libm/powerpc/classic/s_modf.c (renamed from libm/powerpc/s_modf.c)0
-rw-r--r--libm/powerpc/classic/s_nearbyint.c (renamed from libm/powerpc/s_nearbyint.c)0
-rw-r--r--libm/powerpc/classic/s_rint.c (renamed from libm/powerpc/s_rint.c)0
-rw-r--r--libm/powerpc/classic/s_round.c (renamed from libm/powerpc/s_round.c)0
-rw-r--r--libm/powerpc/classic/s_trunc.c (renamed from libm/powerpc/s_trunc.c)0
-rw-r--r--libm/powerpc/classic/w_scalb.c (renamed from libm/powerpc/w_scalb.c)0
-rw-r--r--libm/powerpc/e500/Makefile.arch9
-rw-r--r--libm/powerpc/e500/README.txt8
-rw-r--r--libm/powerpc/e500/fpu/Makefile.arch19
-rw-r--r--libm/powerpc/e500/fpu/fclrexcpt.c39
-rw-r--r--libm/powerpc/e500/fpu/fe_nomask.c32
-rw-r--r--libm/powerpc/e500/fpu/fedisblxcpt.c60
-rw-r--r--libm/powerpc/e500/fpu/feenablxcpt.c60
-rw-r--r--libm/powerpc/e500/fpu/fegetenv.c38
-rw-r--r--libm/powerpc/e500/fpu/fegetexcept.c31
-rw-r--r--libm/powerpc/e500/fpu/fegetround.c31
-rw-r--r--libm/powerpc/e500/fpu/feholdexcpt.c45
-rw-r--r--libm/powerpc/e500/fpu/fenv_const.c27
-rw-r--r--libm/powerpc/e500/fpu/fenv_libc.h77
-rw-r--r--libm/powerpc/e500/fpu/fesetenv.c38
-rw-r--r--libm/powerpc/e500/fpu/fesetround.c37
-rw-r--r--libm/powerpc/e500/fpu/feupdateenv.c49
-rw-r--r--libm/powerpc/e500/fpu/fgetexcptflg.c39
-rw-r--r--libm/powerpc/e500/fpu/fraiseexcpt.c29
-rw-r--r--libm/powerpc/e500/fpu/fsetexcptflg.c46
-rw-r--r--libm/powerpc/e500/fpu/ftestexcept.c32
-rw-r--r--libm/powerpc/e500/spe-raise.c67
35 files changed, 834 insertions, 0 deletions
diff --git a/libm/Makefile.in b/libm/Makefile.in
index 5b2fbff36..a972530cf 100644
--- a/libm/Makefile.in
+++ b/libm/Makefile.in
@@ -29,8 +29,21 @@ LIBS-libm.so := $(LIBS)
libm_FULL_NAME := libm-$(VERSION).so
+
+# Fix builds for powerpc as there are different cores in this
+# section now.`
+ifeq ($(TARGET_ARCH),powerpc)
+ifeq ($(CONFIG_E500),y)
+libm_ARCH_DIR:=$(top_srcdir)libm/$(TARGET_ARCH)/e500
+libm_ARCH_OUT:=$(top_builddir)libm/$(TARGET_ARCH)/e500
+else
+libm_ARCH_DIR:=$(top_srcdir)libm/$(TARGET_ARCH)/classic
+libm_ARCH_OUT:=$(top_builddir)libm/$(TARGET_ARCH)/classic
+endif
+else
libm_ARCH_DIR:=$(top_srcdir)libm/$(TARGET_ARCH)
libm_ARCH_OUT:=$(top_builddir)libm/$(TARGET_ARCH)
+endif
libm_ARCH_fpu_DIR:=$(libm_ARCH_DIR)/fpu
libm_ARCH_fpu_OUT:=$(libm_ARCH_OUT)/fpu
@@ -91,7 +104,15 @@ libm_OUT := $(top_builddir)libm
ifeq ($(UCLIBC_HAS_FPU),y)
ifeq ($(DO_C99_MATH),y)
ifneq ($(strip $(libm_ARCH_OBJS)),)
+ifeq ($(TARGET_ARCH),powerpc)
+ifeq ($(CONFIG_E500),y)
+CFLAGS-libm/$(TARGET_ARCH)/e500/ := $(CFLAGS-libm)
+else
+CFLAGS-libm/$(TARGET_ARCH)/classic/ := $(CFLAGS-libm)
+endif
+else
CFLAGS-libm/$(TARGET_ARCH)/ := $(CFLAGS-libm)
+endif
# remove generic sources, if arch specific version is present
ifneq ($(strip $(libm_ARCH_SRC)),)
diff --git a/libm/powerpc/Makefile.arch b/libm/powerpc/classic/Makefile.arch
index 7c7600f80..7c7600f80 100644
--- a/libm/powerpc/Makefile.arch
+++ b/libm/powerpc/classic/Makefile.arch
diff --git a/libm/powerpc/s_ceil.c b/libm/powerpc/classic/s_ceil.c
index 8db5ce537..8db5ce537 100644
--- a/libm/powerpc/s_ceil.c
+++ b/libm/powerpc/classic/s_ceil.c
diff --git a/libm/powerpc/s_copysign.c b/libm/powerpc/classic/s_copysign.c
index 1a988ac87..1a988ac87 100644
--- a/libm/powerpc/s_copysign.c
+++ b/libm/powerpc/classic/s_copysign.c
diff --git a/libm/powerpc/s_floor.c b/libm/powerpc/classic/s_floor.c
index ff3436707..ff3436707 100644
--- a/libm/powerpc/s_floor.c
+++ b/libm/powerpc/classic/s_floor.c
diff --git a/libm/powerpc/s_frexp.c b/libm/powerpc/classic/s_frexp.c
index 001aaf708..001aaf708 100644
--- a/libm/powerpc/s_frexp.c
+++ b/libm/powerpc/classic/s_frexp.c
diff --git a/libm/powerpc/s_ldexp.c b/libm/powerpc/classic/s_ldexp.c
index 10100d7c2..10100d7c2 100644
--- a/libm/powerpc/s_ldexp.c
+++ b/libm/powerpc/classic/s_ldexp.c
diff --git a/libm/powerpc/s_logb.c b/libm/powerpc/classic/s_logb.c
index 81daa412e..81daa412e 100644
--- a/libm/powerpc/s_logb.c
+++ b/libm/powerpc/classic/s_logb.c
diff --git a/libm/powerpc/s_modf.c b/libm/powerpc/classic/s_modf.c
index b9d69445d..b9d69445d 100644
--- a/libm/powerpc/s_modf.c
+++ b/libm/powerpc/classic/s_modf.c
diff --git a/libm/powerpc/s_nearbyint.c b/libm/powerpc/classic/s_nearbyint.c
index 068e21378..068e21378 100644
--- a/libm/powerpc/s_nearbyint.c
+++ b/libm/powerpc/classic/s_nearbyint.c
diff --git a/libm/powerpc/s_rint.c b/libm/powerpc/classic/s_rint.c
index dd2ae585e..dd2ae585e 100644
--- a/libm/powerpc/s_rint.c
+++ b/libm/powerpc/classic/s_rint.c
diff --git a/libm/powerpc/s_round.c b/libm/powerpc/classic/s_round.c
index 62d5936d9..62d5936d9 100644
--- a/libm/powerpc/s_round.c
+++ b/libm/powerpc/classic/s_round.c
diff --git a/libm/powerpc/s_trunc.c b/libm/powerpc/classic/s_trunc.c
index f793992a7..f793992a7 100644
--- a/libm/powerpc/s_trunc.c
+++ b/libm/powerpc/classic/s_trunc.c
diff --git a/libm/powerpc/w_scalb.c b/libm/powerpc/classic/w_scalb.c
index 408136001..408136001 100644
--- a/libm/powerpc/w_scalb.c
+++ b/libm/powerpc/classic/w_scalb.c
diff --git a/libm/powerpc/e500/Makefile.arch b/libm/powerpc/e500/Makefile.arch
new file mode 100644
index 000000000..bec21caef
--- /dev/null
+++ b/libm/powerpc/e500/Makefile.arch
@@ -0,0 +1,9 @@
+# Makefile for uClibc
+#
+# Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+#
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+#
+
+-include $(libm_ARCH_fpu_DIR)/Makefile.arch
+
diff --git a/libm/powerpc/e500/README.txt b/libm/powerpc/e500/README.txt
new file mode 100644
index 000000000..354d7921a
--- /dev/null
+++ b/libm/powerpc/e500/README.txt
@@ -0,0 +1,8 @@
+The routines this math library have been derived from the e500 math
+library in eglibc. The original e500 port to glibc was done by
+Aldy Hernandez, <aldyh@redhat.com>, and the port to eglibc was done by
+Joseph S. Myers, <joseph@codesourcery.com>
+
+It has been ported to uClibc by Steve Papacharalambous <stevep@freescale.com>
+ 19 December, 2006
+
diff --git a/libm/powerpc/e500/fpu/Makefile.arch b/libm/powerpc/e500/fpu/Makefile.arch
new file mode 100644
index 000000000..8f00e0916
--- /dev/null
+++ b/libm/powerpc/e500/fpu/Makefile.arch
@@ -0,0 +1,19 @@
+# Makefile for uClibc
+#
+# Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+#
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+#
+
+
+libm_ARCH_SRC:=$(wildcard $(libm_ARCH_fpu_DIR)/*.c)
+libm_ARCH_OBJ:=$(patsubst $(libm_ARCH_fpu_DIR)/%.c,$(libm_ARCH_fpu_OUT)/%.o,$(libm_ARCH_SRC))
+
+libm_ARCH_OBJS:=$(libm_ARCH_OBJ)
+
+ifeq ($(DOPIC),y)
+libm-a-y+=$(libm_ARCH_OBJS:.o=.os)
+else
+libm-a-y+=$(libm_ARCH_OBJS)
+endif
+libm-so-y+=$(libm_ARCH_OBJS:.o=.os)
diff --git a/libm/powerpc/e500/fpu/fclrexcpt.c b/libm/powerpc/e500/fpu/fclrexcpt.c
new file mode 100644
index 000000000..42e8b6bab
--- /dev/null
+++ b/libm/powerpc/e500/fpu/fclrexcpt.c
@@ -0,0 +1,39 @@
+/* Clear given exceptions in current floating-point environment.
+ Copyright (C) 2004 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "fenv_libc.h"
+#undef feclearexcept
+int
+__feclearexcept (int excepts)
+{
+ unsigned int fpescr;
+
+ /* Get the current state. */
+ fpescr = fegetenv_register ();
+
+ /* Clear the relevant bits. */
+ fpescr &= ~(excepts & FE_ALL_EXCEPT);
+
+ /* Put the new state in effect. */
+ fesetenv_register (fpescr);
+
+ /* Success. */
+ return 0;
+}
+
diff --git a/libm/powerpc/e500/fpu/fe_nomask.c b/libm/powerpc/e500/fpu/fe_nomask.c
new file mode 100644
index 000000000..ad7b324c0
--- /dev/null
+++ b/libm/powerpc/e500/fpu/fe_nomask.c
@@ -0,0 +1,32 @@
+/* Procedure definition for FE_NOMASK_ENV.
+ Copyright (C) 1997 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <errno.h>
+
+/* This is presently a stub, until it's decided how the kernels should
+ support this. */
+
+const fenv_t *
+__fe_nomask_env(void)
+{
+ __set_errno (ENOSYS);
+ return FE_ENABLED_ENV;
+}
+
diff --git a/libm/powerpc/e500/fpu/fedisblxcpt.c b/libm/powerpc/e500/fpu/fedisblxcpt.c
new file mode 100644
index 000000000..d2c5caba7
--- /dev/null
+++ b/libm/powerpc/e500/fpu/fedisblxcpt.c
@@ -0,0 +1,60 @@
+/* Disable floating-point exceptions.
+ Copyright (C) 2004 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "fenv_libc.h"
+#include <syscall.h>
+#include <sys/prctl.h>
+
+int
+fedisableexcept (int excepts)
+{
+ unsigned int result = 0, pflags, r;
+ INTERNAL_SYSCALL_DECL (err);
+
+ INTERNAL_SYSCALL (prctl, err, 2, PR_GET_FPEXC, &pflags);
+
+ /* Save old enable bits. */
+ if (pflags & PR_FP_EXC_OVF)
+ result |= FE_OVERFLOW;
+ if (pflags & PR_FP_EXC_UND)
+ result |= FE_UNDERFLOW;
+ if (pflags & PR_FP_EXC_INV)
+ result |= FE_INVALID;
+ if (pflags & PR_FP_EXC_DIV)
+ result |= FE_DIVBYZERO;
+ if (pflags & PR_FP_EXC_RES)
+ result |= FE_INEXACT;
+
+ if (excepts & FE_INEXACT)
+ pflags &= ~PR_FP_EXC_RES;
+ if (excepts & FE_DIVBYZERO)
+ pflags &= ~PR_FP_EXC_DIV;
+ if (excepts & FE_UNDERFLOW)
+ pflags &= ~PR_FP_EXC_UND;
+ if (excepts & FE_OVERFLOW)
+ pflags &= ~PR_FP_EXC_OVF;
+ if (excepts & FE_INVALID)
+ pflags &= ~PR_FP_EXC_INV;
+ r = INTERNAL_SYSCALL (prctl, err, 2, PR_SET_FPEXC, pflags);
+ if (INTERNAL_SYSCALL_ERROR_P (r, err))
+ return -1;
+
+ return result;
+}
diff --git a/libm/powerpc/e500/fpu/feenablxcpt.c b/libm/powerpc/e500/fpu/feenablxcpt.c
new file mode 100644
index 000000000..4f00a918d
--- /dev/null
+++ b/libm/powerpc/e500/fpu/feenablxcpt.c
@@ -0,0 +1,60 @@
+/* Enable floating-point exceptions.
+ Copyright (C) 2004 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "fenv_libc.h"
+#include <syscall.h>
+#include <sys/prctl.h>
+
+int
+feenableexcept (int excepts)
+{
+ unsigned int result = 0, pflags, r;
+ INTERNAL_SYSCALL_DECL (err);
+
+ INTERNAL_SYSCALL (prctl, err, 2, PR_GET_FPEXC, &pflags);
+
+ /* Save old enable bits. */
+ if (pflags & PR_FP_EXC_OVF)
+ result |= FE_OVERFLOW;
+ if (pflags & PR_FP_EXC_UND)
+ result |= FE_UNDERFLOW;
+ if (pflags & PR_FP_EXC_INV)
+ result |= FE_INVALID;
+ if (pflags & PR_FP_EXC_DIV)
+ result |= FE_DIVBYZERO;
+ if (pflags & PR_FP_EXC_RES)
+ result |= FE_INEXACT;
+
+ if (excepts & FE_INEXACT)
+ pflags |= PR_FP_EXC_RES;
+ if (excepts & FE_DIVBYZERO)
+ pflags |= PR_FP_EXC_DIV;
+ if (excepts & FE_UNDERFLOW)
+ pflags |= PR_FP_EXC_UND;
+ if (excepts & FE_OVERFLOW)
+ pflags |= PR_FP_EXC_OVF;
+ if (excepts & FE_INVALID)
+ pflags |= PR_FP_EXC_INV;
+ r = INTERNAL_SYSCALL (prctl, err, 2, PR_SET_FPEXC, pflags);
+ if (INTERNAL_SYSCALL_ERROR_P (r, err))
+ return -1;
+
+ return result;
+}
diff --git a/libm/powerpc/e500/fpu/fegetenv.c b/libm/powerpc/e500/fpu/fegetenv.c
new file mode 100644
index 000000000..fbafdc208
--- /dev/null
+++ b/libm/powerpc/e500/fpu/fegetenv.c
@@ -0,0 +1,38 @@
+/* Store current floating-point environment.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ Contributed by Aldy Hernandez <aldyh@redhat.com>, 2004
+ 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "fenv_libc.h"
+#include <syscall.h>
+#include <sys/prctl.h>
+
+int
+__fegetenv (fenv_t *envp)
+{
+ fenv_union_t u;
+ INTERNAL_SYSCALL_DECL (err);
+
+ INTERNAL_SYSCALL (prctl, err, 2, PR_GET_FPEXC, &u.l[0]);
+ u.l[1] = fegetenv_register ();
+ *envp = u.fenv;
+
+ /* Success. */
+ return 0;
+}
+
diff --git a/libm/powerpc/e500/fpu/fegetexcept.c b/libm/powerpc/e500/fpu/fegetexcept.c
new file mode 100644
index 000000000..c0398461c
--- /dev/null
+++ b/libm/powerpc/e500/fpu/fegetexcept.c
@@ -0,0 +1,31 @@
+/* Get floating-point exceptions.
+ Copyright (C) 2004 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "fenv_libc.h"
+
+int
+fegetexcept (void)
+{
+ unsigned long fpescr;
+
+ fpescr = fegetenv_register ();
+
+ return fpescr & FE_ALL_EXCEPT;
+}
diff --git a/libm/powerpc/e500/fpu/fegetround.c b/libm/powerpc/e500/fpu/fegetround.c
new file mode 100644
index 000000000..6e568fa23
--- /dev/null
+++ b/libm/powerpc/e500/fpu/fegetround.c
@@ -0,0 +1,31 @@
+/* Return current rounding direction.
+ Copyright (C) 2004 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "fenv_libc.h"
+
+#undef fegetround
+int
+fegetround (void)
+{
+ unsigned long fpescr;
+
+ fpescr = fegetenv_register ();
+ return fpescr & 3;
+}
diff --git a/libm/powerpc/e500/fpu/feholdexcpt.c b/libm/powerpc/e500/fpu/feholdexcpt.c
new file mode 100644
index 000000000..eccde4217
--- /dev/null
+++ b/libm/powerpc/e500/fpu/feholdexcpt.c
@@ -0,0 +1,45 @@
+/* Store current floating-point environment and clear exceptions.
+ Copyright (C) 2004, 2006 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "fenv_libc.h"
+#include <syscall.h>
+#include <sys/prctl.h>
+
+int
+feholdexcept (fenv_t *envp)
+{
+ fenv_union_t u;
+ INTERNAL_SYSCALL_DECL (err);
+
+
+ /* Get the current state. */
+ INTERNAL_SYSCALL (prctl, err, 2, PR_GET_FPEXC, &u.l[0]);
+ u.l[1] = fegetenv_register ();
+ *envp = u.fenv;
+
+ /* Clear everything except for the rounding mode. */
+ u.l[1] &= 3;
+
+ /* Put the new state in effect. */
+ fesetenv_register (u.l[1]);
+
+ return 0;
+}
+libm_hidden_def (feholdexcept)
diff --git a/libm/powerpc/e500/fpu/fenv_const.c b/libm/powerpc/e500/fpu/fenv_const.c
new file mode 100644
index 000000000..073fc9277
--- /dev/null
+++ b/libm/powerpc/e500/fpu/fenv_const.c
@@ -0,0 +1,27 @@
+/* Constants for fenv_bits.h.
+ Copyright (C) 2004 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* If the default argument is used we use this value. */
+const unsigned long long __fe_dfl_env __attribute__ ((aligned (8))) =
+0x0ULL;
+
+/* Floating-point environment where none of the exceptions are masked. */
+const unsigned long long __fe_enabled_env __attribute__ ((aligned (8))) =
+0xF00000000ULL;
diff --git a/libm/powerpc/e500/fpu/fenv_libc.h b/libm/powerpc/e500/fpu/fenv_libc.h
new file mode 100644
index 000000000..cd003eab7
--- /dev/null
+++ b/libm/powerpc/e500/fpu/fenv_libc.h
@@ -0,0 +1,77 @@
+/* Internal libc stuff for floating point environment routines.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ Contributed by Aldy Hernandez <aldyh@redhat.com>, 2004
+ 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _FENV_LIBC_H
+#define _FENV_LIBC_H 1
+
+#include <fenv.h>
+
+extern int __feraiseexcept_internal (int __excepts);
+
+/* Equivalent to fegetenv, but returns a fenv_t instead of taking a
+ pointer. */
+#define fegetenv_register() \
+ ({ unsigned fscr; asm volatile ("mfspefscr %0" : "=r" (fscr)); fscr; })
+
+/* Equivalent to fesetenv, but takes a fenv_t 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,
+ 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,
+ SPEFSCR_FRMC = 0x00000003
+};
+
+#endif /* fenv_libc.h */
diff --git a/libm/powerpc/e500/fpu/fesetenv.c b/libm/powerpc/e500/fpu/fesetenv.c
new file mode 100644
index 000000000..cc0cc18be
--- /dev/null
+++ b/libm/powerpc/e500/fpu/fesetenv.c
@@ -0,0 +1,38 @@
+/* Install given floating-point environment.
+ Copyright (C) 1997,99,2000,01,02 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "fenv_libc.h"
+#include <syscall.h>
+#include <sys/prctl.h>
+
+int
+__fesetenv (const fenv_t *envp)
+{
+ fenv_union_t u;
+ INTERNAL_SYSCALL_DECL (err);
+
+ u.fenv = *envp;
+ INTERNAL_SYSCALL (prctl, err, 2, PR_SET_FPEXC, &u.l[0]);
+ fesetenv_register (u.l[1]);
+
+ /* Success. */
+ return 0;
+}
+
+libm_hidden_ver (__fesetenv, fesetenv)
diff --git a/libm/powerpc/e500/fpu/fesetround.c b/libm/powerpc/e500/fpu/fesetround.c
new file mode 100644
index 000000000..0f29a91a6
--- /dev/null
+++ b/libm/powerpc/e500/fpu/fesetround.c
@@ -0,0 +1,37 @@
+/* Set current rounding direction.
+ Copyright (C) 2004, 2006 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#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/libm/powerpc/e500/fpu/feupdateenv.c b/libm/powerpc/e500/fpu/feupdateenv.c
new file mode 100644
index 000000000..03f3af8d9
--- /dev/null
+++ b/libm/powerpc/e500/fpu/feupdateenv.c
@@ -0,0 +1,49 @@
+/* Install given floating-point environment and raise exceptions.
+ Copyright (C) 2004 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "fenv_libc.h"
+#include <syscall.h>
+#include <sys/prctl.h>
+
+int
+__feupdateenv (const fenv_t *envp)
+{
+ unsigned long fpescr, old, new, pflags;
+ fenv_union_t u;
+ INTERNAL_SYSCALL_DECL (err);
+
+ /* Save the currently set exceptions. */
+ u.fenv = *envp;
+ new = u.l[1];
+ old = fegetenv_register ();
+ new |= (old & FE_ALL_EXCEPT);
+
+ INTERNAL_SYSCALL (prctl, err, 2, PR_GET_FPEXC, &pflags);
+ pflags |= u.l[0];
+ INTERNAL_SYSCALL (prctl, err, 2, PR_SET_FPEXC, pflags);
+
+ /* Enable and raise (if appropriate) exceptions set in `new'. */
+ fesetenv_register (new);
+ feraiseexcept (new & FE_ALL_EXCEPT);
+
+ /* Success. */
+ return 0;
+}
+
diff --git a/libm/powerpc/e500/fpu/fgetexcptflg.c b/libm/powerpc/e500/fpu/fgetexcptflg.c
new file mode 100644
index 000000000..62d7f2c32
--- /dev/null
+++ b/libm/powerpc/e500/fpu/fgetexcptflg.c
@@ -0,0 +1,39 @@
+/* Store current representation for exceptions.
+ Copyright (C) 2004 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "fenv_libc.h"
+
+int
+__fegetexceptflag (fexcept_t *flagp, int excepts)
+{
+ unsigned long fpescr;
+
+ /* Get the current state. */
+ fpescr = fegetenv_register ();
+
+ /* ?? Classic PPC doesn't do anything with `excepts', so we'll do
+ the same here. (We should really be ignoring exceptions in
+ excepts) ?? */
+ *flagp = fpescr & FE_ALL_EXCEPT;
+
+ /* Success. */
+ return 0;
+}
+
diff --git a/libm/powerpc/e500/fpu/fraiseexcpt.c b/libm/powerpc/e500/fpu/fraiseexcpt.c
new file mode 100644
index 000000000..39caf79d3
--- /dev/null
+++ b/libm/powerpc/e500/fpu/fraiseexcpt.c
@@ -0,0 +1,29 @@
+/* Raise given exceptions.
+ Copyright (C) 2004, 2006 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "fenv_libc.h"
+
+#undef feraiseexcept
+
+#define __FERAISEEXCEPT_INTERNAL feraiseexcept
+
+#include "../spe-raise.c"
+
+libm_hidden_def (feraiseexcept)
diff --git a/libm/powerpc/e500/fpu/fsetexcptflg.c b/libm/powerpc/e500/fpu/fsetexcptflg.c
new file mode 100644
index 000000000..8e4bb895d
--- /dev/null
+++ b/libm/powerpc/e500/fpu/fsetexcptflg.c
@@ -0,0 +1,46 @@
+/* Set floating-point environment exception handling.
+ Copyright (C) 1997,99,2000,01,04 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "fenv_libc.h"
+
+int
+__fesetexceptflag (const fexcept_t *flagp, int excepts)
+{
+ unsigned long spefscr;
+ fexcept_t flag;
+
+ /* Get the current state. */
+ spefscr = fegetenv_register ();
+
+ /* Ignore exceptions not listed in 'excepts'. */
+ flag = *flagp & excepts;
+
+ /* Replace the exception status */
+ spefscr = (spefscr & ~FE_ALL_EXCEPT) | flag;
+
+ /* Store the new status word (along with the rest of the environment).
+ This may cause floating-point exceptions if the restored state
+ requests it. */
+ fesetenv_register (spefscr);
+ feraiseexcept (spefscr & FE_ALL_EXCEPT);
+
+ /* Success. */
+ return 0;
+}
+
diff --git a/libm/powerpc/e500/fpu/ftestexcept.c b/libm/powerpc/e500/fpu/ftestexcept.c
new file mode 100644
index 000000000..971c51965
--- /dev/null
+++ b/libm/powerpc/e500/fpu/ftestexcept.c
@@ -0,0 +1,32 @@
+/* Test exception in current environment.
+ Copyright (C) 2004 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "fenv_libc.h"
+
+int
+fetestexcept (int excepts)
+{
+ unsigned long f;
+
+ /* Get the current state. */
+ f = fegetenv_register ();
+
+ return f & excepts;
+}
diff --git a/libm/powerpc/e500/spe-raise.c b/libm/powerpc/e500/spe-raise.c
new file mode 100644
index 000000000..fb53dcec7
--- /dev/null
+++ b/libm/powerpc/e500/spe-raise.c
@@ -0,0 +1,67 @@
+/* Raise given exceptions.
+ Copyright (C) 1997,99,2000,01,02,04 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "fpu/fenv_libc.h"
+
+int
+__FERAISEEXCEPT_INTERNAL (int excepts)
+{
+ unsigned long f;
+
+ f = fegetenv_register ();
+ f |= (excepts & FE_ALL_EXCEPT);
+ fesetenv_register (f);
+
+ /* Force the operations that cause the exceptions. */
+ if ((FE_INVALID & excepts) != 0)
+ {
+ /* ?? Does not set sticky bit ?? */
+ /* 0 / 0 */
+ asm volatile ("efsdiv %0,%0,%1" : : "r" (0), "r" (0));
+ }
+
+ if ((FE_DIVBYZERO & excepts) != 0)
+ {
+ /* 1.0 / 0.0 */
+ asm volatile ("efsdiv %0,%0,%1" : : "r" (1.0F), "r" (0));
+ }
+
+ if ((FE_OVERFLOW & excepts) != 0)
+ {
+ /* ?? Does not set sticky bit ?? */
+ /* Largest normalized number plus itself. */
+ asm volatile ("efsadd %0,%0,%1" : : "r" (0x7f7fffff), "r" (0x7f7fffff));
+ }
+
+ if ((FE_UNDERFLOW & excepts) != 0)
+ {
+ /* ?? Does not set sticky bit ?? */
+ /* Smallest normalized number times itself. */
+ asm volatile ("efsmul %0,%0,%1" : : "r" (0x800000), "r" (0x800000));
+ }
+
+ if ((FE_INEXACT & 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;
+}