Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/shaggy...
[linux-2.6] / 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(generic_find_next_zero_le_bit)
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         com     r8
140         lsr     r8, r8, r10
141         brne    .L_found
142
143         /* r9 = r9 - (32 - r10) = r9 + r10 - 32 */
144         add     r9, r10
145         sub     r9, 32
146         retle   r11
147
148         /* Main loop. offset must be word-aligned */
149 1:      ldswp.w r8, r12[0]
150         com     r8
151         brne    .L_found
152         sub     r12, -4
153         sub     r9, 32
154         brgt    1b
155         retal   r11