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 2.3KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. #ifndef _BITS_STRINGS_H
  2. #define _BITS_STRINGS_H
  3. FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  4. /**
  5. * Find first (i.e. least significant) set bit
  6. *
  7. * @v value Value
  8. * @ret lsb Least significant bit set in value (LSB=1), or zero
  9. */
  10. static inline __attribute__ (( always_inline )) int __ffsl ( long value ) {
  11. long lsb_minus_one;
  12. /* If the input value is zero, the BSF instruction returns
  13. * ZF=0 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__ ( "bsfl %1, %0"
  20. : "=r" ( lsb_minus_one )
  21. : "rm" ( value ) );
  22. return ( lsb_minus_one + 1 );
  23. } else {
  24. return 0;
  25. }
  26. }
  27. /**
  28. * Find first (i.e. least significant) set bit
  29. *
  30. * @v value Value
  31. * @ret lsb Least significant bit set in value (LSB=1), or zero
  32. */
  33. static inline __attribute__ (( always_inline )) int __ffsll ( long long value ){
  34. unsigned long high = ( value >> 32 );
  35. unsigned long low = ( value >> 0 );
  36. if ( low ) {
  37. return ( __ffsl ( low ) );
  38. } else if ( high ) {
  39. return ( 32 + __ffsl ( high ) );
  40. } else {
  41. return 0;
  42. }
  43. }
  44. /**
  45. * Find last (i.e. most significant) set bit
  46. *
  47. * @v value Value
  48. * @ret msb Most significant bit set in value (LSB=1), or zero
  49. */
  50. static inline __attribute__ (( always_inline )) int __flsl ( long value ) {
  51. long msb_minus_one;
  52. /* If the input value is zero, the BSR instruction returns
  53. * ZF=0 and leaves an undefined value in the output register.
  54. * Perform this check in C rather than asm so that it can be
  55. * omitted in cases where the compiler is able to prove that
  56. * the input is non-zero.
  57. */
  58. if ( value ) {
  59. __asm__ ( "bsrl %1, %0"
  60. : "=r" ( msb_minus_one )
  61. : "rm" ( value ) );
  62. return ( msb_minus_one + 1 );
  63. } else {
  64. return 0;
  65. }
  66. }
  67. /**
  68. * Find last (i.e. most significant) set bit
  69. *
  70. * @v value Value
  71. * @ret msb Most significant bit set in value (LSB=1), or zero
  72. */
  73. static inline __attribute__ (( always_inline )) int __flsll ( long long value ){
  74. unsigned long high = ( value >> 32 );
  75. unsigned long low = ( value >> 0 );
  76. if ( high ) {
  77. return ( 32 + __flsl ( high ) );
  78. } else if ( low ) {
  79. return ( __flsl ( low ) );
  80. } else {
  81. return 0;
  82. }
  83. }
  84. #endif /* _BITS_STRINGS_H */