dix: Use __builtin_popcountl if available to replace Ones()

If the compiler knows of a better algorithm for counting the number of
bits set in a word for the target CPU, let it use that, instead of the
classic algorithm optimized for PDP-6.

Based on xorg/lib/libxext@490a25e6f8a4d2482af4364c700b68ad11a4d10b

v2: make old version static inline, stop exporting after !1695

Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1674>
This commit is contained in:
Alan Coopersmith 2024-09-08 14:54:46 -07:00
parent 1642adec3b
commit 45c485bfdf
2 changed files with 22 additions and 11 deletions

View File

@ -2018,16 +2018,6 @@ NoteLedState(DeviceIntPtr keybd, int led, Bool on)
ctrl->leds &= ~((Leds) 1 << (led - 1)); 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 static int
DoChangeKeyboardControl(ClientPtr client, DeviceIntPtr keybd, XID *vlist, DoChangeKeyboardControl(ClientPtr client, DeviceIntPtr keybd, XID *vlist,
BITS32 vmask) BITS32 vmask)

View File

@ -63,6 +63,10 @@ SOFTWARE.
#include <X11/Xmd.h> #include <X11/Xmd.h>
#include <X11/Xdefs.h> #include <X11/Xdefs.h>
#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 /* If EAGAIN and EWOULDBLOCK are distinct errno values, then we check errno
* for both EAGAIN and EWOULDBLOCK, because some supposedly POSIX * for both EAGAIN and EWOULDBLOCK, because some supposedly POSIX
* systems are broken and return EWOULDBLOCK when they should return EAGAIN * systems are broken and return EWOULDBLOCK when they should return EAGAIN
@ -215,6 +219,23 @@ extern Bool CoreDump;
extern Bool NoListenAll; extern Bool NoListenAll;
extern Bool AllowByteSwappedClients; 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_ */ #endif /* _OSDEP_H_ */