mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 22:29:39 -06:00
Merge pull request #6571 from lioncash/rotate
CommonFuncs: Generify rotation functions and move them to BitUtils.h
This commit is contained in:
@ -100,6 +100,50 @@ constexpr Result ExtractBits(const T src) noexcept
|
||||
return ExtractBits<T, Result>(src, begin, end);
|
||||
}
|
||||
|
||||
///
|
||||
/// Rotates a value left (ROL).
|
||||
///
|
||||
/// @param value The value to rotate.
|
||||
/// @param amount The number of bits to rotate the value.
|
||||
/// @tparam T An unsigned type.
|
||||
///
|
||||
/// @return The rotated value.
|
||||
///
|
||||
template <typename T>
|
||||
constexpr T RotateLeft(const T value, size_t amount) noexcept
|
||||
{
|
||||
static_assert(std::is_unsigned<T>(), "Can only rotate unsigned types left.");
|
||||
|
||||
amount %= BitSize<T>();
|
||||
|
||||
if (amount == 0)
|
||||
return value;
|
||||
|
||||
return static_cast<T>((value << amount) | (value >> (BitSize<T>() - amount)));
|
||||
}
|
||||
|
||||
///
|
||||
/// Rotates a value right (ROR).
|
||||
///
|
||||
/// @param value The value to rotate.
|
||||
/// @param amount The number of bits to rotate the value.
|
||||
/// @tparam T An unsigned type.
|
||||
///
|
||||
/// @return The rotated value.
|
||||
///
|
||||
template <typename T>
|
||||
constexpr T RotateRight(const T value, size_t amount) noexcept
|
||||
{
|
||||
static_assert(std::is_unsigned<T>(), "Can only rotate unsigned types right.");
|
||||
|
||||
amount %= BitSize<T>();
|
||||
|
||||
if (amount == 0)
|
||||
return value;
|
||||
|
||||
return static_cast<T>((value >> amount) | (value << (BitSize<T>() - amount)));
|
||||
}
|
||||
|
||||
///
|
||||
/// Verifies whether the supplied value is a valid bit mask of the form 0b00...0011...11.
|
||||
/// Both edge cases of all zeros and all ones are considered valid masks, too.
|
||||
|
@ -30,38 +30,6 @@ constexpr size_t ArraySize(T (&arr)[N])
|
||||
__builtin_trap(); \
|
||||
}
|
||||
|
||||
// GCC 4.8 defines all the rotate functions now
|
||||
// Small issue with GCC's lrotl/lrotr intrinsics is they are still 32bit while we require 64bit
|
||||
#ifndef _rotl
|
||||
inline u32 _rotl(u32 x, int shift)
|
||||
{
|
||||
shift &= 31;
|
||||
if (!shift)
|
||||
return x;
|
||||
return (x << shift) | (x >> (32 - shift));
|
||||
}
|
||||
|
||||
inline u32 _rotr(u32 x, int shift)
|
||||
{
|
||||
shift &= 31;
|
||||
if (!shift)
|
||||
return x;
|
||||
return (x >> shift) | (x << (32 - shift));
|
||||
}
|
||||
#endif
|
||||
|
||||
inline u64 _rotl64(u64 x, unsigned int shift)
|
||||
{
|
||||
unsigned int n = shift % 64;
|
||||
return (x << n) | (x >> (64 - n));
|
||||
}
|
||||
|
||||
inline u64 _rotr64(u64 x, unsigned int shift)
|
||||
{
|
||||
unsigned int n = shift % 64;
|
||||
return (x >> n) | (x << (64 - n));
|
||||
}
|
||||
|
||||
#else // WIN32
|
||||
// Function Cross-Compatibility
|
||||
#define strcasecmp _stricmp
|
||||
|
@ -3,8 +3,10 @@
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "Common/Hash.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include "Common/BitUtils.h"
|
||||
#include "Common/CPUDetect.h"
|
||||
#include "Common/CommonFuncs.h"
|
||||
#include "Common/Intrinsics.h"
|
||||
@ -117,15 +119,15 @@ static u64 getblock(const u64* p, int i)
|
||||
static void bmix64(u64& h1, u64& h2, u64& k1, u64& k2, u64& c1, u64& c2)
|
||||
{
|
||||
k1 *= c1;
|
||||
k1 = _rotl64(k1, 23);
|
||||
k1 = Common::RotateLeft(k1, 23);
|
||||
k1 *= c2;
|
||||
h1 ^= k1;
|
||||
h1 += h2;
|
||||
|
||||
h2 = _rotl64(h2, 41);
|
||||
h2 = Common::RotateLeft(h2, 41);
|
||||
|
||||
k2 *= c2;
|
||||
k2 = _rotl64(k2, 23);
|
||||
k2 = Common::RotateLeft(k2, 23);
|
||||
k2 *= c1;
|
||||
h2 ^= k2;
|
||||
h2 += h1;
|
||||
@ -396,15 +398,15 @@ static u32 fmix32(u32 h)
|
||||
static void bmix32(u32& h1, u32& h2, u32& k1, u32& k2, u32& c1, u32& c2)
|
||||
{
|
||||
k1 *= c1;
|
||||
k1 = _rotl(k1, 11);
|
||||
k1 = Common::RotateLeft(k1, 11);
|
||||
k1 *= c2;
|
||||
h1 ^= k1;
|
||||
h1 += h2;
|
||||
|
||||
h2 = _rotl(h2, 17);
|
||||
h2 = Common::RotateLeft(h2, 17);
|
||||
|
||||
k2 *= c2;
|
||||
k2 = _rotl(k2, 11);
|
||||
k2 = Common::RotateLeft(k2, 11);
|
||||
k2 *= c1;
|
||||
h2 ^= k2;
|
||||
h2 += h1;
|
||||
|
Reference in New Issue
Block a user