diff options
author | Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> | 2009-10-22 12:12:47 +0200 |
---|---|---|
committer | Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> | 2009-10-22 12:12:47 +0200 |
commit | 67254a403fe14464e25c378591b139cda8cd867f (patch) | |
tree | 032f2d6136a69a12a5343630f408cde5594c3cf4 /arch/arm/include/asm/bitops.h | |
parent | dac4338cdcdff9693f5b6bd4214ad2b1dd263b57 (diff) | |
download | barebox-67254a403fe14464e25c378591b139cda8cd867f.tar.gz barebox-67254a403fe14464e25c378591b139cda8cd867f.tar.xz |
[ARM] move include/asm-arm to arch/arm/include/asm
Move platform independent header files to arch/arm/include/asm, leaving
those in asm/arch* and asm/proc* alone.
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Diffstat (limited to 'arch/arm/include/asm/bitops.h')
-rw-r--r-- | arch/arm/include/asm/bitops.h | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/arch/arm/include/asm/bitops.h b/arch/arm/include/asm/bitops.h new file mode 100644 index 0000000000..138ebe2d8c --- /dev/null +++ b/arch/arm/include/asm/bitops.h @@ -0,0 +1,184 @@ +/* + * Copyright 1995, Russell King. + * Various bits and pieces copyrights include: + * Linus Torvalds (test_bit). + * + * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1). + * + * 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 + * instructions (which are not available from user mode) to ensure + * that they are atomic. + */ + +#ifndef __ASM_ARM_BITOPS_H +#define __ASM_ARM_BITOPS_H + +#ifndef _LINUX_BITOPS_H +#error only <linux/bitops.h> can be included directly +#endif + +/* + * Functions equivalent of ops.h + */ +static inline void __set_bit(int nr, volatile void *addr) +{ + ((unsigned char *) addr)[nr >> 3] |= (1U << (nr & 7)); +} + +static inline void __clear_bit(int nr, volatile void *addr) +{ + ((unsigned char *) addr)[nr >> 3] &= ~(1U << (nr & 7)); +} + +static inline void __change_bit(int nr, volatile void *addr) +{ + ((unsigned char *) addr)[nr >> 3] ^= (1U << (nr & 7)); +} + +static inline int __test_and_set_bit(int nr, volatile void *addr) +{ + unsigned int mask = 1 << (nr & 7); + unsigned int oldval; + + oldval = ((unsigned char *) addr)[nr >> 3]; + ((unsigned char *) addr)[nr >> 3] = oldval | mask; + return oldval & mask; +} + +static inline int __test_and_clear_bit(int nr, volatile void *addr) +{ + unsigned int mask = 1 << (nr & 7); + unsigned int oldval; + + oldval = ((unsigned char *) addr)[nr >> 3]; + ((unsigned char *) addr)[nr >> 3] = oldval & ~mask; + return oldval & mask; +} + +static inline int __test_and_change_bit(int nr, volatile void *addr) +{ + unsigned int mask = 1 << (nr & 7); + unsigned int oldval; + + oldval = ((unsigned char *) addr)[nr >> 3]; + ((unsigned char *) addr)[nr >> 3] = oldval ^ mask; + return oldval & mask; +} + +/* + * This routine doesn't need to be atomic. + */ +static inline int test_bit(int nr, const void * addr) +{ + return ((unsigned char *) addr)[nr >> 3] & (1U << (nr & 7)); +} + +#define set_bit(x, y) __set_bit(x, y) +#define clear_bit(x, y) __clear_bit(x, y) +#define change_bit(x, y) __change_bit(x, y) +#define test_and_set_bit(x, y) __test_and_set_bit(x, y) +#define test_and_clear_bit(x, y) __test_and_clear_bit(x, y) +#define test_and_change_bit(x, y) __test_and_change_bit(x, y) + +#ifndef __ARMEB__ +/* + * These are the little endian definitions. + */ +extern int _find_first_zero_bit_le(const void *p, unsigned size); +extern int _find_next_zero_bit_le(const 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); +#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)) + +#else /* ! __ARMEB__ */ + +/* + * These are the big endian definitions. + */ +extern int _find_first_zero_bit_be(const void *p, unsigned size); +extern int _find_next_zero_bit_be(const void *p, int size, int offset); +extern int _find_first_bit_be(const unsigned long *p, unsigned size); +extern int _find_next_bit_be(const unsigned long *p, int size, int offset); +#define find_first_zero_bit(p, sz) _find_first_zero_bit_be(p, sz) +#define find_next_zero_bit(p, sz, off) _find_next_zero_bit_be(p, sz, off) +#define find_first_bit(p, sz) _find_first_bit_be(p, sz) +#define find_next_bit(p, sz, off) _find_next_bit_be(p, sz, off) + +#define WORD_BITOFF_TO_LE(x) ((x) ^ 0x18) + +#endif /* __ARMEB__ */ + +#if defined(__LINUX_ARM_ARCH__) && (__LINUX_ARM_ARCH__ >= 5) +static inline int constant_fls(int x) +{ + int r = 32; + + if (!x) + return 0; + if (!(x & 0xffff0000u)) { + x <<= 16; + r -= 16; + } + if (!(x & 0xff000000u)) { + x <<= 8; + r -= 8; + } + if (!(x & 0xf0000000u)) { + x <<= 4; + r -= 4; + } + if (!(x & 0xc0000000u)) { + x <<= 2; + r -= 2; + } + if (!(x & 0x80000000u)) { + x <<= 1; + r -= 1; + } + return r; +} + +/* + * On ARMv5 and above those functions can be implemented around + * the clz instruction for much better code efficiency. + */ +#define fls(x) \ + (__builtin_constant_p(x) ? constant_fls(x) : \ + ({ int __r; asm("clz\t%0, %1" : "=r"(__r) : "r"(x) : "cc"); 32-__r; })) +#define ffs(x) ({ unsigned long __t = (x); fls(__t &-__t); }) +#define __ffs(x) (ffs(x) - 1) +#define ffz(x) __ffs(~(x)) +#else /* ! __ARM__USE_GENERIC_FF */ +/* + * 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; +} +#include <asm-generic/bitops/__ffs.h> +#include <asm-generic/bitops/ffs.h> +#include <asm-generic/bitops/fls.h> +#endif /* __ARM__USE_GENERIC_FF */ +#include <asm-generic/bitops/fls64.h> + +#include <asm-generic/bitops/hweight.h> + +#endif /* _ARM_BITOPS_H */ |