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 /src/data.c | |
| 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.
Diffstat (limited to 'src/data.c')
| -rw-r--r-- | src/data.c | 95 |
1 files changed, 5 insertions, 90 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/>. */ | |||
| 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 | { |