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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  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 __ffsll ( long long value ){
  11. long 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__ ( "bsfq %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 __ffsl ( long value ) {
  34. return __ffsll ( value );
  35. }
  36. /**
  37. * Find last (i.e. most significant) set bit
  38. *
  39. * @v value Value
  40. * @ret msb Most significant bit set in value (LSB=1), or zero
  41. */
  42. static inline __attribute__ (( always_inline )) int __flsll ( long long value ){
  43. long long msb_minus_one;
  44. /* If the input value is zero, the BSR instruction returns
  45. * ZF=0 and leaves an undefined value in the output register.
  46. * Perform this check in C rather than asm so that it can be
  47. * omitted in cases where the compiler is able to prove that
  48. * the input is non-zero.
  49. */
  50. if ( value ) {
  51. __asm__ ( "bsrq %1, %0"
  52. : "=r" ( msb_minus_one )
  53. : "rm" ( value ) );
  54. return ( msb_minus_one + 1 );
  55. } else {
  56. return 0;
  57. }
  58. }
  59. /**
  60. * Find last (i.e. most significant) set bit
  61. *
  62. * @v value Value
  63. * @ret msb Most significant bit set in value (LSB=1), or zero
  64. */
  65. static inline __attribute__ (( always_inline )) int __flsl ( long value ) {
  66. return __flsll ( value );
  67. }
  68. #endif /* _BITS_STRINGS_H */