Merge branch 'syscore' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/suspen...
[pandora-kernel.git] / arch / avr32 / lib / findbit.S
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
10         .text
11         /*
12          * unsigned long find_first_zero_bit(const unsigned long *addr,
13          *                                   unsigned long size)
14          */
15 ENTRY(find_first_zero_bit)
16         cp.w    r11, 0
17         reteq   r11
18         mov     r9, r11
19 1:      ld.w    r8, r12[0]
20         com     r8
21         brne    .L_found
22         sub     r12, -4
23         sub     r9, 32
24         brgt    1b
25         retal   r11
26
27         /*
28          * unsigned long find_next_zero_bit(const unsigned long *addr,
29          *                                  unsigned long size,
30          *                                  unsigned long offset)
31          */
32 ENTRY(find_next_zero_bit)
33         lsr     r8, r10, 5
34         sub     r9, r11, r10
35         retle   r11
36
37         lsl     r8, 2
38         add     r12, r8
39         andl    r10, 31, COH
40         breq    1f
41
42         /* offset is not word-aligned. Handle the first (32 - r10) bits */
43         ld.w    r8, r12[0]
44         com     r8
45         sub     r12, -4
46         lsr     r8, r8, r10
47         brne    .L_found
48
49         /* r9 = r9 - (32 - r10) = r9 + r10 - 32 */
50         add     r9, r10
51         sub     r9, 32
52         retle   r11
53
54         /* Main loop. offset must be word-aligned */
55 1:      ld.w    r8, r12[0]
56         com     r8
57         brne    .L_found
58         sub     r12, -4
59         sub     r9, 32
60         brgt    1b
61         retal   r11
62
63         /* Common return path for when a bit is actually found. */
64 .L_found:
65         brev    r8
66         clz     r10, r8
67         rsub    r9, r11
68         add     r10, r9
69
70         /* XXX: If we don't have to return exactly "size" when the bit
71            is not found, we may drop this "min" thing */
72         min     r12, r11, r10
73         retal   r12
74
75         /*
76          * unsigned long find_first_bit(const unsigned long *addr,
77          *                              unsigned long size)
78          */
79 ENTRY(find_first_bit)
80         cp.w    r11, 0
81         reteq   r11
82         mov     r9, r11
83 1:      ld.w    r8, r12[0]
84         cp.w    r8, 0
85         brne    .L_found
86         sub     r12, -4
87         sub     r9, 32
88         brgt    1b
89         retal   r11
90
91         /*
92          * unsigned long find_next_bit(const unsigned long *addr,
93          *                             unsigned long size,
94          *                             unsigned long offset)
95          */
96 ENTRY(find_next_bit)
97         lsr     r8, r10, 5
98         sub     r9, r11, r10
99         retle   r11
100
101         lsl     r8, 2
102         add     r12, r8
103         andl    r10, 31, COH
104         breq    1f
105
106         /* offset is not word-aligned. Handle the first (32 - r10) bits */
107         ld.w    r8, r12[0]
108         sub     r12, -4
109         lsr     r8, r8, r10
110         brne    .L_found
111
112         /* r9 = r9 - (32 - r10) = r9 + r10 - 32 */
113         add     r9, r10
114         sub     r9, 32
115         retle   r11
116
117         /* Main loop. offset must be word-aligned */
118 1:      ld.w    r8, r12[0]
119         cp.w    r8, 0
120         brne    .L_found
121         sub     r12, -4
122         sub     r9, 32
123         brgt    1b
124         retal   r11
125
126 ENTRY(find_next_bit_le)
127         lsr     r8, r10, 5
128         sub     r9, r11, r10
129         retle   r11
130
131         lsl     r8, 2
132         add     r12, r8
133         andl    r10, 31, COH
134         breq    1f
135
136         /* offset is not word-aligned. Handle the first (32 - r10) bits */
137         ldswp.w r8, r12[0]
138         sub     r12, -4
139         lsr     r8, r8, r10
140         brne    .L_found
141
142         /* r9 = r9 - (32 - r10) = r9 + r10 - 32 */
143         add     r9, r10
144         sub     r9, 32
145         retle   r11
146
147         /* Main loop. offset must be word-aligned */
148 1:      ldswp.w r8, r12[0]
149         cp.w    r8, 0
150         brne    .L_found
151         sub     r12, -4
152         sub     r9, 32
153         brgt    1b
154         retal   r11
155
156 ENTRY(find_next_zero_bit_le)
157         lsr     r8, r10, 5
158         sub     r9, r11, r10
159         retle   r11
160
161         lsl     r8, 2
162         add     r12, r8
163         andl    r10, 31, COH
164         breq    1f
165
166         /* offset is not word-aligned. Handle the first (32 - r10) bits */
167         ldswp.w r8, r12[0]
168         sub     r12, -4
169         com     r8
170         lsr     r8, r8, r10
171         brne    .L_found
172
173         /* r9 = r9 - (32 - r10) = r9 + r10 - 32 */
174         add     r9, r10
175         sub     r9, 32
176         retle   r11
177
178         /* Main loop. offset must be word-aligned */
179 1:      ldswp.w r8, r12[0]
180         com     r8
181         brne    .L_found
182         sub     r12, -4
183         sub     r9, 32
184         brgt    1b
185         retal   r11