aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorSteven Rostedt <rostedt@goodmis.org>2005-07-28 08:45:06 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-07-28 11:40:31 -0400
commitcd85c8b4457a52d3545fdb9532082b2c1ebd5f21 (patch)
tree58b294ef3cd90f08fa77555352de63934a881405 /include
parent79a8810221ee9ea96c4e5a5817afb88f22ea698c (diff)
[PATCH] speed up on find_first_bit for i386 (let compiler do the work)
Avoid using "rep scas", just let the compiler select a sequence of regular instructions. Signed-off-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include')
-rw-r--r--include/asm-i386/bitops.h54
1 files changed, 24 insertions, 30 deletions
diff --git a/include/asm-i386/bitops.h b/include/asm-i386/bitops.h
index 9db0b712d57a..1caee1039363 100644
--- a/include/asm-i386/bitops.h
+++ b/include/asm-i386/bitops.h
@@ -311,6 +311,20 @@ static inline int find_first_zero_bit(const unsigned long *addr, unsigned size)
311int find_next_zero_bit(const unsigned long *addr, int size, int offset); 311int find_next_zero_bit(const unsigned long *addr, int size, int offset);
312 312
313/** 313/**
314 * __ffs - find first bit in word.
315 * @word: The word to search
316 *
317 * Undefined if no bit exists, so code should check against 0 first.
318 */
319static inline unsigned long __ffs(unsigned long word)
320{
321 __asm__("bsfl %1,%0"
322 :"=r" (word)
323 :"rm" (word));
324 return word;
325}
326
327/**
314 * find_first_bit - find the first set bit in a memory region 328 * find_first_bit - find the first set bit in a memory region
315 * @addr: The address to start the search at 329 * @addr: The address to start the search at
316 * @size: The maximum size to search 330 * @size: The maximum size to search
@@ -320,22 +334,16 @@ int find_next_zero_bit(const unsigned long *addr, int size, int offset);
320 */ 334 */
321static inline int find_first_bit(const unsigned long *addr, unsigned size) 335static inline int find_first_bit(const unsigned long *addr, unsigned size)
322{ 336{
323 int d0, d1; 337 int x = 0;
324 int res; 338 do {
325 339 if (*addr)
326 /* This looks at memory. Mark it volatile to tell gcc not to move it around */ 340 return __ffs(*addr) + x;
327 __asm__ __volatile__( 341 addr++;
328 "xorl %%eax,%%eax\n\t" 342 if (x >= size)
329 "repe; scasl\n\t" 343 break;
330 "jz 1f\n\t" 344 x += (sizeof(*addr)<<3);
331 "leal -4(%%edi),%%edi\n\t" 345 } while (1);
332 "bsfl (%%edi),%%eax\n" 346 return x;
333 "1:\tsubl %%ebx,%%edi\n\t"
334 "shll $3,%%edi\n\t"
335 "addl %%edi,%%eax"
336 :"=a" (res), "=&c" (d0), "=&D" (d1)
337 :"1" ((size + 31) >> 5), "2" (addr), "b" (addr) : "memory");
338 return res;
339} 347}
340 348
341/** 349/**
@@ -360,20 +368,6 @@ static inline unsigned long ffz(unsigned long word)
360 return word; 368 return word;
361} 369}
362 370
363/**
364 * __ffs - find first bit in word.
365 * @word: The word to search
366 *
367 * Undefined if no bit exists, so code should check against 0 first.
368 */
369static inline unsigned long __ffs(unsigned long word)
370{
371 __asm__("bsfl %1,%0"
372 :"=r" (word)
373 :"rm" (word));
374 return word;
375}
376
377/* 371/*
378 * fls: find last bit set. 372 * fls: find last bit set.
379 */ 373 */