Merge remote-tracking branch 'selinux/next'
[deliverable/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
This page took 0.042211 seconds and 5 git commands to generate.