aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert2024-05-12 14:22:58 -0700
committerPaul Eggert2024-05-18 10:23:51 -0700
commit88b0bb4db9aaecff8b01e81726b911fa5d02b2fb (patch)
tree8ac3e75bba0a9082a94e7c3a03cd8b590f07a97d
parent08550d058f028e0819ba6a72e9a53c0bc789257e (diff)
downloademacs-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.REPO2
-rwxr-xr-xadmin/merge-gnulib5
-rw-r--r--lib/count-leading-zeros.h140
-rw-r--r--lib/count-one-bits.h169
-rw-r--r--lib/count-trailing-zeros.h130
-rw-r--r--lib/gnulib.mk.in133
-rw-r--r--lib/stdbit.c23
-rw-r--r--lib/stdbit.in.h1077
-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.c20
-rw-r--r--m4/gnulib-comp.m446
-rw-r--r--m4/stdbit_h.m437
-rw-r--r--src/data.c95
-rw-r--r--src/lisp.h7
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'
80which will leave you with only files from the git repository. Here 80which will leave you with only files from the git repository. Here
81are some faster methods for a couple of particular error cases: 81are 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
85This can be fixed with 'rm aclocal.m4'. 85This 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
36extern "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
48extern unsigned char _BitScanReverse (unsigned long *, unsigned long);
49# pragma intrinsic (_BitScanReverse)
50# if defined _M_X64
51extern 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. */
83COUNT_LEADING_ZEROS_INLINE int
84count_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. */
103COUNT_LEADING_ZEROS_INLINE int
104count_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. */
110COUNT_LEADING_ZEROS_INLINE int
111count_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. */
117COUNT_LEADING_ZEROS_INLINE int
118count_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
36extern "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. */
51COUNT_ONE_BITS_INLINE int
52count_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. */
88extern void __cpuid (int[4], int);
89# pragma intrinsic (__cpuid)
90extern unsigned int __popcnt (unsigned int);
91# pragma intrinsic (__popcnt)
92# if defined _M_X64
93extern unsigned long long __popcnt64 (unsigned long long);
94# pragma intrinsic (__popcnt64)
95# endif
96# endif
97
98# if !defined _M_X64
99static 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. */
108extern int popcount_support;
109
110COUNT_ONE_BITS_INLINE int
111popcount_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. */
143COUNT_ONE_BITS_INLINE int
144count_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. */
150COUNT_ONE_BITS_INLINE int
151count_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. */
157COUNT_ONE_BITS_INLINE int
158count_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
36extern "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
48extern unsigned char _BitScanForward (unsigned long *, unsigned long);
49# pragma intrinsic (_BitScanForward)
50# if defined _M_X64
51extern 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. */
79COUNT_TRAILING_ZEROS_INLINE int
80count_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. */
93COUNT_TRAILING_ZEROS_INLINE int
94count_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. */
100COUNT_TRAILING_ZEROS_INLINE int
101count_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. */
107COUNT_TRAILING_ZEROS_INLINE int
108count_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@
358GL_GENERATE_IEEE754_H_CONDITION = @GL_GENERATE_IEEE754_H_CONDITION@ 358GL_GENERATE_IEEE754_H_CONDITION = @GL_GENERATE_IEEE754_H_CONDITION@
359GL_GENERATE_LIMITS_H_CONDITION = @GL_GENERATE_LIMITS_H_CONDITION@ 359GL_GENERATE_LIMITS_H_CONDITION = @GL_GENERATE_LIMITS_H_CONDITION@
360GL_GENERATE_MINI_GMP_H_CONDITION = @GL_GENERATE_MINI_GMP_H_CONDITION@ 360GL_GENERATE_MINI_GMP_H_CONDITION = @GL_GENERATE_MINI_GMP_H_CONDITION@
361GL_GENERATE_STDBIT_H_CONDITION = @GL_GENERATE_STDBIT_H_CONDITION@
361GL_GENERATE_STDCKDINT_H_CONDITION = @GL_GENERATE_STDCKDINT_H_CONDITION@ 362GL_GENERATE_STDCKDINT_H_CONDITION = @GL_GENERATE_STDCKDINT_H_CONDITION@
362GL_GENERATE_STDDEF_H_CONDITION = @GL_GENERATE_STDDEF_H_CONDITION@ 363GL_GENERATE_STDDEF_H_CONDITION = @GL_GENERATE_STDDEF_H_CONDITION@
363GL_GENERATE_STDINT_H_CONDITION = @GL_GENERATE_STDINT_H_CONDITION@ 364GL_GENERATE_STDINT_H_CONDITION = @GL_GENERATE_STDINT_H_CONDITION@
@@ -664,6 +665,20 @@ GL_GNULIB_VSPRINTF_POSIX = @GL_GNULIB_VSPRINTF_POSIX@
664GL_GNULIB_WCTOMB = @GL_GNULIB_WCTOMB@ 665GL_GNULIB_WCTOMB = @GL_GNULIB_WCTOMB@
665GL_GNULIB_WRITE = @GL_GNULIB_WRITE@ 666GL_GNULIB_WRITE = @GL_GNULIB_WRITE@
666GL_GNULIB__EXIT = @GL_GNULIB__EXIT@ 667GL_GNULIB__EXIT = @GL_GNULIB__EXIT@
668GL_STDC_BIT_CEIL = @GL_STDC_BIT_CEIL@
669GL_STDC_BIT_FLOOR = @GL_STDC_BIT_FLOOR@
670GL_STDC_BIT_WIDTH = @GL_STDC_BIT_WIDTH@
671GL_STDC_COUNT_ONES = @GL_STDC_COUNT_ONES@
672GL_STDC_COUNT_ZEROS = @GL_STDC_COUNT_ZEROS@
673GL_STDC_FIRST_LEADING_ONE = @GL_STDC_FIRST_LEADING_ONE@
674GL_STDC_FIRST_LEADING_ZERO = @GL_STDC_FIRST_LEADING_ZERO@
675GL_STDC_FIRST_TRAILING_ONE = @GL_STDC_FIRST_TRAILING_ONE@
676GL_STDC_FIRST_TRAILING_ZERO = @GL_STDC_FIRST_TRAILING_ZERO@
677GL_STDC_HAS_SINGLE_BIT = @GL_STDC_HAS_SINGLE_BIT@
678GL_STDC_LEADING_ONES = @GL_STDC_LEADING_ONES@
679GL_STDC_LEADING_ZEROS = @GL_STDC_LEADING_ZEROS@
680GL_STDC_TRAILING_ONES = @GL_STDC_TRAILING_ONES@
681GL_STDC_TRAILING_ZEROS = @GL_STDC_TRAILING_ZEROS@
667GMALLOC_OBJ = @GMALLOC_OBJ@ 682GMALLOC_OBJ = @GMALLOC_OBJ@
668GMP_H = @GMP_H@ 683GMP_H = @GMP_H@
669GNULIBHEADERS_OVERRIDE_WINT_T = @GNULIBHEADERS_OVERRIDE_WINT_T@ 684GNULIBHEADERS_OVERRIDE_WINT_T = @GNULIBHEADERS_OVERRIDE_WINT_T@
@@ -1315,6 +1330,7 @@ SIZE_T_SUFFIX = @SIZE_T_SUFFIX@
1315SMALL_JA_DIC = @SMALL_JA_DIC@ 1330SMALL_JA_DIC = @SMALL_JA_DIC@
1316SQLITE3_CFLAGS = @SQLITE3_CFLAGS@ 1331SQLITE3_CFLAGS = @SQLITE3_CFLAGS@
1317SQLITE3_LIBS = @SQLITE3_LIBS@ 1332SQLITE3_LIBS = @SQLITE3_LIBS@
1333STDBIT_H = @STDBIT_H@
1318STDCKDINT_H = @STDCKDINT_H@ 1334STDCKDINT_H = @STDCKDINT_H@
1319STDDEF_H = @STDDEF_H@ 1335STDDEF_H = @STDDEF_H@
1320STDDEF_NOT_IDEMPOTENT = @STDDEF_NOT_IDEMPOTENT@ 1336STDDEF_NOT_IDEMPOTENT = @STDDEF_NOT_IDEMPOTENT@
@@ -1444,6 +1460,7 @@ gl_GNULIB_ENABLED_open_CONDITION = @gl_GNULIB_ENABLED_open_CONDITION@
1444gl_GNULIB_ENABLED_rawmemchr_CONDITION = @gl_GNULIB_ENABLED_rawmemchr_CONDITION@ 1460gl_GNULIB_ENABLED_rawmemchr_CONDITION = @gl_GNULIB_ENABLED_rawmemchr_CONDITION@
1445gl_GNULIB_ENABLED_strtoll_CONDITION = @gl_GNULIB_ENABLED_strtoll_CONDITION@ 1461gl_GNULIB_ENABLED_strtoll_CONDITION = @gl_GNULIB_ENABLED_strtoll_CONDITION@
1446gl_GNULIB_ENABLED_utimens_CONDITION = @gl_GNULIB_ENABLED_utimens_CONDITION@ 1462gl_GNULIB_ENABLED_utimens_CONDITION = @gl_GNULIB_ENABLED_utimens_CONDITION@
1463gl_GNULIB_ENABLED_verify_CONDITION = @gl_GNULIB_ENABLED_verify_CONDITION@
1447gl_LIBOBJDEPS = @gl_LIBOBJDEPS@ 1464gl_LIBOBJDEPS = @gl_LIBOBJDEPS@
1448gl_LIBOBJS = @gl_LIBOBJS@ 1465gl_LIBOBJS = @gl_LIBOBJS@
1449gl_LTLIBOBJS = @gl_LTLIBOBJS@ 1466gl_LTLIBOBJS = @gl_LTLIBOBJS@
@@ -1721,36 +1738,6 @@ endif
1721endif 1738endif
1722## end gnulib module copy-file-range 1739## end gnulib module copy-file-range
1723 1740
1724## begin gnulib module count-leading-zeros
1725ifeq (,$(OMIT_GNULIB_MODULE_count-leading-zeros))
1726
1727libgnu_a_SOURCES += count-leading-zeros.c
1728
1729EXTRA_DIST += count-leading-zeros.h
1730
1731endif
1732## end gnulib module count-leading-zeros
1733
1734## begin gnulib module count-one-bits
1735ifeq (,$(OMIT_GNULIB_MODULE_count-one-bits))
1736
1737libgnu_a_SOURCES += count-one-bits.c
1738
1739EXTRA_DIST += count-one-bits.h
1740
1741endif
1742## end gnulib module count-one-bits
1743
1744## begin gnulib module count-trailing-zeros
1745ifeq (,$(OMIT_GNULIB_MODULE_count-trailing-zeros))
1746
1747libgnu_a_SOURCES += count-trailing-zeros.c
1748
1749EXTRA_DIST += count-trailing-zeros.h
1750
1751endif
1752## end gnulib module count-trailing-zeros
1753
1754## begin gnulib module crypto/md5 1741## begin gnulib module crypto/md5
1755ifeq (,$(OMIT_GNULIB_MODULE_crypto/md5)) 1742ifeq (,$(OMIT_GNULIB_MODULE_crypto/md5))
1756 1743
@@ -3052,6 +3039,84 @@ EXTRA_DIST += stat-time.h
3052endif 3039endif
3053## end gnulib module stat-time 3040## end gnulib module stat-time
3054 3041
3042## begin gnulib module stdbit-h
3043ifeq (,$(OMIT_GNULIB_MODULE_stdbit-h))
3044
3045BUILT_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.
3049ifneq (,$(GL_GENERATE_STDBIT_H_CONDITION))
3050stdbit.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 $@
3068libgnu_a_SOURCES += stdbit.c
3069else
3070stdbit.h: $(top_builddir)/config.status
3071 rm -f $@
3072endif
3073MOSTLYCLEANFILES += stdbit.h stdbit.h-t
3074
3075EXTRA_DIST += stdbit.in.h
3076
3077endif
3078## end gnulib module stdbit-h
3079
3080## begin gnulib module stdc_bit_width
3081ifeq (,$(OMIT_GNULIB_MODULE_stdc_bit_width))
3082
3083ifneq (,$(GL_GENERATE_STDBIT_H_CONDITION))
3084libgnu_a_SOURCES += stdc_bit_width.c
3085endif
3086
3087endif
3088## end gnulib module stdc_bit_width
3089
3090## begin gnulib module stdc_count_ones
3091ifeq (,$(OMIT_GNULIB_MODULE_stdc_count_ones))
3092
3093ifneq (,$(GL_GENERATE_STDBIT_H_CONDITION))
3094libgnu_a_SOURCES += stdc_count_ones.c
3095endif
3096
3097endif
3098## end gnulib module stdc_count_ones
3099
3100## begin gnulib module stdc_leading_zeros
3101ifeq (,$(OMIT_GNULIB_MODULE_stdc_leading_zeros))
3102
3103ifneq (,$(GL_GENERATE_STDBIT_H_CONDITION))
3104libgnu_a_SOURCES += stdc_leading_zeros.c
3105endif
3106
3107endif
3108## end gnulib module stdc_leading_zeros
3109
3110## begin gnulib module stdc_trailing_zeros
3111ifeq (,$(OMIT_GNULIB_MODULE_stdc_trailing_zeros))
3112
3113ifneq (,$(GL_GENERATE_STDBIT_H_CONDITION))
3114libgnu_a_SOURCES += stdc_trailing_zeros.c
3115endif
3116
3117endif
3118## end gnulib module stdc_trailing_zeros
3119
3055## begin gnulib module stdckdint 3120## begin gnulib module stdckdint
3056ifeq (,$(OMIT_GNULIB_MODULE_stdckdint)) 3121ifeq (,$(OMIT_GNULIB_MODULE_stdckdint))
3057 3122
@@ -4274,7 +4339,9 @@ endif
4274## begin gnulib module verify 4339## begin gnulib module verify
4275ifeq (,$(OMIT_GNULIB_MODULE_verify)) 4340ifeq (,$(OMIT_GNULIB_MODULE_verify))
4276 4341
4342ifneq (,$(gl_GNULIB_ENABLED_verify_CONDITION))
4277 4343
4344endif
4278EXTRA_DIST += verify.h 4345EXTRA_DIST += verify.h
4279 4346
4280endif 4347endif
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
109extern "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. */
155extern unsigned char _BitScanReverse (unsigned long *, unsigned long);
156# pragma intrinsic (_BitScanReverse)
157# ifdef _M_X64
158extern 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. */
234extern unsigned char _BitScanForward (unsigned long *, unsigned long);
235# pragma intrinsic (_BitScanForward)
236# ifdef _M_X64
237extern 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. */
341extern void __cpuid (int[4], int);
342# pragma intrinsic (__cpuid)
343extern unsigned int __popcnt (unsigned int);
344# pragma intrinsic (__popcnt)
345# ifdef _M_X64
346extern 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. */
358extern 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
410stdc_leading_zeros_ui (unsigned int n)
411{
412 return __gl_stdbit_clz (n);
413}
414
415_GL_STDC_LEADING_ZEROS_INLINE unsigned int
416stdc_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
422stdc_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
428stdc_leading_zeros_ul (unsigned long int n)
429{
430 return __gl_stdbit_clzl (n);
431}
432
433_GL_STDC_LEADING_ZEROS_INLINE unsigned int
434stdc_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
454stdc_leading_ones_uc (unsigned char n)
455{
456 return stdc_leading_zeros_uc (~n);
457}
458
459_GL_STDC_LEADING_ONES_INLINE unsigned int
460stdc_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
466stdc_leading_ones_ui (unsigned int n)
467{
468 return stdc_leading_zeros_ui (~n);
469}
470
471_GL_STDC_LEADING_ONES_INLINE unsigned int
472stdc_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
478stdc_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
498stdc_trailing_zeros_ui (unsigned int n)
499{
500 return __gl_stdbit_ctz (n);
501}
502
503_GL_STDC_TRAILING_ZEROS_INLINE unsigned int
504stdc_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
510stdc_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
516stdc_trailing_zeros_ul (unsigned long int n)
517{
518 return __gl_stdbit_ctzl (n);
519}
520
521_GL_STDC_TRAILING_ZEROS_INLINE unsigned int
522stdc_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
542stdc_trailing_ones_uc (unsigned char n)
543{
544 return stdc_trailing_zeros_uc (~n);
545}
546
547_GL_STDC_TRAILING_ONES_INLINE unsigned int
548stdc_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
554stdc_trailing_ones_ui (unsigned int n)
555{
556 return stdc_trailing_zeros_ui (~n);
557}
558
559_GL_STDC_TRAILING_ONES_INLINE unsigned int
560stdc_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
566stdc_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
586stdc_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
594stdc_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
602stdc_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
610stdc_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
618stdc_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
640stdc_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
648stdc_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
656stdc_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
664stdc_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
672stdc_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
694stdc_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
702stdc_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
710stdc_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
718stdc_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
726stdc_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
748stdc_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
756stdc_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
764stdc_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
772stdc_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
780stdc_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
802stdc_count_ones_ui (unsigned int n)
803{
804 return __gl_stdbit_popcount (n);
805}
806
807_GL_STDC_COUNT_ONES_INLINE unsigned int
808stdc_count_ones_uc (unsigned char n)
809{
810 return stdc_count_ones_ui (n);
811}
812
813_GL_STDC_COUNT_ONES_INLINE unsigned int
814stdc_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
820stdc_count_ones_ul (unsigned long int n)
821{
822 return __gl_stdbit_popcountl (n);
823}
824
825_GL_STDC_COUNT_ONES_INLINE unsigned int
826stdc_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
846stdc_count_zeros_uc (unsigned char n)
847{
848 return stdc_count_ones_uc (~n);
849}
850
851_GL_STDC_COUNT_ZEROS_INLINE unsigned int
852stdc_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
858stdc_count_zeros_ui (unsigned int n)
859{
860 return stdc_count_ones_ui (~n);
861}
862
863_GL_STDC_COUNT_ZEROS_INLINE unsigned int
864stdc_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
870stdc_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
890stdc_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
897stdc_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
904stdc_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
911stdc_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
918stdc_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
940stdc_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
946stdc_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
952stdc_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
958stdc_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
964stdc_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
984stdc_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
990stdc_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
996stdc_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
1002stdc_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
1008stdc_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
1030stdc_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
1036stdc_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
1042stdc_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
1048stdc_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
1054stdc_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)
24int popcount_support = -1; 23signed 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
3dnl Copyright 2024 Free Software Foundation, Inc.
4dnl This file is free software; the Free Software Foundation
5dnl gives unlimited permission to copy and/or distribute it,
6dnl with or without modifications, as long as this notice is preserved.
7
8dnl A placeholder for <stdbit.h>, for platforms that have issues.
9
10AC_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
3511DEFUN ("ash", Fash, Sash, 2, 2, 0, 3505DEFUN ("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
3668static bits_word
3669shift_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
3678static int
3679count_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
3695enum bool_vector_op { bool_vector_exclusive_or, 3659enum 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
3804static int
3805pre_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. */
3813static int
3814count_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
3850DEFUN ("bool-vector-exclusive-or", Fbool_vector_exclusive_or, 3765DEFUN ("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. */
4152INLINE int 4152INLINE int
4153elogb (unsigned long long int n) 4153elogb (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