findbit.S 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /*
  2. * Copyright (C) 2006 Atmel Corporation
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2 as
  6. * published by the Free Software Foundation.
  7. */
  8. #include <linux/linkage.h>
  9. .text
  10. /*
  11. * unsigned long find_first_zero_bit(const unsigned long *addr,
  12. * unsigned long size)
  13. */
  14. ENTRY(find_first_zero_bit)
  15. cp.w r11, 0
  16. reteq r11
  17. mov r9, r11
  18. 1: ld.w r8, r12[0]
  19. com r8
  20. brne .L_found
  21. sub r12, -4
  22. sub r9, 32
  23. brgt 1b
  24. retal r11
  25. /*
  26. * unsigned long find_next_zero_bit(const unsigned long *addr,
  27. * unsigned long size,
  28. * unsigned long offset)
  29. */
  30. ENTRY(find_next_zero_bit)
  31. lsr r8, r10, 5
  32. sub r9, r11, r10
  33. retle r11
  34. lsl r8, 2
  35. add r12, r8
  36. andl r10, 31, COH
  37. breq 1f
  38. /* offset is not word-aligned. Handle the first (32 - r10) bits */
  39. ld.w r8, r12[0]
  40. com r8
  41. sub r12, -4
  42. lsr r8, r8, r10
  43. brne .L_found
  44. /* r9 = r9 - (32 - r10) = r9 + r10 - 32 */
  45. add r9, r10
  46. sub r9, 32
  47. retle r11
  48. /* Main loop. offset must be word-aligned */
  49. 1: ld.w r8, r12[0]
  50. com r8
  51. brne .L_found
  52. sub r12, -4
  53. sub r9, 32
  54. brgt 1b
  55. retal r11
  56. /* Common return path for when a bit is actually found. */
  57. .L_found:
  58. brev r8
  59. clz r10, r8
  60. rsub r9, r11
  61. add r10, r9
  62. /* XXX: If we don't have to return exactly "size" when the bit
  63. is not found, we may drop this "min" thing */
  64. min r12, r11, r10
  65. retal r12
  66. /*
  67. * unsigned long find_first_bit(const unsigned long *addr,
  68. * unsigned long size)
  69. */
  70. ENTRY(find_first_bit)
  71. cp.w r11, 0
  72. reteq r11
  73. mov r9, r11
  74. 1: ld.w r8, r12[0]
  75. cp.w r8, 0
  76. brne .L_found
  77. sub r12, -4
  78. sub r9, 32
  79. brgt 1b
  80. retal r11
  81. /*
  82. * unsigned long find_next_bit(const unsigned long *addr,
  83. * unsigned long size,
  84. * unsigned long offset)
  85. */
  86. ENTRY(find_next_bit)
  87. lsr r8, r10, 5
  88. sub r9, r11, r10
  89. retle r11
  90. lsl r8, 2
  91. add r12, r8
  92. andl r10, 31, COH
  93. breq 1f
  94. /* offset is not word-aligned. Handle the first (32 - r10) bits */
  95. ld.w r8, r12[0]
  96. sub r12, -4
  97. lsr r8, r8, r10
  98. brne .L_found
  99. /* r9 = r9 - (32 - r10) = r9 + r10 - 32 */
  100. add r9, r10
  101. sub r9, 32
  102. retle r11
  103. /* Main loop. offset must be word-aligned */
  104. 1: ld.w r8, r12[0]
  105. cp.w r8, 0
  106. brne .L_found
  107. sub r12, -4
  108. sub r9, 32
  109. brgt 1b
  110. retal r11
  111. ENTRY(generic_find_next_zero_le_bit)
  112. lsr r8, r10, 5
  113. sub r9, r11, r10
  114. retle r11
  115. lsl r8, 2
  116. add r12, r8
  117. andl r10, 31, COH
  118. breq 1f
  119. /* offset is not word-aligned. Handle the first (32 - r10) bits */
  120. ldswp.w r8, r12[0]
  121. sub r12, -4
  122. com r8
  123. lsr r8, r8, r10
  124. brne .L_found
  125. /* r9 = r9 - (32 - r10) = r9 + r10 - 32 */
  126. add r9, r10
  127. sub r9, 32
  128. retle r11
  129. /* Main loop. offset must be word-aligned */
  130. 1: ldswp.w r8, r12[0]
  131. com r8
  132. brne .L_found
  133. sub r12, -4
  134. sub r9, 32
  135. brgt 1b
  136. retal r11