aboutsummaryrefslogtreecommitdiffstats
path: root/src/data.c
diff options
context:
space:
mode:
authorPaul Eggert2017-09-30 13:12:33 -0700
committerPaul Eggert2017-09-30 13:14:47 -0700
commitd88a0f6554888643854ddb2c1f49b77b0bf8904c (patch)
tree309616f8e058f79997ede92ed4e8581cea9cadc4 /src/data.c
parent185f33340680d918a95ff704a8f7e2d9e1a6f0ca (diff)
downloademacs-d88a0f6554888643854ddb2c1f49b77b0bf8904c.tar.gz
emacs-d88a0f6554888643854ddb2c1f49b77b0bf8904c.zip
Simplify logcount implementation
* src/data.c (HAVE_BUILTIN_POPCOUNTLL, logcount32, logcount64): Remove. (Flogcount): Simplify by using count_one_bits.
Diffstat (limited to 'src/data.c')
-rw-r--r--src/data.c60
1 files changed, 7 insertions, 53 deletions
diff --git a/src/data.c b/src/data.c
index b595e3fb1ac..fd8cdd19aa2 100644
--- a/src/data.c
+++ b/src/data.c
@@ -3069,64 +3069,18 @@ usage: (logxor &rest INTS-OR-MARKERS) */)
3069 return arith_driver (Alogxor, nargs, args); 3069 return arith_driver (Alogxor, nargs, args);
3070} 3070}
3071 3071
3072#if GNUC_PREREQ (4, 1, 0)
3073#define HAVE_BUILTIN_POPCOUNTLL
3074#endif
3075
3076#ifndef HAVE_BUILTIN_POPCOUNTLL
3077static uint32_t
3078logcount32 (uint32_t b)
3079{
3080 b -= (b >> 1) & 0x55555555;
3081 b = (b & 0x33333333) + ((b >> 2) & 0x33333333);
3082 b = (b + (b >> 4)) & 0x0f0f0f0f;
3083 return (b * 0x01010101) >> 24;
3084}
3085
3086static uint64_t
3087logcount64 (uint64_t b)
3088{
3089 b -= (b >> 1) & 0x5555555555555555ULL;
3090 b = (b & 0x3333333333333333ULL) + ((b >> 2) & 0x3333333333333333ULL);
3091 b = (b + (b >> 4)) & 0x0f0f0f0f0f0f0f0fULL;
3092 return (b * 0x0101010101010101ULL) >> 56;
3093}
3094#endif /* HAVE_BUILTIN_POPCOUNTLL */
3095
3096DEFUN ("logcount", Flogcount, Slogcount, 1, 1, 0, 3072DEFUN ("logcount", Flogcount, Slogcount, 1, 1, 0,
3097 doc: /* Return population count of VALUE. 3073 doc: /* Return population count of VALUE.
3098If VALUE is negative, the count is of its two's complement representation. */) 3074If VALUE is negative, the count is of its two's complement representation. */)
3099 (register Lisp_Object value) 3075 (Lisp_Object value)
3100{ 3076{
3101 Lisp_Object res;
3102 EMACS_UINT v;
3103
3104 CHECK_NUMBER (value); 3077 CHECK_NUMBER (value);
3105 3078 EMACS_UINT v = XUINT (value);
3106 v = XUINT (value); 3079 return make_number (EMACS_UINT_WIDTH <= UINT_WIDTH
3107#ifdef HAVE_BUILTIN_POPCOUNTLL 3080 ? count_one_bits (v)
3108 if (v <= UINT_MAX) 3081 : EMACS_UINT_WIDTH <= ULONG_WIDTH
3109 XSETINT (res, __builtin_popcount (v)); 3082 ? count_one_bits_l (v)
3110 else if (v <= ULONG_MAX) 3083 : count_one_bits_ll (v));
3111 XSETINT (res, __builtin_popcountl (v));
3112 else if (v <= ULONG_LONG_MAX)
3113 XSETINT (res, __builtin_popcountll (v));
3114#else /* HAVE_BUILTIN_POPCOUNTLL */
3115 if (v <= UINT_MAX)
3116 XSETINT (res, logcount32 (v));
3117 else if (v <= ULONG_MAX || v <= ULONG_LONG_MAX)
3118 XSETINT (res, logcount64 (v));
3119#endif /* HAVE_BUILTIN_POPCOUNTLL */
3120 else
3121 {
3122 unsigned int count;
3123 for (count = 0; v; count++)
3124 {
3125 v &= v - 1;
3126 }
3127 XSETINT (res, count);
3128 }
3129 return res;
3130} 3084}
3131 3085
3132static Lisp_Object 3086static Lisp_Object