]> gitweb.factorcode.org Git - factor.git/blob - vm/bitwise_hacks.hpp
VM: storing some sample data in the heap (#337)
[factor.git] / vm / bitwise_hacks.hpp
1 namespace factor {
2
3 inline cell log2(cell x) {
4   cell n;
5 #if defined(FACTOR_X86)
6 #if defined(_MSC_VER)
7   _BitScanReverse((unsigned long*)&n, x);
8 #else
9   asm("bsr %1, %0;" : "=r"(n) : "r"(x));
10 #endif
11 #elif defined(FACTOR_AMD64)
12 #if defined(_MSC_VER)
13   n = 0;
14   _BitScanReverse64((unsigned long*)&n, x);
15 #else
16   asm("bsr %1, %0;" : "=r"(n) : "r"(x));
17 #endif
18 #elif defined(FACTOR_PPC64)
19 #if defined(__GNUC__)
20   n = (63 - __builtin_clzll(x));
21 #else
22 #error Unsupported compiler
23 #endif
24 #elif defined(FACTOR_PPC32)
25 #if defined(__GNUC__)
26   n = (31 - __builtin_clz(x));
27 #else
28 #error Unsupported compiler
29 #endif
30 #else
31 #error Unsupported CPU
32 #endif
33   return n;
34 }
35
36 inline cell rightmost_clear_bit(cell x) { return log2(~x & (x + 1)); }
37
38 inline cell rightmost_set_bit(cell x) { return log2(x & (~x + 1)); }
39
40 inline cell popcount(cell x) {
41 #if defined(__GNUC__)
42 #ifdef FACTOR_64
43   return __builtin_popcountll(x);
44 #else
45   return __builtin_popcount(x);
46 #endif
47 #else
48 #ifdef FACTOR_64
49   uint64_t k1 = 0x5555555555555555ll;
50   uint64_t k2 = 0x3333333333333333ll;
51   uint64_t k4 = 0x0f0f0f0f0f0f0f0fll;
52   uint64_t kf = 0x0101010101010101ll;
53   cell ks = 56;
54 #else
55   uint32_t k1 = 0x55555555;
56   uint32_t k2 = 0x33333333;
57   uint32_t k4 = 0xf0f0f0f;
58   uint32_t kf = 0x1010101;
59   cell ks = 24;
60 #endif
61
62   x = x - ((x >> 1) & k1);         // put count of each 2 bits into those 2 bits
63   x = (x & k2) + ((x >> 2) & k2);  // put count of each 4 bits into those 4 bits
64   x = (x + (x >> 4)) & k4;         // put count of each 8 bits into those 8 bits
65   x = (x * kf) >> ks;  // returns 8 most significant bits of x + (x<<8) +
66                        // (x<<16) + (x<<24) + ...
67
68   return x;
69 #endif
70 }
71
72 inline bool bitmap_p(uint8_t* bitmap, cell index) {
73   cell byte = index >> 3;
74   cell bit = index & 7;
75   return (bitmap[byte] & (1 << bit)) != 0;
76 }
77
78 }