count-one-bits.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /* count-one-bits.h -- counts the number of 1-bits in a word.
  2. Copyright (C) 2007-2015 Free Software Foundation, Inc.
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 3 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  13. /* Written by Ben Pfaff. */
  14. #ifndef COUNT_ONE_BITS_H
  15. #define COUNT_ONE_BITS_H 1
  16. #include <limits.h>
  17. #include <stdlib.h>
  18. #ifndef _GL_INLINE_HEADER_BEGIN
  19. #error "Please include config.h first."
  20. #endif
  21. _GL_INLINE_HEADER_BEGIN
  22. #ifndef COUNT_ONE_BITS_INLINE
  23. # define COUNT_ONE_BITS_INLINE _GL_INLINE
  24. #endif
  25. /* Expand to code that computes the number of 1-bits of the local
  26. variable 'x' of type TYPE (an unsigned integer type) and return it
  27. from the current function. */
  28. #define COUNT_ONE_BITS_GENERIC(TYPE) \
  29. do \
  30. { \
  31. int count = 0; \
  32. int bits; \
  33. for (bits = 0; bits < sizeof (TYPE) * CHAR_BIT; bits += 32) \
  34. { \
  35. count += count_one_bits_32 (x); \
  36. x = x >> 31 >> 1; \
  37. } \
  38. return count; \
  39. } \
  40. while (0)
  41. /* Assuming the GCC builtin is BUILTIN and the MSC builtin is MSC_BUILTIN,
  42. expand to code that computes the number of 1-bits of the local
  43. variable 'x' of type TYPE (an unsigned integer type) and return it
  44. from the current function. */
  45. #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
  46. # define COUNT_ONE_BITS(BUILTIN, MSC_BUILTIN, TYPE) return BUILTIN (x)
  47. #else
  48. /* Compute and return the number of 1-bits set in the least
  49. significant 32 bits of X. */
  50. COUNT_ONE_BITS_INLINE int
  51. count_one_bits_32 (unsigned int x)
  52. {
  53. x = ((x & 0xaaaaaaaaU) >> 1) + (x & 0x55555555U);
  54. x = ((x & 0xccccccccU) >> 2) + (x & 0x33333333U);
  55. x = (x >> 16) + (x & 0xffff);
  56. x = ((x & 0xf0f0) >> 4) + (x & 0x0f0f);
  57. return (x >> 8) + (x & 0x00ff);
  58. }
  59. # if 1500 <= _MSC_VER && (defined _M_IX86 || defined _M_X64)
  60. /* While gcc falls back to its own generic code if the machine
  61. on which it's running doesn't support popcount, with Microsoft's
  62. compiler we need to detect and fallback ourselves. */
  63. # pragma intrinsic __cpuid
  64. # pragma intrinsic __popcnt
  65. # pragma intrinsic __popcnt64
  66. /* Return nonzero if popcount is supported. */
  67. /* 1 if supported, 0 if not supported, -1 if unknown. */
  68. extern int popcount_support;
  69. COUNT_ONE_BITS_INLINE int
  70. popcount_supported (void)
  71. {
  72. if (popcount_support < 0)
  73. {
  74. int cpu_info[4];
  75. __cpuid (cpu_info, 1);
  76. popcount_support = (cpu_info[2] >> 23) & 1; /* See MSDN. */
  77. }
  78. return popcount_support;
  79. }
  80. # define COUNT_ONE_BITS(BUILTIN, MSC_BUILTIN, TYPE) \
  81. do \
  82. { \
  83. if (popcount_supported ()) \
  84. return MSC_BUILTIN (x); \
  85. else \
  86. COUNT_ONE_BITS_GENERIC (TYPE); \
  87. } \
  88. while (0)
  89. # else
  90. # define COUNT_ONE_BITS(BUILTIN, MSC_BUILTIN, TYPE) \
  91. COUNT_ONE_BITS_GENERIC (TYPE)
  92. # endif
  93. #endif
  94. /* Compute and return the number of 1-bits set in X. */
  95. COUNT_ONE_BITS_INLINE int
  96. count_one_bits (unsigned int x)
  97. {
  98. COUNT_ONE_BITS (__builtin_popcount, __popcnt, unsigned int);
  99. }
  100. /* Compute and return the number of 1-bits set in X. */
  101. COUNT_ONE_BITS_INLINE int
  102. count_one_bits_l (unsigned long int x)
  103. {
  104. COUNT_ONE_BITS (__builtin_popcountl, __popcnt, unsigned long int);
  105. }
  106. #if HAVE_UNSIGNED_LONG_LONG_INT
  107. /* Compute and return the number of 1-bits set in X. */
  108. COUNT_ONE_BITS_INLINE int
  109. count_one_bits_ll (unsigned long long int x)
  110. {
  111. COUNT_ONE_BITS (__builtin_popcountll, __popcnt64, unsigned long long int);
  112. }
  113. #endif
  114. _GL_INLINE_HEADER_END
  115. #endif /* COUNT_ONE_BITS_H */