Commit d9d3e5dd authored by Nick Mathewson's avatar Nick Mathewson

Fix bitops on 32-bit MSVC builds

According to the documentation, 32-bit x86 builds do not have the
64-bit _BitScan{Forward,Reverse}64 intrinsics.
parent c2c098ab
...@@ -25,30 +25,46 @@ ...@@ -25,30 +25,46 @@
/* On MSVC, we have these handy functions. We can ignore their return /* On MSVC, we have these handy functions. We can ignore their return
* values, since we will never supply val == 0. */ * values, since we will never supply val == 0. */
static __inline int ctz64(uint64_t val) static __inline int ctz32(unsigned long val)
{ {
DWORD zeros = 0; DWORD zeros = 0;
_BitScanForward64(&zeros, val); _BitScanForward(&zeros, val);
return zeros; return zeros;
} }
static __inline int clz64(uint64_t val) static __inline int clz32(unsigned long val)
{ {
DWORD zeros = 0; DWORD zeros = 0;
_BitScanReverse64(&zeros, val); _BitScanReverse(&zeros, val);
return zeros; return zeros;
} }
static __inline int ctz32(unsigned long val) #ifdef _WIN64
/* According to the documentation, these only exist on Win64. */
static __inline int ctz64(uint64_t val)
{ {
DWORD zeros = 0; DWORD zeros = 0;
_BitScanForward(&zeros, val); _BitScanForward64(&zeros, val);
return zeros; return zeros;
} }
static __inline int clz32(unsigned long val) static __inline int clz64(uint64_t val)
{ {
DWORD zeros = 0; DWORD zeros = 0;
_BitScanReverse(&zeros, val); _BitScanReverse64(&zeros, val);
return zeros; return zeros;
} }
#else
static __inline int ctz64(uint64_t val)
{
uint32_t lo = (uint32_t) val;
uint32_t hi = (uint32_t) (val >> 32);
return lo ? ctz32(lo) : 32 + ctz32(hi);
}
static __inline int clz64(uint64_t val)
{
uint32_t lo = (uint32_t) val;
uint32_t hi = (uint32_t) (val >> 32);
return hi ? clz32(hi) : 32 + clz32(lo);
}
#endif
/* End of MSVC case. */ /* End of MSVC case. */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment