mirror of
https://github.com/WinampDesktop/winamp.git
synced 2025-04-27 18:35:43 -04:00
BitUtils: Make Count{Leading,Trailing}Zeros UB for value==0
This commit is contained in:
parent
38b075c014
commit
5671fde1ae
@ -27,6 +27,7 @@ Other features include:
|
|||||||
- Direct booting of homebrew executables
|
- Direct booting of homebrew executables
|
||||||
- Direct loading of Portable Sound Format (psf) files
|
- Direct loading of Portable Sound Format (psf) files
|
||||||
- Digital and analog controllers for input (rumble is forwarded to host)
|
- Digital and analog controllers for input (rumble is forwarded to host)
|
||||||
|
- Namco GunCon lightgun support (simulated with mouse)
|
||||||
- Qt and SDL frontends for desktop
|
- Qt and SDL frontends for desktop
|
||||||
- Automatic content scanning - game titles/regions are provided by redump.org
|
- Automatic content scanning - game titles/regions are provided by redump.org
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <intrin.h>
|
#include <intrin.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/// Returns the number of zero bits before the first set bit, going MSB->LSB.
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ALWAYS_INLINE unsigned CountLeadingZeros(T value)
|
ALWAYS_INLINE unsigned CountLeadingZeros(T value)
|
||||||
{
|
{
|
||||||
@ -12,27 +13,26 @@ ALWAYS_INLINE unsigned CountLeadingZeros(T value)
|
|||||||
if constexpr (sizeof(value) >= sizeof(u64))
|
if constexpr (sizeof(value) >= sizeof(u64))
|
||||||
{
|
{
|
||||||
unsigned long index;
|
unsigned long index;
|
||||||
return _BitScanReverse64(&index, ZeroExtend64(value)) ? static_cast<unsigned>(index) : 0;
|
_BitScanReverse64(&index, ZeroExtend64(value));
|
||||||
|
return static_cast<unsigned>(index) ^ static_cast<unsigned>((sizeof(value) * 8u) - 1u);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned long index;
|
unsigned long index;
|
||||||
return _BitScanReverse(&index, ZeroExtend32(value)) ? static_cast<unsigned>(index) : 0;
|
_BitScanReverse(&index, ZeroExtend32(value));
|
||||||
|
return static_cast<unsigned>(index) ^ static_cast<unsigned>((sizeof(value) * 8u) - 1u);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if constexpr (sizeof(value) >= sizeof(u64))
|
if constexpr (sizeof(value) >= sizeof(u64))
|
||||||
{
|
return static_cast<unsigned>(__builtin_clzl(ZeroExtend64(value)));
|
||||||
const unsigned bits = static_cast<unsigned>(__builtin_clzl(ZeroExtend64(value)));
|
else if constexpr (sizeof(value) == sizeof(u32))
|
||||||
return (value != 0) ? static_cast<unsigned>(bits) : 0;
|
return static_cast<unsigned>(__builtin_clz(ZeroExtend32(value)));
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
return static_cast<unsigned>(__builtin_clz(ZeroExtend32(value))) & static_cast<unsigned>((sizeof(value) * 8u) - 1u);
|
||||||
const unsigned bits = static_cast<unsigned>(__builtin_clz(ZeroExtend32(value)));
|
|
||||||
return (value != 0) ? static_cast<unsigned>(bits) : 0;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the number of zero bits before the first set bit, going LSB->MSB.
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ALWAYS_INLINE unsigned CountTrailingZeros(T value)
|
ALWAYS_INLINE unsigned CountTrailingZeros(T value)
|
||||||
{
|
{
|
||||||
@ -40,23 +40,19 @@ ALWAYS_INLINE unsigned CountTrailingZeros(T value)
|
|||||||
if constexpr (sizeof(value) >= sizeof(u64))
|
if constexpr (sizeof(value) >= sizeof(u64))
|
||||||
{
|
{
|
||||||
unsigned long index;
|
unsigned long index;
|
||||||
return _BitScanForward64(&index, ZeroExtend64(value)) ? static_cast<unsigned>(index) : 0;
|
_BitScanForward64(&index, ZeroExtend64(value));
|
||||||
|
return index;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned long index;
|
unsigned long index;
|
||||||
return _BitScanForward(&index, ZeroExtend32(value)) ? static_cast<unsigned>(index) : 0;
|
_BitScanForward(&index, ZeroExtend32(value));
|
||||||
|
return index;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if constexpr (sizeof(value) >= sizeof(u64))
|
if constexpr (sizeof(value) >= sizeof(u64))
|
||||||
{
|
return static_cast<unsigned>(__builtin_ctzl(ZeroExtend64(value)));
|
||||||
const unsigned bits = static_cast<unsigned>(__builtin_ctzl(ZeroExtend64(value)));
|
|
||||||
return (value != 0) ? static_cast<unsigned>(bits) : 0;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
return static_cast<unsigned>(__builtin_ctz(ZeroExtend32(value)));
|
||||||
const unsigned bits = static_cast<unsigned>(__builtin_ctz(ZeroExtend32(value)));
|
|
||||||
return (value != 0) ? static_cast<unsigned>(bits) : 0;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -168,7 +168,8 @@ bool InputButtonBindingWidget::eventFilter(QObject* watched, QEvent* event)
|
|||||||
}
|
}
|
||||||
else if (event_type == QEvent::MouseButtonRelease)
|
else if (event_type == QEvent::MouseButtonRelease)
|
||||||
{
|
{
|
||||||
const u32 button_index = CountTrailingZeros(static_cast<u32>(static_cast<const QMouseEvent*>(event)->button()));
|
const u32 button_mask = static_cast<u32>(static_cast<const QMouseEvent*>(event)->button());
|
||||||
|
const u32 button_index = (button_mask == 0u) ? 0 : CountTrailingZeros(button_mask);
|
||||||
m_new_binding_value = QStringLiteral("Mouse/Button%1").arg(button_index + 1);
|
m_new_binding_value = QStringLiteral("Mouse/Button%1").arg(button_index + 1);
|
||||||
setNewBinding();
|
setNewBinding();
|
||||||
stopListeningForInput();
|
stopListeningForInput();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user