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