Browse code

bit test: bit_test_and_reset() added

The function returns the bit found at offset position
in a bitstring and resets the bit to 0.

Miklos Tirpak authored on 05/01/2011 10:40:20
Showing 1 changed files
... ...
@@ -18,6 +18,7 @@
18 18
  * History
19 19
  * -------
20 20
  *  2010-04-26	Initial version (Miklos)
21
+ *  2011-01-05	bit_test_and_reset added (Miklos)
21 22
  */
22 23
 
23 24
 /* Bit test functions:
... ...
@@ -30,6 +31,11 @@
30 31
  *      in a bitstring pointed by addr, and sets
31 32
  *      the bit at the given offset.
32 33
  *
34
+ *  - int bit_test_and_reset(int offset, unsigned int *addr)
35
+ *      Returns the bit found at offset position 
36
+ *      in a bitstring pointed by addr, and resets
37
+ *      the bit at the given offset.
38
+ *
33 39
  * Note that 0 <= offset <= 128, Make sure that addr points to
34 40
  * a large enough memory area.
35 41
  */
... ...
@@ -86,6 +92,24 @@ static inline int bit_test_and_set(int offset, unsigned int *addr)
86 92
 	return (int)v;
87 93
 }
88 94
 
95
+/* Returns the bit found at offset position in the bitstring
96
+ * pointed by addr and resets it to 0.
97
+ * Note that the CPU can access 4 bytes starting from addr,
98
+ * hence 0 <= offset < 128 holds. Make sure that addr points
99
+ * to a memory area that is large enough.
100
+ */
101
+static inline int bit_test_and_reset(int offset, unsigned int *addr)
102
+{
103
+	unsigned char	v;
104
+
105
+	asm volatile(
106
+		" btr %2, %1 \n\t"
107
+		" setc %0 \n\t"
108
+		: "=qm" (v) : "m" (*addr), "r" (offset)
109
+	);
110
+	return (int)v;
111
+}
112
+
89 113
 #else /* BIT_TEST_ASM */
90 114
 
91 115
 /* Returns the bit found at offset position in the bitstring
... ...
@@ -116,6 +140,24 @@ static inline int bit_test_and_set(int offset, unsigned int *addr)
116 140
 	return res;
117 141
 }
118 142
 
143
+/* Returns the bit found at offset position in the bitstring
144
+ * pointed by addr and resets it to 0.
145
+ * Note that offset can be grater than 32, make sure that addr points
146
+ * to a memory area that is large enough.
147
+ */
148
+static inline int bit_test_and_reset(int offset, unsigned int *addr)
149
+{
150
+	unsigned int	*i;
151
+	int	mask, res;
152
+
153
+	i = addr + offset/32;
154
+	mask = 1U << (offset % 32);
155
+	res = ((*i) & mask) ? 1 : 0;
156
+	(*i) &= ~mask;
157
+
158
+	return res;
159
+}
160
+
119 161
 #endif /* BIT_TEST_ASM */
120 162
 
121 163
 #endif /* #ifndef _BIT_TEST_H */