binutils-gdb/gdb/gnulib/import/frexp.c
Sergio Durigan Junior 5e8754f90a Revert "Update gnulib to current upstream master"
This reverts commit 7a6dbc2fdb ("Update
gnulib to current upstream master").  It is needed because the gnulib
update caused problems with people using old GCC compilers (version
4.8, for example), which support C99 but don't default to using it.
Unfortunately this broke GDB for these users.  A more detailed report
of what happened can be found at:

  https://lists.gnu.org/archive/html/bug-gnulib/2018-08/msg00157.html

The reason for updating our gnulib copy was to fix PR gdb/23558.
Reverting this patch reintroduces the bug, so in order to fix it I
will submit a subsequent patch which cherry-picks the fix from gnulib.

gdb/ChangeLog:
2018-09-10  Sergio Durigan Junior  <sergiodj@redhat.com>

	Revert:
	2018-08-29  Sergio Durigan Junior  <sergiodj@redhat.com>

	PR gdb/23555
	PR gdb/23558
	* gnulib/aclocal.m4: Regenerate.
	* gnulib/config.in: Regenerate.
	* gnulib/configure: Regenerate.
	* gnulib/import/Makefile.am: Update.
	* gnulib/import/Makefile.in: Update.
	* gnulib/import/extra/snippet/_Noreturn.h: Rename to...
	* gnulib/import/_Noreturn.h: ... this.
	* gnulib/import/alloca.in.h: Update.
	* gnulib/import/extra/snippet/arg-nonnull.h: Rename to...
	* gnulib/import/arg-nonnull.h: ... this.
	* gnulib/import/assure.h: Update.
	* gnulib/import/at-func.c: Update.
	* gnulib/import/basename-lgpl.c: Update.
	* gnulib/import/extra/snippet/c++defs.h: Rename to...
	* gnulib/import/c++defs.h: ... this.
	* gnulib/import/canonicalize-lgpl.c: Update.
	* gnulib/import/cdefs.h: Update.
	* gnulib/import/chdir-long.c: Update.
	* gnulib/import/chdir-long.h: Update.
	* gnulib/import/cloexec.c: Update.
	* gnulib/import/cloexec.h: Update.
	* gnulib/import/close.c: Update.
	* gnulib/import/closedir.c: Update.
	* gnulib/import/config.charset: Update.
	* gnulib/import/dirent-private.h: Update.
	* gnulib/import/dirent.in.h: Update.
	* gnulib/import/dirfd.c: Update.
	* gnulib/import/dirname-lgpl.c: Update.
	* gnulib/import/dirname.h: Update.
	* gnulib/import/dosname.h: Update.
	* gnulib/import/dup-safer-flag.c: Update.
	* gnulib/import/dup-safer.c: Update.
	* gnulib/import/dup.c: Update.
	* gnulib/import/dup2.c: Update.
	* gnulib/import/errno.in.h: Update.
	* gnulib/import/error.c: Update.
	* gnulib/import/error.h: Update.
	* gnulib/import/exitfail.c: Update.
	* gnulib/import/exitfail.h: Update.
	* gnulib/import/extra/update-copyright: Update.
	* gnulib/import/fchdir.c: Update.
	* gnulib/import/fcntl.c: Update.
	* gnulib/import/fcntl.in.h: Update.
	* gnulib/import/fd-hook.c: Update.
	* gnulib/import/fd-hook.h: Update.
	* gnulib/import/fd-safer-flag.c: Update.
	* gnulib/import/fd-safer.c: Update.
	* gnulib/import/fdopendir.c: Update.
	* gnulib/import/filename.h: Update.
	* gnulib/import/filenamecat-lgpl.c: Update.
	* gnulib/import/filenamecat.h: Update.
	* gnulib/import/flexmember.h: Update.
	* gnulib/import/float+.h: Update.
	* gnulib/import/float.c: Update.
	* gnulib/import/float.in.h: Update.
	* gnulib/import/fnmatch.c: Update.
	* gnulib/import/fnmatch.in.h: Update.
	* gnulib/import/fnmatch_loop.c: Update.
	* gnulib/import/fpucw.h: Update.
	* gnulib/import/frexp.c: Update.
	* gnulib/import/frexpl.c: Update.
	* gnulib/import/fstat.c: Update.
	* gnulib/import/fstatat.c: Update.
	* gnulib/import/getcwd-lgpl.c: Update.
	* gnulib/import/getcwd.c: Update.
	* gnulib/import/getdtablesize.c: Update.
	* gnulib/import/getlogin_r.c: Update.
	* gnulib/import/getprogname.c: Update.
	* gnulib/import/getprogname.h: Update.
	* gnulib/import/gettext.h: Update.
	* gnulib/import/gettimeofday.c: Update.
	* gnulib/import/glob-libc.h: Update.
	* gnulib/import/glob.c: Update.
	* gnulib/import/glob.in.h: Update.
	* gnulib/import/glob_internal.h: Update.
	* gnulib/import/glob_pattern_p.c: Update.
	* gnulib/import/globfree.c: Update.
	* gnulib/import/hard-locale.c: Update.
	* gnulib/import/hard-locale.h: Update.
	* gnulib/import/intprops.h: Update.
	* gnulib/import/inttypes.in.h: Update.
	* gnulib/import/isnan.c: Update.
	* gnulib/import/isnand-nolibm.h: Update.
	* gnulib/import/isnand.c: Update.
	* gnulib/import/isnanl-nolibm.h: Update.
	* gnulib/import/isnanl.c: Update.
	* gnulib/import/itold.c: Update.
	* gnulib/import/libc-config.h: Update.
	* gnulib/import/limits.in.h: Update.
	* gnulib/import/localcharset.c: Update.
	* gnulib/import/localcharset.h: Update.
	* gnulib/import/localtime-buffer.c: Update.
	* gnulib/import/localtime-buffer.h: Update.
	* gnulib/import/lstat.c: Update.
	* gnulib/import/m4/00gnulib.m4: Update.
	* gnulib/import/m4/__inline.m4: Update.
	* gnulib/import/m4/absolute-header.m4: Update.
	* gnulib/import/m4/alloca.m4: Update.
	* gnulib/import/m4/builtin-expect.m4: Update.
	* gnulib/import/m4/canonicalize.m4: Update.
	* gnulib/import/m4/chdir-long.m4: Update.
	* gnulib/import/m4/close.m4: Update.
	* gnulib/import/m4/closedir.m4: Update.
	* gnulib/import/m4/configmake.m4: Update.
	* gnulib/import/m4/d-ino.m4: Update.
	* gnulib/import/m4/d-type.m4: Update.
	* gnulib/import/m4/dirent_h.m4: Update.
	* gnulib/import/m4/dirfd.m4: Update.
	* gnulib/import/m4/dirname.m4: Update.
	* gnulib/import/m4/double-slash-root.m4: Update.
	* gnulib/import/m4/dup.m4: Update.
	* gnulib/import/m4/dup2.m4: Update.
	* gnulib/import/m4/eealloc.m4: Update.
	* gnulib/import/m4/environ.m4: Update.
	* gnulib/import/m4/errno_h.m4: Update.
	* gnulib/import/m4/error.m4: Update.
	* gnulib/import/m4/exponentd.m4: Update.
	* gnulib/import/m4/exponentl.m4: Update.
	* gnulib/import/m4/extensions.m4: Update.
	* gnulib/import/m4/extern-inline.m4: Update.
	* gnulib/import/m4/fchdir.m4: Update.
	* gnulib/import/m4/fcntl-o.m4: Update.
	* gnulib/import/m4/fcntl.m4: Update.
	* gnulib/import/m4/fcntl_h.m4: Update.
	* gnulib/import/m4/fdopendir.m4: Update.
	* gnulib/import/m4/filenamecat.m4: Update.
	* gnulib/import/m4/flexmember.m4: Update.
	* gnulib/import/m4/float_h.m4: Update.
	* gnulib/import/m4/fnmatch.m4: Update.
	* gnulib/import/m4/fnmatch_h.m4: Update.
	* gnulib/import/m4/fpieee.m4: Update.
	* gnulib/import/m4/frexp.m4: Update.
	* gnulib/import/m4/frexpl.m4: Update.
	* gnulib/import/m4/fstat.m4: Update.
	* gnulib/import/m4/fstatat.m4: Update.
	* gnulib/import/m4/getcwd-abort-bug.m4: Update.
	* gnulib/import/m4/getcwd-path-max.m4: Update.
	* gnulib/import/m4/getcwd.m4: Update.
	* gnulib/import/m4/getdtablesize.m4: Update.
	* gnulib/import/m4/getlogin.m4: Update.
	* gnulib/import/m4/getlogin_r.m4: Update.
	* gnulib/import/m4/getpagesize.m4: Update.
	* gnulib/import/m4/getprogname.m4: Update.
	* gnulib/import/m4/gettimeofday.m4: Update.
	* gnulib/import/m4/glibc21.m4: Update.
	* gnulib/import/m4/glob.m4: Update.
	* gnulib/import/m4/glob_h.m4: Update.
	* gnulib/import/m4/gnulib-cache.m4: Update.
	* gnulib/import/m4/gnulib-common.m4: Update.
	* gnulib/import/m4/gnulib-comp.m4: Update.
	* gnulib/import/m4/gnulib-tool.m4: Update.
	* gnulib/import/m4/hard-locale.m4: Update.
	* gnulib/import/m4/include_next.m4: Update.
	* gnulib/import/m4/inttypes-pri.m4: Update.
	* gnulib/import/m4/inttypes.m4: Update.
	* gnulib/import/m4/isnand.m4: Update.
	* gnulib/import/m4/isnanl.m4: Update.
	* gnulib/import/m4/largefile.m4: Update.
	* gnulib/import/m4/limits-h.m4: Update.
	* gnulib/import/m4/localcharset.m4: Update.
	* gnulib/import/m4/locale-fr.m4: Update.
	* gnulib/import/m4/locale-ja.m4: Update.
	* gnulib/import/m4/locale-zh.m4: Update.
	* gnulib/import/m4/localtime-buffer.m4: Update.
	* gnulib/import/m4/longlong.m4: Update.
	* gnulib/import/m4/lstat.m4: Update.
	* gnulib/import/m4/malloc.m4: Update.
	* gnulib/import/m4/malloca.m4: Update.
	* gnulib/import/m4/math_h.m4: Update.
	* gnulib/import/m4/mbrtowc.m4: Update.
	* gnulib/import/m4/mbsinit.m4: Update.
	* gnulib/import/m4/mbsrtowcs.m4: Update.
	* gnulib/import/m4/mbstate_t.m4: Update.
	* gnulib/import/m4/memchr.m4: Update.
	* gnulib/import/m4/memmem.m4: Update.
	* gnulib/import/m4/mempcpy.m4: Update.
	* gnulib/import/m4/memrchr.m4: Update.
	* gnulib/import/m4/mkdir.m4: Update.
	* gnulib/import/m4/mkstemp.m4: Update.
	* gnulib/import/m4/mmap-anon.m4: Update.
	* gnulib/import/m4/mode_t.m4: Update.
	* gnulib/import/m4/msvc-inval.m4: Update.
	* gnulib/import/m4/msvc-nothrow.m4: Update.
	* gnulib/import/m4/multiarch.m4: Update.
	* gnulib/import/m4/nocrash.m4: Update.
	* gnulib/import/m4/off_t.m4: Update.
	* gnulib/import/m4/onceonly.m4: Update.
	* gnulib/import/m4/open-cloexec.m4: Update.
	* gnulib/import/m4/open.m4: Update.
	* gnulib/import/m4/openat.m4: Update.
	* gnulib/import/m4/opendir.m4: Update.
	* gnulib/import/m4/pathmax.m4: Update.
	* gnulib/import/m4/rawmemchr.m4: Update.
	* gnulib/import/m4/readdir.m4: Update.
	* gnulib/import/m4/readlink.m4: Update.
	* gnulib/import/m4/realloc.m4: Update.
	* gnulib/import/m4/rename.m4: Update.
	* gnulib/import/m4/rewinddir.m4: Update.
	* gnulib/import/m4/rmdir.m4: Update.
	* gnulib/import/m4/save-cwd.m4: Update.
	* gnulib/import/m4/secure_getenv.m4: Update.
	* gnulib/import/m4/setenv.m4: Update.
	* gnulib/import/m4/signal_h.m4: Update.
	* gnulib/import/m4/ssize_t.m4: Update.
	* gnulib/import/m4/stat-time.m4: Update.
	* gnulib/import/m4/stat.m4: Update.
	* gnulib/import/m4/std-gnu11.m4: Update.
	* gnulib/import/m4/stdbool.m4: Update.
	* gnulib/import/m4/stddef_h.m4: Update.
	* gnulib/import/m4/stdint.m4: Update.
	* gnulib/import/m4/stdio_h.m4: Update.
	* gnulib/import/m4/stdlib_h.m4: Update.
	* gnulib/import/m4/strchrnul.m4: Update.
	* gnulib/import/m4/strdup.m4: Update.
	* gnulib/import/m4/strerror.m4: Update.
	* gnulib/import/m4/string_h.m4: Update.
	* gnulib/import/m4/strstr.m4: Update.
	* gnulib/import/m4/strtok_r.m4: Update.
	* gnulib/import/m4/sys_socket_h.m4: Update.
	* gnulib/import/m4/sys_stat_h.m4: Update.
	* gnulib/import/m4/sys_time_h.m4: Update.
	* gnulib/import/m4/sys_types_h.m4: Update.
	* gnulib/import/m4/tempname.m4: Update.
	* gnulib/import/m4/time_h.m4: Update.
	* gnulib/import/m4/unistd-safer.m4: Update.
	* gnulib/import/m4/unistd_h.m4: Update.
	* gnulib/import/m4/warn-on-use.m4: Update.
	* gnulib/import/m4/wchar_h.m4: Update.
	* gnulib/import/m4/wchar_t.m4: Update.
	* gnulib/import/m4/wctype_h.m4: Update.
	* gnulib/import/m4/wint_t.m4: Update.
	* gnulib/import/malloc.c: Update.
	* gnulib/import/malloc/scratch_buffer.h: Update.
	* gnulib/import/malloc/scratch_buffer_grow.c: Update.
	* gnulib/import/malloc/scratch_buffer_grow_preserve.c: Update.
	* gnulib/import/malloc/scratch_buffer_set_array_size.c: Update.
	* gnulib/import/malloca.c: Update.
	* gnulib/import/malloca.h: Update.
	* gnulib/import/malloca.valgrind: Update.
	* gnulib/import/math.in.h: Update.
	* gnulib/import/mbrtowc.c: Update.
	* gnulib/import/mbsinit.c: Update.
	* gnulib/import/mbsrtowcs-impl.h: Update.
	* gnulib/import/mbsrtowcs-state.c: Update.
	* gnulib/import/mbsrtowcs.c: Update.
	* gnulib/import/memchr.c: Update.
	* gnulib/import/memmem.c: Update.
	* gnulib/import/mempcpy.c: Update.
	* gnulib/import/memrchr.c: Update.
	* gnulib/import/mkdir.c: Update.
	* gnulib/import/mkstemp.c: Update.
	* gnulib/import/msvc-inval.c: Update.
	* gnulib/import/msvc-inval.h: Update.
	* gnulib/import/msvc-nothrow.c: Update.
	* gnulib/import/msvc-nothrow.h: Update.
	* gnulib/import/open.c: Update.
	* gnulib/import/openat-die.c: Update.
	* gnulib/import/openat-priv.h: Update.
	* gnulib/import/openat-proc.c: Update.
	* gnulib/import/openat.c: Update.
	* gnulib/import/openat.h: Update.
	* gnulib/import/opendir.c: Update.
	* gnulib/import/pathmax.h: Update.
	* gnulib/import/pipe-safer.c: Update.
	* gnulib/import/rawmemchr.c: Update.
	* gnulib/import/readdir.c: Update.
	* gnulib/import/readlink.c: Update.
	* gnulib/import/realloc.c: Update.
	* gnulib/import/ref-add.sin: Update.
	* gnulib/import/ref-del.sin: Update.
	* gnulib/import/rename.c: Update.
	* gnulib/import/rewinddir.c: Update.
	* gnulib/import/rmdir.c: Update.
	* gnulib/import/same-inode.h: Update.
	* gnulib/import/save-cwd.c: Update.
	* gnulib/import/save-cwd.h: Update.
	* gnulib/import/scratch_buffer.h: Update.
	* gnulib/import/secure_getenv.c: Update.
	* gnulib/import/setenv.c: Update.
	* gnulib/import/signal.in.h: Update.
	* gnulib/import/stat-time.c: Update.
	* gnulib/import/stat-time.h: Update.
	* gnulib/import/stat-w32.c: Update.
	* gnulib/import/stat-w32.h: Update.
	* gnulib/import/stat.c: Update.
	* gnulib/import/stdbool.in.h: Update.
	* gnulib/import/stddef.in.h: Update.
	* gnulib/import/stdint.in.h: Update.
	* gnulib/import/stdio.in.h: Update.
	* gnulib/import/stdlib.in.h: Update.
	* gnulib/import/str-two-way.h: Update.
	* gnulib/import/strchrnul.c: Update.
	* gnulib/import/strdup.c: Update.
	* gnulib/import/streq.h: Update.
	* gnulib/import/strerror-override.c: Update.
	* gnulib/import/strerror-override.h: Update.
	* gnulib/import/strerror.c: Update.
	* gnulib/import/string.in.h: Update.
	* gnulib/import/stripslash.c: Update.
	* gnulib/import/strnlen1.c: Update.
	* gnulib/import/strnlen1.h: Update.
	* gnulib/import/strstr.c: Update.
	* gnulib/import/strtok_r.c: Update.
	* gnulib/import/sys_stat.in.h: Update.
	* gnulib/import/sys_time.in.h: Update.
	* gnulib/import/sys_types.in.h: Update.
	* gnulib/import/tempname.c: Update.
	* gnulib/import/tempname.h: Update.
	* gnulib/import/time.in.h: Update.
	* gnulib/import/unistd--.h: Update.
	* gnulib/import/unistd-safer.h: Update.
	* gnulib/import/unistd.in.h: Update.
	* gnulib/import/unsetenv.c: Update.
	* gnulib/import/verify.h: Update.
	* gnulib/import/extra/snippet/warn-on-use.h: Update.
	* gnulib/import/wchar.in.h: Update.
	* gnulib/import/wctype.in.h: Update.
	* gnulib/import/xalloc-oversized.h: Update.
	* gnulib/update-gnulib.sh (GNULIB_COMMIT_SHA1): Set to
	"53e2c179f26a890fa6685af4b6c1397ee370433b".
2018-09-10 13:52:24 -04:00

169 lines
4.2 KiB
C

/* Split a double into fraction and mantissa.
Copyright (C) 2007-2016 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* Written by Paolo Bonzini <bonzini@gnu.org>, 2003, and
Bruno Haible <bruno@clisp.org>, 2007. */
#if ! defined USE_LONG_DOUBLE
# include <config.h>
#endif
/* Specification. */
#include <math.h>
#include <float.h>
#ifdef USE_LONG_DOUBLE
# include "isnanl-nolibm.h"
# include "fpucw.h"
#else
# include "isnand-nolibm.h"
#endif
/* This file assumes FLT_RADIX = 2. If FLT_RADIX is a power of 2 greater
than 2, or not even a power of 2, some rounding errors can occur, so that
then the returned mantissa is only guaranteed to be <= 1.0, not < 1.0. */
#ifdef USE_LONG_DOUBLE
# define FUNC frexpl
# define DOUBLE long double
# define ISNAN isnanl
# define DECL_ROUNDING DECL_LONG_DOUBLE_ROUNDING
# define BEGIN_ROUNDING() BEGIN_LONG_DOUBLE_ROUNDING ()
# define END_ROUNDING() END_LONG_DOUBLE_ROUNDING ()
# define L_(literal) literal##L
#else
# define FUNC frexp
# define DOUBLE double
# define ISNAN isnand
# define DECL_ROUNDING
# define BEGIN_ROUNDING()
# define END_ROUNDING()
# define L_(literal) literal
#endif
DOUBLE
FUNC (DOUBLE x, int *expptr)
{
int sign;
int exponent;
DECL_ROUNDING
/* Test for NaN, infinity, and zero. */
if (ISNAN (x) || x + x == x)
{
*expptr = 0;
return x;
}
sign = 0;
if (x < 0)
{
x = - x;
sign = -1;
}
BEGIN_ROUNDING ();
{
/* Since the exponent is an 'int', it fits in 64 bits. Therefore the
loops are executed no more than 64 times. */
DOUBLE pow2[64]; /* pow2[i] = 2^2^i */
DOUBLE powh[64]; /* powh[i] = 2^-2^i */
int i;
exponent = 0;
if (x >= L_(1.0))
{
/* A positive exponent. */
DOUBLE pow2_i; /* = pow2[i] */
DOUBLE powh_i; /* = powh[i] */
/* Invariants: pow2_i = 2^2^i, powh_i = 2^-2^i,
x * 2^exponent = argument, x >= 1.0. */
for (i = 0, pow2_i = L_(2.0), powh_i = L_(0.5);
;
i++, pow2_i = pow2_i * pow2_i, powh_i = powh_i * powh_i)
{
if (x >= pow2_i)
{
exponent += (1 << i);
x *= powh_i;
}
else
break;
pow2[i] = pow2_i;
powh[i] = powh_i;
}
/* Avoid making x too small, as it could become a denormalized
number and thus lose precision. */
while (i > 0 && x < pow2[i - 1])
{
i--;
powh_i = powh[i];
}
exponent += (1 << i);
x *= powh_i;
/* Here 2^-2^i <= x < 1.0. */
}
else
{
/* A negative or zero exponent. */
DOUBLE pow2_i; /* = pow2[i] */
DOUBLE powh_i; /* = powh[i] */
/* Invariants: pow2_i = 2^2^i, powh_i = 2^-2^i,
x * 2^exponent = argument, x < 1.0. */
for (i = 0, pow2_i = L_(2.0), powh_i = L_(0.5);
;
i++, pow2_i = pow2_i * pow2_i, powh_i = powh_i * powh_i)
{
if (x < powh_i)
{
exponent -= (1 << i);
x *= pow2_i;
}
else
break;
pow2[i] = pow2_i;
powh[i] = powh_i;
}
/* Here 2^-2^i <= x < 1.0. */
}
/* Invariants: x * 2^exponent = argument, and 2^-2^i <= x < 1.0. */
while (i > 0)
{
i--;
if (x < powh[i])
{
exponent -= (1 << i);
x *= pow2[i];
}
}
/* Here 0.5 <= x < 1.0. */
}
if (sign < 0)
x = - x;
END_ROUNDING ();
*expptr = exponent;
return x;
}