Browse code

core: bit conting and testing functions

new functions for bit operations:
- bit_count()
- bit_test()
- bit_test_and_set()

Miklos Tirpak authored on 19/05/2010 09:53:19
Showing 3 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,44 @@
0
+/*
1
+ * $Id$
2
+ *
3
+ * Copyright (C) 2010 iptelorg GmbH
4
+ *
5
+ * Permission to use, copy, modify, and distribute this software for any
6
+ * purpose with or without fee is hereby granted, provided that the above
7
+ * copyright notice and this permission notice appear in all copies.
8
+ *
9
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
+ *
17
+ * History
18
+ * -------
19
+ *  2010-04-26	Initial version (Miklos)
20
+ */
21
+
22
+#include "bit_count.h"
23
+
24
+#if 0
25
+/* number of bits in a byte */
26
+int	bits_in_char[256] = {
27
+			0 ,1 ,1 ,2 ,1 ,2 ,2 ,3 ,1 ,2 ,2 ,3 ,2 ,3 ,3 ,4 ,
28
+			1 ,2 ,2 ,3 ,2 ,3 ,3 ,4 ,2 ,3 ,3 ,4 ,3 ,4 ,4 ,5 ,
29
+			1 ,2 ,2 ,3 ,2 ,3 ,3 ,4 ,2 ,3 ,3 ,4 ,3 ,4 ,4 ,5 ,
30
+			2 ,3 ,3 ,4 ,3 ,4 ,4 ,5 ,3 ,4 ,4 ,5 ,4 ,5 ,5 ,6 ,
31
+			1 ,2 ,2 ,3 ,2 ,3 ,3 ,4 ,2 ,3 ,3 ,4 ,3 ,4 ,4 ,5 ,
32
+			2 ,3 ,3 ,4 ,3 ,4 ,4 ,5 ,3 ,4 ,4 ,5 ,4 ,5 ,5 ,6 ,
33
+			2 ,3 ,3 ,4 ,3 ,4 ,4 ,5 ,3 ,4 ,4 ,5 ,4 ,5 ,5 ,6 ,
34
+			3 ,4 ,4 ,5 ,4 ,5 ,5 ,6 ,4 ,5 ,5 ,6 ,5 ,6 ,6 ,7 ,
35
+			1 ,2 ,2 ,3 ,2 ,3 ,3 ,4 ,2 ,3 ,3 ,4 ,3 ,4 ,4 ,5 ,
36
+			2 ,3 ,3 ,4 ,3 ,4 ,4 ,5 ,3 ,4 ,4 ,5 ,4 ,5 ,5 ,6 ,
37
+			2 ,3 ,3 ,4 ,3 ,4 ,4 ,5 ,3 ,4 ,4 ,5 ,4 ,5 ,5 ,6 ,
38
+			3 ,4 ,4 ,5 ,4 ,5 ,5 ,6 ,4 ,5 ,5 ,6 ,5 ,6 ,6 ,7 ,
39
+			2 ,3 ,3 ,4 ,3 ,4 ,4 ,5 ,3 ,4 ,4 ,5 ,4 ,5 ,5 ,6 ,
40
+			3 ,4 ,4 ,5 ,4 ,5 ,5 ,6 ,4 ,5 ,5 ,6 ,5 ,6 ,6 ,7 ,
41
+			3 ,4 ,4 ,5 ,4 ,5 ,5 ,6 ,4 ,5 ,5 ,6 ,5 ,6 ,6 ,7 ,
42
+			4 ,5 ,5 ,6 ,5 ,6 ,6 ,7 ,5 ,6 ,6 ,7 ,6 ,7 ,7 ,8 };
43
+#endif
0 44
new file mode 100644
... ...
@@ -0,0 +1,101 @@
0
+/*
1
+ * $Id$
2
+ *
3
+ * Copyright (C) 2010 iptelorg GmbH
4
+ *
5
+ * Permission to use, copy, modify, and distribute this software for any
6
+ * purpose with or without fee is hereby granted, provided that the above
7
+ * copyright notice and this permission notice appear in all copies.
8
+ *
9
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
+ *
17
+ * History
18
+ * -------
19
+ *  2010-04-26	Initial version (Miklos)
20
+ */
21
+
22
+/* Implements the bit counting function:
23
+ *   int bit_count(unsigned int u)
24
+ *   Returns the number of bits in u.
25
+ */
26
+
27
+#ifndef _BIT_COUNT_H
28
+#define _BIT_COUNT_H
29
+
30
+/* fix __CPU_i386 -> __CPU_x86 */
31
+#if defined __CPU_i386 && ! defined __CPU_x86
32
+#define __CPU_x86
33
+#endif
34
+ 
35
+#ifdef CC_GCC_LIKE_ASM
36
+#if defined __CPU_x86 || defined __CPU_x86_64
37
+#ifdef __SSE4_2__
38
+/* popcnt requires SSE4.2 support,
39
+ * see http://en.wikipedia.org/wiki/SSE4 */
40
+#define BIT_COUNT_ASM
41
+#endif
42
+#endif
43
+#endif
44
+
45
+#ifdef BIT_COUNT_ASM
46
+
47
+/* Returns the number of 1 bits in u. */
48
+static inline int bit_count(unsigned int u)
49
+{
50
+	int	v;
51
+
52
+	asm volatile(" popcnt %1, %0 " : "=r" (v) : "rm" (u));
53
+	return v;
54
+}
55
+
56
+#else /* BIT_COUNT_ASM */
57
+
58
+/* Returns the number of 1 bits in u.
59
+ * source: http://en.wikipedia.org/wiki/Hamming_weight
60
+ */
61
+#if 0
62
+static inline int bit_count(unsigned int u)
63
+{
64
+	int	count;
65
+
66
+	/* It is likely to have only few
67
+	 * bits set to 1, so there will be only
68
+	 * few iterations */
69
+	for (count=0; u; count++)
70
+		u &= u-1;
71
+	return count;
72
+}
73
+#endif
74
+
75
+static inline int bit_count(unsigned int i)
76
+{
77
+	i = i - ((i >> 1) & 0x55555555);
78
+	i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
79
+	return (((i + (i >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24;
80
+}
81
+
82
+#if 0
83
+/* number of bits in a byte.
84
+ * (Only slightly faster then the above version,
85
+ * It is not worth the extra memory usage.)
86
+ */
87
+extern int	bits_in_char[256];
88
+
89
+static inline int bit_count(unsigned int u)
90
+{
91
+	return bits_in_char [u & 0xffu]
92
+		+  bits_in_char [(u >>  8 ) & 0xffu]
93
+		+  bits_in_char [(u >> 16) & 0xffu]
94
+		+  bits_in_char [(u >> 24) & 0xffu];
95
+}
96
+#endif
97
+
98
+#endif /* BIT_COUNT_ASM */
99
+
100
+#endif /* _BIT_COUNT_H */
0 101
new file mode 100644
... ...
@@ -0,0 +1,121 @@
0
+/*
1
+ * $Id$
2
+ *
3
+ * Copyright (C) 2010 iptelorg GmbH
4
+ *
5
+ * Permission to use, copy, modify, and distribute this software for any
6
+ * purpose with or without fee is hereby granted, provided that the above
7
+ * copyright notice and this permission notice appear in all copies.
8
+ *
9
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
+ *
17
+ * History
18
+ * -------
19
+ *  2010-04-26	Initial version (Miklos)
20
+ */
21
+
22
+/* Bit test functions:
23
+ *  - int bit_test(int offset, unsigned int *addr)
24
+ *      Returns the bit found at offset position 
25
+ *      in a bitstring pointed by addr.
26
+ *
27
+ *  - int bit_test_and_set(int offset, unsigned int *addr)
28
+ *      Returns the bit found at offset position 
29
+ *      in a bitstring pointed by addr, and sets
30
+ *      the bit at the given offset.
31
+ *
32
+ * Note that 0 <= offset <= 128, Make sure that addr points to
33
+ * a large enough memory area.
34
+ */
35
+
36
+#ifndef _BIT_TEST_H
37
+#define _BIT_TEST_H
38
+
39
+/* fix __CPU_i386 -> __CPU_x86 */
40
+#if defined __CPU_i386 && ! defined __CPU_x86
41
+#define __CPU_x86
42
+#endif
43
+ 
44
+#ifdef CC_GCC_LIKE_ASM
45
+#if defined __CPU_x86 || defined __CPU_x86_64
46
+#define BIT_TEST_ASM
47
+#endif
48
+#endif
49
+
50
+#ifdef BIT_TEST_ASM
51
+
52
+/* Returns the bit found at offset position in the bitstring
53
+ * pointed by addr.
54
+ * Note that the CPU can access 4 bytes starting from addr,
55
+ * hence 0 <= offset < 128 holds. Make sure that addr points
56
+ * to a memory area that is large enough.
57
+ */
58
+static inline int bit_test(int offset, unsigned int *addr)
59
+{
60
+	unsigned char	v;
61
+
62
+	asm volatile(
63
+		" bt %2, %1 \n\t"
64
+		" setc %0 \n\t"
65
+		: "=qm" (v) : "m" (*addr), "r" (offset)
66
+	);
67
+	return (int)v;
68
+}
69
+
70
+/* Returns the bit found at offset position in the bitstring
71
+ * pointed by addr and sets it to 1.
72
+ * Note that the CPU can access 4 bytes starting from addr,
73
+ * hence 0 <= offset < 128 holds. Make sure that addr points
74
+ * to a memory area that is large enough.
75
+ */
76
+static inline int bit_test_and_set(int offset, unsigned int *addr)
77
+{
78
+	unsigned char	v;
79
+
80
+	asm volatile(
81
+		" bts %2, %1 \n\t"
82
+		" setc %0 \n\t"
83
+		: "=qm" (v) : "m" (*addr), "r" (offset)
84
+	);
85
+	return (int)v;
86
+}
87
+
88
+#else /* BIT_TEST_ASM */
89
+
90
+/* Returns the bit found at offset position in the bitstring
91
+ * pointed by addr.
92
+ * Note that offset can be grater than 32, make sure that addr points
93
+ * to a memory area that is large enough.
94
+ */
95
+static inline int bit_test(int offset, unsigned int *addr)
96
+{
97
+	return ((*(addr + offset/32)) & (1U << (offset % 32))) ? 1 : 0;
98
+}
99
+
100
+/* Returns the bit found at offset position in the bitstring
101
+ * pointed by addr and sets it to 1.
102
+ * Note that offset can be grater than 32, make sure that addr points
103
+ * to a memory area that is large enough.
104
+ */
105
+static inline int bit_test_and_set(int offset, unsigned int *addr)
106
+{
107
+	unsigned int	*i;
108
+	int	mask, res;
109
+
110
+	i = addr + offset/32;
111
+	mask = 1U << (offset % 32);
112
+	res = ((*i) & mask) ? 1 : 0;
113
+	(*i) |= mask;
114
+
115
+	return res;
116
+}
117
+
118
+#endif /* BIT_TEST_ASM */
119
+
120
+#endif /* #ifndef _BIT_TEST_H */