diff options
Diffstat (limited to 'arch/arm/include')
-rw-r--r-- | arch/arm/include/asm/bitops.h | 54 |
1 files changed, 44 insertions, 10 deletions
diff --git a/arch/arm/include/asm/bitops.h b/arch/arm/include/asm/bitops.h index e691ec91e4d3..b2e298a90d76 100644 --- a/arch/arm/include/asm/bitops.h +++ b/arch/arm/include/asm/bitops.h | |||
@@ -254,25 +254,59 @@ static inline int constant_fls(int x) | |||
254 | } | 254 | } |
255 | 255 | ||
256 | /* | 256 | /* |
257 | * On ARMv5 and above those functions can be implemented around | 257 | * On ARMv5 and above those functions can be implemented around the |
258 | * the clz instruction for much better code efficiency. | 258 | * clz instruction for much better code efficiency. __clz returns |
259 | * the number of leading zeros, zero input will return 32, and | ||
260 | * 0x80000000 will return 0. | ||
259 | */ | 261 | */ |
262 | static inline unsigned int __clz(unsigned int x) | ||
263 | { | ||
264 | unsigned int ret; | ||
265 | |||
266 | asm("clz\t%0, %1" : "=r" (ret) : "r" (x)); | ||
260 | 267 | ||
268 | return ret; | ||
269 | } | ||
270 | |||
271 | /* | ||
272 | * fls() returns zero if the input is zero, otherwise returns the bit | ||
273 | * position of the last set bit, where the LSB is 1 and MSB is 32. | ||
274 | */ | ||
261 | static inline int fls(int x) | 275 | static inline int fls(int x) |
262 | { | 276 | { |
263 | int ret; | ||
264 | |||
265 | if (__builtin_constant_p(x)) | 277 | if (__builtin_constant_p(x)) |
266 | return constant_fls(x); | 278 | return constant_fls(x); |
267 | 279 | ||
268 | asm("clz\t%0, %1" : "=r" (ret) : "r" (x)); | 280 | return 32 - __clz(x); |
269 | ret = 32 - ret; | 281 | } |
270 | return ret; | 282 | |
283 | /* | ||
284 | * __fls() returns the bit position of the last bit set, where the | ||
285 | * LSB is 0 and MSB is 31. Zero input is undefined. | ||
286 | */ | ||
287 | static inline unsigned long __fls(unsigned long x) | ||
288 | { | ||
289 | return fls(x) - 1; | ||
290 | } | ||
291 | |||
292 | /* | ||
293 | * ffs() returns zero if the input was zero, otherwise returns the bit | ||
294 | * position of the first set bit, where the LSB is 1 and MSB is 32. | ||
295 | */ | ||
296 | static inline int ffs(int x) | ||
297 | { | ||
298 | return fls(x & -x); | ||
299 | } | ||
300 | |||
301 | /* | ||
302 | * __ffs() returns the bit position of the first bit set, where the | ||
303 | * LSB is 0 and MSB is 31. Zero input is undefined. | ||
304 | */ | ||
305 | static inline unsigned long __ffs(unsigned long x) | ||
306 | { | ||
307 | return ffs(x) - 1; | ||
271 | } | 308 | } |
272 | 309 | ||
273 | #define __fls(x) (fls(x) - 1) | ||
274 | #define ffs(x) ({ unsigned long __t = (x); fls(__t & -__t); }) | ||
275 | #define __ffs(x) (ffs(x) - 1) | ||
276 | #define ffz(x) __ffs( ~(x) ) | 310 | #define ffz(x) __ffs( ~(x) ) |
277 | 311 | ||
278 | #endif | 312 | #endif |