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