Merge ssh://master.kernel.org/pub/scm/linux/kernel/git/sam/kbuild
[linux-2.6] / include / asm-h8300 / bitops.h
1 #ifndef _H8300_BITOPS_H
2 #define _H8300_BITOPS_H
3
4 /*
5  * Copyright 1992, Linus Torvalds.
6  * Copyright 2002, Yoshinori Sato
7  */
8
9 #include <linux/compiler.h>
10 #include <asm/system.h>
11
12 #ifdef __KERNEL__
13
14 #ifndef _LINUX_BITOPS_H
15 #error only <linux/bitops.h> can be included directly
16 #endif
17
18 /*
19  * Function prototypes to keep gcc -Wall happy
20  */
21
22 /*
23  * ffz = Find First Zero in word. Undefined if no zero exists,
24  * so code should check against ~0UL first..
25  */
26 static __inline__ unsigned long ffz(unsigned long word)
27 {
28         unsigned long result;
29
30         result = -1;
31         __asm__("1:\n\t"
32                 "shlr.l %2\n\t"
33                 "adds #1,%0\n\t"
34                 "bcs 1b"
35                 : "=r" (result)
36                 : "0"  (result),"r" (word));
37         return result;
38 }
39
40 #define H8300_GEN_BITOP_CONST(OP,BIT)                       \
41         case BIT:                                           \
42         __asm__(OP " #" #BIT ",@%0"::"r"(b_addr):"memory"); \
43         break;
44
45 #define H8300_GEN_BITOP(FNAME,OP)                                     \
46 static __inline__ void FNAME(int nr, volatile unsigned long* addr)    \
47 {                                                                     \
48         volatile unsigned char *b_addr;                               \
49         b_addr = (volatile unsigned char *)addr + ((nr >> 3) ^ 3);    \
50         if (__builtin_constant_p(nr)) {                               \
51                 switch(nr & 7) {                                      \
52                         H8300_GEN_BITOP_CONST(OP,0)                   \
53                         H8300_GEN_BITOP_CONST(OP,1)                   \
54                         H8300_GEN_BITOP_CONST(OP,2)                   \
55                         H8300_GEN_BITOP_CONST(OP,3)                   \
56                         H8300_GEN_BITOP_CONST(OP,4)                   \
57                         H8300_GEN_BITOP_CONST(OP,5)                   \
58                         H8300_GEN_BITOP_CONST(OP,6)                   \
59                         H8300_GEN_BITOP_CONST(OP,7)                   \
60                 }                                                     \
61         } else {                                                      \
62                 __asm__(OP " %w0,@%1"::"r"(nr),"r"(b_addr):"memory"); \
63         }                                                             \
64 }
65
66 /*
67  * clear_bit() doesn't provide any barrier for the compiler.
68  */
69 #define smp_mb__before_clear_bit()      barrier()
70 #define smp_mb__after_clear_bit()       barrier()
71
72 H8300_GEN_BITOP(set_bit   ,"bset")
73 H8300_GEN_BITOP(clear_bit ,"bclr")
74 H8300_GEN_BITOP(change_bit,"bnot")
75 #define __set_bit(nr,addr)    set_bit((nr),(addr))
76 #define __clear_bit(nr,addr)  clear_bit((nr),(addr))
77 #define __change_bit(nr,addr) change_bit((nr),(addr))
78
79 #undef H8300_GEN_BITOP
80 #undef H8300_GEN_BITOP_CONST
81
82 static __inline__ int test_bit(int nr, const unsigned long* addr)
83 {
84         return (*((volatile unsigned char *)addr + 
85                ((nr >> 3) ^ 3)) & (1UL << (nr & 7))) != 0;
86 }
87
88 #define __test_bit(nr, addr) test_bit(nr, addr)
89
90 #define H8300_GEN_TEST_BITOP_CONST_INT(OP,BIT)                       \
91         case BIT:                                                    \
92         __asm__("stc ccr,%w1\n\t"                                    \
93                 "orc #0x80,ccr\n\t"                                  \
94                 "bld #" #BIT ",@%4\n\t"                              \
95                 OP " #" #BIT ",@%4\n\t"                              \
96                 "rotxl.l %0\n\t"                                     \
97                 "ldc %w1,ccr"                                        \
98                 : "=r"(retval),"=&r"(ccrsave),"=m"(*b_addr)          \
99                 : "0" (retval),"r" (b_addr)                          \
100                 : "memory");                                         \
101         break;
102
103 #define H8300_GEN_TEST_BITOP_CONST(OP,BIT)                           \
104         case BIT:                                                    \
105         __asm__("bld #" #BIT ",@%3\n\t"                              \
106                 OP " #" #BIT ",@%3\n\t"                              \
107                 "rotxl.l %0\n\t"                                     \
108                 : "=r"(retval),"=m"(*b_addr)                         \
109                 : "0" (retval),"r" (b_addr)                          \
110                 : "memory");                                         \
111         break;
112
113 #define H8300_GEN_TEST_BITOP(FNNAME,OP)                              \
114 static __inline__ int FNNAME(int nr, volatile void * addr)           \
115 {                                                                    \
116         int retval = 0;                                              \
117         char ccrsave;                                                \
118         volatile unsigned char *b_addr;                              \
119         b_addr = (volatile unsigned char *)addr + ((nr >> 3) ^ 3);   \
120         if (__builtin_constant_p(nr)) {                              \
121                 switch(nr & 7) {                                     \
122                         H8300_GEN_TEST_BITOP_CONST_INT(OP,0)         \
123                         H8300_GEN_TEST_BITOP_CONST_INT(OP,1)         \
124                         H8300_GEN_TEST_BITOP_CONST_INT(OP,2)         \
125                         H8300_GEN_TEST_BITOP_CONST_INT(OP,3)         \
126                         H8300_GEN_TEST_BITOP_CONST_INT(OP,4)         \
127                         H8300_GEN_TEST_BITOP_CONST_INT(OP,5)         \
128                         H8300_GEN_TEST_BITOP_CONST_INT(OP,6)         \
129                         H8300_GEN_TEST_BITOP_CONST_INT(OP,7)         \
130                 }                                                    \
131         } else {                                                     \
132                 __asm__("stc ccr,%w1\n\t"                            \
133                         "orc #0x80,ccr\n\t"                          \
134                         "btst %w5,@%4\n\t"                           \
135                         OP " %w5,@%4\n\t"                            \
136                         "beq 1f\n\t"                                 \
137                         "inc.l #1,%0\n"                              \
138                         "1:\n\t"                                     \
139                         "ldc %w1,ccr"                                \
140                         : "=r"(retval),"=&r"(ccrsave),"=m"(*b_addr)  \
141                         : "0" (retval),"r" (b_addr),"r"(nr)          \
142                         : "memory");                                 \
143         }                                                            \
144         return retval;                                               \
145 }                                                                    \
146                                                                      \
147 static __inline__ int __ ## FNNAME(int nr, volatile void * addr)     \
148 {                                                                    \
149         int retval = 0;                                              \
150         volatile unsigned char *b_addr;                              \
151         b_addr = (volatile unsigned char *)addr + ((nr >> 3) ^ 3);   \
152         if (__builtin_constant_p(nr)) {                              \
153                 switch(nr & 7) {                                     \
154                         H8300_GEN_TEST_BITOP_CONST(OP,0)             \
155                         H8300_GEN_TEST_BITOP_CONST(OP,1)             \
156                         H8300_GEN_TEST_BITOP_CONST(OP,2)             \
157                         H8300_GEN_TEST_BITOP_CONST(OP,3)             \
158                         H8300_GEN_TEST_BITOP_CONST(OP,4)             \
159                         H8300_GEN_TEST_BITOP_CONST(OP,5)             \
160                         H8300_GEN_TEST_BITOP_CONST(OP,6)             \
161                         H8300_GEN_TEST_BITOP_CONST(OP,7)             \
162                 }                                                    \
163         } else {                                                     \
164                 __asm__("btst %w4,@%3\n\t"                           \
165                         OP " %w4,@%3\n\t"                            \
166                         "beq 1f\n\t"                                 \
167                         "inc.l #1,%0\n"                              \
168                         "1:"                                         \
169                         : "=r"(retval),"=m"(*b_addr)                 \
170                         : "0" (retval),"r" (b_addr),"r"(nr)          \
171                         : "memory");                                 \
172         }                                                            \
173         return retval;                                               \
174 }
175
176 H8300_GEN_TEST_BITOP(test_and_set_bit,   "bset")
177 H8300_GEN_TEST_BITOP(test_and_clear_bit, "bclr")
178 H8300_GEN_TEST_BITOP(test_and_change_bit,"bnot")
179 #undef H8300_GEN_TEST_BITOP_CONST
180 #undef H8300_GEN_TEST_BITOP_CONST_INT
181 #undef H8300_GEN_TEST_BITOP
182
183 #include <asm-generic/bitops/ffs.h>
184
185 static __inline__ unsigned long __ffs(unsigned long word)
186 {
187         unsigned long result;
188
189         result = -1;
190         __asm__("1:\n\t"
191                 "shlr.l %2\n\t"
192                 "adds #1,%0\n\t"
193                 "bcc 1b"
194                 : "=r" (result)
195                 : "0"(result),"r"(word));
196         return result;
197 }
198
199 #include <asm-generic/bitops/find.h>
200 #include <asm-generic/bitops/sched.h>
201 #include <asm-generic/bitops/hweight.h>
202 #include <asm-generic/bitops/lock.h>
203 #include <asm-generic/bitops/ext2-non-atomic.h>
204 #include <asm-generic/bitops/ext2-atomic.h>
205 #include <asm-generic/bitops/minix.h>
206
207 #endif /* __KERNEL__ */
208
209 #include <asm-generic/bitops/fls.h>
210 #include <asm-generic/bitops/fls64.h>
211
212 #endif /* _H8300_BITOPS_H */