1 #ifndef __ASM_SH_BITOPS_H
2 #define __ASM_SH_BITOPS_H
5 #include <asm/system.h>
7 #include <asm/byteorder.h>
9 extern __inline__
void set_bit(int nr
, void * addr
)
12 unsigned int *a
= addr
;
16 mask
= 1 << (nr
& 0x1f);
23 extern __inline__
void clear_bit(int nr
, void * addr
)
26 unsigned int *a
= addr
;
30 mask
= 1 << (nr
& 0x1f);
37 extern __inline__
void change_bit(int nr
, void * addr
)
40 unsigned int *a
= addr
;
44 mask
= 1 << (nr
& 0x1f);
51 extern __inline__
int test_and_set_bit(int nr
, void * addr
)
54 unsigned int *a
= addr
;
58 mask
= 1 << (nr
& 0x1f);
61 retval
= (mask
& *a
) != 0;
68 extern __inline__
int test_and_clear_bit(int nr
, void * addr
)
71 unsigned int *a
= addr
;
75 mask
= 1 << (nr
& 0x1f);
78 retval
= (mask
& *a
) != 0;
85 extern __inline__
int test_and_change_bit(int nr
, void * addr
)
88 unsigned int *a
= addr
;
92 mask
= 1 << (nr
& 0x1f);
95 retval
= (mask
& *a
) != 0;
103 extern __inline__
int test_bit(int nr
, const void *addr
)
105 return 1UL & (((const int *) addr
)[nr
>> 5] >> (nr
& 31));
108 extern __inline__
unsigned long ffz(unsigned long word
)
110 unsigned long result
;
117 : "r" (word
), "0" (~0L));
121 extern __inline__
int find_next_zero_bit(void *addr
, int size
, int offset
)
123 unsigned long *p
= ((unsigned long *) addr
) + (offset
>> 5);
124 unsigned long result
= offset
& ~31UL;
133 tmp
|= ~0UL >> (32-offset
);
141 while (size
& ~31UL) {
154 return result
+ ffz(tmp
);
157 #define find_first_zero_bit(addr, size) \
158 find_next_zero_bit((addr), (size), 0)
160 extern __inline__
int ext2_set_bit(int nr
,void * addr
)
164 unsigned char *ADDR
= (unsigned char *) addr
;
167 mask
= 1 << (nr
& 0x07);
168 save_flags(flags
); cli();
169 retval
= (mask
& *ADDR
) != 0;
171 restore_flags(flags
);
175 extern __inline__
int ext2_clear_bit(int nr
, void * addr
)
179 unsigned char *ADDR
= (unsigned char *) addr
;
182 mask
= 1 << (nr
& 0x07);
183 save_flags(flags
); cli();
184 retval
= (mask
& *ADDR
) != 0;
186 restore_flags(flags
);
190 extern __inline__
int ext2_test_bit(int nr
, const void * addr
)
193 const unsigned char *ADDR
= (const unsigned char *) addr
;
196 mask
= 1 << (nr
& 0x07);
197 return ((mask
& *ADDR
) != 0);
200 #define ext2_find_first_zero_bit(addr, size) \
201 ext2_find_next_zero_bit((addr), (size), 0)
203 extern __inline__
unsigned long ext2_find_next_zero_bit(void *addr
, unsigned long size
, unsigned long offset
)
205 unsigned long *p
= ((unsigned long *) addr
) + (offset
>> 5);
206 unsigned long result
= offset
& ~31UL;
214 /* We hold the little endian value in tmp, but then the
215 * shift is illegal. So we could keep a big endian value
218 * tmp = __swab32(*(p++));
219 * tmp |= ~0UL >> (32-offset);
221 * but this would decrease preformance, so we change the
225 tmp
|= __swab32(~0UL >> (32-offset
));
233 while(size
& ~31UL) {
244 /* tmp is little endian, so we would have to swab the shift,
245 * see above. But then we have to swab tmp below for ffz, so
246 * we might as well do this here.
248 return result
+ ffz(__swab32(tmp
) | (~0UL << size
));
250 return result
+ ffz(__swab32(tmp
));
253 /* Bitmap functions for the minix filesystem. */
254 #define minix_set_bit(nr,addr) test_and_set_bit(nr,addr)
255 #define minix_clear_bit(nr,addr) test_and_clear_bit(nr,addr)
256 #define minix_test_bit(nr,addr) test_bit(nr,addr)
257 #define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
259 #endif /* __KERNEL__ */
261 #endif /* __ASM_SH_BITOPS_H */