1 #ifndef _LINUX_BITOPS_H 2 #define _LINUX_BITOPS_H 3 4 #include <asm/types.h> 5 6 #define BIT(nr) (1UL << (nr)) 7 8 /* 9 * ffs: find first bit set. This is defined the same way as 10 * the libc and compiler builtin ffs routines, therefore 11 * differs in spirit from the above ffz (man ffs). 12 */ 13 14 static inline int generic_ffs(int x) 15 { 16 int r = 1; 17 18 if (!x) 19 return 0; 20 if (!(x & 0xffff)) { 21 x >>= 16; 22 r += 16; 23 } 24 if (!(x & 0xff)) { 25 x >>= 8; 26 r += 8; 27 } 28 if (!(x & 0xf)) { 29 x >>= 4; 30 r += 4; 31 } 32 if (!(x & 3)) { 33 x >>= 2; 34 r += 2; 35 } 36 if (!(x & 1)) { 37 x >>= 1; 38 r += 1; 39 } 40 return r; 41 } 42 43 /** 44 * fls - find last (most-significant) bit set 45 * @x: the word to search 46 * 47 * This is defined the same way as ffs. 48 * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32. 49 */ 50 static inline int generic_fls(int x) 51 { 52 int r = 32; 53 54 if (!x) 55 return 0; 56 if (!(x & 0xffff0000u)) { 57 x <<= 16; 58 r -= 16; 59 } 60 if (!(x & 0xff000000u)) { 61 x <<= 8; 62 r -= 8; 63 } 64 if (!(x & 0xf0000000u)) { 65 x <<= 4; 66 r -= 4; 67 } 68 if (!(x & 0xc0000000u)) { 69 x <<= 2; 70 r -= 2; 71 } 72 if (!(x & 0x80000000u)) { 73 x <<= 1; 74 r -= 1; 75 } 76 return r; 77 } 78 79 80 /* 81 * hweightN: returns the hamming weight (i.e. the number 82 * of bits set) of a N-bit word 83 */ 84 85 static inline unsigned int generic_hweight32(unsigned int w) 86 { 87 unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555); 88 res = (res & 0x33333333) + ((res >> 2) & 0x33333333); 89 res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F); 90 res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF); 91 return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF); 92 } 93 94 static inline unsigned int generic_hweight16(unsigned int w) 95 { 96 unsigned int res = (w & 0x5555) + ((w >> 1) & 0x5555); 97 res = (res & 0x3333) + ((res >> 2) & 0x3333); 98 res = (res & 0x0F0F) + ((res >> 4) & 0x0F0F); 99 return (res & 0x00FF) + ((res >> 8) & 0x00FF); 100 } 101 102 static inline unsigned int generic_hweight8(unsigned int w) 103 { 104 unsigned int res = (w & 0x55) + ((w >> 1) & 0x55); 105 res = (res & 0x33) + ((res >> 2) & 0x33); 106 return (res & 0x0F) + ((res >> 4) & 0x0F); 107 } 108 109 #define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG)) 110 #define BIT_WORD(nr) ((nr) / BITS_PER_LONG) 111 112 #include <asm/bitops.h> 113 114 /* linux/include/asm-generic/bitops/non-atomic.h */ 115 116 #ifndef PLATFORM__SET_BIT 117 # define __set_bit generic_set_bit 118 #endif 119 120 #ifndef PLATFORM__CLEAR_BIT 121 # define __clear_bit generic_clear_bit 122 #endif 123 124 #ifndef PLATFORM_FFS 125 # define ffs generic_ffs 126 #endif 127 128 #ifndef PLATFORM_FLS 129 # define fls generic_fls 130 #endif 131 132 /** 133 * __set_bit - Set a bit in memory 134 * @nr: the bit to set 135 * @addr: the address to start counting from 136 * 137 * Unlike set_bit(), this function is non-atomic and may be reordered. 138 * If it's called on the same region of memory simultaneously, the effect 139 * may be that only one operation succeeds. 140 */ 141 static inline void generic_set_bit(int nr, volatile unsigned long *addr) 142 { 143 unsigned long mask = BIT_MASK(nr); 144 unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); 145 146 *p |= mask; 147 } 148 149 static inline void generic_clear_bit(int nr, volatile unsigned long *addr) 150 { 151 unsigned long mask = BIT_MASK(nr); 152 unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); 153 154 *p &= ~mask; 155 } 156 157 #endif 158