]> gitweb.factorcode.org Git - factor.git/blob - vm/bitwise_hacks.hpp
1927cd4736199909d2e5e439b7a2ca11959adbb9
[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                 _BitScanReverse64(&n,x);
16         #else
17                 asm ("bsr %1, %0;":"=r"(n):"r"(x));
18         #endif
19 #elif defined(FACTOR_PPC)
20         asm ("cntlzw %1, %0;":"=r"(n):"r"(x));
21         n = (31 - n);
22 #else
23         #error Unsupported CPU
24 #endif
25         return n;
26 }
27
28 inline cell rightmost_clear_bit(cell x)
29 {
30         return log2(~x & (x + 1));
31 }
32
33 inline cell rightmost_set_bit(cell x)
34 {
35         return log2(x & (~x + 1));
36 }
37
38 inline cell popcount(cell x)
39 {
40 #ifdef FACTOR_64
41         u64 k1 = 0x5555555555555555ll;
42         u64 k2 = 0x3333333333333333ll;
43         u64 k4 = 0x0f0f0f0f0f0f0f0fll;
44         u64 kf = 0x0101010101010101ll;
45         cell ks = 56;
46 #else
47         u32 k1 = 0x55555555;
48         u32 k2 = 0x33333333;
49         u32 k4 = 0xf0f0f0f;
50         u32 kf = 0x1010101;
51         cell ks = 24;
52 #endif
53
54         x =  x       - ((x >> 1)  & k1); // put count of each 2 bits into those 2 bits
55         x = (x & k2) + ((x >> 2)  & k2); // put count of each 4 bits into those 4 bits
56         x = (x       +  (x >> 4)) & k4 ; // put count of each 8 bits into those 8 bits
57         x = (x * kf) >> ks; // returns 8 most significant bits of x + (x<<8) + (x<<16) + (x<<24) + ...
58
59         return x;
60 }
61
62 }