@@ -29,15 +29,60 @@ static really_inline uint64_t leading_zeroes(uint64_t mask)
2929 else
3030 return 64 ;
3131}
32+
3233#else
34+
3335static really_inline uint64_t trailing_zeroes (uint64_t mask )
3436{
37+ #if has_builtin (__builtin_ctzll )
3538 return (uint64_t )__builtin_ctzll (mask );
39+ #else
40+ // Code by Kim Walish from https://www.chessprogramming.org/BitScan.
41+ // Distributed under CC BY-SA 3.0.
42+ static const uint64_t magic = 0x03f79d71b4cb0a89ull ;
43+ const int magictable [64 ] = {
44+ 0 , 47 , 1 , 56 , 48 , 27 , 2 , 60 ,
45+ 57 , 49 , 41 , 37 , 28 , 16 , 3 , 61 ,
46+ 54 , 58 , 35 , 52 , 50 , 42 , 21 , 44 ,
47+ 38 , 32 , 29 , 23 , 17 , 11 , 4 , 62 ,
48+ 46 , 55 , 26 , 59 , 40 , 36 , 15 , 53 ,
49+ 34 , 51 , 20 , 43 , 31 , 22 , 10 , 45 ,
50+ 25 , 39 , 14 , 33 , 19 , 30 , 9 , 24 ,
51+ 13 , 18 , 8 , 12 , 7 , 6 , 5 , 63
52+ };
53+
54+ return magictable [((mask ^ (mask - 1 )) * magic ) >> 58 ];
55+ #endif
3656}
3757
3858static really_inline uint64_t leading_zeroes (uint64_t mask )
3959{
60+ #if has_builtin (__builtin_clzll )
4061 return (uint64_t )__builtin_clzll (mask );
62+ #else
63+ // Code by Kim Walish from https://www.chessprogramming.org/BitScan.
64+ // Distributed under CC BY-SA 3.0.
65+ static const uint64_t magic = 0x03f79d71b4cb0a89ull ;
66+ const int magictable [64 ] = {
67+ 63 , 16 , 62 , 7 , 15 , 36 , 61 , 3 ,
68+ 6 , 14 , 22 , 26 , 35 , 47 , 60 , 2 ,
69+ 9 , 5 , 28 , 11 , 13 , 21 , 42 , 19 ,
70+ 25 , 31 , 34 , 40 , 46 , 52 , 59 , 1 ,
71+ 17 , 8 , 37 , 4 , 23 , 27 , 48 , 10 ,
72+ 29 , 12 , 43 , 20 , 32 , 41 , 53 , 18 ,
73+ 38 , 24 , 49 , 30 , 44 , 33 , 54 , 39 ,
74+ 50 , 45 , 55 , 51 , 56 , 57 , 58 , 0
75+ };
76+
77+ mask |= mask >> 1 ;
78+ mask |= mask >> 2 ;
79+ mask |= mask >> 4 ;
80+ mask |= mask >> 8 ;
81+ mask |= mask >> 16 ;
82+ mask |= mask >> 32 ;
83+
84+ return magictable [(mask * magic ) >> 58 ];
85+ #endif
4186}
4287#endif // _MSC_VER
4388#endif // BITS_H
0 commit comments