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