From e7bcf43b6440ac9fc61a0eef5591393810daafb5 Mon Sep 17 00:00:00 2001 From: Joakim Tjernlund Date: Sat, 31 Mar 2007 13:28:15 +0000 Subject: [PATCH] From Steve Papacharalambous: Add math support for PowerPC e500. --- libm/Makefile.in | 21 +++++++++ libm/powerpc/{ => classic}/Makefile.arch | 0 libm/powerpc/{ => classic}/s_ceil.c | 0 libm/powerpc/{ => classic}/s_copysign.c | 0 libm/powerpc/{ => classic}/s_floor.c | 0 libm/powerpc/{ => classic}/s_frexp.c | 0 libm/powerpc/{ => classic}/s_ldexp.c | 0 libm/powerpc/{ => classic}/s_logb.c | 0 libm/powerpc/{ => classic}/s_modf.c | 0 libm/powerpc/{ => classic}/s_nearbyint.c | 0 libm/powerpc/{ => classic}/s_rint.c | 0 libm/powerpc/{ => classic}/s_round.c | 0 libm/powerpc/{ => classic}/s_trunc.c | 0 libm/powerpc/{ => classic}/w_scalb.c | 0 libm/powerpc/e500/Makefile.arch | 9 ++++ libm/powerpc/e500/README.txt | 8 ++++ libm/powerpc/e500/fpu/Makefile.arch | 19 ++++++++ libm/powerpc/e500/fpu/fclrexcpt.c | 39 ++++++++++++++++ libm/powerpc/e500/fpu/fe_nomask.c | 32 +++++++++++++ libm/powerpc/e500/fpu/fedisblxcpt.c | 60 +++++++++++++++++++++++++ libm/powerpc/e500/fpu/feenablxcpt.c | 60 +++++++++++++++++++++++++ libm/powerpc/e500/fpu/fegetenv.c | 38 ++++++++++++++++ libm/powerpc/e500/fpu/fegetexcept.c | 31 +++++++++++++ libm/powerpc/e500/fpu/fegetround.c | 31 +++++++++++++ libm/powerpc/e500/fpu/feholdexcpt.c | 45 +++++++++++++++++++ libm/powerpc/e500/fpu/fenv_const.c | 27 +++++++++++ libm/powerpc/e500/fpu/fenv_libc.h | 77 ++++++++++++++++++++++++++++++++ libm/powerpc/e500/fpu/fesetenv.c | 38 ++++++++++++++++ libm/powerpc/e500/fpu/fesetround.c | 37 +++++++++++++++ libm/powerpc/e500/fpu/feupdateenv.c | 49 ++++++++++++++++++++ libm/powerpc/e500/fpu/fgetexcptflg.c | 39 ++++++++++++++++ libm/powerpc/e500/fpu/fraiseexcpt.c | 29 ++++++++++++ libm/powerpc/e500/fpu/fsetexcptflg.c | 46 +++++++++++++++++++ libm/powerpc/e500/fpu/ftestexcept.c | 32 +++++++++++++ libm/powerpc/e500/spe-raise.c | 67 +++++++++++++++++++++++++++ 35 files changed, 834 insertions(+) rename libm/powerpc/{ => classic}/Makefile.arch (100%) rename libm/powerpc/{ => classic}/s_ceil.c (100%) rename libm/powerpc/{ => classic}/s_copysign.c (100%) rename libm/powerpc/{ => classic}/s_floor.c (100%) rename libm/powerpc/{ => classic}/s_frexp.c (100%) rename libm/powerpc/{ => classic}/s_ldexp.c (100%) rename libm/powerpc/{ => classic}/s_logb.c (100%) rename libm/powerpc/{ => classic}/s_modf.c (100%) rename libm/powerpc/{ => classic}/s_nearbyint.c (100%) rename libm/powerpc/{ => classic}/s_rint.c (100%) rename libm/powerpc/{ => classic}/s_round.c (100%) rename libm/powerpc/{ => classic}/s_trunc.c (100%) rename libm/powerpc/{ => classic}/w_scalb.c (100%) create mode 100644 libm/powerpc/e500/Makefile.arch create mode 100644 libm/powerpc/e500/README.txt create mode 100644 libm/powerpc/e500/fpu/Makefile.arch create mode 100644 libm/powerpc/e500/fpu/fclrexcpt.c create mode 100644 libm/powerpc/e500/fpu/fe_nomask.c create mode 100644 libm/powerpc/e500/fpu/fedisblxcpt.c create mode 100644 libm/powerpc/e500/fpu/feenablxcpt.c create mode 100644 libm/powerpc/e500/fpu/fegetenv.c create mode 100644 libm/powerpc/e500/fpu/fegetexcept.c create mode 100644 libm/powerpc/e500/fpu/fegetround.c create mode 100644 libm/powerpc/e500/fpu/feholdexcpt.c create mode 100644 libm/powerpc/e500/fpu/fenv_const.c create mode 100644 libm/powerpc/e500/fpu/fenv_libc.h create mode 100644 libm/powerpc/e500/fpu/fesetenv.c create mode 100644 libm/powerpc/e500/fpu/fesetround.c create mode 100644 libm/powerpc/e500/fpu/feupdateenv.c create mode 100644 libm/powerpc/e500/fpu/fgetexcptflg.c create mode 100644 libm/powerpc/e500/fpu/fraiseexcpt.c create mode 100644 libm/powerpc/e500/fpu/fsetexcptflg.c create mode 100644 libm/powerpc/e500/fpu/ftestexcept.c create mode 100644 libm/powerpc/e500/spe-raise.c 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 similarity index 100% rename from libm/powerpc/Makefile.arch rename to libm/powerpc/classic/Makefile.arch diff --git a/libm/powerpc/s_ceil.c b/libm/powerpc/classic/s_ceil.c similarity index 100% rename from libm/powerpc/s_ceil.c rename to libm/powerpc/classic/s_ceil.c diff --git a/libm/powerpc/s_copysign.c b/libm/powerpc/classic/s_copysign.c similarity index 100% rename from libm/powerpc/s_copysign.c rename to libm/powerpc/classic/s_copysign.c diff --git a/libm/powerpc/s_floor.c b/libm/powerpc/classic/s_floor.c similarity index 100% rename from libm/powerpc/s_floor.c rename to libm/powerpc/classic/s_floor.c diff --git a/libm/powerpc/s_frexp.c b/libm/powerpc/classic/s_frexp.c similarity index 100% rename from libm/powerpc/s_frexp.c rename to libm/powerpc/classic/s_frexp.c diff --git a/libm/powerpc/s_ldexp.c b/libm/powerpc/classic/s_ldexp.c similarity index 100% rename from libm/powerpc/s_ldexp.c rename to libm/powerpc/classic/s_ldexp.c diff --git a/libm/powerpc/s_logb.c b/libm/powerpc/classic/s_logb.c similarity index 100% rename from libm/powerpc/s_logb.c rename to libm/powerpc/classic/s_logb.c diff --git a/libm/powerpc/s_modf.c b/libm/powerpc/classic/s_modf.c similarity index 100% rename from libm/powerpc/s_modf.c rename to libm/powerpc/classic/s_modf.c diff --git a/libm/powerpc/s_nearbyint.c b/libm/powerpc/classic/s_nearbyint.c similarity index 100% rename from libm/powerpc/s_nearbyint.c rename to libm/powerpc/classic/s_nearbyint.c diff --git a/libm/powerpc/s_rint.c b/libm/powerpc/classic/s_rint.c similarity index 100% rename from libm/powerpc/s_rint.c rename to libm/powerpc/classic/s_rint.c diff --git a/libm/powerpc/s_round.c b/libm/powerpc/classic/s_round.c similarity index 100% rename from libm/powerpc/s_round.c rename to libm/powerpc/classic/s_round.c diff --git a/libm/powerpc/s_trunc.c b/libm/powerpc/classic/s_trunc.c similarity index 100% rename from libm/powerpc/s_trunc.c rename to libm/powerpc/classic/s_trunc.c diff --git a/libm/powerpc/w_scalb.c b/libm/powerpc/classic/w_scalb.c similarity index 100% rename from libm/powerpc/w_scalb.c rename to 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 +# +# 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, , and the port to eglibc was done by +Joseph S. Myers, + +It has been ported to uClibc by Steve Papacharalambous + 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 +# +# 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 +#include + +/* 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 , 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 +#include + +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 , 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 +#include + +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 , 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 +#include + +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 , 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 , 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 , 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 +#include + +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 , 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 , 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 + +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 +#include + +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 , 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 , 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 +#include + +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 , 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 , 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 , 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; +} -- 2.11.0