iPXE
strings.h
Go to the documentation of this file.
00001 #ifndef _BITS_STRINGS_H
00002 #define _BITS_STRINGS_H
00003 
00004 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
00005 
00006 /**
00007  * Find first (i.e. least significant) set bit
00008  *
00009  * @v value             Value
00010  * @ret lsb             Least significant bit set in value (LSB=1), or zero
00011  */
00012 static inline __attribute__ (( always_inline )) int __ffsl ( long value ) {
00013         long lsb_minus_one;
00014 
00015         /* If the input value is zero, the BSF instruction returns
00016          * ZF=0 and leaves an undefined value in the output register.
00017          * Perform this check in C rather than asm so that it can be
00018          * omitted in cases where the compiler is able to prove that
00019          * the input is non-zero.
00020          */
00021         if ( value ) {
00022                 __asm__ ( "bsfl %1, %0"
00023                           : "=r" ( lsb_minus_one )
00024                           : "rm" ( value ) );
00025                 return ( lsb_minus_one + 1 );
00026         } else {
00027                 return 0;
00028         }
00029 }
00030 
00031 /**
00032  * Find first (i.e. least significant) set bit
00033  *
00034  * @v value             Value
00035  * @ret lsb             Least significant bit set in value (LSB=1), or zero
00036  */
00037 static inline __attribute__ (( always_inline )) int __ffsll ( long long value ){
00038         unsigned long high = ( value >> 32 );
00039         unsigned long low = ( value >> 0 );
00040 
00041         if ( low ) {
00042                 return ( __ffsl ( low ) );
00043         } else if ( high ) {
00044                 return ( 32 + __ffsl ( high ) );
00045         } else {
00046                 return 0;
00047         }
00048 }
00049 
00050 /**
00051  * Find last (i.e. most significant) set bit
00052  *
00053  * @v value             Value
00054  * @ret msb             Most significant bit set in value (LSB=1), or zero
00055  */
00056 static inline __attribute__ (( always_inline )) int __flsl ( long value ) {
00057         long msb_minus_one;
00058 
00059         /* If the input value is zero, the BSR instruction returns
00060          * ZF=0 and leaves an undefined value in the output register.
00061          * Perform this check in C rather than asm so that it can be
00062          * omitted in cases where the compiler is able to prove that
00063          * the input is non-zero.
00064          */
00065         if ( value ) {
00066                 __asm__ ( "bsrl %1, %0"
00067                           : "=r" ( msb_minus_one )
00068                           : "rm" ( value ) );
00069                 return ( msb_minus_one + 1 );
00070         } else {
00071                 return 0;
00072         }
00073 }
00074 
00075 /**
00076  * Find last (i.e. most significant) set bit
00077  *
00078  * @v value             Value
00079  * @ret msb             Most significant bit set in value (LSB=1), or zero
00080  */
00081 static inline __attribute__ (( always_inline )) int __flsll ( long long value ){
00082         unsigned long high = ( value >> 32 );
00083         unsigned long low = ( value >> 0 );
00084 
00085         if ( high ) {
00086                 return ( 32 + __flsl ( high ) );
00087         } else if ( low ) {
00088                 return ( __flsl ( low ) );
00089         } else {
00090                 return 0;
00091         }
00092 }
00093 
00094 #endif /* _BITS_STRINGS_H */