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)
9static __forceinline int ffsl(long x) {
10	unsigned long i;
11
12	if (_BitScanForward(&i, x)) {
13		return i + 1;
14	}
15	return 0;
16}
17
18static __forceinline int ffs(int x) {
19	return ffsl(x);
20}
21
22#  ifdef  _M_X64
23#    pragma intrinsic(_BitScanForward64)
24#  endif
25
26static __forceinline int ffsll(unsigned __int64 x) {
27	unsigned long i;
28#ifdef  _M_X64
29	if (_BitScanForward64(&i, x)) {
30		return i + 1;
31	}
32	return 0;
33#else
34// Fallback for 32-bit build where 64-bit version not available
35// assuming little endian
36	union {
37		unsigned __int64 ll;
38		unsigned   long l[2];
39	} s;
40
41	s.ll = x;
42
43	if (_BitScanForward(&i, s.l[0])) {
44		return i + 1;
45	} else if(_BitScanForward(&i, s.l[1])) {
46		return i + 33;
47	}
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