2 * bitops.h --- Bitmap frobbing code. The byte swapping routines are
5 * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
8 * This file may be redistributed under the terms of the GNU Public
12 * i386 bitops operations taken from <asm/bitops.h>, Copyright 1992,
17 extern int ext2fs_set_bit(unsigned int nr,void * addr);
18 extern int ext2fs_clear_bit(unsigned int nr, void * addr);
19 extern int ext2fs_test_bit(unsigned int nr, const void * addr);
20 extern void ext2fs_fast_set_bit(unsigned int nr,void * addr);
21 extern void ext2fs_fast_clear_bit(unsigned int nr, void * addr);
22 extern int ext2fs_set_bit64(__u64 nr,void * addr);
23 extern int ext2fs_clear_bit64(__u64 nr, void * addr);
24 extern int ext2fs_test_bit64(__u64 nr, const void * addr);
25 extern void ext2fs_fast_set_bit64(__u64 nr,void * addr);
26 extern void ext2fs_fast_clear_bit64(__u64 nr, void * addr);
27 extern __u16 ext2fs_swab16(__u16 val);
28 extern __u32 ext2fs_swab32(__u32 val);
29 extern __u64 ext2fs_swab64(__u64 val);
31 #ifdef WORDS_BIGENDIAN
32 #define ext2fs_cpu_to_le64(x) ext2fs_swab64((x))
33 #define ext2fs_le64_to_cpu(x) ext2fs_swab64((x))
34 #define ext2fs_cpu_to_le32(x) ext2fs_swab32((x))
35 #define ext2fs_le32_to_cpu(x) ext2fs_swab32((x))
36 #define ext2fs_cpu_to_le16(x) ext2fs_swab16((x))
37 #define ext2fs_le16_to_cpu(x) ext2fs_swab16((x))
38 #define ext2fs_cpu_to_be32(x) ((__u32)(x))
39 #define ext2fs_be32_to_cpu(x) ((__u32)(x))
40 #define ext2fs_cpu_to_be16(x) ((__u16)(x))
41 #define ext2fs_be16_to_cpu(x) ((__u16)(x))
43 #define ext2fs_cpu_to_le64(x) ((__u64)(x))
44 #define ext2fs_le64_to_cpu(x) ((__u64)(x))
45 #define ext2fs_cpu_to_le32(x) ((__u32)(x))
46 #define ext2fs_le32_to_cpu(x) ((__u32)(x))
47 #define ext2fs_cpu_to_le16(x) ((__u16)(x))
48 #define ext2fs_le16_to_cpu(x) ((__u16)(x))
49 #define ext2fs_cpu_to_be32(x) ext2fs_swab32((x))
50 #define ext2fs_be32_to_cpu(x) ext2fs_swab32((x))
51 #define ext2fs_cpu_to_be16(x) ext2fs_swab16((x))
52 #define ext2fs_be16_to_cpu(x) ext2fs_swab16((x))
56 * EXT2FS bitmap manipulation routines.
59 /* Support for sending warning messages from the inline subroutines */
60 extern const char *ext2fs_block_string;
61 extern const char *ext2fs_inode_string;
62 extern const char *ext2fs_mark_string;
63 extern const char *ext2fs_unmark_string;
64 extern const char *ext2fs_test_string;
65 extern void ext2fs_warn_bitmap(errcode_t errcode, unsigned long arg,
66 const char *description);
67 extern void ext2fs_warn_bitmap2(ext2fs_generic_bitmap bitmap,
68 int code, unsigned long arg);
70 extern int ext2fs_mark_block_bitmap(ext2fs_block_bitmap bitmap, blk_t block);
71 extern int ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
73 extern int ext2fs_test_block_bitmap(ext2fs_block_bitmap bitmap, blk_t block);
75 extern int ext2fs_mark_inode_bitmap(ext2fs_inode_bitmap bitmap, ext2_ino_t inode);
76 extern int ext2fs_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
78 extern int ext2fs_test_inode_bitmap(ext2fs_inode_bitmap bitmap, ext2_ino_t inode);
80 extern void ext2fs_fast_mark_block_bitmap(ext2fs_block_bitmap bitmap,
82 extern void ext2fs_fast_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
84 extern int ext2fs_fast_test_block_bitmap(ext2fs_block_bitmap bitmap,
87 extern void ext2fs_fast_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
89 extern void ext2fs_fast_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
91 extern int ext2fs_fast_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
93 extern blk_t ext2fs_get_block_bitmap_start(ext2fs_block_bitmap bitmap);
94 extern ext2_ino_t ext2fs_get_inode_bitmap_start(ext2fs_inode_bitmap bitmap);
95 extern blk_t ext2fs_get_block_bitmap_end(ext2fs_block_bitmap bitmap);
96 extern ext2_ino_t ext2fs_get_inode_bitmap_end(ext2fs_inode_bitmap bitmap);
98 extern void ext2fs_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
99 blk_t block, int num);
100 extern void ext2fs_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
101 blk_t block, int num);
102 extern int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
103 blk_t block, int num);
104 extern int ext2fs_test_inode_bitmap_range(ext2fs_inode_bitmap bitmap,
105 ino_t inode, int num);
106 extern void ext2fs_fast_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
107 blk_t block, int num);
108 extern void ext2fs_fast_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
109 blk_t block, int num);
110 extern int ext2fs_fast_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
111 blk_t block, int num);
112 extern void ext2fs_set_bitmap_padding(ext2fs_generic_bitmap map);
114 /* These routines moved to gen_bitmap.c */
115 extern int ext2fs_mark_generic_bitmap(ext2fs_generic_bitmap bitmap,
117 extern int ext2fs_unmark_generic_bitmap(ext2fs_generic_bitmap bitmap,
119 extern int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap,
121 extern int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
122 blk_t block, int num);
123 extern __u32 ext2fs_get_generic_bitmap_start(ext2fs_generic_bitmap bitmap);
124 extern __u32 ext2fs_get_generic_bitmap_end(ext2fs_generic_bitmap bitmap);
127 * The inline routines themselves...
129 * If NO_INLINE_FUNCS is defined, then we won't try to do inline
130 * functions at all; they will be included as normal functions in
133 #ifdef NO_INLINE_FUNCS
134 #if (defined(__GNUC__) && (defined(__i386__) || defined(__i486__) || \
135 defined(__i586__) || defined(__mc68000__)))
136 /* This prevents bitops.c from trying to include the C */
137 /* function version of these functions */
138 #define _EXT2_HAVE_ASM_BITOPS_
140 #endif /* NO_INLINE_FUNCS */
142 #if (defined(INCLUDE_INLINE_FUNCS) || !defined(NO_INLINE_FUNCS))
143 #ifdef INCLUDE_INLINE_FUNCS
144 #define _INLINE_ extern
147 #define _INLINE_ extern __inline__
148 #else /* For Watcom C */
149 #define _INLINE_ extern inline
154 * Fast bit set/clear functions that doesn't need to return the
155 * previous bit value.
158 _INLINE_ void ext2fs_fast_set_bit(unsigned int nr,void * addr)
160 unsigned char *ADDR = (unsigned char *) addr;
163 *ADDR |= (1 << (nr & 0x07));
166 _INLINE_ void ext2fs_fast_clear_bit(unsigned int nr, void * addr)
168 unsigned char *ADDR = (unsigned char *) addr;
171 *ADDR &= ~(1 << (nr & 0x07));
175 _INLINE_ void ext2fs_fast_set_bit64(__u64 nr, void * addr)
177 unsigned char *ADDR = (unsigned char *) addr;
180 *ADDR |= (1 << (nr & 0x07));
183 _INLINE_ void ext2fs_fast_clear_bit64(__u64 nr, void * addr)
185 unsigned char *ADDR = (unsigned char *) addr;
188 *ADDR &= ~(1 << (nr & 0x07));
192 #if ((defined __GNUC__) && !defined(_EXT2_USE_C_VERSIONS_) && \
193 (defined(__i386__) || defined(__i486__) || defined(__i586__)))
195 #define _EXT2_HAVE_ASM_BITOPS_
196 #define _EXT2_HAVE_ASM_SWAB_
199 * These are done by inline assembly for speed reasons.....
201 * All bitoperations return 0 if the bit was cleared before the
202 * operation and != 0 if it was not. Bit 0 is the LSB of addr; bit 32
203 * is the LSB of (addr+1).
207 * Some hacks to defeat gcc over-optimizations..
209 struct __dummy_h { unsigned long a[100]; };
210 #define EXT2FS_ADDR (*(struct __dummy_h *) addr)
211 #define EXT2FS_CONST_ADDR (*(const struct __dummy_h *) addr)
213 _INLINE_ int ext2fs_set_bit(unsigned int nr, void * addr)
217 addr = (void *) (((unsigned char *) addr) + (nr >> 3));
218 __asm__ __volatile__("btsl %2,%1\n\tsbbl %0,%0"
219 :"=r" (oldbit),"+m" (EXT2FS_ADDR)
224 _INLINE_ int ext2fs_clear_bit(unsigned int nr, void * addr)
228 addr = (void *) (((unsigned char *) addr) + (nr >> 3));
229 __asm__ __volatile__("btrl %2,%1\n\tsbbl %0,%0"
230 :"=r" (oldbit),"+m" (EXT2FS_ADDR)
235 _INLINE_ int ext2fs_test_bit(unsigned int nr, const void * addr)
239 addr = (const void *) (((const unsigned char *) addr) + (nr >> 3));
240 __asm__ __volatile__("btl %2,%1\n\tsbbl %0,%0"
242 :"m" (EXT2FS_CONST_ADDR),"r" (nr & 7));
246 _INLINE_ __u32 ext2fs_swab32(__u32 val)
248 #ifdef EXT2FS_REQUIRE_486
249 __asm__("bswap %0" : "=r" (val) : "0" (val));
251 __asm__("xchgb %b0,%h0\n\t" /* swap lower bytes */
252 "rorl $16,%0\n\t" /* swap words */
253 "xchgb %b0,%h0" /* swap higher bytes */
260 _INLINE_ __u16 ext2fs_swab16(__u16 val)
262 __asm__("xchgb %b0,%h0" /* swap bytes */ \
272 #if ((defined __GNUC__) && !defined(_EXT2_USE_C_VERSIONS_) && \
273 (defined(__mc68000__)))
275 #define _EXT2_HAVE_ASM_BITOPS_
277 _INLINE_ int ext2fs_set_bit(unsigned int nr,void * addr)
281 __asm__ __volatile__ ("bfset %2@{%1:#1}; sne %0"
282 : "=d" (retval) : "d" (nr^7), "a" (addr));
287 _INLINE_ int ext2fs_clear_bit(unsigned int nr, void * addr)
291 __asm__ __volatile__ ("bfclr %2@{%1:#1}; sne %0"
292 : "=d" (retval) : "d" (nr^7), "a" (addr));
297 _INLINE_ int ext2fs_test_bit(unsigned int nr, const void * addr)
301 __asm__ __volatile__ ("bftst %2@{%1:#1}; sne %0"
302 : "=d" (retval) : "d" (nr^7), "a" (addr));
307 #endif /* __mc68000__ */
310 #if !defined(_EXT2_HAVE_ASM_SWAB_)
312 _INLINE_ __u16 ext2fs_swab16(__u16 val)
314 return (val >> 8) | (val << 8);
317 _INLINE_ __u32 ext2fs_swab32(__u32 val)
319 return ((val>>24) | ((val>>8)&0xFF00) |
320 ((val<<8)&0xFF0000) | (val<<24));
323 #endif /* !_EXT2_HAVE_ASM_SWAB */
325 _INLINE_ __u64 ext2fs_swab64(__u64 val)
327 return (ext2fs_swab32(val >> 32) |
328 (((__u64)ext2fs_swab32(val & 0xFFFFFFFFUL)) << 32));
331 _INLINE_ int ext2fs_mark_block_bitmap(ext2fs_block_bitmap bitmap,
334 return ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap) bitmap,
338 _INLINE_ int ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
341 return ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap,
345 _INLINE_ int ext2fs_test_block_bitmap(ext2fs_block_bitmap bitmap,
348 return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap,
352 _INLINE_ int ext2fs_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
355 return ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap) bitmap,
359 _INLINE_ int ext2fs_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
362 return ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap,
366 _INLINE_ int ext2fs_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
369 return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap,
373 _INLINE_ void ext2fs_fast_mark_block_bitmap(ext2fs_block_bitmap bitmap,
376 ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap) bitmap, block);
379 _INLINE_ void ext2fs_fast_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
382 ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap, block);
385 _INLINE_ int ext2fs_fast_test_block_bitmap(ext2fs_block_bitmap bitmap,
388 return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap,
392 _INLINE_ void ext2fs_fast_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
395 ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap) bitmap, inode);
398 _INLINE_ void ext2fs_fast_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
401 ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap, inode);
404 _INLINE_ int ext2fs_fast_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
407 return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap,
411 _INLINE_ blk_t ext2fs_get_block_bitmap_start(ext2fs_block_bitmap bitmap)
413 return ext2fs_get_generic_bitmap_start((ext2fs_generic_bitmap) bitmap);
416 _INLINE_ ext2_ino_t ext2fs_get_inode_bitmap_start(ext2fs_inode_bitmap bitmap)
418 return ext2fs_get_generic_bitmap_start((ext2fs_generic_bitmap) bitmap);
421 _INLINE_ blk_t ext2fs_get_block_bitmap_end(ext2fs_block_bitmap bitmap)
423 return ext2fs_get_generic_bitmap_end((ext2fs_generic_bitmap) bitmap);
426 _INLINE_ ext2_ino_t ext2fs_get_inode_bitmap_end(ext2fs_inode_bitmap bitmap)
428 return ext2fs_get_generic_bitmap_end((ext2fs_generic_bitmap) bitmap);
431 _INLINE_ int ext2fs_fast_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
432 blk_t block, int num)
434 return ext2fs_test_block_bitmap_range(bitmap, block, num);
437 _INLINE_ void ext2fs_fast_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
438 blk_t block, int num)
440 ext2fs_mark_block_bitmap_range(bitmap, block, num);
443 _INLINE_ void ext2fs_fast_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
444 blk_t block, int num)
446 ext2fs_unmark_block_bitmap_range(bitmap, block, num);