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