Fix portability issues in pg_bitutils

We were using uint64 function arguments as "long int" arguments to
compiler builtins, which fails on machines where long ints are 32 bits:
the upper half of the uint64 was being ignored.  Fix by using the "ll"
builtin variants instead, which on those machines take 64 bit arguments.

Also, remove configure tests for __builtin_popcountl() (as well as
"long" variants for ctz and clz): the theory here is that any compiler
version will provide all widths or none, so one test suffices.  Were
this theory to be wrong, we'd have to add tests for
__builtin_popcountll() and friends, which would be tedious.

Per failures in buildfarm member lapwing and ensuing discussion.
This commit is contained in:
Alvaro Herrera 2019-02-13 20:09:48 -03:00
parent 80c468b4a4
commit 109de05cbb
6 changed files with 98 additions and 256 deletions

View File

@ -400,28 +400,6 @@ undefine([Ac_cachevar])dnl
# PGAC_C_BUILTIN_POPCOUNTL
# -------------------------
AC_DEFUN([PGAC_C_BUILTIN_POPCOUNTL],
[define([Ac_cachevar], [AS_TR_SH([pgac_cv_popcountl])])dnl
AC_CACHE_CHECK([for __builtin_popcountl], [Ac_cachevar],
[pgac_save_CFLAGS=$CFLAGS
CFLAGS="$pgac_save_CFLAGS -mpopcnt"
AC_COMPILE_IFELSE([AC_LANG_SOURCE(
[static int x = __builtin_popcountl(255);])],
[Ac_cachevar=yes],
[Ac_cachevar=no])
CFLAGS="$pgac_save_CFLAGS"])
if test x"$Ac_cachevar" = x"yes"; then
CFLAGS_POPCNT="-mpopcnt"
AC_DEFINE(HAVE__BUILTIN_POPCOUNTL, 1,
[Define to 1 if your compiler understands __builtin_popcountl.])
fi
undefine([Ac_cachevar])dnl
])# PGAC_C_BUILTIN_POPCOUNTL
# PGAC_C_BUILTIN_CTZ
# -------------------------
# Check if the C compiler understands __builtin_ctz(),
@ -440,24 +418,6 @@ fi])# PGAC_C_BUILTIN_CTZ
# PGAC_C_BUILTIN_CTZL
# -------------------------
# Check if the C compiler understands __builtin_ctzl(),
# and define HAVE__BUILTIN_CTZL if so.
AC_DEFUN([PGAC_C_BUILTIN_CTZL],
[AC_CACHE_CHECK(for __builtin_ctzl, pgac_cv__builtin_ctzl,
[AC_COMPILE_IFELSE([AC_LANG_SOURCE(
[static int x = __builtin_ctzl(256);]
)],
[pgac_cv__builtin_ctzl=yes],
[pgac_cv__builtin_ctzl=no])])
if test x"$pgac_cv__builtin_ctzl" = xyes ; then
AC_DEFINE(HAVE__BUILTIN_CTZL, 1,
[Define to 1 if your compiler understands __builtin_ctzl.])
fi])# PGAC_C_BUILTIN_CTZL
# PGAC_C_BUILTIN_CLZ
# -------------------------
# Check if the C compiler understands __builtin_clz(),
@ -476,24 +436,6 @@ fi])# PGAC_C_BUILTIN_CLZ
# PGAC_C_BUILTIN_CLZL
# -------------------------
# Check if the C compiler understands __builtin_clzl(),
# and define HAVE__BUILTIN_CLZL if so.
AC_DEFUN([PGAC_C_BUILTIN_CLZL],
[AC_CACHE_CHECK(for __builtin_clzl, pgac_cv__builtin_clzl,
[AC_COMPILE_IFELSE([AC_LANG_SOURCE(
[static int x = __builtin_clzl(256);]
)],
[pgac_cv__builtin_clzl=yes],
[pgac_cv__builtin_clzl=no])])
if test x"$pgac_cv__builtin_clzl" = xyes ; then
AC_DEFINE(HAVE__BUILTIN_CLZL, 1,
[Define to 1 if your compiler understands __builtin_clzl.])
fi])# PGAC_C_BUILTIN_CLZL
# PGAC_C_BUILTIN_UNREACHABLE
# --------------------------
# Check if the C compiler understands __builtin_unreachable(),

172
configure vendored
View File

@ -14033,6 +14033,30 @@ if test x"$pgac_cv__builtin_bswap64" = xyes ; then
$as_echo "#define HAVE__BUILTIN_BSWAP64 1" >>confdefs.h
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_clz" >&5
$as_echo_n "checking for __builtin_clz... " >&6; }
if ${pgac_cv__builtin_clz+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
static int x = __builtin_clz(256);
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
pgac_cv__builtin_clz=yes
else
pgac_cv__builtin_clz=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv__builtin_clz" >&5
$as_echo "$pgac_cv__builtin_clz" >&6; }
if test x"$pgac_cv__builtin_clz" = xyes ; then
$as_echo "#define HAVE__BUILTIN_CLZ 1" >>confdefs.h
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_constant_p" >&5
$as_echo_n "checking for __builtin_constant_p... " >&6; }
@ -14060,6 +14084,30 @@ if test x"$pgac_cv__builtin_constant_p" = xyes ; then
$as_echo "#define HAVE__BUILTIN_CONSTANT_P 1" >>confdefs.h
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_ctz" >&5
$as_echo_n "checking for __builtin_ctz... " >&6; }
if ${pgac_cv__builtin_ctz+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
static int x = __builtin_ctz(256);
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
pgac_cv__builtin_ctz=yes
else
pgac_cv__builtin_ctz=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv__builtin_ctz" >&5
$as_echo "$pgac_cv__builtin_ctz" >&6; }
if test x"$pgac_cv__builtin_ctz" = xyes ; then
$as_echo "#define HAVE__BUILTIN_CTZ 1" >>confdefs.h
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_popcount" >&5
$as_echo_n "checking for __builtin_popcount... " >&6; }
@ -14089,130 +14137,6 @@ $as_echo "#define HAVE__BUILTIN_POPCOUNT 1" >>confdefs.h
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_popcountl" >&5
$as_echo_n "checking for __builtin_popcountl... " >&6; }
if ${pgac_cv_popcountl+:} false; then :
$as_echo_n "(cached) " >&6
else
pgac_save_CFLAGS=$CFLAGS
CFLAGS="$pgac_save_CFLAGS -mpopcnt"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
static int x = __builtin_popcountl(255);
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
pgac_cv_popcountl=yes
else
pgac_cv_popcountl=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
CFLAGS="$pgac_save_CFLAGS"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_popcountl" >&5
$as_echo "$pgac_cv_popcountl" >&6; }
if test x"$pgac_cv_popcountl" = x"yes"; then
CFLAGS_POPCNT="-mpopcnt"
$as_echo "#define HAVE__BUILTIN_POPCOUNTL 1" >>confdefs.h
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_ctz" >&5
$as_echo_n "checking for __builtin_ctz... " >&6; }
if ${pgac_cv__builtin_ctz+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
static int x = __builtin_ctz(256);
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
pgac_cv__builtin_ctz=yes
else
pgac_cv__builtin_ctz=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv__builtin_ctz" >&5
$as_echo "$pgac_cv__builtin_ctz" >&6; }
if test x"$pgac_cv__builtin_ctz" = xyes ; then
$as_echo "#define HAVE__BUILTIN_CTZ 1" >>confdefs.h
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_ctzl" >&5
$as_echo_n "checking for __builtin_ctzl... " >&6; }
if ${pgac_cv__builtin_ctzl+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
static int x = __builtin_ctzl(256);
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
pgac_cv__builtin_ctzl=yes
else
pgac_cv__builtin_ctzl=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv__builtin_ctzl" >&5
$as_echo "$pgac_cv__builtin_ctzl" >&6; }
if test x"$pgac_cv__builtin_ctzl" = xyes ; then
$as_echo "#define HAVE__BUILTIN_CTZL 1" >>confdefs.h
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_clz" >&5
$as_echo_n "checking for __builtin_clz... " >&6; }
if ${pgac_cv__builtin_clz+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
static int x = __builtin_clz(256);
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
pgac_cv__builtin_clz=yes
else
pgac_cv__builtin_clz=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv__builtin_clz" >&5
$as_echo "$pgac_cv__builtin_clz" >&6; }
if test x"$pgac_cv__builtin_clz" = xyes ; then
$as_echo "#define HAVE__BUILTIN_CLZ 1" >>confdefs.h
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_clzl" >&5
$as_echo_n "checking for __builtin_clzl... " >&6; }
if ${pgac_cv__builtin_clzl+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
static int x = __builtin_clzl(256);
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
pgac_cv__builtin_clzl=yes
else
pgac_cv__builtin_clzl=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv__builtin_clzl" >&5
$as_echo "$pgac_cv__builtin_clzl" >&6; }
if test x"$pgac_cv__builtin_clzl" = xyes ; then
$as_echo "#define HAVE__BUILTIN_CLZL 1" >>confdefs.h
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_unreachable" >&5
$as_echo_n "checking for __builtin_unreachable... " >&6; }
if ${pgac_cv__builtin_unreachable+:} false; then :

View File

@ -1488,13 +1488,10 @@ PGAC_C_TYPES_COMPATIBLE
PGAC_C_BUILTIN_BSWAP16
PGAC_C_BUILTIN_BSWAP32
PGAC_C_BUILTIN_BSWAP64
PGAC_C_BUILTIN_CONSTANT_P
PGAC_C_BUILTIN_POPCOUNT
PGAC_C_BUILTIN_POPCOUNTL
PGAC_C_BUILTIN_CTZ
PGAC_C_BUILTIN_CTZL
PGAC_C_BUILTIN_CLZ
PGAC_C_BUILTIN_CLZL
PGAC_C_BUILTIN_CONSTANT_P
PGAC_C_BUILTIN_CTZ
PGAC_C_BUILTIN_POPCOUNT
PGAC_C_BUILTIN_UNREACHABLE
PGAC_C_COMPUTED_GOTO
PGAC_STRUCT_TIMEZONE

View File

@ -748,30 +748,21 @@
/* Define to 1 if your compiler understands __builtin_bswap64. */
#undef HAVE__BUILTIN_BSWAP64
/* Define to 1 if your compiler understands __builtin_clz. */
#undef HAVE__BUILTIN_CLZ
/* Define to 1 if your compiler understands __builtin_constant_p. */
#undef HAVE__BUILTIN_CONSTANT_P
/* Define to 1 if your compiler understands __builtin_ctz. */
#undef HAVE__BUILTIN_CTZ
/* Define to 1 if your compiler understands __builtin_$op_overflow. */
#undef HAVE__BUILTIN_OP_OVERFLOW
/* Define to 1 if your compiler understands __builtin_popcount. */
#undef HAVE__BUILTIN_POPCOUNT
/* Define to 1 if your compiler understands __builtin_popcountl. */
#undef HAVE__BUILTIN_POPCOUNTL
/* Define to 1 if your compiler understands __builtin_ctz. */
#undef HAVE__BUILTIN_CTZ
/* Define to 1 if your compiler understands __builtin_ctzl. */
#undef HAVE__BUILTIN_CTZL
/* Define to 1 if your compiler understands __builtin_clz. */
#undef HAVE__BUILTIN_CLZ
/* Define to 1 if your compiler understands __builtin_clzl. */
#undef HAVE__BUILTIN_CLZL
/* Define to 1 if your compiler understands __builtin_types_compatible_p. */
#undef HAVE__BUILTIN_TYPES_COMPATIBLE_P

View File

@ -587,30 +587,21 @@
/* Define to 1 if your compiler understands __builtin_bswap64. */
/* #undef HAVE__BUILTIN_BSWAP64 */
/* Define to 1 if your compiler understands __builtin_clz. */
/* #undef HAVE__BUILTIN_CLZ */
/* Define to 1 if your compiler understands __builtin_constant_p. */
/* #undef HAVE__BUILTIN_CONSTANT_P */
/* Define to 1 if your compiler understands __builtin_ctz. */
/* #undef HAVE__BUILTIN_CTZ */
/* Define to 1 if your compiler understands __builtin_$op_overflow. */
/* #undef HAVE__BUILTIN_OP_OVERFLOW */
/* Define to 1 if your compiler understands __builtin_popcount. */
/* #undef HAVE__BUILTIN_POPCOUNT */
/* Define to 1 if your compiler understands __builtin_popcountl. */
/* #undef HAVE__BUILTIN_POPCOUNTL */
/* Define to 1 if your compiler understands __builtin_ctz. */
/* #undef HAVE__BUILTIN_CTZ */
/* Define to 1 if your compiler understands __builtin_ctzl. */
/* #undef HAVE__BUILTIN_CTZL */
/* Define to 1 if your compiler understands __builtin_clz. */
/* #undef HAVE__BUILTIN_CLZ */
/* Define to 1 if your compiler understands __builtin_clzl. */
/* #undef HAVE__BUILTIN_CLZL */
/* Define to 1 if your compiler understands __builtin_types_compatible_p. */
/* #undef HAVE__BUILTIN_TYPES_COMPATIBLE_P */

View File

@ -23,87 +23,62 @@
#include "port/pg_bitutils.h"
#if defined(HAVE__GET_CPUID) && (defined(HAVE__BUILTIN_POPCOUNT) || defined(HAVE__BUILTIN_POPCOUNTL))
static bool pg_popcount_available(void);
#endif
#if defined(HAVE__BUILTIN_POPCOUNT) && defined(HAVE__GET_CPUID)
static bool pg_popcount_available(void);
static int pg_popcount32_choose(uint32 word);
static int pg_popcount32_sse42(uint32 word);
#endif
static int pg_popcount32_slow(uint32 word);
#if defined(HAVE__BUILTIN_POPCOUNTL) && defined(HAVE__GET_CPUID)
static int pg_popcount64_choose(uint64 word);
static int pg_popcount64_sse42(uint64 word);
#endif
static int pg_popcount32_slow(uint32 word);
static int pg_popcount64_slow(uint64 word);
#if defined(HAVE__GET_CPUID) && (defined(HAVE__BUILTIN_CTZ) || defined(HAVE__BUILTIN_CTZL) || defined(HAVE__BUILTIN_CLZ) || defined(HAVE__BUILTIN_CLZL))
#if defined(HAVE__GET_CPUID) && (defined(HAVE__BUILTIN_CTZ) || defined(HAVE__BUILTIN_CLZ))
static bool pg_lzcnt_available(void);
#endif
#if defined(HAVE__BUILTIN_CTZ) && defined(HAVE__GET_CPUID)
static int pg_rightmost_one32_choose(uint32 word);
static int pg_rightmost_one32_abm(uint32 word);
#endif
static int pg_rightmost_one32_slow(uint32 word);
#if defined(HAVE__BUILTIN_CTZL) && defined(HAVE__GET_CPUID)
static int pg_rightmost_one64_choose(uint64 word);
static int pg_rightmost_one64_abm(uint64 word);
#endif
static int pg_rightmost_one32_slow(uint32 word);
static int pg_rightmost_one64_slow(uint64 word);
#if defined(HAVE__BUILTIN_CLZ) && defined(HAVE__GET_CPUID)
static int pg_leftmost_one32_choose(uint32 word);
static int pg_leftmost_one32_abm(uint32 word);
#endif
static int pg_leftmost_one32_slow(uint32 word);
#if defined(HAVE__BUILTIN_CLZL) && defined(HAVE__GET_CPUID)
static int pg_leftmost_one64_choose(uint64 word);
static int pg_leftmost_one64_abm(uint64 word);
#endif
static int pg_leftmost_one32_slow(uint32 word);
static int pg_leftmost_one64_slow(uint64 word);
#if defined(HAVE__BUILTIN_POPCOUNT) && defined(HAVE__GET_CPUID)
int (*pg_popcount32) (uint32 word) = pg_popcount32_choose;
#else
int (*pg_popcount32) (uint32 word) = pg_popcount32_slow;
#endif
#if defined(HAVE__BUILTIN_POPCOUNTL) && defined(HAVE__GET_CPUID)
int (*pg_popcount64) (uint64 word) = pg_popcount64_choose;
#else
int (*pg_popcount32) (uint32 word) = pg_popcount32_slow;
int (*pg_popcount64) (uint64 word) = pg_popcount64_slow;
#endif
#if defined(HAVE__BUILTIN_CTZ) && defined(HAVE__GET_CPUID)
int (*pg_rightmost_one32) (uint32 word) = pg_rightmost_one32_choose;
#else
int (*pg_rightmost_one32) (uint32 word) = pg_rightmost_one32_slow;
#endif
#if defined(HAVE__BUILTIN_CTZL) && defined(HAVE__GET_CPUID)
int (*pg_rightmost_one64) (uint64 word) = pg_rightmost_one64_choose;
#else
int (*pg_rightmost_one32) (uint32 word) = pg_rightmost_one32_slow;
int (*pg_rightmost_one64) (uint64 word) = pg_rightmost_one64_slow;
#endif
#if defined(HAVE__BUILTIN_CLZ) && defined(HAVE__GET_CPUID)
int (*pg_leftmost_one32) (uint32 word) = pg_leftmost_one32_choose;
#else
int (*pg_leftmost_one32) (uint32 word) = pg_leftmost_one32_slow;
#endif
#if defined(HAVE__BUILTIN_CLZL) && defined(HAVE__GET_CPUID)
int (*pg_leftmost_one64) (uint64 word) = pg_leftmost_one64_choose;
#else
int (*pg_leftmost_one32) (uint32 word) = pg_leftmost_one32_slow;
int (*pg_leftmost_one64) (uint64 word) = pg_leftmost_one64_slow;
#endif
/* Array marking the number of 1-bits for each value of 0-255. */
static const uint8 number_of_ones[256] = {
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
@ -172,7 +147,7 @@ static const uint8 leftmost_one_pos[256] = {
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
};
#if defined(HAVE__GET_CPUID) && (defined(HAVE__BUILTIN_POPCOUNT) || defined(HAVE__BUILTIN_POPCOUNTL))
#if defined(HAVE__GET_CPUID) && defined(HAVE__BUILTIN_POPCOUNT)
static bool
pg_popcount_available(void)
@ -279,7 +254,7 @@ pg_popcount(const char *buf, int bytes)
return popcnt;
}
#if defined(HAVE__GET_CPUID) && defined(HAVE__BUILTIN_POPCOUNTL)
#if defined(HAVE__GET_CPUID) && defined(HAVE__BUILTIN_POPCOUNT)
/*
* This gets called on the first call. It replaces the function pointer
@ -299,7 +274,14 @@ pg_popcount64_choose(uint64 word)
static int
pg_popcount64_sse42(uint64 word)
{
#if defined(HAVE_LONG_INT_64)
return __builtin_popcountl(word);
#elif defined(HAVE_LONG_LONG_INT_64)
return __builtin_popcountll(word);
#else
/* shouldn't happen */
#error must have a working 64-bit integer datatype
#endif
}
#endif
@ -322,7 +304,7 @@ pg_popcount64_slow(uint64 word)
return result;
}
#if defined(HAVE__GET_CPUID) && (defined(HAVE__BUILTIN_CTZ) || defined(HAVE__BUILTIN_CTZL) || defined(HAVE__BUILTIN_CLZ) || defined(HAVE__BUILTIN_CLZL))
#if defined(HAVE__GET_CPUID) && (defined(HAVE__BUILTIN_CTZ) || defined(HAVE__BUILTIN_CLZ))
static bool
pg_lzcnt_available(void)
@ -388,7 +370,7 @@ pg_rightmost_one32_slow(uint32 word)
return result;
}
#if defined(HAVE__GET_CPUID) && defined(HAVE__BUILTIN_CTZL)
#if defined(HAVE__GET_CPUID) && defined(HAVE__BUILTIN_CTZ)
/*
* This gets called on the first call. It replaces the function pointer
* so that subsequent calls are routed directly to the chosen implementation.
@ -407,7 +389,14 @@ pg_rightmost_one64_choose(uint64 word)
static int
pg_rightmost_one64_abm(uint64 word)
{
#if defined(HAVE_LONG_INT_64)
return __builtin_ctzl(word);
#elif defined(HAVE_LONG_LONG_INT_64)
return __builtin_ctzll(word);
#else
/* shouldn't happen */
#error must have a working 64-bit integer datatype
#endif
}
#endif
@ -474,7 +463,7 @@ pg_leftmost_one32_slow(uint32 word)
return shift + leftmost_one_pos[(word >> shift) & 255];
}
#if defined(HAVE__GET_CPUID) && defined(HAVE__BUILTIN_CLZL)
#if defined(HAVE__GET_CPUID) && defined(HAVE__BUILTIN_CLZ)
/*
* This gets called on the first call. It replaces the function pointer
* so that subsequent calls are routed directly to the chosen implementation.
@ -493,7 +482,15 @@ pg_leftmost_one64_choose(uint64 word)
static int
pg_leftmost_one64_abm(uint64 word)
{
#if defined(HAVE_LONG_INT_64)
return 63 - __builtin_clzl(word);
#elif defined(HAVE_LONG_LONG_INT_64)
return 63 - __builtin_clzll(word);
#else
/* shouldn't happen */
#error must have a working 64-bit integer datatype
#endif
}
#endif