diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2024-05-12 14:22:58 -0700 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2024-05-18 10:23:51 -0700 |
commit | 88b0bb4db9aaecff8b01e81726b911fa5d02b2fb (patch) | |
tree | 8ac3e75bba0a9082a94e7c3a03cd8b590f07a97d /src | |
parent | 08550d058f028e0819ba6a72e9a53c0bc789257e (diff) | |
download | emacs-88b0bb4db9aaecff8b01e81726b911fa5d02b2fb.tar.gz emacs-88b0bb4db9aaecff8b01e81726b911fa5d02b2fb.tar.bz2 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.
Diffstat (limited to 'src')
-rw-r--r-- | src/data.c | 95 | ||||
-rw-r--r-- | src/lisp.h | 7 |
2 files changed, 9 insertions, 93 deletions
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/>. */ #include <math.h> #include <stdio.h> -#include <count-one-bits.h> -#include <count-trailing-zeros.h> #include <intprops.h> #include "lisp.h" @@ -3500,12 +3498,8 @@ representation. */) } eassume (FIXNUMP (value)); - EMACS_INT v = XFIXNUM (value) < 0 ? -1 - XFIXNUM (value) : XFIXNUM (value); - return make_fixnum (EMACS_UINT_WIDTH <= UINT_WIDTH - ? count_one_bits (v) - : EMACS_UINT_WIDTH <= ULONG_WIDTH - ? count_one_bits_l (v) - : count_one_bits_ll (v)); + EMACS_UINT v = XFIXNUM (value) < 0 ? -1 - XFIXNUM (value) : XFIXNUM (value); + return make_fixnum (stdc_count_ones (v)); } DEFUN ("ash", Fash, Sash, 2, 2, 0, @@ -3662,36 +3656,6 @@ bool_vector_spare_mask (EMACS_INT nr_bits) return (((bits_word) 1) << (nr_bits % BITS_PER_BITS_WORD)) - 1; } -/* Shift VAL right by the width of an unsigned long long. - ULLONG_WIDTH must be less than BITS_PER_BITS_WORD. */ - -static bits_word -shift_right_ull (bits_word w) -{ - /* Pacify bogus GCC warning about shift count exceeding type width. */ - int shift = ULLONG_WIDTH - BITS_PER_BITS_WORD < 0 ? ULLONG_WIDTH : 0; - return w >> shift; -} - -/* Return the number of 1 bits in W. */ - -static int -count_one_bits_word (bits_word w) -{ - if (BITS_WORD_MAX <= UINT_MAX) - return count_one_bits (w); - else if (BITS_WORD_MAX <= ULONG_MAX) - return count_one_bits_l (w); - else - { - int i = 0, count = 0; - while (count += count_one_bits_ll (w), - (i += ULLONG_WIDTH) < BITS_PER_BITS_WORD) - w = shift_right_ull (w); - return count; - } -} - enum bool_vector_op { bool_vector_exclusive_or, bool_vector_union, bool_vector_intersection, @@ -3798,55 +3762,6 @@ bool_vector_binop_driver (Lisp_Object a, return dest; } -/* PRECONDITION must be true. Return VALUE. This odd construction - works around a bogus GCC diagnostic "shift count >= width of type". */ - -static int -pre_value (bool precondition, int value) -{ - eassume (precondition); - return precondition ? value : 0; -} - -/* Compute the number of trailing zero bits in val. If val is zero, - return the number of bits in val. */ -static int -count_trailing_zero_bits (bits_word val) -{ - if (BITS_WORD_MAX == UINT_MAX) - return count_trailing_zeros (val); - if (BITS_WORD_MAX == ULONG_MAX) - return count_trailing_zeros_l (val); - if (BITS_WORD_MAX == ULLONG_MAX) - return count_trailing_zeros_ll (val); - - /* The rest of this code is for the unlikely platform where bits_word differs - in width from unsigned int, unsigned long, and unsigned long long. */ - val |= ~ BITS_WORD_MAX; - if (BITS_WORD_MAX <= UINT_MAX) - return count_trailing_zeros (val); - if (BITS_WORD_MAX <= ULONG_MAX) - return count_trailing_zeros_l (val); - else - { - int count; - for (count = 0; - count < BITS_PER_BITS_WORD - ULLONG_WIDTH; - count += ULLONG_WIDTH) - { - if (val & ULLONG_MAX) - return count + count_trailing_zeros_ll (val); - val = shift_right_ull (val); - } - - if (BITS_PER_BITS_WORD % ULLONG_WIDTH != 0 - && BITS_WORD_MAX == (bits_word) -1) - val |= (bits_word) 1 << pre_value (ULONG_MAX < BITS_WORD_MAX, - BITS_PER_BITS_WORD % ULLONG_WIDTH); - return count + count_trailing_zeros_ll (val); - } -} - DEFUN ("bool-vector-exclusive-or", Fbool_vector_exclusive_or, Sbool_vector_exclusive_or, 2, 3, 0, doc: /* Return A ^ B, bitwise exclusive or. @@ -3961,7 +3876,7 @@ value from A's length. */) adata = bool_vector_data (a); for (i = 0; i < nwords; i++) - count += count_one_bits_word (adata[i]); + count += stdc_count_ones (adata[i]); return make_fixnum (count); } @@ -4009,7 +3924,7 @@ A is a bool vector, B is t or nil, and I is an index into A. */) /* Do not count the pad bits. */ mword |= (bits_word) 1 << (BITS_PER_BITS_WORD - offset); - count = count_trailing_zero_bits (mword); + count = stdc_trailing_zeros (mword); pos++; if (count + offset < BITS_PER_BITS_WORD) 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. */) in the current mword. */ mword = bits_word_to_host_endian (adata[pos]); mword ^= twiddle; - count += count_trailing_zero_bits (mword); + count += stdc_trailing_zeros (mword); } else if (nr_bits % BITS_PER_BITS_WORD != 0) { 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/>. */ #include <alloca.h> #include <setjmp.h> #include <stdarg.h> +#include <stdbit.h> #include <stdckdint.h> #include <stddef.h> #include <string.h> @@ -37,7 +38,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ #include <attribute.h> #include <byteswap.h> -#include <count-leading-zeros.h> #include <intprops.h> #include <verify.h> @@ -4148,11 +4148,12 @@ integer_to_uintmax (Lisp_Object num, uintmax_t *n) } } -/* Return floor (log2 (N)) as an int, where 0 < N <= ULLONG_MAX. */ +/* Return floor (log2 (N)) as an int. If N is zero, return -1. */ INLINE int elogb (unsigned long long int n) { - return ULLONG_WIDTH - 1 - count_leading_zeros_ll (n); + int width = stdc_bit_width (n); + return width - 1; } /* A modification count. These are wide enough, and incremented |