Hi, Now that we have stdbit.h I think that it would be nice to reduce the duplication in all the bit operation modules.
Is there any reason not to use stdbit.h for ffs, ffsl, ffsll, count-leading-zeros, count-one-bits, count-trailing-zeros? I've attached an unpushed patch for count-one-bits and can do the rest if there isn't any disagreement. Collin
>From abacaf822fe21d1acfc766b33fa1ba06867c39c6 Mon Sep 17 00:00:00 2001 From: Collin Funk <collin.fu...@gmail.com> Date: Tue, 17 Dec 2024 12:34:40 -0800 Subject: [PATCH] count-one-bits: Implement using stdbit.h. * lib/count-one-bits.h: Include stdbit.h. (COUNT_ONE_BITS): Remove definition. (COUNT_ONE_BITS_GENERIC): Likewise. (count_one_bits_32): Remove function. (__cpuid, __popcnt, __popcnt64, popcount_support, popcount_supported) [_MSC_VER]: Remove declarations. (__popcnt64) [_MSC_VER && !_M_X64]: Remove function. (count_one_bits): Use stdc_count_ones_ui. (count_one_bits_l): Use stdc_count_ones_ul. (count_one_bits_ll): stdc_count_ones_ull. * lib/count-one-bits.c (popcount_support) [_MSC_VER]: Remove variable. * modules/count-one-bits (Depends-on): Add stdc_count_ones. --- ChangeLog | 16 ++++++ lib/count-one-bits.c | 3 -- lib/count-one-bits.h | 112 ++--------------------------------------- modules/count-one-bits | 1 + 4 files changed, 21 insertions(+), 111 deletions(-) diff --git a/ChangeLog b/ChangeLog index 74d1ded7d5..742a38044f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2024-12-17 Collin Funk <collin.fu...@gmail.com> + + count-one-bits: Implement using stdbit.h. + * lib/count-one-bits.h: Include stdbit.h. + (COUNT_ONE_BITS): Remove definition. + (COUNT_ONE_BITS_GENERIC): Likewise. + (count_one_bits_32): Remove function. + (__cpuid, __popcnt, __popcnt64, popcount_support, popcount_supported) + [_MSC_VER]: Remove declarations. + (__popcnt64) [_MSC_VER && !_M_X64]: Remove function. + (count_one_bits): Use stdc_count_ones_ui. + (count_one_bits_l): Use stdc_count_ones_ul. + (count_one_bits_ll): stdc_count_ones_ull. + * lib/count-one-bits.c (popcount_support) [_MSC_VER]: Remove variable. + * modules/count-one-bits (Depends-on): Add stdc_count_ones. + 2024-12-17 Bruno Haible <br...@clisp.org> crc-x86_64: Tweaks. diff --git a/lib/count-one-bits.c b/lib/count-one-bits.c index 54b8708802..e6e415bf8c 100644 --- a/lib/count-one-bits.c +++ b/lib/count-one-bits.c @@ -20,6 +20,3 @@ #define COUNT_ONE_BITS_INLINE _GL_EXTERN_INLINE #include "count-one-bits.h" -#if 1500 <= _MSC_VER && (defined _M_IX86 || defined _M_X64) -int popcount_support = -1; -#endif diff --git a/lib/count-one-bits.h b/lib/count-one-bits.h index 24bf8cc232..eddcf42f77 100644 --- a/lib/count-one-bits.h +++ b/lib/count-one-bits.h @@ -24,8 +24,7 @@ #error "Please include config.h first." #endif -#include <limits.h> -#include <stdlib.h> +#include <stdbit.h> _GL_INLINE_HEADER_BEGIN #ifndef COUNT_ONE_BITS_INLINE @@ -36,128 +35,25 @@ _GL_INLINE_HEADER_BEGIN extern "C" { #endif -/* Assuming the GCC builtin is GCC_BUILTIN and the MSC builtin is MSC_BUILTIN, - expand to code that computes the number of 1-bits of the local - variable 'x' of type TYPE (an unsigned integer type) and return it - from the current function. */ -#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) \ - || (__clang_major__ >= 4) -# define COUNT_ONE_BITS(GCC_BUILTIN, MSC_BUILTIN, TYPE) \ - return GCC_BUILTIN (x) -#else - -/* Compute and return the number of 1-bits set in the least - significant 32 bits of X. */ -COUNT_ONE_BITS_INLINE int -count_one_bits_32 (unsigned int x) -{ - x = ((x & 0xaaaaaaaaU) >> 1) + (x & 0x55555555U); - x = ((x & 0xccccccccU) >> 2) + (x & 0x33333333U); - x = (x >> 16) + (x & 0xffff); - x = ((x & 0xf0f0) >> 4) + (x & 0x0f0f); - return (x >> 8) + (x & 0x00ff); -} - -/* Expand to code that computes the number of 1-bits of the local - variable 'x' of type TYPE (an unsigned integer type) and return it - from the current function. */ -# define COUNT_ONE_BITS_GENERIC(TYPE) \ - do \ - { \ - int count = 0; \ - int bits; \ - for (bits = 0; bits < sizeof (TYPE) * CHAR_BIT; bits += 32) \ - { \ - count += count_one_bits_32 (x); \ - x = x >> 31 >> 1; \ - } \ - return count; \ - } \ - while (0) - -# if 1500 <= _MSC_VER && (defined _M_IX86 || defined _M_X64) - -/* While gcc falls back to its own generic code if the machine - on which it's running doesn't support popcount, with Microsoft's - compiler we need to detect and fallback ourselves. */ - -# if 0 -# include <intrin.h> -# else - /* Don't pollute the namespace with too many MSVC intrinsics. */ -extern void __cpuid (int[4], int); -# pragma intrinsic (__cpuid) -extern unsigned int __popcnt (unsigned int); -# pragma intrinsic (__popcnt) -# if defined _M_X64 -extern unsigned long long __popcnt64 (unsigned long long); -# pragma intrinsic (__popcnt64) -# endif -# endif - -# if !defined _M_X64 -static inline __popcnt64 (unsigned long long x) -{ - return __popcnt ((unsigned int) (x >> 32)) + __popcnt ((unsigned int) x); -} -# endif - -/* Return nonzero if popcount is supported. */ - -/* 1 if supported, 0 if not supported, -1 if unknown. */ -extern int popcount_support; - -COUNT_ONE_BITS_INLINE int -popcount_supported (void) -{ - if (popcount_support < 0) - { - /* Do as described in - <https://docs.microsoft.com/en-us/cpp/intrinsics/popcnt16-popcnt-popcnt64> */ - int cpu_info[4]; - __cpuid (cpu_info, 1); - popcount_support = (cpu_info[2] >> 23) & 1; - } - return popcount_support; -} - -# define COUNT_ONE_BITS(GCC_BUILTIN, MSC_BUILTIN, TYPE) \ - do \ - { \ - if (popcount_supported ()) \ - return MSC_BUILTIN (x); \ - else \ - COUNT_ONE_BITS_GENERIC (TYPE); \ - } \ - while (0) - -# else - -# define COUNT_ONE_BITS(GCC_BUILTIN, MSC_BUILTIN, TYPE) \ - COUNT_ONE_BITS_GENERIC (TYPE) - -# endif -#endif - /* Compute and return the number of 1-bits set in X. */ COUNT_ONE_BITS_INLINE int count_one_bits (unsigned int x) { - COUNT_ONE_BITS (__builtin_popcount, __popcnt, unsigned int); + return stdc_count_ones_ui (x); } /* Compute and return the number of 1-bits set in X. */ COUNT_ONE_BITS_INLINE int count_one_bits_l (unsigned long int x) { - COUNT_ONE_BITS (__builtin_popcountl, __popcnt, unsigned long int); + return stdc_count_ones_ul (x); } /* Compute and return the number of 1-bits set in X. */ COUNT_ONE_BITS_INLINE int count_one_bits_ll (unsigned long long int x) { - COUNT_ONE_BITS (__builtin_popcountll, __popcnt64, unsigned long long int); + return stdc_count_ones_ull (x); } #ifdef __cplusplus diff --git a/modules/count-one-bits b/modules/count-one-bits index ddceacda4b..4354e07cd4 100644 --- a/modules/count-one-bits +++ b/modules/count-one-bits @@ -7,6 +7,7 @@ lib/count-one-bits.h Depends-on: extern-inline +stdc_count_ones configure.ac: -- 2.47.1