This source file includes following definitions.
- set_bit
- clear_bit
- change_bit
- find_first_zero_bit
- test_bit
- find_next_zero_bit
- ffz
1
2
3
4
5
6
7
8
9
10 #ifndef __ASM_MIPS_BITOPS_H
11 #define __ASM_MIPS_BITOPS_H
12
13 #include <asm/mipsregs.h>
14
15 #if defined(__R4000__)
16
17
18
19
20 extern __inline__ int set_bit(int nr, void *addr)
21 {
22 int mask, retval, mw;
23
24 addr += ((nr >> 3) & ~3);
25 mask = 1 << (nr & 0x1f);
26 do {
27 mw = load_linked(addr);
28 retval = (mask & mw) != 0;
29 }
30 while (!store_conditional(addr, mw|mask));
31
32 return retval;
33 }
34
35 extern __inline__ int clear_bit(int nr, void *addr)
36 {
37 int mask, retval, mw;
38
39 addr += ((nr >> 3) & ~3);
40 mask = 1 << (nr & 0x1f);
41 do {
42 mw = load_linked(addr);
43 retval = (mask & mw) != 0;
44 }
45 while (!store_conditional(addr, mw & ~mask));
46
47 return retval;
48 }
49
50 extern __inline__ int change_bit(int nr, void *addr)
51 {
52 int mask, retval, mw;
53
54 addr += ((nr >> 3) & ~3);
55 mask = 1 << (nr & 0x1f);
56 do {
57 mw = load_linked(addr);
58 retval = (mask & mw) != 0;
59 }
60 while (!store_conditional(addr, mw ^ mask));
61
62 return retval;
63 }
64
65 extern __inline__ int find_first_zero_bit (void *addr, unsigned size)
66 {
67 int res;
68
69 if (!size)
70 return 0;
71
72 __asm__(".set\tnoreorder\n\t"
73 ".set\tnoat\n"
74 "1:\tsubu\t$1,%2,%0\n\t"
75 "blez\t$1,2f\n\t"
76 "lw\t$1,(%4)\n\t"
77 "addiu\t%4,%4,4\n\t"
78 "beql\t%1,$1,1b\n\t"
79 "addiu\t%0,%0,32\n\t"
80 "li\t%1,1\n"
81 "1:\tand\t%4,$1,%1\n\t"
82 "beq\t$0,%4,2f\n\t"
83 "sll\t%1,%1,1\n\t"
84 "bne\t$0,%1,1b\n\t"
85 "add\t%0,%0,1\n\t"
86 ".set\tat\n\t"
87 ".set\treorder\n"
88 "2:"
89 : "=d" (res)
90 : "d" ((unsigned int) 0xffffffff),
91 "d" (size),
92 "0" ((signed int) 0),
93 "d" (addr)
94 : "$1");
95
96 return res;
97 }
98
99 #else
100
101 #define __USE_PORTABLE_STRINGS_H
102
103 #define __USE_GENERIC_set_bit
104 #define __USE_GENERIC_clear_bit
105 #define __USE_GENERIC_change_bit
106 #define __USE_GENERIC_find_first_zero_bit
107
108 #endif
109
110 extern __inline__ int test_bit(int nr, void *addr)
111 {
112 int mask;
113 unsigned long *a;
114
115 a = addr;
116 addr += nr >> 5;
117 mask = 1 << (nr & 0x1f);
118 return ((mask & *a) != 0);
119 }
120
121 extern __inline__ int find_next_zero_bit (void * addr, int size, int offset)
122 {
123 unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
124 int set = 0, bit = offset & 31, res;
125
126 if (bit) {
127
128
129
130 __asm__(".set\tnoreorder\n\t"
131 ".set\tnoat\n"
132 "1:\tand\t$1,%2,%1\n\t"
133 "beq\t$0,$1,2f\n\t"
134 "sll\t%2,%2,1\n\t"
135 "bne\t$0,%2,1b\n\t"
136 "addiu\t%0,%0,1\n\t"
137 ".set\tat\n\t"
138 ".set\treorder\n"
139 : "=r" (set)
140 : "r" (*p >> bit),
141 "r" (1),
142 "0" (0)
143 : "$1");
144 if (set < (32 - bit))
145 return set + offset;
146 set = 32 - bit;
147 p++;
148 }
149
150
151
152 res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr));
153 return (offset + set + res);
154 }
155
156
157
158
159
160 extern __inline__ unsigned long ffz(unsigned long word)
161 {
162 unsigned int __res;
163 unsigned int mask = 1;
164
165 __asm__ __volatile__ (
166 ".set\tnoreorder\n\t"
167 ".set\tnoat\n\t"
168 "li\t%2,1\n"
169 "1:\tand\t$1,%2,%1\n\t"
170 "beq\t$0,$1,2f\n\t"
171 "sll\t%2,%2,1\n\t"
172 "bne\t$0,%2,1b\n\t"
173 "add\t%0,%0,1\n\t"
174 ".set\tat\n\t"
175 ".set\treorder\n"
176 "2:\n\t"
177 : "=r" (__res), "=r" (word), "=r" (mask)
178 : "1" (~(word)),
179 "2" (mask),
180 "0" (0)
181 : "$1");
182
183 return __res;
184 }
185
186 #ifdef __USE_PORTABLE_BITOPS_H
187 #include <asm-generic/bitops.h>
188 #endif
189
190 #endif