Commit 3b9ed1a5d2d121f32d2cb4f2b05f1fc57c99c946

Authored by Akinobu Mita
Committed by Linus Torvalds
1 parent 09020adb61

[PATCH] bitops: generic hweight{64,32,16,8}()

This patch introduces the C-language equivalents of the functions below:

unsigned int hweight32(unsigned int w);
unsigned int hweight16(unsigned int w);
unsigned int hweight8(unsigned int w);
unsigned long hweight64(__u64 w);

In include/asm-generic/bitops/hweight.h

This code largely copied from: include/linux/bitops.h

Signed-off-by: Akinobu Mita <mita@miraclelinux.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

Showing 3 changed files with 64 additions and 0 deletions Side-by-side Diff

include/asm-generic/bitops/hweight.h
  1 +#ifndef _ASM_GENERIC_BITOPS_HWEIGHT_H_
  2 +#define _ASM_GENERIC_BITOPS_HWEIGHT_H_
  3 +
  4 +extern unsigned int hweight32(unsigned int w);
  5 +extern unsigned int hweight16(unsigned int w);
  6 +extern unsigned int hweight8(unsigned int w);
  7 +extern unsigned long hweight64(__u64 w);
  8 +
  9 +#endif /* _ASM_GENERIC_BITOPS_HWEIGHT_H_ */
... ... @@ -23,6 +23,7 @@
23 23 lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o
24 24 lib-$(CONFIG_SEMAPHORE_SLEEPERS) += semaphore-sleepers.o
25 25 lib-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find_next_bit.o
  26 +lib-$(CONFIG_GENERIC_HWEIGHT) += hweight.o
26 27 obj-$(CONFIG_LOCK_KERNEL) += kernel_lock.o
27 28 obj-$(CONFIG_DEBUG_PREEMPT) += smp_processor_id.o
28 29  
  1 +#include <linux/module.h>
  2 +#include <asm/types.h>
  3 +
  4 +/**
  5 + * hweightN - returns the hamming weight of a N-bit word
  6 + * @x: the word to weigh
  7 + *
  8 + * The Hamming Weight of a number is the total number of bits set in it.
  9 + */
  10 +
  11 +unsigned int hweight32(unsigned int w)
  12 +{
  13 + unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555);
  14 + res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
  15 + res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F);
  16 + res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF);
  17 + return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF);
  18 +}
  19 +EXPORT_SYMBOL(hweight32);
  20 +
  21 +unsigned int hweight16(unsigned int w)
  22 +{
  23 + unsigned int res = (w & 0x5555) + ((w >> 1) & 0x5555);
  24 + res = (res & 0x3333) + ((res >> 2) & 0x3333);
  25 + res = (res & 0x0F0F) + ((res >> 4) & 0x0F0F);
  26 + return (res & 0x00FF) + ((res >> 8) & 0x00FF);
  27 +}
  28 +EXPORT_SYMBOL(hweight16);
  29 +
  30 +unsigned int hweight8(unsigned int w)
  31 +{
  32 + unsigned int res = (w & 0x55) + ((w >> 1) & 0x55);
  33 + res = (res & 0x33) + ((res >> 2) & 0x33);
  34 + return (res & 0x0F) + ((res >> 4) & 0x0F);
  35 +}
  36 +EXPORT_SYMBOL(hweight8);
  37 +
  38 +unsigned long hweight64(__u64 w)
  39 +{
  40 +#if BITS_PER_LONG == 32
  41 + return hweight32((unsigned int)(w >> 32)) + hweight32((unsigned int)w);
  42 +#elif BITS_PER_LONG == 64
  43 + u64 res;
  44 + res = (w & 0x5555555555555555ul) + ((w >> 1) & 0x5555555555555555ul);
  45 + res = (res & 0x3333333333333333ul) + ((res >> 2) & 0x3333333333333333ul);
  46 + res = (res & 0x0F0F0F0F0F0F0F0Ful) + ((res >> 4) & 0x0F0F0F0F0F0F0F0Ful);
  47 + res = (res & 0x00FF00FF00FF00FFul) + ((res >> 8) & 0x00FF00FF00FF00FFul);
  48 + res = (res & 0x0000FFFF0000FFFFul) + ((res >> 16) & 0x0000FFFF0000FFFFul);
  49 + return (res & 0x00000000FFFFFFFFul) + ((res >> 32) & 0x00000000FFFFFFFFul);
  50 +#else
  51 +#error BITS_PER_LONG not defined
  52 +#endif
  53 +}
  54 +EXPORT_SYMBOL(hweight64);