Branch data Line data Source code
1 : : #ifndef __CR_BITOPS_H__
2 : : #define __CR_BITOPS_H__
3 : :
4 : : #ifdef CONFIG_X86_64
5 : :
6 : : #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
7 : : #define BITS_PER_LONG (8 * sizeof(long))
8 : : #define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_LONG)
9 : :
10 : : #define DECLARE_BITMAP(name, bits) \
11 : : unsigned long name[BITS_TO_LONGS(bits)]
12 : :
13 : : #if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 1)
14 : : /* Technically wrong, but this avoids compilation errors on some gcc
15 : : versions. */
16 : : #define BITOP_ADDR(x) "=m" (*(volatile long *) (x))
17 : : #else
18 : : #define BITOP_ADDR(x) "+m" (*(volatile long *) (x))
19 : : #endif
20 : :
21 : : #define ADDR BITOP_ADDR(addr)
22 : :
23 : : static inline void set_bit(int nr, volatile unsigned long *addr)
24 : : {
25 : 25636 : asm volatile("bts %1,%0" : ADDR : "Ir" (nr) : "memory");
26 : : }
27 : :
28 : : static inline void change_bit(int nr, volatile unsigned long *addr)
29 : : {
30 : : asm volatile("btc %1,%0" : ADDR : "Ir" (nr));
31 : : }
32 : :
33 : : static inline int test_bit(int nr, volatile const unsigned long *addr)
34 : : {
35 : : int oldbit;
36 : :
37 : 4384 : asm volatile("bt %2,%1\n\t"
38 : : "sbb %0,%0"
39 : : : "=r" (oldbit)
40 : : : "m" (*(unsigned long *)addr), "Ir" (nr));
41 : :
42 : : return oldbit;
43 : : }
44 : :
45 : : static inline void clear_bit(int nr, volatile unsigned long *addr)
46 : : {
47 : 4200 : asm volatile("btr %1,%0" : ADDR : "Ir" (nr));
48 : : }
49 : :
50 : : /**
51 : : * __ffs - find first set bit in word
52 : : * @word: The word to search
53 : : *
54 : : * Undefined if no bit exists, so code should check against 0 first.
55 : : */
56 : : static inline unsigned long __ffs(unsigned long word)
57 : : {
58 : 1670 : asm("bsf %1,%0"
59 : : : "=r" (word)
60 : : : "rm" (word));
61 : : return word;
62 : : }
63 : :
64 : : #define BITOP_WORD(nr) ((nr) / BITS_PER_LONG)
65 : :
66 : : /*
67 : : * Find the next set bit in a memory region.
68 : : */
69 : : static inline
70 : 4168 : unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
71 : : unsigned long offset)
72 : : {
73 : 4168 : const unsigned long *p = addr + BITOP_WORD(offset);
74 : 4168 : unsigned long result = offset & ~(BITS_PER_LONG-1);
75 : : unsigned long tmp;
76 : :
77 [ + - ]: 4168 : if (offset >= size)
78 : : return size;
79 : 4168 : size -= result;
80 : 4168 : offset %= BITS_PER_LONG;
81 [ + + ]: 4168 : if (offset) {
82 : 1646 : tmp = *(p++);
83 : 1646 : tmp &= (~0UL << offset);
84 [ + + ]: 1646 : if (size < BITS_PER_LONG)
85 : : goto found_first;
86 [ + + ]: 1640 : if (tmp)
87 : : goto found_middle;
88 : 42 : size -= BITS_PER_LONG;
89 : 2564 : result += BITS_PER_LONG;
90 : : }
91 [ + + ]: 7953 : while (size & ~(BITS_PER_LONG-1)) {
92 [ + + ]: 5455 : if ((tmp = *(p++)))
93 : : goto found_middle;
94 : 5389 : result += BITS_PER_LONG;
95 : 5389 : size -= BITS_PER_LONG;
96 : : }
97 [ + + ]: 2498 : if (!size)
98 : : return result;
99 : 1838 : tmp = *p;
100 : :
101 : : found_first:
102 : 1844 : tmp &= (~0UL >> (BITS_PER_LONG - size));
103 [ + + ]: 1844 : if (tmp == 0UL) /* Are any bits set? */
104 : 1838 : return result + size; /* Nope. */
105 : : found_middle:
106 : 4168 : return result + __ffs(tmp);
107 : : }
108 : :
109 : : #define for_each_bit(i, bitmask) \
110 : : for (i = find_next_bit(bitmask, sizeof(bitmask), 0); \
111 : : i < sizeof(bitmask); \
112 : : i = find_next_bit(bitmask, sizeof(bitmask), i + 1))
113 : :
114 : : #else /* CONFIG_X86_64 */
115 : : # error x86-32 is not implemented yet
116 : : #endif /* CONFIG_X86_64 */
117 : :
118 : : #endif /* __CR_BITOPS_H__ */
|