diff --git a/dix/devices.c b/dix/devices.c index c3a31ea80..c744b5919 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -2019,16 +2019,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 fb93cd0ff..b10e88132 100644 --- a/os/osdep.h +++ b/os/osdep.h @@ -62,6 +62,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 @@ -246,6 +250,23 @@ void ForceClockId(clockid_t forced_clockid); Bool WaitForSomething(Bool clients_are_ready); void CloseDownConnection(ClientPtr client); -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_ */