Merge tag 'gcc-plugins-v4.9-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git...
[cascardo/linux.git] / 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 #include <asm/export.h>
19                 .text
20
21 /*
22  * Purpose  : Find a 'zero' bit
23  * Prototype: int find_first_zero_bit(void *addr, unsigned int maxbit);
24  */
25 ENTRY(_find_first_zero_bit_le)
26                 teq     r1, #0  
27                 beq     3f
28                 mov     r2, #0
29 1:
30  ARM(           ldrb    r3, [r0, r2, lsr #3]    )
31  THUMB(         lsr     r3, r2, #3              )
32  THUMB(         ldrb    r3, [r0, r3]            )
33                 eors    r3, r3, #0xff           @ invert bits
34                 bne     .L_found                @ any now set - found zero bit
35                 add     r2, r2, #8              @ next bit pointer
36 2:              cmp     r2, r1                  @ any more?
37                 blo     1b
38 3:              mov     r0, r1                  @ no free bits
39                 ret     lr
40 ENDPROC(_find_first_zero_bit_le)
41 EXPORT_SYMBOL(_find_first_zero_bit_le)
42
43 /*
44  * Purpose  : Find next 'zero' bit
45  * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset)
46  */
47 ENTRY(_find_next_zero_bit_le)
48                 teq     r1, #0
49                 beq     3b
50                 ands    ip, r2, #7
51                 beq     1b                      @ If new byte, goto old routine
52  ARM(           ldrb    r3, [r0, r2, lsr #3]    )
53  THUMB(         lsr     r3, r2, #3              )
54  THUMB(         ldrb    r3, [r0, r3]            )
55                 eor     r3, r3, #0xff           @ now looking for a 1 bit
56                 movs    r3, r3, lsr ip          @ shift off unused bits
57                 bne     .L_found
58                 orr     r2, r2, #7              @ if zero, then no bits here
59                 add     r2, r2, #1              @ align bit pointer
60                 b       2b                      @ loop for next bit
61 ENDPROC(_find_next_zero_bit_le)
62 EXPORT_SYMBOL(_find_next_zero_bit_le)
63
64 /*
65  * Purpose  : Find a 'one' bit
66  * Prototype: int find_first_bit(const unsigned long *addr, unsigned int maxbit);
67  */
68 ENTRY(_find_first_bit_le)
69                 teq     r1, #0  
70                 beq     3f
71                 mov     r2, #0
72 1:
73  ARM(           ldrb    r3, [r0, r2, lsr #3]    )
74  THUMB(         lsr     r3, r2, #3              )
75  THUMB(         ldrb    r3, [r0, r3]            )
76                 movs    r3, r3
77                 bne     .L_found                @ any now set - found zero bit
78                 add     r2, r2, #8              @ next bit pointer
79 2:              cmp     r2, r1                  @ any more?
80                 blo     1b
81 3:              mov     r0, r1                  @ no free bits
82                 ret     lr
83 ENDPROC(_find_first_bit_le)
84 EXPORT_SYMBOL(_find_first_bit_le)
85
86 /*
87  * Purpose  : Find next 'one' bit
88  * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset)
89  */
90 ENTRY(_find_next_bit_le)
91                 teq     r1, #0
92                 beq     3b
93                 ands    ip, r2, #7
94                 beq     1b                      @ If new byte, goto old routine
95  ARM(           ldrb    r3, [r0, r2, lsr #3]    )
96  THUMB(         lsr     r3, r2, #3              )
97  THUMB(         ldrb    r3, [r0, r3]            )
98                 movs    r3, r3, lsr ip          @ shift off unused bits
99                 bne     .L_found
100                 orr     r2, r2, #7              @ if zero, then no bits here
101                 add     r2, r2, #1              @ align bit pointer
102                 b       2b                      @ loop for next bit
103 ENDPROC(_find_next_bit_le)
104 EXPORT_SYMBOL(_find_next_bit_le)
105
106 #ifdef __ARMEB__
107
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                 ret     lr
123 ENDPROC(_find_first_zero_bit_be)
124 EXPORT_SYMBOL(_find_first_zero_bit_be)
125
126 ENTRY(_find_next_zero_bit_be)
127                 teq     r1, #0
128                 beq     3b
129                 ands    ip, r2, #7
130                 beq     1b                      @ If new byte, goto old routine
131                 eor     r3, r2, #0x18           @ big endian byte ordering
132  ARM(           ldrb    r3, [r0, r3, lsr #3]    )
133  THUMB(         lsr     r3, #3                  )
134  THUMB(         ldrb    r3, [r0, r3]            )
135                 eor     r3, r3, #0xff           @ now looking for a 1 bit
136                 movs    r3, r3, lsr ip          @ shift off unused bits
137                 bne     .L_found
138                 orr     r2, r2, #7              @ if zero, then no bits here
139                 add     r2, r2, #1              @ align bit pointer
140                 b       2b                      @ loop for next bit
141 ENDPROC(_find_next_zero_bit_be)
142 EXPORT_SYMBOL(_find_next_zero_bit_be)
143
144 ENTRY(_find_first_bit_be)
145                 teq     r1, #0
146                 beq     3f
147                 mov     r2, #0
148 1:              eor     r3, r2, #0x18           @ big endian byte ordering
149  ARM(           ldrb    r3, [r0, r3, lsr #3]    )
150  THUMB(         lsr     r3, #3                  )
151  THUMB(         ldrb    r3, [r0, r3]            )
152                 movs    r3, r3
153                 bne     .L_found                @ any now set - found zero bit
154                 add     r2, r2, #8              @ next bit pointer
155 2:              cmp     r2, r1                  @ any more?
156                 blo     1b
157 3:              mov     r0, r1                  @ no free bits
158                 ret     lr
159 ENDPROC(_find_first_bit_be)
160 EXPORT_SYMBOL(_find_first_bit_be)
161
162 ENTRY(_find_next_bit_be)
163                 teq     r1, #0
164                 beq     3b
165                 ands    ip, r2, #7
166                 beq     1b                      @ If new byte, goto old routine
167                 eor     r3, r2, #0x18           @ big endian byte ordering
168  ARM(           ldrb    r3, [r0, r3, lsr #3]    )
169  THUMB(         lsr     r3, #3                  )
170  THUMB(         ldrb    r3, [r0, r3]            )
171                 movs    r3, r3, lsr ip          @ shift off unused bits
172                 bne     .L_found
173                 orr     r2, r2, #7              @ if zero, then no bits here
174                 add     r2, r2, #1              @ align bit pointer
175                 b       2b                      @ loop for next bit
176 ENDPROC(_find_next_bit_be)
177 EXPORT_SYMBOL(_find_next_bit_be)
178
179 #endif
180
181 /*
182  * One or more bits in the LSB of r3 are assumed to be set.
183  */
184 .L_found:
185 #if __LINUX_ARM_ARCH__ >= 5
186                 rsb     r0, r3, #0
187                 and     r3, r3, r0
188                 clz     r3, r3
189                 rsb     r3, r3, #31
190                 add     r0, r2, r3
191 #else
192                 tst     r3, #0x0f
193                 addeq   r2, r2, #4
194                 movne   r3, r3, lsl #4
195                 tst     r3, #0x30
196                 addeq   r2, r2, #2
197                 movne   r3, r3, lsl #2
198                 tst     r3, #0x40
199                 addeq   r2, r2, #1
200                 mov     r0, r2
201 #endif
202                 cmp     r1, r0                  @ Clamp to maxbit
203                 movlo   r0, r1
204                 ret     lr
205