diff options
34 files changed, 846 insertions, 33 deletions
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..ee4ceb5fc 100644 --- a/libm/powerpc/s_ceil.c +++ b/libm/powerpc/classic/s_ceil.c @@ -75,9 +75,9 @@ double ceil ( double x ) return ( x ); else { // inexact case - asm ("mffs %0" : "=f" (OldEnvironment.dbl)); + __asm__ ("mffs %0" : "=f" (OldEnvironment.dbl)); OldEnvironment.words.lo |= 0x02000000ul; - asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); + __asm__ ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); if ( target ) return ( 1.0 ); else diff --git a/libm/powerpc/s_copysign.c b/libm/powerpc/classic/s_copysign.c index 1a988ac87..c6f1307a3 100644 --- a/libm/powerpc/s_copysign.c +++ b/libm/powerpc/classic/s_copysign.c @@ -23,7 +23,7 @@ *******************************************************************************/ #include <math.h> -#include "../fp_private.h" +#include "../../fp_private.h" /******************************************************************************* * * diff --git a/libm/powerpc/s_floor.c b/libm/powerpc/classic/s_floor.c index ff3436707..2cd720eff 100644 --- a/libm/powerpc/s_floor.c +++ b/libm/powerpc/classic/s_floor.c @@ -75,9 +75,9 @@ double floor ( double x ) return ( x ); else { // inexact case - asm ("mffs %0" : "=f" (OldEnvironment.dbl)); + __asm__ ("mffs %0" : "=f" (OldEnvironment.dbl)); OldEnvironment.words.lo |= 0x02000000ul; - asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); + __asm__ ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); if ( target ) return ( 0.0 ); else 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..c2221bc0b 100644 --- a/libm/powerpc/s_modf.c +++ b/libm/powerpc/classic/s_modf.c @@ -104,12 +104,12 @@ long int rinttol ( double x ) return ( ( long ) argument.words.lo ); } - asm ("mffs %0" : "=f" (OldEnvironment.dbl)); // get environment + __asm__ ("mffs %0" : "=f" (OldEnvironment.dbl)); // get environment if ( xHead > 0x41dffffful ) { // x is safely out of long range OldEnvironment.words.lo |= SET_INVALID; - asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); + __asm__ ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); return ( LONG_MAX ); } @@ -121,7 +121,7 @@ long int rinttol ( double x ) if ( y > ( double ) LONG_MAX ) { // out of range of long OldEnvironment.words.lo |= SET_INVALID; - asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); + __asm__ ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); return ( LONG_MAX ); } argument.dbl = y + doubleToLong; // in range @@ -138,12 +138,12 @@ long int rinttol ( double x ) return ( ( long ) argument.words.lo ); } - asm ("mffs %0" : "=f" (OldEnvironment.dbl)); // get environment + __asm__ ("mffs %0" : "=f" (OldEnvironment.dbl)); // get environment if ( xHead > 0x41e00000ul ) { // x is safely out of long range OldEnvironment.words.lo |= SET_INVALID; - asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); + __asm__ ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); return ( LONG_MIN ); } @@ -155,7 +155,7 @@ long int rinttol ( double x ) if ( y < ( double ) LONG_MIN ) { // out of range of long OldEnvironment.words.lo |= SET_INVALID; - asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); + __asm__ ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); return ( LONG_MIN ); } argument.dbl = y + doubleToLong; // in range @@ -193,9 +193,9 @@ long int roundtol ( double x ) * Is x is out of long range or NaN? * *******************************************************************************/ { - asm ("mffs %0" : "=f" (OldEnvironment.dbl)); // get environment + __asm__ ("mffs %0" : "=f" (OldEnvironment.dbl)); // get environment OldEnvironment.words.lo |= SET_INVALID; - asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); + __asm__ ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); if ( target ) // pin result return ( LONG_MAX ); else @@ -215,11 +215,11 @@ long int roundtol ( double x ) y = ( x + doubleToLong ) - doubleToLong; // round at binary point if ( y != x ) { // inexact case - asm ("mffs %0" : "=f" (OldEnvironment.dbl)); // save environment - asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( kTZ.dbl )); // truncate rounding + __asm__ ("mffs %0" : "=f" (OldEnvironment.dbl)); // save environment + __asm__ ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( kTZ.dbl )); // truncate rounding z = x + 0.5; // truncate x + 0.5 argument.dbl = z + doubleToLong; - asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); + __asm__ ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); return ( ( long ) argument.words.lo ); } @@ -229,9 +229,9 @@ long int roundtol ( double x ) /******************************************************************************* * Rounded positive x is out of the range of a long. * *******************************************************************************/ - asm ("mffs %0" : "=f" (OldEnvironment.dbl)); + __asm__ ("mffs %0" : "=f" (OldEnvironment.dbl)); OldEnvironment.words.lo |= SET_INVALID; - asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); + __asm__ ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); return ( LONG_MAX ); // return pinned result } /******************************************************************************* @@ -245,11 +245,11 @@ long int roundtol ( double x ) y = ( x + doubleToLong ) - doubleToLong; // round at binary point if ( y != x ) { // inexact case - asm ("mffs %0" : "=f" (OldEnvironment.dbl)); // save environment - asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( kUP.dbl )); // round up + __asm__ ("mffs %0" : "=f" (OldEnvironment.dbl)); // save environment + __asm__ ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( kUP.dbl )); // round up z = x - 0.5; // truncate x - 0.5 argument.dbl = z + doubleToLong; - asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); + __asm__ ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); return ( ( long ) argument.words.lo ); } @@ -259,9 +259,9 @@ long int roundtol ( double x ) /******************************************************************************* * Rounded negative x is out of the range of a long. * *******************************************************************************/ - asm ("mffs %0" : "=f" (OldEnvironment.dbl)); + __asm__ ("mffs %0" : "=f" (OldEnvironment.dbl)); OldEnvironment.words.lo |= SET_INVALID; - asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); + __asm__ ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); return ( LONG_MIN ); // return pinned result } @@ -311,15 +311,15 @@ double modf ( double x, double *iptr ) /******************************************************************************* * Is 1.0 < |x| < 2.0^52? * *******************************************************************************/ - asm ("mffs %0" : "=f" (OldEnvironment)); // save environment + __asm__ ("mffs %0" : "=f" (OldEnvironment)); // save environment // round toward zero - asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( TOWARDZERO.dbl )); + __asm__ ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( TOWARDZERO.dbl )); if ( signBit == 0ul ) // truncate to integer xtrunc = ( x + twoTo52 ) - twoTo52; else xtrunc = ( x - twoTo52 ) + twoTo52; // restore caller's env - asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment )); + __asm__ ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment )); *iptr = xtrunc; // store integral part if ( x != xtrunc ) // nonzero fraction return ( x - xtrunc ); diff --git a/libm/powerpc/s_nearbyint.c b/libm/powerpc/classic/s_nearbyint.c index 068e21378..d08430dc6 100644 --- a/libm/powerpc/s_nearbyint.c +++ b/libm/powerpc/classic/s_nearbyint.c @@ -23,7 +23,7 @@ double nearbyint ( double x ) y = twoTo52; - asm ("mffs %0" : "=f" (OldEnvironment)); /* get the environement */ + __asm__ ("mffs %0" : "=f" (OldEnvironment)); /* get the environement */ if ( fabs ( x ) >= y ) /* huge case is exact */ return x; @@ -32,7 +32,7 @@ double nearbyint ( double x ) if ( y == 0.0 ) /* zero results mirror sign of x */ y = copysign ( y, x ); // restore old flags - asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment )); + __asm__ ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment )); return ( y ); } libm_hidden_def(nearbyint) 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..9fd73801d 100644 --- a/libm/powerpc/s_round.c +++ b/libm/powerpc/classic/s_round.c @@ -51,7 +51,7 @@ double round ( double x ) * Is |x| < 1.0? * *******************************************************************************/ { - asm ("mffs %0" : "=f" (OldEnvironment.dbl)); // get environment + __asm__ ("mffs %0" : "=f" (OldEnvironment.dbl)); // get environment if ( xHead < 0x3fe00000ul ) /******************************************************************************* * Is |x| < 0.5? * @@ -59,7 +59,7 @@ double round ( double x ) { if ( ( xHead | argument.words.lo ) != 0ul ) OldEnvironment.words.lo |= 0x02000000ul; - asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); + __asm__ ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); if ( target ) return ( 0.0 ); else @@ -69,7 +69,7 @@ double round ( double x ) * Is 0.5 ² |x| < 1.0? * *******************************************************************************/ OldEnvironment.words.lo |= 0x02000000ul; - asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); + __asm__ ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); if ( target ) return ( 1.0 ); else diff --git a/libm/powerpc/s_trunc.c b/libm/powerpc/classic/s_trunc.c index f793992a7..e9c668127 100644 --- a/libm/powerpc/s_trunc.c +++ b/libm/powerpc/classic/s_trunc.c @@ -51,9 +51,9 @@ double trunc ( double x ) { if ( ( xhi | argument.words.lo ) != 0ul ) { // raise deserved INEXACT - asm ("mffs %0" : "=f" (OldEnvironment.dbl)); + __asm__ ("mffs %0" : "=f" (OldEnvironment.dbl)); OldEnvironment.words.lo |= 0x02000000ul; - asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); + __asm__ ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); } if ( target ) // return properly signed zero return ( 0.0 ); 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..22c3f1452 --- /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..b83087fd0 --- /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; +} |