1 #ifndef strings_h
2 #define strings_h
3 
4 /* MSVC doesn't define ffs/ffsl. This dummy strings.h header is provided
5  * for both */
6 #ifdef _MSC_VER
7 #  include <intrin.h>
8 #  pragma intrinsic(_BitScanForward)
ffsl(long x)9 static __forceinline int ffsl(long x)
10 {
11 	unsigned long i;
12 
13 	if (_BitScanForward(&i, x))
14 		return (i + 1);
15 	return (0);
16 }
17 
ffs(int x)18 static __forceinline int ffs(int x)
19 {
20 
21 	return (ffsl(x));
22 }
23 
24 #  ifdef  _M_X64
25 #    pragma intrinsic(_BitScanForward64)
26 #  endif
27 
ffsll(unsigned __int64 x)28 static __forceinline int ffsll(unsigned __int64 x)
29 {
30 	unsigned long i;
31 #ifdef  _M_X64
32 	if (_BitScanForward64(&i, x))
33 		return (i + 1);
34 	return (0);
35 #else
36 // Fallback for 32-bit build where 64-bit version not available
37 // assuming little endian
38 	union {
39 		unsigned __int64 ll;
40 		unsigned   long l[2];
41 	} s;
42 
43 	s.ll = x;
44 
45 	if (_BitScanForward(&i, s.l[0]))
46 		return (i + 1);
47 	else if(_BitScanForward(&i, s.l[1]))
48 		return (i + 33);
49 	return (0);
50 #endif
51 }
52 
53 #else
54 #  define ffsll(x) __builtin_ffsll(x)
55 #  define ffsl(x) __builtin_ffsl(x)
56 #  define ffs(x) __builtin_ffs(x)
57 #endif
58 
59 #endif /* strings_h */
60