| 
									
										
										
										
											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
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-11 21:45:05 -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
										 |  |  | } |