pg_bitutils.h 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. /*-------------------------------------------------------------------------
  2. *
  3. * pg_bitutils.h
  4. * Miscellaneous functions for bit-wise operations.
  5. *
  6. *
  7. * Copyright (c) 2019-2022, PostgreSQL Global Development Group
  8. *
  9. * src/include/port/pg_bitutils.h
  10. *
  11. *-------------------------------------------------------------------------
  12. */
  13. #ifndef PG_BITUTILS_H
  14. #define PG_BITUTILS_H
  15. extern PGDLLIMPORT const uint8 pg_leftmost_one_pos[256];
  16. extern PGDLLIMPORT const uint8 pg_rightmost_one_pos[256];
  17. extern PGDLLIMPORT const uint8 pg_number_of_ones[256];
  18. /*
  19. * pg_leftmost_one_pos32
  20. * Returns the position of the most significant set bit in "word",
  21. * measured from the least significant bit. word must not be 0.
  22. */
  23. static inline int
  24. pg_leftmost_one_pos32(uint32 word)
  25. {
  26. #ifdef HAVE__BUILTIN_CLZ
  27. Assert(word != 0);
  28. return 31 - __builtin_clz(word);
  29. #else
  30. int shift = 32 - 8;
  31. Assert(word != 0);
  32. while ((word >> shift) == 0)
  33. shift -= 8;
  34. return shift + pg_leftmost_one_pos[(word >> shift) & 255];
  35. #endif /* HAVE__BUILTIN_CLZ */
  36. }
  37. /*
  38. * pg_leftmost_one_pos64
  39. * As above, but for a 64-bit word.
  40. */
  41. static inline int
  42. pg_leftmost_one_pos64(uint64 word)
  43. {
  44. #ifdef HAVE__BUILTIN_CLZ
  45. Assert(word != 0);
  46. #if defined(HAVE_LONG_INT_64)
  47. return 63 - __builtin_clzl(word);
  48. #elif defined(HAVE_LONG_LONG_INT_64)
  49. return 63 - __builtin_clzll(word);
  50. #else
  51. #error must have a working 64-bit integer datatype
  52. #endif
  53. #else /* !HAVE__BUILTIN_CLZ */
  54. int shift = 64 - 8;
  55. Assert(word != 0);
  56. while ((word >> shift) == 0)
  57. shift -= 8;
  58. return shift + pg_leftmost_one_pos[(word >> shift) & 255];
  59. #endif /* HAVE__BUILTIN_CLZ */
  60. }
  61. /*
  62. * pg_rightmost_one_pos32
  63. * Returns the position of the least significant set bit in "word",
  64. * measured from the least significant bit. word must not be 0.
  65. */
  66. static inline int
  67. pg_rightmost_one_pos32(uint32 word)
  68. {
  69. #ifdef HAVE__BUILTIN_CTZ
  70. Assert(word != 0);
  71. return __builtin_ctz(word);
  72. #else
  73. int result = 0;
  74. Assert(word != 0);
  75. while ((word & 255) == 0)
  76. {
  77. word >>= 8;
  78. result += 8;
  79. }
  80. result += pg_rightmost_one_pos[word & 255];
  81. return result;
  82. #endif /* HAVE__BUILTIN_CTZ */
  83. }
  84. /*
  85. * pg_rightmost_one_pos64
  86. * As above, but for a 64-bit word.
  87. */
  88. static inline int
  89. pg_rightmost_one_pos64(uint64 word)
  90. {
  91. #ifdef HAVE__BUILTIN_CTZ
  92. Assert(word != 0);
  93. #if defined(HAVE_LONG_INT_64)
  94. return __builtin_ctzl(word);
  95. #elif defined(HAVE_LONG_LONG_INT_64)
  96. return __builtin_ctzll(word);
  97. #else
  98. #error must have a working 64-bit integer datatype
  99. #endif
  100. #else /* !HAVE__BUILTIN_CTZ */
  101. int result = 0;
  102. Assert(word != 0);
  103. while ((word & 255) == 0)
  104. {
  105. word >>= 8;
  106. result += 8;
  107. }
  108. result += pg_rightmost_one_pos[word & 255];
  109. return result;
  110. #endif /* HAVE__BUILTIN_CTZ */
  111. }
  112. /*
  113. * pg_nextpower2_32
  114. * Returns the next higher power of 2 above 'num', or 'num' if it's
  115. * already a power of 2.
  116. *
  117. * 'num' mustn't be 0 or be above PG_UINT32_MAX / 2 + 1.
  118. */
  119. static inline uint32
  120. pg_nextpower2_32(uint32 num)
  121. {
  122. Assert(num > 0 && num <= PG_UINT32_MAX / 2 + 1);
  123. /*
  124. * A power 2 number has only 1 bit set. Subtracting 1 from such a number
  125. * will turn on all previous bits resulting in no common bits being set
  126. * between num and num-1.
  127. */
  128. if ((num & (num - 1)) == 0)
  129. return num; /* already power 2 */
  130. return ((uint32) 1) << (pg_leftmost_one_pos32(num) + 1);
  131. }
  132. /*
  133. * pg_nextpower2_64
  134. * Returns the next higher power of 2 above 'num', or 'num' if it's
  135. * already a power of 2.
  136. *
  137. * 'num' mustn't be 0 or be above PG_UINT64_MAX / 2 + 1.
  138. */
  139. static inline uint64
  140. pg_nextpower2_64(uint64 num)
  141. {
  142. Assert(num > 0 && num <= PG_UINT64_MAX / 2 + 1);
  143. /*
  144. * A power 2 number has only 1 bit set. Subtracting 1 from such a number
  145. * will turn on all previous bits resulting in no common bits being set
  146. * between num and num-1.
  147. */
  148. if ((num & (num - 1)) == 0)
  149. return num; /* already power 2 */
  150. return ((uint64) 1) << (pg_leftmost_one_pos64(num) + 1);
  151. }
  152. /*
  153. * pg_nextpower2_size_t
  154. * Returns the next higher power of 2 above 'num', for a size_t input.
  155. */
  156. #if SIZEOF_SIZE_T == 4
  157. #define pg_nextpower2_size_t(num) pg_nextpower2_32(num)
  158. #else
  159. #define pg_nextpower2_size_t(num) pg_nextpower2_64(num)
  160. #endif
  161. /*
  162. * pg_prevpower2_32
  163. * Returns the next lower power of 2 below 'num', or 'num' if it's
  164. * already a power of 2.
  165. *
  166. * 'num' mustn't be 0.
  167. */
  168. static inline uint32
  169. pg_prevpower2_32(uint32 num)
  170. {
  171. return ((uint32) 1) << pg_leftmost_one_pos32(num);
  172. }
  173. /*
  174. * pg_prevpower2_64
  175. * Returns the next lower power of 2 below 'num', or 'num' if it's
  176. * already a power of 2.
  177. *
  178. * 'num' mustn't be 0.
  179. */
  180. static inline uint64
  181. pg_prevpower2_64(uint64 num)
  182. {
  183. return ((uint64) 1) << pg_leftmost_one_pos64(num);
  184. }
  185. /*
  186. * pg_prevpower2_size_t
  187. * Returns the next lower power of 2 below 'num', for a size_t input.
  188. */
  189. #if SIZEOF_SIZE_T == 4
  190. #define pg_prevpower2_size_t(num) pg_prevpower2_32(num)
  191. #else
  192. #define pg_prevpower2_size_t(num) pg_prevpower2_64(num)
  193. #endif
  194. /*
  195. * pg_ceil_log2_32
  196. * Returns equivalent of ceil(log2(num))
  197. */
  198. static inline uint32
  199. pg_ceil_log2_32(uint32 num)
  200. {
  201. if (num < 2)
  202. return 0;
  203. else
  204. return pg_leftmost_one_pos32(num - 1) + 1;
  205. }
  206. /*
  207. * pg_ceil_log2_64
  208. * Returns equivalent of ceil(log2(num))
  209. */
  210. static inline uint64
  211. pg_ceil_log2_64(uint64 num)
  212. {
  213. if (num < 2)
  214. return 0;
  215. else
  216. return pg_leftmost_one_pos64(num - 1) + 1;
  217. }
  218. /*
  219. * With MSVC on x86_64 builds, try using native popcnt instructions via the
  220. * __popcnt and __popcnt64 intrinsics. These don't work the same as GCC's
  221. * __builtin_popcount* intrinsic functions as they always emit popcnt
  222. * instructions.
  223. */
  224. #if defined(_MSC_VER) && defined(_M_AMD64)
  225. #define HAVE_X86_64_POPCNTQ
  226. #endif
  227. /*
  228. * On x86_64, we can use the hardware popcount instruction, but only if
  229. * we can verify that the CPU supports it via the cpuid instruction.
  230. *
  231. * Otherwise, we fall back to a hand-rolled implementation.
  232. */
  233. #ifdef HAVE_X86_64_POPCNTQ
  234. #if defined(HAVE__GET_CPUID) || defined(HAVE__CPUID)
  235. #define TRY_POPCNT_FAST 1
  236. #endif
  237. #endif
  238. #ifdef TRY_POPCNT_FAST
  239. /* Attempt to use the POPCNT instruction, but perform a runtime check first */
  240. extern int (*pg_popcount32) (uint32 word);
  241. extern int (*pg_popcount64) (uint64 word);
  242. #else
  243. /* Use a portable implementation -- no need for a function pointer. */
  244. extern int pg_popcount32(uint32 word);
  245. extern int pg_popcount64(uint64 word);
  246. #endif /* TRY_POPCNT_FAST */
  247. /* Count the number of one-bits in a byte array */
  248. extern uint64 pg_popcount(const char *buf, int bytes);
  249. /*
  250. * Rotate the bits of "word" to the right/left by n bits.
  251. */
  252. static inline uint32
  253. pg_rotate_right32(uint32 word, int n)
  254. {
  255. return (word >> n) | (word << (32 - n));
  256. }
  257. static inline uint32
  258. pg_rotate_left32(uint32 word, int n)
  259. {
  260. return (word << n) | (word >> (32 - n));
  261. }
  262. #endif /* PG_BITUTILS_H */