• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 	unsigned long i;
11 
12 	if (_BitScanForward(&i, x)) {
13 		return i + 1;
14 	}
15 	return 0;
16 }
17 
ffs(int x)18 static __forceinline int ffs(int x) {
19 	return ffsl(x);
20 }
21 
22 #  ifdef  _M_X64
23 #    pragma intrinsic(_BitScanForward64)
24 #  endif
25 
ffsll(unsigned __int64 x)26 static __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