Merge git://git.kernel.org/pub/scm/linux/kernel/git/tglx/linux-2.6-hrt
[sfrench/cifs-2.6.git] / include / asm-x86 / bitops_64.h
1 #ifndef _X86_64_BITOPS_H
2 #define _X86_64_BITOPS_H
3
4 /*
5  * Copyright 1992, Linus Torvalds.
6  */
7
8 extern long find_first_zero_bit(const unsigned long *addr, unsigned long size);
9 extern long find_next_zero_bit(const unsigned long *addr, long size, long offset);
10 extern long find_first_bit(const unsigned long *addr, unsigned long size);
11 extern long find_next_bit(const unsigned long *addr, long size, long offset);
12
13 /* return index of first bet set in val or max when no bit is set */
14 static inline long __scanbit(unsigned long val, unsigned long max)
15 {
16         asm("bsfq %1,%0 ; cmovz %2,%0" : "=&r" (val) : "r" (val), "r" (max));
17         return val;
18 }
19
20 #define find_next_bit(addr,size,off) \
21 ((__builtin_constant_p(size) && (size) <= BITS_PER_LONG ?         \
22   ((off) + (__scanbit((*(unsigned long *)addr) >> (off),(size)-(off)))) : \
23         find_next_bit(addr,size,off)))
24
25 #define find_next_zero_bit(addr,size,off) \
26 ((__builtin_constant_p(size) && (size) <= BITS_PER_LONG ?         \
27   ((off)+(__scanbit(~(((*(unsigned long *)addr)) >> (off)),(size)-(off)))) : \
28         find_next_zero_bit(addr,size,off)))
29
30 #define find_first_bit(addr, size)                                      \
31         ((__builtin_constant_p((size)) && (size) <= BITS_PER_LONG       \
32           ? (__scanbit(*(unsigned long *)(addr), (size)))               \
33           : find_first_bit((addr), (size))))
34
35 #define find_first_zero_bit(addr, size)                                 \
36         ((__builtin_constant_p((size)) && (size) <= BITS_PER_LONG       \
37           ? (__scanbit(~*(unsigned long *)(addr), (size)))              \
38           : find_first_zero_bit((addr), (size))))
39
40 static inline void set_bit_string(unsigned long *bitmap, unsigned long i,
41                                   int len)
42 {
43         unsigned long end = i + len;
44         while (i < end) {
45                 __set_bit(i, bitmap);
46                 i++;
47         }
48 }
49
50 /**
51  * ffz - find first zero in word.
52  * @word: The word to search
53  *
54  * Undefined if no zero exists, so code should check against ~0UL first.
55  */
56 static inline unsigned long ffz(unsigned long word)
57 {
58         __asm__("bsfq %1,%0"
59                 :"=r" (word)
60                 :"r" (~word));
61         return word;
62 }
63
64 /**
65  * __ffs - find first bit in word.
66  * @word: The word to search
67  *
68  * Undefined if no bit exists, so code should check against 0 first.
69  */
70 static inline unsigned long __ffs(unsigned long word)
71 {
72         __asm__("bsfq %1,%0"
73                 :"=r" (word)
74                 :"rm" (word));
75         return word;
76 }
77
78 /*
79  * __fls: find last bit set.
80  * @word: The word to search
81  *
82  * Undefined if no zero exists, so code should check against ~0UL first.
83  */
84 static inline unsigned long __fls(unsigned long word)
85 {
86         __asm__("bsrq %1,%0"
87                 :"=r" (word)
88                 :"rm" (word));
89         return word;
90 }
91
92 #ifdef __KERNEL__
93
94 #include <asm-generic/bitops/sched.h>
95
96 /**
97  * ffs - find first bit set
98  * @x: the word to search
99  *
100  * This is defined the same way as
101  * the libc and compiler builtin ffs routines, therefore
102  * differs in spirit from the above ffz (man ffs).
103  */
104 static inline int ffs(int x)
105 {
106         int r;
107
108         __asm__("bsfl %1,%0\n\t"
109                 "cmovzl %2,%0" 
110                 : "=r" (r) : "rm" (x), "r" (-1));
111         return r+1;
112 }
113
114 /**
115  * fls64 - find last bit set in 64 bit word
116  * @x: the word to search
117  *
118  * This is defined the same way as fls.
119  */
120 static inline int fls64(__u64 x)
121 {
122         if (x == 0)
123                 return 0;
124         return __fls(x) + 1;
125 }
126
127 /**
128  * fls - find last bit set
129  * @x: the word to search
130  *
131  * This is defined the same way as ffs.
132  */
133 static inline int fls(int x)
134 {
135         int r;
136
137         __asm__("bsrl %1,%0\n\t"
138                 "cmovzl %2,%0"
139                 : "=&r" (r) : "rm" (x), "rm" (-1));
140         return r+1;
141 }
142
143 #define ARCH_HAS_FAST_MULTIPLIER 1
144
145 #include <asm-generic/bitops/hweight.h>
146
147 #endif /* __KERNEL__ */
148
149 #ifdef __KERNEL__
150
151 #include <asm-generic/bitops/ext2-non-atomic.h>
152
153 #define ext2_set_bit_atomic(lock, nr, addr)                     \
154         test_and_set_bit((nr), (unsigned long *)(addr))
155 #define ext2_clear_bit_atomic(lock, nr, addr)                   \
156         test_and_clear_bit((nr), (unsigned long *)(addr))
157
158 #include <asm-generic/bitops/minix.h>
159
160 #endif /* __KERNEL__ */
161
162 #endif /* _X86_64_BITOPS_H */