findbit.S 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. /*
  2. * File : findbit.S
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006, RT-Thread Development Team
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along
  17. * with this program; if not, write to the Free Software Foundation, Inc.,
  18. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  19. *
  20. * Change Logs:
  21. * Date Author Notes
  22. * 2010-11-13 weety first version
  23. */
  24. //#include <rtthread.h>
  25. //.text
  26. /*
  27. * Purpose : Find a 'zero' bit
  28. * Prototype: int find_first_zero_bit(void *addr, unsigned int maxbit);
  29. */
  30. .globl _find_first_zero_bit_le
  31. _find_first_zero_bit_le:
  32. teq r1, #0
  33. beq 3f
  34. mov r2, #0
  35. 1:
  36. ldrb r3, [r0, r2, lsr #3]
  37. lsr r3, r2, #3
  38. ldrb r3, [r0, r3]
  39. eors r3, r3, #0xff @ invert bits
  40. bne .L_found @ any now set - found zero bit
  41. add r2, r2, #8 @ next bit pointer
  42. 2: cmp r2, r1 @ any more?
  43. blo 1b
  44. 3: mov r0, r1 @ no free bits
  45. mov pc, lr
  46. //ENDPROC(_find_first_zero_bit_le)
  47. /*
  48. * Purpose : Find next 'zero' bit
  49. * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset)
  50. */
  51. .globl _find_next_zero_bit_le
  52. _find_next_zero_bit_le:
  53. teq r1, #0
  54. beq 3b
  55. ands ip, r2, #7
  56. beq 1b @ If new byte, goto old routine
  57. ldrb r3, [r0, r2, lsr #3]
  58. lsr r3, r2, #3
  59. ldrb r3, [r0, r3]
  60. eor r3, r3, #0xff @ now looking for a 1 bit
  61. movs r3, r3, lsr ip @ shift off unused bits
  62. bne .L_found
  63. orr r2, r2, #7 @ if zero, then no bits here
  64. add r2, r2, #1 @ align bit pointer
  65. b 2b @ loop for next bit
  66. //ENDPROC(_find_next_zero_bit_le)
  67. /*
  68. * Purpose : Find a 'one' bit
  69. * Prototype: int find_first_bit(const unsigned long *addr, unsigned int maxbit);
  70. */
  71. .globl _find_first_bit_le
  72. _find_first_bit_le:
  73. teq r1, #0
  74. beq 3f
  75. mov r2, #0
  76. 1:
  77. ldrb r3, [r0, r2, lsr #3]
  78. lsr r3, r2, #3
  79. ldrb r3, [r0, r3]
  80. movs r3, r3
  81. bne .L_found @ any now set - found zero bit
  82. add r2, r2, #8 @ next bit pointer
  83. 2: cmp r2, r1 @ any more?
  84. blo 1b
  85. 3: mov r0, r1 @ no free bits
  86. mov pc, lr
  87. //ENDPROC(_find_first_bit_le)
  88. /*
  89. * Purpose : Find next 'one' bit
  90. * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset)
  91. */
  92. .globl _find_next_bit_le
  93. _find_next_bit_le:
  94. teq r1, #0
  95. beq 3b
  96. ands ip, r2, #7
  97. beq 1b @ If new byte, goto old routine
  98. ldrb r3, [r0, r2, lsr #3]
  99. lsr r3, r2, #3
  100. ldrb r3, [r0, r3]
  101. movs r3, r3, lsr ip @ shift off unused bits
  102. bne .L_found
  103. orr r2, r2, #7 @ if zero, then no bits here
  104. add r2, r2, #1 @ align bit pointer
  105. b 2b @ loop for next bit
  106. //ENDPROC(_find_next_bit_le)
  107. #ifdef __ARMEB__
  108. ENTRY(_find_first_zero_bit_be)
  109. teq r1, #0
  110. beq 3f
  111. mov r2, #0
  112. 1: eor r3, r2, #0x18 @ big endian byte ordering
  113. ARM( ldrb r3, [r0, r3, lsr #3] )
  114. THUMB( lsr r3, #3 )
  115. THUMB( ldrb r3, [r0, r3] )
  116. eors r3, r3, #0xff @ invert bits
  117. bne .L_found @ any now set - found zero bit
  118. add r2, r2, #8 @ next bit pointer
  119. 2: cmp r2, r1 @ any more?
  120. blo 1b
  121. 3: mov r0, r1 @ no free bits
  122. mov pc, lr
  123. ENDPROC(_find_first_zero_bit_be)
  124. ENTRY(_find_next_zero_bit_be)
  125. teq r1, #0
  126. beq 3b
  127. ands ip, r2, #7
  128. beq 1b @ If new byte, goto old routine
  129. eor r3, r2, #0x18 @ big endian byte ordering
  130. ARM( ldrb r3, [r0, r3, lsr #3] )
  131. THUMB( lsr r3, #3 )
  132. THUMB( ldrb r3, [r0, r3] )
  133. eor r3, r3, #0xff @ now looking for a 1 bit
  134. movs r3, r3, lsr ip @ shift off unused bits
  135. bne .L_found
  136. orr r2, r2, #7 @ if zero, then no bits here
  137. add r2, r2, #1 @ align bit pointer
  138. b 2b @ loop for next bit
  139. ENDPROC(_find_next_zero_bit_be)
  140. ENTRY(_find_first_bit_be)
  141. teq r1, #0
  142. beq 3f
  143. mov r2, #0
  144. 1: eor r3, r2, #0x18 @ big endian byte ordering
  145. ARM( ldrb r3, [r0, r3, lsr #3] )
  146. THUMB( lsr r3, #3 )
  147. THUMB( ldrb r3, [r0, r3] )
  148. movs r3, r3
  149. bne .L_found @ any now set - found zero bit
  150. add r2, r2, #8 @ next bit pointer
  151. 2: cmp r2, r1 @ any more?
  152. blo 1b
  153. 3: mov r0, r1 @ no free bits
  154. mov pc, lr
  155. ENDPROC(_find_first_bit_be)
  156. ENTRY(_find_next_bit_be)
  157. teq r1, #0
  158. beq 3b
  159. ands ip, r2, #7
  160. beq 1b @ If new byte, goto old routine
  161. eor r3, r2, #0x18 @ big endian byte ordering
  162. ARM( ldrb r3, [r0, r3, lsr #3] )
  163. THUMB( lsr r3, #3 )
  164. THUMB( ldrb r3, [r0, r3] )
  165. movs r3, r3, lsr ip @ shift off unused bits
  166. bne .L_found
  167. orr r2, r2, #7 @ if zero, then no bits here
  168. add r2, r2, #1 @ align bit pointer
  169. b 2b @ loop for next bit
  170. ENDPROC(_find_next_bit_be)
  171. #endif
  172. /*
  173. * One or more bits in the LSB of r3 are assumed to be set.
  174. */
  175. .L_found:
  176. #if 1 //__LINUX_ARM_ARCH__ >= 5
  177. rsb r0, r3, #0
  178. and r3, r3, r0
  179. clz r3, r3
  180. rsb r3, r3, #31
  181. add r0, r2, r3
  182. #else
  183. tst r3, #0x0f
  184. addeq r2, r2, #4
  185. movne r3, r3, lsl #4
  186. tst r3, #0x30
  187. addeq r2, r2, #2
  188. movne r3, r3, lsl #2
  189. tst r3, #0x40
  190. addeq r2, r2, #1
  191. mov r0, r2
  192. #endif
  193. cmp r1, r0 @ Clamp to maxbit
  194. movlo r0, r1
  195. mov pc, lr