[PATCH] bitops: use non atomic operations for minix_*_bit() and ext2_*_bit()
[linux-3.10.git] / include / asm-v850 / bitops.h
1 /*
2  * include/asm-v850/bitops.h -- Bit operations
3  *
4  *  Copyright (C) 2001,02,03,04,05  NEC Electronics Corporation
5  *  Copyright (C) 2001,02,03,04,05  Miles Bader <miles@gnu.org>
6  *  Copyright (C) 1992  Linus Torvalds.
7  *
8  * This file is subject to the terms and conditions of the GNU General
9  * Public License.  See the file COPYING in the main directory of this
10  * archive for more details.
11  */
12
13 #ifndef __V850_BITOPS_H__
14 #define __V850_BITOPS_H__
15
16
17 #include <linux/config.h>
18 #include <linux/compiler.h>     /* unlikely  */
19 #include <asm/byteorder.h>      /* swab32 */
20 #include <asm/system.h>         /* interrupt enable/disable */
21
22
23 #ifdef __KERNEL__
24
25 /*
26  * The __ functions are not atomic
27  */
28
29 /*
30  * ffz = Find First Zero in word. Undefined if no zero exists,
31  * so code should check against ~0UL first..
32  */
33 static inline unsigned long ffz (unsigned long word)
34 {
35         unsigned long result = 0;
36
37         while (word & 1) {
38                 result++;
39                 word >>= 1;
40         }
41         return result;
42 }
43
44
45 /* In the following constant-bit-op macros, a "g" constraint is used when
46    we really need an integer ("i" constraint).  This is to avoid
47    warnings/errors from the compiler in the case where the associated
48    operand _isn't_ an integer, and shouldn't produce bogus assembly because
49    use of that form is protected by a guard statement that checks for
50    constants, and should otherwise be removed by the optimizer.  This
51    _usually_ works -- however, __builtin_constant_p returns true for a
52    variable with a known constant value too, and unfortunately gcc will
53    happily put the variable in a register and use the register for the "g"
54    constraint'd asm operand.  To avoid the latter problem, we add a
55    constant offset to the operand and subtract it back in the asm code;
56    forcing gcc to do arithmetic on the value is usually enough to get it
57    to use a real constant value.  This is horrible, and ultimately
58    unreliable too, but it seems to work for now (hopefully gcc will offer
59    us more control in the future, so we can do a better job).  */
60
61 #define __const_bit_op(op, nr, addr)                                    \
62   ({ __asm__ (op " (%0 - 0x123), %1"                                    \
63               :: "g" (((nr) & 0x7) + 0x123),                            \
64                  "m" (*((char *)(addr) + ((nr) >> 3)))                  \
65               : "memory"); })
66 #define __var_bit_op(op, nr, addr)                                      \
67   ({ int __nr = (nr);                                                   \
68      __asm__ (op " %0, [%1]"                                            \
69               :: "r" (__nr & 0x7),                                      \
70                  "r" ((char *)(addr) + (__nr >> 3))                     \
71               : "memory"); })
72 #define __bit_op(op, nr, addr)                                          \
73   ((__builtin_constant_p (nr) && (unsigned)(nr) <= 0x7FFFF)             \
74    ? __const_bit_op (op, nr, addr)                                      \
75    : __var_bit_op (op, nr, addr))
76
77 #define __set_bit(nr, addr)             __bit_op ("set1", nr, addr)
78 #define __clear_bit(nr, addr)           __bit_op ("clr1", nr, addr)
79 #define __change_bit(nr, addr)          __bit_op ("not1", nr, addr)
80
81 /* The bit instructions used by `non-atomic' variants are actually atomic.  */
82 #define set_bit __set_bit
83 #define clear_bit __clear_bit
84 #define change_bit __change_bit
85
86
87 #define __const_tns_bit_op(op, nr, addr)                                      \
88   ({ int __tns_res;                                                           \
89      __asm__ __volatile__ (                                                   \
90              "tst1 (%1 - 0x123), %2; setf nz, %0; " op " (%1 - 0x123), %2"    \
91              : "=&r" (__tns_res)                                              \
92              : "g" (((nr) & 0x7) + 0x123),                                    \
93                "m" (*((char *)(addr) + ((nr) >> 3)))                          \
94              : "memory");                                                     \
95      __tns_res;                                                               \
96   })
97 #define __var_tns_bit_op(op, nr, addr)                                        \
98   ({ int __nr = (nr);                                                         \
99      int __tns_res;                                                           \
100      __asm__ __volatile__ (                                                   \
101              "tst1 %1, [%2]; setf nz, %0; " op " %1, [%2]"                    \
102               : "=&r" (__tns_res)                                             \
103               : "r" (__nr & 0x7),                                             \
104                 "r" ((char *)(addr) + (__nr >> 3))                            \
105               : "memory");                                                    \
106      __tns_res;                                                               \
107   })
108 #define __tns_bit_op(op, nr, addr)                                      \
109   ((__builtin_constant_p (nr) && (unsigned)(nr) <= 0x7FFFF)             \
110    ? __const_tns_bit_op (op, nr, addr)                                  \
111    : __var_tns_bit_op (op, nr, addr))
112 #define __tns_atomic_bit_op(op, nr, addr)                               \
113   ({ int __tns_atomic_res, __tns_atomic_flags;                          \
114      local_irq_save (__tns_atomic_flags);                               \
115      __tns_atomic_res = __tns_bit_op (op, nr, addr);                    \
116      local_irq_restore (__tns_atomic_flags);                            \
117      __tns_atomic_res;                                                  \
118   })
119
120 #define __test_and_set_bit(nr, addr)    __tns_bit_op ("set1", nr, addr)
121 #define test_and_set_bit(nr, addr)      __tns_atomic_bit_op ("set1", nr, addr)
122
123 #define __test_and_clear_bit(nr, addr)  __tns_bit_op ("clr1", nr, addr)
124 #define test_and_clear_bit(nr, addr)    __tns_atomic_bit_op ("clr1", nr, addr)
125
126 #define __test_and_change_bit(nr, addr) __tns_bit_op ("not1", nr, addr)
127 #define test_and_change_bit(nr, addr)   __tns_atomic_bit_op ("not1", nr, addr)
128
129
130 #define __const_test_bit(nr, addr)                                            \
131   ({ int __test_bit_res;                                                      \
132      __asm__ __volatile__ ("tst1 (%1 - 0x123), %2; setf nz, %0"               \
133                            : "=r" (__test_bit_res)                            \
134                            : "g" (((nr) & 0x7) + 0x123),                      \
135                              "m" (*((const char *)(addr) + ((nr) >> 3))));    \
136      __test_bit_res;                                                          \
137   })
138 static inline int __test_bit (int nr, const void *addr)
139 {
140         int res;
141         __asm__ __volatile__ ("tst1 %1, [%2]; setf nz, %0"
142                               : "=r" (res)
143                               : "r" (nr & 0x7), "r" (addr + (nr >> 3)));
144         return res;
145 }
146 #define test_bit(nr,addr)                                               \
147   ((__builtin_constant_p (nr) && (unsigned)(nr) <= 0x7FFFF)             \
148    ? __const_test_bit ((nr), (addr))                                    \
149    : __test_bit ((nr), (addr)))
150
151
152 /* clear_bit doesn't provide any barrier for the compiler.  */
153 #define smp_mb__before_clear_bit()      barrier ()
154 #define smp_mb__after_clear_bit()       barrier ()
155
156
157 #define find_first_zero_bit(addr, size) \
158   find_next_zero_bit ((addr), (size), 0)
159
160 static inline int find_next_zero_bit(const void *addr, int size, int offset)
161 {
162         unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
163         unsigned long result = offset & ~31UL;
164         unsigned long tmp;
165
166         if (offset >= size)
167                 return size;
168         size -= result;
169         offset &= 31UL;
170         if (offset) {
171                 tmp = * (p++);
172                 tmp |= ~0UL >> (32-offset);
173                 if (size < 32)
174                         goto found_first;
175                 if (~tmp)
176                         goto found_middle;
177                 size -= 32;
178                 result += 32;
179         }
180         while (size & ~31UL) {
181                 if (~ (tmp = * (p++)))
182                         goto found_middle;
183                 result += 32;
184                 size -= 32;
185         }
186         if (!size)
187                 return result;
188         tmp = *p;
189
190  found_first:
191         tmp |= ~0UL << size;
192  found_middle:
193         return result + ffz (tmp);
194 }
195
196
197 /* This is the same as generic_ffs, but we can't use that because it's
198    inline and the #include order mucks things up.  */
199 static inline int generic_ffs_for_find_next_bit(int x)
200 {
201         int r = 1;
202
203         if (!x)
204                 return 0;
205         if (!(x & 0xffff)) {
206                 x >>= 16;
207                 r += 16;
208         }
209         if (!(x & 0xff)) {
210                 x >>= 8;
211                 r += 8;
212         }
213         if (!(x & 0xf)) {
214                 x >>= 4;
215                 r += 4;
216         }
217         if (!(x & 3)) {
218                 x >>= 2;
219                 r += 2;
220         }
221         if (!(x & 1)) {
222                 x >>= 1;
223                 r += 1;
224         }
225         return r;
226 }
227
228 /*
229  * Find next one bit in a bitmap reasonably efficiently.
230  */
231 static __inline__ unsigned long find_next_bit(const unsigned long *addr,
232         unsigned long size, unsigned long offset)
233 {
234         unsigned int *p = ((unsigned int *) addr) + (offset >> 5);
235         unsigned int result = offset & ~31UL;
236         unsigned int tmp;
237
238         if (offset >= size)
239                 return size;
240         size -= result;
241         offset &= 31UL;
242         if (offset) {
243                 tmp = *p++;
244                 tmp &= ~0UL << offset;
245                 if (size < 32)
246                         goto found_first;
247                 if (tmp)
248                         goto found_middle;
249                 size -= 32;
250                 result += 32;
251         }
252         while (size >= 32) {
253                 if ((tmp = *p++) != 0)
254                         goto found_middle;
255                 result += 32;
256                 size -= 32;
257         }
258         if (!size)
259                 return result;
260         tmp = *p;
261
262 found_first:
263         tmp &= ~0UL >> (32 - size);
264         if (tmp == 0UL)        /* Are any bits set? */
265                 return result + size; /* Nope. */
266 found_middle:
267         return result + generic_ffs_for_find_next_bit(tmp);
268 }
269
270 /*
271  * find_first_bit - find the first set bit in a memory region
272  */
273 #define find_first_bit(addr, size) \
274         find_next_bit((addr), (size), 0)
275
276
277 #define ffs(x) generic_ffs (x)
278 #define fls(x) generic_fls (x)
279 #define fls64(x) generic_fls64(x)
280 #define __ffs(x) ffs(x)
281
282
283 /*
284  * This is just `generic_ffs' from <linux/bitops.h>, except that it assumes
285  * that at least one bit is set, and returns the real index of the bit
286  * (rather than the bit index + 1, like ffs does).
287  */
288 static inline int sched_ffs(int x)
289 {
290         int r = 0;
291
292         if (!(x & 0xffff)) {
293                 x >>= 16;
294                 r += 16;
295         }
296         if (!(x & 0xff)) {
297                 x >>= 8;
298                 r += 8;
299         }
300         if (!(x & 0xf)) {
301                 x >>= 4;
302                 r += 4;
303         }
304         if (!(x & 3)) {
305                 x >>= 2;
306                 r += 2;
307         }
308         if (!(x & 1)) {
309                 x >>= 1;
310                 r += 1;
311         }
312         return r;
313 }
314
315 /*
316  * Every architecture must define this function. It's the fastest
317  * way of searching a 140-bit bitmap where the first 100 bits are
318  * unlikely to be set. It's guaranteed that at least one of the 140
319  * bits is set.
320  */
321 static inline int sched_find_first_bit(unsigned long *b)
322 {
323         unsigned offs = 0;
324         while (! *b) {
325                 b++;
326                 offs += 32;
327         }
328         return sched_ffs (*b) + offs;
329 }
330
331 /*
332  * hweightN: returns the hamming weight (i.e. the number
333  * of bits set) of a N-bit word
334  */
335 #define hweight32(x)                    generic_hweight32 (x)
336 #define hweight16(x)                    generic_hweight16 (x)
337 #define hweight8(x)                     generic_hweight8 (x)
338
339 #define ext2_set_bit                    __test_and_set_bit
340 #define ext2_set_bit_atomic(l,n,a)      test_and_set_bit(n,a)
341 #define ext2_clear_bit                  __test_and_clear_bit
342 #define ext2_clear_bit_atomic(l,n,a)    test_and_clear_bit(n,a)
343 #define ext2_test_bit                   test_bit
344 #define ext2_find_first_zero_bit        find_first_zero_bit
345 #define ext2_find_next_zero_bit         find_next_zero_bit
346
347 /* Bitmap functions for the minix filesystem.  */
348 #define minix_test_and_set_bit          __test_and_set_bit
349 #define minix_set_bit                   __set_bit
350 #define minix_test_and_clear_bit        __test_and_clear_bit
351 #define minix_test_bit                  test_bit
352 #define minix_find_first_zero_bit       find_first_zero_bit
353
354 #endif /* __KERNEL__ */
355
356 #endif /* __V850_BITOPS_H__ */