This source file includes following definitions.
- set_bit
- clear_bit
- change_bit
- set_bit
- clear_bit
- change_bit
- test_bit
- find_first_zero_bit
- find_next_zero_bit
- ffz
1
2
3
4
5
6
7
8
9
10 #ifndef __ASM_MIPS_BITOPS_H
11 #define __ASM_MIPS_BITOPS_H
12
13 #if __mips > 1
14
15
16
17
18
19 #include <asm/mipsregs.h>
20
21
22
23
24 extern __inline__ int set_bit(int nr, void *addr)
25 {
26 int mask, retval, mw;
27
28 addr += ((nr >> 3) & ~3);
29 mask = 1 << (nr & 0x1f);
30 do {
31 mw = load_linked(addr);
32 retval = (mask & mw) != 0;
33 }
34 while (!store_conditional(addr, mw|mask));
35
36 return retval;
37 }
38
39 extern __inline__ int clear_bit(int nr, void *addr)
40 {
41 int mask, retval, mw;
42
43 addr += ((nr >> 3) & ~3);
44 mask = 1 << (nr & 0x1f);
45 do {
46 mw = load_linked(addr);
47 retval = (mask & mw) != 0;
48 }
49 while (!store_conditional(addr, mw & ~mask));
50
51 return retval;
52 }
53
54 extern __inline__ int change_bit(int nr, void *addr)
55 {
56 int mask, retval, mw;
57
58 addr += ((nr >> 3) & ~3);
59 mask = 1 << (nr & 0x1f);
60 do {
61 mw = load_linked(addr);
62 retval = (mask & mw) != 0;
63 }
64 while (!store_conditional(addr, mw ^ mask));
65
66 return retval;
67 }
68
69 #else
70
71
72
73
74
75
76 #include <asm/system.h>
77
78 #ifdef __KERNEL__
79
80
81
82
83 #define __flags unsigned long flags
84 #define __cli() cli()
85 #define __save_flags(x) save_flags(x)
86 #define __restore_flags(x) restore_flags(x)
87 #endif
88
89 extern __inline__ int set_bit(int nr, void * addr)
90 {
91 int mask, retval;
92 int *a = addr;
93 __flags;
94
95 a += nr >> 5;
96 mask = 1 << (nr & 0x1f);
97 __save_flags(flags);
98 __cli();
99 retval = (mask & *a) != 0;
100 *a |= mask;
101 __restore_flags(flags);
102
103 return retval;
104 }
105
106 extern __inline__ int clear_bit(int nr, void * addr)
107 {
108 int mask, retval;
109 int *a = addr;
110 __flags;
111
112 a += nr >> 5;
113 mask = 1 << (nr & 0x1f);
114 __save_flags(flags);
115 __cli();
116 retval = (mask & *a) != 0;
117 *a &= ~mask;
118 __restore_flags(flags);
119
120 return retval;
121 }
122
123 extern __inline__ int change_bit(int nr, void * addr)
124 {
125 int mask, retval;
126 int *a = addr;
127 __flags;
128
129 a += nr >> 5;
130 mask = 1 << (nr & 0x1f);
131 __save_flags(flags);
132 __cli();
133 retval = (mask & *a) != 0;
134 *a ^= mask;
135 __restore_flags(flags);
136
137 return retval;
138 }
139
140 #undef __flags
141 #undef __cli()
142 #undef __save_flags(x)
143 #undef __restore_flags(x)
144
145 #endif
146
147 extern __inline__ int test_bit(int nr, const void *addr)
148 {
149 return 1UL & (((const unsigned int *) addr)[nr >> 5] >> (nr & 31));
150 }
151
152 extern __inline__ int find_first_zero_bit (void *addr, unsigned size)
153 {
154 int res;
155
156 if (!size)
157 return 0;
158
159 __asm__(".set\tnoreorder\n\t"
160 ".set\tnoat\n"
161 "1:\tsubu\t$1,%2,%0\n\t"
162 "blez\t$1,2f\n\t"
163 "lw\t$1,(%4)\n\t"
164 "addiu\t%4,%4,4\n\t"
165 "beql\t%1,$1,1b\n\t"
166 "addiu\t%0,%0,32\n\t"
167 "li\t%1,1\n"
168 "1:\tand\t%4,$1,%1\n\t"
169 "beq\t$0,%4,2f\n\t"
170 "sll\t%1,%1,1\n\t"
171 "bne\t$0,%1,1b\n\t"
172 "add\t%0,%0,1\n\t"
173 ".set\tat\n\t"
174 ".set\treorder\n"
175 "2:"
176 : "=r" (res)
177 : "r" ((unsigned int) 0xffffffff),
178 "r" (size),
179 "0" ((signed int) 0),
180 "r" (addr)
181 : "$1");
182
183 return res;
184 }
185
186 extern __inline__ int find_next_zero_bit (void * addr, int size, int offset)
187 {
188 unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
189 int set = 0, bit = offset & 31, res;
190
191 if (bit) {
192
193
194
195 __asm__(".set\tnoreorder\n\t"
196 ".set\tnoat\n"
197 "1:\tand\t$1,%2,%1\n\t"
198 "beq\t$0,$1,2f\n\t"
199 "sll\t%2,%2,1\n\t"
200 "bne\t$0,%2,1b\n\t"
201 "addiu\t%0,%0,1\n\t"
202 ".set\tat\n\t"
203 ".set\treorder\n"
204 : "=r" (set)
205 : "r" (*p >> bit),
206 "r" (1),
207 "0" (0)
208 : "$1");
209 if (set < (32 - bit))
210 return set + offset;
211 set = 32 - bit;
212 p++;
213 }
214
215
216
217 res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr));
218 return (offset + set + res);
219 }
220
221
222
223
224
225 extern __inline__ unsigned long ffz(unsigned long word)
226 {
227 unsigned int __res;
228 unsigned int mask = 1;
229
230 __asm__ __volatile__ (
231 ".set\tnoreorder\n\t"
232 ".set\tnoat\n\t"
233 "move\t%0,$0\n"
234 "1:\tand\t$1,%2,%1\n\t"
235 "beqz\t$1,2f\n\t"
236 "sll\t%1,1\n\t"
237 "bnez\t%1,1b\n\t"
238 "addiu\t%0,1\n\t"
239 ".set\tat\n\t"
240 ".set\treorder\n"
241 "2:\n\t"
242 : "=r" (__res), "=r" (mask)
243 : "r" (word), "1" (mask)
244 : "$1");
245
246 return __res;
247 }
248
249 #endif