aboutsummaryrefslogtreecommitdiffstats
path: root/src/data.c
diff options
context:
space:
mode:
authorPaul Eggert2024-05-12 14:22:58 -0700
committerPaul Eggert2024-05-18 10:23:51 -0700
commit88b0bb4db9aaecff8b01e81726b911fa5d02b2fb (patch)
tree8ac3e75bba0a9082a94e7c3a03cd8b590f07a97d /src/data.c
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.
Diffstat (limited to 'src/data.c')
-rw-r--r--src/data.c95
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
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 {