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