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