diff --git a/lib/hweight.c b/lib/hweight.c index 738ed27738..bc9b51bc22 100644 --- a/lib/hweight.c +++ b/lib/hweight.c @@ -17,3 +17,17 @@ unsigned int hweight32(uint32_t w) res = res + (res >> 8); return (res + (res >> 16)) & 0x000000FF; } + +unsigned int hweight64(uint64_t w) +{ +#if BITS_PER_LONG == 32 + return hweight32((unsigned int)(w >> 32)) + hweight32((unsigned int)w); +#else + uint64_t res = w - ((w >> 1) & 0x5555555555555555ul); + res = (res & 0x3333333333333333ul) + ((res >> 2) & 0x3333333333333333ul); + res = (res + (res >> 4)) & 0x0F0F0F0F0F0F0F0Ful; + res = res + (res >> 8); + res = res + (res >> 16); + return (res + (res >> 32)) & 0x00000000000000FFul; +#endif +} diff --git a/lib/hweight.h b/lib/hweight.h index 1965eaa641..68861ddd9d 100644 --- a/lib/hweight.h +++ b/lib/hweight.h @@ -5,5 +5,6 @@ unsigned int hweight8(uint8_t w); unsigned int hweight32(uint32_t w); +unsigned int hweight64(uint64_t w); #endif