aboutsummaryrefslogtreecommitdiffstats
path: root/arch/m68k/include/asm/bitops_mm.h
diff options
context:
space:
mode:
Diffstat (limited to 'arch/m68k/include/asm/bitops_mm.h')
-rw-r--r--arch/m68k/include/asm/bitops_mm.h87
1 files changed, 57 insertions, 30 deletions
diff --git a/arch/m68k/include/asm/bitops_mm.h b/arch/m68k/include/asm/bitops_mm.h
index 9d69f6e62365..e9020f88a748 100644
--- a/arch/m68k/include/asm/bitops_mm.h
+++ b/arch/m68k/include/asm/bitops_mm.h
@@ -181,14 +181,15 @@ static inline int find_first_zero_bit(const unsigned long *vaddr,
181{ 181{
182 const unsigned long *p = vaddr; 182 const unsigned long *p = vaddr;
183 int res = 32; 183 int res = 32;
184 unsigned int words;
184 unsigned long num; 185 unsigned long num;
185 186
186 if (!size) 187 if (!size)
187 return 0; 188 return 0;
188 189
189 size = (size + 31) >> 5; 190 words = (size + 31) >> 5;
190 while (!(num = ~*p++)) { 191 while (!(num = ~*p++)) {
191 if (!--size) 192 if (!--words)
192 goto out; 193 goto out;
193 } 194 }
194 195
@@ -196,7 +197,8 @@ static inline int find_first_zero_bit(const unsigned long *vaddr,
196 : "=d" (res) : "d" (num & -num)); 197 : "=d" (res) : "d" (num & -num));
197 res ^= 31; 198 res ^= 31;
198out: 199out:
199 return ((long)p - (long)vaddr - 4) * 8 + res; 200 res += ((long)p - (long)vaddr - 4) * 8;
201 return res < size ? res : size;
200} 202}
201 203
202static inline int find_next_zero_bit(const unsigned long *vaddr, int size, 204static inline int find_next_zero_bit(const unsigned long *vaddr, int size,
@@ -215,27 +217,32 @@ static inline int find_next_zero_bit(const unsigned long *vaddr, int size,
215 /* Look for zero in first longword */ 217 /* Look for zero in first longword */
216 __asm__ __volatile__ ("bfffo %1{#0,#0},%0" 218 __asm__ __volatile__ ("bfffo %1{#0,#0},%0"
217 : "=d" (res) : "d" (num & -num)); 219 : "=d" (res) : "d" (num & -num));
218 if (res < 32) 220 if (res < 32) {
219 return offset + (res ^ 31); 221 offset += res ^ 31;
222 return offset < size ? offset : size;
223 }
220 offset += 32; 224 offset += 32;
225
226 if (offset >= size)
227 return size;
221 } 228 }
222 /* No zero yet, search remaining full bytes for a zero */ 229 /* No zero yet, search remaining full bytes for a zero */
223 res = find_first_zero_bit(p, size - ((long)p - (long)vaddr) * 8); 230 return offset + find_first_zero_bit(p, size - offset);
224 return offset + res;
225} 231}
226 232
227static inline int find_first_bit(const unsigned long *vaddr, unsigned size) 233static inline int find_first_bit(const unsigned long *vaddr, unsigned size)
228{ 234{
229 const unsigned long *p = vaddr; 235 const unsigned long *p = vaddr;
230 int res = 32; 236 int res = 32;
237 unsigned int words;
231 unsigned long num; 238 unsigned long num;
232 239
233 if (!size) 240 if (!size)
234 return 0; 241 return 0;
235 242
236 size = (size + 31) >> 5; 243 words = (size + 31) >> 5;
237 while (!(num = *p++)) { 244 while (!(num = *p++)) {
238 if (!--size) 245 if (!--words)
239 goto out; 246 goto out;
240 } 247 }
241 248
@@ -243,7 +250,8 @@ static inline int find_first_bit(const unsigned long *vaddr, unsigned size)
243 : "=d" (res) : "d" (num & -num)); 250 : "=d" (res) : "d" (num & -num));
244 res ^= 31; 251 res ^= 31;
245out: 252out:
246 return ((long)p - (long)vaddr - 4) * 8 + res; 253 res += ((long)p - (long)vaddr - 4) * 8;
254 return res < size ? res : size;
247} 255}
248 256
249static inline int find_next_bit(const unsigned long *vaddr, int size, 257static inline int find_next_bit(const unsigned long *vaddr, int size,
@@ -262,13 +270,17 @@ static inline int find_next_bit(const unsigned long *vaddr, int size,
262 /* Look for one in first longword */ 270 /* Look for one in first longword */
263 __asm__ __volatile__ ("bfffo %1{#0,#0},%0" 271 __asm__ __volatile__ ("bfffo %1{#0,#0},%0"
264 : "=d" (res) : "d" (num & -num)); 272 : "=d" (res) : "d" (num & -num));
265 if (res < 32) 273 if (res < 32) {
266 return offset + (res ^ 31); 274 offset += res ^ 31;
275 return offset < size ? offset : size;
276 }
267 offset += 32; 277 offset += 32;
278
279 if (offset >= size)
280 return size;
268 } 281 }
269 /* No one yet, search remaining full bytes for a one */ 282 /* No one yet, search remaining full bytes for a one */
270 res = find_first_bit(p, size - ((long)p - (long)vaddr) * 8); 283 return offset + find_first_bit(p, size - offset);
271 return offset + res;
272} 284}
273 285
274/* 286/*
@@ -366,23 +378,25 @@ static inline int test_bit_le(int nr, const void *vaddr)
366static inline int find_first_zero_bit_le(const void *vaddr, unsigned size) 378static inline int find_first_zero_bit_le(const void *vaddr, unsigned size)
367{ 379{
368 const unsigned long *p = vaddr, *addr = vaddr; 380 const unsigned long *p = vaddr, *addr = vaddr;
369 int res; 381 int res = 0;
382 unsigned int words;
370 383
371 if (!size) 384 if (!size)
372 return 0; 385 return 0;
373 386
374 size = (size >> 5) + ((size & 31) > 0); 387 words = (size >> 5) + ((size & 31) > 0);
375 while (*p++ == ~0UL) 388 while (*p++ == ~0UL) {
376 { 389 if (--words == 0)
377 if (--size == 0) 390 goto out;
378 return (p - addr) << 5;
379 } 391 }
380 392
381 --p; 393 --p;
382 for (res = 0; res < 32; res++) 394 for (res = 0; res < 32; res++)
383 if (!test_bit_le(res, p)) 395 if (!test_bit_le(res, p))
384 break; 396 break;
385 return (p - addr) * 32 + res; 397out:
398 res += (p - addr) * 32;
399 return res < size ? res : size;
386} 400}
387 401
388static inline unsigned long find_next_zero_bit_le(const void *addr, 402static inline unsigned long find_next_zero_bit_le(const void *addr,
@@ -400,10 +414,15 @@ static inline unsigned long find_next_zero_bit_le(const void *addr,
400 offset -= bit; 414 offset -= bit;
401 /* Look for zero in first longword */ 415 /* Look for zero in first longword */
402 for (res = bit; res < 32; res++) 416 for (res = bit; res < 32; res++)
403 if (!test_bit_le(res, p)) 417 if (!test_bit_le(res, p)) {
404 return offset + res; 418 offset += res;
419 return offset < size ? offset : size;
420 }
405 p++; 421 p++;
406 offset += 32; 422 offset += 32;
423
424 if (offset >= size)
425 return size;
407 } 426 }
408 /* No zero yet, search remaining full bytes for a zero */ 427 /* No zero yet, search remaining full bytes for a zero */
409 return offset + find_first_zero_bit_le(p, size - offset); 428 return offset + find_first_zero_bit_le(p, size - offset);
@@ -412,22 +431,25 @@ static inline unsigned long find_next_zero_bit_le(const void *addr,
412static inline int find_first_bit_le(const void *vaddr, unsigned size) 431static inline int find_first_bit_le(const void *vaddr, unsigned size)
413{ 432{
414 const unsigned long *p = vaddr, *addr = vaddr; 433 const unsigned long *p = vaddr, *addr = vaddr;
415 int res; 434 int res = 0;
435 unsigned int words;
416 436
417 if (!size) 437 if (!size)
418 return 0; 438 return 0;
419 439
420 size = (size >> 5) + ((size & 31) > 0); 440 words = (size >> 5) + ((size & 31) > 0);
421 while (*p++ == 0UL) { 441 while (*p++ == 0UL) {
422 if (--size == 0) 442 if (--words == 0)
423 return (p - addr) << 5; 443 goto out;
424 } 444 }
425 445
426 --p; 446 --p;
427 for (res = 0; res < 32; res++) 447 for (res = 0; res < 32; res++)
428 if (test_bit_le(res, p)) 448 if (test_bit_le(res, p))
429 break; 449 break;
430 return (p - addr) * 32 + res; 450out:
451 res += (p - addr) * 32;
452 return res < size ? res : size;
431} 453}
432 454
433static inline unsigned long find_next_bit_le(const void *addr, 455static inline unsigned long find_next_bit_le(const void *addr,
@@ -445,10 +467,15 @@ static inline unsigned long find_next_bit_le(const void *addr,
445 offset -= bit; 467 offset -= bit;
446 /* Look for one in first longword */ 468 /* Look for one in first longword */
447 for (res = bit; res < 32; res++) 469 for (res = bit; res < 32; res++)
448 if (test_bit_le(res, p)) 470 if (test_bit_le(res, p)) {
449 return offset + res; 471 offset += res;
472 return offset < size ? offset : size;
473 }
450 p++; 474 p++;
451 offset += 32; 475 offset += 32;
476
477 if (offset >= size)
478 return size;
452 } 479 }
453 /* No set bit yet, search remaining full bytes for a set bit */ 480 /* No set bit yet, search remaining full bytes for a set bit */
454 return offset + find_first_bit_le(p, size - offset); 481 return offset + find_first_bit_le(p, size - offset);