Commit 3b9ed1a5d2d121f32d2cb4f2b05f1fc57c99c946
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 Inline Diff
include/asm-generic/bitops/hweight.h
File was created | 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_ */ | ||
10 |
lib/Makefile
1 | # | 1 | # |
2 | # Makefile for some libs needed in the kernel. | 2 | # Makefile for some libs needed in the kernel. |
3 | # | 3 | # |
4 | 4 | ||
5 | lib-y := errno.o ctype.o string.o vsprintf.o cmdline.o \ | 5 | lib-y := errno.o ctype.o string.o vsprintf.o cmdline.o \ |
6 | bust_spinlocks.o rbtree.o radix-tree.o dump_stack.o \ | 6 | bust_spinlocks.o rbtree.o radix-tree.o dump_stack.o \ |
7 | idr.o div64.o int_sqrt.o bitmap.o extable.o prio_tree.o \ | 7 | idr.o div64.o int_sqrt.o bitmap.o extable.o prio_tree.o \ |
8 | sha1.o | 8 | sha1.o |
9 | 9 | ||
10 | lib-$(CONFIG_SMP) += cpumask.o | 10 | lib-$(CONFIG_SMP) += cpumask.o |
11 | 11 | ||
12 | lib-y += kobject.o kref.o kobject_uevent.o klist.o | 12 | lib-y += kobject.o kref.o kobject_uevent.o klist.o |
13 | 13 | ||
14 | obj-y += sort.o parser.o halfmd4.o iomap_copy.o | 14 | obj-y += sort.o parser.o halfmd4.o iomap_copy.o |
15 | 15 | ||
16 | ifeq ($(CONFIG_DEBUG_KOBJECT),y) | 16 | ifeq ($(CONFIG_DEBUG_KOBJECT),y) |
17 | CFLAGS_kobject.o += -DDEBUG | 17 | CFLAGS_kobject.o += -DDEBUG |
18 | CFLAGS_kobject_uevent.o += -DDEBUG | 18 | CFLAGS_kobject_uevent.o += -DDEBUG |
19 | endif | 19 | endif |
20 | 20 | ||
21 | obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock_debug.o | 21 | obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock_debug.o |
22 | lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o | 22 | lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o |
23 | lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o | 23 | lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o |
24 | lib-$(CONFIG_SEMAPHORE_SLEEPERS) += semaphore-sleepers.o | 24 | lib-$(CONFIG_SEMAPHORE_SLEEPERS) += semaphore-sleepers.o |
25 | lib-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find_next_bit.o | 25 | lib-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find_next_bit.o |
26 | lib-$(CONFIG_GENERIC_HWEIGHT) += hweight.o | ||
26 | obj-$(CONFIG_LOCK_KERNEL) += kernel_lock.o | 27 | obj-$(CONFIG_LOCK_KERNEL) += kernel_lock.o |
27 | obj-$(CONFIG_DEBUG_PREEMPT) += smp_processor_id.o | 28 | obj-$(CONFIG_DEBUG_PREEMPT) += smp_processor_id.o |
28 | 29 | ||
29 | ifneq ($(CONFIG_HAVE_DEC_LOCK),y) | 30 | ifneq ($(CONFIG_HAVE_DEC_LOCK),y) |
30 | lib-y += dec_and_lock.o | 31 | lib-y += dec_and_lock.o |
31 | endif | 32 | endif |
32 | 33 | ||
33 | obj-$(CONFIG_CRC_CCITT) += crc-ccitt.o | 34 | obj-$(CONFIG_CRC_CCITT) += crc-ccitt.o |
34 | obj-$(CONFIG_CRC16) += crc16.o | 35 | obj-$(CONFIG_CRC16) += crc16.o |
35 | obj-$(CONFIG_CRC32) += crc32.o | 36 | obj-$(CONFIG_CRC32) += crc32.o |
36 | obj-$(CONFIG_LIBCRC32C) += libcrc32c.o | 37 | obj-$(CONFIG_LIBCRC32C) += libcrc32c.o |
37 | obj-$(CONFIG_GENERIC_IOMAP) += iomap.o | 38 | obj-$(CONFIG_GENERIC_IOMAP) += iomap.o |
38 | obj-$(CONFIG_GENERIC_ALLOCATOR) += genalloc.o | 39 | obj-$(CONFIG_GENERIC_ALLOCATOR) += genalloc.o |
39 | 40 | ||
40 | obj-$(CONFIG_ZLIB_INFLATE) += zlib_inflate/ | 41 | obj-$(CONFIG_ZLIB_INFLATE) += zlib_inflate/ |
41 | obj-$(CONFIG_ZLIB_DEFLATE) += zlib_deflate/ | 42 | obj-$(CONFIG_ZLIB_DEFLATE) += zlib_deflate/ |
42 | obj-$(CONFIG_REED_SOLOMON) += reed_solomon/ | 43 | obj-$(CONFIG_REED_SOLOMON) += reed_solomon/ |
43 | 44 | ||
44 | obj-$(CONFIG_TEXTSEARCH) += textsearch.o | 45 | obj-$(CONFIG_TEXTSEARCH) += textsearch.o |
45 | obj-$(CONFIG_TEXTSEARCH_KMP) += ts_kmp.o | 46 | obj-$(CONFIG_TEXTSEARCH_KMP) += ts_kmp.o |
46 | obj-$(CONFIG_TEXTSEARCH_BM) += ts_bm.o | 47 | obj-$(CONFIG_TEXTSEARCH_BM) += ts_bm.o |
47 | obj-$(CONFIG_TEXTSEARCH_FSM) += ts_fsm.o | 48 | obj-$(CONFIG_TEXTSEARCH_FSM) += ts_fsm.o |
48 | 49 | ||
49 | obj-$(CONFIG_SWIOTLB) += swiotlb.o | 50 | obj-$(CONFIG_SWIOTLB) += swiotlb.o |
50 | 51 | ||
51 | hostprogs-y := gen_crc32table | 52 | hostprogs-y := gen_crc32table |
52 | clean-files := crc32table.h | 53 | clean-files := crc32table.h |
53 | 54 | ||
54 | $(obj)/crc32.o: $(obj)/crc32table.h | 55 | $(obj)/crc32.o: $(obj)/crc32table.h |
55 | 56 | ||
56 | quiet_cmd_crc32 = GEN $@ | 57 | quiet_cmd_crc32 = GEN $@ |
57 | cmd_crc32 = $< > $@ | 58 | cmd_crc32 = $< > $@ |
58 | 59 | ||
59 | $(obj)/crc32table.h: $(obj)/gen_crc32table | 60 | $(obj)/crc32table.h: $(obj)/gen_crc32table |
60 | $(call cmd,crc32) | 61 | $(call cmd,crc32) |
61 | 62 |
lib/hweight.c
File was created | 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); | ||
55 |