findbit.S 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2010-11-13 weety first version
  9. */
  10. //#include <rtthread.h>
  11. //.text
  12. /*
  13. * Purpose : Find a 'zero' bit
  14. * Prototype: int find_first_zero_bit(void *addr, unsigned int maxbit);
  15. */
  16. .globl _find_first_zero_bit_le
  17. _find_first_zero_bit_le:
  18. teq r1, #0
  19. beq 3f
  20. mov r2, #0
  21. 1:
  22. ldrb r3, [r0, r2, lsr #3]
  23. lsr r3, r2, #3
  24. ldrb r3, [r0, r3]
  25. eors r3, r3, #0xff @ invert bits
  26. bne .L_found @ any now set - found zero bit
  27. add r2, r2, #8 @ next bit pointer
  28. 2: cmp r2, r1 @ any more?
  29. blo 1b
  30. 3: mov r0, r1 @ no free bits
  31. mov pc, lr
  32. //ENDPROC(_find_first_zero_bit_le)
  33. /*
  34. * Purpose : Find next 'zero' bit
  35. * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset)
  36. */
  37. .globl _find_next_zero_bit_le
  38. _find_next_zero_bit_le:
  39. teq r1, #0
  40. beq 3b
  41. ands ip, r2, #7
  42. beq 1b @ If new byte, goto old routine
  43. ldrb r3, [r0, r2, lsr #3]
  44. lsr r3, r2, #3
  45. ldrb r3, [r0, r3]
  46. eor r3, r3, #0xff @ now looking for a 1 bit
  47. movs r3, r3, lsr ip @ shift off unused bits
  48. bne .L_found
  49. orr r2, r2, #7 @ if zero, then no bits here
  50. add r2, r2, #1 @ align bit pointer
  51. b 2b @ loop for next bit
  52. //ENDPROC(_find_next_zero_bit_le)
  53. /*
  54. * Purpose : Find a 'one' bit
  55. * Prototype: int find_first_bit(const unsigned long *addr, unsigned int maxbit);
  56. */
  57. .globl _find_first_bit_le
  58. _find_first_bit_le:
  59. teq r1, #0
  60. beq 3f
  61. mov r2, #0
  62. 1:
  63. ldrb r3, [r0, r2, lsr #3]
  64. lsr r3, r2, #3
  65. ldrb r3, [r0, r3]
  66. movs r3, r3
  67. bne .L_found @ any now set - found zero bit
  68. add r2, r2, #8 @ next bit pointer
  69. 2: cmp r2, r1 @ any more?
  70. blo 1b
  71. 3: mov r0, r1 @ no free bits
  72. mov pc, lr
  73. //ENDPROC(_find_first_bit_le)
  74. /*
  75. * Purpose : Find next 'one' bit
  76. * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset)
  77. */
  78. .globl _find_next_bit_le
  79. _find_next_bit_le:
  80. teq r1, #0
  81. beq 3b
  82. ands ip, r2, #7
  83. beq 1b @ If new byte, goto old routine
  84. ldrb r3, [r0, r2, lsr #3]
  85. lsr r3, r2, #3
  86. 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. mov pc, lr
  109. ENDPROC(_find_first_zero_bit_be)
  110. ENTRY(_find_next_zero_bit_be)
  111. teq r1, #0
  112. beq 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. mov pc, lr
  141. ENDPROC(_find_first_bit_be)
  142. ENTRY(_find_next_bit_be)
  143. teq r1, #0
  144. beq 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 1 //__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. mov pc, lr