unicore32 additional architecture files: low-level lib: misc
[linux-2.6.git] / arch / unicore32 / lib / findbit.S
1 /*
2  * linux/arch/unicore32/lib/findbit.S
3  *
4  * Code specific to PKUnity SoC and UniCore ISA
5  *
6  * Copyright (C) 2001-2010 GUAN Xue-tao
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  */
12 #include <linux/linkage.h>
13 #include <asm/assembler.h>
14                 .text
15
16 /*
17  * Purpose  : Find a 'zero' bit
18  * Prototype: int find_first_zero_bit(void *addr, unsigned int maxbit);
19  */
20 __uc32_find_first_zero_bit:
21                 cxor.a  r1, #0
22                 beq     3f
23                 mov     r2, #0
24 1:              ldb     r3, [r0+], r2 >> #3
25                 xor.a   r3, r3, #0xff           @ invert bits
26                 bne     .L_found                @ any now set - found zero bit
27                 add     r2, r2, #8              @ next bit pointer
28 2:              csub.a  r2, r1                  @ any more?
29                 bub     1b
30 3:              mov     r0, r1                  @ no free bits
31                 mov     pc, lr
32
33 /*
34  * Purpose  : Find next 'zero' bit
35  * Prototype: int find_next_zero_bit
36  *              (void *addr, unsigned int maxbit, int offset)
37  */
38 ENTRY(__uc32_find_next_zero_bit)
39                 cxor.a  r1, #0
40                 beq     3b
41                 and.a   ip, r2, #7
42                 beq     1b                      @ If new byte, goto old routine
43                 ldb     r3, [r0+], r2 >> #3
44                 xor     r3, r3, #0xff           @ now looking for a 1 bit
45                 mov.a   r3, r3 >> ip            @ shift off unused bits
46                 bne     .L_found
47                 or      r2, r2, #7              @ if zero, then no bits here
48                 add     r2, r2, #1              @ align bit pointer
49                 b       2b                      @ loop for next bit
50 ENDPROC(__uc32_find_next_zero_bit)
51
52 /*
53  * Purpose  : Find a 'one' bit
54  * Prototype: int find_first_bit
55  *              (const unsigned long *addr, unsigned int maxbit);
56  */
57 __uc32_find_first_bit:
58                 cxor.a  r1, #0
59                 beq     3f
60                 mov     r2, #0
61 1:              ldb     r3, [r0+], r2 >> #3
62                 mov.a   r3, r3
63                 bne     .L_found                @ any now set - found zero bit
64                 add     r2, r2, #8              @ next bit pointer
65 2:              csub.a  r2, r1                  @ any more?
66                 bub     1b
67 3:              mov     r0, r1                  @ no free bits
68                 mov     pc, lr
69
70 /*
71  * Purpose  : Find next 'one' bit
72  * Prototype: int find_next_zero_bit
73  *              (void *addr, unsigned int maxbit, int offset)
74  */
75 ENTRY(__uc32_find_next_bit)
76                 cxor.a  r1, #0
77                 beq     3b
78                 and.a   ip, r2, #7
79                 beq     1b                      @ If new byte, goto old routine
80                 ldb     r3, [r0+], r2 >> #3
81                 mov.a   r3, r3 >> ip            @ shift off unused bits
82                 bne     .L_found
83                 or      r2, r2, #7              @ if zero, then no bits here
84                 add     r2, r2, #1              @ align bit pointer
85                 b       2b                      @ loop for next bit
86 ENDPROC(__uc32_find_next_bit)
87
88 /*
89  * One or more bits in the LSB of r3 are assumed to be set.
90  */
91 .L_found:
92                 rsub    r1, r3, #0
93                 and     r3, r3, r1
94                 cntlz   r3, r3
95                 rsub    r3, r3, #31
96                 add     r0, r2, r3
97                 mov     pc, lr
98