"Das U-Boot" Source Tree
at jcs/rk3128 224 lines 5.0 kB view raw
1#ifndef _LINUX_BITOPS_H 2#define _LINUX_BITOPS_H 3 4#if !defined(USE_HOSTCC) && !defined(__ASSEMBLY__) 5 6#include <asm/types.h> 7#include <asm-generic/bitsperlong.h> 8#include <linux/compiler.h> 9 10#ifdef __KERNEL__ 11#define BIT(nr) (1UL << (nr)) 12#define BIT_ULL(nr) (1ULL << (nr)) 13#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG)) 14#define BIT_WORD(nr) ((nr) / BITS_PER_LONG) 15#define BIT_ULL_MASK(nr) (1ULL << ((nr) % BITS_PER_LONG_LONG)) 16#define BIT_ULL_WORD(nr) ((nr) / BITS_PER_LONG_LONG) 17#define BITS_PER_BYTE 8 18#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) 19#endif 20 21/* kernel.h includes log.h which include bitops.h */ 22#include <linux/kernel.h> 23 24/* 25 * Create a contiguous bitmask starting at bit position @l and ending at 26 * position @h. For example 27 * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000. 28 */ 29#ifdef CONFIG_SANDBOX 30#define GENMASK(h, l) \ 31 (((~0UL) << (l)) & (~0UL >> (CONFIG_SANDBOX_BITS_PER_LONG - 1 - (h)))) 32#else 33#define GENMASK(h, l) \ 34 (((~0UL) << (l)) & (~0UL >> (BITS_PER_LONG - 1 - (h)))) 35#endif 36 37#define GENMASK_ULL(h, l) \ 38 (((~0ULL) << (l)) & (~0ULL >> (BITS_PER_LONG_LONG - 1 - (h)))) 39 40/* 41 * ffs: find first bit set. This is defined the same way as 42 * the libc and compiler builtin ffs routines, therefore 43 * differs in spirit from the above ffz (man ffs). 44 */ 45 46static inline int generic_ffs(int x) 47{ 48 int r = 1; 49 50 if (!x) 51 return 0; 52 if (!(x & 0xffff)) { 53 x >>= 16; 54 r += 16; 55 } 56 if (!(x & 0xff)) { 57 x >>= 8; 58 r += 8; 59 } 60 if (!(x & 0xf)) { 61 x >>= 4; 62 r += 4; 63 } 64 if (!(x & 3)) { 65 x >>= 2; 66 r += 2; 67 } 68 if (!(x & 1)) { 69 x >>= 1; 70 r += 1; 71 } 72 return r; 73} 74 75/** 76 * fls - find last (most-significant) bit set 77 * @x: the word to search 78 * 79 * This is defined the same way as ffs. 80 * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32. 81 */ 82static inline int generic_fls(int x) 83{ 84 int r = 32; 85 86 if (!x) 87 return 0; 88 if (!(x & 0xffff0000u)) { 89 x <<= 16; 90 r -= 16; 91 } 92 if (!(x & 0xff000000u)) { 93 x <<= 8; 94 r -= 8; 95 } 96 if (!(x & 0xf0000000u)) { 97 x <<= 4; 98 r -= 4; 99 } 100 if (!(x & 0xc0000000u)) { 101 x <<= 2; 102 r -= 2; 103 } 104 if (!(x & 0x80000000u)) { 105 x <<= 1; 106 r -= 1; 107 } 108 return r; 109} 110 111/* 112 * hweightN: returns the hamming weight (i.e. the number 113 * of bits set) of a N-bit word 114 */ 115 116static inline unsigned int generic_hweight32(unsigned int w) 117{ 118 unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555); 119 res = (res & 0x33333333) + ((res >> 2) & 0x33333333); 120 res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F); 121 res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF); 122 return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF); 123} 124 125static inline unsigned int generic_hweight16(unsigned int w) 126{ 127 unsigned int res = (w & 0x5555) + ((w >> 1) & 0x5555); 128 res = (res & 0x3333) + ((res >> 2) & 0x3333); 129 res = (res & 0x0F0F) + ((res >> 4) & 0x0F0F); 130 return (res & 0x00FF) + ((res >> 8) & 0x00FF); 131} 132 133static inline unsigned int generic_hweight8(unsigned int w) 134{ 135 unsigned int res = (w & 0x55) + ((w >> 1) & 0x55); 136 res = (res & 0x33) + ((res >> 2) & 0x33); 137 return (res & 0x0F) + ((res >> 4) & 0x0F); 138} 139 140static inline unsigned long generic_hweight64(__u64 w) 141{ 142 return generic_hweight32((unsigned int)(w >> 32)) + 143 generic_hweight32((unsigned int)w); 144} 145 146static inline unsigned long hweight_long(unsigned long w) 147{ 148 return sizeof(w) == 4 ? generic_hweight32(w) : generic_hweight64(w); 149} 150 151#include <asm/bitops.h> 152 153/* linux/include/asm-generic/bitops/non-atomic.h */ 154 155#ifndef PLATFORM__SET_BIT 156# define __set_bit generic_set_bit 157#endif 158 159#ifndef PLATFORM__CLEAR_BIT 160# define __clear_bit generic_clear_bit 161#endif 162 163#ifndef PLATFORM_FFS 164# define ffs generic_ffs 165#endif 166 167#ifndef PLATFORM_FLS 168# define fls generic_fls 169#endif 170 171static inline unsigned fls_long(unsigned long l) 172{ 173 if (sizeof(l) == 4) 174 return fls(l); 175 return fls64(l); 176} 177 178/** 179 * __ffs64 - find first set bit in a 64 bit word 180 * @word: The 64 bit word 181 * 182 * On 64 bit arches this is a synomyn for __ffs 183 * The result is not defined if no bits are set, so check that @word 184 * is non-zero before calling this. 185 */ 186static inline unsigned long __ffs64(u64 word) 187{ 188#if BITS_PER_LONG == 32 189 if (((u32)word) == 0UL) 190 return __ffs((u32)(word >> 32)) + 32; 191#elif BITS_PER_LONG != 64 192#error BITS_PER_LONG not 32 or 64 193#endif 194 return __ffs((unsigned long)word); 195} 196 197/** 198 * __set_bit - Set a bit in memory 199 * @nr: the bit to set 200 * @addr: the address to start counting from 201 * 202 * Unlike set_bit(), this function is non-atomic and may be reordered. 203 * If it's called on the same region of memory simultaneously, the effect 204 * may be that only one operation succeeds. 205 */ 206static inline void generic_set_bit(int nr, volatile unsigned long *addr) 207{ 208 unsigned long mask = BIT_MASK(nr); 209 unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); 210 211 *p |= mask; 212} 213 214static inline void generic_clear_bit(int nr, volatile unsigned long *addr) 215{ 216 unsigned long mask = BIT_MASK(nr); 217 unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); 218 219 *p &= ~mask; 220} 221 222#endif /* !USE_HOSTCC && !__ASSEMBLY__ */ 223 224#endif