at v2.6.21 123 lines 2.8 kB view raw
1/* 2 * include/asm-xtensa/bitops.h 3 * 4 * Atomic operations that C can't guarantee us.Useful for resource counting etc. 5 * 6 * This file is subject to the terms and conditions of the GNU General Public 7 * License. See the file "COPYING" in the main directory of this archive 8 * for more details. 9 * 10 * Copyright (C) 2001 - 2005 Tensilica Inc. 11 */ 12 13#ifndef _XTENSA_BITOPS_H 14#define _XTENSA_BITOPS_H 15 16#ifdef __KERNEL__ 17 18#include <asm/processor.h> 19#include <asm/byteorder.h> 20#include <asm/system.h> 21 22#ifdef CONFIG_SMP 23# error SMP not supported on this architecture 24#endif 25 26#define smp_mb__before_clear_bit() barrier() 27#define smp_mb__after_clear_bit() barrier() 28 29#include <asm-generic/bitops/atomic.h> 30#include <asm-generic/bitops/non-atomic.h> 31 32#if XCHAL_HAVE_NSA 33 34static __inline__ int __cntlz (unsigned long x) 35{ 36 int lz; 37 asm ("nsau %0, %1" : "=r" (lz) : "r" (x)); 38 return 31 - lz; 39} 40 41#else 42 43static __inline__ int __cntlz (unsigned long x) 44{ 45 unsigned long sum, x1, x2, x4, x8, x16; 46 x1 = x & 0xAAAAAAAA; 47 x2 = x & 0xCCCCCCCC; 48 x4 = x & 0xF0F0F0F0; 49 x8 = x & 0xFF00FF00; 50 x16 = x & 0xFFFF0000; 51 sum = x2 ? 2 : 0; 52 sum += (x16 != 0) * 16; 53 sum += (x8 != 0) * 8; 54 sum += (x4 != 0) * 4; 55 sum += (x1 != 0); 56 57 return sum; 58} 59 60#endif 61 62/* 63 * ffz: Find first zero in word. Undefined if no zero exists. 64 * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1). 65 */ 66 67static __inline__ int ffz(unsigned long x) 68{ 69 if ((x = ~x) == 0) 70 return 32; 71 return __cntlz(x & -x); 72} 73 74/* 75 * __ffs: Find first bit set in word. Return 0 for bit 0 76 */ 77 78static __inline__ int __ffs(unsigned long x) 79{ 80 return __cntlz(x & -x); 81} 82 83/* 84 * ffs: Find first bit set in word. This is defined the same way as 85 * the libc and compiler builtin ffs routines, therefore 86 * differs in spirit from the above ffz (man ffs). 87 */ 88 89static __inline__ int ffs(unsigned long x) 90{ 91 return __cntlz(x & -x) + 1; 92} 93 94/* 95 * fls: Find last (most-significant) bit set in word. 96 * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32. 97 */ 98 99static __inline__ int fls (unsigned int x) 100{ 101 return __cntlz(x); 102} 103#include <asm-generic/bitops/fls64.h> 104#include <asm-generic/bitops/find.h> 105#include <asm-generic/bitops/ext2-non-atomic.h> 106 107#ifdef __XTENSA_EL__ 108# define ext2_set_bit_atomic(lock,nr,addr) test_and_set_bit((nr),(addr)) 109# define ext2_clear_bit_atomic(lock,nr,addr) test_and_clear_bit((nr),(addr)) 110#elif defined(__XTENSA_EB__) 111# define ext2_set_bit_atomic(lock,nr,addr) test_and_set_bit((nr) ^ 0x18, (addr)) 112# define ext2_clear_bit_atomic(lock,nr,addr) test_and_clear_bit((nr)^0x18,(addr)) 113#else 114# error processor byte order undefined! 115#endif 116 117#include <asm-generic/bitops/hweight.h> 118#include <asm-generic/bitops/sched.h> 119#include <asm-generic/bitops/minix.h> 120 121#endif /* __KERNEL__ */ 122 123#endif /* _XTENSA_BITOPS_H */