Duckstation/src/common/bitutils.h

62 lines
1.8 KiB
C
Raw Normal View History

// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com>
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
2020-04-26 07:21:33 +00:00
#pragma once
#include "types.h"
#ifdef _MSC_VER
#include <intrin.h>
#endif
/// Returns the number of zero bits before the first set bit, going MSB->LSB.
2020-04-26 07:21:33 +00:00
template<typename T>
ALWAYS_INLINE unsigned CountLeadingZeros(T value)
{
#ifdef _MSC_VER
if constexpr (sizeof(value) >= sizeof(u64))
{
unsigned long index;
_BitScanReverse64(&index, ZeroExtend64(value));
return static_cast<unsigned>(index) ^ static_cast<unsigned>((sizeof(value) * 8u) - 1u);
2020-04-26 07:21:33 +00:00
}
else
{
unsigned long index;
_BitScanReverse(&index, ZeroExtend32(value));
return static_cast<unsigned>(index) ^ static_cast<unsigned>((sizeof(value) * 8u) - 1u);
2020-04-26 07:21:33 +00:00
}
#else
if constexpr (sizeof(value) >= sizeof(u64))
return static_cast<unsigned>(__builtin_clzl(ZeroExtend64(value)));
else if constexpr (sizeof(value) == sizeof(u32))
return static_cast<unsigned>(__builtin_clz(ZeroExtend32(value)));
2020-04-26 07:21:33 +00:00
else
return static_cast<unsigned>(__builtin_clz(ZeroExtend32(value))) & static_cast<unsigned>((sizeof(value) * 8u) - 1u);
2020-04-26 07:21:33 +00:00
#endif
}
/// Returns the number of zero bits before the first set bit, going LSB->MSB.
2020-04-26 07:21:33 +00:00
template<typename T>
ALWAYS_INLINE unsigned CountTrailingZeros(T value)
{
#ifdef _MSC_VER
if constexpr (sizeof(value) >= sizeof(u64))
{
unsigned long index;
_BitScanForward64(&index, ZeroExtend64(value));
return index;
2020-04-26 07:21:33 +00:00
}
else
{
unsigned long index;
_BitScanForward(&index, ZeroExtend32(value));
return index;
2020-04-26 07:21:33 +00:00
}
#else
if constexpr (sizeof(value) >= sizeof(u64))
return static_cast<unsigned>(__builtin_ctzl(ZeroExtend64(value)));
2020-04-26 07:21:33 +00:00
else
return static_cast<unsigned>(__builtin_ctz(ZeroExtend32(value)));
2020-04-26 07:21:33 +00:00
#endif
}