mirror of
https://github.com/ipxe/ipxe
synced 2026-02-04 06:59:59 +03:00
[libc] Add ffs(), ffsl(), and ffsll()
Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
@@ -3,6 +3,42 @@
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
/**
|
||||
* Find first (i.e. least significant) set bit
|
||||
*
|
||||
* @v value Value
|
||||
* @ret lsb Least significant bit set in value (LSB=1), or zero
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) int __ffsll ( long long value ){
|
||||
long long lsb_minus_one;
|
||||
|
||||
/* If the input value is zero, the BSF instruction returns
|
||||
* ZF=0 and leaves an undefined value in the output register.
|
||||
* Perform this check in C rather than asm so that it can be
|
||||
* omitted in cases where the compiler is able to prove that
|
||||
* the input is non-zero.
|
||||
*/
|
||||
if ( value ) {
|
||||
__asm__ ( "bsfq %1, %0"
|
||||
: "=r" ( lsb_minus_one )
|
||||
: "rm" ( value ) );
|
||||
return ( lsb_minus_one + 1 );
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find first (i.e. least significant) set bit
|
||||
*
|
||||
* @v value Value
|
||||
* @ret lsb Least significant bit set in value (LSB=1), or zero
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) int __ffsl ( long value ) {
|
||||
|
||||
return __ffsll ( value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Find last (i.e. most significant) set bit
|
||||
*
|
||||
@@ -13,7 +49,7 @@ static inline __attribute__ (( always_inline )) int __flsll ( long long value ){
|
||||
long long msb_minus_one;
|
||||
|
||||
/* If the input value is zero, the BSR instruction returns
|
||||
* ZF=1 and leaves an undefined value in the output register.
|
||||
* ZF=0 and leaves an undefined value in the output register.
|
||||
* Perform this check in C rather than asm so that it can be
|
||||
* omitted in cases where the compiler is able to prove that
|
||||
* the input is non-zero.
|
||||
|
||||
Reference in New Issue
Block a user