blob: 48adbf56ca60c9f2d7da5954e3245188d6f8a2ea [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001#ifndef _X86_64_BITOPS_H
2#define _X86_64_BITOPS_H
3
4/*
5 * Copyright 1992, Linus Torvalds.
6 */
7
Randy Dunlapade8c562007-10-25 14:27:24 -07008extern long find_first_zero_bit(const unsigned long *addr, unsigned long size);
9extern long find_next_zero_bit(const unsigned long *addr, long size, long offset);
10extern long find_first_bit(const unsigned long *addr, unsigned long size);
11extern long find_next_bit(const unsigned long *addr, long size, long offset);
Linus Torvalds1da177e2005-04-16 15:20:36 -070012
13/* return index of first bet set in val or max when no bit is set */
Chuck Leverd2ccc3f2007-10-17 18:04:38 +020014static inline long __scanbit(unsigned long val, unsigned long max)
Linus Torvalds1da177e2005-04-16 15:20:36 -070015{
16 asm("bsfq %1,%0 ; cmovz %2,%0" : "=&r" (val) : "r" (val), "r" (max));
17 return val;
18}
19
20#define find_first_bit(addr,size) \
21((__builtin_constant_p(size) && (size) <= BITS_PER_LONG ? \
22 (__scanbit(*(unsigned long *)addr,(size))) : \
23 find_first_bit(addr,size)))
24
25#define find_next_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_bit(addr,size,off)))
29
30#define find_first_zero_bit(addr,size) \
31((__builtin_constant_p(size) && (size) <= BITS_PER_LONG ? \
32 (__scanbit(~*(unsigned long *)addr,(size))) : \
33 find_first_zero_bit(addr,size)))
34
35#define find_next_zero_bit(addr,size,off) \
36((__builtin_constant_p(size) && (size) <= BITS_PER_LONG ? \
37 ((off)+(__scanbit(~(((*(unsigned long *)addr)) >> (off)),(size)-(off)))) : \
38 find_next_zero_bit(addr,size,off)))
39
40/*
41 * Find string of zero bits in a bitmap. -1 when not found.
42 */
43extern unsigned long
44find_next_zero_string(unsigned long *bitmap, long start, long nbits, int len);
45
46static inline void set_bit_string(unsigned long *bitmap, unsigned long i,
47 int len)
48{
49 unsigned long end = i + len;
50 while (i < end) {
51 __set_bit(i, bitmap);
52 i++;
53 }
54}
55
56static inline void __clear_bit_string(unsigned long *bitmap, unsigned long i,
57 int len)
58{
59 unsigned long end = i + len;
60 while (i < end) {
61 __clear_bit(i, bitmap);
62 i++;
63 }
64}
65
66/**
67 * ffz - find first zero in word.
68 * @word: The word to search
69 *
70 * Undefined if no zero exists, so code should check against ~0UL first.
71 */
Randy Dunlapade8c562007-10-25 14:27:24 -070072static inline unsigned long ffz(unsigned long word)
Linus Torvalds1da177e2005-04-16 15:20:36 -070073{
74 __asm__("bsfq %1,%0"
75 :"=r" (word)
76 :"r" (~word));
77 return word;
78}
79
80/**
81 * __ffs - find first bit in word.
82 * @word: The word to search
83 *
84 * Undefined if no bit exists, so code should check against 0 first.
85 */
Randy Dunlapade8c562007-10-25 14:27:24 -070086static inline unsigned long __ffs(unsigned long word)
Linus Torvalds1da177e2005-04-16 15:20:36 -070087{
88 __asm__("bsfq %1,%0"
89 :"=r" (word)
90 :"rm" (word));
91 return word;
92}
93
Stephen Hemminger90933fc2005-12-21 19:31:36 -080094/*
95 * __fls: find last bit set.
96 * @word: The word to search
97 *
98 * Undefined if no zero exists, so code should check against ~0UL first.
99 */
Randy Dunlapade8c562007-10-25 14:27:24 -0700100static inline unsigned long __fls(unsigned long word)
Stephen Hemminger90933fc2005-12-21 19:31:36 -0800101{
102 __asm__("bsrq %1,%0"
103 :"=r" (word)
104 :"rm" (word));
105 return word;
106}
107
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108#ifdef __KERNEL__
109
Akinobu Mitaf33e2fb2006-03-26 01:39:42 -0800110#include <asm-generic/bitops/sched.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111
112/**
113 * ffs - find first bit set
114 * @x: the word to search
115 *
116 * This is defined the same way as
117 * the libc and compiler builtin ffs routines, therefore
118 * differs in spirit from the above ffz (man ffs).
119 */
Randy Dunlapade8c562007-10-25 14:27:24 -0700120static inline int ffs(int x)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700121{
122 int r;
123
124 __asm__("bsfl %1,%0\n\t"
125 "cmovzl %2,%0"
126 : "=r" (r) : "rm" (x), "r" (-1));
127 return r+1;
128}
129
130/**
Stephen Hemminger90933fc2005-12-21 19:31:36 -0800131 * fls64 - find last bit set in 64 bit word
132 * @x: the word to search
133 *
134 * This is defined the same way as fls.
135 */
Randy Dunlapade8c562007-10-25 14:27:24 -0700136static inline int fls64(__u64 x)
Stephen Hemminger90933fc2005-12-21 19:31:36 -0800137{
138 if (x == 0)
139 return 0;
140 return __fls(x) + 1;
141}
142
143/**
Stephen Hemminger636dd2b2006-01-11 22:43:24 +0100144 * fls - find last bit set
145 * @x: the word to search
146 *
147 * This is defined the same way as ffs.
148 */
Randy Dunlapade8c562007-10-25 14:27:24 -0700149static inline int fls(int x)
Stephen Hemminger636dd2b2006-01-11 22:43:24 +0100150{
151 int r;
152
153 __asm__("bsrl %1,%0\n\t"
154 "cmovzl %2,%0"
155 : "=&r" (r) : "rm" (x), "rm" (-1));
156 return r+1;
157}
158
Andi Kleen01366112006-09-26 10:52:38 +0200159#define ARCH_HAS_FAST_MULTIPLIER 1
160
Akinobu Mitaf33e2fb2006-03-26 01:39:42 -0800161#include <asm-generic/bitops/hweight.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700162
163#endif /* __KERNEL__ */
164
165#ifdef __KERNEL__
166
Akinobu Mitaf33e2fb2006-03-26 01:39:42 -0800167#include <asm-generic/bitops/ext2-non-atomic.h>
168
Linus Torvalds1da177e2005-04-16 15:20:36 -0700169#define ext2_set_bit_atomic(lock,nr,addr) \
170 test_and_set_bit((nr),(unsigned long*)addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700171#define ext2_clear_bit_atomic(lock,nr,addr) \
172 test_and_clear_bit((nr),(unsigned long*)addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700173
Akinobu Mitaf33e2fb2006-03-26 01:39:42 -0800174#include <asm-generic/bitops/minix.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700175
Linus Torvalds1da177e2005-04-16 15:20:36 -0700176#endif /* __KERNEL__ */
177
178#endif /* _X86_64_BITOPS_H */