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.8KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. #ifndef _BITS_STRINGS_H
  2. #define _BITS_STRINGS_H
  3. /** @file
  4. *
  5. * String functions
  6. *
  7. */
  8. FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  9. /**
  10. * Find first (i.e. least significant) set bit
  11. *
  12. * @v value Value
  13. * @ret lsb Least significant bit set in value (LSB=1), or zero
  14. */
  15. static inline __attribute__ (( always_inline )) int __ffsl ( long value ) {
  16. unsigned long bits = value;
  17. unsigned long lsb;
  18. unsigned int lz;
  19. /* Extract least significant set bit */
  20. lsb = ( bits & -bits );
  21. /* Count number of leading zeroes before LSB */
  22. __asm__ ( "clz %0, %1" : "=r" ( lz ) : "r" ( lsb ) );
  23. return ( 32 - lz );
  24. }
  25. /**
  26. * Find first (i.e. least significant) set bit
  27. *
  28. * @v value Value
  29. * @ret lsb Least significant bit set in value (LSB=1), or zero
  30. */
  31. static inline __attribute__ (( always_inline )) int __ffsll ( long long value ){
  32. unsigned long high = ( value >> 32 );
  33. unsigned long low = ( value >> 0 );
  34. if ( low ) {
  35. return ( __ffsl ( low ) );
  36. } else if ( high ) {
  37. return ( 32 + __ffsl ( high ) );
  38. } else {
  39. return 0;
  40. }
  41. }
  42. /**
  43. * Find last (i.e. most significant) set bit
  44. *
  45. * @v value Value
  46. * @ret msb Most significant bit set in value (LSB=1), or zero
  47. */
  48. static inline __attribute__ (( always_inline )) int __flsl ( long value ) {
  49. unsigned int lz;
  50. /* Count number of leading zeroes */
  51. __asm__ ( "clz %0, %1" : "=r" ( lz ) : "r" ( value ) );
  52. return ( 32 - lz );
  53. }
  54. /**
  55. * Find last (i.e. most significant) set bit
  56. *
  57. * @v value Value
  58. * @ret msb Most significant bit set in value (LSB=1), or zero
  59. */
  60. static inline __attribute__ (( always_inline )) int __flsll ( long long value ){
  61. unsigned long high = ( value >> 32 );
  62. unsigned long low = ( value >> 0 );
  63. if ( high ) {
  64. return ( 32 + __flsl ( high ) );
  65. } else if ( low ) {
  66. return ( __flsl ( low ) );
  67. } else {
  68. return 0;
  69. }
  70. }
  71. #endif /* _BITS_STRINGS_H */