2013-05-11 21:45:05 -04:00
|
|
|
namespace factor {
|
2009-11-01 21:15:42 -05:00
|
|
|
|
2013-05-11 21:45:05 -04:00
|
|
|
inline cell log2(cell x) {
|
|
|
|
cell n;
|
2010-01-16 09:43:22 -05:00
|
|
|
#if defined(FACTOR_X86)
|
2013-05-11 21:45:05 -04:00
|
|
|
#if defined(_MSC_VER)
|
2013-05-13 18:18:48 -04:00
|
|
|
_BitScanReverse((unsigned long*)&n, x);
|
2013-05-11 21:45:05 -04:00
|
|
|
#else
|
|
|
|
asm("bsr %1, %0;" : "=r"(n) : "r"(x));
|
|
|
|
#endif
|
2010-01-16 09:43:22 -05:00
|
|
|
#elif defined(FACTOR_AMD64)
|
2013-05-11 21:45:05 -04:00
|
|
|
#if defined(_MSC_VER)
|
|
|
|
n = 0;
|
2013-05-13 18:18:48 -04:00
|
|
|
_BitScanReverse64((unsigned long*)&n, x);
|
2013-05-11 21:45:05 -04:00
|
|
|
#else
|
|
|
|
asm("bsr %1, %0;" : "=r"(n) : "r"(x));
|
|
|
|
#endif
|
2011-05-20 18:11:50 -04:00
|
|
|
#elif defined(FACTOR_PPC64)
|
|
|
|
#if defined(__GNUC__)
|
2013-05-11 21:45:05 -04:00
|
|
|
n = (63 - __builtin_clzll(x));
|
2011-05-20 18:11:50 -04:00
|
|
|
#else
|
2013-05-11 21:45:05 -04:00
|
|
|
#error Unsupported compiler
|
2011-05-20 18:11:50 -04:00
|
|
|
#endif
|
|
|
|
#elif defined(FACTOR_PPC32)
|
|
|
|
#if defined(__GNUC__)
|
2013-05-11 21:45:05 -04:00
|
|
|
n = (31 - __builtin_clz(x));
|
2011-05-20 18:11:50 -04:00
|
|
|
#else
|
2013-05-11 21:45:05 -04:00
|
|
|
#error Unsupported compiler
|
2011-05-20 18:11:50 -04:00
|
|
|
#endif
|
2009-11-08 07:08:17 -05:00
|
|
|
#else
|
2013-05-11 21:45:05 -04:00
|
|
|
#error Unsupported CPU
|
2009-11-08 07:08:17 -05:00
|
|
|
#endif
|
2013-05-11 21:45:05 -04:00
|
|
|
return n;
|
2009-11-08 07:08:17 -05:00
|
|
|
}
|
|
|
|
|
2013-05-11 21:45:05 -04:00
|
|
|
inline cell rightmost_clear_bit(cell x) { return log2(~x & (x + 1)); }
|
2009-11-08 07:08:17 -05:00
|
|
|
|
2013-05-11 21:45:05 -04:00
|
|
|
inline cell rightmost_set_bit(cell x) { return log2(x & (~x + 1)); }
|
2009-11-01 21:15:42 -05:00
|
|
|
|
2013-05-11 21:45:05 -04:00
|
|
|
inline cell popcount(cell x) {
|
2011-05-20 18:11:50 -04:00
|
|
|
#if defined(__GNUC__)
|
|
|
|
#ifdef FACTOR_64
|
2013-05-11 21:45:05 -04:00
|
|
|
return __builtin_popcountll(x);
|
2011-05-20 18:11:50 -04:00
|
|
|
#else
|
2013-05-11 21:45:05 -04:00
|
|
|
return __builtin_popcount(x);
|
2011-05-20 18:11:50 -04:00
|
|
|
#endif
|
|
|
|
#else
|
2009-11-05 20:29:27 -05:00
|
|
|
#ifdef FACTOR_64
|
2013-05-13 00:28:25 -04:00
|
|
|
uint64_t k1 = 0x5555555555555555ll;
|
|
|
|
uint64_t k2 = 0x3333333333333333ll;
|
|
|
|
uint64_t k4 = 0x0f0f0f0f0f0f0f0fll;
|
|
|
|
uint64_t kf = 0x0101010101010101ll;
|
2013-05-11 21:45:05 -04:00
|
|
|
cell ks = 56;
|
2009-11-05 20:29:27 -05:00
|
|
|
#else
|
2013-05-13 00:28:25 -04:00
|
|
|
uint32_t k1 = 0x55555555;
|
|
|
|
uint32_t k2 = 0x33333333;
|
|
|
|
uint32_t k4 = 0xf0f0f0f;
|
|
|
|
uint32_t kf = 0x1010101;
|
2013-05-11 21:45:05 -04:00
|
|
|
cell ks = 24;
|
2009-11-05 20:29:27 -05:00
|
|
|
#endif
|
|
|
|
|
2016-08-05 08:44:37 -04:00
|
|
|
x = x - ((x >> 1) & k1); // put count of each 2 bits into those 2 bits
|
|
|
|
x = (x & k2) + ((x >> 2) & k2); // put count of each 4 bits into those 4 bits
|
|
|
|
x = (x + (x >> 4)) & k4; // put count of each 8 bits into those 8 bits
|
|
|
|
x = (x * kf) >> ks; // returns 8 most significant bits of x + (x<<8) +
|
|
|
|
// (x<<16) + (x<<24) + ...
|
2009-11-01 21:15:42 -05:00
|
|
|
|
2013-05-11 21:45:05 -04:00
|
|
|
return x;
|
2011-05-20 18:11:50 -04:00
|
|
|
#endif
|
2009-11-01 21:15:42 -05:00
|
|
|
}
|
|
|
|
|
2013-05-13 00:28:25 -04:00
|
|
|
inline bool bitmap_p(uint8_t* bitmap, cell index) {
|
2013-05-11 21:45:05 -04:00
|
|
|
cell byte = index >> 3;
|
|
|
|
cell bit = index & 7;
|
|
|
|
return (bitmap[byte] & (1 << bit)) != 0;
|
2010-06-11 20:06:00 -04:00
|
|
|
}
|
|
|
|
|
2009-11-01 21:15:42 -05:00
|
|
|
}
|