2014-12-16 01:50:12 +03:00
/* find_next_bit.c: fallback find next bit implementation
*
2016-01-08 16:46:52 +03:00
* Copied from lib / find_next_bit . c to tools / lib / find_bit . c
2014-12-16 01:50:12 +03:00
*
* Copyright ( C ) 2004 Red Hat , Inc . All Rights Reserved .
* Written by David Howells ( dhowells @ redhat . com )
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; either version
* 2 of the License , or ( at your option ) any later version .
*/
# include <linux/bitops.h>
# include <asm/types.h>
# include <asm/byteorder.h>
# define BITOP_WORD(nr) ((nr) / BITS_PER_LONG)
# ifndef find_next_bit
/*
* Find the next set bit in a memory region .
*/
unsigned long find_next_bit ( const unsigned long * addr , unsigned long size ,
unsigned long offset )
{
const unsigned long * p = addr + BITOP_WORD ( offset ) ;
unsigned long result = offset & ~ ( BITS_PER_LONG - 1 ) ;
unsigned long tmp ;
if ( offset > = size )
return size ;
size - = result ;
offset % = BITS_PER_LONG ;
if ( offset ) {
tmp = * ( p + + ) ;
tmp & = ( ~ 0UL < < offset ) ;
if ( size < BITS_PER_LONG )
goto found_first ;
if ( tmp )
goto found_middle ;
size - = BITS_PER_LONG ;
result + = BITS_PER_LONG ;
}
while ( size & ~ ( BITS_PER_LONG - 1 ) ) {
if ( ( tmp = * ( p + + ) ) )
goto found_middle ;
result + = BITS_PER_LONG ;
size - = BITS_PER_LONG ;
}
if ( ! size )
return result ;
tmp = * p ;
found_first :
tmp & = ( ~ 0UL > > ( BITS_PER_LONG - size ) ) ;
if ( tmp = = 0UL ) /* Are any bits set? */
return result + size ; /* Nope. */
found_middle :
return result + __ffs ( tmp ) ;
}
# endif
# ifndef find_first_bit
/*
* Find the first set bit in a memory region .
*/
unsigned long find_first_bit ( const unsigned long * addr , unsigned long size )
{
const unsigned long * p = addr ;
unsigned long result = 0 ;
unsigned long tmp ;
while ( size & ~ ( BITS_PER_LONG - 1 ) ) {
if ( ( tmp = * ( p + + ) ) )
goto found ;
result + = BITS_PER_LONG ;
size - = BITS_PER_LONG ;
}
if ( ! size )
return result ;
tmp = ( * p ) & ( ~ 0UL > > ( BITS_PER_LONG - size ) ) ;
if ( tmp = = 0UL ) /* Are any bits set? */
return result + size ; /* Nope. */
found :
return result + __ffs ( tmp ) ;
}
# endif