]> gitweb.factorcode.org Git - factor.git/blob - vm/bitwise_hacks.hpp
GC maps for more compact inline GC checks
[factor.git] / vm / bitwise_hacks.hpp
1 namespace factor
2 {
3
4 inline cell log2(cell x)
5 {
6         cell n;
7 #if defined(FACTOR_X86)
8         #if defined(_MSC_VER)
9                 _BitScanReverse(&n,x);
10         #else
11                 asm ("bsr %1, %0;":"=r"(n):"r"(x));
12         #endif
13 #elif defined(FACTOR_AMD64)
14         #if defined(_MSC_VER)
15                 n = 0;
16                 _BitScanReverse64((DWORD *)&n,x);
17         #else
18                 asm ("bsr %1, %0;":"=r"(n):"r"(x));
19         #endif
20 #elif defined(FACTOR_PPC)
21         asm ("cntlzw %1, %0;":"=r"(n):"r"(x));
22         n = (31 - n);
23 #else
24         #error Unsupported CPU
25 #endif
26         return n;
27 }
28
29 inline cell rightmost_clear_bit(cell x)
30 {
31         return log2(~x & (x + 1));
32 }
33
34 inline cell rightmost_set_bit(cell x)
35 {
36         return log2(x & (~x + 1));
37 }
38
39 inline cell popcount(cell x)
40 {
41 #ifdef FACTOR_64
42         u64 k1 = 0x5555555555555555ll;
43         u64 k2 = 0x3333333333333333ll;
44         u64 k4 = 0x0f0f0f0f0f0f0f0fll;
45         u64 kf = 0x0101010101010101ll;
46         cell ks = 56;
47 #else
48         u32 k1 = 0x55555555;
49         u32 k2 = 0x33333333;
50         u32 k4 = 0xf0f0f0f;
51         u32 kf = 0x1010101;
52         cell ks = 24;
53 #endif
54
55         x =  x       - ((x >> 1)  & k1); // put count of each 2 bits into those 2 bits
56         x = (x & k2) + ((x >> 2)  & k2); // put count of each 4 bits into those 4 bits
57         x = (x       +  (x >> 4)) & k4 ; // put count of each 8 bits into those 8 bits
58         x = (x * kf) >> ks; // returns 8 most significant bits of x + (x<<8) + (x<<16) + (x<<24) + ...
59
60         return x;
61 }
62
63 inline bool bitmap_p(u8 *bitmap, cell index)
64 {
65         cell byte = index >> 3;
66         cell bit = index & 7;
67         return (bitmap[byte] & (1 << bit)) != 0;
68 }
69
70 }