summaryrefslogtreecommitdiff
path: root/sysdeps/powerpc/powerpc32/fpu
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/powerpc/powerpc32/fpu')
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S2
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/__longjmp.S2
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/configure56
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/configure.ac34
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/fix-int-fp-convert-zero.h28
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/fprrest.S2
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/fprsave.S2
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_ceil.S2
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_ceilf.S2
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_copysign.S2
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_copysignl.S2
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_fabsl.S2
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_floor.S2
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_floorf.S2
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_isnan.S2
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_llrint.c33
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_llrintf.c24
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_llround.c90
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_llroundf.c72
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_lrint.S2
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_lround.S45
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_nearbyint.S8
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_nearbyintf.S8
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_rint.S2
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_rintf.S2
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_round.S11
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_roundf.S11
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_trunc.S2
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_truncf.S2
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/setjmp-common.S2
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/setjmp.S2
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