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