1#ifndef _PARISC_BITOPS_H
2#define _PARISC_BITOPS_H
3
4#include <linux/compiler.h>
5#include <asm/system.h>
6#include <asm/byteorder.h>
7#include <asm/atomic.h>
8
9
10
11
12
13
14
15#ifdef __LP64__
16# define SHIFT_PER_LONG 6
17#ifndef BITS_PER_LONG
18# define BITS_PER_LONG 64
19#endif
20#else
21# define SHIFT_PER_LONG 5
22#ifndef BITS_PER_LONG
23# define BITS_PER_LONG 32
24#endif
25#endif
26
27#define CHOP_SHIFTCOUNT(x) ((x) & (BITS_PER_LONG - 1))
28
29
30#define smp_mb__before_clear_bit() smp_mb()
31#define smp_mb__after_clear_bit() smp_mb()
32
33static __inline__ void set_bit(int nr, void * address)
34{
35 unsigned long mask;
36 unsigned long *addr = (unsigned long *) address;
37 unsigned long flags;
38
39 addr += (nr >> SHIFT_PER_LONG);
40 mask = 1L << CHOP_SHIFTCOUNT(nr);
41 SPIN_LOCK_IRQSAVE(ATOMIC_HASH(addr), flags);
42 *addr |= mask;
43 SPIN_UNLOCK_IRQRESTORE(ATOMIC_HASH(addr), flags);
44}
45
46static __inline__ void __set_bit(int nr, void * address)
47{
48 unsigned long mask;
49 unsigned long *addr = (unsigned long *) address;
50
51 addr += (nr >> SHIFT_PER_LONG);
52 mask = 1L << CHOP_SHIFTCOUNT(nr);
53 *addr |= mask;
54}
55
56static __inline__ void clear_bit(int nr, void * address)
57{
58 unsigned long mask;
59 unsigned long *addr = (unsigned long *) address;
60 unsigned long flags;
61
62 addr += (nr >> SHIFT_PER_LONG);
63 mask = 1L << CHOP_SHIFTCOUNT(nr);
64 SPIN_LOCK_IRQSAVE(ATOMIC_HASH(addr), flags);
65 *addr &= ~mask;
66 SPIN_UNLOCK_IRQRESTORE(ATOMIC_HASH(addr), flags);
67}
68
69static __inline__ void __clear_bit(unsigned long nr, volatile void * address)
70{
71 unsigned long mask;
72 unsigned long *addr = (unsigned long *) address;
73
74 addr += (nr >> SHIFT_PER_LONG);
75 mask = 1L << CHOP_SHIFTCOUNT(nr);
76 *addr &= ~mask;
77}
78
79static __inline__ void change_bit(int nr, void * address)
80{
81 unsigned long mask;
82 unsigned long *addr = (unsigned long *) address;
83 unsigned long flags;
84
85 addr += (nr >> SHIFT_PER_LONG);
86 mask = 1L << CHOP_SHIFTCOUNT(nr);
87 SPIN_LOCK_IRQSAVE(ATOMIC_HASH(addr), flags);
88 *addr ^= mask;
89 SPIN_UNLOCK_IRQRESTORE(ATOMIC_HASH(addr), flags);
90}
91
92static __inline__ void __change_bit(int nr, void * address)
93{
94 unsigned long mask;
95 unsigned long *addr = (unsigned long *) address;
96
97 addr += (nr >> SHIFT_PER_LONG);
98 mask = 1L << CHOP_SHIFTCOUNT(nr);
99 *addr ^= mask;
100}
101
102static __inline__ int test_and_set_bit(int nr, void * address)
103{
104 unsigned long mask;
105 unsigned long *addr = (unsigned long *) address;
106 int oldbit;
107 unsigned long flags;
108
109 addr += (nr >> SHIFT_PER_LONG);
110 mask = 1L << CHOP_SHIFTCOUNT(nr);
111 SPIN_LOCK_IRQSAVE(ATOMIC_HASH(addr), flags);
112 oldbit = (*addr & mask) ? 1 : 0;
113 *addr |= mask;
114 SPIN_UNLOCK_IRQRESTORE(ATOMIC_HASH(addr), flags);
115
116 return oldbit;
117}
118
119static __inline__ int __test_and_set_bit(int nr, void * address)
120{
121 unsigned long mask;
122 unsigned long *addr = (unsigned long *) address;
123 int oldbit;
124
125 addr += (nr >> SHIFT_PER_LONG);
126 mask = 1L << CHOP_SHIFTCOUNT(nr);
127 oldbit = (*addr & mask) ? 1 : 0;
128 *addr |= mask;
129
130 return oldbit;
131}
132
133static __inline__ int test_and_clear_bit(int nr, void * address)
134{
135 unsigned long mask;
136 unsigned long *addr = (unsigned long *) address;
137 int oldbit;
138 unsigned long flags;
139
140 addr += (nr >> SHIFT_PER_LONG);
141 mask = 1L << CHOP_SHIFTCOUNT(nr);
142 SPIN_LOCK_IRQSAVE(ATOMIC_HASH(addr), flags);
143 oldbit = (*addr & mask) ? 1 : 0;
144 *addr &= ~mask;
145 SPIN_UNLOCK_IRQRESTORE(ATOMIC_HASH(addr), flags);
146
147 return oldbit;
148}
149
150static __inline__ int __test_and_clear_bit(int nr, void * address)
151{
152 unsigned long mask;
153 unsigned long *addr = (unsigned long *) address;
154 int oldbit;
155
156 addr += (nr >> SHIFT_PER_LONG);
157 mask = 1L << CHOP_SHIFTCOUNT(nr);
158 oldbit = (*addr & mask) ? 1 : 0;
159 *addr &= ~mask;
160
161 return oldbit;
162}
163
164static __inline__ int test_and_change_bit(int nr, void * address)
165{
166 unsigned long mask;
167 unsigned long *addr = (unsigned long *) address;
168 int oldbit;
169 unsigned long flags;
170
171 addr += (nr >> SHIFT_PER_LONG);
172 mask = 1L << CHOP_SHIFTCOUNT(nr);
173 SPIN_LOCK_IRQSAVE(ATOMIC_HASH(addr), flags);
174 oldbit = (*addr & mask) ? 1 : 0;
175 *addr ^= mask;
176 SPIN_UNLOCK_IRQRESTORE(ATOMIC_HASH(addr), flags);
177
178 return oldbit;
179}
180
181static __inline__ int __test_and_change_bit(int nr, void * address)
182{
183 unsigned long mask;
184 unsigned long *addr = (unsigned long *) address;
185 int oldbit;
186
187 addr += (nr >> SHIFT_PER_LONG);
188 mask = 1L << CHOP_SHIFTCOUNT(nr);
189 oldbit = (*addr & mask) ? 1 : 0;
190 *addr ^= mask;
191
192 return oldbit;
193}
194
195static __inline__ int test_bit(int nr, const void *address)
196{
197 unsigned long mask;
198 unsigned long *addr = (unsigned long *) address;
199
200 addr += (nr >> SHIFT_PER_LONG);
201 mask = 1L << CHOP_SHIFTCOUNT(nr);
202
203 return !!(*addr & mask);
204}
205
206extern __inline__ unsigned long ffz(unsigned long word)
207{
208 unsigned long result;
209
210 result = 0;
211 while (word & 1) {
212 result++;
213 word >>= 1;
214 }
215
216 return result;
217}
218
219#ifdef __KERNEL__
220
221
222
223
224
225
226
227static __inline__ unsigned long __ffs(unsigned long word)
228{
229 unsigned long result = 0;
230
231 while (!(word & 1UL)) {
232 result++;
233 word >>= 1;
234 }
235 return result;
236}
237
238
239
240
241
242
243static __inline__ int ffs(int x)
244{
245 if (!x)
246 return 0;
247 return __ffs((unsigned long)x);
248}
249
250
251
252
253
254#define fls(x) generic_fls(x)
255
256
257
258
259
260
261#define hweight32(x) generic_hweight32(x)
262#define hweight16(x) generic_hweight16(x)
263#define hweight8(x) generic_hweight8(x)
264
265
266
267
268
269
270
271static inline int sched_find_first_bit(unsigned long *b)
272{
273#ifndef __LP64__
274 if (unlikely(b[0]))
275 return __ffs(b[0]);
276 if (unlikely(b[1]))
277 return __ffs(b[1]) + 32;
278 if (unlikely(b[2]))
279 return __ffs(b[2]) + 64;
280 if (b[3])
281 return __ffs(b[3]) + 96;
282 return __ffs(b[4]) + 128;
283#else
284 if (unlikely(b[0]))
285 return __ffs(b[0]);
286 if (unlikely(((unsigned int)b[1])))
287 return __ffs(b[1]) + 64;
288 if (b[1] >> 32)
289 return __ffs(b[1] >> 32) + 96;
290 return __ffs(b[2]) + 128;
291#endif
292}
293
294#endif
295
296
297
298
299
300#define find_first_zero_bit(addr, size) \
301 find_next_zero_bit((addr), (size), 0)
302
303static __inline__ unsigned long find_next_zero_bit(void * addr, unsigned long size, unsigned long offset)
304{
305 unsigned long * p = ((unsigned long *) addr) + (offset >> SHIFT_PER_LONG);
306 unsigned long result = offset & ~(BITS_PER_LONG-1);
307 unsigned long tmp;
308
309 if (offset >= size)
310 return size;
311 size -= result;
312 offset &= (BITS_PER_LONG-1);
313 if (offset) {
314 tmp = *(p++);
315 tmp |= ~0UL >> (BITS_PER_LONG-offset);
316 if (size < BITS_PER_LONG)
317 goto found_first;
318 if (~tmp)
319 goto found_middle;
320 size -= BITS_PER_LONG;
321 result += BITS_PER_LONG;
322 }
323 while (size & ~(BITS_PER_LONG -1)) {
324 if (~(tmp = *(p++)))
325 goto found_middle;
326 result += BITS_PER_LONG;
327 size -= BITS_PER_LONG;
328 }
329 if (!size)
330 return result;
331 tmp = *p;
332found_first:
333 tmp |= ~0UL << size;
334found_middle:
335 return result + ffz(tmp);
336}
337
338static __inline__ unsigned long find_next_bit(unsigned long *addr, unsigned long size, unsigned long offset)
339{
340 unsigned long *p = addr + (offset >> 6);
341 unsigned long result = offset & ~(BITS_PER_LONG-1);
342 unsigned long tmp;
343
344 if (offset >= size)
345 return size;
346 size -= result;
347 offset &= (BITS_PER_LONG-1);
348 if (offset) {
349 tmp = *(p++);
350 tmp &= (~0UL << offset);
351 if (size < BITS_PER_LONG)
352 goto found_first;
353 if (tmp)
354 goto found_middle;
355 size -= BITS_PER_LONG;
356 result += BITS_PER_LONG;
357 }
358 while (size & ~(BITS_PER_LONG-1)) {
359 if ((tmp = *(p++)))
360 goto found_middle;
361 result += BITS_PER_LONG;
362 size -= BITS_PER_LONG;
363 }
364 if (!size)
365 return result;
366 tmp = *p;
367
368found_first:
369 tmp &= (~0UL >> (BITS_PER_LONG - size));
370 if (tmp == 0UL)
371 return result + size;
372found_middle:
373 return result + __ffs(tmp);
374}
375
376#define _EXT2_HAVE_ASM_BITOPS_
377
378#ifdef __KERNEL__
379
380
381
382
383#ifdef __LP64__
384#define ext2_set_bit(nr, addr) test_and_set_bit((nr) ^ 0x38, addr)
385#define ext2_clear_bit(nr, addr) test_and_clear_bit((nr) ^ 0x38, addr)
386#else
387#define ext2_set_bit(nr, addr) test_and_set_bit((nr) ^ 0x18, addr)
388#define ext2_clear_bit(nr, addr) test_and_clear_bit((nr) ^ 0x18, addr)
389#endif
390
391#endif
392
393static __inline__ int ext2_test_bit(int nr, __const__ void * addr)
394{
395 __const__ unsigned char *ADDR = (__const__ unsigned char *) addr;
396
397 return (ADDR[nr >> 3] >> (nr & 7)) & 1;
398}
399
400
401
402
403
404
405#define ext2_find_first_zero_bit(addr, size) \
406 ext2_find_next_zero_bit((addr), (size), 0)
407
408extern __inline__ unsigned long ext2_find_next_zero_bit(void *addr,
409 unsigned long size, unsigned long offset)
410{
411 unsigned int *p = ((unsigned int *) addr) + (offset >> 5);
412 unsigned int result = offset & ~31UL;
413 unsigned int tmp;
414
415 if (offset >= size)
416 return size;
417 size -= result;
418 offset &= 31UL;
419 if (offset) {
420 tmp = cpu_to_le32p(p++);
421 tmp |= ~0UL >> (32-offset);
422 if (size < 32)
423 goto found_first;
424 if (tmp != ~0U)
425 goto found_middle;
426 size -= 32;
427 result += 32;
428 }
429 while (size >= 32) {
430 if ((tmp = cpu_to_le32p(p++)) != ~0U)
431 goto found_middle;
432 result += 32;
433 size -= 32;
434 }
435 if (!size)
436 return result;
437 tmp = cpu_to_le32p(p);
438found_first:
439 tmp |= ~0U << size;
440found_middle:
441 return result + ffz(tmp);
442}
443
444
445#define minix_test_and_set_bit(nr,addr) ext2_set_bit(nr,addr)
446#define minix_set_bit(nr,addr) ((void)ext2_set_bit(nr,addr))
447#define minix_test_and_clear_bit(nr,addr) ext2_clear_bit(nr,addr)
448#define minix_test_bit(nr,addr) ext2_test_bit(nr,addr)
449#define minix_find_first_zero_bit(addr,size) ext2_find_first_zero_bit(addr,size)
450
451#endif
452