diff options
Diffstat (limited to 'sysdeps/powerpc/powerpc32/fpu')
31 files changed, 418 insertions, 40 deletions
diff --git a/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S b/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S index 7aa6718d50..5395410e61 100644 --- a/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S +++ b/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S @@ -1,5 +1,5 @@ /* longjmp for PowerPC. - Copyright (C) 1995-2015 Free Software Foundation, Inc. + Copyright (C) 1995-2016 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 diff --git a/sysdeps/powerpc/powerpc32/fpu/__longjmp.S b/sysdeps/powerpc/powerpc32/fpu/__longjmp.S index 31b1ce2589..529e0956cc 100644 --- a/sysdeps/powerpc/powerpc32/fpu/__longjmp.S +++ b/sysdeps/powerpc/powerpc32/fpu/__longjmp.S @@ -1,5 +1,5 @@ /* AltiVec/VMX (new) version of __longjmp for PowerPC. - Copyright (C) 1995-2015 Free Software Foundation, Inc. + Copyright (C) 1995-2016 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 diff --git a/sysdeps/powerpc/powerpc32/fpu/configure b/sysdeps/powerpc/powerpc32/fpu/configure new file mode 100644 index 0000000000..98c6f30ca3 --- /dev/null +++ b/sysdeps/powerpc/powerpc32/fpu/configure @@ -0,0 +1,56 @@ +# This file is generated from configure.ac by Autoconf. DO NOT EDIT! + # Local configure fragment for sysdeps/powerpc/powerpc32/fpu. + +# Test whether integer to floating point conversions use fcfid. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fcfid use" >&5 +$as_echo_n "checking for fcfid use... " >&6; } +if ${libc_cv_ppc_fcfid+:} false; then : + $as_echo_n "(cached) " >&6 +else + echo 'double foo (int x) { return (double) x; }' > conftest.c +libc_cv_ppc_fcfid=no +if { ac_try='${CC-cc} -S $CFLAGS conftest.c -o conftest.s 1>&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + if grep '[ ]fcfid' conftest.s > /dev/null 2>&1; then + libc_cv_ppc_fcfid=yes + fi +fi +rm -rf conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_ppc_fcfid" >&5 +$as_echo "$libc_cv_ppc_fcfid" >&6; } +if test $libc_cv_ppc_fcfid = yes; then + $as_echo "#define HAVE_PPC_FCFID 1" >>confdefs.h + +fi + +# Test whether floating point to long long conversions use fctidz. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fctidz use" >&5 +$as_echo_n "checking for fctidz use... " >&6; } +if ${libc_cv_ppc_fctidz+:} false; then : + $as_echo_n "(cached) " >&6 +else + echo 'long long int foo (double x) { return (long long int) x; }' > conftest.c +libc_cv_ppc_fctidz=no +if { ac_try='${CC-cc} -S $CFLAGS conftest.c -o conftest.s 1>&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + if grep '[ ]fctidz' conftest.s > /dev/null 2>&1; then + libc_cv_ppc_fctidz=yes + fi +fi +rm -rf conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_ppc_fctidz" >&5 +$as_echo "$libc_cv_ppc_fctidz" >&6; } +if test $libc_cv_ppc_fctidz = yes; then + $as_echo "#define HAVE_PPC_FCTIDZ 1" >>confdefs.h + +fi diff --git a/sysdeps/powerpc/powerpc32/fpu/configure.ac b/sysdeps/powerpc/powerpc32/fpu/configure.ac new file mode 100644 index 0000000000..1899705aab --- /dev/null +++ b/sysdeps/powerpc/powerpc32/fpu/configure.ac @@ -0,0 +1,34 @@ +GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. +# Local configure fragment for sysdeps/powerpc/powerpc32/fpu. + +# Test whether integer to floating point conversions use fcfid. +AC_CACHE_CHECK([for fcfid use], [libc_cv_ppc_fcfid], [dnl +echo 'double foo (int x) { return (double) x; }' > conftest.c +libc_cv_ppc_fcfid=no +if AC_TRY_COMMAND(${CC-cc} -S $CFLAGS conftest.c -o conftest.s 1>&AS_MESSAGE_LOG_FD); then +changequote(,)dnl + if grep '[ ]fcfid' conftest.s > /dev/null 2>&1; then + libc_cv_ppc_fcfid=yes + fi +changequote([,])dnl +fi +rm -rf conftest*]) +if test $libc_cv_ppc_fcfid = yes; then + AC_DEFINE([HAVE_PPC_FCFID]) +fi + +# Test whether floating point to long long conversions use fctidz. +AC_CACHE_CHECK([for fctidz use], [libc_cv_ppc_fctidz], [dnl +echo 'long long int foo (double x) { return (long long int) x; }' > conftest.c +libc_cv_ppc_fctidz=no +if AC_TRY_COMMAND(${CC-cc} -S $CFLAGS conftest.c -o conftest.s 1>&AS_MESSAGE_LOG_FD); then +changequote(,)dnl + if grep '[ ]fctidz' conftest.s > /dev/null 2>&1; then + libc_cv_ppc_fctidz=yes + fi +changequote([,])dnl +fi +rm -rf conftest*]) +if test $libc_cv_ppc_fctidz = yes; then + AC_DEFINE([HAVE_PPC_FCTIDZ]) +fi diff --git a/sysdeps/powerpc/powerpc32/fpu/fix-int-fp-convert-zero.h b/sysdeps/powerpc/powerpc32/fpu/fix-int-fp-convert-zero.h new file mode 100644 index 0000000000..a2d002c256 --- /dev/null +++ b/sysdeps/powerpc/powerpc32/fpu/fix-int-fp-convert-zero.h @@ -0,0 +1,28 @@ +/* Fix for conversion of integer 0 to floating point. PowerPC version. + Copyright (C) 2015-2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef FIX_INT_FP_CONVERT_ZERO_H +#define FIX_INT_FP_CONVERT_ZERO_H 1 + +/* The code sequences GCC generates for conversion of integers to + floating point result in -0 instead of +0 in FE_DOWNWARD mode when + the fcfid instruction is not used, as of GCC 5. See + <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67771>. */ +#define FIX_INT_FP_CONVERT_ZERO (!HAVE_PPC_FCFID) + +#endif /* fix-int-fp-convert-zero.h */ diff --git a/sysdeps/powerpc/powerpc32/fpu/fprrest.S b/sysdeps/powerpc/powerpc32/fpu/fprrest.S index 3b5e4e7e7a..df08df41d7 100644 --- a/sysdeps/powerpc/powerpc32/fpu/fprrest.S +++ b/sysdeps/powerpc/powerpc32/fpu/fprrest.S @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2015 Free Software Foundation, Inc. +/* Copyright (C) 2000-2016 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 diff --git a/sysdeps/powerpc/powerpc32/fpu/fprsave.S b/sysdeps/powerpc/powerpc32/fpu/fprsave.S index 7a22229e4c..4a257cdb46 100644 --- a/sysdeps/powerpc/powerpc32/fpu/fprsave.S +++ b/sysdeps/powerpc/powerpc32/fpu/fprsave.S @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2015 Free Software Foundation, Inc. +/* Copyright (C) 2000-2016 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 diff --git a/sysdeps/powerpc/powerpc32/fpu/s_ceil.S b/sysdeps/powerpc/powerpc32/fpu/s_ceil.S index 7288f1c8ab..48d6d0de19 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_ceil.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_ceil.S @@ -1,5 +1,5 @@ /* ceil function. PowerPC32 version. - Copyright (C) 2004-2015 Free Software Foundation, Inc. + Copyright (C) 2004-2016 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 diff --git a/sysdeps/powerpc/powerpc32/fpu/s_ceilf.S b/sysdeps/powerpc/powerpc32/fpu/s_ceilf.S index 92af077bf3..c70fd444e2 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_ceilf.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_ceilf.S @@ -1,5 +1,5 @@ /* float ceil function. PowerPC32 version. - Copyright (C) 2004-2015 Free Software Foundation, Inc. + Copyright (C) 2004-2016 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 diff --git a/sysdeps/powerpc/powerpc32/fpu/s_copysign.S b/sysdeps/powerpc/powerpc32/fpu/s_copysign.S index d553a7c690..05eb07df3f 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_copysign.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_copysign.S @@ -1,5 +1,5 @@ /* Copy a sign bit between floating-point values. - Copyright (C) 1997-2015 Free Software Foundation, Inc. + Copyright (C) 1997-2016 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 diff --git a/sysdeps/powerpc/powerpc32/fpu/s_copysignl.S b/sysdeps/powerpc/powerpc32/fpu/s_copysignl.S index 06f14cff81..aed783ad59 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_copysignl.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_copysignl.S @@ -1,6 +1,6 @@ /* Copy a sign bit between floating-point values. IBM extended format long double version. - Copyright (C) 2006-2015 Free Software Foundation, Inc. + Copyright (C) 2006-2016 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 diff --git a/sysdeps/powerpc/powerpc32/fpu/s_fabsl.S b/sysdeps/powerpc/powerpc32/fpu/s_fabsl.S index 280dedc21f..0462d20630 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_fabsl.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_fabsl.S @@ -1,6 +1,6 @@ /* Copy a sign bit between floating-point values. IBM extended format long double version. - Copyright (C) 2004-2015 Free Software Foundation, Inc. + Copyright (C) 2004-2016 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 diff --git a/sysdeps/powerpc/powerpc32/fpu/s_floor.S b/sysdeps/powerpc/powerpc32/fpu/s_floor.S index 032d41d84f..3f84465a8e 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_floor.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_floor.S @@ -1,5 +1,5 @@ /* Floor function. PowerPC32 version. - Copyright (C) 2004-2015 Free Software Foundation, Inc. + Copyright (C) 2004-2016 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 diff --git a/sysdeps/powerpc/powerpc32/fpu/s_floorf.S b/sysdeps/powerpc/powerpc32/fpu/s_floorf.S index 746424f945..55ac526d71 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_floorf.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_floorf.S @@ -1,5 +1,5 @@ /* float Floor function. PowerPC32 version. - Copyright (C) 2004-2015 Free Software Foundation, Inc. + Copyright (C) 2004-2016 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 diff --git a/sysdeps/powerpc/powerpc32/fpu/s_isnan.S b/sysdeps/powerpc/powerpc32/fpu/s_isnan.S index ee41d429f2..c33b89492d 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_isnan.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_isnan.S @@ -1,5 +1,5 @@ /* isnan(). PowerPC32 version. - Copyright (C) 2008-2015 Free Software Foundation, Inc. + Copyright (C) 2008-2016 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 diff --git a/sysdeps/powerpc/powerpc32/fpu/s_llrint.c b/sysdeps/powerpc/powerpc32/fpu/s_llrint.c index 48af9eb726..9cb72a1fd6 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_llrint.c +++ b/sysdeps/powerpc/powerpc32/fpu/s_llrint.c @@ -1,5 +1,5 @@ /* Round a double value to a long long in the current rounding mode. - Copyright (C) 1997-2015 Free Software Foundation, Inc. + Copyright (C) 1997-2016 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 @@ -16,13 +16,42 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ +#include <limits.h> #include <math.h> #include <math_ldbl_opt.h> +#include <math_private.h> +#include <stdint.h> long long int __llrint (double x) { - return (long long int) __rint (x); + double rx = __rint (x); + if (HAVE_PPC_FCTIDZ || rx != x) + return (long long int) rx; + else + { + /* Avoid incorrect exceptions from libgcc conversions (as of GCC + 5): <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59412>. */ + if (fabs (rx) < 0x1p31) + return (long long int) (long int) rx; + uint64_t i0; + EXTRACT_WORDS64 (i0, rx); + int exponent = ((i0 >> 52) & 0x7ff) - 0x3ff; + if (exponent < 63) + { + unsigned long long int mant + = (i0 & ((1ULL << 52) - 1)) | (1ULL << 52); + if (exponent < 52) + mant >>= 52 - exponent; + else + mant <<= exponent - 52; + return (long long int) ((i0 & (1ULL << 63)) != 0 ? -mant : mant); + } + else if (rx == (double) LLONG_MIN) + return LLONG_MIN; + else + return (long long int) (long int) rx << 32; + } } weak_alias (__llrint, llrint) #ifdef NO_LONG_DOUBLE diff --git a/sysdeps/powerpc/powerpc32/fpu/s_llrintf.c b/sysdeps/powerpc/powerpc32/fpu/s_llrintf.c index 205df4e03a..7151bed1c9 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_llrintf.c +++ b/sysdeps/powerpc/powerpc32/fpu/s_llrintf.c @@ -1,5 +1,5 @@ /* Round a float value to a long long in the current rounding mode. - Copyright (C) 1997-2015 Free Software Foundation, Inc. + Copyright (C) 1997-2016 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 @@ -17,10 +17,30 @@ <http://www.gnu.org/licenses/>. */ #include <math.h> +#include <math_private.h> +#include <stdint.h> long long int __llrintf (float x) { - return (long long int) __rintf (x); + float rx = __rintf (x); + if (HAVE_PPC_FCTIDZ || rx != x) + return (long long int) rx; + else + { + float arx = fabsf (rx); + /* Avoid incorrect exceptions from libgcc conversions (as of GCC + 5): <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59412>. */ + if (arx < 0x1p31f) + return (long long int) (long int) rx; + else if (!(arx < 0x1p55f)) + return (long long int) (long int) (rx * 0x1p-32f) << 32; + uint32_t i0; + GET_FLOAT_WORD (i0, rx); + int exponent = ((i0 >> 23) & 0xff) - 0x7f; + unsigned long long int mant = (i0 & 0x7fffff) | 0x800000; + mant <<= exponent - 23; + return (long long int) ((i0 & 0x80000000) != 0 ? -mant : mant); + } } weak_alias (__llrintf, llrintf) diff --git a/sysdeps/powerpc/powerpc32/fpu/s_llround.c b/sysdeps/powerpc/powerpc32/fpu/s_llround.c new file mode 100644 index 0000000000..b09949bce5 --- /dev/null +++ b/sysdeps/powerpc/powerpc32/fpu/s_llround.c @@ -0,0 +1,90 @@ +/* Round double value to long long int. + Copyright (C) 1997-2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <limits.h> +#include <math.h> +#include <math_ldbl_opt.h> +#include <math_private.h> +#include <stdint.h> + +/* Round to the nearest integer, with values exactly on a 0.5 boundary + rounded away from zero, regardless of the current rounding mode. + If (long long)x, when x is out of range of a long long, clips at + LLONG_MAX or LLONG_MIN, then this implementation also clips. */ + +long long int +__llround (double x) +{ + long long xr; + if (HAVE_PPC_FCTIDZ) + xr = (long long) x; + else + { + /* Avoid incorrect exceptions from libgcc conversions (as of GCC + 5): <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59412>. */ + if (fabs (x) < 0x1p31) + xr = (long long int) (long int) x; + else + { + uint64_t i0; + EXTRACT_WORDS64 (i0, x); + int exponent = ((i0 >> 52) & 0x7ff) - 0x3ff; + if (exponent < 63) + { + unsigned long long int mant + = (i0 & ((1ULL << 52) - 1)) | (1ULL << 52); + if (exponent < 52) + /* llround is not required to raise "inexact". */ + mant >>= 52 - exponent; + else + mant <<= exponent - 52; + xr = (long long int) ((i0 & (1ULL << 63)) != 0 ? -mant : mant); + } + else if (x == (double) LLONG_MIN) + xr = LLONG_MIN; + else + xr = (long long int) (long int) x << 32; + } + } + /* Avoid spurious "inexact" converting LLONG_MAX to double, and from + subtraction when the result is out of range, by returning early + for arguments large enough that no rounding is needed. */ + if (!(fabs (x) < 0x1p52)) + return xr; + double xrf = (double) xr; + + if (x >= 0.0) + { + if (x - xrf >= 0.5) + xr += (long long) ((unsigned long long) xr + 1) > 0; + } + else + { + if (xrf - x >= 0.5) + xr -= (long long) ((unsigned long long) xr - 1) < 0; + } + return xr; +} +weak_alias (__llround, llround) +#ifdef NO_LONG_DOUBLE +strong_alias (__llround, __llroundl) +weak_alias (__llround, llroundl) +#endif +#if LONG_DOUBLE_COMPAT (libm, GLIBC_2_1) +compat_symbol (libm, __llround, llroundl, GLIBC_2_1); +#endif diff --git a/sysdeps/powerpc/powerpc32/fpu/s_llroundf.c b/sysdeps/powerpc/powerpc32/fpu/s_llroundf.c new file mode 100644 index 0000000000..607977c0ab --- /dev/null +++ b/sysdeps/powerpc/powerpc32/fpu/s_llroundf.c @@ -0,0 +1,72 @@ +/* Round float value to long long int. + Copyright (C) 1997-2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <math.h> +#include <math_private.h> +#include <stdint.h> + +/* Round to the nearest integer, with values exactly on a 0.5 boundary + rounded away from zero, regardless of the current rounding mode. + If (long long)x, when x is out of range of a long long, clips at + LLONG_MAX or LLONG_MIN, then this implementation also clips. */ + +long long int +__llroundf (float x) +{ + long long xr; + if (HAVE_PPC_FCTIDZ) + xr = (long long) x; + else + { + float ax = fabsf (x); + /* Avoid incorrect exceptions from libgcc conversions (as of GCC + 5): <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59412>. */ + if (ax < 0x1p31f) + xr = (long long int) (long int) x; + else if (!(ax < 0x1p55f)) + xr = (long long int) (long int) (x * 0x1p-32f) << 32; + else + { + uint32_t i0; + GET_FLOAT_WORD (i0, x); + int exponent = ((i0 >> 23) & 0xff) - 0x7f; + unsigned long long int mant = (i0 & 0x7fffff) | 0x800000; + mant <<= exponent - 23; + xr = (long long int) ((i0 & 0x80000000) != 0 ? -mant : mant); + } + } + /* Avoid spurious "inexact" converting LLONG_MAX to float, and from + subtraction when the result is out of range, by returning early + for arguments large enough that no rounding is needed. */ + if (!(fabsf (x) < 0x1p23f)) + return xr; + float xrf = (float) xr; + + if (x >= 0.0) + { + if (x - xrf >= 0.5) + xr += (long long) ((unsigned long long) xr + 1) > 0; + } + else + { + if (xrf - x >= 0.5) + xr -= (long long) ((unsigned long long) xr - 1) < 0; + } + return xr; +} +weak_alias (__llroundf, llroundf) diff --git a/sysdeps/powerpc/powerpc32/fpu/s_lrint.S b/sysdeps/powerpc/powerpc32/fpu/s_lrint.S index 200a2195b3..54326268b7 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_lrint.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_lrint.S @@ -1,5 +1,5 @@ /* Round double to long int. PowerPC32 version. - Copyright (C) 2004-2015 Free Software Foundation, Inc. + Copyright (C) 2004-2016 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 diff --git a/sysdeps/powerpc/powerpc32/fpu/s_lround.S b/sysdeps/powerpc/powerpc32/fpu/s_lround.S index 231d5e4f45..66d9a67e1a 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_lround.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_lround.S @@ -1,5 +1,5 @@ /* lround function. PowerPC32 version. - Copyright (C) 2004-2015 Free Software Foundation, Inc. + Copyright (C) 2004-2016 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 @@ -23,6 +23,16 @@ .align 2 .LC0: /* 0.5 */ .long 0x3f000000 +.LC1: /* 2^52. */ + .long 0x59800000 + .section .rodata.cst8,"aM",@progbits,8 + .align 3 +.LC2: /* 0x7fffffff.8p0. */ + .long 0x41dfffff + .long 0xffe00000 +.LC3: /* -0x80000000.8p0. */ + .long 0xc1e00000 + .long 0x00100000 .section ".text" /* long [r3] lround (float x [fp1]) @@ -45,19 +55,40 @@ ENTRY (__lround) mflr r11 cfi_register(lr,r11) SETUP_GOT_ACCESS(r9,got_label) - addis r9,r9,.LC0-got_label@ha - lfs fp10,.LC0-got_label@l(r9) + addis r10,r9,.LC0-got_label@ha + lfs fp10,.LC0-got_label@l(r10) + addis r10,r9,.LC1-got_label@ha + lfs fp11,.LC1-got_label@l(r10) + addis r10,r9,.LC2-got_label@ha + lfd fp9,.LC2-got_label@l(r10) + addis r10,r9,.LC3-got_label@ha + lfd fp8,.LC3-got_label@l(r10) mtlr r11 cfi_same_value (lr) #else lis r9,.LC0@ha lfs fp10,.LC0@l(r9) + lis r9,.LC1@ha + lfs fp11,.LC1@l(r9) + lis r9,.LC2@ha + lfd fp9,.LC2@l(r9) + lis r9,.LC3@ha + lfd fp8,.LC3@l(r9) #endif fabs fp2, fp1 /* Get the absolute value of x. */ fsub fp12,fp10,fp10 /* Compute 0.0. */ fcmpu cr6, fp2, fp10 /* if |x| < 0.5 */ + fcmpu cr5, fp1, fp9 /* if x >= 0x7fffffff.8p0 */ + fcmpu cr1, fp1, fp8 /* if x <= -0x80000000.8p0 */ fcmpu cr7, fp1, fp12 /* x is negative? x < 0.0 */ blt- cr6,.Lretzero + bge- cr5,.Loflow + ble- cr1,.Loflow + /* Test whether an integer to avoid spurious "inexact". */ + fadd fp3,fp2,fp11 + fsub fp3,fp3,fp11 + fcmpu cr5, fp2, fp3 + beq cr5,.Lnobias fadd fp3,fp2,fp10 /* |x|+=0.5 bias to prepare to round. */ bge cr7,.Lconvert /* x is positive so don't negate x. */ fnabs fp3,fp3 /* -(|x|+=0.5) */ @@ -74,6 +105,14 @@ ENTRY (__lround) .Lretzero: /* when 0.5 > x > -0.5 */ li r3,0 /* return 0. */ b .Lout +.Lnobias: + fmr fp3,fp1 + b .Lconvert +.Loflow: + fmr fp3,fp11 + bge cr7,.Lconvert + fnabs fp3,fp3 + b .Lconvert END (__lround) weak_alias (__lround, lround) diff --git a/sysdeps/powerpc/powerpc32/fpu/s_nearbyint.S b/sysdeps/powerpc/powerpc32/fpu/s_nearbyint.S index cee4c7b239..68e3182b0d 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_nearbyint.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_nearbyint.S @@ -1,5 +1,5 @@ /* Round to int floating-point values. PowerPC32 version. - Copyright (C) 2011-2015 Free Software Foundation, Inc. + Copyright (C) 2011-2016 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Adhemerval Zanella <azanella@br.ibm.com>, 2011 @@ -52,19 +52,21 @@ ENTRY (__nearbyint) bgelr cr7 fcmpu cr7,fp1,fp12 /* if (x > 0.0 */ ble cr7,L(lessthanzero) + mffs fp11 mtfsb0 4*cr7+lt /* Disable FE_INEXACT exception */ fadd fp1,fp1,fp13 /* x += TWO52 */ fsub fp1,fp1,fp13 /* x -= TWO52 */ fabs fp1,fp1 /* if (x == 0.0 */ - mtfsb0 4*cr1+eq /* Clear any FE_INEXACT exception */ + mtfsf 0xff,fp11 /* Restore FE_INEXACT state. */ blr L(lessthanzero): bgelr cr7 + mffs fp11 mtfsb0 4*cr7+lt /* Disable FE_INEXACT exception */ fsub fp1,fp1,fp13 /* x -= TWO52 */ fadd fp1,fp1,fp13 /* x += TWO52 */ fnabs fp1,fp1 /* if (x == 0.0) */ - mtfsb0 4*cr1+eq /* Clear any FE_INEXACT exception */ + mtfsf 0xff,fp11 /* Restore FE_INEXACT state. */ blr END (__nearbyint) diff --git a/sysdeps/powerpc/powerpc32/fpu/s_nearbyintf.S b/sysdeps/powerpc/powerpc32/fpu/s_nearbyintf.S index 96a39c673d..107b035a24 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_nearbyintf.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_nearbyintf.S @@ -1,5 +1,5 @@ /* Round to int floating-point values. PowerPC32 version. - Copyright (C) 2011-2015 Free Software Foundation, Inc. + Copyright (C) 2011-2016 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Adhemerval Zanella <azanella@br.ibm.com>, 2011 @@ -51,19 +51,21 @@ ENTRY (__nearbyintf) bgelr cr7 fcmpu cr7,fp1,fp12 /* if (x > 0.0 */ ble cr7,L(lessthanzero) + mffs fp11 mtfsb0 4*cr7+lt /* Disable FE_INEXACT exception */ fadds fp1,fp1,fp13 /* x += TWO23 */ fsubs fp1,fp1,fp13 /* x -= TWO23 */ fabs fp1,fp1 /* if (x == 0.0) */ - mtfsb0 4*cr1+eq /* Clear any FE_INEXACT exception */ + mtfsf 0xff,fp11 /* Restore FE_INEXACT state. */ blr L(lessthanzero): bgelr cr7 + mffs fp11 mtfsb0 4*cr7+lt /* Disable FE_INEXACT exception */ fsubs fp1,fp1,fp13 /* x -= TWO23 */ fadds fp1,fp1,fp13 /* x += TWO23 */ fnabs fp1,fp1 /* if (x == 0.0) */ - mtfsb0 4*cr1+eq /* Clear any FE_INEXACT exception */ + mtfsf 0xff,fp11 /* Restore FE_INEXACT state. */ blr END (__nearbyintf) diff --git a/sysdeps/powerpc/powerpc32/fpu/s_rint.S b/sysdeps/powerpc/powerpc32/fpu/s_rint.S index dbe14ccaa0..5d78f3a5fc 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_rint.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_rint.S @@ -1,5 +1,5 @@ /* Round to int floating-point values. PowerPC32 version. - Copyright (C) 2004-2015 Free Software Foundation, Inc. + Copyright (C) 2004-2016 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 diff --git a/sysdeps/powerpc/powerpc32/fpu/s_rintf.S b/sysdeps/powerpc/powerpc32/fpu/s_rintf.S index c1e190519d..94b7045da6 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_rintf.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_rintf.S @@ -1,5 +1,5 @@ /* Round float to int floating-point values. PowerPC32 version. - Copyright (C) 2004-2015 Free Software Foundation, Inc. + Copyright (C) 2004-2016 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 diff --git a/sysdeps/powerpc/powerpc32/fpu/s_round.S b/sysdeps/powerpc/powerpc32/fpu/s_round.S index 061fbe2575..ae25364bd9 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_round.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_round.S @@ -1,5 +1,5 @@ /* round function. PowerPC32 version. - Copyright (C) 2004-2015 Free Software Foundation, Inc. + Copyright (C) 2004-2016 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 @@ -38,7 +38,6 @@ .section ".text" ENTRY (__round) - mffs fp11 /* Save current FPU rounding mode. */ #ifdef SHARED mflr r11 cfi_register(lr,r11) @@ -55,6 +54,8 @@ ENTRY (__round) fabs fp0,fp1 fsub fp12,fp13,fp13 /* generate 0.0 */ fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */ + mffs fp11 /* Save current FPU rounding mode and + "inexact" state. */ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ bnllr- cr7 mtfsfi 7,1 /* Set rounding mode toward 0. */ @@ -70,7 +71,8 @@ ENTRY (__round) fsub fp1,fp1,fp13 /* x-= TWO52; */ fabs fp1,fp1 /* if (x == 0.0) */ /* x = 0.0; */ - mtfsf 0x01,fp11 /* restore previous rounding mode. */ + mtfsf 0xff,fp11 /* Restore previous rounding mode and + "inexact" state. */ blr .L4: fsub fp9,fp1,fp10 /* x+= 0.5; */ @@ -80,7 +82,8 @@ ENTRY (__round) fnabs fp1,fp1 /* if (x == 0.0) */ /* x = -0.0; */ .L9: - mtfsf 0x01,fp11 /* restore previous rounding mode. */ + mtfsf 0xff,fp11 /* Restore previous rounding mode and + "inexact" state. */ blr END (__round) diff --git a/sysdeps/powerpc/powerpc32/fpu/s_roundf.S b/sysdeps/powerpc/powerpc32/fpu/s_roundf.S index 414bede361..f63248138f 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_roundf.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_roundf.S @@ -1,5 +1,5 @@ /* roundf function. PowerPC32 version. - Copyright (C) 2004-2015 Free Software Foundation, Inc. + Copyright (C) 2004-2016 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 @@ -37,7 +37,6 @@ .section ".text" ENTRY (__roundf ) - mffs fp11 /* Save current FPU rounding mode. */ #ifdef SHARED mflr r11 cfi_register(lr,r11) @@ -54,6 +53,8 @@ ENTRY (__roundf ) fabs fp0,fp1 fsubs fp12,fp13,fp13 /* generate 0.0 */ fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO23) */ + mffs fp11 /* Save current FPU rounding mode and + "inexact" state. */ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ bnllr- cr7 mtfsfi 7,1 /* Set rounding mode toward 0. */ @@ -68,7 +69,8 @@ ENTRY (__roundf ) fsubs fp1,fp1,fp13 /* x-= TWO23; */ fabs fp1,fp1 /* if (x == 0.0) */ /* x = 0.0; */ - mtfsf 0x01,fp11 /* restore previous rounding mode. */ + mtfsf 0xff,fp11 /* Restore previous rounding mode and + "inexact" state. */ blr .L4: fsubs fp9,fp1,fp10 /* x+= 0.5; */ @@ -78,7 +80,8 @@ ENTRY (__roundf ) fnabs fp1,fp1 /* if (x == 0.0) */ /* x = -0.0; */ .L9: - mtfsf 0x01,fp11 /* restore previous rounding mode. */ + mtfsf 0xff,fp11 /* Restore previous rounding mode and + "inexact" state. */ blr END (__roundf) diff --git a/sysdeps/powerpc/powerpc32/fpu/s_trunc.S b/sysdeps/powerpc/powerpc32/fpu/s_trunc.S index bf0cf46b0a..c8aa2fb245 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_trunc.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_trunc.S @@ -1,5 +1,5 @@ /* trunc function. PowerPC32 version. - Copyright (C) 2004-2015 Free Software Foundation, Inc. + Copyright (C) 2004-2016 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 diff --git a/sysdeps/powerpc/powerpc32/fpu/s_truncf.S b/sysdeps/powerpc/powerpc32/fpu/s_truncf.S index 81762bee72..e47ee96c55 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_truncf.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_truncf.S @@ -1,5 +1,5 @@ /* truncf function. PowerPC32 version. - Copyright (C) 2004-2015 Free Software Foundation, Inc. + Copyright (C) 2004-2016 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 diff --git a/sysdeps/powerpc/powerpc32/fpu/setjmp-common.S b/sysdeps/powerpc/powerpc32/fpu/setjmp-common.S index e3bfb30a1f..59f4e8b3da 100644 --- a/sysdeps/powerpc/powerpc32/fpu/setjmp-common.S +++ b/sysdeps/powerpc/powerpc32/fpu/setjmp-common.S @@ -1,5 +1,5 @@ /* setjmp for PowerPC. - Copyright (C) 1995-2015 Free Software Foundation, Inc. + Copyright (C) 1995-2016 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 diff --git a/sysdeps/powerpc/powerpc32/fpu/setjmp.S b/sysdeps/powerpc/powerpc32/fpu/setjmp.S index ccd84fea48..6a4016c229 100644 --- a/sysdeps/powerpc/powerpc32/fpu/setjmp.S +++ b/sysdeps/powerpc/powerpc32/fpu/setjmp.S @@ -1,5 +1,5 @@ /* non altivec (old) version of setjmp for PowerPC. - Copyright (C) 1995-2015 Free Software Foundation, Inc. + Copyright (C) 1995-2016 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 |