From 9dc874df52f8e7d251e4684cefe95320c31074fd Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 20 Mar 2000 20:32:11 +0000 Subject: [PATCH] * sysdeps/alpha/fpu/fraiseexcpt.c: Use get/set_fp_control instead of arithmetic instructions. * sysdeps/alpha/fpu/s_ceil.c: Use round to -inf instead of playing with the fpcr. Protect from INV exception. * sysdeps/alpha/fpu/s_ceilf.c: Likewise. * sysdeps/alpha/fpu/s_floor.c: Protect from INV exception. * sysdeps/alpha/fpu/s_floorf.c: Likewise. * sysdeps/alpha/fpu/s_copysign.c: New. * sysdeps/alpha/fpu/s_copysignf.c: New. * sysdeps/alpha/fpu/s_fabs.c: New. * sysdeps/alpha/fpu/s_fabsf.c: New. * sysdeps/alpha/fpu/s_rint.c: New. * sysdeps/alpha/fpu/s_rintf.c: New. --- sysdeps/alpha/fpu/{s_floor.c => fraiseexcpt.c} | 50 +++++++++++--------------- sysdeps/alpha/fpu/{s_floor.c => s_ceil.c} | 29 ++++++++------- sysdeps/alpha/fpu/{s_floorf.c => s_ceilf.c} | 24 +++++++------ sysdeps/alpha/fpu/{s_floor.c => s_copysign.c} | 30 ++++------------ sysdeps/alpha/fpu/{s_floor.c => s_copysignf.c} | 32 +++-------------- sysdeps/alpha/fpu/{s_floor.c => s_fabs.c} | 32 +++++------------ sysdeps/alpha/fpu/{s_floor.c => s_fabsf.c} | 34 +++++------------- sysdeps/alpha/fpu/s_floor.c | 14 +++++--- sysdeps/alpha/fpu/s_floorf.c | 13 ++++--- sysdeps/alpha/fpu/{s_floor.c => s_rint.c} | 31 ++++++++-------- sysdeps/alpha/fpu/{s_floorf.c => s_rintf.c} | 27 +++++++------- 11 files changed, 123 insertions(+), 193 deletions(-) copy sysdeps/alpha/fpu/{s_floor.c => fraiseexcpt.c} (51%) copy sysdeps/alpha/fpu/{s_floor.c => s_ceil.c} (67%) copy sysdeps/alpha/fpu/{s_floorf.c => s_ceilf.c} (72%) copy sysdeps/alpha/fpu/{s_floor.c => s_copysign.c} (56%) copy sysdeps/alpha/fpu/{s_floor.c => s_copysignf.c} (54%) copy sysdeps/alpha/fpu/{s_floor.c => s_fabs.c} (57%) copy sysdeps/alpha/fpu/{s_floor.c => s_fabsf.c} (55%) copy sysdeps/alpha/fpu/{s_floor.c => s_rint.c} (61%) copy sysdeps/alpha/fpu/{s_floorf.c => s_rintf.c} (68%) diff --git a/sysdeps/alpha/fpu/s_floor.c b/sysdeps/alpha/fpu/fraiseexcpt.c similarity index 51% copy from sysdeps/alpha/fpu/s_floor.c copy to sysdeps/alpha/fpu/fraiseexcpt.c index 146e19b35a..b0eab000cb 100644 --- a/sysdeps/alpha/fpu/s_floor.c +++ b/sysdeps/alpha/fpu/fraiseexcpt.c @@ -1,6 +1,7 @@ -/* Copyright (C) 1998, 1999 Free Software Foundation, Inc. +/* Raise given exceptions. + Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. This file is part of the GNU C Library. - Contributed by Richard Henderson. + Contributed by Richard Henderson , 1997. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as @@ -17,35 +18,26 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include #include +int +__feraiseexcept (int excepts) +{ + unsigned long int tmp; -/* Use the -inf rounding mode conversion instructions to implement - floor. We note when the exponent is large enough that the value - must be integral, as this avoids unpleasant integer overflows. */ + /* Get the current exception state. */ + tmp = __ieee_get_fp_control (); -double -__floor (double x) -{ - /* Check not zero since floor(-0) == -0. */ - if (x != 0 && fabs (x) < 9007199254740992.0) /* 1 << DBL_MANT_DIG */ - { - double __tmp1; - __asm ( -#ifdef _IEEE_FP_INEXACT - "cvttq/svim %2,%1\n\t" -#else - "cvttq/svm %2,%1\n\t" -#endif - "cvtqt/m %1,%0\n\t" - : "=f"(x), "=&f"(__tmp1) - : "f"(x)); - } - return x; -} + /* Set all the bits that were called for. */ + tmp |= (excepts & FE_ALL_EXCEPT); -weak_alias (__floor, floor) -#ifdef NO_LONG_DOUBLE -strong_alias (__floor, __floorl) -weak_alias (__floor, floorl) -#endif + /* And store it back. */ + __ieee_set_fp_control (tmp); + + /* Success. */ + return 0; +} +strong_alias (__feraiseexcept, __old_feraiseexcept) +symbol_version (__old_feraiseexcept, feraiseexcept, GLIBC_2.1); +default_symbol_version (__feraiseexcept, feraiseexcept, GLIBC_2.2); diff --git a/sysdeps/alpha/fpu/s_floor.c b/sysdeps/alpha/fpu/s_ceil.c similarity index 67% copy from sysdeps/alpha/fpu/s_floor.c copy to sysdeps/alpha/fpu/s_ceil.c index 146e19b35a..f30db008ce 100644 --- a/sysdeps/alpha/fpu/s_floor.c +++ b/sysdeps/alpha/fpu/s_ceil.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1998, 1999 Free Software Foundation, Inc. +/* Copyright (C) 1998, 2000 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Richard Henderson. @@ -19,18 +19,18 @@ #include - /* Use the -inf rounding mode conversion instructions to implement - floor. We note when the exponent is large enough that the value - must be integral, as this avoids unpleasant integer overflows. */ + ceil, via something akin to -floor(-x). This is much faster than + playing with the fpcr to achieve +inf rounding mode. */ double -__floor (double x) +__ceil (double x) { - /* Check not zero since floor(-0) == -0. */ - if (x != 0 && fabs (x) < 9007199254740992.0) /* 1 << DBL_MANT_DIG */ + if (isless (fabs (x), 9007199254740992.0)) /* 1 << DBL_MANT_DIG */ { - double __tmp1; + double tmp1, new_x; + + new_x = -x; __asm ( #ifdef _IEEE_FP_INEXACT "cvttq/svim %2,%1\n\t" @@ -38,14 +38,17 @@ __floor (double x) "cvttq/svm %2,%1\n\t" #endif "cvtqt/m %1,%0\n\t" - : "=f"(x), "=&f"(__tmp1) - : "f"(x)); + : "=f"(new_x), "=&f"(tmp1) + : "f"(new_x)); + + /* Fix up the negation we did above, as well as handling -0 properly. */ + x = copysign(new_x, x); } return x; } -weak_alias (__floor, floor) +weak_alias (__ceil, ceil) #ifdef NO_LONG_DOUBLE -strong_alias (__floor, __floorl) -weak_alias (__floor, floorl) +strong_alias (__ceil, __ceill) +weak_alias (__ceil, ceill) #endif diff --git a/sysdeps/alpha/fpu/s_floorf.c b/sysdeps/alpha/fpu/s_ceilf.c similarity index 72% copy from sysdeps/alpha/fpu/s_floorf.c copy to sysdeps/alpha/fpu/s_ceilf.c index 9e693642dd..35c51a2766 100644 --- a/sysdeps/alpha/fpu/s_floorf.c +++ b/sysdeps/alpha/fpu/s_ceilf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1998, 1999 Free Software Foundation, Inc. +/* Copyright (C) 1998, 2000 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Richard Henderson. @@ -19,24 +19,23 @@ #include - /* Use the -inf rounding mode conversion instructions to implement - floor. We note when the exponent is large enough that the value - must be integral, as this avoids unpleasant integer overflows. */ + ceil, via something akin to -floor(-x). This is much faster than + playing with the fpcr to achieve +inf rounding mode. */ float -__floorf (float x) +__ceilf (float x) { - /* Check not zero since floor(-0) == -0. */ - if (x != 0 && fabsf (x) < 16777216.0f) /* 1 << FLT_MANT_DIG */ + if (isless (fabsf (x), 16777216.0f)) /* 1 << FLT_MANT_DIG */ { /* Note that Alpha S_Floating is stored in registers in a restricted T_Floating format, so we don't even need to convert back to S_Floating in the end. The initial conversion to T_Floating is needed to handle denormals. */ - float tmp1, tmp2; + float tmp1, tmp2, new_x; + new_x = -x; __asm ("cvtst/s %3,%2\n\t" #ifdef _IEEE_FP_INEXACT "cvttq/svim %2,%1\n\t" @@ -44,10 +43,13 @@ __floorf (float x) "cvttq/svm %2,%1\n\t" #endif "cvtqt/m %1,%0\n\t" - : "=f"(x), "=&f"(tmp1), "=&f"(tmp2) - : "f"(x)); + : "=f"(new_x), "=&f"(tmp1), "=&f"(tmp2) + : "f"(new_x)); + + /* Fix up the negation we did above, as well as handling -0 properly. */ + x = copysignf(new_x, x); } return x; } -weak_alias (__floorf, floorf) +weak_alias (__ceilf, ceilf) diff --git a/sysdeps/alpha/fpu/s_floor.c b/sysdeps/alpha/fpu/s_copysign.c similarity index 56% copy from sysdeps/alpha/fpu/s_floor.c copy to sysdeps/alpha/fpu/s_copysign.c index 146e19b35a..5c8d827018 100644 --- a/sysdeps/alpha/fpu/s_floor.c +++ b/sysdeps/alpha/fpu/s_copysign.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1998, 1999 Free Software Foundation, Inc. +/* Copyright (C) 2000 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Richard Henderson. @@ -19,33 +19,15 @@ #include - -/* Use the -inf rounding mode conversion instructions to implement - floor. We note when the exponent is large enough that the value - must be integral, as this avoids unpleasant integer overflows. */ - double -__floor (double x) +__copysign (double x, double y) { - /* Check not zero since floor(-0) == -0. */ - if (x != 0 && fabs (x) < 9007199254740992.0) /* 1 << DBL_MANT_DIG */ - { - double __tmp1; - __asm ( -#ifdef _IEEE_FP_INEXACT - "cvttq/svim %2,%1\n\t" -#else - "cvttq/svm %2,%1\n\t" -#endif - "cvtqt/m %1,%0\n\t" - : "=f"(x), "=&f"(__tmp1) - : "f"(x)); - } + __asm ("cpys %1, %2, %0" : "=f" (x) : "f" (y), "f" (x)); return x; } -weak_alias (__floor, floor) +weak_alias (__copysign, copysign) #ifdef NO_LONG_DOUBLE -strong_alias (__floor, __floorl) -weak_alias (__floor, floorl) +strong_alias (__copysign, __copysignl) +weak_alias (__copysign, copysignl) #endif diff --git a/sysdeps/alpha/fpu/s_floor.c b/sysdeps/alpha/fpu/s_copysignf.c similarity index 54% copy from sysdeps/alpha/fpu/s_floor.c copy to sysdeps/alpha/fpu/s_copysignf.c index 146e19b35a..d2c5d886d0 100644 --- a/sysdeps/alpha/fpu/s_floor.c +++ b/sysdeps/alpha/fpu/s_copysignf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1998, 1999 Free Software Foundation, Inc. +/* Copyright (C) 2000 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Richard Henderson. @@ -19,33 +19,11 @@ #include - -/* Use the -inf rounding mode conversion instructions to implement - floor. We note when the exponent is large enough that the value - must be integral, as this avoids unpleasant integer overflows. */ - -double -__floor (double x) +float +__copysignf (float x, float y) { - /* Check not zero since floor(-0) == -0. */ - if (x != 0 && fabs (x) < 9007199254740992.0) /* 1 << DBL_MANT_DIG */ - { - double __tmp1; - __asm ( -#ifdef _IEEE_FP_INEXACT - "cvttq/svim %2,%1\n\t" -#else - "cvttq/svm %2,%1\n\t" -#endif - "cvtqt/m %1,%0\n\t" - : "=f"(x), "=&f"(__tmp1) - : "f"(x)); - } + __asm ("cpys %1, %2, %0" : "=f" (x) : "f" (y), "f" (x)); return x; } -weak_alias (__floor, floor) -#ifdef NO_LONG_DOUBLE -strong_alias (__floor, __floorl) -weak_alias (__floor, floorl) -#endif +weak_alias (__copysignf, copysignf) diff --git a/sysdeps/alpha/fpu/s_floor.c b/sysdeps/alpha/fpu/s_fabs.c similarity index 57% copy from sysdeps/alpha/fpu/s_floor.c copy to sysdeps/alpha/fpu/s_fabs.c index 146e19b35a..fb446d8cb9 100644 --- a/sysdeps/alpha/fpu/s_floor.c +++ b/sysdeps/alpha/fpu/s_fabs.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1998, 1999 Free Software Foundation, Inc. +/* Copyright (C) 2000 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Richard Henderson. @@ -19,33 +19,19 @@ #include - -/* Use the -inf rounding mode conversion instructions to implement - floor. We note when the exponent is large enough that the value - must be integral, as this avoids unpleasant integer overflows. */ - double -__floor (double x) +__fabs (double x) { - /* Check not zero since floor(-0) == -0. */ - if (x != 0 && fabs (x) < 9007199254740992.0) /* 1 << DBL_MANT_DIG */ - { - double __tmp1; - __asm ( -#ifdef _IEEE_FP_INEXACT - "cvttq/svim %2,%1\n\t" +#if __GNUC_PREREQ (2, 8) + return __builtin_fabs (x); #else - "cvttq/svm %2,%1\n\t" -#endif - "cvtqt/m %1,%0\n\t" - : "=f"(x), "=&f"(__tmp1) - : "f"(x)); - } + __asm ("cpys $f31, %1, %0" : "=f" (x) : "f" (x)); return x; +#endif } -weak_alias (__floor, floor) +weak_alias (__fabs, fabs) #ifdef NO_LONG_DOUBLE -strong_alias (__floor, __floorl) -weak_alias (__floor, floorl) +strong_alias (__fabs, __fabsl) +weak_alias (__fabs, fabsl) #endif diff --git a/sysdeps/alpha/fpu/s_floor.c b/sysdeps/alpha/fpu/s_fabsf.c similarity index 55% copy from sysdeps/alpha/fpu/s_floor.c copy to sysdeps/alpha/fpu/s_fabsf.c index 146e19b35a..ec5390747f 100644 --- a/sysdeps/alpha/fpu/s_floor.c +++ b/sysdeps/alpha/fpu/s_fabsf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1998, 1999 Free Software Foundation, Inc. +/* Copyright (C) 2000 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Richard Henderson. @@ -19,33 +19,15 @@ #include - -/* Use the -inf rounding mode conversion instructions to implement - floor. We note when the exponent is large enough that the value - must be integral, as this avoids unpleasant integer overflows. */ - -double -__floor (double x) +float +__fabsf (float x) { - /* Check not zero since floor(-0) == -0. */ - if (x != 0 && fabs (x) < 9007199254740992.0) /* 1 << DBL_MANT_DIG */ - { - double __tmp1; - __asm ( -#ifdef _IEEE_FP_INEXACT - "cvttq/svim %2,%1\n\t" +#if __GNUC_PREREQ (2, 8) + return __builtin_fabsf (x); #else - "cvttq/svm %2,%1\n\t" -#endif - "cvtqt/m %1,%0\n\t" - : "=f"(x), "=&f"(__tmp1) - : "f"(x)); - } + __asm ("cpys $f31, %1, %0" : "=f" (x) : "f" (x)); return x; +#endif } -weak_alias (__floor, floor) -#ifdef NO_LONG_DOUBLE -strong_alias (__floor, __floorl) -weak_alias (__floor, floorl) -#endif +weak_alias (__fabsf, fabsf) diff --git a/sysdeps/alpha/fpu/s_floor.c b/sysdeps/alpha/fpu/s_floor.c index 146e19b35a..b6d01f5947 100644 --- a/sysdeps/alpha/fpu/s_floor.c +++ b/sysdeps/alpha/fpu/s_floor.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1998, 1999 Free Software Foundation, Inc. +/* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Richard Henderson. @@ -27,10 +27,10 @@ double __floor (double x) { - /* Check not zero since floor(-0) == -0. */ - if (x != 0 && fabs (x) < 9007199254740992.0) /* 1 << DBL_MANT_DIG */ + if (isless (fabs (x), 9007199254740992.0)) /* 1 << DBL_MANT_DIG */ { - double __tmp1; + double tmp1, new_x; + __asm ( #ifdef _IEEE_FP_INEXACT "cvttq/svim %2,%1\n\t" @@ -38,8 +38,12 @@ __floor (double x) "cvttq/svm %2,%1\n\t" #endif "cvtqt/m %1,%0\n\t" - : "=f"(x), "=&f"(__tmp1) + : "=f"(new_x), "=&f"(tmp1) : "f"(x)); + + /* floor(-0) == -0, and in general we'll always have the same + sign as our input. */ + x = copysign(new_x, x); } return x; } diff --git a/sysdeps/alpha/fpu/s_floorf.c b/sysdeps/alpha/fpu/s_floorf.c index 9e693642dd..624e7c87b8 100644 --- a/sysdeps/alpha/fpu/s_floorf.c +++ b/sysdeps/alpha/fpu/s_floorf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1998, 1999 Free Software Foundation, Inc. +/* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Richard Henderson. @@ -27,15 +27,14 @@ float __floorf (float x) { - /* Check not zero since floor(-0) == -0. */ - if (x != 0 && fabsf (x) < 16777216.0f) /* 1 << FLT_MANT_DIG */ + if (isless (fabsf (x), 16777216.0f)) /* 1 << FLT_MANT_DIG */ { /* Note that Alpha S_Floating is stored in registers in a restricted T_Floating format, so we don't even need to convert back to S_Floating in the end. The initial conversion to T_Floating is needed to handle denormals. */ - float tmp1, tmp2; + float tmp1, tmp2, new_x; __asm ("cvtst/s %3,%2\n\t" #ifdef _IEEE_FP_INEXACT @@ -44,8 +43,12 @@ __floorf (float x) "cvttq/svm %2,%1\n\t" #endif "cvtqt/m %1,%0\n\t" - : "=f"(x), "=&f"(tmp1), "=&f"(tmp2) + : "=f"(new_x), "=&f"(tmp1), "=&f"(tmp2) : "f"(x)); + + /* floor(-0) == -0, and in general we'll always have the same + sign as our input. */ + x = copysignf(new_x, x); } return x; } diff --git a/sysdeps/alpha/fpu/s_floor.c b/sysdeps/alpha/fpu/s_rint.c similarity index 61% copy from sysdeps/alpha/fpu/s_floor.c copy to sysdeps/alpha/fpu/s_rint.c index 146e19b35a..7309b4134e 100644 --- a/sysdeps/alpha/fpu/s_floor.c +++ b/sysdeps/alpha/fpu/s_rint.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1998, 1999 Free Software Foundation, Inc. +/* Copyright (C) 2000 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Richard Henderson. @@ -20,32 +20,31 @@ #include -/* Use the -inf rounding mode conversion instructions to implement - floor. We note when the exponent is large enough that the value - must be integral, as this avoids unpleasant integer overflows. */ - double -__floor (double x) +__rint (double x) { - /* Check not zero since floor(-0) == -0. */ - if (x != 0 && fabs (x) < 9007199254740992.0) /* 1 << DBL_MANT_DIG */ + if (isless (fabs (x), 9007199254740992.0)) /* 1 << DBL_MANT_DIG */ { - double __tmp1; + double tmp1, new_x; __asm ( #ifdef _IEEE_FP_INEXACT - "cvttq/svim %2,%1\n\t" + "cvttq/svid %2,%1\n\t" #else - "cvttq/svm %2,%1\n\t" + "cvttq/svd %2,%1\n\t" #endif - "cvtqt/m %1,%0\n\t" - : "=f"(x), "=&f"(__tmp1) + "cvtqt/d %1,%0\n\t" + : "=f"(new_x), "=&f"(tmp1) : "f"(x)); + + /* rint(-0.1) == -0, and in general we'll always have the same + sign as our input. */ + x = copysign(new_x, x); } return x; } -weak_alias (__floor, floor) +weak_alias (__rint, rint) #ifdef NO_LONG_DOUBLE -strong_alias (__floor, __floorl) -weak_alias (__floor, floorl) +strong_alias (__rint, __rintl) +weak_alias (__rint, rintl) #endif diff --git a/sysdeps/alpha/fpu/s_floorf.c b/sysdeps/alpha/fpu/s_rintf.c similarity index 68% copy from sysdeps/alpha/fpu/s_floorf.c copy to sysdeps/alpha/fpu/s_rintf.c index 9e693642dd..044f7e5f7a 100644 --- a/sysdeps/alpha/fpu/s_floorf.c +++ b/sysdeps/alpha/fpu/s_rintf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1998, 1999 Free Software Foundation, Inc. +/* Copyright (C) 2000 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Richard Henderson. @@ -20,34 +20,33 @@ #include -/* Use the -inf rounding mode conversion instructions to implement - floor. We note when the exponent is large enough that the value - must be integral, as this avoids unpleasant integer overflows. */ - float -__floorf (float x) +__rintf (float x) { - /* Check not zero since floor(-0) == -0. */ - if (x != 0 && fabsf (x) < 16777216.0f) /* 1 << FLT_MANT_DIG */ + if (isless (fabsf (x), 16777216.0f)) /* 1 << FLT_MANT_DIG */ { /* Note that Alpha S_Floating is stored in registers in a restricted T_Floating format, so we don't even need to convert back to S_Floating in the end. The initial conversion to T_Floating is needed to handle denormals. */ - float tmp1, tmp2; + float tmp1, tmp2, new_x; __asm ("cvtst/s %3,%2\n\t" #ifdef _IEEE_FP_INEXACT - "cvttq/svim %2,%1\n\t" + "cvttq/svid %2,%1\n\t" #else - "cvttq/svm %2,%1\n\t" + "cvttq/svd %2,%1\n\t" #endif - "cvtqt/m %1,%0\n\t" - : "=f"(x), "=&f"(tmp1), "=&f"(tmp2) + "cvtqt/d %1,%0\n\t" + : "=f"(new_x), "=&f"(tmp1), "=&f"(tmp2) : "f"(x)); + + /* rint(-0.1) == -0, and in general we'll always have the same + sign as our input. */ + x = copysignf(new_x, x); } return x; } -weak_alias (__floorf, floorf) +weak_alias (__rintf, rintf) -- 2.11.4.GIT