diff options
| author | Paul Eggert | 2013-10-07 21:25:33 -0700 |
|---|---|---|
| committer | Paul Eggert | 2013-10-07 21:25:33 -0700 |
| commit | 87c4314d27420e5da8c2f6f97b4cfd94902f1d04 (patch) | |
| tree | b395b1c6c7ef33d35b1795e1659c620230a186dc /src | |
| parent | 442560600080f6131ec63956ed43eee7d26bf65a (diff) | |
| download | emacs-87c4314d27420e5da8c2f6f97b4cfd94902f1d04.tar.gz emacs-87c4314d27420e5da8c2f6f97b4cfd94902f1d04.zip | |
* lisp.h (bits_word, BITS_WORD_MAX): New type and macro.
All uses of 'size_t' and 'SIZE_MAX' changed to use them, when
they're talking about words in Lisp bool vectors.
(BITS_PER_BITS_WORD): Rename from BITS_PER_SIZE_T. All uses changed.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 7 | ||||
| -rw-r--r-- | src/alloc.c | 8 | ||||
| -rw-r--r-- | src/data.c | 128 | ||||
| -rw-r--r-- | src/lisp.h | 7 |
4 files changed, 81 insertions, 69 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 753e123378c..755e710c079 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,10 @@ | |||
| 1 | 2013-10-08 Paul Eggert <eggert@cs.ucla.edu> | ||
| 2 | |||
| 3 | * lisp.h (bits_word, BITS_WORD_MAX): New type and macro. | ||
| 4 | All uses of 'size_t' and 'SIZE_MAX' changed to use them, when | ||
| 5 | they're talking about words in Lisp bool vectors. | ||
| 6 | (BITS_PER_BITS_WORD): Rename from BITS_PER_SIZE_T. All uses changed. | ||
| 7 | |||
| 1 | 2013-10-07 Paul Eggert <eggert@cs.ucla.edu> | 8 | 2013-10-07 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 9 | ||
| 3 | Improve support for popcount and counting trailing zeros (Bug#15550). | 10 | Improve support for popcount and counting trailing zeros (Bug#15550). |
diff --git a/src/alloc.c b/src/alloc.c index 990390f5a36..2a00767682d 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -2017,8 +2017,8 @@ INIT must be an integer that represents a character. */) | |||
| 2017 | return val; | 2017 | return val; |
| 2018 | } | 2018 | } |
| 2019 | 2019 | ||
| 2020 | verify (sizeof (size_t) * CHAR_BIT == BITS_PER_SIZE_T); | 2020 | verify (sizeof (size_t) * CHAR_BIT == BITS_PER_BITS_WORD); |
| 2021 | verify ((BITS_PER_SIZE_T & (BITS_PER_SIZE_T - 1)) == 0); | 2021 | verify ((BITS_PER_BITS_WORD & (BITS_PER_BITS_WORD - 1)) == 0); |
| 2022 | 2022 | ||
| 2023 | static ptrdiff_t | 2023 | static ptrdiff_t |
| 2024 | bool_vector_payload_bytes (ptrdiff_t nr_bits, | 2024 | bool_vector_payload_bytes (ptrdiff_t nr_bits, |
| @@ -2030,14 +2030,14 @@ bool_vector_payload_bytes (ptrdiff_t nr_bits, | |||
| 2030 | eassert (nr_bits >= 0); | 2030 | eassert (nr_bits >= 0); |
| 2031 | 2031 | ||
| 2032 | exact_needed_bytes = ROUNDUP ((size_t) nr_bits, CHAR_BIT) / CHAR_BIT; | 2032 | exact_needed_bytes = ROUNDUP ((size_t) nr_bits, CHAR_BIT) / CHAR_BIT; |
| 2033 | needed_bytes = ROUNDUP ((size_t) nr_bits, BITS_PER_SIZE_T) / CHAR_BIT; | 2033 | needed_bytes = ROUNDUP ((size_t) nr_bits, BITS_PER_BITS_WORD) / CHAR_BIT; |
| 2034 | 2034 | ||
| 2035 | if (needed_bytes == 0) | 2035 | if (needed_bytes == 0) |
| 2036 | { | 2036 | { |
| 2037 | /* Always allocate at least one machine word of payload so that | 2037 | /* Always allocate at least one machine word of payload so that |
| 2038 | bool-vector operations in data.c don't need a special case | 2038 | bool-vector operations in data.c don't need a special case |
| 2039 | for empty vectors. */ | 2039 | for empty vectors. */ |
| 2040 | needed_bytes = sizeof (size_t); | 2040 | needed_bytes = sizeof (bits_word); |
| 2041 | } | 2041 | } |
| 2042 | 2042 | ||
| 2043 | if (exact_needed_bytes_out != NULL) | 2043 | if (exact_needed_bytes_out != NULL) |
diff --git a/src/data.c b/src/data.c index 4ef326e4cfd..8045cd138ea 100644 --- a/src/data.c +++ b/src/data.c | |||
| @@ -2963,24 +2963,24 @@ lowercase l) for small endian machines. */) | |||
| 2963 | /* Because we round up the bool vector allocate size to word_size | 2963 | /* Because we round up the bool vector allocate size to word_size |
| 2964 | units, we can safely read past the "end" of the vector in the | 2964 | units, we can safely read past the "end" of the vector in the |
| 2965 | operations below. These extra bits are always zero. Also, we | 2965 | operations below. These extra bits are always zero. Also, we |
| 2966 | always allocate bool vectors with at least one size_t of storage so | 2966 | always allocate bool vectors with at least one bits_word of storage so |
| 2967 | that we don't have to special-case empty bit vectors. */ | 2967 | that we don't have to special-case empty bit vectors. */ |
| 2968 | 2968 | ||
| 2969 | static size_t | 2969 | static bits_word |
| 2970 | bool_vector_spare_mask (ptrdiff_t nr_bits) | 2970 | bool_vector_spare_mask (ptrdiff_t nr_bits) |
| 2971 | { | 2971 | { |
| 2972 | eassert (nr_bits > 0); | 2972 | eassert (nr_bits > 0); |
| 2973 | return (((size_t) 1) << (nr_bits % BITS_PER_SIZE_T)) - 1; | 2973 | return (((bits_word) 1) << (nr_bits % BITS_PER_BITS_WORD)) - 1; |
| 2974 | } | 2974 | } |
| 2975 | 2975 | ||
| 2976 | #if SIZE_MAX <= UINT_MAX | 2976 | #if BITS_WORD_MAX <= UINT_MAX |
| 2977 | # define popcount_size_t count_one_bits | 2977 | # define popcount_bits_word count_one_bits |
| 2978 | #elif SIZE_MAX <= ULONG_MAX | 2978 | #elif BITS_WORD_MAX <= ULONG_MAX |
| 2979 | # define popcount_size_t count_one_bits_l | 2979 | # define popcount_bits_word count_one_bits_l |
| 2980 | #elif SIZE_MAX <= ULLONG_MAX | 2980 | #elif BITS_WORD_MAX <= ULLONG_MAX |
| 2981 | # define popcount_size_t count_one_bits_ll | 2981 | # define popcount_bits_word count_one_bits_ll |
| 2982 | #else | 2982 | #else |
| 2983 | # error "size_t wider than long long? Please file a bug report." | 2983 | # error "bits_word wider than long long? Please file a bug report." |
| 2984 | #endif | 2984 | #endif |
| 2985 | 2985 | ||
| 2986 | enum bool_vector_op { bool_vector_exclusive_or, | 2986 | enum bool_vector_op { bool_vector_exclusive_or, |
| @@ -2996,10 +2996,10 @@ bool_vector_binop_driver (Lisp_Object op1, | |||
| 2996 | enum bool_vector_op op) | 2996 | enum bool_vector_op op) |
| 2997 | { | 2997 | { |
| 2998 | EMACS_INT nr_bits; | 2998 | EMACS_INT nr_bits; |
| 2999 | size_t *adata, *bdata, *cdata; | 2999 | bits_word *adata, *bdata, *cdata; |
| 3000 | ptrdiff_t i; | 3000 | ptrdiff_t i; |
| 3001 | size_t changed = 0; | 3001 | bits_word changed = 0; |
| 3002 | size_t mword; | 3002 | bits_word mword; |
| 3003 | ptrdiff_t nr_words; | 3003 | ptrdiff_t nr_words; |
| 3004 | 3004 | ||
| 3005 | CHECK_BOOL_VECTOR (op1); | 3005 | CHECK_BOOL_VECTOR (op1); |
| @@ -3020,11 +3020,11 @@ bool_vector_binop_driver (Lisp_Object op1, | |||
| 3020 | } | 3020 | } |
| 3021 | 3021 | ||
| 3022 | eassert (nr_bits >= 0); | 3022 | eassert (nr_bits >= 0); |
| 3023 | nr_words = ROUNDUP (nr_bits, BITS_PER_SIZE_T) / BITS_PER_SIZE_T; | 3023 | nr_words = ROUNDUP (nr_bits, BITS_PER_BITS_WORD) / BITS_PER_BITS_WORD; |
| 3024 | 3024 | ||
| 3025 | adata = (size_t *) XBOOL_VECTOR (dest)->data; | 3025 | adata = (bits_word *) XBOOL_VECTOR (dest)->data; |
| 3026 | bdata = (size_t *) XBOOL_VECTOR (op1)->data; | 3026 | bdata = (bits_word *) XBOOL_VECTOR (op1)->data; |
| 3027 | cdata = (size_t *) XBOOL_VECTOR (op2)->data; | 3027 | cdata = (bits_word *) XBOOL_VECTOR (op2)->data; |
| 3028 | i = 0; | 3028 | i = 0; |
| 3029 | do | 3029 | do |
| 3030 | { | 3030 | { |
| @@ -3054,47 +3054,47 @@ bool_vector_binop_driver (Lisp_Object op1, | |||
| 3054 | /* Compute the number of trailing zero bits in val. If val is zero, | 3054 | /* Compute the number of trailing zero bits in val. If val is zero, |
| 3055 | return the number of bits in val. */ | 3055 | return the number of bits in val. */ |
| 3056 | static int | 3056 | static int |
| 3057 | count_trailing_zero_bits (size_t val) | 3057 | count_trailing_zero_bits (bits_word val) |
| 3058 | { | 3058 | { |
| 3059 | if (SIZE_MAX == UINT_MAX) | 3059 | if (BITS_WORD_MAX == UINT_MAX) |
| 3060 | return count_trailing_zeros (val); | 3060 | return count_trailing_zeros (val); |
| 3061 | if (SIZE_MAX == ULONG_MAX) | 3061 | if (BITS_WORD_MAX == ULONG_MAX) |
| 3062 | return count_trailing_zeros_l (val); | 3062 | return count_trailing_zeros_l (val); |
| 3063 | # if HAVE_UNSIGNED_LONG_LONG_INT | 3063 | # if HAVE_UNSIGNED_LONG_LONG_INT |
| 3064 | if (SIZE_MAX == ULLONG_MAX) | 3064 | if (BITS_WORD_MAX == ULLONG_MAX) |
| 3065 | return count_trailing_zeros_ll (val); | 3065 | return count_trailing_zeros_ll (val); |
| 3066 | # endif | 3066 | # endif |
| 3067 | 3067 | ||
| 3068 | /* The rest of this code is for the unlikely platform where size_t differs | 3068 | /* The rest of this code is for the unlikely platform where bits_word differs |
| 3069 | in width from unsigned int, unsigned long, and unsigned long long. */ | 3069 | in width from unsigned int, unsigned long, and unsigned long long. */ |
| 3070 | if (val == 0) | 3070 | if (val == 0) |
| 3071 | return CHAR_BIT * sizeof (val); | 3071 | return CHAR_BIT * sizeof (val); |
| 3072 | if (SIZE_MAX <= UINT_MAX) | 3072 | if (BITS_WORD_MAX <= UINT_MAX) |
| 3073 | return count_trailing_zeros (val); | 3073 | return count_trailing_zeros (val); |
| 3074 | if (SIZE_MAX <= ULONG_MAX) | 3074 | if (BITS_WORD_MAX <= ULONG_MAX) |
| 3075 | return count_trailing_zeros_l (val); | 3075 | return count_trailing_zeros_l (val); |
| 3076 | { | 3076 | { |
| 3077 | # if HAVE_UNSIGNED_LONG_LONG_INT | 3077 | # if HAVE_UNSIGNED_LONG_LONG_INT |
| 3078 | verify (SIZE_MAX <= ULLONG_MAX); | 3078 | verify (BITS_WORD_MAX <= ULLONG_MAX); |
| 3079 | return count_trailing_zeros_ll (val); | 3079 | return count_trailing_zeros_ll (val); |
| 3080 | # else | 3080 | # else |
| 3081 | verify (SIZE_MAX <= ULONG_MAX); | 3081 | verify (BITS_WORD_MAX <= ULONG_MAX); |
| 3082 | # endif | 3082 | # endif |
| 3083 | } | 3083 | } |
| 3084 | } | 3084 | } |
| 3085 | 3085 | ||
| 3086 | static size_t | 3086 | static bits_word |
| 3087 | size_t_to_host_endian (size_t val) | 3087 | bits_word_to_host_endian (bits_word val) |
| 3088 | { | 3088 | { |
| 3089 | #ifndef WORDS_BIGENDIAN | 3089 | #ifndef WORDS_BIGENDIAN |
| 3090 | return val; | 3090 | return val; |
| 3091 | #elif SIZE_MAX >> 31 == 1 | 3091 | #elif BITS_WORD_MAX >> 31 == 1 |
| 3092 | return bswap_32 (val); | 3092 | return bswap_32 (val); |
| 3093 | #elif SIZE_MAX >> 31 >> 31 >> 1 == 1 | 3093 | #elif BITS_WORD_MAX >> 31 >> 31 >> 1 == 1 |
| 3094 | return bswap_64 (val); | 3094 | return bswap_64 (val); |
| 3095 | #else | 3095 | #else |
| 3096 | int i; | 3096 | int i; |
| 3097 | size_t r = 0; | 3097 | bits_word r = 0; |
| 3098 | for (i = 0; i < sizeof val; i++) | 3098 | for (i = 0; i < sizeof val; i++) |
| 3099 | { | 3099 | { |
| 3100 | r = (r << CHAR_BIT) | (val & ((1u << CHAR_BIT) - 1)); | 3100 | r = (r << CHAR_BIT) | (val & ((1u << CHAR_BIT) - 1)); |
| @@ -3167,9 +3167,9 @@ Return the destination vector. */) | |||
| 3167 | (Lisp_Object a, Lisp_Object b) | 3167 | (Lisp_Object a, Lisp_Object b) |
| 3168 | { | 3168 | { |
| 3169 | EMACS_INT nr_bits; | 3169 | EMACS_INT nr_bits; |
| 3170 | size_t *bdata, *adata; | 3170 | bits_word *bdata, *adata; |
| 3171 | ptrdiff_t i; | 3171 | ptrdiff_t i; |
| 3172 | size_t mword; | 3172 | bits_word mword; |
| 3173 | 3173 | ||
| 3174 | CHECK_BOOL_VECTOR (a); | 3174 | CHECK_BOOL_VECTOR (a); |
| 3175 | nr_bits = XBOOL_VECTOR (a)->size; | 3175 | nr_bits = XBOOL_VECTOR (a)->size; |
| @@ -3182,20 +3182,20 @@ Return the destination vector. */) | |||
| 3182 | nr_bits = min (nr_bits, XBOOL_VECTOR (b)->size); | 3182 | nr_bits = min (nr_bits, XBOOL_VECTOR (b)->size); |
| 3183 | } | 3183 | } |
| 3184 | 3184 | ||
| 3185 | bdata = (size_t *) XBOOL_VECTOR (b)->data; | 3185 | bdata = (bits_word *) XBOOL_VECTOR (b)->data; |
| 3186 | adata = (size_t *) XBOOL_VECTOR (a)->data; | 3186 | adata = (bits_word *) XBOOL_VECTOR (a)->data; |
| 3187 | 3187 | ||
| 3188 | eassert (nr_bits >= 0); | 3188 | eassert (nr_bits >= 0); |
| 3189 | 3189 | ||
| 3190 | for (i = 0; i < nr_bits / BITS_PER_SIZE_T; i++) | 3190 | for (i = 0; i < nr_bits / BITS_PER_BITS_WORD; i++) |
| 3191 | bdata[i] = ~adata[i]; | 3191 | bdata[i] = ~adata[i]; |
| 3192 | 3192 | ||
| 3193 | if (nr_bits % BITS_PER_SIZE_T) | 3193 | if (nr_bits % BITS_PER_BITS_WORD) |
| 3194 | { | 3194 | { |
| 3195 | mword = size_t_to_host_endian (adata[i]); | 3195 | mword = bits_word_to_host_endian (adata[i]); |
| 3196 | mword = ~mword; | 3196 | mword = ~mword; |
| 3197 | mword &= bool_vector_spare_mask (nr_bits); | 3197 | mword &= bool_vector_spare_mask (nr_bits); |
| 3198 | bdata[i] = size_t_to_host_endian (mword); | 3198 | bdata[i] = bits_word_to_host_endian (mword); |
| 3199 | } | 3199 | } |
| 3200 | 3200 | ||
| 3201 | return b; | 3201 | return b; |
| @@ -3209,28 +3209,28 @@ A must be a bool vector. B is a generalized bool. */) | |||
| 3209 | { | 3209 | { |
| 3210 | ptrdiff_t count; | 3210 | ptrdiff_t count; |
| 3211 | EMACS_INT nr_bits; | 3211 | EMACS_INT nr_bits; |
| 3212 | size_t *adata; | 3212 | bits_word *adata; |
| 3213 | size_t match; | 3213 | bits_word match; |
| 3214 | ptrdiff_t i; | 3214 | ptrdiff_t i; |
| 3215 | 3215 | ||
| 3216 | CHECK_BOOL_VECTOR (a); | 3216 | CHECK_BOOL_VECTOR (a); |
| 3217 | 3217 | ||
| 3218 | nr_bits = XBOOL_VECTOR (a)->size; | 3218 | nr_bits = XBOOL_VECTOR (a)->size; |
| 3219 | count = 0; | 3219 | count = 0; |
| 3220 | match = NILP (b) ? (size_t) -1 : 0; | 3220 | match = NILP (b) ? -1 : 0; |
| 3221 | adata = (size_t *) XBOOL_VECTOR (a)->data; | 3221 | adata = (bits_word *) XBOOL_VECTOR (a)->data; |
| 3222 | 3222 | ||
| 3223 | eassert (nr_bits >= 0); | 3223 | eassert (nr_bits >= 0); |
| 3224 | 3224 | ||
| 3225 | for (i = 0; i < nr_bits / BITS_PER_SIZE_T; ++i) | 3225 | for (i = 0; i < nr_bits / BITS_PER_BITS_WORD; ++i) |
| 3226 | count += popcount_size_t (adata[i] ^ match); | 3226 | count += popcount_bits_word (adata[i] ^ match); |
| 3227 | 3227 | ||
| 3228 | /* Mask out trailing parts of final mword. */ | 3228 | /* Mask out trailing parts of final mword. */ |
| 3229 | if (nr_bits % BITS_PER_SIZE_T) | 3229 | if (nr_bits % BITS_PER_BITS_WORD) |
| 3230 | { | 3230 | { |
| 3231 | size_t mword = adata[i] ^ match; | 3231 | bits_word mword = adata[i] ^ match; |
| 3232 | mword = size_t_to_host_endian (mword); | 3232 | mword = bits_word_to_host_endian (mword); |
| 3233 | count += popcount_size_t (mword & bool_vector_spare_mask (nr_bits)); | 3233 | count += popcount_bits_word (mword & bool_vector_spare_mask (nr_bits)); |
| 3234 | } | 3234 | } |
| 3235 | 3235 | ||
| 3236 | return make_number (count); | 3236 | return make_number (count); |
| @@ -3247,9 +3247,9 @@ index into the vector. */) | |||
| 3247 | ptrdiff_t count; | 3247 | ptrdiff_t count; |
| 3248 | EMACS_INT nr_bits; | 3248 | EMACS_INT nr_bits; |
| 3249 | ptrdiff_t offset; | 3249 | ptrdiff_t offset; |
| 3250 | size_t *adata; | 3250 | bits_word *adata; |
| 3251 | size_t twiddle; | 3251 | bits_word twiddle; |
| 3252 | size_t mword; /* Machine word. */ | 3252 | bits_word mword; /* Machine word. */ |
| 3253 | ptrdiff_t pos; | 3253 | ptrdiff_t pos; |
| 3254 | ptrdiff_t nr_words; | 3254 | ptrdiff_t nr_words; |
| 3255 | 3255 | ||
| @@ -3260,30 +3260,30 @@ index into the vector. */) | |||
| 3260 | if (XFASTINT (i) > nr_bits) /* Allow one past the end for convenience */ | 3260 | if (XFASTINT (i) > nr_bits) /* Allow one past the end for convenience */ |
| 3261 | args_out_of_range (a, i); | 3261 | args_out_of_range (a, i); |
| 3262 | 3262 | ||
| 3263 | adata = (size_t *) XBOOL_VECTOR (a)->data; | 3263 | adata = (bits_word *) XBOOL_VECTOR (a)->data; |
| 3264 | 3264 | ||
| 3265 | assume (nr_bits >= 0); | 3265 | assume (nr_bits >= 0); |
| 3266 | nr_words = ROUNDUP (nr_bits, BITS_PER_SIZE_T) / BITS_PER_SIZE_T; | 3266 | nr_words = ROUNDUP (nr_bits, BITS_PER_BITS_WORD) / BITS_PER_BITS_WORD; |
| 3267 | 3267 | ||
| 3268 | pos = XFASTINT (i) / BITS_PER_SIZE_T; | 3268 | pos = XFASTINT (i) / BITS_PER_BITS_WORD; |
| 3269 | offset = XFASTINT (i) % BITS_PER_SIZE_T; | 3269 | offset = XFASTINT (i) % BITS_PER_BITS_WORD; |
| 3270 | count = 0; | 3270 | count = 0; |
| 3271 | 3271 | ||
| 3272 | /* By XORing with twiddle, we transform the problem of "count | 3272 | /* By XORing with twiddle, we transform the problem of "count |
| 3273 | consecutive equal values" into "count the zero bits". The latter | 3273 | consecutive equal values" into "count the zero bits". The latter |
| 3274 | operation usually has hardware support. */ | 3274 | operation usually has hardware support. */ |
| 3275 | twiddle = NILP (b) ? 0 : (size_t) -1; | 3275 | twiddle = NILP (b) ? 0 : -1; |
| 3276 | 3276 | ||
| 3277 | /* Scan the remainder of the mword at the current offset. */ | 3277 | /* Scan the remainder of the mword at the current offset. */ |
| 3278 | if (pos < nr_words && offset != 0) | 3278 | if (pos < nr_words && offset != 0) |
| 3279 | { | 3279 | { |
| 3280 | mword = size_t_to_host_endian (adata[pos]); | 3280 | mword = bits_word_to_host_endian (adata[pos]); |
| 3281 | mword ^= twiddle; | 3281 | mword ^= twiddle; |
| 3282 | mword >>= offset; | 3282 | mword >>= offset; |
| 3283 | count = count_trailing_zero_bits (mword); | 3283 | count = count_trailing_zero_bits (mword); |
| 3284 | count = min (count, BITS_PER_SIZE_T - offset); | 3284 | count = min (count, BITS_PER_BITS_WORD - offset); |
| 3285 | pos++; | 3285 | pos++; |
| 3286 | if (count + offset < BITS_PER_SIZE_T) | 3286 | if (count + offset < BITS_PER_BITS_WORD) |
| 3287 | return make_number (count); | 3287 | return make_number (count); |
| 3288 | } | 3288 | } |
| 3289 | 3289 | ||
| @@ -3292,7 +3292,7 @@ index into the vector. */) | |||
| 3292 | endian-independent. */ | 3292 | endian-independent. */ |
| 3293 | while (pos < nr_words && adata[pos] == twiddle) | 3293 | while (pos < nr_words && adata[pos] == twiddle) |
| 3294 | { | 3294 | { |
| 3295 | count += BITS_PER_SIZE_T; | 3295 | count += BITS_PER_BITS_WORD; |
| 3296 | ++pos; | 3296 | ++pos; |
| 3297 | } | 3297 | } |
| 3298 | 3298 | ||
| @@ -3300,16 +3300,16 @@ index into the vector. */) | |||
| 3300 | { | 3300 | { |
| 3301 | /* If we stopped because of a mismatch, see how many bits match | 3301 | /* If we stopped because of a mismatch, see how many bits match |
| 3302 | in the current mword. */ | 3302 | in the current mword. */ |
| 3303 | mword = size_t_to_host_endian (adata[pos]); | 3303 | mword = bits_word_to_host_endian (adata[pos]); |
| 3304 | mword ^= twiddle; | 3304 | mword ^= twiddle; |
| 3305 | count += count_trailing_zero_bits (mword); | 3305 | count += count_trailing_zero_bits (mword); |
| 3306 | } | 3306 | } |
| 3307 | else if (nr_bits % BITS_PER_SIZE_T != 0) | 3307 | else if (nr_bits % BITS_PER_BITS_WORD != 0) |
| 3308 | { | 3308 | { |
| 3309 | /* If we hit the end, we might have overshot our count. Reduce | 3309 | /* If we hit the end, we might have overshot our count. Reduce |
| 3310 | the total by the number of spare bits at the end of the | 3310 | the total by the number of spare bits at the end of the |
| 3311 | vector. */ | 3311 | vector. */ |
| 3312 | count -= BITS_PER_SIZE_T - nr_bits % BITS_PER_SIZE_T; | 3312 | count -= BITS_PER_BITS_WORD - nr_bits % BITS_PER_BITS_WORD; |
| 3313 | } | 3313 | } |
| 3314 | 3314 | ||
| 3315 | return make_number (count); | 3315 | return make_number (count); |
diff --git a/src/lisp.h b/src/lisp.h index b8863d6821d..3e63aa0255f 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -64,6 +64,11 @@ typedef unsigned int EMACS_UINT; | |||
| 64 | # endif | 64 | # endif |
| 65 | #endif | 65 | #endif |
| 66 | 66 | ||
| 67 | /* An unsigned integer type representing a fixed-length bit sequence, | ||
| 68 | suitable for words in a Lisp bool vector. */ | ||
| 69 | typedef size_t bits_word; | ||
| 70 | #define BITS_WORD_MAX SIZE_MAX | ||
| 71 | |||
| 67 | /* Number of bits in some machine integer types. */ | 72 | /* Number of bits in some machine integer types. */ |
| 68 | enum | 73 | enum |
| 69 | { | 74 | { |
| @@ -71,7 +76,7 @@ enum | |||
| 71 | BITS_PER_SHORT = CHAR_BIT * sizeof (short), | 76 | BITS_PER_SHORT = CHAR_BIT * sizeof (short), |
| 72 | BITS_PER_INT = CHAR_BIT * sizeof (int), | 77 | BITS_PER_INT = CHAR_BIT * sizeof (int), |
| 73 | BITS_PER_LONG = CHAR_BIT * sizeof (long int), | 78 | BITS_PER_LONG = CHAR_BIT * sizeof (long int), |
| 74 | BITS_PER_SIZE_T = CHAR_BIT * sizeof (size_t), | 79 | BITS_PER_BITS_WORD = CHAR_BIT * sizeof (bits_word), |
| 75 | BITS_PER_EMACS_INT = CHAR_BIT * sizeof (EMACS_INT) | 80 | BITS_PER_EMACS_INT = CHAR_BIT * sizeof (EMACS_INT) |
| 76 | }; | 81 | }; |
| 77 | 82 | ||