~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/include/asm-m68k/bitops.h

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 #ifndef _M68K_BITOPS_H
  2 #define _M68K_BITOPS_H
  3 /*
  4  * Copyright 1992, Linus Torvalds.
  5  *
  6  * This file is subject to the terms and conditions of the GNU General Public
  7  * License.  See the file COPYING in the main directory of this archive
  8  * for more details.
  9  */
 10 
 11 /*
 12  * Require 68020 or better.
 13  *
 14  * They use the standard big-endian m680x0 bit ordering.
 15  */
 16 
 17 #define test_and_set_bit(nr,vaddr) \
 18   (__builtin_constant_p(nr) ? \
 19    __constant_test_and_set_bit(nr, vaddr) : \
 20    __generic_test_and_set_bit(nr, vaddr))
 21 
 22 extern __inline__ int __constant_test_and_set_bit(int nr,void * vaddr)
 23 {
 24         char retval;
 25 
 26         __asm__ __volatile__ ("bset %1,%2; sne %0"
 27              : "=d" (retval)
 28              : "di" (nr & 7), "m" (((char *)vaddr)[(nr^31) >> 3]));
 29 
 30         return retval;
 31 }
 32 
 33 extern __inline__ int __generic_test_and_set_bit(int nr,void * vaddr)
 34 {
 35         char retval;
 36 
 37         __asm__ __volatile__ ("bfset %2@{%1:#1}; sne %0"
 38              : "=d" (retval) : "d" (nr^31), "a" (vaddr));
 39 
 40         return retval;
 41 }
 42 
 43 #define set_bit(nr,vaddr) \
 44   (__builtin_constant_p(nr) ? \
 45    __constant_set_bit(nr, vaddr) : \
 46    __generic_set_bit(nr, vaddr))
 47 
 48 extern __inline__ void __constant_set_bit(int nr, void * vaddr)
 49 {
 50         __asm__ __volatile__ ("bset %0,%1"
 51              : : "di" (nr & 7), "m" (((char *)vaddr)[(nr^31) >> 3]));
 52 }
 53 
 54 extern __inline__ void __generic_set_bit(int nr, void * vaddr)
 55 {
 56         __asm__ __volatile__ ("bfset %1@{%0:#1}"
 57              : : "d" (nr^31), "a" (vaddr));
 58 }
 59 
 60 #define test_and_clear_bit(nr,vaddr) \
 61   (__builtin_constant_p(nr) ? \
 62    __constant_test_and_clear_bit(nr, vaddr) : \
 63    __generic_test_and_clear_bit(nr, vaddr))
 64 
 65 extern __inline__ int __constant_test_and_clear_bit(int nr, void * vaddr)
 66 {
 67         char retval;
 68 
 69         __asm__ __volatile__ ("bclr %1,%2; sne %0"
 70              : "=d" (retval)
 71              : "di" (nr & 7), "m" (((char *)vaddr)[(nr^31) >> 3]));
 72 
 73         return retval;
 74 }
 75 
 76 extern __inline__ int __generic_test_and_clear_bit(int nr, void * vaddr)
 77 {
 78         char retval;
 79 
 80         __asm__ __volatile__ ("bfclr %2@{%1:#1}; sne %0"
 81              : "=d" (retval) : "d" (nr^31), "a" (vaddr));
 82 
 83         return retval;
 84 }
 85 
 86 /*
 87  * clear_bit() doesn't provide any barrier for the compiler.
 88  */
 89 #define smp_mb__before_clear_bit()      barrier()
 90 #define smp_mb__after_clear_bit()       barrier()
 91 
 92 #define clear_bit(nr,vaddr) \
 93   (__builtin_constant_p(nr) ? \
 94    __constant_clear_bit(nr, vaddr) : \
 95    __generic_clear_bit(nr, vaddr))
 96 
 97 extern __inline__ void __constant_clear_bit(int nr, void * vaddr)
 98 {
 99         __asm__ __volatile__ ("bclr %0,%1"
100              : : "di" (nr & 7), "m" (((char *)vaddr)[(nr^31) >> 3]));
101 }
102 
103 extern __inline__ void __generic_clear_bit(int nr, void * vaddr)
104 {
105         __asm__ __volatile__ ("bfclr %1@{%0:#1}"
106              : : "d" (nr^31), "a" (vaddr));
107 }
108 
109 #define test_and_change_bit(nr,vaddr) \
110   (__builtin_constant_p(nr) ? \
111    __constant_test_and_change_bit(nr, vaddr) : \
112    __generic_test_and_change_bit(nr, vaddr))
113 
114 extern __inline__ int __constant_test_and_change_bit(int nr, void * vaddr)
115 {
116         char retval;
117 
118         __asm__ __volatile__ ("bchg %1,%2; sne %0"
119              : "=d" (retval)
120              : "di" (nr & 7), "m" (((char *)vaddr)[(nr^31) >> 3]));
121 
122         return retval;
123 }
124 
125 extern __inline__ int __generic_test_and_change_bit(int nr, void * vaddr)
126 {
127         char retval;
128 
129         __asm__ __volatile__ ("bfchg %2@{%1:#1}; sne %0"
130              : "=d" (retval) : "d" (nr^31), "a" (vaddr));
131 
132         return retval;
133 }
134 
135 #define change_bit(nr,vaddr) \
136   (__builtin_constant_p(nr) ? \
137    __constant_change_bit(nr, vaddr) : \
138    __generic_change_bit(nr, vaddr))
139 
140 extern __inline__ void __constant_change_bit(int nr, void * vaddr)
141 {
142         __asm__ __volatile__ ("bchg %0,%1"
143              : : "di" (nr & 7), "m" (((char *)vaddr)[(nr^31) >> 3]));
144 }
145 
146 extern __inline__ void __generic_change_bit(int nr, void * vaddr)
147 {
148         __asm__ __volatile__ ("bfchg %1@{%0:#1}"
149              : : "d" (nr^31), "a" (vaddr));
150 }
151 
152 extern __inline__ int test_bit(int nr, const void * vaddr)
153 {
154         return ((1UL << (nr & 31)) & (((const unsigned int *) vaddr)[nr >> 5])) != 0;
155 }
156 
157 extern __inline__ int find_first_zero_bit(void * vaddr, unsigned size)
158 {
159         unsigned long *p = vaddr, *addr = vaddr;
160         unsigned long allones = ~0UL;
161         int res;
162         unsigned long num;
163 
164         if (!size)
165                 return 0;
166 
167         size = (size >> 5) + ((size & 31) > 0);
168         while (*p++ == allones)
169         {
170                 if (--size == 0)
171                         return (p - addr) << 5;
172         }
173 
174         num = ~*--p;
175         __asm__ __volatile__ ("bfffo %1{#0,#0},%0"
176                               : "=d" (res) : "d" (num & -num));
177         return ((p - addr) << 5) + (res ^ 31);
178 }
179 
180 extern __inline__ int find_next_zero_bit (void *vaddr, int size,
181                                       int offset)
182 {
183         unsigned long *addr = vaddr;
184         unsigned long *p = addr + (offset >> 5);
185         int set = 0, bit = offset & 31UL, res;
186 
187         if (offset >= size)
188                 return size;
189 
190         if (bit) {
191                 unsigned long num = ~*p & (~0UL << bit);
192 
193                 /* Look for zero in first longword */
194                 __asm__ __volatile__ ("bfffo %1{#0,#0},%0"
195                                       : "=d" (res) : "d" (num & -num));
196                 if (res < 32)
197                         return (offset & ~31UL) + (res ^ 31);
198                 set = 32 - bit;
199                 p++;
200         }
201         /* No zero yet, search remaining full bytes for a zero */
202         res = find_first_zero_bit (p, size - 32 * (p - addr));
203         return (offset + set + res);
204 }
205 
206 /*
207  * ffz = Find First Zero in word. Undefined if no zero exists,
208  * so code should check against ~0UL first..
209  */
210 extern __inline__ unsigned long ffz(unsigned long word)
211 {
212         int res;
213 
214         __asm__ __volatile__ ("bfffo %1{#0,#0},%0"
215                               : "=d" (res) : "d" (~word & -~word));
216         return res ^ 31;
217 }
218 
219 #ifdef __KERNEL__
220 
221 /*
222  * ffs: find first bit set. This is defined the same way as
223  * the libc and compiler builtin ffs routines, therefore
224  * differs in spirit from the above ffz (man ffs).
225  */
226 
227 extern __inline__ int ffs(int x)
228 {
229         int cnt;
230 
231         asm ("bfffo %1{#0:#0}" : "=d" (cnt) : "dm" (x & -x));
232 
233         return 32 - cnt;
234 }
235 
236 /*
237  * hweightN: returns the hamming weight (i.e. the number
238  * of bits set) of a N-bit word
239  */
240 
241 #define hweight32(x) generic_hweight32(x)
242 #define hweight16(x) generic_hweight16(x)
243 #define hweight8(x) generic_hweight8(x)
244 
245 /* Bitmap functions for the minix filesystem */
246 
247 extern __inline__ int
248 minix_find_first_zero_bit (const void *vaddr, unsigned size)
249 {
250         const unsigned short *p = vaddr, *addr = vaddr;
251         int res;
252         unsigned short num;
253 
254         if (!size)
255                 return 0;
256 
257         size = (size >> 4) + ((size & 15) > 0);
258         while (*p++ == 0xffff)
259         {
260                 if (--size == 0)
261                         return (p - addr) << 4;
262         }
263 
264         num = ~*--p;
265         __asm__ __volatile__ ("bfffo %1{#16,#16},%0"
266                               : "=d" (res) : "d" (num & -num));
267         return ((p - addr) << 4) + (res ^ 31);
268 }
269 
270 extern __inline__ int
271 minix_test_and_set_bit (int nr, void *vaddr)
272 {
273         char retval;
274 
275         __asm__ __volatile__ ("bfset %2{%1:#1}; sne %0"
276              : "=d" (retval) : "d" (nr^15), "m" (*(char *)vaddr));
277 
278         return retval;
279 }
280 
281 #define minix_set_bit(nr,addr)  ((void)minix_test_and_set_bit(nr,addr))
282 
283 extern __inline__ int
284 minix_test_and_clear_bit (int nr, void *vaddr)
285 {
286         char retval;
287 
288         __asm__ __volatile__ ("bfclr %2{%1:#1}; sne %0"
289              : "=d" (retval) : "d" (nr^15), "m" (*(char *) vaddr));
290 
291         return retval;
292 }
293 
294 extern __inline__ int
295 minix_test_bit (int nr, const void *vaddr)
296 {
297         return ((1U << (nr & 15)) & (((const unsigned short *) vaddr)[nr >> 4])) != 0;
298 }
299 
300 /* Bitmap functions for the ext2 filesystem. */
301 
302 extern __inline__ int
303 ext2_set_bit (int nr, void *vaddr)
304 {
305         char retval;
306 
307         __asm__ __volatile__ ("bfset %2{%1,#1}; sne %0"
308              : "=d" (retval) : "d" (nr^7), "m" (*(char *) vaddr));
309 
310         return retval;
311 }
312 
313 extern __inline__ int
314 ext2_clear_bit (int nr, void *vaddr)
315 {
316         char retval;
317 
318         __asm__ __volatile__ ("bfclr %2{%1,#1}; sne %0"
319              : "=d" (retval) : "d" (nr^7), "m" (*(char *) vaddr));
320 
321         return retval;
322 }
323 
324 extern __inline__ int
325 ext2_test_bit (int nr, const void *vaddr)
326 {
327         return ((1U << (nr & 7)) & (((const unsigned char *) vaddr)[nr >> 3])) != 0;
328 }
329 
330 extern __inline__ int
331 ext2_find_first_zero_bit (const void *vaddr, unsigned size)
332 {
333         const unsigned long *p = vaddr, *addr = vaddr;
334         int res;
335 
336         if (!size)
337                 return 0;
338 
339         size = (size >> 5) + ((size & 31) > 0);
340         while (*p++ == ~0UL)
341         {
342                 if (--size == 0)
343                         return (p - addr) << 5;
344         }
345 
346         --p;
347         for (res = 0; res < 32; res++)
348                 if (!ext2_test_bit (res, p))
349                         break;
350         return (p - addr) * 32 + res;
351 }
352 
353 extern __inline__ int
354 ext2_find_next_zero_bit (const void *vaddr, unsigned size, unsigned offset)
355 {
356         const unsigned long *addr = vaddr;
357         const unsigned long *p = addr + (offset >> 5);
358         int bit = offset & 31UL, res;
359 
360         if (offset >= size)
361                 return size;
362 
363         if (bit) {
364                 /* Look for zero in first longword */
365                 for (res = bit; res < 32; res++)
366                         if (!ext2_test_bit (res, p))
367                                 return (p - addr) * 32 + res;
368                 p++;
369         }
370         /* No zero yet, search remaining full bytes for a zero */
371         res = ext2_find_first_zero_bit (p, size - 32 * (p - addr));
372         return (p - addr) * 32 + res;
373 }
374 
375 #endif /* __KERNEL__ */
376 
377 #endif /* _M68K_BITOPS_H */
378 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.