Ruby 4.1.0dev (2026-09-14 revision 6ca2b168f3790e4972a01686f16f6b82524c699a)
bit.h
1#ifndef PRISM_INTERNAL_BIT_H
2#define PRISM_INTERNAL_BIT_H
3
5
6/*
7 * Count trailing zero bits in a 64-bit value. Used by SWAR identifier scanning
8 * to find the first non-matching byte in a word.
9 *
10 * Precondition: v must be nonzero. The result is undefined when v == 0
11 * (matching the behavior of __builtin_ctzll and _BitScanForward64).
12 */
13#if defined(__GNUC__) || defined(__clang__)
14#define pm_ctzll(v) ((unsigned) __builtin_ctzll(v))
15#elif defined(_MSC_VER)
16#include <intrin.h>
17#include <stdint.h>
18
19static PRISM_INLINE unsigned
20pm_ctzll(uint64_t v) {
21 unsigned long index;
22 _BitScanForward64(&index, v);
23 return (unsigned) index;
24}
25#else
26#include <stdint.h>
27
28static PRISM_INLINE unsigned
29pm_ctzll(uint64_t v) {
30 unsigned c = 0;
31 v &= (uint64_t) (-(int64_t) v);
32 if (v & 0x00000000FFFFFFFFULL) c += 0; else c += 32;
33 if (v & 0x0000FFFF0000FFFFULL) c += 0; else c += 16;
34 if (v & 0x00FF00FF00FF00FFULL) c += 0; else c += 8;
35 if (v & 0x0F0F0F0F0F0F0F0FULL) c += 0; else c += 4;
36 if (v & 0x3333333333333333ULL) c += 0; else c += 2;
37 if (v & 0x5555555555555555ULL) c += 0; else c += 1;
38 return c;
39}
40#endif
41
42#endif
#define PRISM_INLINE
Old Visual Studio versions do not support the inline keyword, so we need to define it to be __inline.
Definition inline.h:12