diff options
| author | Ginger Bill <bill@gingerbill.org> | 2017-10-08 15:16:13 +0100 |
|---|---|---|
| committer | Ginger Bill <bill@gingerbill.org> | 2017-10-08 15:16:13 +0100 |
| commit | 6424966b7ad6f85dc56d72cf623276f788a1a157 (patch) | |
| tree | 063d3063c885f331b71c51844f35a85d19af1f75 /src/common.cpp | |
| parent | 4e42d7df4303470dec5b3c354a9469699f6abf8d (diff) | |
Union tag stored as an integer
Diffstat (limited to 'src/common.cpp')
| -rw-r--r-- | src/common.cpp | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/src/common.cpp b/src/common.cpp index ef2b5f68d..1379db50d 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -304,6 +304,68 @@ i64 next_pow2(i64 n) { return n; } +i32 bit_set_count(u32 x) { + x -= ((x >> 1) & 0x55555555); + x = (((x >> 2) & 0x33333333) + (x & 0x33333333)); + x = (((x >> 4) + x) & 0x0f0f0f0f); + x += (x >> 8); + x += (x >> 16); + + return cast(i32)(x & 0x0000003f); +} + +i64 bit_set_count(u64 x) { + u32 a = *(cast(u32 *)&x); + u32 b = *(cast(u32 *)&x + 1); + return bit_set_count(a) + bit_set_count(b); +} + +u32 floor_log2(u32 x) { + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + return cast(u32)(bit_set_count(x) - 1); +} + +u64 floor_log2(u64 x) { + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + x |= x >> 32; + return cast(u64)(bit_set_count(x) - 1); +} + + +u32 ceil_log2(u32 x) { + i32 y = cast(i32)(x & (x-1)); + y |= -y; + y >>= 32-1; + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + return cast(u32)(bit_set_count(x) - 1 - y); +} + +u64 ceil_log2(u64 x) { + i64 y = cast(i64)(x & (x-1)); + y |= -y; + y >>= 64-1; + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + x |= x >> 32; + return cast(u64)(bit_set_count(x) - 1 - y); +} + + i32 prev_pow2(i32 n) { if (n <= 0) { return 0; |