bitops.c 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. #include <linux/bitops.h>
  2. #include <linux/module.h>
  3. /**
  4. * find_next_bit - find the first set bit in a memory region
  5. * @addr: The address to base the search on
  6. * @offset: The bitnumber to start searching at
  7. * @size: The maximum size to search
  8. */
  9. int find_next_bit(const unsigned long *addr, int size, int offset)
  10. {
  11. const unsigned long *p = addr + (offset >> 5);
  12. int set = 0, bit = offset & 31, res;
  13. if (bit) {
  14. /*
  15. * Look for nonzero in the first 32 bits:
  16. */
  17. __asm__("bsfl %1,%0\n\t"
  18. "jne 1f\n\t"
  19. "movl $32, %0\n"
  20. "1:"
  21. : "=r" (set)
  22. : "r" (*p >> bit));
  23. if (set < (32 - bit))
  24. return set + offset;
  25. set = 32 - bit;
  26. p++;
  27. }
  28. /*
  29. * No set bit yet, search remaining full words for a bit
  30. */
  31. res = find_first_bit (p, size - 32 * (p - addr));
  32. return (offset + set + res);
  33. }
  34. EXPORT_SYMBOL(find_next_bit);
  35. /**
  36. * find_next_zero_bit - find the first zero bit in a memory region
  37. * @addr: The address to base the search on
  38. * @offset: The bitnumber to start searching at
  39. * @size: The maximum size to search
  40. */
  41. int find_next_zero_bit(const unsigned long *addr, int size, int offset)
  42. {
  43. unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
  44. int set = 0, bit = offset & 31, res;
  45. if (bit) {
  46. /*
  47. * Look for zero in the first 32 bits.
  48. */
  49. __asm__("bsfl %1,%0\n\t"
  50. "jne 1f\n\t"
  51. "movl $32, %0\n"
  52. "1:"
  53. : "=r" (set)
  54. : "r" (~(*p >> bit)));
  55. if (set < (32 - bit))
  56. return set + offset;
  57. set = 32 - bit;
  58. p++;
  59. }
  60. /*
  61. * No zero yet, search remaining full bytes for a zero
  62. */
  63. res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr));
  64. return (offset + set + res);
  65. }
  66. EXPORT_SYMBOL(find_next_zero_bit);