Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
422 giacomo 1
#ifndef _LINUX_BITOPS_H
2
#define _LINUX_BITOPS_H
3
#include <asm/types.h>
4
#include <asm/bitops.h>
5
 
6
/*
7
 * ffs: find first bit set. This is defined the same way as
8
 * the libc and compiler builtin ffs routines, therefore
9
 * differs in spirit from the above ffz (man ffs).
10
 */
11
 
12
static inline int generic_ffs(int x)
13
{
14
        int r = 1;
15
 
16
        if (!x)
17
                return 0;
18
        if (!(x & 0xffff)) {
19
                x >>= 16;
20
                r += 16;
21
        }
22
        if (!(x & 0xff)) {
23
                x >>= 8;
24
                r += 8;
25
        }
26
        if (!(x & 0xf)) {
27
                x >>= 4;
28
                r += 4;
29
        }
30
        if (!(x & 3)) {
31
                x >>= 2;
32
                r += 2;
33
        }
34
        if (!(x & 1)) {
35
                x >>= 1;
36
                r += 1;
37
        }
38
        return r;
39
}
40
 
41
/*
42
 * fls: find last bit set.
43
 */
44
 
45
extern __inline__ int generic_fls(int x)
46
{
47
        int r = 32;
48
 
49
        if (!x)
50
                return 0;
51
        if (!(x & 0xffff0000u)) {
52
                x <<= 16;
53
                r -= 16;
54
        }
55
        if (!(x & 0xff000000u)) {
56
                x <<= 8;
57
                r -= 8;
58
        }
59
        if (!(x & 0xf0000000u)) {
60
                x <<= 4;
61
                r -= 4;
62
        }
63
        if (!(x & 0xc0000000u)) {
64
                x <<= 2;
65
                r -= 2;
66
        }
67
        if (!(x & 0x80000000u)) {
68
                x <<= 1;
69
                r -= 1;
70
        }
71
        return r;
72
}
73
 
74
extern __inline__ int get_bitmask_order(unsigned int count)
75
{
76
        int order;
77
 
78
        order = fls(count);
79
        return order;   /* We could be slightly more clever with -1 here... */
80
}
81
 
82
/*
83
 * hweightN: returns the hamming weight (i.e. the number
84
 * of bits set) of a N-bit word
85
 */
86
 
87
static inline unsigned int generic_hweight32(unsigned int w)
88
{
89
        unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555);
90
        res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
91
        res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F);
92
        res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF);
93
        return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF);
94
}
95
 
96
static inline unsigned int generic_hweight16(unsigned int w)
97
{
98
        unsigned int res = (w & 0x5555) + ((w >> 1) & 0x5555);
99
        res = (res & 0x3333) + ((res >> 2) & 0x3333);
100
        res = (res & 0x0F0F) + ((res >> 4) & 0x0F0F);
101
        return (res & 0x00FF) + ((res >> 8) & 0x00FF);
102
}
103
 
104
static inline unsigned int generic_hweight8(unsigned int w)
105
{
106
        unsigned int res = (w & 0x55) + ((w >> 1) & 0x55);
107
        res = (res & 0x33) + ((res >> 2) & 0x33);
108
        return (res & 0x0F) + ((res >> 4) & 0x0F);
109
}
110
 
111
static inline unsigned long generic_hweight64(__u64 w)
112
{
113
#if BITS_PER_LONG < 64
114
        return generic_hweight32((unsigned int)(w >> 32)) +
115
                                generic_hweight32((unsigned int)w);
116
#else
117
        u64 res;
118
        res = (w & 0x5555555555555555) + ((w >> 1) & 0x5555555555555555);
119
        res = (res & 0x3333333333333333) + ((res >> 2) & 0x3333333333333333);
120
        res = (res & 0x0F0F0F0F0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F0F0F0F0F);
121
        res = (res & 0x00FF00FF00FF00FF) + ((res >> 8) & 0x00FF00FF00FF00FF);
122
        res = (res & 0x0000FFFF0000FFFF) + ((res >> 16) & 0x0000FFFF0000FFFF);
123
        return (res & 0x00000000FFFFFFFF) + ((res >> 32) & 0x00000000FFFFFFFF);
124
#endif
125
}
126
 
127
static inline unsigned long hweight_long(unsigned long w)
128
{
129
        return sizeof(w) == 4 ? generic_hweight32(w) : generic_hweight64(w);
130
}
131
 
132
#endif