diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-10-23 17:52:22 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-10-23 17:52:22 +0000 |
commit | 3a1720af1d7f43edc5b214cde0be11bfb94d077e (patch) | |
tree | 029e0ff2d5e3c0eaf2405fd8e669555fdf5e1297 /lib/fuzzer/FuzzerBuiltinsMsvc.h | |
parent | 8f3cadc28cb2bb9e8f9d69eeaaea1f57f2f7b2ab (diff) | |
download | src-test2-vendor/compiler-rt.tar.gz src-test2-vendor/compiler-rt.zip |
Notes
Diffstat (limited to 'lib/fuzzer/FuzzerBuiltinsMsvc.h')
-rw-r--r-- | lib/fuzzer/FuzzerBuiltinsMsvc.h | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/lib/fuzzer/FuzzerBuiltinsMsvc.h b/lib/fuzzer/FuzzerBuiltinsMsvc.h index 82709cfe7b40..bc65c60098be 100644 --- a/lib/fuzzer/FuzzerBuiltinsMsvc.h +++ b/lib/fuzzer/FuzzerBuiltinsMsvc.h @@ -15,9 +15,6 @@ #include "FuzzerDefs.h" #if LIBFUZZER_MSVC -#if !defined(_M_ARM) && !defined(_M_X64) -#error "_BitScanReverse64 unavailable on this platform so MSVC is unsupported." -#endif #include <intrin.h> #include <cstdint> #include <cstdlib> @@ -40,7 +37,18 @@ inline uint64_t Bswap(uint64_t x) { return _byteswap_uint64(x); } // outside of Windows. inline uint32_t Clzll(uint64_t X) { unsigned long LeadZeroIdx = 0; + +#if !defined(_M_ARM) && !defined(_M_X64) + // Scan the high 32 bits. + if (_BitScanReverse(&LeadZeroIdx, static_cast<unsigned long>(X >> 32))) + return static_cast<int>(63 - (LeadZeroIdx + 32)); // Create a bit offset from the MSB. + // Scan the low 32 bits. + if (_BitScanReverse(&LeadZeroIdx, static_cast<unsigned long>(X))) + return static_cast<int>(63 - LeadZeroIdx); + +#else if (_BitScanReverse64(&LeadZeroIdx, X)) return 63 - LeadZeroIdx; +#endif return 64; } @@ -50,7 +58,13 @@ inline uint32_t Clz(uint32_t X) { return 32; } -inline int Popcountll(unsigned long long X) { return __popcnt64(X); } +inline int Popcountll(unsigned long long X) { +#if !defined(_M_ARM) && !defined(_M_X64) + return __popcnt(X) + __popcnt(X >> 32); +#else + return __popcnt64(X); +#endif +} } // namespace fuzzer |