You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

strings.h 1.2KB

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