]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - include/asm-sh/bitops.h
sh: Plug in SH-5 ffz()/__ffs() bitops.
[linux-2.6-omap-h63xx.git] / include / asm-sh / bitops.h
1 #ifndef __ASM_SH_BITOPS_H
2 #define __ASM_SH_BITOPS_H
3
4 #ifdef __KERNEL__
5
6 #ifndef _LINUX_BITOPS_H
7 #error only <linux/bitops.h> can be included directly
8 #endif
9
10 #include <asm/system.h>
11 /* For __swab32 */
12 #include <asm/byteorder.h>
13
14 static inline void set_bit(int nr, volatile void * addr)
15 {
16         int     mask;
17         volatile unsigned int *a = addr;
18         unsigned long flags;
19
20         a += nr >> 5;
21         mask = 1 << (nr & 0x1f);
22         local_irq_save(flags);
23         *a |= mask;
24         local_irq_restore(flags);
25 }
26
27 /*
28  * clear_bit() doesn't provide any barrier for the compiler.
29  */
30 #define smp_mb__before_clear_bit()      barrier()
31 #define smp_mb__after_clear_bit()       barrier()
32 static inline void clear_bit(int nr, volatile void * addr)
33 {
34         int     mask;
35         volatile unsigned int *a = addr;
36         unsigned long flags;
37
38         a += nr >> 5;
39         mask = 1 << (nr & 0x1f);
40         local_irq_save(flags);
41         *a &= ~mask;
42         local_irq_restore(flags);
43 }
44
45 static inline void change_bit(int nr, volatile void * addr)
46 {
47         int     mask;
48         volatile unsigned int *a = addr;
49         unsigned long flags;
50
51         a += nr >> 5;
52         mask = 1 << (nr & 0x1f);
53         local_irq_save(flags);
54         *a ^= mask;
55         local_irq_restore(flags);
56 }
57
58 static inline int test_and_set_bit(int nr, volatile void * addr)
59 {
60         int     mask, retval;
61         volatile unsigned int *a = addr;
62         unsigned long flags;
63
64         a += nr >> 5;
65         mask = 1 << (nr & 0x1f);
66         local_irq_save(flags);
67         retval = (mask & *a) != 0;
68         *a |= mask;
69         local_irq_restore(flags);
70
71         return retval;
72 }
73
74 static inline int test_and_clear_bit(int nr, volatile void * addr)
75 {
76         int     mask, retval;
77         volatile unsigned int *a = addr;
78         unsigned long flags;
79
80         a += nr >> 5;
81         mask = 1 << (nr & 0x1f);
82         local_irq_save(flags);
83         retval = (mask & *a) != 0;
84         *a &= ~mask;
85         local_irq_restore(flags);
86
87         return retval;
88 }
89
90 static inline int test_and_change_bit(int nr, volatile void * addr)
91 {
92         int     mask, retval;
93         volatile unsigned int *a = addr;
94         unsigned long flags;
95
96         a += nr >> 5;
97         mask = 1 << (nr & 0x1f);
98         local_irq_save(flags);
99         retval = (mask & *a) != 0;
100         *a ^= mask;
101         local_irq_restore(flags);
102
103         return retval;
104 }
105
106 #include <asm-generic/bitops/non-atomic.h>
107
108 #ifdef CONFIG_SUPERH32
109 static inline unsigned long ffz(unsigned long word)
110 {
111         unsigned long result;
112
113         __asm__("1:\n\t"
114                 "shlr   %1\n\t"
115                 "bt/s   1b\n\t"
116                 " add   #1, %0"
117                 : "=r" (result), "=r" (word)
118                 : "0" (~0L), "1" (word)
119                 : "t");
120         return result;
121 }
122
123 /**
124  * __ffs - find first bit in word.
125  * @word: The word to search
126  *
127  * Undefined if no bit exists, so code should check against 0 first.
128  */
129 static inline unsigned long __ffs(unsigned long word)
130 {
131         unsigned long result;
132
133         __asm__("1:\n\t"
134                 "shlr   %1\n\t"
135                 "bf/s   1b\n\t"
136                 " add   #1, %0"
137                 : "=r" (result), "=r" (word)
138                 : "0" (~0L), "1" (word)
139                 : "t");
140         return result;
141 }
142 #else
143 static inline unsigned long ffz(unsigned long word)
144 {
145         unsigned long result, __d2, __d3;
146
147         __asm__("gettr  tr0, %2\n\t"
148                 "pta    $+32, tr0\n\t"
149                 "andi   %1, 1, %3\n\t"
150                 "beq    %3, r63, tr0\n\t"
151                 "pta    $+4, tr0\n"
152                 "0:\n\t"
153                 "shlri.l        %1, 1, %1\n\t"
154                 "addi   %0, 1, %0\n\t"
155                 "andi   %1, 1, %3\n\t"
156                 "beqi   %3, 1, tr0\n"
157                 "1:\n\t"
158                 "ptabs  %2, tr0\n\t"
159                 : "=r" (result), "=r" (word), "=r" (__d2), "=r" (__d3)
160                 : "0" (0L), "1" (word));
161
162         return result;
163 }
164
165 #include <asm-generic/bitops/__ffs.h>
166 #endif
167
168 #include <asm-generic/bitops/find.h>
169 #include <asm-generic/bitops/ffs.h>
170 #include <asm-generic/bitops/hweight.h>
171 #include <asm-generic/bitops/lock.h>
172 #include <asm-generic/bitops/sched.h>
173 #include <asm-generic/bitops/ext2-non-atomic.h>
174 #include <asm-generic/bitops/ext2-atomic.h>
175 #include <asm-generic/bitops/minix.h>
176 #include <asm-generic/bitops/fls.h>
177 #include <asm-generic/bitops/fls64.h>
178
179 #endif /* __KERNEL__ */
180
181 #endif /* __ASM_SH_BITOPS_H */