diff options
| author | Paul Eggert | 2024-05-12 14:22:58 -0700 |
|---|---|---|
| committer | Paul Eggert | 2024-05-18 10:23:51 -0700 |
| commit | 88b0bb4db9aaecff8b01e81726b911fa5d02b2fb (patch) | |
| tree | 8ac3e75bba0a9082a94e7c3a03cd8b590f07a97d | |
| parent | 08550d058f028e0819ba6a72e9a53c0bc789257e (diff) | |
| download | emacs-88b0bb4db9aaecff8b01e81726b911fa5d02b2fb.tar.gz emacs-88b0bb4db9aaecff8b01e81726b911fa5d02b2fb.zip | |
Prefer stdbit.h to count-one-bits.h etc
C23's <stdbit.h> in the long run should be better supported than
Gnulib's count-one-bits.h and similar headers, so switch to the
C23 primitives, with a Gnulib fallback for platforms lacking C23.
* admin/merge-gnulib (GNULIB_MODULES): Remove count-leading-zeros,
count-one-bits, count-trailing-zeros. Add stdc_bit_width,
stdc_count_ones, stdc_trailing_zeros.
* lib/count-leading-zeros.c, lib/count-leading-zeros.h:
* lib/count-one-bits.c, lib/count-one-bits.h:
* lib/count-trailing-zeros.c, lib/count-trailing-zeros.h: Remove.
* lib/stdbit.c, lib/stdbit.in.h, lib/stdc_bit_width.c:
* lib/stdc_count_ones.c, lib/stdc_leading_zeros.c:
* lib/stdc_trailing_zeros.c, m4/stdbit_h.m4:
New files, copied from Gnulib.
* lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
* src/data.c: Do not include count-one-bits.h, count-trailing-zeros.h.
Instead, rely on lisp.h including stdbit.h.
(Flogcount, Fbool_vector_count_population)
(Fbool_vector_count_consecutive): Use stdbit.h macros instead of
count-one-bits.h and count-trailing-zeros.h macros.
(shift_right_ull, count_one_bits_word, pre_value)
(count_trailing_zero_bits): Remove; no longer needed.
* src/lisp.h: Include stdbit.h instead of count-leading-zeros.h.
(elogb): Use stdbit.h macro instead of count-leading-zeros.h macro.
| -rw-r--r-- | INSTALL.REPO | 2 | ||||
| -rwxr-xr-x | admin/merge-gnulib | 5 | ||||
| -rw-r--r-- | lib/count-leading-zeros.h | 140 | ||||
| -rw-r--r-- | lib/count-one-bits.h | 169 | ||||
| -rw-r--r-- | lib/count-trailing-zeros.h | 130 | ||||
| -rw-r--r-- | lib/gnulib.mk.in | 133 | ||||
| -rw-r--r-- | lib/stdbit.c | 23 | ||||
| -rw-r--r-- | lib/stdbit.in.h | 1077 | ||||
| -rw-r--r-- | lib/stdc_bit_width.c (renamed from lib/count-trailing-zeros.c) | 9 | ||||
| -rw-r--r-- | lib/stdc_count_ones.c (renamed from lib/count-one-bits.c) | 11 | ||||
| -rw-r--r-- | lib/stdc_leading_zeros.c (renamed from lib/count-leading-zeros.c) | 9 | ||||
| -rw-r--r-- | lib/stdc_trailing_zeros.c | 20 | ||||
| -rw-r--r-- | m4/gnulib-comp.m4 | 46 | ||||
| -rw-r--r-- | m4/stdbit_h.m4 | 37 | ||||
| -rw-r--r-- | src/data.c | 95 | ||||
| -rw-r--r-- | src/lisp.h | 7 |
16 files changed, 1320 insertions, 593 deletions
diff --git a/INSTALL.REPO b/INSTALL.REPO index 77d8153a5a8..46ac4440aee 100644 --- a/INSTALL.REPO +++ b/INSTALL.REPO | |||
| @@ -80,7 +80,7 @@ handle. The most thorough cleaning can be achieved by 'git clean -fdx' | |||
| 80 | which will leave you with only files from the git repository. Here | 80 | which will leave you with only files from the git repository. Here |
| 81 | are some faster methods for a couple of particular error cases: | 81 | are some faster methods for a couple of particular error cases: |
| 82 | 82 | ||
| 83 | /usr/bin/m4:aclocal.m4:9: cannot open `m4/count-leading-zeros.m4': No such file or directory | 83 | /usr/bin/m4:aclocal.m4:9: cannot open `m4/stdbit_h.m4': No such file or directory |
| 84 | 84 | ||
| 85 | This can be fixed with 'rm aclocal.m4'. | 85 | This can be fixed with 'rm aclocal.m4'. |
| 86 | 86 | ||
diff --git a/admin/merge-gnulib b/admin/merge-gnulib index c4daaded015..65e098c7123 100755 --- a/admin/merge-gnulib +++ b/admin/merge-gnulib | |||
| @@ -29,7 +29,6 @@ GNULIB_MODULES=' | |||
| 29 | alignasof alloca-opt binary-io boot-time byteswap c-ctype c-strcase | 29 | alignasof alloca-opt binary-io boot-time byteswap c-ctype c-strcase |
| 30 | canonicalize-lgpl | 30 | canonicalize-lgpl |
| 31 | careadlinkat close-stream copy-file-range | 31 | careadlinkat close-stream copy-file-range |
| 32 | count-leading-zeros count-one-bits count-trailing-zeros | ||
| 33 | crypto/md5 crypto/md5-buffer | 32 | crypto/md5 crypto/md5-buffer |
| 34 | crypto/sha1-buffer crypto/sha256-buffer crypto/sha512-buffer | 33 | crypto/sha1-buffer crypto/sha256-buffer crypto/sha512-buffer |
| 35 | d-type diffseq double-slash-root dtoastr dtotimespec dup2 | 34 | d-type diffseq double-slash-root dtoastr dtotimespec dup2 |
| @@ -44,7 +43,9 @@ GNULIB_MODULES=' | |||
| 44 | nanosleep nproc nstrftime | 43 | nanosleep nproc nstrftime |
| 45 | pathmax pipe2 pselect pthread_sigmask | 44 | pathmax pipe2 pselect pthread_sigmask |
| 46 | qcopy-acl readlink readlinkat regex | 45 | qcopy-acl readlink readlinkat regex |
| 47 | sig2str sigdescr_np socklen stat-time std-gnu11 stdbool stdckdint stddef stdio | 46 | sig2str sigdescr_np socklen stat-time std-gnu11 stdbool |
| 47 | stdc_bit_width stdc_count_ones stdc_trailing_zeros | ||
| 48 | stdckdint stddef stdio | ||
| 48 | stpcpy strnlen strnlen strtoimax symlink sys_stat sys_time | 49 | stpcpy strnlen strnlen strtoimax symlink sys_stat sys_time |
| 49 | tempname time-h time_r time_rz timegm timer-time timespec-add timespec-sub | 50 | tempname time-h time_r time_rz timegm timer-time timespec-add timespec-sub |
| 50 | update-copyright unlocked-io utimensat | 51 | update-copyright unlocked-io utimensat |
diff --git a/lib/count-leading-zeros.h b/lib/count-leading-zeros.h deleted file mode 100644 index a4b68c21064..00000000000 --- a/lib/count-leading-zeros.h +++ /dev/null | |||
| @@ -1,140 +0,0 @@ | |||
| 1 | /* count-leading-zeros.h -- counts the number of leading 0 bits in a word. | ||
| 2 | Copyright (C) 2012-2024 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU Lesser General Public License as | ||
| 6 | published by the Free Software Foundation; either version 2.1 of the | ||
| 7 | License, or (at your option) any later version. | ||
| 8 | |||
| 9 | This file is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU Lesser General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU Lesser General Public License | ||
| 15 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | /* Written by Eric Blake. */ | ||
| 18 | |||
| 19 | #ifndef COUNT_LEADING_ZEROS_H | ||
| 20 | #define COUNT_LEADING_ZEROS_H 1 | ||
| 21 | |||
| 22 | /* This file uses _GL_INLINE_HEADER_BEGIN, _GL_INLINE. */ | ||
| 23 | #if !_GL_CONFIG_H_INCLUDED | ||
| 24 | #error "Please include config.h first." | ||
| 25 | #endif | ||
| 26 | |||
| 27 | #include <limits.h> | ||
| 28 | #include <stdlib.h> | ||
| 29 | |||
| 30 | _GL_INLINE_HEADER_BEGIN | ||
| 31 | #ifndef COUNT_LEADING_ZEROS_INLINE | ||
| 32 | # define COUNT_LEADING_ZEROS_INLINE _GL_INLINE | ||
| 33 | #endif | ||
| 34 | |||
| 35 | #ifdef __cplusplus | ||
| 36 | extern "C" { | ||
| 37 | #endif | ||
| 38 | |||
| 39 | /* Assuming the GCC builtin is BUILTIN and the MSC builtin is MSC_BUILTIN, | ||
| 40 | expand to code that computes the number of leading zeros of the local | ||
| 41 | variable 'x' of type TYPE (an unsigned integer type) and return it | ||
| 42 | from the current function. */ | ||
| 43 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) \ | ||
| 44 | || (__clang_major__ >= 4) | ||
| 45 | # define COUNT_LEADING_ZEROS(BUILTIN, MSC_BUILTIN, TYPE) \ | ||
| 46 | return x ? BUILTIN (x) : CHAR_BIT * sizeof x; | ||
| 47 | #elif _MSC_VER | ||
| 48 | extern unsigned char _BitScanReverse (unsigned long *, unsigned long); | ||
| 49 | # pragma intrinsic (_BitScanReverse) | ||
| 50 | # if defined _M_X64 | ||
| 51 | extern unsigned char _BitScanReverse64 (unsigned long *, unsigned long long); | ||
| 52 | # pragma intrinsic (_BitScanReverse64) | ||
| 53 | # endif | ||
| 54 | # define COUNT_LEADING_ZEROS(BUILTIN, MSC_BUILTIN, TYPE) \ | ||
| 55 | do \ | ||
| 56 | { \ | ||
| 57 | unsigned long result; \ | ||
| 58 | if (MSC_BUILTIN (&result, x)) \ | ||
| 59 | return CHAR_BIT * sizeof x - 1 - result; \ | ||
| 60 | return CHAR_BIT * sizeof x; \ | ||
| 61 | } \ | ||
| 62 | while (0) | ||
| 63 | #else | ||
| 64 | # define COUNT_LEADING_ZEROS(BUILTIN, MSC_BUILTIN, TYPE) \ | ||
| 65 | do \ | ||
| 66 | { \ | ||
| 67 | int count; \ | ||
| 68 | unsigned int leading_32; \ | ||
| 69 | if (! x) \ | ||
| 70 | return CHAR_BIT * sizeof x; \ | ||
| 71 | for (count = 0; \ | ||
| 72 | (leading_32 = ((x >> (sizeof (TYPE) * CHAR_BIT - 32)) \ | ||
| 73 | & 0xffffffffU), \ | ||
| 74 | count < CHAR_BIT * sizeof x - 32 && !leading_32); \ | ||
| 75 | count += 32) \ | ||
| 76 | x = x << 31 << 1; \ | ||
| 77 | return count + count_leading_zeros_32 (leading_32); \ | ||
| 78 | } \ | ||
| 79 | while (0) | ||
| 80 | |||
| 81 | /* Compute and return the number of leading zeros in X, | ||
| 82 | where 0 < X < 2**32. */ | ||
| 83 | COUNT_LEADING_ZEROS_INLINE int | ||
| 84 | count_leading_zeros_32 (unsigned int x) | ||
| 85 | { | ||
| 86 | /* <https://github.com/gibsjose/BitHacks> | ||
| 87 | <https://www.fit.vutbr.cz/~ibarina/pub/bithacks.pdf> */ | ||
| 88 | static const char de_Bruijn_lookup[32] = { | ||
| 89 | 31, 22, 30, 21, 18, 10, 29, 2, 20, 17, 15, 13, 9, 6, 28, 1, | ||
| 90 | 23, 19, 11, 3, 16, 14, 7, 24, 12, 4, 8, 25, 5, 26, 27, 0 | ||
| 91 | }; | ||
| 92 | |||
| 93 | x |= x >> 1; | ||
| 94 | x |= x >> 2; | ||
| 95 | x |= x >> 4; | ||
| 96 | x |= x >> 8; | ||
| 97 | x |= x >> 16; | ||
| 98 | return de_Bruijn_lookup[((x * 0x07c4acddU) & 0xffffffffU) >> 27]; | ||
| 99 | } | ||
| 100 | #endif | ||
| 101 | |||
| 102 | /* Compute and return the number of leading zeros in X. */ | ||
| 103 | COUNT_LEADING_ZEROS_INLINE int | ||
| 104 | count_leading_zeros (unsigned int x) | ||
| 105 | { | ||
| 106 | COUNT_LEADING_ZEROS (__builtin_clz, _BitScanReverse, unsigned int); | ||
| 107 | } | ||
| 108 | |||
| 109 | /* Compute and return the number of leading zeros in X. */ | ||
| 110 | COUNT_LEADING_ZEROS_INLINE int | ||
| 111 | count_leading_zeros_l (unsigned long int x) | ||
| 112 | { | ||
| 113 | COUNT_LEADING_ZEROS (__builtin_clzl, _BitScanReverse, unsigned long int); | ||
| 114 | } | ||
| 115 | |||
| 116 | /* Compute and return the number of leading zeros in X. */ | ||
| 117 | COUNT_LEADING_ZEROS_INLINE int | ||
| 118 | count_leading_zeros_ll (unsigned long long int x) | ||
| 119 | { | ||
| 120 | #if (defined _MSC_VER && !defined __clang__) && !defined _M_X64 | ||
| 121 | /* 32-bit MSVC does not have _BitScanReverse64, only _BitScanReverse. */ | ||
| 122 | unsigned long result; | ||
| 123 | if (_BitScanReverse (&result, (unsigned long) (x >> 32))) | ||
| 124 | return CHAR_BIT * sizeof x - 1 - 32 - result; | ||
| 125 | if (_BitScanReverse (&result, (unsigned long) x)) | ||
| 126 | return CHAR_BIT * sizeof x - 1 - result; | ||
| 127 | return CHAR_BIT * sizeof x; | ||
| 128 | #else | ||
| 129 | COUNT_LEADING_ZEROS (__builtin_clzll, _BitScanReverse64, | ||
| 130 | unsigned long long int); | ||
| 131 | #endif | ||
| 132 | } | ||
| 133 | |||
| 134 | #ifdef __cplusplus | ||
| 135 | } | ||
| 136 | #endif | ||
| 137 | |||
| 138 | _GL_INLINE_HEADER_END | ||
| 139 | |||
| 140 | #endif /* COUNT_LEADING_ZEROS_H */ | ||
diff --git a/lib/count-one-bits.h b/lib/count-one-bits.h deleted file mode 100644 index 24bf8cc2327..00000000000 --- a/lib/count-one-bits.h +++ /dev/null | |||
| @@ -1,169 +0,0 @@ | |||
| 1 | /* count-one-bits.h -- counts the number of 1-bits in a word. | ||
| 2 | Copyright (C) 2007-2024 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU Lesser General Public License as | ||
| 6 | published by the Free Software Foundation; either version 2.1 of the | ||
| 7 | License, or (at your option) any later version. | ||
| 8 | |||
| 9 | This file is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU Lesser General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU Lesser General Public License | ||
| 15 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | /* Written by Ben Pfaff. */ | ||
| 18 | |||
| 19 | #ifndef COUNT_ONE_BITS_H | ||
| 20 | #define COUNT_ONE_BITS_H 1 | ||
| 21 | |||
| 22 | /* This file uses _GL_INLINE_HEADER_BEGIN, _GL_INLINE. */ | ||
| 23 | #if !_GL_CONFIG_H_INCLUDED | ||
| 24 | #error "Please include config.h first." | ||
| 25 | #endif | ||
| 26 | |||
| 27 | #include <limits.h> | ||
| 28 | #include <stdlib.h> | ||
| 29 | |||
| 30 | _GL_INLINE_HEADER_BEGIN | ||
| 31 | #ifndef COUNT_ONE_BITS_INLINE | ||
| 32 | # define COUNT_ONE_BITS_INLINE _GL_INLINE | ||
| 33 | #endif | ||
| 34 | |||
| 35 | #ifdef __cplusplus | ||
| 36 | extern "C" { | ||
| 37 | #endif | ||
| 38 | |||
| 39 | /* Assuming the GCC builtin is GCC_BUILTIN and the MSC builtin is MSC_BUILTIN, | ||
| 40 | expand to code that computes the number of 1-bits of the local | ||
| 41 | variable 'x' of type TYPE (an unsigned integer type) and return it | ||
| 42 | from the current function. */ | ||
| 43 | #if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) \ | ||
| 44 | || (__clang_major__ >= 4) | ||
| 45 | # define COUNT_ONE_BITS(GCC_BUILTIN, MSC_BUILTIN, TYPE) \ | ||
| 46 | return GCC_BUILTIN (x) | ||
| 47 | #else | ||
| 48 | |||
| 49 | /* Compute and return the number of 1-bits set in the least | ||
| 50 | significant 32 bits of X. */ | ||
| 51 | COUNT_ONE_BITS_INLINE int | ||
| 52 | count_one_bits_32 (unsigned int x) | ||
| 53 | { | ||
| 54 | x = ((x & 0xaaaaaaaaU) >> 1) + (x & 0x55555555U); | ||
| 55 | x = ((x & 0xccccccccU) >> 2) + (x & 0x33333333U); | ||
| 56 | x = (x >> 16) + (x & 0xffff); | ||
| 57 | x = ((x & 0xf0f0) >> 4) + (x & 0x0f0f); | ||
| 58 | return (x >> 8) + (x & 0x00ff); | ||
| 59 | } | ||
| 60 | |||
| 61 | /* Expand to code that computes the number of 1-bits of the local | ||
| 62 | variable 'x' of type TYPE (an unsigned integer type) and return it | ||
| 63 | from the current function. */ | ||
| 64 | # define COUNT_ONE_BITS_GENERIC(TYPE) \ | ||
| 65 | do \ | ||
| 66 | { \ | ||
| 67 | int count = 0; \ | ||
| 68 | int bits; \ | ||
| 69 | for (bits = 0; bits < sizeof (TYPE) * CHAR_BIT; bits += 32) \ | ||
| 70 | { \ | ||
| 71 | count += count_one_bits_32 (x); \ | ||
| 72 | x = x >> 31 >> 1; \ | ||
| 73 | } \ | ||
| 74 | return count; \ | ||
| 75 | } \ | ||
| 76 | while (0) | ||
| 77 | |||
| 78 | # if 1500 <= _MSC_VER && (defined _M_IX86 || defined _M_X64) | ||
| 79 | |||
| 80 | /* While gcc falls back to its own generic code if the machine | ||
| 81 | on which it's running doesn't support popcount, with Microsoft's | ||
| 82 | compiler we need to detect and fallback ourselves. */ | ||
| 83 | |||
| 84 | # if 0 | ||
| 85 | # include <intrin.h> | ||
| 86 | # else | ||
| 87 | /* Don't pollute the namespace with too many MSVC intrinsics. */ | ||
| 88 | extern void __cpuid (int[4], int); | ||
| 89 | # pragma intrinsic (__cpuid) | ||
| 90 | extern unsigned int __popcnt (unsigned int); | ||
| 91 | # pragma intrinsic (__popcnt) | ||
| 92 | # if defined _M_X64 | ||
| 93 | extern unsigned long long __popcnt64 (unsigned long long); | ||
| 94 | # pragma intrinsic (__popcnt64) | ||
| 95 | # endif | ||
| 96 | # endif | ||
| 97 | |||
| 98 | # if !defined _M_X64 | ||
| 99 | static inline __popcnt64 (unsigned long long x) | ||
| 100 | { | ||
| 101 | return __popcnt ((unsigned int) (x >> 32)) + __popcnt ((unsigned int) x); | ||
| 102 | } | ||
| 103 | # endif | ||
| 104 | |||
| 105 | /* Return nonzero if popcount is supported. */ | ||
| 106 | |||
| 107 | /* 1 if supported, 0 if not supported, -1 if unknown. */ | ||
| 108 | extern int popcount_support; | ||
| 109 | |||
| 110 | COUNT_ONE_BITS_INLINE int | ||
| 111 | popcount_supported (void) | ||
| 112 | { | ||
| 113 | if (popcount_support < 0) | ||
| 114 | { | ||
| 115 | /* Do as described in | ||
| 116 | <https://docs.microsoft.com/en-us/cpp/intrinsics/popcnt16-popcnt-popcnt64> */ | ||
| 117 | int cpu_info[4]; | ||
| 118 | __cpuid (cpu_info, 1); | ||
| 119 | popcount_support = (cpu_info[2] >> 23) & 1; | ||
| 120 | } | ||
| 121 | return popcount_support; | ||
| 122 | } | ||
| 123 | |||
| 124 | # define COUNT_ONE_BITS(GCC_BUILTIN, MSC_BUILTIN, TYPE) \ | ||
| 125 | do \ | ||
| 126 | { \ | ||
| 127 | if (popcount_supported ()) \ | ||
| 128 | return MSC_BUILTIN (x); \ | ||
| 129 | else \ | ||
| 130 | COUNT_ONE_BITS_GENERIC (TYPE); \ | ||
| 131 | } \ | ||
| 132 | while (0) | ||
| 133 | |||
| 134 | # else | ||
| 135 | |||
| 136 | # define COUNT_ONE_BITS(GCC_BUILTIN, MSC_BUILTIN, TYPE) \ | ||
| 137 | COUNT_ONE_BITS_GENERIC (TYPE) | ||
| 138 | |||
| 139 | # endif | ||
| 140 | #endif | ||
| 141 | |||
| 142 | /* Compute and return the number of 1-bits set in X. */ | ||
| 143 | COUNT_ONE_BITS_INLINE int | ||
| 144 | count_one_bits (unsigned int x) | ||
| 145 | { | ||
| 146 | COUNT_ONE_BITS (__builtin_popcount, __popcnt, unsigned int); | ||
| 147 | } | ||
| 148 | |||
| 149 | /* Compute and return the number of 1-bits set in X. */ | ||
| 150 | COUNT_ONE_BITS_INLINE int | ||
| 151 | count_one_bits_l (unsigned long int x) | ||
| 152 | { | ||
| 153 | COUNT_ONE_BITS (__builtin_popcountl, __popcnt, unsigned long int); | ||
| 154 | } | ||
| 155 | |||
| 156 | /* Compute and return the number of 1-bits set in X. */ | ||
| 157 | COUNT_ONE_BITS_INLINE int | ||
| 158 | count_one_bits_ll (unsigned long long int x) | ||
| 159 | { | ||
| 160 | COUNT_ONE_BITS (__builtin_popcountll, __popcnt64, unsigned long long int); | ||
| 161 | } | ||
| 162 | |||
| 163 | #ifdef __cplusplus | ||
| 164 | } | ||
| 165 | #endif | ||
| 166 | |||
| 167 | _GL_INLINE_HEADER_END | ||
| 168 | |||
| 169 | #endif /* COUNT_ONE_BITS_H */ | ||
diff --git a/lib/count-trailing-zeros.h b/lib/count-trailing-zeros.h deleted file mode 100644 index 82de8731ec1..00000000000 --- a/lib/count-trailing-zeros.h +++ /dev/null | |||
| @@ -1,130 +0,0 @@ | |||
| 1 | /* count-trailing-zeros.h -- counts the number of trailing 0 bits in a word. | ||
| 2 | Copyright 2013-2024 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU Lesser General Public License as | ||
| 6 | published by the Free Software Foundation; either version 2.1 of the | ||
| 7 | License, or (at your option) any later version. | ||
| 8 | |||
| 9 | This file is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU Lesser General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU Lesser General Public License | ||
| 15 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | /* Written by Paul Eggert. */ | ||
| 18 | |||
| 19 | #ifndef COUNT_TRAILING_ZEROS_H | ||
| 20 | #define COUNT_TRAILING_ZEROS_H 1 | ||
| 21 | |||
| 22 | /* This file uses _GL_INLINE_HEADER_BEGIN, _GL_INLINE. */ | ||
| 23 | #if !_GL_CONFIG_H_INCLUDED | ||
| 24 | #error "Please include config.h first." | ||
| 25 | #endif | ||
| 26 | |||
| 27 | #include <limits.h> | ||
| 28 | #include <stdlib.h> | ||
| 29 | |||
| 30 | _GL_INLINE_HEADER_BEGIN | ||
| 31 | #ifndef COUNT_TRAILING_ZEROS_INLINE | ||
| 32 | # define COUNT_TRAILING_ZEROS_INLINE _GL_INLINE | ||
| 33 | #endif | ||
| 34 | |||
| 35 | #ifdef __cplusplus | ||
| 36 | extern "C" { | ||
| 37 | #endif | ||
| 38 | |||
| 39 | /* Assuming the GCC builtin is BUILTIN and the MSC builtin is MSC_BUILTIN, | ||
| 40 | expand to code that computes the number of trailing zeros of the local | ||
| 41 | variable 'x' of type TYPE (an unsigned integer type) and return it | ||
| 42 | from the current function. */ | ||
| 43 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) \ | ||
| 44 | || (__clang_major__ >= 4) | ||
| 45 | # define COUNT_TRAILING_ZEROS(BUILTIN, MSC_BUILTIN, TYPE) \ | ||
| 46 | return x ? BUILTIN (x) : CHAR_BIT * sizeof x; | ||
| 47 | #elif _MSC_VER | ||
| 48 | extern unsigned char _BitScanForward (unsigned long *, unsigned long); | ||
| 49 | # pragma intrinsic (_BitScanForward) | ||
| 50 | # if defined _M_X64 | ||
| 51 | extern unsigned char _BitScanForward64 (unsigned long *, unsigned long long); | ||
| 52 | # pragma intrinsic (_BitScanForward64) | ||
| 53 | # endif | ||
| 54 | # define COUNT_TRAILING_ZEROS(BUILTIN, MSC_BUILTIN, TYPE) \ | ||
| 55 | do \ | ||
| 56 | { \ | ||
| 57 | unsigned long result; \ | ||
| 58 | return MSC_BUILTIN (&result, x) ? result : CHAR_BIT * sizeof x; \ | ||
| 59 | } \ | ||
| 60 | while (0) | ||
| 61 | #else | ||
| 62 | # define COUNT_TRAILING_ZEROS(BUILTIN, MSC_BUILTIN, TYPE) \ | ||
| 63 | do \ | ||
| 64 | { \ | ||
| 65 | int count = 0; \ | ||
| 66 | if (! x) \ | ||
| 67 | return CHAR_BIT * sizeof x; \ | ||
| 68 | for (count = 0; \ | ||
| 69 | (count < CHAR_BIT * sizeof x - 32 \ | ||
| 70 | && ! (x & 0xffffffffU)); \ | ||
| 71 | count += 32) \ | ||
| 72 | x = x >> 31 >> 1; \ | ||
| 73 | return count + count_trailing_zeros_32 (x); \ | ||
| 74 | } \ | ||
| 75 | while (0) | ||
| 76 | |||
| 77 | /* Compute and return the number of trailing zeros in the least | ||
| 78 | significant 32 bits of X. One of these bits must be nonzero. */ | ||
| 79 | COUNT_TRAILING_ZEROS_INLINE int | ||
| 80 | count_trailing_zeros_32 (unsigned int x) | ||
| 81 | { | ||
| 82 | /* <https://github.com/gibsjose/BitHacks> | ||
| 83 | <https://www.fit.vutbr.cz/~ibarina/pub/bithacks.pdf> */ | ||
| 84 | static const char de_Bruijn_lookup[32] = { | ||
| 85 | 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, | ||
| 86 | 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 | ||
| 87 | }; | ||
| 88 | return de_Bruijn_lookup[(((x & -x) * 0x077cb531U) & 0xffffffffU) >> 27]; | ||
| 89 | } | ||
| 90 | #endif | ||
| 91 | |||
| 92 | /* Compute and return the number of trailing zeros in X. */ | ||
| 93 | COUNT_TRAILING_ZEROS_INLINE int | ||
| 94 | count_trailing_zeros (unsigned int x) | ||
| 95 | { | ||
| 96 | COUNT_TRAILING_ZEROS (__builtin_ctz, _BitScanForward, unsigned int); | ||
| 97 | } | ||
| 98 | |||
| 99 | /* Compute and return the number of trailing zeros in X. */ | ||
| 100 | COUNT_TRAILING_ZEROS_INLINE int | ||
| 101 | count_trailing_zeros_l (unsigned long int x) | ||
| 102 | { | ||
| 103 | COUNT_TRAILING_ZEROS (__builtin_ctzl, _BitScanForward, unsigned long int); | ||
| 104 | } | ||
| 105 | |||
| 106 | /* Compute and return the number of trailing zeros in X. */ | ||
| 107 | COUNT_TRAILING_ZEROS_INLINE int | ||
| 108 | count_trailing_zeros_ll (unsigned long long int x) | ||
| 109 | { | ||
| 110 | #if (defined _MSC_VER && !defined __clang__) && !defined _M_X64 | ||
| 111 | /* 32-bit MSVC does not have _BitScanForward64, only _BitScanForward. */ | ||
| 112 | unsigned long result; | ||
| 113 | if (_BitScanForward (&result, (unsigned long) x)) | ||
| 114 | return result; | ||
| 115 | if (_BitScanForward (&result, (unsigned long) (x >> 32))) | ||
| 116 | return result + 32; | ||
| 117 | return CHAR_BIT * sizeof x; | ||
| 118 | #else | ||
| 119 | COUNT_TRAILING_ZEROS (__builtin_ctzll, _BitScanForward64, | ||
| 120 | unsigned long long int); | ||
| 121 | #endif | ||
| 122 | } | ||
| 123 | |||
| 124 | #ifdef __cplusplus | ||
| 125 | } | ||
| 126 | #endif | ||
| 127 | |||
| 128 | _GL_INLINE_HEADER_END | ||
| 129 | |||
| 130 | #endif | ||
diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in index d03e193b63c..358d58d5015 100644 --- a/lib/gnulib.mk.in +++ b/lib/gnulib.mk.in | |||
| @@ -86,9 +86,6 @@ | |||
| 86 | # careadlinkat \ | 86 | # careadlinkat \ |
| 87 | # close-stream \ | 87 | # close-stream \ |
| 88 | # copy-file-range \ | 88 | # copy-file-range \ |
| 89 | # count-leading-zeros \ | ||
| 90 | # count-one-bits \ | ||
| 91 | # count-trailing-zeros \ | ||
| 92 | # crypto/md5 \ | 89 | # crypto/md5 \ |
| 93 | # crypto/md5-buffer \ | 90 | # crypto/md5-buffer \ |
| 94 | # crypto/sha1-buffer \ | 91 | # crypto/sha1-buffer \ |
| @@ -156,6 +153,9 @@ | |||
| 156 | # stat-time \ | 153 | # stat-time \ |
| 157 | # std-gnu11 \ | 154 | # std-gnu11 \ |
| 158 | # stdbool \ | 155 | # stdbool \ |
| 156 | # stdc_bit_width \ | ||
| 157 | # stdc_count_ones \ | ||
| 158 | # stdc_trailing_zeros \ | ||
| 159 | # stdckdint \ | 159 | # stdckdint \ |
| 160 | # stddef \ | 160 | # stddef \ |
| 161 | # stdio \ | 161 | # stdio \ |
| @@ -358,6 +358,7 @@ GL_GENERATE_GMP_H_CONDITION = @GL_GENERATE_GMP_H_CONDITION@ | |||
| 358 | GL_GENERATE_IEEE754_H_CONDITION = @GL_GENERATE_IEEE754_H_CONDITION@ | 358 | GL_GENERATE_IEEE754_H_CONDITION = @GL_GENERATE_IEEE754_H_CONDITION@ |
| 359 | GL_GENERATE_LIMITS_H_CONDITION = @GL_GENERATE_LIMITS_H_CONDITION@ | 359 | GL_GENERATE_LIMITS_H_CONDITION = @GL_GENERATE_LIMITS_H_CONDITION@ |
| 360 | GL_GENERATE_MINI_GMP_H_CONDITION = @GL_GENERATE_MINI_GMP_H_CONDITION@ | 360 | GL_GENERATE_MINI_GMP_H_CONDITION = @GL_GENERATE_MINI_GMP_H_CONDITION@ |
| 361 | GL_GENERATE_STDBIT_H_CONDITION = @GL_GENERATE_STDBIT_H_CONDITION@ | ||
| 361 | GL_GENERATE_STDCKDINT_H_CONDITION = @GL_GENERATE_STDCKDINT_H_CONDITION@ | 362 | GL_GENERATE_STDCKDINT_H_CONDITION = @GL_GENERATE_STDCKDINT_H_CONDITION@ |
| 362 | GL_GENERATE_STDDEF_H_CONDITION = @GL_GENERATE_STDDEF_H_CONDITION@ | 363 | GL_GENERATE_STDDEF_H_CONDITION = @GL_GENERATE_STDDEF_H_CONDITION@ |
| 363 | GL_GENERATE_STDINT_H_CONDITION = @GL_GENERATE_STDINT_H_CONDITION@ | 364 | GL_GENERATE_STDINT_H_CONDITION = @GL_GENERATE_STDINT_H_CONDITION@ |
| @@ -664,6 +665,20 @@ GL_GNULIB_VSPRINTF_POSIX = @GL_GNULIB_VSPRINTF_POSIX@ | |||
| 664 | GL_GNULIB_WCTOMB = @GL_GNULIB_WCTOMB@ | 665 | GL_GNULIB_WCTOMB = @GL_GNULIB_WCTOMB@ |
| 665 | GL_GNULIB_WRITE = @GL_GNULIB_WRITE@ | 666 | GL_GNULIB_WRITE = @GL_GNULIB_WRITE@ |
| 666 | GL_GNULIB__EXIT = @GL_GNULIB__EXIT@ | 667 | GL_GNULIB__EXIT = @GL_GNULIB__EXIT@ |
| 668 | GL_STDC_BIT_CEIL = @GL_STDC_BIT_CEIL@ | ||
| 669 | GL_STDC_BIT_FLOOR = @GL_STDC_BIT_FLOOR@ | ||
| 670 | GL_STDC_BIT_WIDTH = @GL_STDC_BIT_WIDTH@ | ||
| 671 | GL_STDC_COUNT_ONES = @GL_STDC_COUNT_ONES@ | ||
| 672 | GL_STDC_COUNT_ZEROS = @GL_STDC_COUNT_ZEROS@ | ||
| 673 | GL_STDC_FIRST_LEADING_ONE = @GL_STDC_FIRST_LEADING_ONE@ | ||
| 674 | GL_STDC_FIRST_LEADING_ZERO = @GL_STDC_FIRST_LEADING_ZERO@ | ||
| 675 | GL_STDC_FIRST_TRAILING_ONE = @GL_STDC_FIRST_TRAILING_ONE@ | ||
| 676 | GL_STDC_FIRST_TRAILING_ZERO = @GL_STDC_FIRST_TRAILING_ZERO@ | ||
| 677 | GL_STDC_HAS_SINGLE_BIT = @GL_STDC_HAS_SINGLE_BIT@ | ||
| 678 | GL_STDC_LEADING_ONES = @GL_STDC_LEADING_ONES@ | ||
| 679 | GL_STDC_LEADING_ZEROS = @GL_STDC_LEADING_ZEROS@ | ||
| 680 | GL_STDC_TRAILING_ONES = @GL_STDC_TRAILING_ONES@ | ||
| 681 | GL_STDC_TRAILING_ZEROS = @GL_STDC_TRAILING_ZEROS@ | ||
| 667 | GMALLOC_OBJ = @GMALLOC_OBJ@ | 682 | GMALLOC_OBJ = @GMALLOC_OBJ@ |
| 668 | GMP_H = @GMP_H@ | 683 | GMP_H = @GMP_H@ |
| 669 | GNULIBHEADERS_OVERRIDE_WINT_T = @GNULIBHEADERS_OVERRIDE_WINT_T@ | 684 | GNULIBHEADERS_OVERRIDE_WINT_T = @GNULIBHEADERS_OVERRIDE_WINT_T@ |
| @@ -1315,6 +1330,7 @@ SIZE_T_SUFFIX = @SIZE_T_SUFFIX@ | |||
| 1315 | SMALL_JA_DIC = @SMALL_JA_DIC@ | 1330 | SMALL_JA_DIC = @SMALL_JA_DIC@ |
| 1316 | SQLITE3_CFLAGS = @SQLITE3_CFLAGS@ | 1331 | SQLITE3_CFLAGS = @SQLITE3_CFLAGS@ |
| 1317 | SQLITE3_LIBS = @SQLITE3_LIBS@ | 1332 | SQLITE3_LIBS = @SQLITE3_LIBS@ |
| 1333 | STDBIT_H = @STDBIT_H@ | ||
| 1318 | STDCKDINT_H = @STDCKDINT_H@ | 1334 | STDCKDINT_H = @STDCKDINT_H@ |
| 1319 | STDDEF_H = @STDDEF_H@ | 1335 | STDDEF_H = @STDDEF_H@ |
| 1320 | STDDEF_NOT_IDEMPOTENT = @STDDEF_NOT_IDEMPOTENT@ | 1336 | STDDEF_NOT_IDEMPOTENT = @STDDEF_NOT_IDEMPOTENT@ |
| @@ -1444,6 +1460,7 @@ gl_GNULIB_ENABLED_open_CONDITION = @gl_GNULIB_ENABLED_open_CONDITION@ | |||
| 1444 | gl_GNULIB_ENABLED_rawmemchr_CONDITION = @gl_GNULIB_ENABLED_rawmemchr_CONDITION@ | 1460 | gl_GNULIB_ENABLED_rawmemchr_CONDITION = @gl_GNULIB_ENABLED_rawmemchr_CONDITION@ |
| 1445 | gl_GNULIB_ENABLED_strtoll_CONDITION = @gl_GNULIB_ENABLED_strtoll_CONDITION@ | 1461 | gl_GNULIB_ENABLED_strtoll_CONDITION = @gl_GNULIB_ENABLED_strtoll_CONDITION@ |
| 1446 | gl_GNULIB_ENABLED_utimens_CONDITION = @gl_GNULIB_ENABLED_utimens_CONDITION@ | 1462 | gl_GNULIB_ENABLED_utimens_CONDITION = @gl_GNULIB_ENABLED_utimens_CONDITION@ |
| 1463 | gl_GNULIB_ENABLED_verify_CONDITION = @gl_GNULIB_ENABLED_verify_CONDITION@ | ||
| 1447 | gl_LIBOBJDEPS = @gl_LIBOBJDEPS@ | 1464 | gl_LIBOBJDEPS = @gl_LIBOBJDEPS@ |
| 1448 | gl_LIBOBJS = @gl_LIBOBJS@ | 1465 | gl_LIBOBJS = @gl_LIBOBJS@ |
| 1449 | gl_LTLIBOBJS = @gl_LTLIBOBJS@ | 1466 | gl_LTLIBOBJS = @gl_LTLIBOBJS@ |
| @@ -1721,36 +1738,6 @@ endif | |||
| 1721 | endif | 1738 | endif |
| 1722 | ## end gnulib module copy-file-range | 1739 | ## end gnulib module copy-file-range |
| 1723 | 1740 | ||
| 1724 | ## begin gnulib module count-leading-zeros | ||
| 1725 | ifeq (,$(OMIT_GNULIB_MODULE_count-leading-zeros)) | ||
| 1726 | |||
| 1727 | libgnu_a_SOURCES += count-leading-zeros.c | ||
| 1728 | |||
| 1729 | EXTRA_DIST += count-leading-zeros.h | ||
| 1730 | |||
| 1731 | endif | ||
| 1732 | ## end gnulib module count-leading-zeros | ||
| 1733 | |||
| 1734 | ## begin gnulib module count-one-bits | ||
| 1735 | ifeq (,$(OMIT_GNULIB_MODULE_count-one-bits)) | ||
| 1736 | |||
| 1737 | libgnu_a_SOURCES += count-one-bits.c | ||
| 1738 | |||
| 1739 | EXTRA_DIST += count-one-bits.h | ||
| 1740 | |||
| 1741 | endif | ||
| 1742 | ## end gnulib module count-one-bits | ||
| 1743 | |||
| 1744 | ## begin gnulib module count-trailing-zeros | ||
| 1745 | ifeq (,$(OMIT_GNULIB_MODULE_count-trailing-zeros)) | ||
| 1746 | |||
| 1747 | libgnu_a_SOURCES += count-trailing-zeros.c | ||
| 1748 | |||
| 1749 | EXTRA_DIST += count-trailing-zeros.h | ||
| 1750 | |||
| 1751 | endif | ||
| 1752 | ## end gnulib module count-trailing-zeros | ||
| 1753 | |||
| 1754 | ## begin gnulib module crypto/md5 | 1741 | ## begin gnulib module crypto/md5 |
| 1755 | ifeq (,$(OMIT_GNULIB_MODULE_crypto/md5)) | 1742 | ifeq (,$(OMIT_GNULIB_MODULE_crypto/md5)) |
| 1756 | 1743 | ||
| @@ -3052,6 +3039,84 @@ EXTRA_DIST += stat-time.h | |||
| 3052 | endif | 3039 | endif |
| 3053 | ## end gnulib module stat-time | 3040 | ## end gnulib module stat-time |
| 3054 | 3041 | ||
| 3042 | ## begin gnulib module stdbit-h | ||
| 3043 | ifeq (,$(OMIT_GNULIB_MODULE_stdbit-h)) | ||
| 3044 | |||
| 3045 | BUILT_SOURCES += $(STDBIT_H) | ||
| 3046 | |||
| 3047 | # We need the following in order to create <stdbit.h> when the system | ||
| 3048 | # doesn't have one that works with the given compiler. | ||
| 3049 | ifneq (,$(GL_GENERATE_STDBIT_H_CONDITION)) | ||
| 3050 | stdbit.h: stdbit.in.h $(top_builddir)/config.status | ||
| 3051 | $(gl_V_at)$(SED_HEADER_STDOUT) \ | ||
| 3052 | -e 's/@''GL_STDC_LEADING_ZEROS''@/$(GL_STDC_LEADING_ZEROS)/g' \ | ||
| 3053 | -e 's/@''GL_STDC_LEADING_ONES''@/$(GL_STDC_LEADING_ONES)/g' \ | ||
| 3054 | -e 's/@''GL_STDC_TRAILING_ZEROS''@/$(GL_STDC_TRAILING_ZEROS)/g' \ | ||
| 3055 | -e 's/@''GL_STDC_TRAILING_ONES''@/$(GL_STDC_TRAILING_ONES)/g' \ | ||
| 3056 | -e 's/@''GL_STDC_FIRST_LEADING_ZERO''@/$(GL_STDC_FIRST_LEADING_ZERO)/g' \ | ||
| 3057 | -e 's/@''GL_STDC_FIRST_LEADING_ONE''@/$(GL_STDC_FIRST_LEADING_ONE)/g' \ | ||
| 3058 | -e 's/@''GL_STDC_FIRST_TRAILING_ZERO''@/$(GL_STDC_FIRST_TRAILING_ZERO)/g' \ | ||
| 3059 | -e 's/@''GL_STDC_FIRST_TRAILING_ONE''@/$(GL_STDC_FIRST_TRAILING_ONE)/g' \ | ||
| 3060 | -e 's/@''GL_STDC_COUNT_ZEROS''@/$(GL_STDC_COUNT_ZEROS)/g' \ | ||
| 3061 | -e 's/@''GL_STDC_COUNT_ONES''@/$(GL_STDC_COUNT_ONES)/g' \ | ||
| 3062 | -e 's/@''GL_STDC_HAS_SINGLE_BIT''@/$(GL_STDC_HAS_SINGLE_BIT)/g' \ | ||
| 3063 | -e 's/@''GL_STDC_BIT_WIDTH''@/$(GL_STDC_BIT_WIDTH)/g' \ | ||
| 3064 | -e 's/@''GL_STDC_BIT_FLOOR''@/$(GL_STDC_BIT_FLOOR)/g' \ | ||
| 3065 | -e 's/@''GL_STDC_BIT_CEIL''@/$(GL_STDC_BIT_CEIL)/g' \ | ||
| 3066 | $(srcdir)/stdbit.in.h > $@-t | ||
| 3067 | $(AM_V_at)mv $@-t $@ | ||
| 3068 | libgnu_a_SOURCES += stdbit.c | ||
| 3069 | else | ||
| 3070 | stdbit.h: $(top_builddir)/config.status | ||
| 3071 | rm -f $@ | ||
| 3072 | endif | ||
| 3073 | MOSTLYCLEANFILES += stdbit.h stdbit.h-t | ||
| 3074 | |||
| 3075 | EXTRA_DIST += stdbit.in.h | ||
| 3076 | |||
| 3077 | endif | ||
| 3078 | ## end gnulib module stdbit-h | ||
| 3079 | |||
| 3080 | ## begin gnulib module stdc_bit_width | ||
| 3081 | ifeq (,$(OMIT_GNULIB_MODULE_stdc_bit_width)) | ||
| 3082 | |||
| 3083 | ifneq (,$(GL_GENERATE_STDBIT_H_CONDITION)) | ||
| 3084 | libgnu_a_SOURCES += stdc_bit_width.c | ||
| 3085 | endif | ||
| 3086 | |||
| 3087 | endif | ||
| 3088 | ## end gnulib module stdc_bit_width | ||
| 3089 | |||
| 3090 | ## begin gnulib module stdc_count_ones | ||
| 3091 | ifeq (,$(OMIT_GNULIB_MODULE_stdc_count_ones)) | ||
| 3092 | |||
| 3093 | ifneq (,$(GL_GENERATE_STDBIT_H_CONDITION)) | ||
| 3094 | libgnu_a_SOURCES += stdc_count_ones.c | ||
| 3095 | endif | ||
| 3096 | |||
| 3097 | endif | ||
| 3098 | ## end gnulib module stdc_count_ones | ||
| 3099 | |||
| 3100 | ## begin gnulib module stdc_leading_zeros | ||
| 3101 | ifeq (,$(OMIT_GNULIB_MODULE_stdc_leading_zeros)) | ||
| 3102 | |||
| 3103 | ifneq (,$(GL_GENERATE_STDBIT_H_CONDITION)) | ||
| 3104 | libgnu_a_SOURCES += stdc_leading_zeros.c | ||
| 3105 | endif | ||
| 3106 | |||
| 3107 | endif | ||
| 3108 | ## end gnulib module stdc_leading_zeros | ||
| 3109 | |||
| 3110 | ## begin gnulib module stdc_trailing_zeros | ||
| 3111 | ifeq (,$(OMIT_GNULIB_MODULE_stdc_trailing_zeros)) | ||
| 3112 | |||
| 3113 | ifneq (,$(GL_GENERATE_STDBIT_H_CONDITION)) | ||
| 3114 | libgnu_a_SOURCES += stdc_trailing_zeros.c | ||
| 3115 | endif | ||
| 3116 | |||
| 3117 | endif | ||
| 3118 | ## end gnulib module stdc_trailing_zeros | ||
| 3119 | |||
| 3055 | ## begin gnulib module stdckdint | 3120 | ## begin gnulib module stdckdint |
| 3056 | ifeq (,$(OMIT_GNULIB_MODULE_stdckdint)) | 3121 | ifeq (,$(OMIT_GNULIB_MODULE_stdckdint)) |
| 3057 | 3122 | ||
| @@ -4274,7 +4339,9 @@ endif | |||
| 4274 | ## begin gnulib module verify | 4339 | ## begin gnulib module verify |
| 4275 | ifeq (,$(OMIT_GNULIB_MODULE_verify)) | 4340 | ifeq (,$(OMIT_GNULIB_MODULE_verify)) |
| 4276 | 4341 | ||
| 4342 | ifneq (,$(gl_GNULIB_ENABLED_verify_CONDITION)) | ||
| 4277 | 4343 | ||
| 4344 | endif | ||
| 4278 | EXTRA_DIST += verify.h | 4345 | EXTRA_DIST += verify.h |
| 4279 | 4346 | ||
| 4280 | endif | 4347 | endif |
diff --git a/lib/stdbit.c b/lib/stdbit.c new file mode 100644 index 00000000000..4801e74d281 --- /dev/null +++ b/lib/stdbit.c | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | /* Support C23 bit and byte utilities on non-C23 platforms. | ||
| 2 | |||
| 3 | Copyright 2024 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This file is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU Lesser General Public License as | ||
| 7 | published by the Free Software Foundation; either version 2.1 of the | ||
| 8 | License, or (at your option) any later version. | ||
| 9 | |||
| 10 | This file is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public License | ||
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | /* Written by Paul Eggert. */ | ||
| 19 | |||
| 20 | #include <config.h> | ||
| 21 | |||
| 22 | #define _GL_STDBIT_INLINE _GL_EXTERN_INLINE | ||
| 23 | #include <stdbit.h> | ||
diff --git a/lib/stdbit.in.h b/lib/stdbit.in.h new file mode 100644 index 00000000000..9f9e60a5d38 --- /dev/null +++ b/lib/stdbit.in.h | |||
| @@ -0,0 +1,1077 @@ | |||
| 1 | /* stdbit.h - C23 bit and byte utilities for non-C23 platforms | ||
| 2 | |||
| 3 | Copyright 2024 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This file is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU Lesser General Public License as | ||
| 7 | published by the Free Software Foundation; either version 2.1 of the | ||
| 8 | License, or (at your option) any later version. | ||
| 9 | |||
| 10 | This file is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public License | ||
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | /* Written by Paul Eggert. */ | ||
| 19 | |||
| 20 | #ifndef STDBIT_H | ||
| 21 | #define STDBIT_H 1 | ||
| 22 | |||
| 23 | /* This file uses _GL_INLINE, WORDS_BIGENDIAN. */ | ||
| 24 | #if !_GL_CONFIG_H_INCLUDED | ||
| 25 | #error "Please include config.h first." | ||
| 26 | #endif | ||
| 27 | |||
| 28 | _GL_INLINE_HEADER_BEGIN | ||
| 29 | |||
| 30 | #ifndef _GL_STDBIT_INLINE | ||
| 31 | # define _GL_STDBIT_INLINE _GL_INLINE | ||
| 32 | #endif | ||
| 33 | #ifndef _GL_STDC_LEADING_ZEROS_INLINE | ||
| 34 | # define _GL_STDC_LEADING_ZEROS_INLINE _GL_INLINE | ||
| 35 | #endif | ||
| 36 | #ifndef _GL_STDC_LEADING_ONES_INLINE | ||
| 37 | # define _GL_STDC_LEADING_ONES_INLINE _GL_INLINE | ||
| 38 | #endif | ||
| 39 | #ifndef _GL_STDC_TRAILING_ZEROS_INLINE | ||
| 40 | # define _GL_STDC_TRAILING_ZEROS_INLINE _GL_INLINE | ||
| 41 | #endif | ||
| 42 | #ifndef _GL_STDC_TRAILING_ONES_INLINE | ||
| 43 | # define _GL_STDC_TRAILING_ONES_INLINE _GL_INLINE | ||
| 44 | #endif | ||
| 45 | #ifndef _GL_STDC_FIRST_LEADING_ZERO_INLINE | ||
| 46 | # define _GL_STDC_FIRST_LEADING_ZERO_INLINE _GL_INLINE | ||
| 47 | #endif | ||
| 48 | #ifndef _GL_STDC_FIRST_LEADING_ONE_INLINE | ||
| 49 | # define _GL_STDC_FIRST_LEADING_ONE_INLINE _GL_INLINE | ||
| 50 | #endif | ||
| 51 | #ifndef _GL_STDC_FIRST_TRAILING_ZERO_INLINE | ||
| 52 | # define _GL_STDC_FIRST_TRAILING_ZERO_INLINE _GL_INLINE | ||
| 53 | #endif | ||
| 54 | #ifndef _GL_STDC_FIRST_TRAILING_ONE_INLINE | ||
| 55 | # define _GL_STDC_FIRST_TRAILING_ONE_INLINE _GL_INLINE | ||
| 56 | #endif | ||
| 57 | #ifndef _GL_STDC_COUNT_ZEROS_INLINE | ||
| 58 | # define _GL_STDC_COUNT_ZEROS_INLINE _GL_INLINE | ||
| 59 | #endif | ||
| 60 | #ifndef _GL_STDC_COUNT_ONES_INLINE | ||
| 61 | # define _GL_STDC_COUNT_ONES_INLINE _GL_INLINE | ||
| 62 | #endif | ||
| 63 | #ifndef _GL_STDC_HAS_SINGLE_BIT_INLINE | ||
| 64 | # define _GL_STDC_HAS_SINGLE_BIT_INLINE _GL_INLINE | ||
| 65 | #endif | ||
| 66 | #ifndef _GL_STDC_BIT_WIDTH_INLINE | ||
| 67 | # define _GL_STDC_BIT_WIDTH_INLINE _GL_INLINE | ||
| 68 | #endif | ||
| 69 | #ifndef _GL_STDC_BIT_FLOOR_INLINE | ||
| 70 | # define _GL_STDC_BIT_FLOOR_INLINE _GL_INLINE | ||
| 71 | #endif | ||
| 72 | #ifndef _GL_STDC_BIT_CEIL_INLINE | ||
| 73 | # define _GL_STDC_BIT_CEIL_INLINE _GL_INLINE | ||
| 74 | #endif | ||
| 75 | |||
| 76 | /* An expression, preferably with the type of A, that has the value of B. */ | ||
| 77 | #if ((defined __GNUC__ && 2 <= __GNUC__) \ | ||
| 78 | || (defined __clang_major__ && 4 <= __clang_major__) \ | ||
| 79 | || (defined __IBMC__ && 1210 <= __IBMC__ && defined __IBM__TYPEOF__) \ | ||
| 80 | || (defined __SUNPRO_C && 0x5110 <= __SUNPRO_C && !__STDC__)) | ||
| 81 | # define _GL_STDBIT_TYPEOF_CAST(a, b) ((__typeof__ (a)) (b)) | ||
| 82 | #elif 202311 <= __STDC_VERSION__ | ||
| 83 | # define _GL_STDBIT_TYPEOF_CAST(a, b) ((typeof (a)) (b)) | ||
| 84 | #else | ||
| 85 | /* This platform is so old that it lacks typeof, so _Generic is likely | ||
| 86 | missing or unreliable. The C23 standard seems to allow yielding B | ||
| 87 | (which is always unsigned long long int), so do that. */ | ||
| 88 | # define _GL_STDBIT_TYPEOF_CAST(a, b) (b) | ||
| 89 | #endif | ||
| 90 | |||
| 91 | |||
| 92 | /* ISO C 23 § 7.18.1 General */ | ||
| 93 | |||
| 94 | #define __STDC_VERSION_STDBIT_H__ 202311L | ||
| 95 | |||
| 96 | |||
| 97 | /* ISO C 23 § 7.18.2 Endian */ | ||
| 98 | |||
| 99 | #define __STDC_ENDIAN_BIG__ 4321 | ||
| 100 | #define __STDC_ENDIAN_LITTLE__ 1234 | ||
| 101 | #ifdef WORDS_BIGENDIAN | ||
| 102 | # define __STDC_ENDIAN_NATIVE__ __STDC_ENDIAN_BIG__ | ||
| 103 | #else | ||
| 104 | # define __STDC_ENDIAN_NATIVE__ __STDC_ENDIAN_LITTLE__ | ||
| 105 | #endif | ||
| 106 | |||
| 107 | |||
| 108 | #ifdef __cplusplus | ||
| 109 | extern "C" { | ||
| 110 | #endif | ||
| 111 | |||
| 112 | #if 3 < __GNUC__ + (4 <= __GNUC_MINOR__) || 4 <= __clang_major__ | ||
| 113 | # define _GL_STDBIT_HAS_BUILTIN_CLZ true | ||
| 114 | # define _GL_STDBIT_HAS_BUILTIN_CTZ true | ||
| 115 | # define _GL_STDBIT_HAS_BUILTIN_POPCOUNT true | ||
| 116 | #elif defined __has_builtin | ||
| 117 | # if (__has_builtin (__builtin_clz) \ | ||
| 118 | && __has_builtin (__builtin_clzl) \ | ||
| 119 | && __has_builtin (__builtin_clzll)) | ||
| 120 | # define _GL_STDBIT_HAS_BUILTIN_CLZ true | ||
| 121 | # endif | ||
| 122 | # if (__has_builtin (__builtin_ctz) \ | ||
| 123 | && __has_builtin (__builtin_ctzl) \ | ||
| 124 | && __has_builtin (__builtin_ctzll)) | ||
| 125 | # define _GL_STDBIT_HAS_BUILTIN_CTZ true | ||
| 126 | # endif | ||
| 127 | # if (__has_builtin (__builtin_popcount) \ | ||
| 128 | && __has_builtin (__builtin_popcountl) \ | ||
| 129 | && __has_builtin (__builtin_popcountll)) | ||
| 130 | # define _GL_STDBIT_HAS_BUILTIN_POPCOUNT true | ||
| 131 | # endif | ||
| 132 | #endif | ||
| 133 | |||
| 134 | /* Count leading 0 bits of N, even if N is 0. */ | ||
| 135 | #ifdef _GL_STDBIT_HAS_BUILTIN_CLZ | ||
| 136 | _GL_STDBIT_INLINE int | ||
| 137 | __gl_stdbit_clz (unsigned int n) | ||
| 138 | { | ||
| 139 | return n ? __builtin_clz (n) : 8 * sizeof n; | ||
| 140 | } | ||
| 141 | _GL_STDBIT_INLINE int | ||
| 142 | __gl_stdbit_clzl (unsigned long int n) | ||
| 143 | { | ||
| 144 | return n ? __builtin_clzl (n) : 8 * sizeof n; | ||
| 145 | } | ||
| 146 | _GL_STDBIT_INLINE int | ||
| 147 | __gl_stdbit_clzll (unsigned long long int n) | ||
| 148 | { | ||
| 149 | return n ? __builtin_clzll (n) : 8 * sizeof n; | ||
| 150 | } | ||
| 151 | #elif defined _MSC_VER | ||
| 152 | |||
| 153 | /* Declare the few MSVC intrinsics that we need. We prefer not to include | ||
| 154 | <intrin.h> because it would pollute the namespace. */ | ||
| 155 | extern unsigned char _BitScanReverse (unsigned long *, unsigned long); | ||
| 156 | # pragma intrinsic (_BitScanReverse) | ||
| 157 | # ifdef _M_X64 | ||
| 158 | extern unsigned char _BitScanReverse64 (unsigned long *, unsigned long long); | ||
| 159 | # pragma intrinsic (_BitScanReverse64) | ||
| 160 | # endif | ||
| 161 | |||
| 162 | _GL_STDBIT_INLINE int | ||
| 163 | __gl_stdbit_clzl (unsigned long int n) | ||
| 164 | { | ||
| 165 | unsigned long int r; | ||
| 166 | return 8 * sizeof n - (_BitScanReverse (&r, n) ? r + 1 : 0); | ||
| 167 | } | ||
| 168 | _GL_STDBIT_INLINE int | ||
| 169 | __gl_stdbit_clz (unsigned int n) | ||
| 170 | { | ||
| 171 | return __gl_stdbit_clzl (n) - 8 * (sizeof 0ul - sizeof n); | ||
| 172 | } | ||
| 173 | _GL_STDBIT_INLINE int | ||
| 174 | __gl_stdbit_clzll (unsigned long long int n) | ||
| 175 | { | ||
| 176 | # ifdef _M_X64 | ||
| 177 | unsigned long int r; | ||
| 178 | return 8 * sizeof n - (_BitScanReverse64 (&r, n) ? r + 1 : 0); | ||
| 179 | # else | ||
| 180 | unsigned long int hi = n >> 32; | ||
| 181 | return __gl_stdbit_clzl (hi ? hi : n) + (hi ? 0 : 32); | ||
| 182 | # endif | ||
| 183 | } | ||
| 184 | |||
| 185 | #else /* !_MSC_VER */ | ||
| 186 | |||
| 187 | _GL_STDBIT_INLINE int | ||
| 188 | __gl_stdbit_clzll (unsigned long long int n) | ||
| 189 | { | ||
| 190 | int r = 0; | ||
| 191 | for (int i = 8 * sizeof n >> 1; 1 << 6 <= i; i >>= 1) | ||
| 192 | { | ||
| 193 | int a = (1ull << i <= n) * i; n >>= a; r += a; | ||
| 194 | } | ||
| 195 | int a5 = (0x00000000ffffffff < n) << 5; n >>= a5; r += a5; | ||
| 196 | int a4 = (0x000000000000ffff < n) << 4; n >>= a4; r += a4; | ||
| 197 | int a3 = (0x00000000000000ff < n) << 3; n >>= a3; r += a3; | ||
| 198 | int a2 = (0x000000000000000f < n) << 2; n >>= a2; r += a2; | ||
| 199 | return (8 * sizeof n - (1 << 2) - r) + ((0x11112234ull >> (n << 2)) & 0xf); | ||
| 200 | } | ||
| 201 | _GL_STDBIT_INLINE int | ||
| 202 | __gl_stdbit_clz (unsigned int n) | ||
| 203 | { | ||
| 204 | return __gl_stdbit_clzll (n) - 8 * (sizeof 0ull - sizeof 0u); | ||
| 205 | } | ||
| 206 | _GL_STDBIT_INLINE int | ||
| 207 | __gl_stdbit_clzl (unsigned long int n) | ||
| 208 | { | ||
| 209 | return __gl_stdbit_clzll (n) - 8 * (sizeof 0ull - sizeof 0ul); | ||
| 210 | } | ||
| 211 | #endif | ||
| 212 | |||
| 213 | /* Count trailing 0 bits of N, even if N is 0. */ | ||
| 214 | #ifdef _GL_STDBIT_HAS_BUILTIN_CTZ | ||
| 215 | _GL_STDBIT_INLINE int | ||
| 216 | __gl_stdbit_ctz (unsigned int n) | ||
| 217 | { | ||
| 218 | return n ? __builtin_ctz (n) : 8 * sizeof n; | ||
| 219 | } | ||
| 220 | _GL_STDBIT_INLINE int | ||
| 221 | __gl_stdbit_ctzl (unsigned long int n) | ||
| 222 | { | ||
| 223 | return n ? __builtin_ctzl (n) : 8 * sizeof n; | ||
| 224 | } | ||
| 225 | _GL_STDBIT_INLINE int | ||
| 226 | __gl_stdbit_ctzll (unsigned long long int n) | ||
| 227 | { | ||
| 228 | return n ? __builtin_ctzll (n) : 8 * sizeof n; | ||
| 229 | } | ||
| 230 | #elif defined _MSC_VER | ||
| 231 | |||
| 232 | /* Declare the few MSVC intrinsics that we need. We prefer not to include | ||
| 233 | <intrin.h> because it would pollute the namespace. */ | ||
| 234 | extern unsigned char _BitScanForward (unsigned long *, unsigned long); | ||
| 235 | # pragma intrinsic (_BitScanForward) | ||
| 236 | # ifdef _M_X64 | ||
| 237 | extern unsigned char _BitScanForward64 (unsigned long *, unsigned long long); | ||
| 238 | # pragma intrinsic (_BitScanForward64) | ||
| 239 | # endif | ||
| 240 | |||
| 241 | _GL_STDBIT_INLINE int | ||
| 242 | __gl_stdbit_ctzl (unsigned long int n) | ||
| 243 | { | ||
| 244 | unsigned long int r; | ||
| 245 | return _BitScanForward (&r, n) ? r : 8 * sizeof n; | ||
| 246 | } | ||
| 247 | _GL_STDBIT_INLINE int | ||
| 248 | __gl_stdbit_ctz (unsigned int n) | ||
| 249 | { | ||
| 250 | return __gl_stdbit_ctzl (n | (1ul << (8 * sizeof n - 1) << 1)); | ||
| 251 | } | ||
| 252 | _GL_STDBIT_INLINE int | ||
| 253 | __gl_stdbit_ctzll (unsigned long long int n) | ||
| 254 | { | ||
| 255 | # ifdef _M_X64 | ||
| 256 | unsigned long int r; | ||
| 257 | return _BitScanForward64 (&r, n) ? r : 8 * sizeof n; | ||
| 258 | # else | ||
| 259 | unsigned int lo = n; | ||
| 260 | return __gl_stdbit_ctzl (lo ? lo : n >> 32) + (lo ? 0 : 32); | ||
| 261 | # endif | ||
| 262 | } | ||
| 263 | |||
| 264 | #else /* !_MSC_VER */ | ||
| 265 | |||
| 266 | _GL_STDBIT_INLINE int | ||
| 267 | __gl_stdbit_ctz (unsigned int n) | ||
| 268 | { | ||
| 269 | return 8 * sizeof n - (n ? __gl_stdbit_clz (n & -n) + 1 : 0); | ||
| 270 | } | ||
| 271 | _GL_STDBIT_INLINE int | ||
| 272 | __gl_stdbit_ctzl (unsigned long int n) | ||
| 273 | { | ||
| 274 | return 8 * sizeof n - (n ? __gl_stdbit_clzl (n & -n) + 1 : 0); | ||
| 275 | } | ||
| 276 | _GL_STDBIT_INLINE int | ||
| 277 | __gl_stdbit_ctzll (unsigned long long int n) | ||
| 278 | { | ||
| 279 | return 8 * sizeof n - (n ? __gl_stdbit_clzll (n & -n) + 1 : 0); | ||
| 280 | } | ||
| 281 | #endif | ||
| 282 | |||
| 283 | #if @GL_STDC_COUNT_ONES@ | ||
| 284 | /* Count 1 bits in N. */ | ||
| 285 | # ifdef _GL_STDBIT_HAS_BUILTIN_POPCOUNT | ||
| 286 | # define __gl_stdbit_popcount __builtin_popcount | ||
| 287 | # define __gl_stdbit_popcountl __builtin_popcountl | ||
| 288 | # define __gl_stdbit_popcountll __builtin_popcountll | ||
| 289 | # else | ||
| 290 | _GL_STDC_COUNT_ONES_INLINE int | ||
| 291 | __gl_stdbit_popcount_wide (unsigned long long int n) | ||
| 292 | { | ||
| 293 | if (sizeof n & (sizeof n - 1)) | ||
| 294 | { | ||
| 295 | /* Use a simple O(log N) loop on theoretical platforms where N's | ||
| 296 | width is not a power of 2. */ | ||
| 297 | int count = 0; | ||
| 298 | for (int i = 0; i < 8 * sizeof n; i++, n >>= 1) | ||
| 299 | count += n & 1; | ||
| 300 | return count; | ||
| 301 | } | ||
| 302 | else | ||
| 303 | { | ||
| 304 | /* N's width is a power of 2; count in parallel. */ | ||
| 305 | unsigned long long int | ||
| 306 | max = -1ull, | ||
| 307 | x555555 = max / (1 << 1 | 1), /* 0x555555... */ | ||
| 308 | x333333 = max / (1 << 2 | 1), /* 0x333333... */ | ||
| 309 | x0f0f0f = max / (1 << 4 | 1), /* 0x0f0f0f... */ | ||
| 310 | x010101 = max / ((1 << 8) - 1), /* 0x010101... */ | ||
| 311 | x000_7f = max / 0xffffffffffffffff * 0x7f; /* 0x000000000000007f... */ | ||
| 312 | n -= (n >> 1) & x555555; | ||
| 313 | n = (n & x333333) + ((n >> 2) & x333333); | ||
| 314 | n = (n + (n >> 4)) & x0f0f0f; | ||
| 315 | |||
| 316 | /* If the popcount always fits in 8 bits, multiply so that the | ||
| 317 | popcount is in the leading 8 bits of the product; these days | ||
| 318 | this is typically faster than the alternative below. */ | ||
| 319 | if (8 * sizeof n < 1 << 8) | ||
| 320 | return n * x010101 >> 8 * (sizeof n - 1); | ||
| 321 | |||
| 322 | /* N is at least 256 bits wide! Fall back on an O(log log N) | ||
| 323 | loop that a compiler could unroll. Unroll the first three | ||
| 324 | iterations by hand, to skip some division and masking. This | ||
| 325 | is the most we can easily do without hassling with constants | ||
| 326 | that a typical-platform compiler would reject. */ | ||
| 327 | n += n >> (1 << 3); | ||
| 328 | n += n >> (1 << 4); | ||
| 329 | n += n >> (1 << 5); | ||
| 330 | n &= x000_7f; | ||
| 331 | for (int i = 64; i < 8 * sizeof n; i <<= 1) | ||
| 332 | n = (n + (n >> i)) & max / (1ull << i | 1); | ||
| 333 | return n; | ||
| 334 | } | ||
| 335 | } | ||
| 336 | |||
| 337 | # ifdef _MSC_VER | ||
| 338 | # if 1500 <= _MSC_VER && (defined _M_IX86 || defined _M_X64) | ||
| 339 | /* Declare the few MSVC intrinsics that we need. We prefer not to include | ||
| 340 | <intrin.h> because it would pollute the namespace. */ | ||
| 341 | extern void __cpuid (int[4], int); | ||
| 342 | # pragma intrinsic (__cpuid) | ||
| 343 | extern unsigned int __popcnt (unsigned int); | ||
| 344 | # pragma intrinsic (__popcnt) | ||
| 345 | # ifdef _M_X64 | ||
| 346 | extern unsigned long long __popcnt64 (unsigned long long); | ||
| 347 | # pragma intrinsic (__popcnt64) | ||
| 348 | # else | ||
| 349 | _GL_STDC_COUNT_ONES_INLINE int | ||
| 350 | __popcnt64 (unsigned long long int n) | ||
| 351 | { | ||
| 352 | return __popcnt (n >> 32) + __popcnt (n); | ||
| 353 | } | ||
| 354 | # endif | ||
| 355 | # endif | ||
| 356 | |||
| 357 | /* 1 if supported, -1 if not, 0 if unknown. */ | ||
| 358 | extern signed char __gl_stdbit_popcount_support; | ||
| 359 | |||
| 360 | _GL_STDC_COUNT_ONES_INLINE bool | ||
| 361 | __gl_stdbit_popcount_supported (void) | ||
| 362 | { | ||
| 363 | if (!__gl_stdbit_popcount_support) | ||
| 364 | { | ||
| 365 | /* Do as described in | ||
| 366 | <https://docs.microsoft.com/en-us/cpp/intrinsics/popcnt16-popcnt-popcnt64> | ||
| 367 | Although Microsoft started requiring POPCNT in MS-Windows 11 24H2, | ||
| 368 | we'll be more cautious. */ | ||
| 369 | int cpu_info[4]; | ||
| 370 | __cpuid (cpu_info, 1); | ||
| 371 | __gl_stdbit_popcount_support = cpu_info[2] & 1 << 23 ? 1 : -1; | ||
| 372 | } | ||
| 373 | return 0 < __gl_stdbit_popcount_support; | ||
| 374 | } | ||
| 375 | _GL_STDC_COUNT_ONES_INLINE int | ||
| 376 | __gl_stdbit_popcount (unsigned int n) | ||
| 377 | { | ||
| 378 | return (__gl_stdbit_popcount_supported () | ||
| 379 | ? __popcnt (n) | ||
| 380 | : __gl_stdbit_popcount_wide (n)); | ||
| 381 | } | ||
| 382 | _GL_STDC_COUNT_ONES_INLINE int | ||
| 383 | __gl_stdbit_popcountl (unsigned long int n) | ||
| 384 | { | ||
| 385 | return (__gl_stdbit_popcount_supported () | ||
| 386 | ? __popcnt (n) | ||
| 387 | : __gl_stdbit_popcount_wide (n)); | ||
| 388 | } | ||
| 389 | _GL_STDC_COUNT_ONES_INLINE int | ||
| 390 | __gl_stdbit_popcountll (unsigned long long int n) | ||
| 391 | { | ||
| 392 | return (__gl_stdbit_popcount_supported () | ||
| 393 | ? __popcnt64 (n) | ||
| 394 | : __gl_stdbit_popcount_wide (n)); | ||
| 395 | } | ||
| 396 | # else /* !_MSC_VER */ | ||
| 397 | # define __gl_stdbit_popcount __gl_stdbit_popcount_wide | ||
| 398 | # define __gl_stdbit_popcountl __gl_stdbit_popcount_wide | ||
| 399 | # define __gl_stdbit_popcountll __gl_stdbit_popcount_wide | ||
| 400 | # endif | ||
| 401 | # endif | ||
| 402 | #endif | ||
| 403 | |||
| 404 | |||
| 405 | /* ISO C 23 § 7.18.3 Count Leading Zeros */ | ||
| 406 | |||
| 407 | #if @GL_STDC_LEADING_ZEROS@ | ||
| 408 | |||
| 409 | _GL_STDC_LEADING_ZEROS_INLINE unsigned int | ||
| 410 | stdc_leading_zeros_ui (unsigned int n) | ||
| 411 | { | ||
| 412 | return __gl_stdbit_clz (n); | ||
| 413 | } | ||
| 414 | |||
| 415 | _GL_STDC_LEADING_ZEROS_INLINE unsigned int | ||
| 416 | stdc_leading_zeros_uc (unsigned char n) | ||
| 417 | { | ||
| 418 | return stdc_leading_zeros_ui (n) - 8 * (sizeof 0u - sizeof n); | ||
| 419 | } | ||
| 420 | |||
| 421 | _GL_STDC_LEADING_ZEROS_INLINE unsigned int | ||
| 422 | stdc_leading_zeros_us (unsigned short int n) | ||
| 423 | { | ||
| 424 | return stdc_leading_zeros_ui (n) - 8 * (sizeof 0u - sizeof n); | ||
| 425 | } | ||
| 426 | |||
| 427 | _GL_STDC_LEADING_ZEROS_INLINE unsigned int | ||
| 428 | stdc_leading_zeros_ul (unsigned long int n) | ||
| 429 | { | ||
| 430 | return __gl_stdbit_clzl (n); | ||
| 431 | } | ||
| 432 | |||
| 433 | _GL_STDC_LEADING_ZEROS_INLINE unsigned int | ||
| 434 | stdc_leading_zeros_ull (unsigned long long int n) | ||
| 435 | { | ||
| 436 | return __gl_stdbit_clzll (n); | ||
| 437 | } | ||
| 438 | |||
| 439 | # define stdc_leading_zeros(n) \ | ||
| 440 | (sizeof (n) == 1 ? stdc_leading_zeros_uc (n) \ | ||
| 441 | : sizeof (n) == sizeof (unsigned short int) ? stdc_leading_zeros_us (n) \ | ||
| 442 | : sizeof (n) == sizeof 0u ? stdc_leading_zeros_ui (n) \ | ||
| 443 | : sizeof (n) == sizeof 0ul ? stdc_leading_zeros_ul (n) \ | ||
| 444 | : stdc_leading_zeros_ull (n)) | ||
| 445 | |||
| 446 | #endif | ||
| 447 | |||
| 448 | |||
| 449 | /* ISO C 23 § 7.18.4 Count Leading Ones */ | ||
| 450 | |||
| 451 | #if @GL_STDC_LEADING_ONES@ | ||
| 452 | |||
| 453 | _GL_STDC_LEADING_ONES_INLINE unsigned int | ||
| 454 | stdc_leading_ones_uc (unsigned char n) | ||
| 455 | { | ||
| 456 | return stdc_leading_zeros_uc (~n); | ||
| 457 | } | ||
| 458 | |||
| 459 | _GL_STDC_LEADING_ONES_INLINE unsigned int | ||
| 460 | stdc_leading_ones_us (unsigned short int n) | ||
| 461 | { | ||
| 462 | return stdc_leading_zeros_us (~n); | ||
| 463 | } | ||
| 464 | |||
| 465 | _GL_STDC_LEADING_ONES_INLINE unsigned int | ||
| 466 | stdc_leading_ones_ui (unsigned int n) | ||
| 467 | { | ||
| 468 | return stdc_leading_zeros_ui (~n); | ||
| 469 | } | ||
| 470 | |||
| 471 | _GL_STDC_LEADING_ONES_INLINE unsigned int | ||
| 472 | stdc_leading_ones_ul (unsigned long int n) | ||
| 473 | { | ||
| 474 | return stdc_leading_zeros_ul (~n); | ||
| 475 | } | ||
| 476 | |||
| 477 | _GL_STDC_LEADING_ONES_INLINE unsigned int | ||
| 478 | stdc_leading_ones_ull (unsigned long long int n) | ||
| 479 | { | ||
| 480 | return stdc_leading_zeros_ull (~n); | ||
| 481 | } | ||
| 482 | |||
| 483 | # define stdc_leading_ones(n) \ | ||
| 484 | (sizeof (n) == 1 ? stdc_leading_ones_uc (n) \ | ||
| 485 | : sizeof (n) == sizeof (unsigned short int) ? stdc_leading_ones_us (n) \ | ||
| 486 | : sizeof (n) == sizeof 0u ? stdc_leading_ones_ui (n) \ | ||
| 487 | : sizeof (n) == sizeof 0ul ? stdc_leading_ones_ul (n) \ | ||
| 488 | : stdc_leading_ones_ull (n)) | ||
| 489 | |||
| 490 | #endif | ||
| 491 | |||
| 492 | |||
| 493 | /* ISO C 23 § 7.18.5 Count Trailing Zeros */ | ||
| 494 | |||
| 495 | #if @GL_STDC_TRAILING_ZEROS@ | ||
| 496 | |||
| 497 | _GL_STDC_TRAILING_ZEROS_INLINE unsigned int | ||
| 498 | stdc_trailing_zeros_ui (unsigned int n) | ||
| 499 | { | ||
| 500 | return __gl_stdbit_ctz (n); | ||
| 501 | } | ||
| 502 | |||
| 503 | _GL_STDC_TRAILING_ZEROS_INLINE unsigned int | ||
| 504 | stdc_trailing_zeros_uc (unsigned char n) | ||
| 505 | { | ||
| 506 | return stdc_trailing_zeros_ui (n | (1 + (unsigned char) -1)); | ||
| 507 | } | ||
| 508 | |||
| 509 | _GL_STDC_TRAILING_ZEROS_INLINE unsigned int | ||
| 510 | stdc_trailing_zeros_us (unsigned short int n) | ||
| 511 | { | ||
| 512 | return stdc_trailing_zeros_ui (n | (1 + (unsigned short int) -1)); | ||
| 513 | } | ||
| 514 | |||
| 515 | _GL_STDC_TRAILING_ZEROS_INLINE unsigned int | ||
| 516 | stdc_trailing_zeros_ul (unsigned long int n) | ||
| 517 | { | ||
| 518 | return __gl_stdbit_ctzl (n); | ||
| 519 | } | ||
| 520 | |||
| 521 | _GL_STDC_TRAILING_ZEROS_INLINE unsigned int | ||
| 522 | stdc_trailing_zeros_ull (unsigned long long int n) | ||
| 523 | { | ||
| 524 | return __gl_stdbit_ctzll (n); | ||
| 525 | } | ||
| 526 | |||
| 527 | # define stdc_trailing_zeros(n) \ | ||
| 528 | (sizeof (n) == 1 ? stdc_trailing_zeros_uc (n) \ | ||
| 529 | : sizeof (n) == sizeof (unsigned short int) ? stdc_trailing_zeros_us (n) \ | ||
| 530 | : sizeof (n) == sizeof 0u ? stdc_trailing_zeros_ui (n) \ | ||
| 531 | : sizeof (n) == sizeof 0ul ? stdc_trailing_zeros_ul (n) \ | ||
| 532 | : stdc_trailing_zeros_ull (n)) | ||
| 533 | |||
| 534 | #endif | ||
| 535 | |||
| 536 | |||
| 537 | /* ISO C 23 § 7.18.6 Count Trailing Ones */ | ||
| 538 | |||
| 539 | #if @GL_STDC_TRAILING_ONES@ | ||
| 540 | |||
| 541 | _GL_STDC_TRAILING_ONES_INLINE unsigned int | ||
| 542 | stdc_trailing_ones_uc (unsigned char n) | ||
| 543 | { | ||
| 544 | return stdc_trailing_zeros_uc (~n); | ||
| 545 | } | ||
| 546 | |||
| 547 | _GL_STDC_TRAILING_ONES_INLINE unsigned int | ||
| 548 | stdc_trailing_ones_us (unsigned short int n) | ||
| 549 | { | ||
| 550 | return stdc_trailing_zeros_us (~n); | ||
| 551 | } | ||
| 552 | |||
| 553 | _GL_STDC_TRAILING_ONES_INLINE unsigned int | ||
| 554 | stdc_trailing_ones_ui (unsigned int n) | ||
| 555 | { | ||
| 556 | return stdc_trailing_zeros_ui (~n); | ||
| 557 | } | ||
| 558 | |||
| 559 | _GL_STDC_TRAILING_ONES_INLINE unsigned int | ||
| 560 | stdc_trailing_ones_ul (unsigned long int n) | ||
| 561 | { | ||
| 562 | return stdc_trailing_zeros_ul (~n); | ||
| 563 | } | ||
| 564 | |||
| 565 | _GL_STDC_TRAILING_ONES_INLINE unsigned int | ||
| 566 | stdc_trailing_ones_ull (unsigned long long int n) | ||
| 567 | { | ||
| 568 | return stdc_trailing_zeros_ull (~n); | ||
| 569 | } | ||
| 570 | |||
| 571 | # define stdc_trailing_ones(n) \ | ||
| 572 | (sizeof (n) == 1 ? stdc_trailing_ones_uc (n) \ | ||
| 573 | : sizeof (n) == sizeof (unsigned short int) ? stdc_trailing_ones_us (n) \ | ||
| 574 | : sizeof (n) == sizeof 0u ? stdc_trailing_ones_ui (n) \ | ||
| 575 | : sizeof (n) == sizeof 0ul ? stdc_trailing_ones_ul (n) \ | ||
| 576 | : stdc_trailing_ones_ull (n)) | ||
| 577 | |||
| 578 | #endif | ||
| 579 | |||
| 580 | |||
| 581 | /* ISO C 23 § 7.18.7 First Leading Zero */ | ||
| 582 | |||
| 583 | #if @GL_STDC_FIRST_LEADING_ZERO@ | ||
| 584 | |||
| 585 | _GL_STDC_FIRST_LEADING_ZERO_INLINE unsigned int | ||
| 586 | stdc_first_leading_zero_uc (unsigned char n) | ||
| 587 | { | ||
| 588 | unsigned int count = stdc_leading_ones_uc (n); | ||
| 589 | unsigned int bits = 8 * sizeof n; | ||
| 590 | return count % bits + (count < bits); | ||
| 591 | } | ||
| 592 | |||
| 593 | _GL_STDC_FIRST_LEADING_ZERO_INLINE unsigned int | ||
| 594 | stdc_first_leading_zero_us (unsigned short int n) | ||
| 595 | { | ||
| 596 | unsigned int count = stdc_leading_ones_us (n); | ||
| 597 | unsigned int bits = 8 * sizeof n; | ||
| 598 | return count % bits + (count < bits); | ||
| 599 | } | ||
| 600 | |||
| 601 | _GL_STDC_FIRST_LEADING_ZERO_INLINE unsigned int | ||
| 602 | stdc_first_leading_zero_ui (unsigned int n) | ||
| 603 | { | ||
| 604 | unsigned int count = stdc_leading_ones_ui (n); | ||
| 605 | unsigned int bits = 8 * sizeof n; | ||
| 606 | return count % bits + (count < bits); | ||
| 607 | } | ||
| 608 | |||
| 609 | _GL_STDC_FIRST_LEADING_ZERO_INLINE unsigned int | ||
| 610 | stdc_first_leading_zero_ul (unsigned long int n) | ||
| 611 | { | ||
| 612 | unsigned int count = stdc_leading_ones_ul (n); | ||
| 613 | unsigned int bits = 8 * sizeof n; | ||
| 614 | return count % bits + (count < bits); | ||
| 615 | } | ||
| 616 | |||
| 617 | _GL_STDC_FIRST_LEADING_ZERO_INLINE unsigned int | ||
| 618 | stdc_first_leading_zero_ull (unsigned long long int n) | ||
| 619 | { | ||
| 620 | unsigned int count = stdc_leading_ones_ull (n); | ||
| 621 | unsigned int bits = 8 * sizeof n; | ||
| 622 | return count % bits + (count < bits); | ||
| 623 | } | ||
| 624 | |||
| 625 | # define stdc_first_leading_zero(n) \ | ||
| 626 | (sizeof (n) == 1 ? stdc_first_leading_zero_uc (n) \ | ||
| 627 | : sizeof (n) == sizeof (unsigned short) ? stdc_first_leading_zero_us (n) \ | ||
| 628 | : sizeof (n) == sizeof 0u ? stdc_first_leading_zero_ui (n) \ | ||
| 629 | : sizeof (n) == sizeof 0ul ? stdc_first_leading_zero_ul (n) \ | ||
| 630 | : stdc_first_leading_zero_ull (n)) | ||
| 631 | |||
| 632 | #endif | ||
| 633 | |||
| 634 | |||
| 635 | /* ISO C 23 § 7.18.8 First Leading One */ | ||
| 636 | |||
| 637 | #if @GL_STDC_FIRST_LEADING_ONE@ | ||
| 638 | |||
| 639 | _GL_STDC_FIRST_LEADING_ONE_INLINE unsigned int | ||
| 640 | stdc_first_leading_one_uc (unsigned char n) | ||
| 641 | { | ||
| 642 | unsigned int count = stdc_leading_zeros_uc (n); | ||
| 643 | unsigned int bits = 8 * sizeof n; | ||
| 644 | return count % bits + (count < bits); | ||
| 645 | } | ||
| 646 | |||
| 647 | _GL_STDC_FIRST_LEADING_ONE_INLINE unsigned int | ||
| 648 | stdc_first_leading_one_us (unsigned short int n) | ||
| 649 | { | ||
| 650 | unsigned int count = stdc_leading_zeros_us (n); | ||
| 651 | unsigned int bits = 8 * sizeof n; | ||
| 652 | return count % bits + (count < bits); | ||
| 653 | } | ||
| 654 | |||
| 655 | _GL_STDC_FIRST_LEADING_ONE_INLINE unsigned int | ||
| 656 | stdc_first_leading_one_ui (unsigned int n) | ||
| 657 | { | ||
| 658 | unsigned int count = stdc_leading_zeros_ui (n); | ||
| 659 | unsigned int bits = 8 * sizeof n; | ||
| 660 | return count % bits + (count < bits); | ||
| 661 | } | ||
| 662 | |||
| 663 | _GL_STDC_FIRST_LEADING_ONE_INLINE unsigned int | ||
| 664 | stdc_first_leading_one_ul (unsigned long int n) | ||
| 665 | { | ||
| 666 | unsigned int count = stdc_leading_zeros_ul (n); | ||
| 667 | unsigned int bits = 8 * sizeof n; | ||
| 668 | return count % bits + (count < bits); | ||
| 669 | } | ||
| 670 | |||
| 671 | _GL_STDC_FIRST_LEADING_ONE_INLINE unsigned int | ||
| 672 | stdc_first_leading_one_ull (unsigned long long int n) | ||
| 673 | { | ||
| 674 | unsigned int count = stdc_leading_zeros_ull (n); | ||
| 675 | unsigned int bits = 8 * sizeof n; | ||
| 676 | return count % bits + (count < bits); | ||
| 677 | } | ||
| 678 | |||
| 679 | # define stdc_first_leading_one(n) \ | ||
| 680 | (sizeof (n) == 1 ? stdc_first_leading_one_uc (n) \ | ||
| 681 | : sizeof (n) == sizeof (unsigned short) ? stdc_first_leading_one_us (n) \ | ||
| 682 | : sizeof (n) == sizeof 0u ? stdc_first_leading_one_ui (n) \ | ||
| 683 | : sizeof (n) == sizeof 0ul ? stdc_first_leading_one_ul (n) \ | ||
| 684 | : stdc_first_leading_one_ull (n)) | ||
| 685 | |||
| 686 | #endif | ||
| 687 | |||
| 688 | |||
| 689 | /* ISO C 23 § 7.18.9 First Trailing Zero */ | ||
| 690 | |||
| 691 | #if @GL_STDC_FIRST_TRAILING_ZERO@ | ||
| 692 | |||
| 693 | _GL_STDC_FIRST_TRAILING_ZERO_INLINE unsigned int | ||
| 694 | stdc_first_trailing_zero_uc (unsigned char n) | ||
| 695 | { | ||
| 696 | unsigned int count = stdc_trailing_ones_uc (n); | ||
| 697 | unsigned int bits = 8 * sizeof n; | ||
| 698 | return count % bits + (count < bits); | ||
| 699 | } | ||
| 700 | |||
| 701 | _GL_STDC_FIRST_TRAILING_ZERO_INLINE unsigned int | ||
| 702 | stdc_first_trailing_zero_us (unsigned short int n) | ||
| 703 | { | ||
| 704 | unsigned int count = stdc_trailing_ones_us (n); | ||
| 705 | unsigned int bits = 8 * sizeof n; | ||
| 706 | return count % bits + (count < bits); | ||
| 707 | } | ||
| 708 | |||
| 709 | _GL_STDC_FIRST_TRAILING_ZERO_INLINE unsigned int | ||
| 710 | stdc_first_trailing_zero_ui (unsigned int n) | ||
| 711 | { | ||
| 712 | unsigned int count = stdc_trailing_ones_ui (n); | ||
| 713 | unsigned int bits = 8 * sizeof n; | ||
| 714 | return count % bits + (count < bits); | ||
| 715 | } | ||
| 716 | |||
| 717 | _GL_STDC_FIRST_TRAILING_ZERO_INLINE unsigned int | ||
| 718 | stdc_first_trailing_zero_ul (unsigned long int n) | ||
| 719 | { | ||
| 720 | unsigned int count = stdc_trailing_ones_ul (n); | ||
| 721 | unsigned int bits = 8 * sizeof n; | ||
| 722 | return count % bits + (count < bits); | ||
| 723 | } | ||
| 724 | |||
| 725 | _GL_STDC_FIRST_TRAILING_ZERO_INLINE unsigned int | ||
| 726 | stdc_first_trailing_zero_ull (unsigned long long int n) | ||
| 727 | { | ||
| 728 | unsigned int count = stdc_trailing_ones_ull (n); | ||
| 729 | unsigned int bits = 8 * sizeof n; | ||
| 730 | return count % bits + (count < bits); | ||
| 731 | } | ||
| 732 | |||
| 733 | # define stdc_first_trailing_zero(n) \ | ||
| 734 | (sizeof (n) == 1 ? stdc_first_trailing_zero_uc (n) \ | ||
| 735 | : sizeof (n) == sizeof (unsigned short) ? stdc_first_trailing_zero_us (n) \ | ||
| 736 | : sizeof (n) == sizeof 0u ? stdc_first_trailing_zero_ui (n) \ | ||
| 737 | : sizeof (n) == sizeof 0ul ? stdc_first_trailing_zero_ul (n) \ | ||
| 738 | : stdc_first_trailing_zero_ull (n)) | ||
| 739 | |||
| 740 | #endif | ||
| 741 | |||
| 742 | |||
| 743 | /* ISO C 23 § 7.18.10 First Trailing One */ | ||
| 744 | |||
| 745 | #if @GL_STDC_FIRST_TRAILING_ONE@ | ||
| 746 | |||
| 747 | _GL_STDC_FIRST_TRAILING_ONE_INLINE unsigned int | ||
| 748 | stdc_first_trailing_one_uc (unsigned char n) | ||
| 749 | { | ||
| 750 | unsigned int count = stdc_trailing_zeros_uc (n); | ||
| 751 | unsigned int bits = 8 * sizeof n; | ||
| 752 | return count % bits + (count < bits); | ||
| 753 | } | ||
| 754 | |||
| 755 | _GL_STDC_FIRST_TRAILING_ONE_INLINE unsigned int | ||
| 756 | stdc_first_trailing_one_us (unsigned short int n) | ||
| 757 | { | ||
| 758 | unsigned int count = stdc_trailing_zeros_us (n); | ||
| 759 | unsigned int bits = 8 * sizeof n; | ||
| 760 | return count % bits + (count < bits); | ||
| 761 | } | ||
| 762 | |||
| 763 | _GL_STDC_FIRST_TRAILING_ONE_INLINE unsigned int | ||
| 764 | stdc_first_trailing_one_ui (unsigned int n) | ||
| 765 | { | ||
| 766 | unsigned int count = stdc_trailing_zeros_ui (n); | ||
| 767 | unsigned int bits = 8 * sizeof n; | ||
| 768 | return count % bits + (count < bits); | ||
| 769 | } | ||
| 770 | |||
| 771 | _GL_STDC_FIRST_TRAILING_ONE_INLINE unsigned int | ||
| 772 | stdc_first_trailing_one_ul (unsigned long int n) | ||
| 773 | { | ||
| 774 | unsigned int count = stdc_trailing_zeros_ul (n); | ||
| 775 | unsigned int bits = 8 * sizeof n; | ||
| 776 | return count % bits + (count < bits); | ||
| 777 | } | ||
| 778 | |||
| 779 | _GL_STDC_FIRST_TRAILING_ONE_INLINE unsigned int | ||
| 780 | stdc_first_trailing_one_ull (unsigned long long int n) | ||
| 781 | { | ||
| 782 | unsigned int count = stdc_trailing_zeros_ull (n); | ||
| 783 | unsigned int bits = 8 * sizeof n; | ||
| 784 | return count % bits + (count < bits); | ||
| 785 | } | ||
| 786 | |||
| 787 | #define stdc_first_trailing_one(n) \ | ||
| 788 | (sizeof (n) == 1 ? stdc_first_trailing_one_uc (n) \ | ||
| 789 | : sizeof (n) == sizeof (unsigned short) ? stdc_first_trailing_one_us (n) \ | ||
| 790 | : sizeof (n) == sizeof 0u ? stdc_first_trailing_one_ui (n) \ | ||
| 791 | : sizeof (n) == sizeof 0ul ? stdc_first_trailing_one_ul (n) \ | ||
| 792 | : stdc_first_trailing_one_ull (n)) | ||
| 793 | |||
| 794 | #endif | ||
| 795 | |||
| 796 | |||
| 797 | /* ISO C 23 § 7.18.12 Count Ones */ | ||
| 798 | |||
| 799 | #if @GL_STDC_COUNT_ONES@ | ||
| 800 | |||
| 801 | _GL_STDC_COUNT_ONES_INLINE unsigned int | ||
| 802 | stdc_count_ones_ui (unsigned int n) | ||
| 803 | { | ||
| 804 | return __gl_stdbit_popcount (n); | ||
| 805 | } | ||
| 806 | |||
| 807 | _GL_STDC_COUNT_ONES_INLINE unsigned int | ||
| 808 | stdc_count_ones_uc (unsigned char n) | ||
| 809 | { | ||
| 810 | return stdc_count_ones_ui (n); | ||
| 811 | } | ||
| 812 | |||
| 813 | _GL_STDC_COUNT_ONES_INLINE unsigned int | ||
| 814 | stdc_count_ones_us (unsigned short int n) | ||
| 815 | { | ||
| 816 | return stdc_count_ones_ui (n); | ||
| 817 | } | ||
| 818 | |||
| 819 | _GL_STDC_COUNT_ONES_INLINE unsigned int | ||
| 820 | stdc_count_ones_ul (unsigned long int n) | ||
| 821 | { | ||
| 822 | return __gl_stdbit_popcountl (n); | ||
| 823 | } | ||
| 824 | |||
| 825 | _GL_STDC_COUNT_ONES_INLINE unsigned int | ||
| 826 | stdc_count_ones_ull (unsigned long long int n) | ||
| 827 | { | ||
| 828 | return __gl_stdbit_popcountll (n); | ||
| 829 | } | ||
| 830 | |||
| 831 | # define stdc_count_ones(n) \ | ||
| 832 | (sizeof (n) == 1 ? stdc_count_ones_uc (n) \ | ||
| 833 | : sizeof (n) == sizeof (unsigned short int) ? stdc_count_ones_us (n) \ | ||
| 834 | : sizeof (n) == sizeof 0u ? stdc_count_ones_ui (n) \ | ||
| 835 | : sizeof (n) == sizeof 0ul ? stdc_count_ones_ul (n) \ | ||
| 836 | : stdc_count_ones_ull (n)) | ||
| 837 | |||
| 838 | #endif | ||
| 839 | |||
| 840 | |||
| 841 | /* ISO C 23 § 7.18.11 Count Zeros */ | ||
| 842 | |||
| 843 | #if @GL_STDC_COUNT_ZEROS@ | ||
| 844 | |||
| 845 | _GL_STDC_COUNT_ZEROS_INLINE unsigned int | ||
| 846 | stdc_count_zeros_uc (unsigned char n) | ||
| 847 | { | ||
| 848 | return stdc_count_ones_uc (~n); | ||
| 849 | } | ||
| 850 | |||
| 851 | _GL_STDC_COUNT_ZEROS_INLINE unsigned int | ||
| 852 | stdc_count_zeros_us (unsigned short int n) | ||
| 853 | { | ||
| 854 | return stdc_count_ones_us (~n); | ||
| 855 | } | ||
| 856 | |||
| 857 | _GL_STDC_COUNT_ZEROS_INLINE unsigned int | ||
| 858 | stdc_count_zeros_ui (unsigned int n) | ||
| 859 | { | ||
| 860 | return stdc_count_ones_ui (~n); | ||
| 861 | } | ||
| 862 | |||
| 863 | _GL_STDC_COUNT_ZEROS_INLINE unsigned int | ||
| 864 | stdc_count_zeros_ul (unsigned long int n) | ||
| 865 | { | ||
| 866 | return stdc_count_ones_ul (~n); | ||
| 867 | } | ||
| 868 | |||
| 869 | _GL_STDC_COUNT_ZEROS_INLINE unsigned int | ||
| 870 | stdc_count_zeros_ull (unsigned long long int n) | ||
| 871 | { | ||
| 872 | return stdc_count_ones_ull (~n); | ||
| 873 | } | ||
| 874 | |||
| 875 | # define stdc_count_zeros(n) \ | ||
| 876 | (sizeof (n) == 1 ? stdc_count_zeros_uc (n) \ | ||
| 877 | : sizeof (n) == sizeof (unsigned short int) ? stdc_count_zeros_us (n) \ | ||
| 878 | : sizeof (n) == sizeof 0u ? stdc_count_zeros_ui (n) \ | ||
| 879 | : sizeof (n) == sizeof 0ul ? stdc_count_zeros_ul (n) \ | ||
| 880 | : stdc_count_zeros_ull (n)) | ||
| 881 | |||
| 882 | #endif | ||
| 883 | |||
| 884 | |||
| 885 | /* ISO C 23 § 7.18.13 Single-bit Check */ | ||
| 886 | |||
| 887 | #if @GL_STDC_HAS_SINGLE_BIT@ | ||
| 888 | |||
| 889 | _GL_STDC_HAS_SINGLE_BIT_INLINE bool | ||
| 890 | stdc_has_single_bit_uc (unsigned char n) | ||
| 891 | { | ||
| 892 | unsigned char n_1 = n - 1, nx = n_1 ^ n; | ||
| 893 | return n_1 < nx; | ||
| 894 | } | ||
| 895 | |||
| 896 | _GL_STDC_HAS_SINGLE_BIT_INLINE bool | ||
| 897 | stdc_has_single_bit_us (unsigned short int n) | ||
| 898 | { | ||
| 899 | unsigned short int n_1 = n - 1, nx = n_1 ^ n; | ||
| 900 | return n_1 < nx; | ||
| 901 | } | ||
| 902 | |||
| 903 | _GL_STDC_HAS_SINGLE_BIT_INLINE bool | ||
| 904 | stdc_has_single_bit_ui (unsigned int n) | ||
| 905 | { | ||
| 906 | unsigned int n_1 = n - 1, nx = n_1 ^ n; | ||
| 907 | return n_1 < nx; | ||
| 908 | } | ||
| 909 | |||
| 910 | _GL_STDC_HAS_SINGLE_BIT_INLINE bool | ||
| 911 | stdc_has_single_bit_ul (unsigned long int n) | ||
| 912 | { | ||
| 913 | unsigned long int n_1 = n - 1, nx = n_1 ^ n; | ||
| 914 | return n_1 < nx; | ||
| 915 | } | ||
| 916 | |||
| 917 | _GL_STDC_HAS_SINGLE_BIT_INLINE bool | ||
| 918 | stdc_has_single_bit_ull (unsigned long long int n) | ||
| 919 | { | ||
| 920 | unsigned long long int n_1 = n - 1, nx = n_1 ^ n; | ||
| 921 | return n_1 < nx; | ||
| 922 | } | ||
| 923 | |||
| 924 | # define stdc_has_single_bit(n) \ | ||
| 925 | ((bool) \ | ||
| 926 | (sizeof (n) == 1 ? stdc_has_single_bit_uc (n) \ | ||
| 927 | : sizeof (n) == sizeof (unsigned short int) ? stdc_has_single_bit_us (n) \ | ||
| 928 | : sizeof (n) == sizeof 0u ? stdc_has_single_bit_ui (n) \ | ||
| 929 | : sizeof (n) == sizeof 0ul ? stdc_has_single_bit_ul (n) \ | ||
| 930 | : stdc_has_single_bit_ull (n))) | ||
| 931 | |||
| 932 | #endif | ||
| 933 | |||
| 934 | |||
| 935 | /* ISO C 23 § 7.18.14 Bit Width */ | ||
| 936 | |||
| 937 | #if @GL_STDC_BIT_WIDTH@ | ||
| 938 | |||
| 939 | _GL_STDC_BIT_WIDTH_INLINE unsigned int | ||
| 940 | stdc_bit_width_uc (unsigned char n) | ||
| 941 | { | ||
| 942 | return 8 * sizeof n - stdc_leading_zeros_uc (n); | ||
| 943 | } | ||
| 944 | |||
| 945 | _GL_STDC_BIT_WIDTH_INLINE unsigned int | ||
| 946 | stdc_bit_width_us (unsigned short int n) | ||
| 947 | { | ||
| 948 | return 8 * sizeof n - stdc_leading_zeros_us (n); | ||
| 949 | } | ||
| 950 | |||
| 951 | _GL_STDC_BIT_WIDTH_INLINE unsigned int | ||
| 952 | stdc_bit_width_ui (unsigned int n) | ||
| 953 | { | ||
| 954 | return 8 * sizeof n - stdc_leading_zeros_ui (n); | ||
| 955 | } | ||
| 956 | |||
| 957 | _GL_STDC_BIT_WIDTH_INLINE unsigned int | ||
| 958 | stdc_bit_width_ul (unsigned long int n) | ||
| 959 | { | ||
| 960 | return 8 * sizeof n - stdc_leading_zeros_ul (n); | ||
| 961 | } | ||
| 962 | |||
| 963 | _GL_STDC_BIT_WIDTH_INLINE unsigned int | ||
| 964 | stdc_bit_width_ull (unsigned long long int n) | ||
| 965 | { | ||
| 966 | return 8 * sizeof n - stdc_leading_zeros_ull (n); | ||
| 967 | } | ||
| 968 | |||
| 969 | # define stdc_bit_width(n) \ | ||
| 970 | (sizeof (n) == 1 ? stdc_bit_width_uc (n) \ | ||
| 971 | : sizeof (n) == sizeof (unsigned short int) ? stdc_bit_width_us (n) \ | ||
| 972 | : sizeof (n) == sizeof 0u ? stdc_bit_width_ui (n) \ | ||
| 973 | : sizeof (n) == sizeof 0ul ? stdc_bit_width_ul (n) \ | ||
| 974 | : stdc_bit_width_ull (n)) | ||
| 975 | |||
| 976 | #endif | ||
| 977 | |||
| 978 | |||
| 979 | /* ISO C 23 § 7.18.15 Bit Floor */ | ||
| 980 | |||
| 981 | #if @GL_STDC_BIT_FLOOR@ | ||
| 982 | |||
| 983 | _GL_STDC_BIT_FLOOR_INLINE unsigned char | ||
| 984 | stdc_bit_floor_uc (unsigned char n) | ||
| 985 | { | ||
| 986 | return n ? 1u << (stdc_bit_width_uc (n) - 1) : 0; | ||
| 987 | } | ||
| 988 | |||
| 989 | _GL_STDC_BIT_FLOOR_INLINE unsigned short int | ||
| 990 | stdc_bit_floor_us (unsigned short int n) | ||
| 991 | { | ||
| 992 | return n ? 1u << (stdc_bit_width_us (n) - 1) : 0; | ||
| 993 | } | ||
| 994 | |||
| 995 | _GL_STDC_BIT_FLOOR_INLINE unsigned int | ||
| 996 | stdc_bit_floor_ui (unsigned int n) | ||
| 997 | { | ||
| 998 | return n ? 1u << (stdc_bit_width_ui (n) - 1) : 0; | ||
| 999 | } | ||
| 1000 | |||
| 1001 | _GL_STDC_BIT_FLOOR_INLINE unsigned long int | ||
| 1002 | stdc_bit_floor_ul (unsigned long int n) | ||
| 1003 | { | ||
| 1004 | return n ? 1ul << (stdc_bit_width_ul (n) - 1) : 0; | ||
| 1005 | } | ||
| 1006 | |||
| 1007 | _GL_STDC_BIT_FLOOR_INLINE unsigned long long int | ||
| 1008 | stdc_bit_floor_ull (unsigned long long int n) | ||
| 1009 | { | ||
| 1010 | return n ? 1ull << (stdc_bit_width_ull (n) - 1) : 0; | ||
| 1011 | } | ||
| 1012 | |||
| 1013 | # define stdc_bit_floor(n) \ | ||
| 1014 | (_GL_STDBIT_TYPEOF_CAST \ | ||
| 1015 | (n, \ | ||
| 1016 | (sizeof (n) == 1 ? stdc_bit_floor_uc (n) \ | ||
| 1017 | : sizeof (n) == sizeof (unsigned short int) ? stdc_bit_floor_us (n) \ | ||
| 1018 | : sizeof (n) == sizeof 0u ? stdc_bit_floor_ui (n) \ | ||
| 1019 | : sizeof (n) == sizeof 0ul ? stdc_bit_floor_ul (n) \ | ||
| 1020 | : stdc_bit_floor_ull (n)))) | ||
| 1021 | |||
| 1022 | #endif | ||
| 1023 | |||
| 1024 | |||
| 1025 | /* ISO C 23 § 7.18.16 Bit Ceiling */ | ||
| 1026 | |||
| 1027 | #if @GL_STDC_BIT_CEIL@ | ||
| 1028 | |||
| 1029 | _GL_STDC_BIT_CEIL_INLINE unsigned char | ||
| 1030 | stdc_bit_ceil_uc (unsigned char n) | ||
| 1031 | { | ||
| 1032 | return n <= 1 ? 1 : 2u << (stdc_bit_width_uc (n - 1) - 1); | ||
| 1033 | } | ||
| 1034 | |||
| 1035 | _GL_STDC_BIT_CEIL_INLINE unsigned short int | ||
| 1036 | stdc_bit_ceil_us (unsigned short int n) | ||
| 1037 | { | ||
| 1038 | return n <= 1 ? 1 : 2u << (stdc_bit_width_us (n - 1) - 1); | ||
| 1039 | } | ||
| 1040 | |||
| 1041 | _GL_STDC_BIT_CEIL_INLINE unsigned int | ||
| 1042 | stdc_bit_ceil_ui (unsigned int n) | ||
| 1043 | { | ||
| 1044 | return n <= 1 ? 1 : 2u << (stdc_bit_width_ui (n - 1) - 1); | ||
| 1045 | } | ||
| 1046 | |||
| 1047 | _GL_STDC_BIT_CEIL_INLINE unsigned long int | ||
| 1048 | stdc_bit_ceil_ul (unsigned long int n) | ||
| 1049 | { | ||
| 1050 | return n <= 1 ? 1 : 2ul << (stdc_bit_width_ul (n - 1) - 1); | ||
| 1051 | } | ||
| 1052 | |||
| 1053 | _GL_STDC_BIT_CEIL_INLINE unsigned long long int | ||
| 1054 | stdc_bit_ceil_ull (unsigned long long int n) | ||
| 1055 | { | ||
| 1056 | return n <= 1 ? 1 : 2ull << (stdc_bit_width_ull (n - 1) - 1); | ||
| 1057 | } | ||
| 1058 | |||
| 1059 | # define stdc_bit_ceil(n) \ | ||
| 1060 | (_GL_STDBIT_TYPEOF_CAST \ | ||
| 1061 | (n, \ | ||
| 1062 | (sizeof (n) == 1 ? stdc_bit_ceil_uc (n) \ | ||
| 1063 | : sizeof (n) == sizeof (unsigned short int) ? stdc_bit_ceil_us (n) \ | ||
| 1064 | : sizeof (n) == sizeof 0u ? stdc_bit_ceil_ui (n) \ | ||
| 1065 | : sizeof (n) == sizeof 0ul ? stdc_bit_ceil_ul (n) \ | ||
| 1066 | : stdc_bit_ceil_ull (n)))) | ||
| 1067 | |||
| 1068 | #endif | ||
| 1069 | |||
| 1070 | |||
| 1071 | #ifdef __cplusplus | ||
| 1072 | } | ||
| 1073 | #endif | ||
| 1074 | |||
| 1075 | _GL_INLINE_HEADER_END | ||
| 1076 | |||
| 1077 | #endif /* STDBIT_H */ | ||
diff --git a/lib/count-trailing-zeros.c b/lib/stdc_bit_width.c index e13f77788da..a0dc8de3b5f 100644 --- a/lib/count-trailing-zeros.c +++ b/lib/stdc_bit_width.c | |||
| @@ -1,6 +1,5 @@ | |||
| 1 | /* Count the number of trailing 0 bits in a word. | 1 | /* stdc_bit_width_* functions. |
| 2 | 2 | Copyright (C) 2024 Free Software Foundation, Inc. | |
| 3 | Copyright 2013-2024 Free Software Foundation, Inc. | ||
| 4 | 3 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
| @@ -17,5 +16,5 @@ | |||
| 17 | 16 | ||
| 18 | #include <config.h> | 17 | #include <config.h> |
| 19 | 18 | ||
| 20 | #define COUNT_TRAILING_ZEROS_INLINE _GL_EXTERN_INLINE | 19 | #define _GL_STDC_BIT_WIDTH_INLINE _GL_EXTERN_INLINE |
| 21 | #include "count-trailing-zeros.h" | 20 | #include <stdbit.h> |
diff --git a/lib/count-one-bits.c b/lib/stdc_count_ones.c index 54b87088028..7421178adf0 100644 --- a/lib/count-one-bits.c +++ b/lib/stdc_count_ones.c | |||
| @@ -1,6 +1,5 @@ | |||
| 1 | /* Count the number of 1-bits in a word. | 1 | /* stdc_count_ones_* functions. |
| 2 | 2 | Copyright (C) 2024 Free Software Foundation, Inc. | |
| 3 | Copyright (C) 2012-2024 Free Software Foundation, Inc. | ||
| 4 | 3 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
| @@ -17,9 +16,9 @@ | |||
| 17 | 16 | ||
| 18 | #include <config.h> | 17 | #include <config.h> |
| 19 | 18 | ||
| 20 | #define COUNT_ONE_BITS_INLINE _GL_EXTERN_INLINE | 19 | #define _GL_STDC_COUNT_ONES_INLINE _GL_EXTERN_INLINE |
| 21 | #include "count-one-bits.h" | 20 | #include <stdbit.h> |
| 22 | 21 | ||
| 23 | #if 1500 <= _MSC_VER && (defined _M_IX86 || defined _M_X64) | 22 | #if 1500 <= _MSC_VER && (defined _M_IX86 || defined _M_X64) |
| 24 | int popcount_support = -1; | 23 | signed char __gl_stdbit_popcount_support; |
| 25 | #endif | 24 | #endif |
diff --git a/lib/count-leading-zeros.c b/lib/stdc_leading_zeros.c index 2bbfd674849..45695e51aa8 100644 --- a/lib/count-leading-zeros.c +++ b/lib/stdc_leading_zeros.c | |||
| @@ -1,6 +1,5 @@ | |||
| 1 | /* Count the number of leading 0 bits in a word. | 1 | /* stdc_leading_zeros_* functions. |
| 2 | 2 | Copyright (C) 2024 Free Software Foundation, Inc. | |
| 3 | Copyright (C) 2012-2024 Free Software Foundation, Inc. | ||
| 4 | 3 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
| @@ -17,5 +16,5 @@ | |||
| 17 | 16 | ||
| 18 | #include <config.h> | 17 | #include <config.h> |
| 19 | 18 | ||
| 20 | #define COUNT_LEADING_ZEROS_INLINE _GL_EXTERN_INLINE | 19 | #define _GL_STDC_LEADING_ZEROS_INLINE _GL_EXTERN_INLINE |
| 21 | #include "count-leading-zeros.h" | 20 | #include <stdbit.h> |
diff --git a/lib/stdc_trailing_zeros.c b/lib/stdc_trailing_zeros.c new file mode 100644 index 00000000000..f4bc43ac6ba --- /dev/null +++ b/lib/stdc_trailing_zeros.c | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | /* stdc_trailing_zeros_* functions. | ||
| 2 | Copyright (C) 2024 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU Lesser General Public License as | ||
| 6 | published by the Free Software Foundation; either version 2.1 of the | ||
| 7 | License, or (at your option) any later version. | ||
| 8 | |||
| 9 | This file is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU Lesser General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU Lesser General Public License | ||
| 15 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | #include <config.h> | ||
| 18 | |||
| 19 | #define _GL_STDC_TRAILING_ZEROS_INLINE _GL_EXTERN_INLINE | ||
| 20 | #include <stdbit.h> | ||
diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4 index 61040987b57..4dd1e68d15c 100644 --- a/m4/gnulib-comp.m4 +++ b/m4/gnulib-comp.m4 | |||
| @@ -63,9 +63,6 @@ AC_DEFUN([gl_EARLY], | |||
| 63 | # Code from module cloexec: | 63 | # Code from module cloexec: |
| 64 | # Code from module close-stream: | 64 | # Code from module close-stream: |
| 65 | # Code from module copy-file-range: | 65 | # Code from module copy-file-range: |
| 66 | # Code from module count-leading-zeros: | ||
| 67 | # Code from module count-one-bits: | ||
| 68 | # Code from module count-trailing-zeros: | ||
| 69 | # Code from module crypto/md5: | 66 | # Code from module crypto/md5: |
| 70 | # Code from module crypto/md5-buffer: | 67 | # Code from module crypto/md5-buffer: |
| 71 | # Code from module crypto/sha1-buffer: | 68 | # Code from module crypto/sha1-buffer: |
| @@ -174,7 +171,12 @@ AC_DEFUN([gl_EARLY], | |||
| 174 | # Code from module ssize_t: | 171 | # Code from module ssize_t: |
| 175 | # Code from module stat-time: | 172 | # Code from module stat-time: |
| 176 | # Code from module std-gnu11: | 173 | # Code from module std-gnu11: |
| 174 | # Code from module stdbit-h: | ||
| 177 | # Code from module stdbool: | 175 | # Code from module stdbool: |
| 176 | # Code from module stdc_bit_width: | ||
| 177 | # Code from module stdc_count_ones: | ||
| 178 | # Code from module stdc_leading_zeros: | ||
| 179 | # Code from module stdc_trailing_zeros: | ||
| 178 | # Code from module stdckdint: | 180 | # Code from module stdckdint: |
| 179 | # Code from module stddef: | 181 | # Code from module stddef: |
| 180 | # Code from module stdint: | 182 | # Code from module stdint: |
| @@ -514,7 +516,18 @@ AC_DEFUN([gl_INIT], | |||
| 514 | gt_TYPE_SSIZE_T | 516 | gt_TYPE_SSIZE_T |
| 515 | gl_STAT_TIME | 517 | gl_STAT_TIME |
| 516 | gl_STAT_BIRTHTIME | 518 | gl_STAT_BIRTHTIME |
| 519 | gl_STDBIT_H | ||
| 520 | gl_CONDITIONAL_HEADER([stdbit.h]) | ||
| 521 | AC_PROG_MKDIR_P | ||
| 517 | gl_C_BOOL | 522 | gl_C_BOOL |
| 523 | AC_REQUIRE([gl_STDBIT_H]) | ||
| 524 | GL_STDC_BIT_WIDTH=1 | ||
| 525 | AC_REQUIRE([gl_STDBIT_H]) | ||
| 526 | GL_STDC_COUNT_ONES=1 | ||
| 527 | AC_REQUIRE([gl_STDBIT_H]) | ||
| 528 | GL_STDC_LEADING_ZEROS=1 | ||
| 529 | AC_REQUIRE([gl_STDBIT_H]) | ||
| 530 | GL_STDC_TRAILING_ZEROS=1 | ||
| 518 | AC_CHECK_HEADERS_ONCE([stdckdint.h]) | 531 | AC_CHECK_HEADERS_ONCE([stdckdint.h]) |
| 519 | if test $ac_cv_header_stdckdint_h = yes; then | 532 | if test $ac_cv_header_stdckdint_h = yes; then |
| 520 | GL_GENERATE_STDCKDINT_H=false | 533 | GL_GENERATE_STDCKDINT_H=false |
| @@ -673,6 +686,7 @@ AC_DEFUN([gl_INIT], | |||
| 673 | gl_gnulib_enabled_6099e9737f757db36c47fa9d9f02e88c=false | 686 | gl_gnulib_enabled_6099e9737f757db36c47fa9d9f02e88c=false |
| 674 | gl_gnulib_enabled_strtoll=false | 687 | gl_gnulib_enabled_strtoll=false |
| 675 | gl_gnulib_enabled_utimens=false | 688 | gl_gnulib_enabled_utimens=false |
| 689 | gl_gnulib_enabled_verify=false | ||
| 676 | gl_gnulib_enabled_682e609604ccaac6be382e4ee3a4eaec=false | 690 | gl_gnulib_enabled_682e609604ccaac6be382e4ee3a4eaec=false |
| 677 | func_gl_gnulib_m4code_260941c0e5dc67ec9e87d1fb321c300b () | 691 | func_gl_gnulib_m4code_260941c0e5dc67ec9e87d1fb321c300b () |
| 678 | { | 692 | { |
| @@ -953,6 +967,12 @@ AC_DEFUN([gl_INIT], | |||
| 953 | gl_gnulib_enabled_utimens=true | 967 | gl_gnulib_enabled_utimens=true |
| 954 | fi | 968 | fi |
| 955 | } | 969 | } |
| 970 | func_gl_gnulib_m4code_verify () | ||
| 971 | { | ||
| 972 | if $gl_gnulib_enabled_verify; then :; else | ||
| 973 | gl_gnulib_enabled_verify=true | ||
| 974 | fi | ||
| 975 | } | ||
| 956 | func_gl_gnulib_m4code_682e609604ccaac6be382e4ee3a4eaec () | 976 | func_gl_gnulib_m4code_682e609604ccaac6be382e4ee3a4eaec () |
| 957 | { | 977 | { |
| 958 | if $gl_gnulib_enabled_682e609604ccaac6be382e4ee3a4eaec; then :; else | 978 | if $gl_gnulib_enabled_682e609604ccaac6be382e4ee3a4eaec; then :; else |
| @@ -1016,6 +1036,9 @@ AC_DEFUN([gl_INIT], | |||
| 1016 | if case $host_os in mingw* | windows*) false;; *) test $HAVE_GETRANDOM = 0 || test $REPLACE_GETRANDOM = 1;; esac; then | 1036 | if case $host_os in mingw* | windows*) false;; *) test $HAVE_GETRANDOM = 0 || test $REPLACE_GETRANDOM = 1;; esac; then |
| 1017 | func_gl_gnulib_m4code_open | 1037 | func_gl_gnulib_m4code_open |
| 1018 | fi | 1038 | fi |
| 1039 | if test $REPLACE_MKTIME = 1; then | ||
| 1040 | func_gl_gnulib_m4code_verify | ||
| 1041 | fi | ||
| 1019 | if test $HAVE_READLINKAT = 0 || test $REPLACE_READLINKAT = 1; then | 1042 | if test $HAVE_READLINKAT = 0 || test $REPLACE_READLINKAT = 1; then |
| 1020 | func_gl_gnulib_m4code_260941c0e5dc67ec9e87d1fb321c300b | 1043 | func_gl_gnulib_m4code_260941c0e5dc67ec9e87d1fb321c300b |
| 1021 | fi | 1044 | fi |
| @@ -1025,6 +1048,9 @@ AC_DEFUN([gl_INIT], | |||
| 1025 | if test $ac_use_included_regex = yes; then | 1048 | if test $ac_use_included_regex = yes; then |
| 1026 | func_gl_gnulib_m4code_fd38c7e463b54744b77b98aeafb4fa7c | 1049 | func_gl_gnulib_m4code_fd38c7e463b54744b77b98aeafb4fa7c |
| 1027 | fi | 1050 | fi |
| 1051 | if test $ac_use_included_regex = yes; then | ||
| 1052 | func_gl_gnulib_m4code_verify | ||
| 1053 | fi | ||
| 1028 | if test $HAVE_DECL_STRTOIMAX = 0 || test $REPLACE_STRTOIMAX = 1; then | 1054 | if test $HAVE_DECL_STRTOIMAX = 0 || test $REPLACE_STRTOIMAX = 1; then |
| 1029 | func_gl_gnulib_m4code_strtoll | 1055 | func_gl_gnulib_m4code_strtoll |
| 1030 | fi | 1056 | fi |
| @@ -1065,6 +1091,7 @@ AC_DEFUN([gl_INIT], | |||
| 1065 | AM_CONDITIONAL([gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c], [$gl_gnulib_enabled_6099e9737f757db36c47fa9d9f02e88c]) | 1091 | AM_CONDITIONAL([gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c], [$gl_gnulib_enabled_6099e9737f757db36c47fa9d9f02e88c]) |
| 1066 | AM_CONDITIONAL([gl_GNULIB_ENABLED_strtoll], [$gl_gnulib_enabled_strtoll]) | 1092 | AM_CONDITIONAL([gl_GNULIB_ENABLED_strtoll], [$gl_gnulib_enabled_strtoll]) |
| 1067 | AM_CONDITIONAL([gl_GNULIB_ENABLED_utimens], [$gl_gnulib_enabled_utimens]) | 1093 | AM_CONDITIONAL([gl_GNULIB_ENABLED_utimens], [$gl_gnulib_enabled_utimens]) |
| 1094 | AM_CONDITIONAL([gl_GNULIB_ENABLED_verify], [$gl_gnulib_enabled_verify]) | ||
| 1068 | AM_CONDITIONAL([gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec], [$gl_gnulib_enabled_682e609604ccaac6be382e4ee3a4eaec]) | 1095 | AM_CONDITIONAL([gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec], [$gl_gnulib_enabled_682e609604ccaac6be382e4ee3a4eaec]) |
| 1069 | # End of code from modules | 1096 | # End of code from modules |
| 1070 | m4_ifval(gl_LIBSOURCES_LIST, [ | 1097 | m4_ifval(gl_LIBSOURCES_LIST, [ |
| @@ -1276,12 +1303,6 @@ AC_DEFUN([gl_FILE_LIST], [ | |||
| 1276 | lib/close-stream.c | 1303 | lib/close-stream.c |
| 1277 | lib/close-stream.h | 1304 | lib/close-stream.h |
| 1278 | lib/copy-file-range.c | 1305 | lib/copy-file-range.c |
| 1279 | lib/count-leading-zeros.c | ||
| 1280 | lib/count-leading-zeros.h | ||
| 1281 | lib/count-one-bits.c | ||
| 1282 | lib/count-one-bits.h | ||
| 1283 | lib/count-trailing-zeros.c | ||
| 1284 | lib/count-trailing-zeros.h | ||
| 1285 | lib/diffseq.h | 1306 | lib/diffseq.h |
| 1286 | lib/dirent-private.h | 1307 | lib/dirent-private.h |
| 1287 | lib/dirent.in.h | 1308 | lib/dirent.in.h |
| @@ -1414,6 +1435,12 @@ AC_DEFUN([gl_FILE_LIST], [ | |||
| 1414 | lib/signal.in.h | 1435 | lib/signal.in.h |
| 1415 | lib/stat-time.c | 1436 | lib/stat-time.c |
| 1416 | lib/stat-time.h | 1437 | lib/stat-time.h |
| 1438 | lib/stdbit.c | ||
| 1439 | lib/stdbit.in.h | ||
| 1440 | lib/stdc_bit_width.c | ||
| 1441 | lib/stdc_count_ones.c | ||
| 1442 | lib/stdc_leading_zeros.c | ||
| 1443 | lib/stdc_trailing_zeros.c | ||
| 1417 | lib/stdckdint.in.h | 1444 | lib/stdckdint.in.h |
| 1418 | lib/stddef.in.h | 1445 | lib/stddef.in.h |
| 1419 | lib/stdint.in.h | 1446 | lib/stdint.in.h |
| @@ -1567,6 +1594,7 @@ AC_DEFUN([gl_FILE_LIST], [ | |||
| 1567 | m4/stat-time.m4 | 1594 | m4/stat-time.m4 |
| 1568 | m4/std-gnu11.m4 | 1595 | m4/std-gnu11.m4 |
| 1569 | m4/stdalign.m4 | 1596 | m4/stdalign.m4 |
| 1597 | m4/stdbit_h.m4 | ||
| 1570 | m4/stddef_h.m4 | 1598 | m4/stddef_h.m4 |
| 1571 | m4/stdint.m4 | 1599 | m4/stdint.m4 |
| 1572 | m4/stdio_h.m4 | 1600 | m4/stdio_h.m4 |
diff --git a/m4/stdbit_h.m4 b/m4/stdbit_h.m4 new file mode 100644 index 00000000000..6af813f39dc --- /dev/null +++ b/m4/stdbit_h.m4 | |||
| @@ -0,0 +1,37 @@ | |||
| 1 | # stdbit_h.m4 | ||
| 2 | # serial 2 | ||
| 3 | dnl Copyright 2024 Free Software Foundation, Inc. | ||
| 4 | dnl This file is free software; the Free Software Foundation | ||
| 5 | dnl gives unlimited permission to copy and/or distribute it, | ||
| 6 | dnl with or without modifications, as long as this notice is preserved. | ||
| 7 | |||
| 8 | dnl A placeholder for <stdbit.h>, for platforms that have issues. | ||
| 9 | |||
| 10 | AC_DEFUN_ONCE([gl_STDBIT_H], | ||
| 11 | [ | ||
| 12 | AC_REQUIRE([gl_BIGENDIAN]) | ||
| 13 | |||
| 14 | AC_CHECK_HEADERS_ONCE([stdbit.h]) | ||
| 15 | if test $ac_cv_header_stdbit_h = yes; then | ||
| 16 | GL_GENERATE_STDBIT_H=false | ||
| 17 | else | ||
| 18 | GL_GENERATE_STDBIT_H=true | ||
| 19 | fi | ||
| 20 | |||
| 21 | dnl We don't use gl_MODULE_INDICATOR_INIT_VARIABLE here, because stdbit.in.h | ||
| 22 | dnl does not use #include_next. | ||
| 23 | GL_STDC_LEADING_ZEROS=0; AC_SUBST([GL_STDC_LEADING_ZEROS]) | ||
| 24 | GL_STDC_LEADING_ONES=0; AC_SUBST([GL_STDC_LEADING_ONES]) | ||
| 25 | GL_STDC_TRAILING_ZEROS=0; AC_SUBST([GL_STDC_TRAILING_ZEROS]) | ||
| 26 | GL_STDC_TRAILING_ONES=0; AC_SUBST([GL_STDC_TRAILING_ONES]) | ||
| 27 | GL_STDC_FIRST_LEADING_ZERO=0; AC_SUBST([GL_STDC_FIRST_LEADING_ZERO]) | ||
| 28 | GL_STDC_FIRST_LEADING_ONE=0; AC_SUBST([GL_STDC_FIRST_LEADING_ONE]) | ||
| 29 | GL_STDC_FIRST_TRAILING_ZERO=0; AC_SUBST([GL_STDC_FIRST_TRAILING_ZERO]) | ||
| 30 | GL_STDC_FIRST_TRAILING_ONE=0; AC_SUBST([GL_STDC_FIRST_TRAILING_ONE]) | ||
| 31 | GL_STDC_COUNT_ZEROS=0; AC_SUBST([GL_STDC_COUNT_ZEROS]) | ||
| 32 | GL_STDC_COUNT_ONES=0; AC_SUBST([GL_STDC_COUNT_ONES]) | ||
| 33 | GL_STDC_HAS_SINGLE_BIT=0; AC_SUBST([GL_STDC_HAS_SINGLE_BIT]) | ||
| 34 | GL_STDC_BIT_WIDTH=0; AC_SUBST([GL_STDC_BIT_WIDTH]) | ||
| 35 | GL_STDC_BIT_FLOOR=0; AC_SUBST([GL_STDC_BIT_FLOOR]) | ||
| 36 | GL_STDC_BIT_CEIL=0; AC_SUBST([GL_STDC_BIT_CEIL]) | ||
| 37 | ]) | ||
diff --git a/src/data.c b/src/data.c index ea611ad1abf..30d8eab7359 100644 --- a/src/data.c +++ b/src/data.c | |||
| @@ -23,8 +23,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 23 | #include <math.h> | 23 | #include <math.h> |
| 24 | #include <stdio.h> | 24 | #include <stdio.h> |
| 25 | 25 | ||
| 26 | #include <count-one-bits.h> | ||
| 27 | #include <count-trailing-zeros.h> | ||
| 28 | #include <intprops.h> | 26 | #include <intprops.h> |
| 29 | 27 | ||
| 30 | #include "lisp.h" | 28 | #include "lisp.h" |
| @@ -3500,12 +3498,8 @@ representation. */) | |||
| 3500 | } | 3498 | } |
| 3501 | 3499 | ||
| 3502 | eassume (FIXNUMP (value)); | 3500 | eassume (FIXNUMP (value)); |
| 3503 | EMACS_INT v = XFIXNUM (value) < 0 ? -1 - XFIXNUM (value) : XFIXNUM (value); | 3501 | EMACS_UINT v = XFIXNUM (value) < 0 ? -1 - XFIXNUM (value) : XFIXNUM (value); |
| 3504 | return make_fixnum (EMACS_UINT_WIDTH <= UINT_WIDTH | 3502 | return make_fixnum (stdc_count_ones (v)); |
| 3505 | ? count_one_bits (v) | ||
| 3506 | : EMACS_UINT_WIDTH <= ULONG_WIDTH | ||
| 3507 | ? count_one_bits_l (v) | ||
| 3508 | : count_one_bits_ll (v)); | ||
| 3509 | } | 3503 | } |
| 3510 | 3504 | ||
| 3511 | DEFUN ("ash", Fash, Sash, 2, 2, 0, | 3505 | DEFUN ("ash", Fash, Sash, 2, 2, 0, |
| @@ -3662,36 +3656,6 @@ bool_vector_spare_mask (EMACS_INT nr_bits) | |||
| 3662 | return (((bits_word) 1) << (nr_bits % BITS_PER_BITS_WORD)) - 1; | 3656 | return (((bits_word) 1) << (nr_bits % BITS_PER_BITS_WORD)) - 1; |
| 3663 | } | 3657 | } |
| 3664 | 3658 | ||
| 3665 | /* Shift VAL right by the width of an unsigned long long. | ||
| 3666 | ULLONG_WIDTH must be less than BITS_PER_BITS_WORD. */ | ||
| 3667 | |||
| 3668 | static bits_word | ||
| 3669 | shift_right_ull (bits_word w) | ||
| 3670 | { | ||
| 3671 | /* Pacify bogus GCC warning about shift count exceeding type width. */ | ||
| 3672 | int shift = ULLONG_WIDTH - BITS_PER_BITS_WORD < 0 ? ULLONG_WIDTH : 0; | ||
| 3673 | return w >> shift; | ||
| 3674 | } | ||
| 3675 | |||
| 3676 | /* Return the number of 1 bits in W. */ | ||
| 3677 | |||
| 3678 | static int | ||
| 3679 | count_one_bits_word (bits_word w) | ||
| 3680 | { | ||
| 3681 | if (BITS_WORD_MAX <= UINT_MAX) | ||
| 3682 | return count_one_bits (w); | ||
| 3683 | else if (BITS_WORD_MAX <= ULONG_MAX) | ||
| 3684 | return count_one_bits_l (w); | ||
| 3685 | else | ||
| 3686 | { | ||
| 3687 | int i = 0, count = 0; | ||
| 3688 | while (count += count_one_bits_ll (w), | ||
| 3689 | (i += ULLONG_WIDTH) < BITS_PER_BITS_WORD) | ||
| 3690 | w = shift_right_ull (w); | ||
| 3691 | return count; | ||
| 3692 | } | ||
| 3693 | } | ||
| 3694 | |||
| 3695 | enum bool_vector_op { bool_vector_exclusive_or, | 3659 | enum bool_vector_op { bool_vector_exclusive_or, |
| 3696 | bool_vector_union, | 3660 | bool_vector_union, |
| 3697 | bool_vector_intersection, | 3661 | bool_vector_intersection, |
| @@ -3798,55 +3762,6 @@ bool_vector_binop_driver (Lisp_Object a, | |||
| 3798 | return dest; | 3762 | return dest; |
| 3799 | } | 3763 | } |
| 3800 | 3764 | ||
| 3801 | /* PRECONDITION must be true. Return VALUE. This odd construction | ||
| 3802 | works around a bogus GCC diagnostic "shift count >= width of type". */ | ||
| 3803 | |||
| 3804 | static int | ||
| 3805 | pre_value (bool precondition, int value) | ||
| 3806 | { | ||
| 3807 | eassume (precondition); | ||
| 3808 | return precondition ? value : 0; | ||
| 3809 | } | ||
| 3810 | |||
| 3811 | /* Compute the number of trailing zero bits in val. If val is zero, | ||
| 3812 | return the number of bits in val. */ | ||
| 3813 | static int | ||
| 3814 | count_trailing_zero_bits (bits_word val) | ||
| 3815 | { | ||
| 3816 | if (BITS_WORD_MAX == UINT_MAX) | ||
| 3817 | return count_trailing_zeros (val); | ||
| 3818 | if (BITS_WORD_MAX == ULONG_MAX) | ||
| 3819 | return count_trailing_zeros_l (val); | ||
| 3820 | if (BITS_WORD_MAX == ULLONG_MAX) | ||
| 3821 | return count_trailing_zeros_ll (val); | ||
| 3822 | |||
| 3823 | /* The rest of this code is for the unlikely platform where bits_word differs | ||
| 3824 | in width from unsigned int, unsigned long, and unsigned long long. */ | ||
| 3825 | val |= ~ BITS_WORD_MAX; | ||
| 3826 | if (BITS_WORD_MAX <= UINT_MAX) | ||
| 3827 | return count_trailing_zeros (val); | ||
| 3828 | if (BITS_WORD_MAX <= ULONG_MAX) | ||
| 3829 | return count_trailing_zeros_l (val); | ||
| 3830 | else | ||
| 3831 | { | ||
| 3832 | int count; | ||
| 3833 | for (count = 0; | ||
| 3834 | count < BITS_PER_BITS_WORD - ULLONG_WIDTH; | ||
| 3835 | count += ULLONG_WIDTH) | ||
| 3836 | { | ||
| 3837 | if (val & ULLONG_MAX) | ||
| 3838 | return count + count_trailing_zeros_ll (val); | ||
| 3839 | val = shift_right_ull (val); | ||
| 3840 | } | ||
| 3841 | |||
| 3842 | if (BITS_PER_BITS_WORD % ULLONG_WIDTH != 0 | ||
| 3843 | && BITS_WORD_MAX == (bits_word) -1) | ||
| 3844 | val |= (bits_word) 1 << pre_value (ULONG_MAX < BITS_WORD_MAX, | ||
| 3845 | BITS_PER_BITS_WORD % ULLONG_WIDTH); | ||
| 3846 | return count + count_trailing_zeros_ll (val); | ||
| 3847 | } | ||
| 3848 | } | ||
| 3849 | |||
| 3850 | DEFUN ("bool-vector-exclusive-or", Fbool_vector_exclusive_or, | 3765 | DEFUN ("bool-vector-exclusive-or", Fbool_vector_exclusive_or, |
| 3851 | Sbool_vector_exclusive_or, 2, 3, 0, | 3766 | Sbool_vector_exclusive_or, 2, 3, 0, |
| 3852 | doc: /* Return A ^ B, bitwise exclusive or. | 3767 | doc: /* Return A ^ B, bitwise exclusive or. |
| @@ -3961,7 +3876,7 @@ value from A's length. */) | |||
| 3961 | adata = bool_vector_data (a); | 3876 | adata = bool_vector_data (a); |
| 3962 | 3877 | ||
| 3963 | for (i = 0; i < nwords; i++) | 3878 | for (i = 0; i < nwords; i++) |
| 3964 | count += count_one_bits_word (adata[i]); | 3879 | count += stdc_count_ones (adata[i]); |
| 3965 | 3880 | ||
| 3966 | return make_fixnum (count); | 3881 | return make_fixnum (count); |
| 3967 | } | 3882 | } |
| @@ -4009,7 +3924,7 @@ A is a bool vector, B is t or nil, and I is an index into A. */) | |||
| 4009 | /* Do not count the pad bits. */ | 3924 | /* Do not count the pad bits. */ |
| 4010 | mword |= (bits_word) 1 << (BITS_PER_BITS_WORD - offset); | 3925 | mword |= (bits_word) 1 << (BITS_PER_BITS_WORD - offset); |
| 4011 | 3926 | ||
| 4012 | count = count_trailing_zero_bits (mword); | 3927 | count = stdc_trailing_zeros (mword); |
| 4013 | pos++; | 3928 | pos++; |
| 4014 | if (count + offset < BITS_PER_BITS_WORD) | 3929 | if (count + offset < BITS_PER_BITS_WORD) |
| 4015 | return make_fixnum (count); | 3930 | return make_fixnum (count); |
| @@ -4029,7 +3944,7 @@ A is a bool vector, B is t or nil, and I is an index into A. */) | |||
| 4029 | in the current mword. */ | 3944 | in the current mword. */ |
| 4030 | mword = bits_word_to_host_endian (adata[pos]); | 3945 | mword = bits_word_to_host_endian (adata[pos]); |
| 4031 | mword ^= twiddle; | 3946 | mword ^= twiddle; |
| 4032 | count += count_trailing_zero_bits (mword); | 3947 | count += stdc_trailing_zeros (mword); |
| 4033 | } | 3948 | } |
| 4034 | else if (nr_bits % BITS_PER_BITS_WORD != 0) | 3949 | else if (nr_bits % BITS_PER_BITS_WORD != 0) |
| 4035 | { | 3950 | { |
diff --git a/src/lisp.h b/src/lisp.h index 8ee37f5298a..d61a4d5c982 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -23,6 +23,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 23 | #include <alloca.h> | 23 | #include <alloca.h> |
| 24 | #include <setjmp.h> | 24 | #include <setjmp.h> |
| 25 | #include <stdarg.h> | 25 | #include <stdarg.h> |
| 26 | #include <stdbit.h> | ||
| 26 | #include <stdckdint.h> | 27 | #include <stdckdint.h> |
| 27 | #include <stddef.h> | 28 | #include <stddef.h> |
| 28 | #include <string.h> | 29 | #include <string.h> |
| @@ -37,7 +38,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 37 | 38 | ||
| 38 | #include <attribute.h> | 39 | #include <attribute.h> |
| 39 | #include <byteswap.h> | 40 | #include <byteswap.h> |
| 40 | #include <count-leading-zeros.h> | ||
| 41 | #include <intprops.h> | 41 | #include <intprops.h> |
| 42 | #include <verify.h> | 42 | #include <verify.h> |
| 43 | 43 | ||
| @@ -4148,11 +4148,12 @@ integer_to_uintmax (Lisp_Object num, uintmax_t *n) | |||
| 4148 | } | 4148 | } |
| 4149 | } | 4149 | } |
| 4150 | 4150 | ||
| 4151 | /* Return floor (log2 (N)) as an int, where 0 < N <= ULLONG_MAX. */ | 4151 | /* Return floor (log2 (N)) as an int. If N is zero, return -1. */ |
| 4152 | INLINE int | 4152 | INLINE int |
| 4153 | elogb (unsigned long long int n) | 4153 | elogb (unsigned long long int n) |
| 4154 | { | 4154 | { |
| 4155 | return ULLONG_WIDTH - 1 - count_leading_zeros_ll (n); | 4155 | int width = stdc_bit_width (n); |
| 4156 | return width - 1; | ||
| 4156 | } | 4157 | } |
| 4157 | 4158 | ||
| 4158 | /* A modification count. These are wide enough, and incremented | 4159 | /* A modification count. These are wide enough, and incremented |