bitops.c 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. #include "bitops.h"
  2. #include "config.h"
  3. #include <ccan/build_assert/build_assert.h>
  4. #include <ccan/short_types/short_types.h>
  5. #include <ccan/ilog/ilog.h>
  6. #include <limits.h>
  7. unsigned int fls(unsigned long val)
  8. {
  9. BUILD_ASSERT(sizeof(val) == sizeof(u32) || sizeof(val) == sizeof(u64));
  10. if (sizeof(val) == sizeof(u32))
  11. return ilog32(val);
  12. else
  13. return ilog64(val);
  14. }
  15. /* FIXME: Move to bitops. */
  16. unsigned int ffsl(unsigned long val)
  17. {
  18. #if HAVE_BUILTIN_FFSL
  19. /* This is significantly faster! */
  20. return __builtin_ffsl(val);
  21. #else
  22. unsigned int r = 1;
  23. if (!val)
  24. return 0;
  25. if (sizeof(long) == sizeof(u64)) {
  26. if (!(val & 0xffffffff)) {
  27. /* Workaround gcc warning on 32-bit:
  28. error: right shift count >= width of type */
  29. u64 tmp = val;
  30. tmp >>= 32;
  31. val = tmp;
  32. r += 32;
  33. }
  34. }
  35. if (!(val & 0xffff)) {
  36. val >>= 16;
  37. r += 16;
  38. }
  39. if (!(val & 0xff)) {
  40. val >>= 8;
  41. r += 8;
  42. }
  43. if (!(val & 0xf)) {
  44. val >>= 4;
  45. r += 4;
  46. }
  47. if (!(val & 3)) {
  48. val >>= 2;
  49. r += 2;
  50. }
  51. if (!(val & 1)) {
  52. val >>= 1;
  53. r += 1;
  54. }
  55. return r;
  56. #endif
  57. }
  58. unsigned int popcount(unsigned long val)
  59. {
  60. #if HAVE_BUILTIN_POPCOUNTL
  61. return __builtin_popcountl(val);
  62. #else
  63. if (sizeof(long) == sizeof(u64)) {
  64. u64 v = val;
  65. v = (v & 0x5555555555555555ULL)
  66. + ((v >> 1) & 0x5555555555555555ULL);
  67. v = (v & 0x3333333333333333ULL)
  68. + ((v >> 1) & 0x3333333333333333ULL);
  69. v = (v & 0x0F0F0F0F0F0F0F0FULL)
  70. + ((v >> 1) & 0x0F0F0F0F0F0F0F0FULL);
  71. v = (v & 0x00FF00FF00FF00FFULL)
  72. + ((v >> 1) & 0x00FF00FF00FF00FFULL);
  73. v = (v & 0x0000FFFF0000FFFFULL)
  74. + ((v >> 1) & 0x0000FFFF0000FFFFULL);
  75. v = (v & 0x00000000FFFFFFFFULL)
  76. + ((v >> 1) & 0x00000000FFFFFFFFULL);
  77. return v;
  78. }
  79. val = (val & 0x55555555ULL) + ((val >> 1) & 0x55555555ULL);
  80. val = (val & 0x33333333ULL) + ((val >> 1) & 0x33333333ULL);
  81. val = (val & 0x0F0F0F0FULL) + ((val >> 1) & 0x0F0F0F0FULL);
  82. val = (val & 0x00FF00FFULL) + ((val >> 1) & 0x00FF00FFULL);
  83. val = (val & 0x0000FFFFULL) + ((val >> 1) & 0x0000FFFFULL);
  84. return val;
  85. #endif
  86. }
  87. unsigned long align_up(unsigned long x, unsigned long align)
  88. {
  89. return (x + align - 1) & ~(align - 1);
  90. }