patch-2.4.22 linux-2.4.22/include/asm-mips/bitops.h
Next file: linux-2.4.22/include/asm-mips/bootinfo.h
Previous file: linux-2.4.22/include/asm-mips/baget/vic.h
Back to the patch index
Back to the overall index
- Lines: 825
- Date:
2003-08-25 04:44:43.000000000 -0700
- Orig file:
linux-2.4.21/include/asm-mips/bitops.h
- Orig date:
2002-11-28 15:53:15.000000000 -0800
diff -urN linux-2.4.21/include/asm-mips/bitops.h linux-2.4.22/include/asm-mips/bitops.h
@@ -13,6 +13,14 @@
#include <linux/types.h>
#include <asm/byteorder.h> /* sigh ... */
+#if (_MIPS_SZLONG == 32)
+#define SZLONG_LOG 5
+#define SZLONG_MASK 31UL
+#elif (_MIPS_SZLONG == 64)
+#define SZLONG_LOG 6
+#define SZLONG_MASK 63UL
+#endif
+
#ifdef __KERNEL__
#include <asm/sgidefs.h>
@@ -28,17 +36,17 @@
* Only disable interrupt for kernel mode stuff to keep usermode stuff
* that dares to use kernel include files alive.
*/
-#define __bi_flags unsigned long flags
-#define __bi_cli() __cli()
-#define __bi_save_flags(x) __save_flags(x)
-#define __bi_save_and_cli(x) __save_and_cli(x)
-#define __bi_restore_flags(x) __restore_flags(x)
+#define __bi_flags unsigned long flags
+#define __bi_cli() local_irq_disable()
+#define __bi_save_flags(x) local_save_flags(x)
+#define __bi_local_irq_save(x) local_irq_save(x)
+#define __bi_local_irq_restore(x) local_irq_restore(x)
#else
#define __bi_flags
#define __bi_cli()
#define __bi_save_flags(x)
-#define __bi_save_and_cli(x)
-#define __bi_restore_flags(x)
+#define __bi_local_irq_save(x)
+#define __bi_local_irq_restore(x)
#endif /* __KERNEL__ */
#ifdef CONFIG_CPU_HAS_LLSC
@@ -58,8 +66,7 @@
* Note that @nr may be almost arbitrarily large; this function is not
* restricted to acting on a single-word quantity.
*/
-extern __inline__ void
-set_bit(int nr, volatile void *addr)
+static __inline__ void set_bit(int nr, volatile void *addr)
{
unsigned long *m = ((unsigned long *) addr) + (nr >> 5);
unsigned long temp;
@@ -82,7 +89,7 @@
* If it's called on the same region of memory simultaneously, the effect
* may be that only one operation succeeds.
*/
-extern __inline__ void __set_bit(int nr, volatile void * addr)
+static __inline__ void __set_bit(int nr, volatile void * addr)
{
unsigned long * m = ((unsigned long *) addr) + (nr >> 5);
@@ -99,8 +106,7 @@
* you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit()
* in order to ensure changes are visible on other processors.
*/
-extern __inline__ void
-clear_bit(int nr, volatile void *addr)
+static __inline__ void clear_bit(int nr, volatile void *addr)
{
unsigned long *m = ((unsigned long *) addr) + (nr >> 5);
unsigned long temp;
@@ -123,8 +129,7 @@
* Note that @nr may be almost arbitrarily large; this function is not
* restricted to acting on a single-word quantity.
*/
-extern __inline__ void
-change_bit(int nr, volatile void *addr)
+static __inline__ void change_bit(int nr, volatile void *addr)
{
unsigned long *m = ((unsigned long *) addr) + (nr >> 5);
unsigned long temp;
@@ -140,14 +145,14 @@
/*
* __change_bit - Toggle a bit in memory
- * @nr: the bit to set
+ * @nr: the bit to change
* @addr: the address to start counting from
*
* Unlike change_bit(), this function is non-atomic and may be reordered.
* If it's called on the same region of memory simultaneously, the effect
* may be that only one operation succeeds.
*/
-extern __inline__ void __change_bit(int nr, volatile void * addr)
+static __inline__ void __change_bit(int nr, volatile void * addr)
{
unsigned long * m = ((unsigned long *) addr) + (nr >> 5);
@@ -162,11 +167,11 @@
* This operation is atomic and cannot be reordered.
* It also implies a memory barrier.
*/
-extern __inline__ int
-test_and_set_bit(int nr, volatile void *addr)
+static __inline__ int test_and_set_bit(int nr, volatile void *addr)
{
unsigned long *m = ((unsigned long *) addr) + (nr >> 5);
- unsigned long temp, res;
+ unsigned long temp;
+ int res;
__asm__ __volatile__(
".set\tnoreorder\t\t# test_and_set_bit\n"
@@ -195,10 +200,11 @@
* If two examples of this operation race, one can appear to succeed
* but actually fail. You must protect multiple accesses with a lock.
*/
-extern __inline__ int __test_and_set_bit(int nr, volatile void * addr)
+static __inline__ int __test_and_set_bit(int nr, volatile void * addr)
{
- int mask, retval;
- volatile int *a = addr;
+ volatile unsigned long *a = addr;
+ unsigned long mask;
+ int retval;
a += nr >> 5;
mask = 1 << (nr & 0x1f);
@@ -210,14 +216,13 @@
/*
* test_and_clear_bit - Clear a bit and return its old value
- * @nr: Bit to set
+ * @nr: Bit to clear
* @addr: Address to count from
*
* This operation is atomic and cannot be reordered.
* It also implies a memory barrier.
*/
-extern __inline__ int
-test_and_clear_bit(int nr, volatile void *addr)
+static __inline__ int test_and_clear_bit(int nr, volatile void *addr)
{
unsigned long *m = ((unsigned long *) addr) + (nr >> 5);
unsigned long temp, res;
@@ -243,17 +248,17 @@
/*
* __test_and_clear_bit - Clear a bit and return its old value
- * @nr: Bit to set
+ * @nr: Bit to clear
* @addr: Address to count from
*
* This operation is non-atomic and can be reordered.
* If two examples of this operation race, one can appear to succeed
* but actually fail. You must protect multiple accesses with a lock.
*/
-extern __inline__ int __test_and_clear_bit(int nr, volatile void * addr)
+static __inline__ int __test_and_clear_bit(int nr, volatile void * addr)
{
- int mask, retval;
- volatile int *a = addr;
+ volatile unsigned long *a = addr;
+ unsigned long mask, retval;
a += nr >> 5;
mask = 1 << (nr & 0x1f);
@@ -265,14 +270,13 @@
/*
* test_and_change_bit - Change a bit and return its new value
- * @nr: Bit to set
+ * @nr: Bit to change
* @addr: Address to count from
*
* This operation is atomic and cannot be reordered.
* It also implies a memory barrier.
*/
-extern __inline__ int
-test_and_change_bit(int nr, volatile void *addr)
+static __inline__ int test_and_change_bit(int nr, volatile void *addr)
{
unsigned long *m = ((unsigned long *) addr) + (nr >> 5);
unsigned long temp, res;
@@ -297,17 +301,18 @@
/*
* __test_and_change_bit - Change a bit and return its old value
- * @nr: Bit to set
+ * @nr: Bit to change
* @addr: Address to count from
*
* This operation is non-atomic and can be reordered.
* If two examples of this operation race, one can appear to succeed
* but actually fail. You must protect multiple accesses with a lock.
*/
-extern __inline__ int __test_and_change_bit(int nr, volatile void * addr)
+static __inline__ int __test_and_change_bit(int nr, volatile void * addr)
{
- int mask, retval;
- volatile int *a = addr;
+ volatile unsigned long *a = addr;
+ unsigned long mask;
+ int retval;
a += nr >> 5;
mask = 1 << (nr & 0x1f);
@@ -329,17 +334,17 @@
* Note that @nr may be almost arbitrarily large; this function is not
* restricted to acting on a single-word quantity.
*/
-extern __inline__ void set_bit(int nr, volatile void * addr)
+static __inline__ void set_bit(int nr, volatile void * addr)
{
- int mask;
- volatile int *a = addr;
+ volatile unsigned long *a = addr;
+ unsigned long mask;
__bi_flags;
a += nr >> 5;
mask = 1 << (nr & 0x1f);
- __bi_save_and_cli(flags);
+ __bi_local_irq_save(flags);
*a |= mask;
- __bi_restore_flags(flags);
+ __bi_local_irq_restore(flags);
}
/*
@@ -351,10 +356,10 @@
* If it's called on the same region of memory simultaneously, the effect
* may be that only one operation succeeds.
*/
-extern __inline__ void __set_bit(int nr, volatile void * addr)
+static __inline__ void __set_bit(int nr, volatile void * addr)
{
- int mask;
- volatile int *a = addr;
+ volatile unsigned long *a = addr;
+ unsigned long mask;
a += nr >> 5;
mask = 1 << (nr & 0x1f);
@@ -371,51 +376,51 @@
* you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit()
* in order to ensure changes are visible on other processors.
*/
-extern __inline__ void clear_bit(int nr, volatile void * addr)
+static __inline__ void clear_bit(int nr, volatile void * addr)
{
- int mask;
- volatile int *a = addr;
+ volatile unsigned long *a = addr;
+ unsigned long mask;
__bi_flags;
a += nr >> 5;
mask = 1 << (nr & 0x1f);
- __bi_save_and_cli(flags);
+ __bi_local_irq_save(flags);
*a &= ~mask;
- __bi_restore_flags(flags);
+ __bi_local_irq_restore(flags);
}
/*
* change_bit - Toggle a bit in memory
- * @nr: Bit to clear
+ * @nr: Bit to change
* @addr: Address to start counting from
*
* change_bit() is atomic and may not be reordered.
* Note that @nr may be almost arbitrarily large; this function is not
* restricted to acting on a single-word quantity.
*/
-extern __inline__ void change_bit(int nr, volatile void * addr)
+static __inline__ void change_bit(int nr, volatile void * addr)
{
- int mask;
- volatile int *a = addr;
+ volatile unsigned long *a = addr;
+ unsigned long mask;
__bi_flags;
a += nr >> 5;
mask = 1 << (nr & 0x1f);
- __bi_save_and_cli(flags);
+ __bi_local_irq_save(flags);
*a ^= mask;
- __bi_restore_flags(flags);
+ __bi_local_irq_restore(flags);
}
/*
* __change_bit - Toggle a bit in memory
- * @nr: the bit to set
+ * @nr: the bit to change
* @addr: the address to start counting from
*
* Unlike change_bit(), this function is non-atomic and may be reordered.
* If it's called on the same region of memory simultaneously, the effect
* may be that only one operation succeeds.
*/
-extern __inline__ void __change_bit(int nr, volatile void * addr)
+static __inline__ void __change_bit(int nr, volatile void * addr)
{
unsigned long * m = ((unsigned long *) addr) + (nr >> 5);
@@ -430,18 +435,19 @@
* This operation is atomic and cannot be reordered.
* It also implies a memory barrier.
*/
-extern __inline__ int test_and_set_bit(int nr, volatile void * addr)
+static __inline__ int test_and_set_bit(int nr, volatile void * addr)
{
- int mask, retval;
- volatile int *a = addr;
+ volatile unsigned long *a = addr;
+ unsigned long mask;
+ int retval;
__bi_flags;
a += nr >> 5;
mask = 1 << (nr & 0x1f);
- __bi_save_and_cli(flags);
+ __bi_local_irq_save(flags);
retval = (mask & *a) != 0;
*a |= mask;
- __bi_restore_flags(flags);
+ __bi_local_irq_restore(flags);
return retval;
}
@@ -455,10 +461,11 @@
* If two examples of this operation race, one can appear to succeed
* but actually fail. You must protect multiple accesses with a lock.
*/
-extern __inline__ int __test_and_set_bit(int nr, volatile void * addr)
+static __inline__ int __test_and_set_bit(int nr, volatile void * addr)
{
- int mask, retval;
- volatile int *a = addr;
+ volatile unsigned long *a = addr;
+ unsigned long mask;
+ int retval;
a += nr >> 5;
mask = 1 << (nr & 0x1f);
@@ -470,41 +477,43 @@
/*
* test_and_clear_bit - Clear a bit and return its old value
- * @nr: Bit to set
+ * @nr: Bit to clear
* @addr: Address to count from
*
* This operation is atomic and cannot be reordered.
* It also implies a memory barrier.
*/
-extern __inline__ int test_and_clear_bit(int nr, volatile void * addr)
+static __inline__ int test_and_clear_bit(int nr, volatile void * addr)
{
- int mask, retval;
- volatile int *a = addr;
+ volatile unsigned long *a = addr;
+ unsigned long mask;
+ int retval;
__bi_flags;
a += nr >> 5;
mask = 1 << (nr & 0x1f);
- __bi_save_and_cli(flags);
+ __bi_local_irq_save(flags);
retval = (mask & *a) != 0;
*a &= ~mask;
- __bi_restore_flags(flags);
+ __bi_local_irq_restore(flags);
return retval;
}
/*
* __test_and_clear_bit - Clear a bit and return its old value
- * @nr: Bit to set
+ * @nr: Bit to clear
* @addr: Address to count from
*
* This operation is non-atomic and can be reordered.
* If two examples of this operation race, one can appear to succeed
* but actually fail. You must protect multiple accesses with a lock.
*/
-extern __inline__ int __test_and_clear_bit(int nr, volatile void * addr)
+static __inline__ int __test_and_clear_bit(int nr, volatile void * addr)
{
- int mask, retval;
- volatile int *a = addr;
+ volatile unsigned long *a = addr;
+ unsigned long mask;
+ int retval;
a += nr >> 5;
mask = 1 << (nr & 0x1f);
@@ -516,41 +525,42 @@
/*
* test_and_change_bit - Change a bit and return its new value
- * @nr: Bit to set
+ * @nr: Bit to change
* @addr: Address to count from
*
* This operation is atomic and cannot be reordered.
* It also implies a memory barrier.
*/
-extern __inline__ int test_and_change_bit(int nr, volatile void * addr)
+static __inline__ int test_and_change_bit(int nr, volatile void * addr)
{
- int mask, retval;
- volatile int *a = addr;
+ volatile unsigned long *a = addr;
+ unsigned long mask, retval;
__bi_flags;
a += nr >> 5;
mask = 1 << (nr & 0x1f);
- __bi_save_and_cli(flags);
+ __bi_local_irq_save(flags);
retval = (mask & *a) != 0;
*a ^= mask;
- __bi_restore_flags(flags);
+ __bi_local_irq_restore(flags);
return retval;
}
/*
* __test_and_change_bit - Change a bit and return its old value
- * @nr: Bit to set
+ * @nr: Bit to change
* @addr: Address to count from
*
* This operation is non-atomic and can be reordered.
* If two examples of this operation race, one can appear to succeed
* but actually fail. You must protect multiple accesses with a lock.
*/
-extern __inline__ int __test_and_change_bit(int nr, volatile void * addr)
+static __inline__ int __test_and_change_bit(int nr, volatile void * addr)
{
- int mask, retval;
- volatile int *a = addr;
+ volatile unsigned long *a = addr;
+ unsigned long mask;
+ int retval;
a += nr >> 5;
mask = 1 << (nr & 0x1f);
@@ -563,7 +573,7 @@
#undef __bi_flags
#undef __bi_cli
#undef __bi_save_flags
-#undef __bi_restore_flags
+#undef __bi_local_irq_restore
#endif /* MIPS I */
@@ -572,112 +582,11 @@
* @nr: bit number to test
* @addr: Address to start counting from
*/
-extern __inline__ int test_bit(int nr, volatile void *addr)
+static inline int test_bit(int nr, volatile void *addr)
{
- return ((1UL << (nr & 31)) & (((const unsigned int *) addr)[nr >> 5])) != 0;
+ return 1UL & (((const volatile unsigned long *) addr)[nr >> SZLONG_LOG] >> (nr & SZLONG_MASK));
}
-#ifndef __MIPSEB__
-
-/* Little endian versions. */
-
-/*
- * find_first_zero_bit - find the first zero bit in a memory region
- * @addr: The address to start the search at
- * @size: The maximum size to search
- *
- * Returns the bit-number of the first zero bit, not the number of the byte
- * containing a bit.
- */
-extern __inline__ int find_first_zero_bit (void *addr, unsigned size)
-{
- unsigned long dummy;
- int res;
-
- if (!size)
- return 0;
-
- __asm__ (".set\tnoreorder\n\t"
- ".set\tnoat\n"
- "1:\tsubu\t$1,%6,%0\n\t"
- "blez\t$1,2f\n\t"
- "lw\t$1,(%5)\n\t"
- "addiu\t%5,4\n\t"
-#if (_MIPS_ISA == _MIPS_ISA_MIPS2 ) || (_MIPS_ISA == _MIPS_ISA_MIPS3 ) || \
- (_MIPS_ISA == _MIPS_ISA_MIPS4 ) || (_MIPS_ISA == _MIPS_ISA_MIPS5 ) || \
- (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
- "beql\t%1,$1,1b\n\t"
- "addiu\t%0,32\n\t"
-#else
- "addiu\t%0,32\n\t"
- "beq\t%1,$1,1b\n\t"
- "nop\n\t"
- "subu\t%0,32\n\t"
-#endif
-#ifdef __MIPSEB__
-#error "Fix this for big endian"
-#endif /* __MIPSEB__ */
- "li\t%1,1\n"
- "1:\tand\t%2,$1,%1\n\t"
- "beqz\t%2,2f\n\t"
- "sll\t%1,%1,1\n\t"
- "bnez\t%1,1b\n\t"
- "add\t%0,%0,1\n\t"
- ".set\tat\n\t"
- ".set\treorder\n"
- "2:"
- : "=r" (res), "=r" (dummy), "=r" (addr)
- : "0" ((signed int) 0), "1" ((unsigned int) 0xffffffff),
- "2" (addr), "r" (size));
-
- return res;
-}
-
-/*
- * find_next_zero_bit - find the first zero bit in a memory region
- * @addr: The address to base the search on
- * @offset: The bitnumber to start searching at
- * @size: The maximum size to search
- */
-extern __inline__ int find_next_zero_bit (void * addr, int size, int offset)
-{
- unsigned int *p = ((unsigned int *) addr) + (offset >> 5);
- int set = 0, bit = offset & 31, res;
- unsigned long dummy;
-
- if (bit) {
- /*
- * Look for zero in first byte
- */
-#ifdef __MIPSEB__
-#error "Fix this for big endian byte order"
-#endif
- __asm__(".set\tnoreorder\n\t"
- ".set\tnoat\n"
- "1:\tand\t$1,%4,%1\n\t"
- "beqz\t$1,1f\n\t"
- "sll\t%1,%1,1\n\t"
- "bnez\t%1,1b\n\t"
- "addiu\t%0,1\n\t"
- ".set\tat\n\t"
- ".set\treorder\n"
- "1:"
- : "=r" (set), "=r" (dummy)
- : "0" (0), "1" (1 << bit), "r" (*p));
- if (set < (32 - bit))
- return set + offset;
- set = 32 - bit;
- p++;
- }
- /*
- * No zero yet, search remaining full bytes for a zero
- */
- res = find_first_zero_bit(p, size - 32 * (p - (unsigned int *) addr));
- return offset + set + res;
-}
-
-#endif /* !(__MIPSEB__) */
-
/*
* ffz - find first zero in word.
* @word: The word to search
@@ -701,38 +610,23 @@
#ifdef __KERNEL__
-/**
+/*
* ffs - find first bit set
* @x: the word to search
*
- * This is defined the same way as
- * the libc and compiler builtin ffs routines, therefore
- * differs in spirit from the above ffz (man ffs).
+ * Undefined if no bit exists, so code should check against 0 first.
*/
#define ffs(x) generic_ffs(x)
/*
- * hweightN - returns the hamming weight of a N-bit word
- * @x: the word to weigh
- *
- * The Hamming Weight of a number is the total number of bits set in it.
- */
-
-#define hweight32(x) generic_hweight32(x)
-#define hweight16(x) generic_hweight16(x)
-#define hweight8(x) generic_hweight8(x)
-
-#endif /* __KERNEL__ */
-
-#ifdef __MIPSEB__
-/*
* find_next_zero_bit - find the first zero bit in a memory region
* @addr: The address to base the search on
* @offset: The bitnumber to start searching at
* @size: The maximum size to search
*/
-extern __inline__ int find_next_zero_bit(void *addr, int size, int offset)
+static inline long find_next_zero_bit(void *addr, unsigned long size,
+ unsigned long offset)
{
unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
unsigned long result = offset & ~31UL;
@@ -768,9 +662,8 @@
return result + ffz(tmp);
}
-/* Linus sez that gcc can optimize the following correctly, we'll see if this
- * holds on the Sparc as it does for the ALPHA.
- */
+#define find_first_zero_bit(addr, size) \
+ find_next_zero_bit((addr), (size), 0)
#if 0 /* Fool kernel-doc since it doesn't do macros yet */
/*
@@ -781,121 +674,129 @@
* Returns the bit-number of the first zero bit, not the number of the byte
* containing a bit.
*/
-extern int find_first_zero_bit (void *addr, unsigned size);
+static int find_first_zero_bit (void *addr, unsigned size);
#endif
#define find_first_zero_bit(addr, size) \
find_next_zero_bit((addr), (size), 0)
-#endif /* (__MIPSEB__) */
-/* Now for the ext2 filesystem bit operations and helper routines. */
+/*
+ * hweightN - returns the hamming weight of a N-bit word
+ * @x: the word to weigh
+ *
+ * The Hamming Weight of a number is the total number of bits set in it.
+ */
+
+#define hweight32(x) generic_hweight32(x)
+#define hweight16(x) generic_hweight16(x)
+#define hweight8(x) generic_hweight8(x)
+
-#ifdef __MIPSEB__
-extern __inline__ int ext2_set_bit(int nr, void * addr)
+static __inline__ int __test_and_set_le_bit(int nr, void * addr)
{
- int mask, retval, flags;
unsigned char *ADDR = (unsigned char *) addr;
+ int mask, retval;
ADDR += nr >> 3;
mask = 1 << (nr & 0x07);
- save_and_cli(flags);
retval = (mask & *ADDR) != 0;
*ADDR |= mask;
- restore_flags(flags);
+
return retval;
}
-extern __inline__ int ext2_clear_bit(int nr, void * addr)
+static __inline__ int __test_and_clear_le_bit(int nr, void * addr)
{
- int mask, retval, flags;
unsigned char *ADDR = (unsigned char *) addr;
+ int mask, retval;
ADDR += nr >> 3;
mask = 1 << (nr & 0x07);
- save_and_cli(flags);
retval = (mask & *ADDR) != 0;
*ADDR &= ~mask;
- restore_flags(flags);
+
return retval;
}
-extern __inline__ int ext2_test_bit(int nr, const void * addr)
+static __inline__ int test_le_bit(int nr, const void * addr)
{
- int mask;
const unsigned char *ADDR = (const unsigned char *) addr;
+ int mask;
ADDR += nr >> 3;
mask = 1 << (nr & 0x07);
+
return ((mask & *ADDR) != 0);
}
-#define ext2_find_first_zero_bit(addr, size) \
- ext2_find_next_zero_bit((addr), (size), 0)
+static inline unsigned long ext2_ffz(unsigned int word)
+{
+ int b = 0, s;
+
+ word = ~word;
+ s = 16; if (word << 16 != 0) s = 0; b += s; word >>= s;
+ s = 8; if (word << 24 != 0) s = 0; b += s; word >>= s;
+ s = 4; if (word << 28 != 0) s = 0; b += s; word >>= s;
+ s = 2; if (word << 30 != 0) s = 0; b += s; word >>= s;
+ s = 1; if (word << 31 != 0) s = 0; b += s;
+
+ return b;
+}
-extern __inline__ unsigned long ext2_find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
+static inline unsigned long find_next_zero_le_bit(void *addr,
+ unsigned long size, unsigned long offset)
{
- unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
- unsigned long result = offset & ~31UL;
- unsigned long tmp;
+ unsigned int *p = ((unsigned int *) addr) + (offset >> 5);
+ unsigned int result = offset & ~31;
+ unsigned int tmp;
if (offset >= size)
return size;
+
size -= result;
- offset &= 31UL;
- if(offset) {
- /* We hold the little endian value in tmp, but then the
- * shift is illegal. So we could keep a big endian value
- * in tmp, like this:
- *
- * tmp = __swab32(*(p++));
- * tmp |= ~0UL >> (32-offset);
- *
- * but this would decrease preformance, so we change the
- * shift:
- */
- tmp = *(p++);
- tmp |= __swab32(~0UL >> (32-offset));
- if(size < 32)
+ offset &= 31;
+ if (offset) {
+ tmp = cpu_to_le32p(p++);
+ tmp |= ~0U >> (32-offset); /* bug or feature ? */
+ if (size < 32)
goto found_first;
- if(~tmp)
+ if (tmp != ~0U)
goto found_middle;
size -= 32;
result += 32;
}
- while(size & ~31UL) {
- if(~(tmp = *(p++)))
+ while (size >= 32) {
+ if ((tmp = cpu_to_le32p(p++)) != ~0U)
goto found_middle;
result += 32;
size -= 32;
}
- if(!size)
+ if (!size)
return result;
- tmp = *p;
+ tmp = cpu_to_le32p(p);
found_first:
- /* tmp is little endian, so we would have to swab the shift,
- * see above. But then we have to swab tmp below for ffz, so
- * we might as well do this here.
- */
- return result + ffz(__swab32(tmp) | (~0UL << size));
+ tmp |= ~0 << size;
+ if (tmp == ~0U) /* Are any bits zero? */
+ return result + size; /* Nope. */
+
found_middle:
- return result + ffz(__swab32(tmp));
+ return result + ext2_ffz(tmp);
}
-#else /* !(__MIPSEB__) */
-/* Native ext2 byte ordering, just collapse using defines. */
-#define ext2_set_bit(nr, addr) test_and_set_bit((nr), (addr))
-#define ext2_clear_bit(nr, addr) test_and_clear_bit((nr), (addr))
-#define ext2_test_bit(nr, addr) test_bit((nr), (addr))
-#define ext2_find_first_zero_bit(addr, size) find_first_zero_bit((addr), (size))
-#define ext2_find_next_zero_bit(addr, size, offset) \
- find_next_zero_bit((addr), (size), (offset))
+#define find_first_zero_le_bit(addr, size) \
+ find_next_zero_le_bit((addr), (size), 0)
-#endif /* !(__MIPSEB__) */
+#define ext2_set_bit __test_and_set_le_bit
+#define ext2_clear_bit __test_and_clear_le_bit
+#define ext2_test_bit test_le_bit
+#define ext2_find_first_zero_bit find_first_zero_le_bit
+#define ext2_find_next_zero_bit find_next_zero_le_bit
/*
* Bitmap functions for the minix filesystem.
+ *
* FIXME: These assume that Minix uses the native byte/bitorder.
* This limits the Minix filesystem's value for data exchange very much.
*/
@@ -905,4 +806,6 @@
#define minix_test_bit(nr,addr) test_bit(nr,addr)
#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
+#endif /* __KERNEL__ */
+
#endif /* _ASM_BITOPS_H */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)