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