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 	return (ffsl(x));
21 }
22 
23 #  ifdef  _M_X64
24 #    pragma intrinsic(_BitScanForward64)
25 #  endif
26 
ffsll(unsigned __int64 x)27 static __forceinline int ffsll(unsigned __int64 x)
28 {
29 	unsigned long i;
30 #ifdef  _M_X64
31 	if (_BitScanForward64(&i, x))
32 		return (i + 1);
33 	return (0);
34 #else
35 // Fallback for 32-bit build where 64-bit version not available
36 // assuming little endian
37 	union {
38 		unsigned __int64 ll;
39 		unsigned   long l[2];
40 	} s;
41 
42 	s.ll = x;
43 
44 	if (_BitScanForward(&i, s.l[0]))
45 		return (i + 1);
46 	else if(_BitScanForward(&i, s.l[1]))
47 		return (i + 33);
48 	return (0);
49 #endif
50 }
51 
52 #else
53 #  define ffsll(x) __builtin_ffsll(x)
54 #  define ffsl(x) __builtin_ffsl(x)
55 #  define ffs(x) __builtin_ffs(x)
56 #endif
57 
58 #endif /* strings_h */
59