findbit.S 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * linux/arch/arm/lib/findbit.S
  4. *
  5. * Copyright (C) 1995-2000 Russell King
  6. *
  7. * 16th March 2001 - John Ripley <[email protected]>
  8. * Fixed so that "size" is an exclusive not an inclusive quantity.
  9. * All users of these functions expect exclusive sizes, and may
  10. * also call with zero size.
  11. * Reworked by rmk.
  12. */
  13. #include <linux/linkage.h>
  14. #include <asm/assembler.h>
  15. .text
  16. /*
  17. * Purpose : Find a 'zero' bit
  18. * Prototype: int find_first_zero_bit(void *addr, unsigned int maxbit);
  19. */
  20. ENTRY(_find_first_zero_bit_le)
  21. teq r1, #0
  22. beq 3f
  23. mov r2, #0
  24. 1:
  25. ARM( ldrb r3, [r0, r2, lsr #3] )
  26. THUMB( lsr r3, r2, #3 )
  27. THUMB( ldrb r3, [r0, r3] )
  28. eors r3, r3, #0xff @ invert bits
  29. bne .L_found @ any now set - found zero bit
  30. add r2, r2, #8 @ next bit pointer
  31. 2: cmp r2, r1 @ any more?
  32. blo 1b
  33. 3: mov r0, r1 @ no free bits
  34. ret lr
  35. ENDPROC(_find_first_zero_bit_le)
  36. /*
  37. * Purpose : Find next 'zero' bit
  38. * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset)
  39. */
  40. ENTRY(_find_next_zero_bit_le)
  41. cmp r2, r1
  42. bhs 3b
  43. ands ip, r2, #7
  44. beq 1b @ If new byte, goto old routine
  45. ARM( ldrb r3, [r0, r2, lsr #3] )
  46. THUMB( lsr r3, r2, #3 )
  47. THUMB( ldrb r3, [r0, r3] )
  48. eor r3, r3, #0xff @ now looking for a 1 bit
  49. movs r3, r3, lsr ip @ shift off unused bits
  50. bne .L_found
  51. orr r2, r2, #7 @ if zero, then no bits here
  52. add r2, r2, #1 @ align bit pointer
  53. b 2b @ loop for next bit
  54. ENDPROC(_find_next_zero_bit_le)
  55. /*
  56. * Purpose : Find a 'one' bit
  57. * Prototype: int find_first_bit(const unsigned long *addr, unsigned int maxbit);
  58. */
  59. ENTRY(_find_first_bit_le)
  60. teq r1, #0
  61. beq 3f
  62. mov r2, #0
  63. 1:
  64. ARM( ldrb r3, [r0, r2, lsr #3] )
  65. THUMB( lsr r3, r2, #3 )
  66. THUMB( ldrb r3, [r0, r3] )
  67. movs r3, r3
  68. bne .L_found @ any now set - found zero bit
  69. add r2, r2, #8 @ next bit pointer
  70. 2: cmp r2, r1 @ any more?
  71. blo 1b
  72. 3: mov r0, r1 @ no free bits
  73. ret lr
  74. ENDPROC(_find_first_bit_le)
  75. /*
  76. * Purpose : Find next 'one' bit
  77. * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset)
  78. */
  79. ENTRY(_find_next_bit_le)
  80. cmp r2, r1
  81. bhs 3b
  82. ands ip, r2, #7
  83. beq 1b @ If new byte, goto old routine
  84. ARM( ldrb r3, [r0, r2, lsr #3] )
  85. THUMB( lsr r3, r2, #3 )
  86. THUMB( ldrb r3, [r0, r3] )
  87. movs r3, r3, lsr ip @ shift off unused bits
  88. bne .L_found
  89. orr r2, r2, #7 @ if zero, then no bits here
  90. add r2, r2, #1 @ align bit pointer
  91. b 2b @ loop for next bit
  92. ENDPROC(_find_next_bit_le)
  93. #ifdef __ARMEB__
  94. ENTRY(_find_first_zero_bit_be)
  95. teq r1, #0
  96. beq 3f
  97. mov r2, #0
  98. 1: eor r3, r2, #0x18 @ big endian byte ordering
  99. ARM( ldrb r3, [r0, r3, lsr #3] )
  100. THUMB( lsr r3, #3 )
  101. THUMB( ldrb r3, [r0, r3] )
  102. eors r3, r3, #0xff @ invert bits
  103. bne .L_found @ any now set - found zero bit
  104. add r2, r2, #8 @ next bit pointer
  105. 2: cmp r2, r1 @ any more?
  106. blo 1b
  107. 3: mov r0, r1 @ no free bits
  108. ret lr
  109. ENDPROC(_find_first_zero_bit_be)
  110. ENTRY(_find_next_zero_bit_be)
  111. cmp r2, r1
  112. bhs 3b
  113. ands ip, r2, #7
  114. beq 1b @ If new byte, goto old routine
  115. eor r3, r2, #0x18 @ big endian byte ordering
  116. ARM( ldrb r3, [r0, r3, lsr #3] )
  117. THUMB( lsr r3, #3 )
  118. THUMB( ldrb r3, [r0, r3] )
  119. eor r3, r3, #0xff @ now looking for a 1 bit
  120. movs r3, r3, lsr ip @ shift off unused bits
  121. bne .L_found
  122. orr r2, r2, #7 @ if zero, then no bits here
  123. add r2, r2, #1 @ align bit pointer
  124. b 2b @ loop for next bit
  125. ENDPROC(_find_next_zero_bit_be)
  126. ENTRY(_find_first_bit_be)
  127. teq r1, #0
  128. beq 3f
  129. mov r2, #0
  130. 1: eor r3, r2, #0x18 @ big endian byte ordering
  131. ARM( ldrb r3, [r0, r3, lsr #3] )
  132. THUMB( lsr r3, #3 )
  133. THUMB( ldrb r3, [r0, r3] )
  134. movs r3, r3
  135. bne .L_found @ any now set - found zero bit
  136. add r2, r2, #8 @ next bit pointer
  137. 2: cmp r2, r1 @ any more?
  138. blo 1b
  139. 3: mov r0, r1 @ no free bits
  140. ret lr
  141. ENDPROC(_find_first_bit_be)
  142. ENTRY(_find_next_bit_be)
  143. cmp r2, r1
  144. bhs 3b
  145. ands ip, r2, #7
  146. beq 1b @ If new byte, goto old routine
  147. eor r3, r2, #0x18 @ big endian byte ordering
  148. ARM( ldrb r3, [r0, r3, lsr #3] )
  149. THUMB( lsr r3, #3 )
  150. THUMB( ldrb r3, [r0, r3] )
  151. movs r3, r3, lsr ip @ shift off unused bits
  152. bne .L_found
  153. orr r2, r2, #7 @ if zero, then no bits here
  154. add r2, r2, #1 @ align bit pointer
  155. b 2b @ loop for next bit
  156. ENDPROC(_find_next_bit_be)
  157. #endif
  158. /*
  159. * One or more bits in the LSB of r3 are assumed to be set.
  160. */
  161. .L_found:
  162. #if __LINUX_ARM_ARCH__ >= 5
  163. rsb r0, r3, #0
  164. and r3, r3, r0
  165. clz r3, r3
  166. rsb r3, r3, #31
  167. add r0, r2, r3
  168. #else
  169. tst r3, #0x0f
  170. addeq r2, r2, #4
  171. movne r3, r3, lsl #4
  172. tst r3, #0x30
  173. addeq r2, r2, #2
  174. movne r3, r3, lsl #2
  175. tst r3, #0x40
  176. addeq r2, r2, #1
  177. mov r0, r2
  178. #endif
  179. cmp r1, r0 @ Clamp to maxbit
  180. movlo r0, r1
  181. ret lr