bitops_32.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. #ifndef _I386_BITOPS_H
  2. #define _I386_BITOPS_H
  3. /*
  4. * Copyright 1992, Linus Torvalds.
  5. */
  6. /**
  7. * find_first_zero_bit - find the first zero bit in a memory region
  8. * @addr: The address to start the search at
  9. * @size: The maximum size to search
  10. *
  11. * Returns the bit number of the first zero bit, not the number of the byte
  12. * containing a bit.
  13. */
  14. static inline int find_first_zero_bit(const unsigned long *addr, unsigned size)
  15. {
  16. int d0, d1, d2;
  17. int res;
  18. if (!size)
  19. return 0;
  20. /* This looks at memory.
  21. * Mark it volatile to tell gcc not to move it around
  22. */
  23. asm volatile("movl $-1,%%eax\n\t"
  24. "xorl %%edx,%%edx\n\t"
  25. "repe; scasl\n\t"
  26. "je 1f\n\t"
  27. "xorl -4(%%edi),%%eax\n\t"
  28. "subl $4,%%edi\n\t"
  29. "bsfl %%eax,%%edx\n"
  30. "1:\tsubl %%ebx,%%edi\n\t"
  31. "shll $3,%%edi\n\t"
  32. "addl %%edi,%%edx"
  33. : "=d" (res), "=&c" (d0), "=&D" (d1), "=&a" (d2)
  34. : "1" ((size + 31) >> 5), "2" (addr),
  35. "b" (addr) : "memory");
  36. return res;
  37. }
  38. /**
  39. * find_next_zero_bit - find the first zero bit in a memory region
  40. * @addr: The address to base the search on
  41. * @offset: The bit number to start searching at
  42. * @size: The maximum size to search
  43. */
  44. int find_next_zero_bit(const unsigned long *addr, int size, int offset);
  45. /**
  46. * __ffs - find first bit in word.
  47. * @word: The word to search
  48. *
  49. * Undefined if no bit exists, so code should check against 0 first.
  50. */
  51. static inline unsigned long __ffs(unsigned long word)
  52. {
  53. __asm__("bsfl %1,%0"
  54. :"=r" (word)
  55. :"rm" (word));
  56. return word;
  57. }
  58. /**
  59. * find_first_bit - find the first set bit in a memory region
  60. * @addr: The address to start the search at
  61. * @size: The maximum size to search
  62. *
  63. * Returns the bit number of the first set bit, not the number of the byte
  64. * containing a bit.
  65. */
  66. static inline unsigned find_first_bit(const unsigned long *addr, unsigned size)
  67. {
  68. unsigned x = 0;
  69. while (x < size) {
  70. unsigned long val = *addr++;
  71. if (val)
  72. return __ffs(val) + x;
  73. x += sizeof(*addr) << 3;
  74. }
  75. return x;
  76. }
  77. /**
  78. * find_next_bit - find the first set bit in a memory region
  79. * @addr: The address to base the search on
  80. * @offset: The bit number to start searching at
  81. * @size: The maximum size to search
  82. */
  83. int find_next_bit(const unsigned long *addr, int size, int offset);
  84. /**
  85. * ffz - find first zero in word.
  86. * @word: The word to search
  87. *
  88. * Undefined if no zero exists, so code should check against ~0UL first.
  89. */
  90. static inline unsigned long ffz(unsigned long word)
  91. {
  92. __asm__("bsfl %1,%0"
  93. :"=r" (word)
  94. :"r" (~word));
  95. return word;
  96. }
  97. #ifdef __KERNEL__
  98. #include <asm-generic/bitops/sched.h>
  99. /**
  100. * ffs - find first bit set
  101. * @x: the word to search
  102. *
  103. * This is defined the same way as
  104. * the libc and compiler builtin ffs routines, therefore
  105. * differs in spirit from the above ffz() (man ffs).
  106. */
  107. static inline int ffs(int x)
  108. {
  109. int r;
  110. __asm__("bsfl %1,%0\n\t"
  111. "jnz 1f\n\t"
  112. "movl $-1,%0\n"
  113. "1:" : "=r" (r) : "rm" (x));
  114. return r+1;
  115. }
  116. /**
  117. * fls - find last bit set
  118. * @x: the word to search
  119. *
  120. * This is defined the same way as ffs().
  121. */
  122. static inline int fls(int x)
  123. {
  124. int r;
  125. __asm__("bsrl %1,%0\n\t"
  126. "jnz 1f\n\t"
  127. "movl $-1,%0\n"
  128. "1:" : "=r" (r) : "rm" (x));
  129. return r+1;
  130. }
  131. #include <asm-generic/bitops/hweight.h>
  132. #endif /* __KERNEL__ */
  133. #include <asm-generic/bitops/fls64.h>
  134. #ifdef __KERNEL__
  135. #include <asm-generic/bitops/ext2-non-atomic.h>
  136. #define ext2_set_bit_atomic(lock, nr, addr) \
  137. test_and_set_bit((nr), (unsigned long *)(addr))
  138. #define ext2_clear_bit_atomic(lock, nr, addr) \
  139. test_and_clear_bit((nr), (unsigned long *)(addr))
  140. #include <asm-generic/bitops/minix.h>
  141. #endif /* __KERNEL__ */
  142. #endif /* _I386_BITOPS_H */