fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / include / asm-arm26 / bitops.h
index b74d9f7..19a6957 100644 (file)
@@ -1,15 +1,15 @@
 /*
  * Copyright 1995, Russell King.
- * Various bits and pieces copyrights include:
- *  Linus Torvalds (test_bit).
- * Big endian support: Copyright 2001, Nicolas Pitre
- *  reworked by rmk.
  *
- * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
+ * Based on the arm32 version by RMK (and others). Their copyrights apply to
+ * Those parts.
+ * Modified for arm26 by Ian Molton on 25/11/04
+ *
+ * bit 0 is the LSB of an "unsigned long" quantity.
  *
  * Please note that the code in this file should never be included
  * from user space.  Many of these are not implemented in assembler
- * since they would be too costly.  Also, they require priviledged
+ * since they would be too costly.  Also, they require privileged
  * instructions (which are not available from user mode) to ensure
  * that they are atomic.
  */
@@ -19,6 +19,7 @@
 
 #ifdef __KERNEL__
 
+#include <linux/compiler.h>
 #include <asm/system.h>
 
 #define smp_mb__before_clear_bit()     do { } while (0)
 
 /*
  * These functions are the basis of our bit ops.
- * First, the atomic bitops.
  *
- * The endian issue for these functions is handled by the macros below.
+ * First, the atomic bitops. These use native endian.
  */
-static inline void
-____atomic_set_bit(unsigned int bit, volatile unsigned long *p)
+static inline void ____atomic_set_bit(unsigned int bit, volatile unsigned long *p)
 {
        unsigned long flags;
        unsigned long mask = 1UL << (bit & 31);
@@ -43,8 +42,7 @@ ____atomic_set_bit(unsigned int bit, volatile unsigned long *p)
        local_irq_restore(flags);
 }
 
-static inline void
-____atomic_clear_bit(unsigned int bit, volatile unsigned long *p)
+static inline void ____atomic_clear_bit(unsigned int bit, volatile unsigned long *p)
 {
        unsigned long flags;
        unsigned long mask = 1UL << (bit & 31);
@@ -56,8 +54,7 @@ ____atomic_clear_bit(unsigned int bit, volatile unsigned long *p)
        local_irq_restore(flags);
 }
 
-static inline void
-____atomic_change_bit(unsigned int bit, volatile unsigned long *p)
+static inline void ____atomic_change_bit(unsigned int bit, volatile unsigned long *p)
 {
        unsigned long flags;
        unsigned long mask = 1UL << (bit & 31);
@@ -104,7 +101,7 @@ ____atomic_test_and_clear_bit(unsigned int bit, volatile unsigned long *p)
 }
 
 static inline int
-____atomic_test_and_change_bit_mask(unsigned int bit, volatile unsigned long *p)
+____atomic_test_and_change_bit(unsigned int bit, volatile unsigned long *p)
 {
        unsigned long flags;
        unsigned int res;
@@ -120,78 +117,7 @@ ____atomic_test_and_change_bit_mask(unsigned int bit, volatile unsigned long *p)
        return res & mask;
 }
 
-/*
- * Now the non-atomic variants.  We let the compiler handle all
- * optimisations for these.  These are all _native_ endian.
- */
-static inline void __set_bit(int nr, volatile unsigned long *p)
-{
-       p[nr >> 5] |= (1UL << (nr & 31));
-}
-
-static inline void __clear_bit(int nr, volatile unsigned long *p)
-{
-       p[nr >> 5] &= ~(1UL << (nr & 31));
-}
-
-static inline void __change_bit(int nr, volatile unsigned long *p)
-{
-       p[nr >> 5] ^= (1UL << (nr & 31));
-}
-
-static inline int __test_and_set_bit(int nr, volatile unsigned long *p)
-{
-       unsigned long oldval, mask = 1UL << (nr & 31);
-
-       p += nr >> 5;
-
-       oldval = *p;
-       *p = oldval | mask;
-       return oldval & mask;
-}
-
-static inline int __test_and_clear_bit(int nr, volatile unsigned long *p)
-{
-       unsigned long oldval, mask = 1UL << (nr & 31);
-
-       p += nr >> 5;
-
-       oldval = *p;
-       *p = oldval & ~mask;
-
-       return oldval & mask;
-}
-
-static inline int __test_and_change_bit(int nr, volatile unsigned long *p)
-{
-       unsigned long oldval, mask = 1UL << (nr & 31);
-
-       p += nr >> 5;
-
-       oldval = *p;
-       *p = oldval ^ mask;
-
-       return oldval & mask;
-}
-
-/*
- * This routine doesn't need to be atomic.
- */
-static inline int __test_bit(int nr, const unsigned long * p)
-{
-       return p[nr >> 5] & (1UL << (nr & 31));
-}
-
-/*
- *  A note about Endian-ness.
- *  -------------------------
- *
- *          ------------ physical data bus bits -----------
- *          D31 ... D24  D23 ... D16  D15 ... D8  D7 ... D0
- *            byte 3       byte 2       byte 1      byte 0
- *
- * Note that bit 0 is defined to be 32-bit word bit 0, not byte 0 bit 0.
- */
+#include <asm-generic/bitops/non-atomic.h>
 
 /*
  * Little endian assembly bitops.  nr = 0 -> byte 0 bit 0.
@@ -202,8 +128,10 @@ extern void _change_bit_le(int nr, volatile unsigned long * p);
 extern int _test_and_set_bit_le(int nr, volatile unsigned long * p);
 extern int _test_and_clear_bit_le(int nr, volatile unsigned long * p);
 extern int _test_and_change_bit_le(int nr, volatile unsigned long * p);
-extern int _find_first_zero_bit_le(void * p, unsigned size);
+extern int _find_first_zero_bit_le(const unsigned long * p, unsigned size);
 extern int _find_next_zero_bit_le(void * p, int size, int offset);
+extern int _find_first_bit_le(const unsigned long *p, unsigned size);
+extern int _find_next_bit_le(const unsigned long *p, int size, int offset);
 
 /*
  * The __* form of bitops are non-atomic and may be reordered.
@@ -213,11 +141,6 @@ extern int _find_next_zero_bit_le(void * p, int size, int offset);
         ____atomic_##name(nr, p) :             \
         _##name##_le(nr,p))
 
-#define        ATOMIC_BITOP_BE(name,nr,p)              \
-       (__builtin_constant_p(nr) ?             \
-        ____atomic_##name(nr, p) :             \
-        _##name##_be(nr,p))
-
 #define NONATOMIC_BITOP(name,nr,p)             \
        (____nonatomic_##name(nr, p))
 
@@ -230,100 +153,35 @@ extern int _find_next_zero_bit_le(void * p, int size, int offset);
 #define test_and_set_bit(nr,p)         ATOMIC_BITOP_LE(test_and_set_bit,nr,p)
 #define test_and_clear_bit(nr,p)       ATOMIC_BITOP_LE(test_and_clear_bit,nr,p)
 #define test_and_change_bit(nr,p)      ATOMIC_BITOP_LE(test_and_change_bit,nr,p)
-#define test_bit(nr,p)                 __test_bit(nr,p)
 #define find_first_zero_bit(p,sz)      _find_first_zero_bit_le(p,sz)
 #define find_next_zero_bit(p,sz,off)   _find_next_zero_bit_le(p,sz,off)
+#define find_first_bit(p,sz)           _find_first_bit_le(p,sz)
+#define find_next_bit(p,sz,off)                _find_next_bit_le(p,sz,off)
 
 #define WORD_BITOFF_TO_LE(x)           ((x))
 
-/*
- * ffz = Find First Zero in word. Undefined if no zero exists,
- * so code should check against ~0UL first..
- */
-static inline unsigned long ffz(unsigned long word)
-{
-       int k;
-
-       word = ~word;
-       k = 31;
-       if (word & 0x0000ffff) { k -= 16; word <<= 16; }
-       if (word & 0x00ff0000) { k -= 8;  word <<= 8;  }
-       if (word & 0x0f000000) { k -= 4;  word <<= 4;  }
-       if (word & 0x30000000) { k -= 2;  word <<= 2;  }
-       if (word & 0x40000000) { k -= 1; }
-        return k;
-}
-
-/*
- * ffz = Find First Zero in word. Undefined if no zero exists,
- * so code should check against ~0UL first..
- */
-static inline unsigned long __ffs(unsigned long word)
-{
-       int k;
-
-       k = 31;
-       if (word & 0x0000ffff) { k -= 16; word <<= 16; }
-       if (word & 0x00ff0000) { k -= 8;  word <<= 8;  }
-       if (word & 0x0f000000) { k -= 4;  word <<= 4;  }
-       if (word & 0x30000000) { k -= 2;  word <<= 2;  }
-       if (word & 0x40000000) { k -= 1; }
-        return k;
-}
-
-/*
- * fls: find last bit set.
- */
-
-#define fls(x) generic_fls(x)
-
-/*
- * ffs: find first bit set. This is defined the same way as
- * the libc and compiler builtin ffs routines, therefore
- * differs in spirit from the above ffz (man ffs).
- */
-
-#define ffs(x) generic_ffs(x)
-
-/*
- * Find first bit set in a 168-bit bitmap, where the first
- * 128 bits are unlikely to be set.
- */
-static inline int sched_find_first_bit(unsigned long *b)
-{
-       unsigned long v;
-       unsigned int off;
-
-       for (off = 0; v = b[off], off < 4; off++) {
-               if (unlikely(v))
-                       break;
-       }
-       return __ffs(v) + off * 32;
-}
-
-/*
- * hweightN: returns the hamming weight (i.e. the number
- * of bits set) of a N-bit word
- */
-
-#define hweight32(x) generic_hweight32(x)
-#define hweight16(x) generic_hweight16(x)
-#define hweight8(x) generic_hweight8(x)
+#include <asm-generic/bitops/ffz.h>
+#include <asm-generic/bitops/__ffs.h>
+#include <asm-generic/bitops/fls.h>
+#include <asm-generic/bitops/fls64.h>
+#include <asm-generic/bitops/ffs.h>
+#include <asm-generic/bitops/sched.h>
+#include <asm-generic/bitops/hweight.h>
 
 /*
  * Ext2 is defined to use little-endian byte ordering.
  * These do not need to be atomic.
  */
 #define ext2_set_bit(nr,p)                     \
-               __test_and_set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)p)
-#define ext2_set_bit_atomic(lock,nr,p)         \
-               test_and_set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
+               __test_and_set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
+#define ext2_set_bit_atomic(lock,nr,p)          \
+                test_and_set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
 #define ext2_clear_bit(nr,p)                   \
-               __test_and_clear_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)p)
+               __test_and_clear_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
 #define ext2_clear_bit_atomic(lock,nr,p)        \
-               test_and_clear_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
+                test_and_clear_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
 #define ext2_test_bit(nr,p)                    \
-               __test_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)p)
+               test_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
 #define ext2_find_first_zero_bit(p,sz)         \
                _find_first_zero_bit_le(p,sz)
 #define ext2_find_next_zero_bit(p,sz,off)      \
@@ -334,15 +192,15 @@ static inline int sched_find_first_bit(unsigned long *b)
  * These do not need to be atomic.
  */
 #define minix_set_bit(nr,p)                    \
-               __set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)p)
+               __set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
 #define minix_test_bit(nr,p)                   \
-               __test_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)p)
+               test_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
 #define minix_test_and_set_bit(nr,p)           \
-               __test_and_set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)p)
+               __test_and_set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
 #define minix_test_and_clear_bit(nr,p)         \
-               __test_and_clear_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)p)
+               __test_and_clear_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
 #define minix_find_first_zero_bit(p,sz)                \
-               _find_first_zero_bit_le(p,sz)
+               _find_first_zero_bit_le((unsigned long *)(p),sz)
 
 #endif /* __KERNEL__ */