* added 0.99 linux version
[mascara-docs.git] / i386 / linux / linux-2.3.21 / arch / arm / lib / bitops.S
blob4c1f4b0aa23269f3e09351c00c65cd82966b073d
1 /*
2  * linux/arch/arm/lib/bitops.S
3  *
4  * Copyright (C) 1995, 1996 Russell King
5  */
7 #include <linux/linkage.h>
8 #include <asm/assembler.h>
9                 .text
11 @ Purpose  : Function to set a bit
12 @ Prototype: int set_bit(int bit,int *addr)
14 ENTRY(set_bit)
15                 and     r2, r0, #7
16                 mov     r3, #1
17                 mov     r3, r3, lsl r2
18                 SAVEIRQS(ip)
19                 DISABLEIRQS(ip)
20                 ldrb    r2, [r1, r0, lsr #3]
21                 orr     r2, r2, r3
22                 strb    r2, [r1, r0, lsr #3]
23                 RESTOREIRQS(ip)
24                 RETINSTR(mov,pc,lr)
26 ENTRY(test_and_set_bit)
27                 add     r1, r1, r0, lsr #3      @ Get byte offset
28                 and     r3, r0, #7              @ Get bit offset
29                 mov     r0, #1
30                 SAVEIRQS(ip)
31                 DISABLEIRQS(ip)
32                 ldrb    r2, [r1]
33                 tst     r2, r0, lsl r3
34                 orr     r2, r2, r0, lsl r3
35                 moveq   r0, #0
36                 strb    r2, [r1]
37                 RESTOREIRQS(ip)
38                 RETINSTR(mov,pc,lr)
40 @ Purpose  : Function to clear a bit
41 @ Prototype: int clear_bit(int bit,int *addr)
43 ENTRY(clear_bit)
44                 and     r2, r0, #7
45                 mov     r3, #1
46                 mov     r3, r3, lsl r2
47                 SAVEIRQS(ip)
48                 DISABLEIRQS(ip)
49                 ldrb    r2, [r1, r0, lsr #3]
50                 bic     r2, r2, r3
51                 strb    r2, [r1, r0, lsr #3]
52                 RESTOREIRQS(ip)
53                 RETINSTR(mov,pc,lr)
55 ENTRY(test_and_clear_bit)
56                 add     r1, r1, r0, lsr #3      @ Get byte offset
57                 and     r3, r0, #7      @ Get bit offset
58                 mov     r0, #1
59                 SAVEIRQS(ip)
60                 DISABLEIRQS(ip)
61                 ldrb    r2, [r1]
62                 tst     r2, r0, lsl r3
63                 bic     r2, r2, r0, lsl r3
64                 moveq   r0, #0
65                 strb    r2, [r1]
66                 RESTOREIRQS(ip)
67                 RETINSTR(mov,pc,lr)
69 /* Purpose  : Function to change a bit
70  * Prototype: int change_bit(int bit,int *addr)
71  */
72 ENTRY(change_bit)
73                 and     r2, r0, #7
74                 mov     r3, #1
75                 mov     r3, r3, lsl r2
76                 SAVEIRQS(ip)
77                 DISABLEIRQS(ip)
78                 ldrb    r2, [r1, r0, lsr #3]
79                 eor     r2, r2, r3
80                 strb    r2, [r1, r0, lsr #3]
81                 RESTOREIRQS(ip)
82                 RETINSTR(mov,pc,lr)
84 ENTRY(test_and_change_bit)
85                 add     r1, r1, r0, lsr #3
86                 and     r3, r0, #7
87                 mov     r0, #1
88                 SAVEIRQS(ip)
89                 DISABLEIRQS(ip)
90                 ldrb    r2, [r1]
91                 tst     r2, r0, lsl r3
92                 eor     r2, r2, r0, lsl r3
93                 moveq   r0, #0
94                 strb    r2, [r1]
95                 RESTOREIRQS(ip)
96                 RETINSTR(mov,pc,lr)
98 @ Purpose  : Find a 'zero' bit
99 @ Prototype: int find_first_zero_bit(char *addr,int maxbit);
101 ENTRY(find_first_zero_bit)
102                 mov     r2, #0                  @ Initialise bit position
103 Lfindzbit1lp:   ldrb    r3, [r0, r2, lsr #3]    @ Check byte, if 0xFF, then all bits set
104                 teq     r3, #0xFF
105                 bne     Lfoundzbit
106                 add     r2, r2, #8
107                 cmp     r2, r1                  @ Check to see if we have come to the end
108                 bcc     Lfindzbit1lp
109                 add     r0, r1, #1              @ Make sure that we flag an error
110                 RETINSTR(mov,pc,lr)
111 Lfoundzbit:     tst     r3, #1                  @ Check individual bits
112                 moveq   r0, r2
113                 RETINSTR(moveq,pc,lr)
114                 tst     r3, #2
115                 addeq   r0, r2, #1
116                 RETINSTR(moveq,pc,lr)
117                 tst     r3, #4
118                 addeq   r0, r2, #2
119                 RETINSTR(moveq,pc,lr)
120                 tst     r3, #8
121                 addeq   r0, r2, #3
122                 RETINSTR(moveq,pc,lr)
123                 tst     r3, #16
124                 addeq   r0, r2, #4
125                 RETINSTR(moveq,pc,lr)
126                 tst     r3, #32
127                 addeq   r0, r2, #5
128                 RETINSTR(moveq,pc,lr)
129                 tst     r3, #64
130                 addeq   r0, r2, #6
131                 RETINSTR(moveq,pc,lr)
132                 add     r0, r2, #7
133                 RETINSTR(mov,pc,lr)
135 @ Purpose  : Find next 'zero' bit
136 @ Prototype: int find_next_zero_bit(char *addr,int maxbit,int offset)
138 ENTRY(find_next_zero_bit)
139                 tst     r2, #7
140                 beq     Lfindzbit1lp            @ If new byte, goto old routine
141                 ldrb    r3, [r0, r2, lsr#3]
142                 orr     r3, r3, #0xFF00         @ Set top bits so we wont get confused
143                 stmfd   sp!, {r4}
144                 and     r4, r2, #7
145                 mov     r3, r3, lsr r4          @ Shift right by no. of bits
146                 ldmfd   sp!, {r4}
147                 and     r3, r3, #0xFF
148                 teq     r3, #0xFF
149                 orreq   r2, r2, #7
150                 addeq   r2, r2, #1
151                 beq     Lfindzbit1lp            @ If all bits are set, goto old routine
152                 b       Lfoundzbit