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