mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 03:40:34 +02:00
Merge remote-tracking branch 'origin/stable-2.0'
Conflicts: libguile/numbers.c libguile/vm-i-scheme.c
This commit is contained in:
commit
d8d7c7bf57
20 changed files with 1492 additions and 330 deletions
|
@ -21,7 +21,7 @@
|
|||
# the same distribution terms as the rest of that program.
|
||||
#
|
||||
# Generated by gnulib-tool.
|
||||
# Reproduce by: gnulib-tool --import --dir=. --local-dir=gnulib-local --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --lgpl=3 --no-conditional-dependencies --libtool --macro-prefix=gl --no-vc-files accept alignof alloca-opt announce-gen autobuild bind byteswap c-strcase canonicalize-lgpl ceil clock-time close connect dirfd duplocale environ extensions flock floor fpieee frexp fstat full-read full-write func gendocs getaddrinfo getlogin getpeername getsockname getsockopt git-version-gen gitlog-to-changelog gnu-web-doc-update gnupload havelib iconv_open-utf inet_ntop inet_pton isinf isnan ldexp lib-symbol-versions lib-symbol-visibility libunistring listen localcharset locale log1p maintainer-makefile malloc-gnu malloca nl_langinfo nproc open pipe-posix pipe2 poll putenv recv recvfrom regex rename select send sendto setenv setsockopt shutdown socket stat-time stdlib strftime striconveh string sys_stat time times trunc verify vsnprintf warnings wchar
|
||||
# Reproduce by: gnulib-tool --import --dir=. --local-dir=gnulib-local --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --lgpl=3 --no-conditional-dependencies --libtool --macro-prefix=gl --no-vc-files accept alignof alloca-opt announce-gen autobuild bind byteswap c-strcase canonicalize-lgpl ceil clock-time close connect copysign dirfd duplocale environ extensions flock floor fpieee frexp fstat full-read full-write func gendocs getaddrinfo getlogin getpeername getsockname getsockopt git-version-gen gitlog-to-changelog gnu-web-doc-update gnupload havelib iconv_open-utf inet_ntop inet_pton isfinite isinf isnan ldexp lib-symbol-versions lib-symbol-visibility libunistring listen localcharset locale log1p maintainer-makefile malloc-gnu malloca nl_langinfo nproc open pipe-posix pipe2 poll putenv recv recvfrom regex rename select send sendto setenv setsockopt shutdown socket stat-time stdlib strftime striconveh string sys_stat time times trunc verify vsnprintf warnings wchar
|
||||
|
||||
AUTOMAKE_OPTIONS = 1.5 gnits subdir-objects
|
||||
|
||||
|
@ -50,6 +50,7 @@ EXTRA_libgnu_la_SOURCES =
|
|||
libgnu_la_LDFLAGS = $(AM_LDFLAGS)
|
||||
libgnu_la_LDFLAGS += -no-undefined
|
||||
libgnu_la_LDFLAGS += $(CEIL_LIBM)
|
||||
libgnu_la_LDFLAGS += $(COPYSIGN_LIBM)
|
||||
libgnu_la_LDFLAGS += $(FLOOR_LIBM)
|
||||
libgnu_la_LDFLAGS += $(FREXP_LIBM)
|
||||
libgnu_la_LDFLAGS += $(GETADDRINFO_LIB)
|
||||
|
@ -312,6 +313,15 @@ EXTRA_libgnu_la_SOURCES += connect.c
|
|||
|
||||
## end gnulib module connect
|
||||
|
||||
## begin gnulib module copysign
|
||||
|
||||
|
||||
EXTRA_DIST += copysign.c
|
||||
|
||||
EXTRA_libgnu_la_SOURCES += copysign.c
|
||||
|
||||
## end gnulib module copysign
|
||||
|
||||
## begin gnulib module dirent
|
||||
|
||||
BUILT_SOURCES += dirent.h
|
||||
|
@ -753,6 +763,15 @@ EXTRA_libgnu_la_SOURCES += inet_pton.c
|
|||
|
||||
## end gnulib module inet_pton
|
||||
|
||||
## begin gnulib module isfinite
|
||||
|
||||
|
||||
EXTRA_DIST += isfinite.c
|
||||
|
||||
EXTRA_libgnu_la_SOURCES += isfinite.c
|
||||
|
||||
## end gnulib module isfinite
|
||||
|
||||
## begin gnulib module isinf
|
||||
|
||||
|
||||
|
@ -789,6 +808,15 @@ EXTRA_libgnu_la_SOURCES += isnan.c isnanf.c
|
|||
|
||||
## end gnulib module isnanf
|
||||
|
||||
## begin gnulib module isnanf-nolibm
|
||||
|
||||
|
||||
EXTRA_DIST += float+.h isnan.c isnanf-nolibm.h isnanf.c
|
||||
|
||||
EXTRA_libgnu_la_SOURCES += isnan.c isnanf.c
|
||||
|
||||
## end gnulib module isnanf-nolibm
|
||||
|
||||
## begin gnulib module isnanl
|
||||
|
||||
|
||||
|
@ -798,6 +826,15 @@ EXTRA_libgnu_la_SOURCES += isnan.c isnanl.c
|
|||
|
||||
## end gnulib module isnanl
|
||||
|
||||
## begin gnulib module isnanl-nolibm
|
||||
|
||||
|
||||
EXTRA_DIST += float+.h isnan.c isnanl-nolibm.h isnanl.c
|
||||
|
||||
EXTRA_libgnu_la_SOURCES += isnan.c isnanl.c
|
||||
|
||||
## end gnulib module isnanl-nolibm
|
||||
|
||||
## begin gnulib module langinfo
|
||||
|
||||
BUILT_SOURCES += langinfo.h
|
||||
|
@ -1734,6 +1771,15 @@ EXTRA_DIST += signal.in.h
|
|||
|
||||
## end gnulib module signal-h
|
||||
|
||||
## begin gnulib module signbit
|
||||
|
||||
|
||||
EXTRA_DIST += float+.h signbitd.c signbitf.c signbitl.c
|
||||
|
||||
EXTRA_libgnu_la_SOURCES += signbitd.c signbitf.c signbitl.c
|
||||
|
||||
## end gnulib module signbit
|
||||
|
||||
## begin gnulib module size_max
|
||||
|
||||
libgnu_la_SOURCES += size_max.h
|
||||
|
|
26
lib/copysign.c
Normal file
26
lib/copysign.c
Normal file
|
@ -0,0 +1,26 @@
|
|||
/* Copy sign into another 'double' number.
|
||||
Copyright (C) 2011-2013 Free Software Foundation, Inc.
|
||||
|
||||
This program 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 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include <math.h>
|
||||
|
||||
double
|
||||
copysign (double x, double y)
|
||||
{
|
||||
return (signbit (x) != signbit (y) ? - x : x);
|
||||
}
|
51
lib/isfinite.c
Normal file
51
lib/isfinite.c
Normal file
|
@ -0,0 +1,51 @@
|
|||
/* Test for finite value (zero, subnormal, or normal, and not infinite or NaN).
|
||||
Copyright (C) 2007-2013 Free Software Foundation, Inc.
|
||||
|
||||
This program 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, 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with this program; if not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Ben Pfaff <blp@gnu.org>, 2007. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "isnanf-nolibm.h"
|
||||
#include "isnand-nolibm.h"
|
||||
#include "isnanl-nolibm.h"
|
||||
|
||||
/* The "cc" compiler on HP-UX 11.11, when optimizing, simplifies the test
|
||||
x - y == 0.0 to x == y, a simplification which is invalid when x and y
|
||||
are Infinity. Disable this optimization. */
|
||||
#if defined __hpux && !defined __GNUC__
|
||||
static float zerof;
|
||||
static double zerod;
|
||||
static long double zerol;
|
||||
#else
|
||||
# define zerof 0.f
|
||||
# define zerod 0.
|
||||
# define zerol 0.L
|
||||
#endif
|
||||
|
||||
int gl_isfinitef (float x)
|
||||
{
|
||||
return !isnanf (x) && x - x == zerof;
|
||||
}
|
||||
|
||||
int gl_isfinited (double x)
|
||||
{
|
||||
return !isnand (x) && x - x == zerod;
|
||||
}
|
||||
|
||||
int gl_isfinitel (long double x)
|
||||
{
|
||||
return !isnanl (x) && x - x == zerol;
|
||||
}
|
40
lib/isnanf-nolibm.h
Normal file
40
lib/isnanf-nolibm.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
/* Test for NaN that does not need libm.
|
||||
Copyright (C) 2007-2013 Free Software Foundation, Inc.
|
||||
|
||||
This program 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 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#if HAVE_ISNANF_IN_LIBC
|
||||
/* Get declaration of isnan macro or (older) isnanf function. */
|
||||
# include <math.h>
|
||||
# if __GNUC__ >= 4
|
||||
/* GCC 4.0 and newer provides three built-ins for isnan. */
|
||||
# undef isnanf
|
||||
# define isnanf(x) __builtin_isnanf ((float)(x))
|
||||
# elif defined isnan
|
||||
# undef isnanf
|
||||
# define isnanf(x) isnan ((float)(x))
|
||||
# else
|
||||
/* Get declaration of isnanf(), if not declared in <math.h>. */
|
||||
# if defined __sgi
|
||||
/* We can't include <ieeefp.h>, because it conflicts with our definition of
|
||||
isnand. Therefore declare isnanf separately. */
|
||||
extern int isnanf (float x);
|
||||
# endif
|
||||
# endif
|
||||
#else
|
||||
/* Test whether X is a NaN. */
|
||||
# undef isnanf
|
||||
# define isnanf rpl_isnanf
|
||||
extern int isnanf (float x);
|
||||
#endif
|
33
lib/isnanl-nolibm.h
Normal file
33
lib/isnanl-nolibm.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/* Test for NaN that does not need libm.
|
||||
Copyright (C) 2007-2013 Free Software Foundation, Inc.
|
||||
|
||||
This program 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 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#if HAVE_ISNANL_IN_LIBC
|
||||
/* Get declaration of isnan macro or (older) isnanl function. */
|
||||
# include <math.h>
|
||||
# if __GNUC__ >= 4
|
||||
/* GCC 4.0 and newer provides three built-ins for isnan. */
|
||||
# undef isnanl
|
||||
# define isnanl(x) __builtin_isnanl ((long double)(x))
|
||||
# elif defined isnan
|
||||
# undef isnanl
|
||||
# define isnanl(x) isnan ((long double)(x))
|
||||
# endif
|
||||
#else
|
||||
/* Test whether X is a NaN. */
|
||||
# undef isnanl
|
||||
# define isnanl rpl_isnanl
|
||||
extern int isnanl (long double x);
|
||||
#endif
|
64
lib/signbitd.c
Normal file
64
lib/signbitd.c
Normal file
|
@ -0,0 +1,64 @@
|
|||
/* signbit() macro: Determine the sign bit of a floating-point number.
|
||||
Copyright (C) 2007-2013 Free Software Foundation, Inc.
|
||||
|
||||
This program 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 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include <math.h>
|
||||
|
||||
#include <string.h>
|
||||
#include "isnand-nolibm.h"
|
||||
#include "float+.h"
|
||||
|
||||
#ifdef gl_signbitd_OPTIMIZED_MACRO
|
||||
# undef gl_signbitd
|
||||
#endif
|
||||
|
||||
int
|
||||
gl_signbitd (double arg)
|
||||
{
|
||||
#if defined DBL_SIGNBIT_WORD && defined DBL_SIGNBIT_BIT
|
||||
/* The use of a union to extract the bits of the representation of a
|
||||
'long double' is safe in practice, despite of the "aliasing rules" of
|
||||
C99, because the GCC docs say
|
||||
"Even with '-fstrict-aliasing', type-punning is allowed, provided the
|
||||
memory is accessed through the union type."
|
||||
and similarly for other compilers. */
|
||||
# define NWORDS \
|
||||
((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
|
||||
union { double value; unsigned int word[NWORDS]; } m;
|
||||
m.value = arg;
|
||||
return (m.word[DBL_SIGNBIT_WORD] >> DBL_SIGNBIT_BIT) & 1;
|
||||
#elif HAVE_COPYSIGN_IN_LIBC
|
||||
return copysign (1.0, arg) < 0;
|
||||
#else
|
||||
/* This does not do the right thing for NaN, but this is irrelevant for
|
||||
most use cases. */
|
||||
if (isnand (arg))
|
||||
return 0;
|
||||
if (arg < 0.0)
|
||||
return 1;
|
||||
else if (arg == 0.0)
|
||||
{
|
||||
/* Distinguish 0.0 and -0.0. */
|
||||
static double plus_zero = 0.0;
|
||||
double arg_mem = arg;
|
||||
return (memcmp (&plus_zero, &arg_mem, SIZEOF_DBL) != 0);
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
64
lib/signbitf.c
Normal file
64
lib/signbitf.c
Normal file
|
@ -0,0 +1,64 @@
|
|||
/* signbit() macro: Determine the sign bit of a floating-point number.
|
||||
Copyright (C) 2007, 2009-2013 Free Software Foundation, Inc.
|
||||
|
||||
This program 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 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include <math.h>
|
||||
|
||||
#include <string.h>
|
||||
#include "isnanf-nolibm.h"
|
||||
#include "float+.h"
|
||||
|
||||
#ifdef gl_signbitf_OPTIMIZED_MACRO
|
||||
# undef gl_signbitf
|
||||
#endif
|
||||
|
||||
int
|
||||
gl_signbitf (float arg)
|
||||
{
|
||||
#if defined FLT_SIGNBIT_WORD && defined FLT_SIGNBIT_BIT
|
||||
/* The use of a union to extract the bits of the representation of a
|
||||
'long double' is safe in practice, despite of the "aliasing rules" of
|
||||
C99, because the GCC docs say
|
||||
"Even with '-fstrict-aliasing', type-punning is allowed, provided the
|
||||
memory is accessed through the union type."
|
||||
and similarly for other compilers. */
|
||||
# define NWORDS \
|
||||
((sizeof (float) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
|
||||
union { float value; unsigned int word[NWORDS]; } m;
|
||||
m.value = arg;
|
||||
return (m.word[FLT_SIGNBIT_WORD] >> FLT_SIGNBIT_BIT) & 1;
|
||||
#elif HAVE_COPYSIGNF_IN_LIBC
|
||||
return copysignf (1.0f, arg) < 0;
|
||||
#else
|
||||
/* This does not do the right thing for NaN, but this is irrelevant for
|
||||
most use cases. */
|
||||
if (isnanf (arg))
|
||||
return 0;
|
||||
if (arg < 0.0f)
|
||||
return 1;
|
||||
else if (arg == 0.0f)
|
||||
{
|
||||
/* Distinguish 0.0f and -0.0f. */
|
||||
static float plus_zero = 0.0f;
|
||||
float arg_mem = arg;
|
||||
return (memcmp (&plus_zero, &arg_mem, SIZEOF_FLT) != 0);
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
64
lib/signbitl.c
Normal file
64
lib/signbitl.c
Normal file
|
@ -0,0 +1,64 @@
|
|||
/* signbit() macro: Determine the sign bit of a floating-point number.
|
||||
Copyright (C) 2007, 2009-2013 Free Software Foundation, Inc.
|
||||
|
||||
This program 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 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include <math.h>
|
||||
|
||||
#include <string.h>
|
||||
#include "isnanl-nolibm.h"
|
||||
#include "float+.h"
|
||||
|
||||
#ifdef gl_signbitl_OPTIMIZED_MACRO
|
||||
# undef gl_signbitl
|
||||
#endif
|
||||
|
||||
int
|
||||
gl_signbitl (long double arg)
|
||||
{
|
||||
#if defined LDBL_SIGNBIT_WORD && defined LDBL_SIGNBIT_BIT
|
||||
/* The use of a union to extract the bits of the representation of a
|
||||
'long double' is safe in practice, despite of the "aliasing rules" of
|
||||
C99, because the GCC docs say
|
||||
"Even with '-fstrict-aliasing', type-punning is allowed, provided the
|
||||
memory is accessed through the union type."
|
||||
and similarly for other compilers. */
|
||||
# define NWORDS \
|
||||
((sizeof (long double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
|
||||
union { long double value; unsigned int word[NWORDS]; } m;
|
||||
m.value = arg;
|
||||
return (m.word[LDBL_SIGNBIT_WORD] >> LDBL_SIGNBIT_BIT) & 1;
|
||||
#elif HAVE_COPYSIGNL_IN_LIBC
|
||||
return copysignl (1.0L, arg) < 0;
|
||||
#else
|
||||
/* This does not do the right thing for NaN, but this is irrelevant for
|
||||
most use cases. */
|
||||
if (isnanl (arg))
|
||||
return 0;
|
||||
if (arg < 0.0L)
|
||||
return 1;
|
||||
else if (arg == 0.0L)
|
||||
{
|
||||
/* Distinguish 0.0L and -0.0L. */
|
||||
static long double plus_zero = 0.0L;
|
||||
long double arg_mem = arg;
|
||||
return (memcmp (&plus_zero, &arg_mem, SIZEOF_LDBL) != 0);
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -219,8 +219,13 @@ VM_DEFINE_FUNCTION (151, ge, "ge?", 2)
|
|||
*/
|
||||
|
||||
/* The maximum/minimum tagged integers. */
|
||||
#define INUM_MAX (INTPTR_MAX - 1)
|
||||
#define INUM_MIN (INTPTR_MIN + scm_tc2_int)
|
||||
#define INUM_MAX \
|
||||
((scm_t_signed_bits) SCM_UNPACK (SCM_I_MAKINUM (SCM_MOST_POSITIVE_FIXNUM)))
|
||||
#define INUM_MIN \
|
||||
((scm_t_signed_bits) SCM_UNPACK (SCM_I_MAKINUM (SCM_MOST_NEGATIVE_FIXNUM)))
|
||||
#define INUM_STEP \
|
||||
((scm_t_signed_bits) SCM_UNPACK (SCM_INUM1) \
|
||||
- (scm_t_signed_bits) SCM_UNPACK (SCM_INUM0))
|
||||
|
||||
#define FUNC2(CFUNC,SFUNC) \
|
||||
{ \
|
||||
|
@ -238,28 +243,36 @@ VM_DEFINE_FUNCTION (151, ge, "ge?", 2)
|
|||
/* Assembly tagged integer arithmetic routines. This code uses the
|
||||
`asm goto' feature introduced in GCC 4.5. */
|
||||
|
||||
#if defined __x86_64__ && SCM_GNUC_PREREQ (4, 5)
|
||||
#if SCM_GNUC_PREREQ (4, 5) && (defined __x86_64__ || defined __i386__)
|
||||
|
||||
# undef _CX
|
||||
# ifdef __x86_64__
|
||||
# define _CX "rcx"
|
||||
# else
|
||||
# define _CX "ecx"
|
||||
# endif
|
||||
|
||||
/* The macros below check the CPU's overflow flag to improve fixnum
|
||||
arithmetic. The %rcx register is explicitly clobbered because `asm
|
||||
goto' can't have outputs, in which case the `r' constraint could be
|
||||
used to let the register allocator choose a register.
|
||||
arithmetic. The _CX register (%rcx or %ecx) is explicitly
|
||||
clobbered because `asm goto' can't have outputs, in which case the
|
||||
`r' constraint could be used to let the register allocator choose a
|
||||
register.
|
||||
|
||||
TODO: Use `cold' label attribute in GCC 4.6.
|
||||
http://gcc.gnu.org/ml/gcc-patches/2010-10/msg01777.html */
|
||||
|
||||
# define ASM_ADD(x, y) \
|
||||
{ \
|
||||
asm volatile goto ("mov %1, %%rcx; " \
|
||||
asm volatile goto ("mov %1, %%"_CX"; " \
|
||||
"test %[tag], %%cl; je %l[slow_add]; " \
|
||||
"test %[tag], %0; je %l[slow_add]; " \
|
||||
"add %0, %%rcx; jo %l[slow_add]; " \
|
||||
"sub %[tag], %%rcx; " \
|
||||
"mov %%rcx, (%[vsp])\n" \
|
||||
"sub %[tag], %%"_CX"; " \
|
||||
"add %0, %%"_CX"; jo %l[slow_add]; " \
|
||||
"mov %%"_CX", (%[vsp])\n" \
|
||||
: /* no outputs */ \
|
||||
: "r" (x), "r" (y), \
|
||||
[vsp] "r" (sp), [tag] "i" (scm_tc2_int) \
|
||||
: "rcx", "memory" \
|
||||
: _CX, "memory", "cc" \
|
||||
: slow_add); \
|
||||
NEXT; \
|
||||
} \
|
||||
|
@ -268,24 +281,106 @@ VM_DEFINE_FUNCTION (151, ge, "ge?", 2)
|
|||
|
||||
# define ASM_SUB(x, y) \
|
||||
{ \
|
||||
asm volatile goto ("mov %0, %%rcx; " \
|
||||
asm volatile goto ("mov %0, %%"_CX"; " \
|
||||
"test %[tag], %%cl; je %l[slow_sub]; " \
|
||||
"test %[tag], %1; je %l[slow_sub]; " \
|
||||
"sub %1, %%rcx; jo %l[slow_sub]; " \
|
||||
"add %[tag], %%rcx; " \
|
||||
"mov %%rcx, (%[vsp])\n" \
|
||||
"sub %1, %%"_CX"; jo %l[slow_sub]; " \
|
||||
"add %[tag], %%"_CX"; " \
|
||||
"mov %%"_CX", (%[vsp])\n" \
|
||||
: /* no outputs */ \
|
||||
: "r" (x), "r" (y), \
|
||||
[vsp] "r" (sp), [tag] "i" (scm_tc2_int) \
|
||||
: "rcx", "memory" \
|
||||
: _CX, "memory", "cc" \
|
||||
: slow_sub); \
|
||||
NEXT; \
|
||||
} \
|
||||
slow_sub: \
|
||||
do { } while (0)
|
||||
|
||||
# define ASM_MUL(x, y) \
|
||||
{ \
|
||||
scm_t_signed_bits xx = SCM_I_INUM (x); \
|
||||
asm volatile goto ("mov %1, %%"_CX"; " \
|
||||
"test %[tag], %%cl; je %l[slow_mul]; " \
|
||||
"sub %[tag], %%"_CX"; " \
|
||||
"test %[tag], %0; je %l[slow_mul]; " \
|
||||
"imul %2, %%"_CX"; jo %l[slow_mul]; " \
|
||||
"add %[tag], %%"_CX"; " \
|
||||
"mov %%"_CX", (%[vsp])\n" \
|
||||
: /* no outputs */ \
|
||||
: "r" (x), "r" (y), "r" (xx), \
|
||||
[vsp] "r" (sp), [tag] "i" (scm_tc2_int) \
|
||||
: _CX, "memory", "cc" \
|
||||
: slow_mul); \
|
||||
NEXT; \
|
||||
} \
|
||||
slow_mul: \
|
||||
do { } while (0)
|
||||
|
||||
#endif
|
||||
|
||||
#if SCM_GNUC_PREREQ (4, 5) && defined __arm__
|
||||
|
||||
# define ASM_ADD(x, y) \
|
||||
if (SCM_LIKELY (SCM_I_INUMP (x) && SCM_I_INUMP (y))) \
|
||||
{ \
|
||||
asm volatile goto ("adds r0, %0, %1; bvs %l[slow_add]; " \
|
||||
"str r0, [%[vsp]]\n" \
|
||||
: /* no outputs */ \
|
||||
: "r" (x), "r" (y - scm_tc2_int), \
|
||||
[vsp] "r" (sp) \
|
||||
: "r0", "memory", "cc" \
|
||||
: slow_add); \
|
||||
NEXT; \
|
||||
} \
|
||||
slow_add: \
|
||||
do { } while (0)
|
||||
|
||||
# define ASM_SUB(x, y) \
|
||||
if (SCM_LIKELY (SCM_I_INUMP (x) && SCM_I_INUMP (y))) \
|
||||
{ \
|
||||
asm volatile goto ("subs r0, %0, %1; bvs %l[slow_sub]; " \
|
||||
"str r0, [%[vsp]]\n" \
|
||||
: /* no outputs */ \
|
||||
: "r" (x), "r" (y - scm_tc2_int), \
|
||||
[vsp] "r" (sp) \
|
||||
: "r0", "memory", "cc" \
|
||||
: slow_sub); \
|
||||
NEXT; \
|
||||
} \
|
||||
slow_sub: \
|
||||
do { } while (0)
|
||||
|
||||
# if defined (__ARM_ARCH_3M__) || defined (__ARM_ARCH_4__) \
|
||||
|| defined (__ARM_ARCH_4T__) || defined (__ARM_ARCH_5__) \
|
||||
|| defined (__ARM_ARCH_5T__) || defined (__ARM_ARCH_5E__) \
|
||||
|| defined (__ARM_ARCH_5TE__) || defined (__ARM_ARCH_5TEJ__) \
|
||||
|| defined (__ARM_ARCH_6__) || defined (__ARM_ARCH_6J__) \
|
||||
|| defined (__ARM_ARCH_6K__) || defined (__ARM_ARCH_6Z__) \
|
||||
|| defined (__ARM_ARCH_6ZK__) || defined (__ARM_ARCH_6T2__) \
|
||||
|| defined (__ARM_ARCH_6M__) || defined (__ARM_ARCH_7__) \
|
||||
|| defined (__ARM_ARCH_7A__) || defined (__ARM_ARCH_7R__) \
|
||||
|| defined (__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) \
|
||||
|| defined (__ARM_ARCH_8A__)
|
||||
|
||||
/* The ARM architectures listed above support the SMULL instruction */
|
||||
|
||||
# define ASM_MUL(x, y) \
|
||||
if (SCM_LIKELY (SCM_I_INUMP (x) && SCM_I_INUMP (y))) \
|
||||
{ \
|
||||
scm_t_signed_bits rlo, rhi; \
|
||||
asm ("smull %0, %1, %2, %3\n" \
|
||||
: "=r" (rlo), "=r" (rhi) \
|
||||
: "r" (SCM_UNPACK (x) - scm_tc2_int), \
|
||||
"r" (SCM_I_INUM (y))); \
|
||||
if (SCM_LIKELY (SCM_SRS (rlo, 31) == rhi)) \
|
||||
RETURN (SCM_PACK (rlo + scm_tc2_int)); \
|
||||
} \
|
||||
do { } while (0)
|
||||
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
VM_DEFINE_FUNCTION (152, add, "add", 2)
|
||||
{
|
||||
|
@ -303,15 +398,14 @@ VM_DEFINE_FUNCTION (153, add1, "add1", 1)
|
|||
{
|
||||
ARGS1 (x);
|
||||
|
||||
/* Check for overflow. */
|
||||
if (SCM_LIKELY ((scm_t_intptr) SCM_UNPACK (x) < INUM_MAX))
|
||||
/* Check for overflow. We must avoid overflow in the signed
|
||||
addition below, even if X is not an inum. */
|
||||
if (SCM_LIKELY ((scm_t_signed_bits) SCM_UNPACK (x) <= INUM_MAX - INUM_STEP))
|
||||
{
|
||||
SCM result;
|
||||
|
||||
/* Add the integers without untagging. */
|
||||
result = SCM_PACK ((scm_t_intptr) SCM_UNPACK (x)
|
||||
+ (scm_t_intptr) SCM_UNPACK (SCM_I_MAKINUM (1))
|
||||
- scm_tc2_int);
|
||||
/* Add 1 to the integer without untagging. */
|
||||
result = SCM_PACK ((scm_t_signed_bits) SCM_UNPACK (x) + INUM_STEP);
|
||||
|
||||
if (SCM_LIKELY (SCM_I_INUMP (result)))
|
||||
RETURN (result);
|
||||
|
@ -337,15 +431,14 @@ VM_DEFINE_FUNCTION (155, sub1, "sub1", 1)
|
|||
{
|
||||
ARGS1 (x);
|
||||
|
||||
/* Check for underflow. */
|
||||
if (SCM_LIKELY ((scm_t_intptr) SCM_UNPACK (x) > INUM_MIN))
|
||||
/* Check for overflow. We must avoid overflow in the signed
|
||||
subtraction below, even if X is not an inum. */
|
||||
if (SCM_LIKELY ((scm_t_signed_bits) SCM_UNPACK (x) >= INUM_MIN + INUM_STEP))
|
||||
{
|
||||
SCM result;
|
||||
|
||||
/* Substract the integers without untagging. */
|
||||
result = SCM_PACK ((scm_t_intptr) SCM_UNPACK (x)
|
||||
- (scm_t_intptr) SCM_UNPACK (SCM_I_MAKINUM (1))
|
||||
+ scm_tc2_int);
|
||||
/* Substract 1 from the integer without untagging. */
|
||||
result = SCM_PACK ((scm_t_signed_bits) SCM_UNPACK (x) - INUM_STEP);
|
||||
|
||||
if (SCM_LIKELY (SCM_I_INUMP (result)))
|
||||
RETURN (result);
|
||||
|
@ -355,19 +448,24 @@ VM_DEFINE_FUNCTION (155, sub1, "sub1", 1)
|
|||
RETURN (scm_difference (x, SCM_I_MAKINUM (1)));
|
||||
}
|
||||
|
||||
#undef ASM_ADD
|
||||
#undef ASM_SUB
|
||||
#undef FUNC2
|
||||
#undef INUM_MAX
|
||||
#undef INUM_MIN
|
||||
|
||||
VM_DEFINE_FUNCTION (156, mul, "mul", 2)
|
||||
{
|
||||
ARGS2 (x, y);
|
||||
#ifdef ASM_MUL
|
||||
ASM_MUL (x, y);
|
||||
#endif
|
||||
SYNC_REGISTER ();
|
||||
RETURN (scm_product (x, y));
|
||||
}
|
||||
|
||||
#undef ASM_ADD
|
||||
#undef ASM_SUB
|
||||
#undef ASM_MUL
|
||||
#undef FUNC2
|
||||
#undef INUM_MAX
|
||||
#undef INUM_MIN
|
||||
#undef INUM_STEP
|
||||
|
||||
VM_DEFINE_FUNCTION (157, div, "div", 2)
|
||||
{
|
||||
ARGS2 (x, y);
|
||||
|
@ -402,12 +500,11 @@ VM_DEFINE_FUNCTION (161, ash, "ash", 2)
|
|||
if (SCM_I_INUMP (x) && SCM_I_INUMP (y))
|
||||
{
|
||||
if (SCM_I_INUM (y) < 0)
|
||||
{
|
||||
/* Right shift, will be a fixnum. */
|
||||
if (SCM_I_INUM (y) > -SCM_I_FIXNUM_BIT)
|
||||
RETURN (SCM_I_MAKINUM (SCM_I_INUM (x) >> -SCM_I_INUM (y)));
|
||||
/* fall through */
|
||||
}
|
||||
RETURN (SCM_I_MAKINUM
|
||||
(SCM_SRS (SCM_I_INUM (x),
|
||||
(-SCM_I_INUM (y) <= SCM_I_FIXNUM_BIT-1)
|
||||
? -SCM_I_INUM (y) : SCM_I_FIXNUM_BIT-1)));
|
||||
else
|
||||
/* Left shift. See comments in scm_ash. */
|
||||
{
|
||||
|
@ -433,7 +530,8 @@ VM_DEFINE_FUNCTION (162, logand, "logand", 2)
|
|||
{
|
||||
ARGS2 (x, y);
|
||||
if (SCM_I_INUMP (x) && SCM_I_INUMP (y))
|
||||
RETURN (SCM_I_MAKINUM (SCM_I_INUM (x) & SCM_I_INUM (y)));
|
||||
/* Compute bitwise AND without untagging */
|
||||
RETURN (SCM_PACK (SCM_UNPACK (x) & SCM_UNPACK (y)));
|
||||
SYNC_REGISTER ();
|
||||
RETURN (scm_logand (x, y));
|
||||
}
|
||||
|
@ -442,7 +540,8 @@ VM_DEFINE_FUNCTION (163, logior, "logior", 2)
|
|||
{
|
||||
ARGS2 (x, y);
|
||||
if (SCM_I_INUMP (x) && SCM_I_INUMP (y))
|
||||
RETURN (SCM_I_MAKINUM (SCM_I_INUM (x) | SCM_I_INUM (y)));
|
||||
/* Compute bitwise OR without untagging */
|
||||
RETURN (SCM_PACK (SCM_UNPACK (x) | SCM_UNPACK (y)));
|
||||
SYNC_REGISTER ();
|
||||
RETURN (scm_logior (x, y));
|
||||
}
|
||||
|
|
19
m4/copysign.m4
Normal file
19
m4/copysign.m4
Normal file
|
@ -0,0 +1,19 @@
|
|||
# copysign.m4 serial 1
|
||||
dnl Copyright (C) 2011-2013 Free Software Foundation, Inc.
|
||||
dnl This file is free software; the Free Software Foundation
|
||||
dnl gives unlimited permission to copy and/or distribute it,
|
||||
dnl with or without modifications, as long as this notice is preserved.
|
||||
|
||||
AC_DEFUN([gl_FUNC_COPYSIGN],
|
||||
[
|
||||
AC_REQUIRE([gl_MATH_H_DEFAULTS])
|
||||
|
||||
dnl Determine COPYSIGN_LIBM.
|
||||
gl_MATHFUNC([copysign], [double], [(double, double)])
|
||||
if test $gl_cv_func_copysign_no_libm = no \
|
||||
&& test $gl_cv_func_copysign_in_libm = no; then
|
||||
HAVE_COPYSIGN=0
|
||||
COPYSIGN_LIBM=
|
||||
fi
|
||||
AC_SUBST([COPYSIGN_LIBM])
|
||||
])
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
|
||||
# Specification in the form of a command-line invocation:
|
||||
# gnulib-tool --import --dir=. --local-dir=gnulib-local --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --lgpl=3 --no-conditional-dependencies --libtool --macro-prefix=gl --no-vc-files accept alignof alloca-opt announce-gen autobuild bind byteswap c-strcase canonicalize-lgpl ceil clock-time close connect dirfd duplocale environ extensions flock floor fpieee frexp fstat full-read full-write func gendocs getaddrinfo getlogin getpeername getsockname getsockopt git-version-gen gitlog-to-changelog gnu-web-doc-update gnupload havelib iconv_open-utf inet_ntop inet_pton isinf isnan ldexp lib-symbol-versions lib-symbol-visibility libunistring listen localcharset locale log1p maintainer-makefile malloc-gnu malloca nl_langinfo nproc open pipe-posix pipe2 poll putenv recv recvfrom regex rename select send sendto setenv setsockopt shutdown socket stat-time stdlib strftime striconveh string sys_stat time times trunc verify vsnprintf warnings wchar
|
||||
# gnulib-tool --import --dir=. --local-dir=gnulib-local --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --lgpl=3 --no-conditional-dependencies --libtool --macro-prefix=gl --no-vc-files accept alignof alloca-opt announce-gen autobuild bind byteswap c-strcase canonicalize-lgpl ceil clock-time close connect copysign dirfd duplocale environ extensions flock floor fpieee frexp fstat full-read full-write func gendocs getaddrinfo getlogin getpeername getsockname getsockopt git-version-gen gitlog-to-changelog gnu-web-doc-update gnupload havelib iconv_open-utf inet_ntop inet_pton isfinite isinf isnan ldexp lib-symbol-versions lib-symbol-visibility libunistring listen localcharset locale log1p maintainer-makefile malloc-gnu malloca nl_langinfo nproc open pipe-posix pipe2 poll putenv recv recvfrom regex rename select send sendto setenv setsockopt shutdown socket stat-time stdlib strftime striconveh string sys_stat time times trunc verify vsnprintf warnings wchar
|
||||
|
||||
# Specification in the form of a few gnulib-tool.m4 macro invocations:
|
||||
gl_LOCAL_DIR([gnulib-local])
|
||||
|
@ -45,6 +45,7 @@ gl_MODULES([
|
|||
clock-time
|
||||
close
|
||||
connect
|
||||
copysign
|
||||
dirfd
|
||||
duplocale
|
||||
environ
|
||||
|
@ -71,6 +72,7 @@ gl_MODULES([
|
|||
iconv_open-utf
|
||||
inet_ntop
|
||||
inet_pton
|
||||
isfinite
|
||||
isinf
|
||||
isnan
|
||||
largefile
|
||||
|
|
|
@ -61,6 +61,7 @@ AC_DEFUN([gl_EARLY],
|
|||
# Code from module close:
|
||||
# Code from module configmake:
|
||||
# Code from module connect:
|
||||
# Code from module copysign:
|
||||
# Code from module dirent:
|
||||
# Code from module dirfd:
|
||||
# Code from module dirname-lgpl:
|
||||
|
@ -108,12 +109,15 @@ AC_DEFUN([gl_EARLY],
|
|||
# Code from module inet_ntop:
|
||||
# Code from module inet_pton:
|
||||
# Code from module inline:
|
||||
# Code from module isfinite:
|
||||
# Code from module isinf:
|
||||
# Code from module isnan:
|
||||
# Code from module isnand:
|
||||
# Code from module isnand-nolibm:
|
||||
# Code from module isnanf:
|
||||
# Code from module isnanf-nolibm:
|
||||
# Code from module isnanl:
|
||||
# Code from module isnanl-nolibm:
|
||||
# Code from module langinfo:
|
||||
# Code from module largefile:
|
||||
AC_REQUIRE([AC_SYS_LARGEFILE])
|
||||
|
@ -172,6 +176,7 @@ AC_DEFUN([gl_EARLY],
|
|||
# Code from module setsockopt:
|
||||
# Code from module shutdown:
|
||||
# Code from module signal-h:
|
||||
# Code from module signbit:
|
||||
# Code from module size_max:
|
||||
# Code from module snippet/_Noreturn:
|
||||
# Code from module snippet/arg-nonnull:
|
||||
|
@ -292,6 +297,11 @@ AC_SUBST([LTALLOCA])
|
|||
AC_LIBOBJ([connect])
|
||||
fi
|
||||
gl_SYS_SOCKET_MODULE_INDICATOR([connect])
|
||||
gl_FUNC_COPYSIGN
|
||||
if test $HAVE_COPYSIGN = 0; then
|
||||
AC_LIBOBJ([copysign])
|
||||
fi
|
||||
gl_MATH_MODULE_INDICATOR([copysign])
|
||||
gl_DIRENT_H
|
||||
gl_FUNC_DIRFD
|
||||
if test $ac_cv_func_dirfd = no && test $gl_cv_func_dirfd_macro = no; then
|
||||
|
@ -415,6 +425,11 @@ AC_SUBST([LTALLOCA])
|
|||
fi
|
||||
gl_ARPA_INET_MODULE_INDICATOR([inet_pton])
|
||||
gl_INLINE
|
||||
gl_ISFINITE
|
||||
if test $REPLACE_ISFINITE = 1; then
|
||||
AC_LIBOBJ([isfinite])
|
||||
fi
|
||||
gl_MATH_MODULE_INDICATOR([isfinite])
|
||||
gl_ISINF
|
||||
if test $REPLACE_ISINF = 1; then
|
||||
AC_LIBOBJ([isinf])
|
||||
|
@ -445,6 +460,11 @@ AC_SUBST([LTALLOCA])
|
|||
gl_PREREQ_ISNANF
|
||||
fi
|
||||
gl_MATH_MODULE_INDICATOR([isnanf])
|
||||
gl_FUNC_ISNANF_NO_LIBM
|
||||
if test $gl_func_isnanf_no_libm != yes; then
|
||||
AC_LIBOBJ([isnanf])
|
||||
gl_PREREQ_ISNANF
|
||||
fi
|
||||
gl_FUNC_ISNANL
|
||||
m4_ifdef([gl_ISNAN], [
|
||||
AC_REQUIRE([gl_ISNAN])
|
||||
|
@ -454,6 +474,11 @@ AC_SUBST([LTALLOCA])
|
|||
gl_PREREQ_ISNANL
|
||||
fi
|
||||
gl_MATH_MODULE_INDICATOR([isnanl])
|
||||
gl_FUNC_ISNANL_NO_LIBM
|
||||
if test $gl_func_isnanl_no_libm != yes; then
|
||||
AC_LIBOBJ([isnanl])
|
||||
gl_PREREQ_ISNANL
|
||||
fi
|
||||
gl_LANGINFO_H
|
||||
AC_REQUIRE([gl_LARGEFILE])
|
||||
gl_FUNC_LDEXP
|
||||
|
@ -656,6 +681,13 @@ AC_SUBST([LTALLOCA])
|
|||
fi
|
||||
gl_SYS_SOCKET_MODULE_INDICATOR([shutdown])
|
||||
gl_SIGNAL_H
|
||||
gl_SIGNBIT
|
||||
if test $REPLACE_SIGNBIT = 1; then
|
||||
AC_LIBOBJ([signbitf])
|
||||
AC_LIBOBJ([signbitd])
|
||||
AC_LIBOBJ([signbitl])
|
||||
fi
|
||||
gl_MATH_MODULE_INDICATOR([signbit])
|
||||
gl_SIZE_MAX
|
||||
gl_FUNC_SNPRINTF
|
||||
gl_STDIO_MODULE_INDICATOR([snprintf])
|
||||
|
@ -935,6 +967,7 @@ AC_DEFUN([gl_FILE_LIST], [
|
|||
lib/close.c
|
||||
lib/config.charset
|
||||
lib/connect.c
|
||||
lib/copysign.c
|
||||
lib/dirent.in.h
|
||||
lib/dirfd.c
|
||||
lib/dirname-lgpl.c
|
||||
|
@ -976,11 +1009,14 @@ AC_DEFUN([gl_FILE_LIST], [
|
|||
lib/iconveh.h
|
||||
lib/inet_ntop.c
|
||||
lib/inet_pton.c
|
||||
lib/isfinite.c
|
||||
lib/isinf.c
|
||||
lib/isnan.c
|
||||
lib/isnand-nolibm.h
|
||||
lib/isnand.c
|
||||
lib/isnanf-nolibm.h
|
||||
lib/isnanf.c
|
||||
lib/isnanl-nolibm.h
|
||||
lib/isnanl.c
|
||||
lib/itold.c
|
||||
lib/langinfo.in.h
|
||||
|
@ -1053,6 +1089,9 @@ AC_DEFUN([gl_FILE_LIST], [
|
|||
lib/setsockopt.c
|
||||
lib/shutdown.c
|
||||
lib/signal.in.h
|
||||
lib/signbitd.c
|
||||
lib/signbitf.c
|
||||
lib/signbitl.c
|
||||
lib/size_max.h
|
||||
lib/snprintf.c
|
||||
lib/socket.c
|
||||
|
@ -1125,6 +1164,7 @@ AC_DEFUN([gl_FILE_LIST], [
|
|||
m4/close.m4
|
||||
m4/codeset.m4
|
||||
m4/configmake.m4
|
||||
m4/copysign.m4
|
||||
m4/dirent_h.m4
|
||||
m4/dirfd.m4
|
||||
m4/dirname.m4
|
||||
|
@ -1163,6 +1203,7 @@ AC_DEFUN([gl_FILE_LIST], [
|
|||
m4/inline.m4
|
||||
m4/intmax_t.m4
|
||||
m4/inttypes_h.m4
|
||||
m4/isfinite.m4
|
||||
m4/isinf.m4
|
||||
m4/isnan.m4
|
||||
m4/isnand.m4
|
||||
|
@ -1228,6 +1269,7 @@ AC_DEFUN([gl_FILE_LIST], [
|
|||
m4/servent.m4
|
||||
m4/setenv.m4
|
||||
m4/signal_h.m4
|
||||
m4/signbit.m4
|
||||
m4/size_max.m4
|
||||
m4/snprintf.m4
|
||||
m4/socketlib.m4
|
||||
|
|
165
m4/isfinite.m4
Normal file
165
m4/isfinite.m4
Normal file
|
@ -0,0 +1,165 @@
|
|||
# isfinite.m4 serial 13
|
||||
dnl Copyright (C) 2007-2013 Free Software Foundation, Inc.
|
||||
dnl This file is free software; the Free Software Foundation
|
||||
dnl gives unlimited permission to copy and/or distribute it,
|
||||
dnl with or without modifications, as long as this notice is preserved.
|
||||
|
||||
AC_DEFUN([gl_ISFINITE],
|
||||
[
|
||||
AC_REQUIRE([gl_MATH_H_DEFAULTS])
|
||||
dnl Persuade glibc <math.h> to declare isfinite.
|
||||
AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
|
||||
AC_CHECK_DECLS([isfinite], , , [[#include <math.h>]])
|
||||
if test "$ac_cv_have_decl_isfinite" = yes; then
|
||||
gl_CHECK_MATH_LIB([ISFINITE_LIBM],
|
||||
[x = isfinite (x) + isfinite ((float) x);])
|
||||
if test "$ISFINITE_LIBM" != missing; then
|
||||
dnl Test whether isfinite() on 'long double' works.
|
||||
gl_ISFINITEL_WORKS
|
||||
case "$gl_cv_func_isfinitel_works" in
|
||||
*yes) ;;
|
||||
*) ISFINITE_LIBM=missing;;
|
||||
esac
|
||||
dnl Also, isfinite() on 'double' does not work on Linux/ia64 (because of
|
||||
dnl signalling NaNs). But this does not have to be tested, since
|
||||
dnl isfinite(long double) also does not work in this situation.
|
||||
fi
|
||||
fi
|
||||
if test "$ac_cv_have_decl_isfinite" != yes ||
|
||||
test "$ISFINITE_LIBM" = missing; then
|
||||
REPLACE_ISFINITE=1
|
||||
dnl No libraries are needed to link lib/isfinite.c.
|
||||
ISFINITE_LIBM=
|
||||
fi
|
||||
AC_SUBST([ISFINITE_LIBM])
|
||||
])
|
||||
|
||||
dnl Test whether isfinite() on 'long double' recognizes all numbers which are
|
||||
dnl neither finite nor infinite. This test fails e.g. on i686, x86_64, ia64,
|
||||
dnl because of
|
||||
dnl - pseudo-denormals on x86_64,
|
||||
dnl - pseudo-zeroes, unnormalized numbers, and pseudo-denormals on i686,
|
||||
dnl - pseudo-NaN, pseudo-Infinity, pseudo-zeroes, unnormalized numbers, and
|
||||
dnl pseudo-denormals on ia64.
|
||||
AC_DEFUN([gl_ISFINITEL_WORKS],
|
||||
[
|
||||
AC_REQUIRE([AC_PROG_CC])
|
||||
AC_REQUIRE([gl_BIGENDIAN])
|
||||
AC_REQUIRE([gl_LONG_DOUBLE_VS_DOUBLE])
|
||||
AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
|
||||
AC_CACHE_CHECK([whether isfinite(long double) works], [gl_cv_func_isfinitel_works],
|
||||
[
|
||||
AC_RUN_IFELSE([AC_LANG_SOURCE([[
|
||||
#include <float.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#define NWORDS \
|
||||
((sizeof (long double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
|
||||
typedef union { unsigned int word[NWORDS]; long double value; }
|
||||
memory_long_double;
|
||||
/* On Irix 6.5, gcc 3.4.3 can't compute compile-time NaN, and needs the
|
||||
runtime type conversion. */
|
||||
#ifdef __sgi
|
||||
static long double NaNl ()
|
||||
{
|
||||
double zero = 0.0;
|
||||
return zero / zero;
|
||||
}
|
||||
#else
|
||||
# define NaNl() (0.0L / 0.0L)
|
||||
#endif
|
||||
int main ()
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
{
|
||||
memory_long_double m;
|
||||
unsigned int i;
|
||||
|
||||
/* The isfinite macro should be immune against changes in the sign bit and
|
||||
in the mantissa bits. The xor operation twiddles a bit that can only be
|
||||
a sign bit or a mantissa bit (since the exponent never extends to
|
||||
bit 31). */
|
||||
m.value = NaNl ();
|
||||
m.word[NWORDS / 2] ^= (unsigned int) 1 << (sizeof (unsigned int) * CHAR_BIT - 1);
|
||||
for (i = 0; i < NWORDS; i++)
|
||||
m.word[i] |= 1;
|
||||
if (isfinite (m.value))
|
||||
result |= 1;
|
||||
}
|
||||
|
||||
#if ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_)) && !HAVE_SAME_LONG_DOUBLE_AS_DOUBLE
|
||||
/* Representation of an 80-bit 'long double' as an initializer for a sequence
|
||||
of 'unsigned int' words. */
|
||||
# ifdef WORDS_BIGENDIAN
|
||||
# define LDBL80_WORDS(exponent,manthi,mantlo) \
|
||||
{ ((unsigned int) (exponent) << 16) | ((unsigned int) (manthi) >> 16), \
|
||||
((unsigned int) (manthi) << 16) | (unsigned int) (mantlo) >> 16), \
|
||||
(unsigned int) (mantlo) << 16 \
|
||||
}
|
||||
# else
|
||||
# define LDBL80_WORDS(exponent,manthi,mantlo) \
|
||||
{ mantlo, manthi, exponent }
|
||||
# endif
|
||||
{ /* Quiet NaN. */
|
||||
static memory_long_double x =
|
||||
{ LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
|
||||
if (isfinite (x.value))
|
||||
result |= 2;
|
||||
}
|
||||
{
|
||||
/* Signalling NaN. */
|
||||
static memory_long_double x =
|
||||
{ LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
|
||||
if (isfinite (x.value))
|
||||
result |= 2;
|
||||
}
|
||||
/* The isfinite macro should recognize Pseudo-NaNs, Pseudo-Infinities,
|
||||
Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
|
||||
Intel IA-64 Architecture Software Developer's Manual, Volume 1:
|
||||
Application Architecture.
|
||||
Table 5-2 "Floating-Point Register Encodings"
|
||||
Figure 5-6 "Memory to Floating-Point Register Data Translation"
|
||||
*/
|
||||
{ /* Pseudo-NaN. */
|
||||
static memory_long_double x =
|
||||
{ LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
|
||||
if (isfinite (x.value))
|
||||
result |= 4;
|
||||
}
|
||||
{ /* Pseudo-Infinity. */
|
||||
static memory_long_double x =
|
||||
{ LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
|
||||
if (isfinite (x.value))
|
||||
result |= 8;
|
||||
}
|
||||
{ /* Pseudo-Zero. */
|
||||
static memory_long_double x =
|
||||
{ LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
|
||||
if (isfinite (x.value))
|
||||
result |= 16;
|
||||
}
|
||||
{ /* Unnormalized number. */
|
||||
static memory_long_double x =
|
||||
{ LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
|
||||
if (isfinite (x.value))
|
||||
result |= 32;
|
||||
}
|
||||
{ /* Pseudo-Denormal. */
|
||||
static memory_long_double x =
|
||||
{ LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
|
||||
if (isfinite (x.value))
|
||||
result |= 64;
|
||||
}
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}]])], [gl_cv_func_isfinitel_works=yes], [gl_cv_func_isfinitel_works=no],
|
||||
[case "$host_cpu" in
|
||||
# Guess no on ia64, x86_64, i386.
|
||||
ia64 | x86_64 | i*86) gl_cv_func_isfinitel_works="guessing no";;
|
||||
*) gl_cv_func_isfinitel_works="guessing yes";;
|
||||
esac
|
||||
])
|
||||
])
|
||||
])
|
365
m4/signbit.m4
Normal file
365
m4/signbit.m4
Normal file
|
@ -0,0 +1,365 @@
|
|||
# signbit.m4 serial 13
|
||||
dnl Copyright (C) 2007-2013 Free Software Foundation, Inc.
|
||||
dnl This file is free software; the Free Software Foundation
|
||||
dnl gives unlimited permission to copy and/or distribute it,
|
||||
dnl with or without modifications, as long as this notice is preserved.
|
||||
|
||||
AC_DEFUN([gl_SIGNBIT],
|
||||
[
|
||||
AC_REQUIRE([gl_MATH_H_DEFAULTS])
|
||||
AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
|
||||
AC_CACHE_CHECK([for signbit macro], [gl_cv_func_signbit],
|
||||
[
|
||||
AC_RUN_IFELSE(
|
||||
[AC_LANG_SOURCE([[
|
||||
#include <math.h>
|
||||
/* If signbit is defined as a function, don't use it, since calling it for
|
||||
'float' or 'long double' arguments would involve conversions.
|
||||
If signbit is not declared at all but exists as a library function, don't
|
||||
use it, since the prototype may not match.
|
||||
If signbit is not declared at all but exists as a compiler built-in, don't
|
||||
use it, since it's preferable to use __builtin_signbit* (no warnings,
|
||||
no conversions). */
|
||||
#ifndef signbit
|
||||
# error "signbit should be a macro"
|
||||
#endif
|
||||
#include <string.h>
|
||||
]gl_SIGNBIT_TEST_PROGRAM
|
||||
])],
|
||||
[gl_cv_func_signbit=yes],
|
||||
[gl_cv_func_signbit=no],
|
||||
[case "$host_os" in
|
||||
# Guess yes on glibc systems.
|
||||
*-gnu*) gl_cv_func_signbit="guessing yes" ;;
|
||||
# If we don't know, assume the worst.
|
||||
*) gl_cv_func_signbit="guessing no" ;;
|
||||
esac
|
||||
])
|
||||
])
|
||||
dnl GCC 4.0 and newer provides three built-ins for signbit.
|
||||
dnl They can be used without warnings, also in C++, regardless of <math.h>.
|
||||
dnl But they may expand to calls to functions, which may or may not be in
|
||||
dnl libc.
|
||||
AC_CACHE_CHECK([for signbit compiler built-ins], [gl_cv_func_signbit_gcc],
|
||||
[
|
||||
AC_RUN_IFELSE(
|
||||
[AC_LANG_SOURCE([[
|
||||
#if __GNUC__ >= 4
|
||||
# define signbit(x) \
|
||||
(sizeof (x) == sizeof (long double) ? __builtin_signbitl (x) : \
|
||||
sizeof (x) == sizeof (double) ? __builtin_signbit (x) : \
|
||||
__builtin_signbitf (x))
|
||||
#else
|
||||
# error "signbit should be three compiler built-ins"
|
||||
#endif
|
||||
#include <string.h>
|
||||
]gl_SIGNBIT_TEST_PROGRAM
|
||||
])],
|
||||
[gl_cv_func_signbit_gcc=yes],
|
||||
[gl_cv_func_signbit_gcc=no],
|
||||
[case "$host_os" in
|
||||
# Guess yes on glibc systems.
|
||||
*-gnu*) gl_cv_func_signbit_gcc="guessing yes" ;;
|
||||
# If we don't know, assume the worst.
|
||||
*) gl_cv_func_signbit_gcc="guessing no" ;;
|
||||
esac
|
||||
])
|
||||
])
|
||||
dnl Use the compiler built-ins whenever possible, because they are more
|
||||
dnl efficient than the system library functions (if they exist).
|
||||
case "$gl_cv_func_signbit_gcc" in
|
||||
*yes)
|
||||
REPLACE_SIGNBIT_USING_GCC=1
|
||||
;;
|
||||
*)
|
||||
case "$gl_cv_func_signbit" in
|
||||
*yes) ;;
|
||||
*)
|
||||
dnl REPLACE_SIGNBIT=1 makes sure the signbit[fdl] functions get built.
|
||||
REPLACE_SIGNBIT=1
|
||||
gl_FLOAT_SIGN_LOCATION
|
||||
gl_DOUBLE_SIGN_LOCATION
|
||||
gl_LONG_DOUBLE_SIGN_LOCATION
|
||||
if test "$gl_cv_cc_float_signbit" = unknown; then
|
||||
dnl Test whether copysignf() is declared.
|
||||
AC_CHECK_DECLS([copysignf], , , [[#include <math.h>]])
|
||||
if test "$ac_cv_have_decl_copysignf" = yes; then
|
||||
dnl Test whether copysignf() can be used without libm.
|
||||
AC_CACHE_CHECK([whether copysignf can be used without linking with libm],
|
||||
[gl_cv_func_copysignf_no_libm],
|
||||
[
|
||||
AC_LINK_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
[[#include <math.h>
|
||||
float x, y;]],
|
||||
[[return copysignf (x, y) < 0;]])],
|
||||
[gl_cv_func_copysignf_no_libm=yes],
|
||||
[gl_cv_func_copysignf_no_libm=no])
|
||||
])
|
||||
if test $gl_cv_func_copysignf_no_libm = yes; then
|
||||
AC_DEFINE([HAVE_COPYSIGNF_IN_LIBC], [1],
|
||||
[Define if the copysignf function is declared in <math.h> and available in libc.])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if test "$gl_cv_cc_double_signbit" = unknown; then
|
||||
dnl Test whether copysign() is declared.
|
||||
AC_CHECK_DECLS([copysign], , , [[#include <math.h>]])
|
||||
if test "$ac_cv_have_decl_copysign" = yes; then
|
||||
dnl Test whether copysign() can be used without libm.
|
||||
AC_CACHE_CHECK([whether copysign can be used without linking with libm],
|
||||
[gl_cv_func_copysign_no_libm],
|
||||
[
|
||||
AC_LINK_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
[[#include <math.h>
|
||||
double x, y;]],
|
||||
[[return copysign (x, y) < 0;]])],
|
||||
[gl_cv_func_copysign_no_libm=yes],
|
||||
[gl_cv_func_copysign_no_libm=no])
|
||||
])
|
||||
if test $gl_cv_func_copysign_no_libm = yes; then
|
||||
AC_DEFINE([HAVE_COPYSIGN_IN_LIBC], [1],
|
||||
[Define if the copysign function is declared in <math.h> and available in libc.])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if test "$gl_cv_cc_long_double_signbit" = unknown; then
|
||||
dnl Test whether copysignl() is declared.
|
||||
AC_CHECK_DECLS([copysignl], , , [[#include <math.h>]])
|
||||
if test "$ac_cv_have_decl_copysignl" = yes; then
|
||||
dnl Test whether copysignl() can be used without libm.
|
||||
AC_CACHE_CHECK([whether copysignl can be used without linking with libm],
|
||||
[gl_cv_func_copysignl_no_libm],
|
||||
[
|
||||
AC_LINK_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
[[#include <math.h>
|
||||
long double x, y;]],
|
||||
[[return copysignl (x, y) < 0;]])],
|
||||
[gl_cv_func_copysignl_no_libm=yes],
|
||||
[gl_cv_func_copysignl_no_libm=no])
|
||||
])
|
||||
if test $gl_cv_func_copysignl_no_libm = yes; then
|
||||
AC_DEFINE([HAVE_COPYSIGNL_IN_LIBC], [1],
|
||||
[Define if the copysignl function is declared in <math.h> and available in libc.])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
])
|
||||
|
||||
AC_DEFUN([gl_SIGNBIT_TEST_PROGRAM], [[
|
||||
/* Global variables.
|
||||
Needed because GCC 4 constant-folds __builtin_signbitl (literal)
|
||||
but cannot constant-fold __builtin_signbitl (variable). */
|
||||
float vf;
|
||||
double vd;
|
||||
long double vl;
|
||||
int main ()
|
||||
{
|
||||
/* HP cc on HP-UX 10.20 has a bug with the constant expression -0.0.
|
||||
So we use -p0f and -p0d instead. */
|
||||
float p0f = 0.0f;
|
||||
float m0f = -p0f;
|
||||
double p0d = 0.0;
|
||||
double m0d = -p0d;
|
||||
/* On HP-UX 10.20, negating 0.0L does not yield -0.0L.
|
||||
So we use another constant expression instead.
|
||||
But that expression does not work on other platforms, such as when
|
||||
cross-compiling to PowerPC on Mac OS X 10.5. */
|
||||
long double p0l = 0.0L;
|
||||
#if defined __hpux || defined __sgi
|
||||
long double m0l = -LDBL_MIN * LDBL_MIN;
|
||||
#else
|
||||
long double m0l = -p0l;
|
||||
#endif
|
||||
int result = 0;
|
||||
if (signbit (vf)) /* link check */
|
||||
vf++;
|
||||
{
|
||||
float plus_inf = 1.0f / p0f;
|
||||
float minus_inf = -1.0f / p0f;
|
||||
if (!(!signbit (255.0f)
|
||||
&& signbit (-255.0f)
|
||||
&& !signbit (p0f)
|
||||
&& (memcmp (&m0f, &p0f, sizeof (float)) == 0 || signbit (m0f))
|
||||
&& !signbit (plus_inf)
|
||||
&& signbit (minus_inf)))
|
||||
result |= 1;
|
||||
}
|
||||
if (signbit (vd)) /* link check */
|
||||
vd++;
|
||||
{
|
||||
double plus_inf = 1.0 / p0d;
|
||||
double minus_inf = -1.0 / p0d;
|
||||
if (!(!signbit (255.0)
|
||||
&& signbit (-255.0)
|
||||
&& !signbit (p0d)
|
||||
&& (memcmp (&m0d, &p0d, sizeof (double)) == 0 || signbit (m0d))
|
||||
&& !signbit (plus_inf)
|
||||
&& signbit (minus_inf)))
|
||||
result |= 2;
|
||||
}
|
||||
if (signbit (vl)) /* link check */
|
||||
vl++;
|
||||
{
|
||||
long double plus_inf = 1.0L / p0l;
|
||||
long double minus_inf = -1.0L / p0l;
|
||||
if (signbit (255.0L))
|
||||
result |= 4;
|
||||
if (!signbit (-255.0L))
|
||||
result |= 4;
|
||||
if (signbit (p0l))
|
||||
result |= 8;
|
||||
if (!(memcmp (&m0l, &p0l, sizeof (long double)) == 0 || signbit (m0l)))
|
||||
result |= 16;
|
||||
if (signbit (plus_inf))
|
||||
result |= 32;
|
||||
if (!signbit (minus_inf))
|
||||
result |= 64;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
]])
|
||||
|
||||
AC_DEFUN([gl_FLOAT_SIGN_LOCATION],
|
||||
[
|
||||
gl_FLOATTYPE_SIGN_LOCATION([float], [gl_cv_cc_float_signbit], [f], [FLT])
|
||||
])
|
||||
|
||||
AC_DEFUN([gl_DOUBLE_SIGN_LOCATION],
|
||||
[
|
||||
gl_FLOATTYPE_SIGN_LOCATION([double], [gl_cv_cc_double_signbit], [], [DBL])
|
||||
])
|
||||
|
||||
AC_DEFUN([gl_LONG_DOUBLE_SIGN_LOCATION],
|
||||
[
|
||||
gl_FLOATTYPE_SIGN_LOCATION([long double], [gl_cv_cc_long_double_signbit], [L], [LDBL])
|
||||
])
|
||||
|
||||
AC_DEFUN([gl_FLOATTYPE_SIGN_LOCATION],
|
||||
[
|
||||
AC_CACHE_CHECK([where to find the sign bit in a '$1'],
|
||||
[$2],
|
||||
[
|
||||
AC_RUN_IFELSE(
|
||||
[AC_LANG_SOURCE([[
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#define NWORDS \
|
||||
((sizeof ($1) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
|
||||
typedef union { $1 value; unsigned int word[NWORDS]; }
|
||||
memory_float;
|
||||
static memory_float plus = { 1.0$3 };
|
||||
static memory_float minus = { -1.0$3 };
|
||||
int main ()
|
||||
{
|
||||
size_t j, k, i;
|
||||
unsigned int m;
|
||||
FILE *fp = fopen ("conftest.out", "w");
|
||||
if (fp == NULL)
|
||||
return 1;
|
||||
/* Find the different bit. */
|
||||
k = 0; m = 0;
|
||||
for (j = 0; j < NWORDS; j++)
|
||||
{
|
||||
unsigned int x = plus.word[j] ^ minus.word[j];
|
||||
if ((x & (x - 1)) || (x && m))
|
||||
{
|
||||
/* More than one bit difference. */
|
||||
fprintf (fp, "unknown");
|
||||
return 2;
|
||||
}
|
||||
if (x)
|
||||
{
|
||||
k = j;
|
||||
m = x;
|
||||
}
|
||||
}
|
||||
if (m == 0)
|
||||
{
|
||||
/* No difference. */
|
||||
fprintf (fp, "unknown");
|
||||
return 3;
|
||||
}
|
||||
/* Now m = plus.word[k] ^ ~minus.word[k]. */
|
||||
if (plus.word[k] & ~minus.word[k])
|
||||
{
|
||||
/* Oh? The sign bit is set in the positive and cleared in the negative
|
||||
numbers? */
|
||||
fprintf (fp, "unknown");
|
||||
return 4;
|
||||
}
|
||||
for (i = 0; ; i++)
|
||||
if ((m >> i) & 1)
|
||||
break;
|
||||
fprintf (fp, "word %d bit %d", (int) k, (int) i);
|
||||
if (fclose (fp) != 0)
|
||||
return 5;
|
||||
return 0;
|
||||
}
|
||||
]])],
|
||||
[$2=`cat conftest.out`],
|
||||
[$2="unknown"],
|
||||
[
|
||||
dnl When cross-compiling, we don't know. It depends on the
|
||||
dnl ABI and compiler version. There are too many cases.
|
||||
$2="unknown"
|
||||
])
|
||||
rm -f conftest.out
|
||||
])
|
||||
case "$]$2[" in
|
||||
word*bit*)
|
||||
word=`echo "$]$2[" | sed -e 's/word //' -e 's/ bit.*//'`
|
||||
bit=`echo "$]$2[" | sed -e 's/word.*bit //'`
|
||||
AC_DEFINE_UNQUOTED([$4][_SIGNBIT_WORD], [$word],
|
||||
[Define as the word index where to find the sign of '$1'.])
|
||||
AC_DEFINE_UNQUOTED([$4][_SIGNBIT_BIT], [$bit],
|
||||
[Define as the bit index in the word where to find the sign of '$1'.])
|
||||
;;
|
||||
esac
|
||||
])
|
||||
|
||||
# Expands to code that defines a function signbitf(float).
|
||||
# It extracts the sign bit of a non-NaN value.
|
||||
AC_DEFUN([gl_FLOAT_SIGNBIT_CODE],
|
||||
[
|
||||
gl_FLOATTYPE_SIGNBIT_CODE([float], [f], [f])
|
||||
])
|
||||
|
||||
# Expands to code that defines a function signbitd(double).
|
||||
# It extracts the sign bit of a non-NaN value.
|
||||
AC_DEFUN([gl_DOUBLE_SIGNBIT_CODE],
|
||||
[
|
||||
gl_FLOATTYPE_SIGNBIT_CODE([double], [d], [])
|
||||
])
|
||||
|
||||
# Expands to code that defines a function signbitl(long double).
|
||||
# It extracts the sign bit of a non-NaN value.
|
||||
AC_DEFUN([gl_LONG_DOUBLE_SIGNBIT_CODE],
|
||||
[
|
||||
gl_FLOATTYPE_SIGNBIT_CODE([long double], [l], [L])
|
||||
])
|
||||
|
||||
AC_DEFUN([gl_FLOATTYPE_SIGNBIT_CODE],
|
||||
[[
|
||||
static int
|
||||
signbit$2 ($1 value)
|
||||
{
|
||||
typedef union { $1 f; unsigned char b[sizeof ($1)]; } float_union;
|
||||
static float_union plus_one = { 1.0$3 }; /* unused bits are zero here */
|
||||
static float_union minus_one = { -1.0$3 }; /* unused bits are zero here */
|
||||
/* Compute the sign bit mask as the XOR of plus_one and minus_one. */
|
||||
float_union u;
|
||||
unsigned int i;
|
||||
u.f = value;
|
||||
for (i = 0; i < sizeof ($1); i++)
|
||||
if (u.b[i] & (plus_one.b[i] ^ minus_one.b[i]))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
]])
|
|
@ -41,6 +41,18 @@
|
|||
bitwise-reverse-bit-field)
|
||||
(import (rnrs base (6))
|
||||
(rnrs control (6))
|
||||
(rename (only (srfi srfi-60) bitwise-if
|
||||
integer-length
|
||||
first-set-bit
|
||||
copy-bit
|
||||
bit-field
|
||||
copy-bit-field
|
||||
rotate-bit-field
|
||||
reverse-bit-field)
|
||||
(integer-length bitwise-length)
|
||||
(first-set-bit bitwise-first-bit-set)
|
||||
(bit-field bitwise-bit-field)
|
||||
(reverse-bit-field bitwise-reverse-bit-field))
|
||||
(rename (only (guile) lognot
|
||||
logand
|
||||
logior
|
||||
|
@ -60,70 +72,21 @@
|
|||
(bitwise-not (logcount ei))
|
||||
(logcount ei)))
|
||||
|
||||
(define (bitwise-if ei1 ei2 ei3)
|
||||
(bitwise-ior (bitwise-and ei1 ei2) (bitwise-and (bitwise-not ei1) ei3)))
|
||||
|
||||
(define (bitwise-length ei)
|
||||
(do ((result 0 (+ result 1))
|
||||
(bits (if (negative? ei) (bitwise-not ei) ei)
|
||||
(bitwise-arithmetic-shift bits -1)))
|
||||
((zero? bits)
|
||||
result)))
|
||||
|
||||
(define (bitwise-first-bit-set ei)
|
||||
(define (bitwise-first-bit-set-inner bits count)
|
||||
(cond ((zero? bits) -1)
|
||||
((logbit? 0 bits) count)
|
||||
(else (bitwise-first-bit-set-inner
|
||||
(bitwise-arithmetic-shift bits -1) (+ count 1)))))
|
||||
(bitwise-first-bit-set-inner ei 0))
|
||||
|
||||
(define (bitwise-bit-set? ei1 ei2) (logbit? ei2 ei1))
|
||||
|
||||
(define (bitwise-copy-bit ei1 ei2 ei3)
|
||||
(bitwise-if (bitwise-arithmetic-shift-left 1 ei2)
|
||||
(bitwise-arithmetic-shift-left ei3 ei2)
|
||||
ei1))
|
||||
|
||||
(define (bitwise-bit-field ei1 ei2 ei3)
|
||||
(bitwise-arithmetic-shift-right
|
||||
(bitwise-and ei1 (bitwise-not (bitwise-arithmetic-shift-left -1 ei3)))
|
||||
ei2))
|
||||
;; The specification states that ei3 should be either 0 or 1.
|
||||
;; However, other values have been tolerated by both Guile 2.0.x and
|
||||
;; the sample implementation given the R6RS library document, so for
|
||||
;; backward compatibility we continue to permit it.
|
||||
(copy-bit ei2 ei1 (logbit? 0 ei3)))
|
||||
|
||||
(define (bitwise-copy-bit-field ei1 ei2 ei3 ei4)
|
||||
(bitwise-if (bitwise-and (bitwise-arithmetic-shift-left -1 ei2)
|
||||
(bitwise-not
|
||||
(bitwise-arithmetic-shift-left -1 ei3)))
|
||||
(bitwise-arithmetic-shift-left ei4 ei2)
|
||||
ei1))
|
||||
(copy-bit-field ei1 ei4 ei2 ei3))
|
||||
|
||||
(define (bitwise-rotate-bit-field ei1 ei2 ei3 ei4)
|
||||
(rotate-bit-field ei1 ei4 ei2 ei3))
|
||||
|
||||
(define bitwise-arithmetic-shift-left bitwise-arithmetic-shift)
|
||||
(define (bitwise-arithmetic-shift-right ei1 ei2)
|
||||
(bitwise-arithmetic-shift ei1 (- ei2)))
|
||||
|
||||
(define (bitwise-rotate-bit-field ei1 ei2 ei3 ei4)
|
||||
(let ((width (- ei3 ei2)))
|
||||
(if (positive? width)
|
||||
(let ((field (bitwise-bit-field ei1 ei2 ei3))
|
||||
(count (modulo ei4 width)))
|
||||
(bitwise-copy-bit-field
|
||||
ei1 ei2 ei3
|
||||
(bitwise-ior (bitwise-arithmetic-shift-left field count)
|
||||
(bitwise-arithmetic-shift-right
|
||||
field (- width count)))))
|
||||
ei1)))
|
||||
|
||||
(define (bitwise-reverse-bit-field ei1 ei2 ei3)
|
||||
(define (reverse-bit-field-recursive n1 n2 len)
|
||||
(if (> len 0)
|
||||
(reverse-bit-field-recursive
|
||||
(bitwise-arithmetic-shift-right n1 1)
|
||||
(bitwise-copy-bit (bitwise-arithmetic-shift-left n2 1) 0 n1)
|
||||
(- len 1))
|
||||
n2))
|
||||
(let ((width (- ei3 ei2)))
|
||||
(if (positive? width)
|
||||
(let ((field (bitwise-bit-field ei1 ei2 ei3)))
|
||||
(bitwise-copy-bit-field
|
||||
ei1 ei2 ei3 (reverse-bit-field-recursive field 0 width)))
|
||||
ei1))))
|
||||
(bitwise-arithmetic-shift ei1 (- ei2))))
|
||||
|
|
|
@ -150,7 +150,7 @@
|
|||
(testeqv (inexact->exact (exact->inexact 2135445/16777216)) 2135445/16777216)
|
||||
(testeq (< (- (exact->inexact 10197734562406803221/17452826108659293487)
|
||||
.584302765576009) .0000001) #t)
|
||||
(testeqv (rationalize #e0.76 1/10) 3/4)
|
||||
(testeqv (rationalize #e0.76 1/10) 2/3)
|
||||
(testeqv (rationalize #e0.723 1/10) 2/3)
|
||||
(testeqv (rationalize #e0.723 1/100) 5/7)
|
||||
(testeqv (rationalize #e-0.723 1/100) -5/7)
|
||||
|
@ -351,7 +351,7 @@
|
|||
(test= (- 0+6i 1/4 0.5 7) -7.75+6.0i)
|
||||
(testeqv (rationalize #e2.5 1/1000) 5/2)
|
||||
(testeqv (rationalize 7/3 1/1000) 7/3)
|
||||
(testeqv (rationalize #e3.14159265 1/10) 22/7)
|
||||
(testeqv (rationalize #e3.14159265 1/10) 16/5)
|
||||
(testeqv (numerator (/ 8 -6)) -4)
|
||||
(testeqv (denominator (/ 8 -6)) 3)
|
||||
(testeqv (gcd (numerator 7/9) (denominator 7/9)) 1)
|
||||
|
|
|
@ -1431,6 +1431,35 @@
|
|||
(pass-if (eqv? 1/3 (rationalize 3/10 -1/10)))
|
||||
(pass-if (eqv? -1/3 (rationalize -3/10 -1/10)))
|
||||
|
||||
;; Prior to Guile 2.0.10, rationalize used a faulty algorithm that
|
||||
;; incorrectly returned 2/3 and -2/3 in the following cases.
|
||||
(pass-if (eqv? 1/2 (rationalize #e+0.67 1/4)))
|
||||
(pass-if (eqv? -1/2 (rationalize #e-0.67 1/4)))
|
||||
|
||||
(pass-if (eqv? 1 (rationalize #e+0.67 1/3)))
|
||||
(pass-if (eqv? -1 (rationalize #e-0.67 1/3)))
|
||||
|
||||
(pass-if (eqv? 1/2 (rationalize #e+0.66 1/3)))
|
||||
(pass-if (eqv? -1/2 (rationalize #e-0.66 1/3)))
|
||||
|
||||
(pass-if (eqv? 1 (rationalize #e+0.67 2/3)))
|
||||
(pass-if (eqv? -1 (rationalize #e-0.67 2/3)))
|
||||
|
||||
(pass-if (eqv? 0 (rationalize #e+0.66 2/3)))
|
||||
(pass-if (eqv? 0 (rationalize #e-0.66 2/3)))
|
||||
|
||||
;; Prior to Guile 2.0.10, rationalize used a faulty algorithm that
|
||||
;; incorrectly computed the following approximations of PI.
|
||||
(with-test-prefix "pi"
|
||||
(define *pi* #e3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679)
|
||||
(pass-if (eqv? 16/5 (rationalize *pi* 1/10)))
|
||||
(pass-if (eqv? 201/64 (rationalize *pi* 1/1000)))
|
||||
(pass-if (eqv? 75948/24175 (rationalize *pi* (expt 10 -7))))
|
||||
(pass-if (eqv? 100798/32085 (rationalize *pi* (expt 10 -8))))
|
||||
(pass-if (eqv? 58466453/18610450 (rationalize *pi* (expt 10 -14))))
|
||||
(pass-if (eqv? 2307954651196778721982809475299879198775111361078/734644782339796933783743757007944508986600750685
|
||||
(rationalize *pi* (expt 10 -95)))))
|
||||
|
||||
(pass-if (test-eqv? (/ 1.0 3) (rationalize 0.3 1/10)))
|
||||
(pass-if (test-eqv? (/ -1.0 3) (rationalize -0.3 1/10)))
|
||||
(pass-if (test-eqv? (/ 1.0 3) (rationalize 0.3 -1/10)))
|
||||
|
|
|
@ -62,7 +62,7 @@
|
|||
|
||||
(with-test-prefix "bitwise-copy-bit"
|
||||
(pass-if "bitwise-copy-bit simple"
|
||||
(eqv? (bitwise-copy-bit #b010 2 #b111) #b110)))
|
||||
(eqv? (bitwise-copy-bit #b010 2 1) #b110)))
|
||||
|
||||
(with-test-prefix "bitwise-bit-field"
|
||||
(pass-if "bitwise-bit-field simple"
|
||||
|
|
|
@ -184,7 +184,7 @@
|
|||
|
||||
(pass-if "fxbit-set? is #f on index of unset bit" (not (fxbit-set? 5 1))))
|
||||
|
||||
(with-test-prefix "fxcopy-bit" (pass-if "simple" (fx=? (fxcopy-bit 2 2 7) 6)))
|
||||
(with-test-prefix "fxcopy-bit" (pass-if "simple" (fx=? (fxcopy-bit 2 2 1) 6)))
|
||||
|
||||
(with-test-prefix "fxbit-field"
|
||||
(pass-if "simple" (fx=? (fxbit-field 50 1 4) 1)))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue