Commit 2371906a authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Reimplement RtlNumberOfSetBits() to check 32 bits at a time.

parent 504f9d3c
...@@ -37,14 +37,6 @@ ...@@ -37,14 +37,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(ntdll); WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
/* Bits set from LSB to MSB; used as mask for runs < 8 bits */
static const BYTE NTDLL_maskBits[8] = { 0, 1, 3, 7, 15, 31, 63, 127 };
/* Number of set bits for each value of a nibble; used for counting */
static const BYTE NTDLL_nibbleBitCount[16] = {
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4
};
/* First set bit in a nibble; used for determining least significant bit */ /* First set bit in a nibble; used for determining least significant bit */
static const BYTE NTDLL_leastSignificant[16] = { static const BYTE NTDLL_leastSignificant[16] = {
0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
...@@ -60,6 +52,17 @@ static inline ULONG maskbits( ULONG idx ) ...@@ -60,6 +52,17 @@ static inline ULONG maskbits( ULONG idx )
return ~0u << (idx & 31); return ~0u << (idx & 31);
} }
static ULONG popcount( ULONG val )
{
#if defined(__MINGW32__)
return __builtin_popcount( val );
#else
val -= val >> 1 & 0x55555555;
val = (val & 0x33333333) + (val >> 2 & 0x33333333);
return ((val + (val >> 4)) & 0x0f0f0f0f) * 0x01010101 >> 24;
#endif
}
/************************************************************************* /*************************************************************************
* RtlInitializeBitMap [NTDLL.@] * RtlInitializeBitMap [NTDLL.@]
* *
...@@ -352,45 +355,16 @@ ULONG WINAPI RtlFindClearBitsAndSet(PRTL_BITMAP lpBits, ULONG ulCount, ULONG ulH ...@@ -352,45 +355,16 @@ ULONG WINAPI RtlFindClearBitsAndSet(PRTL_BITMAP lpBits, ULONG ulCount, ULONG ulH
/************************************************************************* /*************************************************************************
* RtlNumberOfSetBits [NTDLL.@] * RtlNumberOfSetBits [NTDLL.@]
*
* Find the number of set bits in a bitmap.
*
* PARAMS
* lpBits [I] Bitmap pointer
*
* RETURNS
* The number of set bits.
*/ */
ULONG WINAPI RtlNumberOfSetBits(PCRTL_BITMAP lpBits) ULONG WINAPI RtlNumberOfSetBits( const RTL_BITMAP *bitmap )
{ {
ULONG ulSet = 0; ULONG i, ret = 0;
TRACE("(%p)\n", lpBits); for (i = 0; i < bitmap->SizeOfBitMap / 32; i++) ret += popcount( bitmap->Buffer[i] );
if (bitmap->SizeOfBitMap & 31) ret += popcount( bitmap->Buffer[i] & ~maskbits( bitmap->SizeOfBitMap ));
if (lpBits)
{
LPBYTE lpOut = (BYTE *)lpBits->Buffer;
ULONG ulCount, ulRemainder;
BYTE bMasked;
ulCount = lpBits->SizeOfBitMap >> 3;
ulRemainder = lpBits->SizeOfBitMap & 0x7;
while (ulCount--)
{
ulSet += NTDLL_nibbleBitCount[*lpOut >> 4];
ulSet += NTDLL_nibbleBitCount[*lpOut & 0xf];
lpOut++;
}
if (ulRemainder) TRACE( "%p -> %lu\n", bitmap, ret );
{ return ret;
bMasked = *lpOut & NTDLL_maskBits[ulRemainder];
ulSet += NTDLL_nibbleBitCount[bMasked >> 4];
ulSet += NTDLL_nibbleBitCount[bMasked & 0xf];
}
}
return ulSet;
} }
/************************************************************************* /*************************************************************************
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment