mirror of
https://github.com/ipxe/ipxe
synced 2025-12-30 04:28:12 +03:00
50
src/arch/i386/include/bits/strings.h
Normal file
50
src/arch/i386/include/bits/strings.h
Normal file
@@ -0,0 +1,50 @@
|
||||
#ifndef _BITS_STRINGS_H
|
||||
#define _BITS_STRINGS_H
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER );
|
||||
|
||||
/**
|
||||
* Find last (i.e. most significant) set bit
|
||||
*
|
||||
* @v value Value
|
||||
* @ret msb Most significant bit set in value (LSB=1), or zero
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) int __flsl ( long value ) {
|
||||
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.
|
||||
* 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__ ( "bsrl %1, %0"
|
||||
: "=r" ( msb_minus_one )
|
||||
: "rm" ( value ) );
|
||||
return ( msb_minus_one + 1 );
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find last (i.e. most significant) set bit
|
||||
*
|
||||
* @v value Value
|
||||
* @ret msb Most significant bit set in value (LSB=1), or zero
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) int __flsll ( long long value ){
|
||||
unsigned long high = ( value >> 32 );
|
||||
unsigned long low = ( value >> 0 );
|
||||
|
||||
if ( high ) {
|
||||
return ( 32 + __flsl ( high ) );
|
||||
} else if ( low ) {
|
||||
return ( __flsl ( low ) );
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* _BITS_STRINGS_H */
|
||||
@@ -9,8 +9,8 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
||||
* @v value Value
|
||||
* @ret msb Most significant bit set in value (LSB=1), or zero
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) int __flsl ( long value ) {
|
||||
long msb_minus_one;
|
||||
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.
|
||||
@@ -19,7 +19,7 @@ static inline __attribute__ (( always_inline )) int __flsl ( long value ) {
|
||||
* the input is non-zero.
|
||||
*/
|
||||
if ( value ) {
|
||||
__asm__ ( "bsr %1, %0"
|
||||
__asm__ ( "bsrq %1, %0"
|
||||
: "=r" ( msb_minus_one )
|
||||
: "rm" ( value ) );
|
||||
return ( msb_minus_one + 1 );
|
||||
@@ -28,4 +28,15 @@ static inline __attribute__ (( always_inline )) int __flsl ( long value ) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find last (i.e. most significant) set bit
|
||||
*
|
||||
* @v value Value
|
||||
* @ret msb Most significant bit set in value (LSB=1), or zero
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) int __flsl ( long value ) {
|
||||
|
||||
return __flsll ( value );
|
||||
}
|
||||
|
||||
#endif /* _BITS_STRINGS_H */
|
||||
Reference in New Issue
Block a user