fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / include / asm-xtensa / bitops.h
1 /*
2  * include/asm-xtensa/bitops.h
3  *
4  * Atomic operations that C can't guarantee us.Useful for resource counting etc.
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  * Copyright (C) 2001 - 2005 Tensilica Inc.
11  */
12
13 #ifndef _XTENSA_BITOPS_H
14 #define _XTENSA_BITOPS_H
15
16 #ifdef __KERNEL__
17
18 #include <asm/processor.h>
19 #include <asm/byteorder.h>
20 #include <asm/system.h>
21
22 #ifdef CONFIG_SMP
23 # error SMP not supported on this architecture
24 #endif
25
26 #define smp_mb__before_clear_bit()      barrier()
27 #define smp_mb__after_clear_bit()       barrier()
28
29 #include <asm-generic/bitops/atomic.h>
30 #include <asm-generic/bitops/non-atomic.h>
31
32 #if XCHAL_HAVE_NSA
33
34 static __inline__ int __cntlz (unsigned long x)
35 {
36         int lz;
37         asm ("nsau %0, %1" : "=r" (lz) : "r" (x));
38         return 31 - lz;
39 }
40
41 #else
42
43 static __inline__ int __cntlz (unsigned long x)
44 {
45         unsigned long sum, x1, x2, x4, x8, x16;
46         x1  = x & 0xAAAAAAAA;
47         x2  = x & 0xCCCCCCCC;
48         x4  = x & 0xF0F0F0F0;
49         x8  = x & 0xFF00FF00;
50         x16 = x & 0xFFFF0000;
51         sum = x2 ? 2 : 0;
52         sum += (x16 != 0) * 16;
53         sum += (x8 != 0) * 8;
54         sum += (x4 != 0) * 4;
55         sum += (x1 != 0);
56
57         return sum;
58 }
59
60 #endif
61
62 /*
63  * ffz: Find first zero in word. Undefined if no zero exists.
64  * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
65  */
66
67 static __inline__ int ffz(unsigned long x)
68 {
69         if ((x = ~x) == 0)
70                 return 32;
71         return __cntlz(x & -x);
72 }
73
74 /*
75  * __ffs: Find first bit set in word. Return 0 for bit 0
76  */
77
78 static __inline__ int __ffs(unsigned long x)
79 {
80         return __cntlz(x & -x);
81 }
82
83 /*
84  * ffs: Find first bit set in word. This is defined the same way as
85  * the libc and compiler builtin ffs routines, therefore
86  * differs in spirit from the above ffz (man ffs).
87  */
88
89 static __inline__ int ffs(unsigned long x)
90 {
91         return __cntlz(x & -x) + 1;
92 }
93
94 /*
95  * fls: Find last (most-significant) bit set in word.
96  * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
97  */
98
99 static __inline__ int fls (unsigned int x)
100 {
101         return __cntlz(x);
102 }
103 #include <asm-generic/bitops/fls64.h>
104 #include <asm-generic/bitops/find.h>
105 #include <asm-generic/bitops/ext2-non-atomic.h>
106
107 #ifdef __XTENSA_EL__
108 # define ext2_set_bit_atomic(lock,nr,addr) test_and_set_bit((nr),(addr))
109 # define ext2_clear_bit_atomic(lock,nr,addr) test_and_clear_bit((nr),(addr))
110 #elif defined(__XTENSA_EB__)
111 # define ext2_set_bit_atomic(lock,nr,addr) test_and_set_bit((nr) ^ 0x18, (addr))
112 # define ext2_clear_bit_atomic(lock,nr,addr) test_and_clear_bit((nr)^0x18,(addr))
113 #else
114 # error processor byte order undefined!
115 #endif
116
117 #include <asm-generic/bitops/hweight.h>
118 #include <asm-generic/bitops/sched.h>
119 #include <asm-generic/bitops/minix.h>
120
121 #endif  /* __KERNEL__ */
122
123 #endif  /* _XTENSA_BITOPS_H */