|  | @@ -0,0 +1,31 @@
 | 
		
	
		
			
			|  | 1 | +#ifndef _BITS_STRINGS_H
 | 
		
	
		
			
			|  | 2 | +#define _BITS_STRINGS_H
 | 
		
	
		
			
			|  | 3 | +
 | 
		
	
		
			
			|  | 4 | +FILE_LICENCE ( GPL2_OR_LATER );
 | 
		
	
		
			
			|  | 5 | +
 | 
		
	
		
			
			|  | 6 | +/**
 | 
		
	
		
			
			|  | 7 | + * Find last (i.e. most significant) set bit
 | 
		
	
		
			
			|  | 8 | + *
 | 
		
	
		
			
			|  | 9 | + * @v value		Value
 | 
		
	
		
			
			|  | 10 | + * @ret msb		Most significant bit set in value (LSB=1), or zero
 | 
		
	
		
			
			|  | 11 | + */
 | 
		
	
		
			
			|  | 12 | +static inline __attribute__ (( always_inline )) int __flsl ( long value ) {
 | 
		
	
		
			
			|  | 13 | +	long msb_minus_one;
 | 
		
	
		
			
			|  | 14 | +
 | 
		
	
		
			
			|  | 15 | +	/* If the input value is zero, the BSR instruction returns
 | 
		
	
		
			
			|  | 16 | +	 * ZF=1 and leaves an undefined value in the output register.
 | 
		
	
		
			
			|  | 17 | +	 * Perform this check in C rather than asm so that it can be
 | 
		
	
		
			
			|  | 18 | +	 * omitted in cases where the compiler is able to prove that
 | 
		
	
		
			
			|  | 19 | +	 * the input is non-zero.
 | 
		
	
		
			
			|  | 20 | +	 */
 | 
		
	
		
			
			|  | 21 | +	if ( value ) {
 | 
		
	
		
			
			|  | 22 | +		__asm__ ( "bsr %1, %0"
 | 
		
	
		
			
			|  | 23 | +			  : "=r" ( msb_minus_one )
 | 
		
	
		
			
			|  | 24 | +			  : "rm" ( value ) );
 | 
		
	
		
			
			|  | 25 | +		return ( msb_minus_one + 1 );
 | 
		
	
		
			
			|  | 26 | +	} else {
 | 
		
	
		
			
			|  | 27 | +		return 0;
 | 
		
	
		
			
			|  | 28 | +	}
 | 
		
	
		
			
			|  | 29 | +}
 | 
		
	
		
			
			|  | 30 | +
 | 
		
	
		
			
			|  | 31 | +#endif /* _BITS_STRINGS_H */
 |