bitops.c 2.3 KB

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