Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Merge branch 'devel'
[palacios.git] / kitten / include / arch-x86_64 / bitops.h
1 #ifndef _X86_64_BITOPS_H
2 #define _X86_64_BITOPS_H
3
4 /*
5  * Copyright 1992, Linus Torvalds.
6  */
7
8 #define ADDR (*(volatile long *) addr)
9
10 /**
11  * set_bit - Atomically set a bit in memory
12  * @nr: the bit to set
13  * @addr: the address to start counting from
14  *
15  * This function is atomic and may not be reordered.  See __set_bit()
16  * if you do not require the atomic guarantees.
17  * Note that @nr may be almost arbitrarily large; this function is not
18  * restricted to acting on a single-word quantity.
19  */
20 static __inline__ void set_bit(int nr, volatile void * addr)
21 {
22         __asm__ __volatile__(
23                 "lock ; btsl %1,%0"
24                 :"+m" (ADDR)
25                 :"dIr" (nr) : "memory");
26 }
27
28 /**
29  * __set_bit - Set a bit in memory
30  * @nr: the bit to set
31  * @addr: the address to start counting from
32  *
33  * Unlike set_bit(), this function is non-atomic and may be reordered.
34  * If it's called on the same region of memory simultaneously, the effect
35  * may be that only one operation succeeds.
36  */
37 static __inline__ void __set_bit(int nr, volatile void * addr)
38 {
39         __asm__ volatile(
40                 "btsl %1,%0"
41                 :"+m" (ADDR)
42                 :"dIr" (nr) : "memory");
43 }
44
45 /**
46  * clear_bit - Clears a bit in memory
47  * @nr: Bit to clear
48  * @addr: Address to start counting from
49  *
50  * clear_bit() is atomic and may not be reordered.  However, it does
51  * not contain a memory barrier, so if it is used for locking purposes,
52  * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit()
53  * in order to ensure changes are visible on other processors.
54  */
55 static __inline__ void clear_bit(int nr, volatile void * addr)
56 {
57         __asm__ __volatile__(
58                 "lock ; btrl %1,%0"
59                 :"+m" (ADDR)
60                 :"dIr" (nr));
61 }
62
63 static __inline__ void __clear_bit(int nr, volatile void * addr)
64 {
65         __asm__ __volatile__(
66                 "btrl %1,%0"
67                 :"+m" (ADDR)
68                 :"dIr" (nr));
69 }
70
71 #define smp_mb__before_clear_bit()      barrier()
72 #define smp_mb__after_clear_bit()       barrier()
73
74 /**
75  * __change_bit - Toggle a bit in memory
76  * @nr: the bit to change
77  * @addr: the address to start counting from
78  *
79  * Unlike change_bit(), this function is non-atomic and may be reordered.
80  * If it's called on the same region of memory simultaneously, the effect
81  * may be that only one operation succeeds.
82  */
83 static __inline__ void __change_bit(int nr, volatile void * addr)
84 {
85         __asm__ __volatile__(
86                 "btcl %1,%0"
87                 :"+m" (ADDR)
88                 :"dIr" (nr));
89 }
90
91 /**
92  * change_bit - Toggle a bit in memory
93  * @nr: Bit to change
94  * @addr: Address to start counting from
95  *
96  * change_bit() is atomic and may not be reordered.
97  * Note that @nr may be almost arbitrarily large; this function is not
98  * restricted to acting on a single-word quantity.
99  */
100 static __inline__ void change_bit(int nr, volatile void * addr)
101 {
102         __asm__ __volatile__(
103                 "lock ; btcl %1,%0"
104                 :"+m" (ADDR)
105                 :"dIr" (nr));
106 }
107
108 /**
109  * test_and_set_bit - Set a bit and return its old value
110  * @nr: Bit to set
111  * @addr: Address to count from
112  *
113  * This operation is atomic and cannot be reordered.  
114  * It also implies a memory barrier.
115  */
116 static __inline__ int test_and_set_bit(int nr, volatile void * addr)
117 {
118         int oldbit;
119
120         __asm__ __volatile__(
121                 "lock ; btsl %2,%1\n\tsbbl %0,%0"
122                 :"=r" (oldbit),"+m" (ADDR)
123                 :"dIr" (nr) : "memory");
124         return oldbit;
125 }
126
127 /**
128  * __test_and_set_bit - Set a bit and return its old value
129  * @nr: Bit to set
130  * @addr: Address to count from
131  *
132  * This operation is non-atomic and can be reordered.  
133  * If two examples of this operation race, one can appear to succeed
134  * but actually fail.  You must protect multiple accesses with a lock.
135  */
136 static __inline__ int __test_and_set_bit(int nr, volatile void * addr)
137 {
138         int oldbit;
139
140         __asm__(
141                 "btsl %2,%1\n\tsbbl %0,%0"
142                 :"=r" (oldbit),"+m" (ADDR)
143                 :"dIr" (nr));
144         return oldbit;
145 }
146
147 /**
148  * test_and_clear_bit - Clear a bit and return its old value
149  * @nr: Bit to clear
150  * @addr: Address to count from
151  *
152  * This operation is atomic and cannot be reordered.  
153  * It also implies a memory barrier.
154  */
155 static __inline__ int test_and_clear_bit(int nr, volatile void * addr)
156 {
157         int oldbit;
158
159         __asm__ __volatile__(
160                 "lock ; btrl %2,%1\n\tsbbl %0,%0"
161                 :"=r" (oldbit),"+m" (ADDR)
162                 :"dIr" (nr) : "memory");
163         return oldbit;
164 }
165
166 /**
167  * __test_and_clear_bit - Clear a bit and return its old value
168  * @nr: Bit to clear
169  * @addr: Address to count from
170  *
171  * This operation is non-atomic and can be reordered.  
172  * If two examples of this operation race, one can appear to succeed
173  * but actually fail.  You must protect multiple accesses with a lock.
174  */
175 static __inline__ int __test_and_clear_bit(int nr, volatile void * addr)
176 {
177         int oldbit;
178
179         __asm__(
180                 "btrl %2,%1\n\tsbbl %0,%0"
181                 :"=r" (oldbit),"+m" (ADDR)
182                 :"dIr" (nr));
183         return oldbit;
184 }
185
186 /* WARNING: non atomic and it can be reordered! */
187 static __inline__ int __test_and_change_bit(int nr, volatile void * addr)
188 {
189         int oldbit;
190
191         __asm__ __volatile__(
192                 "btcl %2,%1\n\tsbbl %0,%0"
193                 :"=r" (oldbit),"+m" (ADDR)
194                 :"dIr" (nr) : "memory");
195         return oldbit;
196 }
197
198 /**
199  * test_and_change_bit - Change a bit and return its old value
200  * @nr: Bit to change
201  * @addr: Address to count from
202  *
203  * This operation is atomic and cannot be reordered.  
204  * It also implies a memory barrier.
205  */
206 static __inline__ int test_and_change_bit(int nr, volatile void * addr)
207 {
208         int oldbit;
209
210         __asm__ __volatile__(
211                 "lock ; btcl %2,%1\n\tsbbl %0,%0"
212                 :"=r" (oldbit),"+m" (ADDR)
213                 :"dIr" (nr) : "memory");
214         return oldbit;
215 }
216
217 #if 0 /* Fool kernel-doc since it doesn't do macros yet */
218 /**
219  * test_bit - Determine whether a bit is set
220  * @nr: bit number to test
221  * @addr: Address to start counting from
222  */
223 static int test_bit(int nr, const volatile void * addr);
224 #endif
225
226 static __inline__ int constant_test_bit(int nr, const volatile void * addr)
227 {
228         return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0;
229 }
230
231 static __inline__ int variable_test_bit(int nr, volatile const void * addr)
232 {
233         int oldbit;
234
235         __asm__ __volatile__(
236                 "btl %2,%1\n\tsbbl %0,%0"
237                 :"=r" (oldbit)
238                 :"m" (ADDR),"dIr" (nr));
239         return oldbit;
240 }
241
242 #define test_bit(nr,addr) \
243 (__builtin_constant_p(nr) ? \
244  constant_test_bit((nr),(addr)) : \
245  variable_test_bit((nr),(addr)))
246
247 #undef ADDR
248
249 extern long find_first_zero_bit(const unsigned long * addr, unsigned long size);
250 extern long find_next_zero_bit (const unsigned long * addr, long size, long offset);
251 extern long find_first_bit(const unsigned long * addr, unsigned long size);
252 extern long find_next_bit(const unsigned long * addr, long size, long offset);
253
254 /* return index of first bet set in val or max when no bit is set */
255 static inline unsigned long __scanbit(unsigned long val, unsigned long max)
256 {
257         asm("bsfq %1,%0 ; cmovz %2,%0" : "=&r" (val) : "r" (val), "r" (max));
258         return val;
259 }
260
261 #define find_first_bit(addr,size) \
262 ((__builtin_constant_p(size) && (size) <= BITS_PER_LONG ? \
263   (__scanbit(*(unsigned long *)addr,(size))) : \
264   find_first_bit(addr,size)))
265
266 #define find_next_bit(addr,size,off) \
267 ((__builtin_constant_p(size) && (size) <= BITS_PER_LONG ?         \
268   ((off) + (__scanbit((*(unsigned long *)addr) >> (off),(size)-(off)))) : \
269         find_next_bit(addr,size,off)))
270
271 #define find_first_zero_bit(addr,size) \
272 ((__builtin_constant_p(size) && (size) <= BITS_PER_LONG ? \
273   (__scanbit(~*(unsigned long *)addr,(size))) : \
274         find_first_zero_bit(addr,size)))
275         
276 #define find_next_zero_bit(addr,size,off) \
277 ((__builtin_constant_p(size) && (size) <= BITS_PER_LONG ?         \
278   ((off)+(__scanbit(~(((*(unsigned long *)addr)) >> (off)),(size)-(off)))) : \
279         find_next_zero_bit(addr,size,off)))
280
281 /* 
282  * Find string of zero bits in a bitmap. -1 when not found.
283  */ 
284 extern unsigned long 
285 find_next_zero_string(unsigned long *bitmap, long start, long nbits, int len);
286
287 static inline void set_bit_string(unsigned long *bitmap, unsigned long i, 
288                                   int len) 
289
290         unsigned long end = i + len; 
291         while (i < end) {
292                 __set_bit(i, bitmap); 
293                 i++;
294         }
295
296
297 static inline void __clear_bit_string(unsigned long *bitmap, unsigned long i, 
298                                     int len) 
299
300         unsigned long end = i + len; 
301         while (i < end) {
302                 __clear_bit(i, bitmap); 
303                 i++;
304         }
305
306
307 /**
308  * ffz - find first zero in word.
309  * @word: The word to search
310  *
311  * Undefined if no zero exists, so code should check against ~0UL first.
312  */
313 static __inline__ unsigned long ffz(unsigned long word)
314 {
315         __asm__("bsfq %1,%0"
316                 :"=r" (word)
317                 :"r" (~word));
318         return word;
319 }
320
321 /**
322  * __ffs - find first bit in word.
323  * @word: The word to search
324  *
325  * Undefined if no bit exists, so code should check against 0 first.
326  */
327 static __inline__ unsigned long __ffs(unsigned long word)
328 {
329         __asm__("bsfq %1,%0"
330                 :"=r" (word)
331                 :"rm" (word));
332         return word;
333 }
334
335 /*
336  * __fls: find last bit set.
337  * @word: The word to search
338  *
339  * Undefined if no zero exists, so code should check against ~0UL first.
340  */
341 static __inline__ unsigned long __fls(unsigned long word)
342 {
343         __asm__("bsrq %1,%0"
344                 :"=r" (word)
345                 :"rm" (word));
346         return word;
347 }
348
349 #ifdef __KERNEL__
350
351 /**
352  * ffs - find first bit set
353  * @x: the word to search
354  *
355  * This is defined the same way as
356  * the libc and compiler builtin ffs routines, therefore
357  * differs in spirit from the above ffz (man ffs).
358  */
359 static __inline__ int ffs(int x)
360 {
361         int r;
362
363         __asm__("bsfl %1,%0\n\t"
364                 "cmovzl %2,%0" 
365                 : "=r" (r) : "rm" (x), "r" (-1));
366         return r+1;
367 }
368
369 /**
370  * fls64 - find last bit set in 64 bit word
371  * @x: the word to search
372  *
373  * This is defined the same way as fls.
374  */
375 static __inline__ int fls64(__u64 x)
376 {
377         if (x == 0)
378                 return 0;
379         return __fls(x) + 1;
380 }
381
382 /**
383  * fls - find last bit set
384  * @x: the word to search
385  *
386  * This is defined the same way as ffs.
387  */
388 static __inline__ int fls(int x)
389 {
390         int r;
391
392         __asm__("bsrl %1,%0\n\t"
393                 "cmovzl %2,%0"
394                 : "=&r" (r) : "rm" (x), "rm" (-1));
395         return r+1;
396 }
397
398 #include <arch-generic/bitops/hweight.h>
399
400 #endif /* __KERNEL__ */
401
402 #endif /* _X86_64_BITOPS_H */