blob: 7d30ace41fcb29fe14f83c8db7332b5f6262697a [file] [log] [blame]
wdenkb15cbc02000-08-21 15:05:47 +00001#ifndef _LINUX_BITOPS_H
2#define _LINUX_BITOPS_H
3
Simon Kagstrom13edaf32009-08-24 09:09:50 +02004#include <asm/types.h>
wdenkb15cbc02000-08-21 15:05:47 +00005
Heiko Schocher69bab552015-09-07 13:43:52 +02006#define BIT(nr) (1UL << (nr))
7
wdenkb15cbc02000-08-21 15:05:47 +00008/*
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
14static 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
Simon Kagstrom2258cec2009-08-24 09:10:12 +020043/**
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 */
50static 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
wdenkb15cbc02000-08-21 15:05:47 +000080/*
81 * hweightN: returns the hamming weight (i.e. the number
82 * of bits set) of a N-bit word
83 */
84
85static inline unsigned int generic_hweight32(unsigned int w)
86{
wdenk57b2d802003-06-27 21:31:46 +000087 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);
wdenkb15cbc02000-08-21 15:05:47 +000092}
93
94static inline unsigned int generic_hweight16(unsigned int w)
95{
wdenk57b2d802003-06-27 21:31:46 +000096 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);
wdenkb15cbc02000-08-21 15:05:47 +0000100}
101
102static inline unsigned int generic_hweight8(unsigned int w)
103{
wdenk57b2d802003-06-27 21:31:46 +0000104 unsigned int res = (w & 0x55) + ((w >> 1) & 0x55);
105 res = (res & 0x33) + ((res >> 2) & 0x33);
106 return (res & 0x0F) + ((res >> 4) & 0x0F);
wdenkb15cbc02000-08-21 15:05:47 +0000107}
108
Simon Kagstrom13edaf32009-08-24 09:09:50 +0200109#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
110#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
111
wdenkb15cbc02000-08-21 15:05:47 +0000112#include <asm/bitops.h>
113
Simon Kagstrom13edaf32009-08-24 09:09:50 +0200114/* linux/include/asm-generic/bitops/non-atomic.h */
115
Simon Kagstrom95a3c732009-09-17 15:15:52 +0200116#ifndef PLATFORM__SET_BIT
Simon Kagstrom13edaf32009-08-24 09:09:50 +0200117# define __set_bit generic_set_bit
118#endif
119
Simon Kagstrom95a3c732009-09-17 15:15:52 +0200120#ifndef PLATFORM__CLEAR_BIT
Simon Kagstrom13edaf32009-08-24 09:09:50 +0200121# define __clear_bit generic_clear_bit
122#endif
123
Simon Kagstrom95a3c732009-09-17 15:15:52 +0200124#ifndef PLATFORM_FFS
Simon Kagstrom2258cec2009-08-24 09:10:12 +0200125# define ffs generic_ffs
126#endif
127
Simon Kagstrom95a3c732009-09-17 15:15:52 +0200128#ifndef PLATFORM_FLS
Simon Kagstrom2258cec2009-08-24 09:10:12 +0200129# define fls generic_fls
130#endif
131
Simon Kagstrom13edaf32009-08-24 09:09:50 +0200132/**
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 */
141static 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
149static 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}
wdenkb15cbc02000-08-21 15:05:47 +0000156
157#endif