1 /* $Id: bitops.h,v 1.67 2001/11/19 18:36:34 davem Exp $
2 * bitops.h: Bit string operations on the Sparc.
4 * Copyright 1995 David S. Miller (davem@caip.rutgers.edu)
5 * Copyright 1996 Eddie C. Dost (ecd@skynet.be)
6 * Copyright 2001 Anton Blanchard (anton@samba.org)
9 #ifndef _SPARC_BITOPS_H
10 #define _SPARC_BITOPS_H
12 #include <linux/kernel.h>
13 #include <asm/byteorder.h>
14 #include <asm/system.h>
19 * Set bit 'nr' in 32-bit quantity at address 'addr' where bit '0'
20 * is in the highest of the four bytes and bit '31' is the high bit
21 * within the first byte. Sparc is BIG-Endian. Unless noted otherwise
22 * all bit-ops return 0 if bit was previously clear and != 0 otherwise.
24 static inline int test_and_set_bit(unsigned long nr, volatile void *addr)
26 register unsigned long mask asm("g2");
27 register unsigned long *ADDR asm("g1");
28 register int tmp1 asm("g3");
29 register int tmp2 asm("g4");
30 register int tmp3 asm("g5");
31 register int tmp4 asm("g7");
33 ADDR = ((unsigned long *) addr) + (nr >> 5);
34 mask = 1 << (nr & 31);
39 " add %%o7, 8, %%o7\n"
40 : "=&r" (mask), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3), "=r" (tmp4)
41 : "0" (mask), "r" (ADDR)
47 static inline void set_bit(unsigned long nr, volatile void *addr)
49 register unsigned long mask asm("g2");
50 register unsigned long *ADDR asm("g1");
51 register int tmp1 asm("g3");
52 register int tmp2 asm("g4");
53 register int tmp3 asm("g5");
54 register int tmp4 asm("g7");
56 ADDR = ((unsigned long *) addr) + (nr >> 5);
57 mask = 1 << (nr & 31);
62 " add %%o7, 8, %%o7\n"
63 : "=&r" (mask), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3), "=r" (tmp4)
64 : "0" (mask), "r" (ADDR)
68 static inline int test_and_clear_bit(unsigned long nr, volatile void *addr)
70 register unsigned long mask asm("g2");
71 register unsigned long *ADDR asm("g1");
72 register int tmp1 asm("g3");
73 register int tmp2 asm("g4");
74 register int tmp3 asm("g5");
75 register int tmp4 asm("g7");
77 ADDR = ((unsigned long *) addr) + (nr >> 5);
78 mask = 1 << (nr & 31);
82 "call ___clear_bit\n\t"
83 " add %%o7, 8, %%o7\n"
84 : "=&r" (mask), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3), "=r" (tmp4)
85 : "0" (mask), "r" (ADDR)
91 static inline void clear_bit(unsigned long nr, volatile void *addr)
93 register unsigned long mask asm("g2");
94 register unsigned long *ADDR asm("g1");
95 register int tmp1 asm("g3");
96 register int tmp2 asm("g4");
97 register int tmp3 asm("g5");
98 register int tmp4 asm("g7");
100 ADDR = ((unsigned long *) addr) + (nr >> 5);
101 mask = 1 << (nr & 31);
103 __asm__ __volatile__(
105 "call ___clear_bit\n\t"
106 " add %%o7, 8, %%o7\n"
107 : "=&r" (mask), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3), "=r" (tmp4)
108 : "0" (mask), "r" (ADDR)
112 static inline int test_and_change_bit(unsigned long nr, volatile void *addr)
114 register unsigned long mask asm("g2");
115 register unsigned long *ADDR asm("g1");
116 register int tmp1 asm("g3");
117 register int tmp2 asm("g4");
118 register int tmp3 asm("g5");
119 register int tmp4 asm("g7");
121 ADDR = ((unsigned long *) addr) + (nr >> 5);
122 mask = 1 << (nr & 31);
124 __asm__ __volatile__(
126 "call ___change_bit\n\t"
127 " add %%o7, 8, %%o7\n"
128 : "=&r" (mask), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3), "=r" (tmp4)
129 : "0" (mask), "r" (ADDR)
135 static inline void change_bit(unsigned long nr, volatile void *addr)
137 register unsigned long mask asm("g2");
138 register unsigned long *ADDR asm("g1");
139 register int tmp1 asm("g3");
140 register int tmp2 asm("g4");
141 register int tmp3 asm("g5");
142 register int tmp4 asm("g7");
144 ADDR = ((unsigned long *) addr) + (nr >> 5);
145 mask = 1 << (nr & 31);
147 __asm__ __volatile__(
149 "call ___change_bit\n\t"
150 " add %%o7, 8, %%o7\n"
151 : "=&r" (mask), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3), "=r" (tmp4)
152 : "0" (mask), "r" (ADDR)
157 * non-atomic versions
159 static inline void __set_bit(int nr, volatile void *addr)
161 unsigned long mask = 1UL << (nr & 0x1f);
162 unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
167 static inline void __clear_bit(int nr, volatile void *addr)
169 unsigned long mask = 1UL << (nr & 0x1f);
170 unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
175 static inline void __change_bit(int nr, volatile void *addr)
177 unsigned long mask = 1UL << (nr & 0x1f);
178 unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
183 static inline int __test_and_set_bit(int nr, volatile void *addr)
185 unsigned long mask = 1UL << (nr & 0x1f);
186 unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
187 unsigned long old = *p;
190 return (old & mask) != 0;
193 static inline int __test_and_clear_bit(int nr, volatile void *addr)
195 unsigned long mask = 1UL << (nr & 0x1f);
196 unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
197 unsigned long old = *p;
200 return (old & mask) != 0;
203 static inline int __test_and_change_bit(int nr, volatile void *addr)
205 unsigned long mask = 1UL << (nr & 0x1f);
206 unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
207 unsigned long old = *p;
210 return (old & mask) != 0;
213 #define smp_mb__before_clear_bit() do { } while(0)
214 #define smp_mb__after_clear_bit() do { } while(0)
216 /* The following routine need not be atomic. */
217 static inline int test_bit(int nr, __const__ void *addr)
219 return (1 & (((__const__ unsigned int *) addr)[nr >> 5] >> (nr & 31))) != 0;
222 /* The easy/cheese version for now. */
223 static inline unsigned long ffz(unsigned long word)
225 unsigned long result = 0;
235 * ffs: find first bit set. This is defined the same way as
236 * the libc and compiler builtin ffs routines, therefore
237 * differs in spirit from the above ffz (man ffs).
239 #define ffs(x) generic_ffs(x)
242 * hweightN: returns the hamming weight (i.e. the number
243 * of bits set) of a N-bit word
245 #define hweight32(x) generic_hweight32(x)
246 #define hweight16(x) generic_hweight16(x)
247 #define hweight8(x) generic_hweight8(x)
250 * find_next_zero_bit() finds the first zero bit in a bit string of length
251 * 'size' bits, starting the search at bit 'offset'. This is largely based
252 * on Linus's ALPHA routines, which are pretty portable BTW.
254 static inline unsigned long find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
256 unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
257 unsigned long result = offset & ~31UL;
266 tmp |= ~0UL >> (32-offset);
274 while (size & ~31UL) {
286 if (tmp == ~0UL) /* Are any bits zero? */
287 return result + size; /* Nope. */
289 return result + ffz(tmp);
293 * Linus sez that gcc can optimize the following correctly, we'll see if this
294 * holds on the Sparc as it does for the ALPHA.
296 #define find_first_zero_bit(addr, size) \
297 find_next_zero_bit((addr), (size), 0)
299 static inline int test_le_bit(int nr, __const__ void * addr)
301 __const__ unsigned char *ADDR = (__const__ unsigned char *) addr;
302 return (ADDR[nr >> 3] >> (nr & 7)) & 1;
306 * non-atomic versions
308 static inline void __set_le_bit(int nr, void *addr)
310 unsigned char *ADDR = (unsigned char *)addr;
313 *ADDR |= 1 << (nr & 0x07);
316 static inline void __clear_le_bit(int nr, void *addr)
318 unsigned char *ADDR = (unsigned char *)addr;
321 *ADDR &= ~(1 << (nr & 0x07));
324 static inline int __test_and_set_le_bit(int nr, void *addr)
327 unsigned char *ADDR = (unsigned char *)addr;
330 mask = 1 << (nr & 0x07);
331 retval = (mask & *ADDR) != 0;
336 static inline int __test_and_clear_le_bit(int nr, void *addr)
339 unsigned char *ADDR = (unsigned char *)addr;
342 mask = 1 << (nr & 0x07);
343 retval = (mask & *ADDR) != 0;
348 static inline unsigned long find_next_zero_le_bit(void *addr, unsigned long size, unsigned long offset)
350 unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
351 unsigned long result = offset & ~31UL;
360 tmp |= __swab32(~0UL >> (32-offset));
368 while(size & ~31UL) {
379 tmp = __swab32(tmp) | (~0UL << size);
380 if (tmp == ~0UL) /* Are any bits zero? */
381 return result + size; /* Nope. */
382 return result + ffz(tmp);
385 return result + ffz(__swab32(tmp));
388 #define find_first_zero_le_bit(addr, size) \
389 find_next_zero_le_bit((addr), (size), 0)
391 #define ext2_set_bit __test_and_set_le_bit
392 #define ext2_clear_bit __test_and_clear_le_bit
393 #define ext2_test_bit test_le_bit
394 #define ext2_find_first_zero_bit find_first_zero_le_bit
395 #define ext2_find_next_zero_bit find_next_zero_le_bit
397 /* Bitmap functions for the minix filesystem. */
398 #define minix_test_and_set_bit(nr,addr) test_and_set_bit(nr,addr)
399 #define minix_set_bit(nr,addr) set_bit(nr,addr)
400 #define minix_test_and_clear_bit(nr,addr) test_and_clear_bit(nr,addr)
401 #define minix_test_bit(nr,addr) test_bit(nr,addr)
402 #define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
404 #endif /* __KERNEL__ */
406 #endif /* defined(_SPARC_BITOPS_H) */