diff options
| author | Paul Eggert | 2017-09-30 13:12:33 -0700 |
|---|---|---|
| committer | Paul Eggert | 2017-09-30 13:14:47 -0700 |
| commit | d88a0f6554888643854ddb2c1f49b77b0bf8904c (patch) | |
| tree | 309616f8e058f79997ede92ed4e8581cea9cadc4 /src/data.c | |
| parent | 185f33340680d918a95ff704a8f7e2d9e1a6f0ca (diff) | |
| download | emacs-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.c | 60 |
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 | ||
| 3077 | static uint32_t | ||
| 3078 | logcount32 (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 | |||
| 3086 | static uint64_t | ||
| 3087 | logcount64 (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 | |||
| 3096 | DEFUN ("logcount", Flogcount, Slogcount, 1, 1, 0, | 3072 | DEFUN ("logcount", Flogcount, Slogcount, 1, 1, 0, |
| 3097 | doc: /* Return population count of VALUE. | 3073 | doc: /* Return population count of VALUE. |
| 3098 | If VALUE is negative, the count is of its two's complement representation. */) | 3074 | If 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 | ||
| 3132 | static Lisp_Object | 3086 | static Lisp_Object |