… | |
… | |
473 | _BitScanForward (&r, x); |
473 | _BitScanForward (&r, x); |
474 | return (int)r; |
474 | return (int)r; |
475 | #else |
475 | #else |
476 | int r = 0; |
476 | int r = 0; |
477 | |
477 | |
|
|
478 | /* todo: use david seal's algorithm */ |
|
|
479 | |
478 | x &= ~x + 1; /* this isolates the lowest bit */ |
480 | x &= ~x + 1; /* this isolates the lowest bit */ |
479 | |
481 | |
480 | #if ECB_branchless_on_i386 |
482 | #if ECB_branchless_on_i386 |
481 | r += !!(x & 0xaaaaaaaa) << 0; |
483 | r += !!(x & 0xaaaaaaaa) << 0; |
482 | r += !!(x & 0xcccccccc) << 1; |
484 | r += !!(x & 0xcccccccc) << 1; |
… | |
… | |
591 | x = ( x >> 16 ) | ( x << 16); |
593 | x = ( x >> 16 ) | ( x << 16); |
592 | |
594 | |
593 | return x; |
595 | return x; |
594 | } |
596 | } |
595 | |
597 | |
596 | /* popcount64 is only available on 64 bit cpus as gcc builtin */ |
|
|
597 | /* so for this version we are lazy */ |
|
|
598 | ecb_function_ ecb_const int ecb_popcount64 (uint64_t x); |
598 | ecb_function_ ecb_const int ecb_popcount64 (uint64_t x); |
599 | ecb_function_ ecb_const int |
599 | ecb_function_ ecb_const int |
600 | ecb_popcount64 (uint64_t x) |
600 | ecb_popcount64 (uint64_t x) |
601 | { |
601 | { |
|
|
602 | /* popcount64 is only available on 64 bit cpus as gcc builtin. */ |
|
|
603 | /* also, gcc/clang make this surprisingly difficult to use */ |
|
|
604 | #if __LP64__ && (ECB_GCC_VERSION(3,4) || ECB_CLANG_BUILTIN (__builtin_popcountl)) |
|
|
605 | return __builtin_popcountl (x); |
|
|
606 | #else |
602 | return ecb_popcount32 (x) + ecb_popcount32 (x >> 32); |
607 | return ecb_popcount32 (x) + ecb_popcount32 (x >> 32); |
|
|
608 | #endif |
603 | } |
609 | } |
604 | |
610 | |
605 | ecb_inline ecb_const uint8_t ecb_rotl8 (uint8_t x, unsigned int count); |
611 | ecb_inline ecb_const uint8_t ecb_rotl8 (uint8_t x, unsigned int count); |
606 | ecb_inline ecb_const uint8_t ecb_rotr8 (uint8_t x, unsigned int count); |
612 | ecb_inline ecb_const uint8_t ecb_rotr8 (uint8_t x, unsigned int count); |
607 | ecb_inline ecb_const uint16_t ecb_rotl16 (uint16_t x, unsigned int count); |
613 | ecb_inline ecb_const uint16_t ecb_rotl16 (uint16_t x, unsigned int count); |