This source file includes following definitions.
- set_bit
- clear_bit
- change_bit
- test_bit
- ffz
- find_next_zero_bit
1 #ifndef _SPARC_BITOPS_H
2 #define _SPARC_BITOPS_H
3
4 #include <linux/kernel.h>
5 #include <asm/system.h>
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 extern __inline__ unsigned int set_bit(unsigned int nr, void *vaddr)
41 {
42
43
44 #ifdef LITTLE_ENDIAN_BITOPS
45
46
47 int retval;
48 unsigned char *addr = (unsigned char *)vaddr;
49 unsigned char mask;
50 #ifndef TEST_BITOPS
51 unsigned long flags;
52 #endif
53
54 addr += nr >> 3;
55 mask = 1 << (nr & 0x7);
56
57 #ifndef TEST_BITOPS
58 save_flags(flags);
59 cli();
60 #endif
61
62 retval = (mask & *addr) != 0;
63 *addr |= mask;
64
65 #ifndef TEST_BITOPS
66 restore_flags(flags);
67 #endif
68
69 return retval;
70
71 #else
72
73
74 int retval;
75 unsigned long *addr = vaddr;
76 unsigned long mask;
77 #ifndef TEST_BITOPS
78 unsigned long flags;
79 #endif
80
81 addr += nr>>5;
82 mask = 1 << (nr&31);
83
84 #ifndef TEST_BITOPS
85 save_flags(flags);
86 cli();
87 #endif
88
89 retval = (mask & *addr) != 0;
90 *addr |= mask;
91
92 #ifndef TEST_BITOPS
93 restore_flags(flags);
94 #endif
95
96 return retval;
97
98
99 #endif
100 }
101
102 extern __inline__ unsigned int clear_bit(unsigned int nr, void *vaddr)
103 {
104 #ifdef LITTLE_ENDIAN_BITOPS
105
106
107 int retval;
108 unsigned char *addr = (unsigned char *)vaddr;
109 unsigned char mask;
110 #ifndef TEST_BITOPS
111 unsigned long flags;
112 #endif
113
114 addr += nr >> 3;
115 mask = 1 << (nr & 7);
116
117 #ifndef TEST_BITOPS
118 save_flags(flags);
119 cli();
120 #endif
121
122 retval = (mask & *addr) != 0;
123 *addr &= ~mask;
124
125 #ifndef TEST_BITOPS
126 restore_flags(flags);
127 #endif
128
129 return retval;
130
131
132 #else
133
134
135 int retval;
136 unsigned long *addr = vaddr;
137 unsigned long mask;
138 #ifndef TEST_BITOPS
139 unsigned long flags;
140 #endif
141
142 addr += nr>>5;
143 mask = 1 << (nr&31);
144
145 #ifndef TEST_BITOPS
146 save_flags(flags);
147 cli();
148 #endif
149
150 retval = (mask & *addr) != 0;
151 *addr &= ~mask;
152
153 #ifndef TEST_BITOPS
154 restore_flags(flags);
155 #endif
156
157 return retval;
158
159
160 #endif
161 }
162
163 extern __inline__ unsigned int change_bit(unsigned int nr, void *vaddr)
164 {
165 #ifdef LITTLE_ENDIAN_BITOPS
166
167
168 int retval;
169 unsigned char *addr = (unsigned char *)vaddr;
170 unsigned char mask;
171 #ifndef TEST_BITOPS
172 unsigned long flags;
173 #endif
174
175 addr += nr >> 3;
176 mask = 1 << (nr & 7);
177
178 #ifndef TEST_BITOPS
179 save_flags(flags);
180 cli();
181 #endif
182
183 retval = (mask & *addr) != 0;
184 *addr ^= mask;
185
186 #ifndef TEST_BITOPS
187 restore_flags(flags);
188 #endif
189
190 return retval;
191
192
193 #else
194
195
196 int retval;
197 unsigned long *addr = vaddr;
198 unsigned long mask;
199 #ifndef TEST_BITOPS
200 unsigned long flags;
201 #endif
202
203 addr += nr>>5;
204 mask = 1 << (nr&31);
205
206 #ifndef TEST_BITOPS
207 save_flags(flags);
208 cli();
209 #endif
210
211 retval = (mask & *addr) != 0;
212 *addr ^= mask;
213
214 #ifndef TEST_BITOPS
215 restore_flags(flags);
216 #endif
217
218 return retval;
219
220
221 #endif
222 }
223
224
225
226 extern __inline__ unsigned int test_bit(int nr, void *vaddr)
227 {
228 #ifdef LITTLE_ENDIAN_BITOPS
229
230 unsigned char mask;
231 unsigned char *addr = (unsigned char *)vaddr;
232
233 addr += nr >> 3;
234 mask = 1 << (nr & 7);
235 return ((mask & *addr) != 0);
236
237 #else
238
239 unsigned long mask;
240 unsigned long *addr = vaddr;
241
242 addr += (nr>>5);
243 mask = 1 << (nr&31);
244 return ((mask & *addr) != 0);
245
246 #endif
247 }
248
249
250
251 extern __inline__ unsigned long ffz(unsigned long word)
252 {
253 register unsigned long cnt;
254
255 cnt = 0;
256
257 #ifdef LITTLE_ENDIAN_BITOPS
258
259 for(int byte_bit = 24; byte_bit >=0; byte_bit -= 8)
260 for(int bit = 0; bit<8; bit++)
261 if((word>>(byte_bit+bit))&1)
262 cnt++;
263 else
264 return cnt;
265
266 #else
267 while(cnt<32) {
268 if(!((word>>cnt)&1))
269 return cnt;
270 else
271 cnt++;
272 }
273 return cnt;
274 #endif
275
276 }
277
278
279
280
281
282
283 extern __inline__ unsigned long
284 find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
285 {
286 #ifdef LITTLE_ENDIAN_BITOPS
287
288
289
290 #else
291 unsigned long *p = ((unsigned long *) addr) + (offset >> 6);
292 unsigned long result = offset & ~31UL;
293 unsigned long tmp;
294
295 if (offset >= size)
296 return size;
297 size -= result;
298 offset &= 31UL;
299 if (offset)
300 {
301 tmp = *(p++);
302 tmp |= ~0UL >> (32-offset);
303 if (size < 32)
304 goto found_first;
305 if (~tmp)
306 goto found_middle;
307 size -= 32;
308 result += 32;
309 }
310 while (size & ~32UL)
311 {
312 if (~(tmp = *(p++)))
313 goto found_middle;
314 result += 32;
315 size -= 32;
316 }
317 if (!size)
318 return result;
319 tmp = *p;
320
321 found_first:
322 tmp |= ~0UL << size;
323 found_middle:
324 return result + ffz(tmp);
325 #endif
326 }
327
328
329
330
331
332 #define find_first_zero_bit(addr, size) \
333 find_next_zero_bit((addr), (size), 0)
334
335
336 #endif
337