diff --git a/dix/devices.c b/dix/devices.c index 922e85ae0..750437ab2 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -2018,16 +2018,6 @@ NoteLedState(DeviceIntPtr keybd, int led, Bool on) ctrl->leds &= ~((Leds) 1 << (led - 1)); } -int -Ones(unsigned long mask) -{ /* HACKMEM 169 */ - unsigned long y; - - y = (mask >> 1) & 033333333333; - y = mask - y - ((y >> 1) & 033333333333); - return (((y + (y >> 3)) & 030707070707) % 077); -} - static int DoChangeKeyboardControl(ClientPtr client, DeviceIntPtr keybd, XID *vlist, BITS32 vmask) diff --git a/os/osdep.h b/os/osdep.h index 90df49d35..8d2f0678e 100644 --- a/os/osdep.h +++ b/os/osdep.h @@ -63,6 +63,10 @@ SOFTWARE. #include #include +#ifndef __has_builtin +# define __has_builtin(x) 0 /* Compatibility with older compilers */ +#endif + /* If EAGAIN and EWOULDBLOCK are distinct errno values, then we check errno * for both EAGAIN and EWOULDBLOCK, because some supposedly POSIX * systems are broken and return EWOULDBLOCK when they should return EAGAIN @@ -215,6 +219,23 @@ extern Bool CoreDump; extern Bool NoListenAll; extern Bool AllowByteSwappedClients; -int Ones(unsigned long mask); +#if __has_builtin(__builtin_popcountl) +# define Ones __builtin_popcountl +#else +/* + * Count the number of bits set to 1 in a 32-bit word. + * Algorithm from MIT AI Lab Memo 239: "HAKMEM", ITEM 169. + * https://dspace.mit.edu/handle/1721.1/6086 + */ +static inline int +Ones(unsigned long mask) +{ + unsigned long y; + + y = (mask >> 1) & 033333333333; + y = mask - y - ((y >> 1) & 033333333333); + return (((y + (y >> 3)) & 030707070707) % 077); +} +#endif #endif /* _OSDEP_H_ */