return (value & (0 - value));
}
-//------------------------------------------------------------------------
-// genFindHighestBit: Return the highest bit that is set (that is, a mask that includes just the
-// highest bit).
-//
-// Return Value:
-// The highest position (0 is LSB) of bit that is set in the 'value'.
-//
-// Note:
-// It performs the "LeadingZeroCount " operation using intrinsics and then mask out everything
-// but the highest bit.
-inline unsigned int genFindHighestBit(unsigned int mask)
-{
- assert(mask != 0);
-#if defined(_MSC_VER)
- unsigned long index;
-#else
- unsigned int index;
-#endif
- BitScanReverse(&index, mask);
- return 1L << index;
-}
-
-//------------------------------------------------------------------------
-// genFindHighestBit: Return the highest bit that is set (that is, a mask that includes just the
-// highest bit).
-//
-// Return Value:
-// The highest position (0 is LSB) of bit that is set in the 'value'.
-//
-// Note:
-// It performs the "LeadingZeroCount " operation using intrinsics and then mask out everything
-// but the highest bit.
-inline unsigned __int64 genFindHighestBit(unsigned __int64 mask)
-{
- assert(mask != 0);
-#if defined(_MSC_VER)
- unsigned long index;
-#else
- unsigned int index;
-#endif
- BitScanReverse64(&index, mask);
- return 1LL << index;
-}
-
/*****************************************************************************
*
-* Return true if the given 64-bit value has exactly zero or one bits set.
+* Return true if the given value has exactly zero or one bits set.
*/
template <typename T>
/*****************************************************************************
*
-* Return true if the given 32-bit value has exactly zero or one bits set.
-*/
-
-inline bool genMaxOneBit(unsigned value)
-{
- return (value & (value - 1)) == 0;
-}
-
-/*****************************************************************************
-*
-* Return true if the given 64-bit value has exactly one bit set.
+* Return true if the given value has exactly one bit set.
*/
template <typename T>
return ((value != 0) && genMaxOneBit(value));
}
-/*****************************************************************************
-*
-* Return true if the given 32-bit value has exactly zero or one bits set.
-*/
-
-inline bool genExactlyOneBit(unsigned value)
-{
- return ((value != 0) && genMaxOneBit(value));
-}
-
/*****************************************************************************
*
* Given a value that has exactly one bit set, return the position of that
*/
inline unsigned genLog2(unsigned value)
{
- return BitPosition(value);
-}
-
-// Given an unsigned 64-bit value, returns the lower 32-bits in unsigned format
-//
-inline unsigned ulo32(unsigned __int64 value)
-{
- return static_cast<unsigned>(value);
-}
-
-// Given an unsigned 64-bit value, returns the upper 32-bits in unsigned format
-//
-inline unsigned uhi32(unsigned __int64 value)
-{
- return static_cast<unsigned>(value >> 32);
+ assert(genExactlyOneBit(value));
+ return BitOperations::BitScanForward(value);
}
-/*****************************************************************************
- *
- * Given a value that has exactly one bit set, return the position of that
- * bit, in other words return the logarithm in base 2 of the given value.
- */
-
inline unsigned genLog2(unsigned __int64 value)
{
-#ifdef HOST_64BIT
- return BitPosition(value);
-#else // HOST_32BIT
- unsigned lo32 = ulo32(value);
- unsigned hi32 = uhi32(value);
-
- if (lo32 != 0)
- {
- assert(hi32 == 0);
- return genLog2(lo32);
- }
- else
- {
- return genLog2(hi32) + 32;
- }
-#endif
+ assert(genExactlyOneBit(value));
+ return BitOperations::BitScanForward(value);
}
#ifdef __APPLE__
}
#endif // __APPLE__
-/*****************************************************************************
- *
- * Return the lowest bit that is set in the given register mask.
- */
+// Given an unsigned 64-bit value, returns the lower 32-bits in unsigned format
+//
+inline unsigned ulo32(unsigned __int64 value)
+{
+ return static_cast<unsigned>(value);
+}
-inline regMaskTP genFindLowestReg(regMaskTP value)
+// Given an unsigned 64-bit value, returns the upper 32-bits in unsigned format
+//
+inline unsigned uhi32(unsigned __int64 value)
{
- return (regMaskTP)genFindLowestBit(value);
+ return static_cast<unsigned>(value >> 32);
}
/*****************************************************************************
// Needed for unreached()
#include "error.h"
-#ifdef TARGET_64BIT
-#define BitScanForwardPtr BitScanForward64
-#else
-#define BitScanForwardPtr BitScanForward
-#endif
+#if defined(_MSC_VER)
+
+// Define wrappers over the non-underscore versions of the BitScan* APIs. The PAL defines these already.
+// We've #undef'ed the definitions in winnt.h for these names to avoid confusion.
+
+inline BOOLEAN BitScanForward(DWORD* Index, DWORD Mask)
+{
+ return ::_BitScanForward(Index, Mask);
+}
+
+inline BOOLEAN BitScanReverse(DWORD* Index, DWORD Mask)
+{
+ return ::_BitScanReverse(Index, Mask);
+}
+
+#if defined(HOST_64BIT)
+inline BOOLEAN BitScanForward64(DWORD* Index, DWORD64 Mask)
+{
+ return ::_BitScanForward64(Index, Mask);
+}
+
+inline BOOLEAN BitScanReverse64(DWORD* Index, DWORD64 Mask)
+{
+ return ::_BitScanReverse64(Index, Mask);
+}
+#endif // defined(HOST_64BIT)
+
+#endif // _MSC_VER
template <typename T, int size>
inline constexpr unsigned ArrLen(T (&)[size])