bitops.c 2.1 KB

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