Merge pull request #10950 from JosJuice/replace-bitutils-rotate
Replace BitUtils with C++20: RotateLeft/RotateRight
This commit is contained in:
commit
a1c4861ad8
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <bit>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
@ -558,15 +559,15 @@ struct LogicalImm
|
||||||
// pick the next sequence of ones. This ensures we get a complete element
|
// pick the next sequence of ones. This ensures we get a complete element
|
||||||
// that has not been cut-in-half due to rotation across the word boundary.
|
// that has not been cut-in-half due to rotation across the word boundary.
|
||||||
|
|
||||||
const size_t rotation = Common::CountTrailingZeros(value & (value + 1));
|
const int rotation = Common::CountTrailingZeros(value & (value + 1));
|
||||||
const u64 normalized = Common::RotateRight(value, rotation);
|
const u64 normalized = std::rotr(value, rotation);
|
||||||
|
|
||||||
const size_t element_size = Common::CountTrailingZeros(normalized & (normalized + 1));
|
const int element_size = Common::CountTrailingZeros(normalized & (normalized + 1));
|
||||||
const size_t ones = Common::CountTrailingZeros(~normalized);
|
const int ones = Common::CountTrailingZeros(~normalized);
|
||||||
|
|
||||||
// Check the value is repeating; also ensures element size is a power of two.
|
// Check the value is repeating; also ensures element size is a power of two.
|
||||||
|
|
||||||
if (Common::RotateRight(value, element_size) != value)
|
if (std::rotr(value, element_size) != value)
|
||||||
{
|
{
|
||||||
valid = false;
|
valid = false;
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -107,50 +107,6 @@ constexpr Result ExtractBits(const T src) noexcept
|
||||||
return ExtractBits<T, Result>(src, begin, end);
|
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.
|
/// 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.
|
/// Both edge cases of all zeros and all ones are considered valid masks, too.
|
||||||
|
|
|
@ -2,12 +2,12 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <bit>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include <mbedtls/aes.h>
|
#include <mbedtls/aes.h>
|
||||||
|
|
||||||
#include "Common/Assert.h"
|
#include "Common/Assert.h"
|
||||||
#include "Common/BitUtils.h"
|
|
||||||
#include "Common/CPUDetect.h"
|
#include "Common/CPUDetect.h"
|
||||||
#include "Common/Crypto/AES.h"
|
#include "Common/Crypto/AES.h"
|
||||||
|
|
||||||
|
@ -294,7 +294,7 @@ public:
|
||||||
{
|
{
|
||||||
const uint8x16_t enc = vaeseq_u8(vreinterpretq_u8_u32(vmovq_n_u32(rk[i + 3])), vmovq_n_u8(0));
|
const uint8x16_t enc = vaeseq_u8(vreinterpretq_u8_u32(vmovq_n_u32(rk[i + 3])), vmovq_n_u8(0));
|
||||||
const u32 temp = vgetq_lane_u32(vreinterpretq_u32_u8(enc), 0);
|
const u32 temp = vgetq_lane_u32(vreinterpretq_u32_u8(enc), 0);
|
||||||
rk[i + 4] = rk[i + 0] ^ Common::RotateRight(temp, 8) ^ rcon[i / Nk];
|
rk[i + 4] = rk[i + 0] ^ std::rotr(temp, 8) ^ rcon[i / Nk];
|
||||||
rk[i + 5] = rk[i + 4] ^ rk[i + 1];
|
rk[i + 5] = rk[i + 4] ^ rk[i + 1];
|
||||||
rk[i + 6] = rk[i + 5] ^ rk[i + 2];
|
rk[i + 6] = rk[i + 5] ^ rk[i + 2];
|
||||||
rk[i + 7] = rk[i + 6] ^ rk[i + 3];
|
rk[i + 7] = rk[i + 6] ^ rk[i + 3];
|
||||||
|
|
|
@ -4,7 +4,9 @@
|
||||||
#include "Common/Hash.h"
|
#include "Common/Hash.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <bit>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
|
|
||||||
#include "Common/BitUtils.h"
|
#include "Common/BitUtils.h"
|
||||||
|
@ -60,15 +62,15 @@ static u64 getblock(const u64* p, int i)
|
||||||
static void bmix64(u64& h1, u64& h2, u64& k1, u64& k2, u64& c1, u64& c2)
|
static void bmix64(u64& h1, u64& h2, u64& k1, u64& k2, u64& c1, u64& c2)
|
||||||
{
|
{
|
||||||
k1 *= c1;
|
k1 *= c1;
|
||||||
k1 = Common::RotateLeft(k1, 23);
|
k1 = std::rotl(k1, 23);
|
||||||
k1 *= c2;
|
k1 *= c2;
|
||||||
h1 ^= k1;
|
h1 ^= k1;
|
||||||
h1 += h2;
|
h1 += h2;
|
||||||
|
|
||||||
h2 = Common::RotateLeft(h2, 41);
|
h2 = std::rotl(h2, 41);
|
||||||
|
|
||||||
k2 *= c2;
|
k2 *= c2;
|
||||||
k2 = Common::RotateLeft(k2, 23);
|
k2 = std::rotl(k2, 23);
|
||||||
k2 *= c1;
|
k2 *= c1;
|
||||||
h2 ^= k2;
|
h2 ^= k2;
|
||||||
h2 += h1;
|
h2 += h1;
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <bit>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -17,7 +18,6 @@
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "Common/BitUtils.h"
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "Common/MsgHandler.h"
|
#include "Common/MsgHandler.h"
|
||||||
#include "Common/StringUtil.h"
|
#include "Common/StringUtil.h"
|
||||||
|
@ -249,26 +249,26 @@ static void unscramble1(u32* addr, u32* val)
|
||||||
{
|
{
|
||||||
u32 tmp;
|
u32 tmp;
|
||||||
|
|
||||||
*val = Common::RotateLeft(*val, 4);
|
*val = std::rotl(*val, 4);
|
||||||
|
|
||||||
tmp = ((*addr ^ *val) & 0xF0F0F0F0);
|
tmp = ((*addr ^ *val) & 0xF0F0F0F0);
|
||||||
*addr ^= tmp;
|
*addr ^= tmp;
|
||||||
*val = Common::RotateRight((*val ^ tmp), 0x14);
|
*val = std::rotr((*val ^ tmp), 0x14);
|
||||||
|
|
||||||
tmp = ((*addr ^ *val) & 0xFFFF0000);
|
tmp = ((*addr ^ *val) & 0xFFFF0000);
|
||||||
*addr ^= tmp;
|
*addr ^= tmp;
|
||||||
*val = Common::RotateRight((*val ^ tmp), 0x12);
|
*val = std::rotr((*val ^ tmp), 0x12);
|
||||||
|
|
||||||
tmp = ((*addr ^ *val) & 0x33333333);
|
tmp = ((*addr ^ *val) & 0x33333333);
|
||||||
*addr ^= tmp;
|
*addr ^= tmp;
|
||||||
*val = Common::RotateRight((*val ^ tmp), 6);
|
*val = std::rotr((*val ^ tmp), 6);
|
||||||
|
|
||||||
tmp = ((*addr ^ *val) & 0x00FF00FF);
|
tmp = ((*addr ^ *val) & 0x00FF00FF);
|
||||||
*addr ^= tmp;
|
*addr ^= tmp;
|
||||||
*val = Common::RotateLeft((*val ^ tmp), 9);
|
*val = std::rotl((*val ^ tmp), 9);
|
||||||
|
|
||||||
tmp = ((*addr ^ *val) & 0xAAAAAAAA);
|
tmp = ((*addr ^ *val) & 0xAAAAAAAA);
|
||||||
*addr = Common::RotateLeft((*addr ^ tmp), 1);
|
*addr = std::rotl((*addr ^ tmp), 1);
|
||||||
*val ^= tmp;
|
*val ^= tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,27 +276,27 @@ static void unscramble2(u32* addr, u32* val)
|
||||||
{
|
{
|
||||||
u32 tmp;
|
u32 tmp;
|
||||||
|
|
||||||
*val = Common::RotateRight(*val, 1);
|
*val = std::rotr(*val, 1);
|
||||||
|
|
||||||
tmp = ((*addr ^ *val) & 0xAAAAAAAA);
|
tmp = ((*addr ^ *val) & 0xAAAAAAAA);
|
||||||
*val ^= tmp;
|
*val ^= tmp;
|
||||||
*addr = Common::RotateRight((*addr ^ tmp), 9);
|
*addr = std::rotr((*addr ^ tmp), 9);
|
||||||
|
|
||||||
tmp = ((*addr ^ *val) & 0x00FF00FF);
|
tmp = ((*addr ^ *val) & 0x00FF00FF);
|
||||||
*val ^= tmp;
|
*val ^= tmp;
|
||||||
*addr = Common::RotateLeft((*addr ^ tmp), 6);
|
*addr = std::rotl((*addr ^ tmp), 6);
|
||||||
|
|
||||||
tmp = ((*addr ^ *val) & 0x33333333);
|
tmp = ((*addr ^ *val) & 0x33333333);
|
||||||
*val ^= tmp;
|
*val ^= tmp;
|
||||||
*addr = Common::RotateLeft((*addr ^ tmp), 0x12);
|
*addr = std::rotl((*addr ^ tmp), 0x12);
|
||||||
|
|
||||||
tmp = ((*addr ^ *val) & 0xFFFF0000);
|
tmp = ((*addr ^ *val) & 0xFFFF0000);
|
||||||
*val ^= tmp;
|
*val ^= tmp;
|
||||||
*addr = Common::RotateLeft((*addr ^ tmp), 0x14);
|
*addr = std::rotl((*addr ^ tmp), 0x14);
|
||||||
|
|
||||||
tmp = ((*addr ^ *val) & 0xF0F0F0F0);
|
tmp = ((*addr ^ *val) & 0xF0F0F0F0);
|
||||||
*val ^= tmp;
|
*val ^= tmp;
|
||||||
*addr = Common::RotateRight((*addr ^ tmp), 4);
|
*addr = std::rotr((*addr ^ tmp), 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void decryptcode(const u32* seeds, u32* code)
|
static void decryptcode(const u32* seeds, u32* code)
|
||||||
|
@ -309,13 +309,13 @@ static void decryptcode(const u32* seeds, u32* code)
|
||||||
unscramble1(&addr, &val);
|
unscramble1(&addr, &val);
|
||||||
while (i < 32)
|
while (i < 32)
|
||||||
{
|
{
|
||||||
tmp = (Common::RotateRight(val, 4) ^ seeds[i++]);
|
tmp = (std::rotr(val, 4) ^ seeds[i++]);
|
||||||
tmp2 = (val ^ seeds[i++]);
|
tmp2 = (val ^ seeds[i++]);
|
||||||
addr ^= (table6[tmp & 0x3F] ^ table4[(tmp >> 8) & 0x3F] ^ table2[(tmp >> 16) & 0x3F] ^
|
addr ^= (table6[tmp & 0x3F] ^ table4[(tmp >> 8) & 0x3F] ^ table2[(tmp >> 16) & 0x3F] ^
|
||||||
table0[(tmp >> 24) & 0x3F] ^ table7[tmp2 & 0x3F] ^ table5[(tmp2 >> 8) & 0x3F] ^
|
table0[(tmp >> 24) & 0x3F] ^ table7[tmp2 & 0x3F] ^ table5[(tmp2 >> 8) & 0x3F] ^
|
||||||
table3[(tmp2 >> 16) & 0x3F] ^ table1[(tmp2 >> 24) & 0x3F]);
|
table3[(tmp2 >> 16) & 0x3F] ^ table1[(tmp2 >> 24) & 0x3F]);
|
||||||
|
|
||||||
tmp = (Common::RotateRight(addr, 4) ^ seeds[i++]);
|
tmp = (std::rotr(addr, 4) ^ seeds[i++]);
|
||||||
tmp2 = (addr ^ seeds[i++]);
|
tmp2 = (addr ^ seeds[i++]);
|
||||||
val ^= (table6[tmp & 0x3F] ^ table4[(tmp >> 8) & 0x3F] ^ table2[(tmp >> 16) & 0x3F] ^
|
val ^= (table6[tmp & 0x3F] ^ table4[(tmp >> 8) & 0x3F] ^ table2[(tmp >> 16) & 0x3F] ^
|
||||||
table0[(tmp >> 24) & 0x3F] ^ table7[tmp2 & 0x3F] ^ table5[(tmp2 >> 8) & 0x3F] ^
|
table0[(tmp >> 24) & 0x3F] ^ table7[tmp2 & 0x3F] ^ table5[(tmp2 >> 8) & 0x3F] ^
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
#include "Core/HW/WiimoteEmu/Encryption.h"
|
#include "Core/HW/WiimoteEmu/Encryption.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <bit>
|
||||||
|
|
||||||
#include "Common/BitUtils.h"
|
|
||||||
#include "Common/Logging/Log.h"
|
#include "Common/Logging/Log.h"
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
@ -520,15 +520,13 @@ EncryptionKey::KeyData KeyGen1stParty::GenerateKeyData(const EncryptionKey::Rand
|
||||||
for (std::size_t i = 0; i != t0.size(); ++i)
|
for (std::size_t i = 0; i != t0.size(); ++i)
|
||||||
t0[i] = keygen_sbox_1st_party[rand[i]];
|
t0[i] = keygen_sbox_1st_party[rand[i]];
|
||||||
|
|
||||||
auto& ror8 = Common::RotateRight<u8>;
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
u8((ror8(ans[0] ^ t0[5], t0[2]) - t0[9]) ^ t0[4]),
|
u8((std::rotr<u8>(ans[0] ^ t0[5], t0[2]) - t0[9]) ^ t0[4]),
|
||||||
u8((ror8(ans[1] ^ t0[1], t0[0]) - t0[5]) ^ t0[7]),
|
u8((std::rotr<u8>(ans[1] ^ t0[1], t0[0]) - t0[5]) ^ t0[7]),
|
||||||
u8((ror8(ans[2] ^ t0[6], t0[8]) - t0[2]) ^ t0[0]),
|
u8((std::rotr<u8>(ans[2] ^ t0[6], t0[8]) - t0[2]) ^ t0[0]),
|
||||||
u8((ror8(ans[3] ^ t0[4], t0[7]) - t0[3]) ^ t0[2]),
|
u8((std::rotr<u8>(ans[3] ^ t0[4], t0[7]) - t0[3]) ^ t0[2]),
|
||||||
u8((ror8(ans[4] ^ t0[1], t0[6]) - t0[3]) ^ t0[4]),
|
u8((std::rotr<u8>(ans[4] ^ t0[1], t0[6]) - t0[3]) ^ t0[4]),
|
||||||
u8((ror8(ans[5] ^ t0[7], t0[8]) - t0[5]) ^ t0[9]),
|
u8((std::rotr<u8>(ans[5] ^ t0[7], t0[8]) - t0[5]) ^ t0[9]),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -548,15 +546,13 @@ EncryptionKey::KeyData KeyGen3rdParty::GenerateKeyData(const EncryptionKey::Rand
|
||||||
for (std::size_t i = 0; i != t0.size(); ++i)
|
for (std::size_t i = 0; i != t0.size(); ++i)
|
||||||
t0[i] = keygen_sbox_3rd_party[rand[i]];
|
t0[i] = keygen_sbox_3rd_party[rand[i]];
|
||||||
|
|
||||||
auto& rol8 = Common::RotateLeft<u8>;
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
u8(t0[7] ^ (t0[6] + rol8(ans[0] ^ t0[0], t0[1]))),
|
u8(t0[7] ^ (t0[6] + std::rotl<u8>(ans[0] ^ t0[0], t0[1]))),
|
||||||
u8(t0[1] ^ (t0[3] + rol8(ans[1] ^ t0[4], t0[2]))),
|
u8(t0[1] ^ (t0[3] + std::rotl<u8>(ans[1] ^ t0[4], t0[2]))),
|
||||||
u8(t0[5] ^ (t0[4] + rol8(ans[2] ^ t0[2], t0[8]))),
|
u8(t0[5] ^ (t0[4] + std::rotl<u8>(ans[2] ^ t0[2], t0[8]))),
|
||||||
u8(t0[0] ^ (t0[7] + rol8(ans[3] ^ t0[6], t0[9]))),
|
u8(t0[0] ^ (t0[7] + std::rotl<u8>(ans[3] ^ t0[6], t0[9]))),
|
||||||
u8(t0[1] ^ (t0[8] + rol8(ans[4] ^ t0[5], t0[4]))),
|
u8(t0[1] ^ (t0[8] + std::rotl<u8>(ans[4] ^ t0[5], t0[4]))),
|
||||||
u8(t0[5] ^ (t0[8] + rol8(ans[5] ^ t0[9], t0[3]))),
|
u8(t0[5] ^ (t0[8] + std::rotl<u8>(ans[5] ^ t0[9], t0[3]))),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
#include "Core/PowerPC/Interpreter/Interpreter.h"
|
#include "Core/PowerPC/Interpreter/Interpreter.h"
|
||||||
|
|
||||||
|
#include <bit>
|
||||||
|
|
||||||
#include "Common/BitUtils.h"
|
#include "Common/BitUtils.h"
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "Common/Logging/Log.h"
|
#include "Common/Logging/Log.h"
|
||||||
|
@ -151,7 +153,7 @@ void Interpreter::xoris(UGeckoInstruction inst)
|
||||||
void Interpreter::rlwimix(UGeckoInstruction inst)
|
void Interpreter::rlwimix(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
const u32 mask = MakeRotationMask(inst.MB, inst.ME);
|
const u32 mask = MakeRotationMask(inst.MB, inst.ME);
|
||||||
rGPR[inst.RA] = (rGPR[inst.RA] & ~mask) | (Common::RotateLeft(rGPR[inst.RS], inst.SH) & mask);
|
rGPR[inst.RA] = (rGPR[inst.RA] & ~mask) | (std::rotl(rGPR[inst.RS], inst.SH) & mask);
|
||||||
|
|
||||||
if (inst.Rc)
|
if (inst.Rc)
|
||||||
Helper_UpdateCR0(rGPR[inst.RA]);
|
Helper_UpdateCR0(rGPR[inst.RA]);
|
||||||
|
@ -160,7 +162,7 @@ void Interpreter::rlwimix(UGeckoInstruction inst)
|
||||||
void Interpreter::rlwinmx(UGeckoInstruction inst)
|
void Interpreter::rlwinmx(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
const u32 mask = MakeRotationMask(inst.MB, inst.ME);
|
const u32 mask = MakeRotationMask(inst.MB, inst.ME);
|
||||||
rGPR[inst.RA] = Common::RotateLeft(rGPR[inst.RS], inst.SH) & mask;
|
rGPR[inst.RA] = std::rotl(rGPR[inst.RS], inst.SH) & mask;
|
||||||
|
|
||||||
if (inst.Rc)
|
if (inst.Rc)
|
||||||
Helper_UpdateCR0(rGPR[inst.RA]);
|
Helper_UpdateCR0(rGPR[inst.RA]);
|
||||||
|
@ -169,7 +171,7 @@ void Interpreter::rlwinmx(UGeckoInstruction inst)
|
||||||
void Interpreter::rlwnmx(UGeckoInstruction inst)
|
void Interpreter::rlwnmx(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
const u32 mask = MakeRotationMask(inst.MB, inst.ME);
|
const u32 mask = MakeRotationMask(inst.MB, inst.ME);
|
||||||
rGPR[inst.RA] = Common::RotateLeft(rGPR[inst.RS], rGPR[inst.RB] & 0x1F) & mask;
|
rGPR[inst.RA] = std::rotl(rGPR[inst.RS], rGPR[inst.RB] & 0x1F) & mask;
|
||||||
|
|
||||||
if (inst.Rc)
|
if (inst.Rc)
|
||||||
Helper_UpdateCR0(rGPR[inst.RA]);
|
Helper_UpdateCR0(rGPR[inst.RA]);
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "Core/PowerPC/Jit64/Jit.h"
|
#include "Core/PowerPC/Jit64/Jit.h"
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <bit>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -2005,7 +2006,7 @@ void Jit64::rlwinmx(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
u32 result = gpr.Imm32(s);
|
u32 result = gpr.Imm32(s);
|
||||||
if (inst.SH != 0)
|
if (inst.SH != 0)
|
||||||
result = Common::RotateLeft(result, inst.SH);
|
result = std::rotl(result, inst.SH);
|
||||||
result &= MakeRotationMask(inst.MB, inst.ME);
|
result &= MakeRotationMask(inst.MB, inst.ME);
|
||||||
gpr.SetImmediate32(a, result);
|
gpr.SetImmediate32(a, result);
|
||||||
if (inst.Rc)
|
if (inst.Rc)
|
||||||
|
@ -2017,7 +2018,7 @@ void Jit64::rlwinmx(UGeckoInstruction inst)
|
||||||
const bool right_shift = inst.SH && inst.ME == 31 && inst.MB == 32 - inst.SH;
|
const bool right_shift = inst.SH && inst.ME == 31 && inst.MB == 32 - inst.SH;
|
||||||
const bool field_extract = inst.SH && inst.ME == 31 && inst.MB > 32 - inst.SH;
|
const bool field_extract = inst.SH && inst.ME == 31 && inst.MB > 32 - inst.SH;
|
||||||
const u32 mask = MakeRotationMask(inst.MB, inst.ME);
|
const u32 mask = MakeRotationMask(inst.MB, inst.ME);
|
||||||
const u32 prerotate_mask = Common::RotateRight(mask, inst.SH);
|
const u32 prerotate_mask = std::rotr(mask, inst.SH);
|
||||||
const bool simple_mask = mask == 0xff || mask == 0xffff;
|
const bool simple_mask = mask == 0xff || mask == 0xffff;
|
||||||
const bool simple_prerotate_mask = prerotate_mask == 0xff || prerotate_mask == 0xffff;
|
const bool simple_prerotate_mask = prerotate_mask == 0xff || prerotate_mask == 0xffff;
|
||||||
// In case of a merged branch, track whether or not we've set flags.
|
// In case of a merged branch, track whether or not we've set flags.
|
||||||
|
@ -2106,14 +2107,13 @@ void Jit64::rlwimix(UGeckoInstruction inst)
|
||||||
|
|
||||||
if (gpr.IsImm(a, s))
|
if (gpr.IsImm(a, s))
|
||||||
{
|
{
|
||||||
gpr.SetImmediate32(a,
|
gpr.SetImmediate32(a, (gpr.Imm32(a) & ~mask) | (std::rotl(gpr.Imm32(s), inst.SH) & mask));
|
||||||
(gpr.Imm32(a) & ~mask) | (Common::RotateLeft(gpr.Imm32(s), inst.SH) & mask));
|
|
||||||
if (inst.Rc)
|
if (inst.Rc)
|
||||||
ComputeRC(a);
|
ComputeRC(a);
|
||||||
}
|
}
|
||||||
else if (gpr.IsImm(s) && mask == 0xFFFFFFFF)
|
else if (gpr.IsImm(s) && mask == 0xFFFFFFFF)
|
||||||
{
|
{
|
||||||
gpr.SetImmediate32(a, Common::RotateLeft(gpr.Imm32(s), inst.SH));
|
gpr.SetImmediate32(a, std::rotl(gpr.Imm32(s), inst.SH));
|
||||||
|
|
||||||
if (inst.Rc)
|
if (inst.Rc)
|
||||||
ComputeRC(a);
|
ComputeRC(a);
|
||||||
|
@ -2141,7 +2141,7 @@ void Jit64::rlwimix(UGeckoInstruction inst)
|
||||||
RCX64Reg Ra = gpr.Bind(a, RCMode::ReadWrite);
|
RCX64Reg Ra = gpr.Bind(a, RCMode::ReadWrite);
|
||||||
RegCache::Realize(Ra);
|
RegCache::Realize(Ra);
|
||||||
AndWithMask(Ra, ~mask);
|
AndWithMask(Ra, ~mask);
|
||||||
OR(32, Ra, Imm32(Common::RotateLeft(gpr.Imm32(s), inst.SH) & mask));
|
OR(32, Ra, Imm32(std::rotl(gpr.Imm32(s), inst.SH) & mask));
|
||||||
}
|
}
|
||||||
else if (gpr.IsImm(a))
|
else if (gpr.IsImm(a))
|
||||||
{
|
{
|
||||||
|
@ -2244,7 +2244,7 @@ void Jit64::rlwnmx(UGeckoInstruction inst)
|
||||||
const u32 mask = MakeRotationMask(inst.MB, inst.ME);
|
const u32 mask = MakeRotationMask(inst.MB, inst.ME);
|
||||||
if (gpr.IsImm(b, s))
|
if (gpr.IsImm(b, s))
|
||||||
{
|
{
|
||||||
gpr.SetImmediate32(a, Common::RotateLeft(gpr.Imm32(s), gpr.Imm32(b) & 0x1F) & mask);
|
gpr.SetImmediate32(a, std::rotl(gpr.Imm32(s), gpr.Imm32(b) & 0x1F) & mask);
|
||||||
}
|
}
|
||||||
else if (gpr.IsImm(b))
|
else if (gpr.IsImm(b))
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
#include "Core/PowerPC/JitArm64/Jit.h"
|
#include "Core/PowerPC/JitArm64/Jit.h"
|
||||||
|
|
||||||
|
#include <bit>
|
||||||
|
|
||||||
#include "Common/Arm64Emitter.h"
|
#include "Common/Arm64Emitter.h"
|
||||||
#include "Common/Assert.h"
|
#include "Common/Assert.h"
|
||||||
#include "Common/BitUtils.h"
|
#include "Common/BitUtils.h"
|
||||||
|
@ -700,7 +702,7 @@ void JitArm64::rlwinmx(UGeckoInstruction inst)
|
||||||
const u32 mask = MakeRotationMask(inst.MB, inst.ME);
|
const u32 mask = MakeRotationMask(inst.MB, inst.ME);
|
||||||
if (gpr.IsImm(inst.RS))
|
if (gpr.IsImm(inst.RS))
|
||||||
{
|
{
|
||||||
gpr.SetImmediate(a, Common::RotateLeft(gpr.GetImm(s), inst.SH) & mask);
|
gpr.SetImmediate(a, std::rotl(gpr.GetImm(s), inst.SH) & mask);
|
||||||
if (inst.Rc)
|
if (inst.Rc)
|
||||||
ComputeRC0(gpr.GetImm(a));
|
ComputeRC0(gpr.GetImm(a));
|
||||||
return;
|
return;
|
||||||
|
@ -749,7 +751,7 @@ void JitArm64::rlwnmx(UGeckoInstruction inst)
|
||||||
|
|
||||||
if (gpr.IsImm(b) && gpr.IsImm(s))
|
if (gpr.IsImm(b) && gpr.IsImm(s))
|
||||||
{
|
{
|
||||||
gpr.SetImmediate(a, Common::RotateLeft(gpr.GetImm(s), gpr.GetImm(b) & 0x1F) & mask);
|
gpr.SetImmediate(a, std::rotl(gpr.GetImm(s), gpr.GetImm(b) & 0x1F) & mask);
|
||||||
if (inst.Rc)
|
if (inst.Rc)
|
||||||
ComputeRC0(gpr.GetImm(a));
|
ComputeRC0(gpr.GetImm(a));
|
||||||
}
|
}
|
||||||
|
@ -1924,7 +1926,7 @@ void JitArm64::rlwimix(UGeckoInstruction inst)
|
||||||
|
|
||||||
if (gpr.IsImm(a) && gpr.IsImm(s))
|
if (gpr.IsImm(a) && gpr.IsImm(s))
|
||||||
{
|
{
|
||||||
u32 res = (gpr.GetImm(a) & ~mask) | (Common::RotateLeft(gpr.GetImm(s), inst.SH) & mask);
|
u32 res = (gpr.GetImm(a) & ~mask) | (std::rotl(gpr.GetImm(s), inst.SH) & mask);
|
||||||
gpr.SetImmediate(a, res);
|
gpr.SetImmediate(a, res);
|
||||||
if (inst.Rc)
|
if (inst.Rc)
|
||||||
ComputeRC0(res);
|
ComputeRC0(res);
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include "Core/PowerPC/MMU.h"
|
#include "Core/PowerPC/MMU.h"
|
||||||
|
|
||||||
|
#include <bit>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -267,8 +268,8 @@ static void WriteToHardware(Memory::MemoryManager& memory, u32 em_address, const
|
||||||
// Note that "word" means 32-bit, so paired singles or doubles might still be 32-bit aligned!
|
// Note that "word" means 32-bit, so paired singles or doubles might still be 32-bit aligned!
|
||||||
const u32 first_half_size = em_address_end_page - em_address;
|
const u32 first_half_size = em_address_end_page - em_address;
|
||||||
const u32 second_half_size = size - first_half_size;
|
const u32 second_half_size = size - first_half_size;
|
||||||
WriteToHardware<flag, never_translate>(
|
WriteToHardware<flag, never_translate>(memory, em_address,
|
||||||
memory, em_address, Common::RotateRight(data, second_half_size * 8), first_half_size);
|
std::rotr(data, second_half_size * 8), first_half_size);
|
||||||
WriteToHardware<flag, never_translate>(memory, em_address_end_page, data, second_half_size);
|
WriteToHardware<flag, never_translate>(memory, em_address_end_page, data, second_half_size);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -353,7 +354,7 @@ static void WriteToHardware(Memory::MemoryManager& memory, u32 em_address, const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const u32 swapped_data = Common::swap32(Common::RotateRight(data, size * 8));
|
const u32 swapped_data = Common::swap32(std::rotr(data, size * 8));
|
||||||
|
|
||||||
// Locked L1 technically doesn't have a fixed address, but games all use 0xE0000000.
|
// Locked L1 technically doesn't have a fixed address, but games all use 0xE0000000.
|
||||||
if (memory.GetL1Cache() && (em_address >> 28 == 0xE) &&
|
if (memory.GetL1Cache() && (em_address >> 28 == 0xE) &&
|
||||||
|
@ -376,7 +377,7 @@ static void WriteToHardware(Memory::MemoryManager& memory, u32 em_address, const
|
||||||
// (https://github.com/dolphin-emu/hwtests/pull/42)
|
// (https://github.com/dolphin-emu/hwtests/pull/42)
|
||||||
ProcessorInterface::SetInterrupt(ProcessorInterface::INT_CAUSE_PI);
|
ProcessorInterface::SetInterrupt(ProcessorInterface::INT_CAUSE_PI);
|
||||||
|
|
||||||
const u32 rotated_data = Common::RotateRight(data, ((em_address & 0x3) + size) * 8);
|
const u32 rotated_data = std::rotr(data, ((em_address & 0x3) + size) * 8);
|
||||||
|
|
||||||
for (u32 addr = em_address & ~0x7; addr < em_address + size; addr += 8)
|
for (u32 addr = em_address & ~0x7; addr < em_address + size; addr += 8)
|
||||||
{
|
{
|
||||||
|
|
|
@ -57,44 +57,6 @@ TEST(BitUtils, ExtractBits)
|
||||||
EXPECT_EQ((Common::ExtractBits<0, 31, s32, s32>(negative_one)), -1);
|
EXPECT_EQ((Common::ExtractBits<0, 31, s32, s32>(negative_one)), -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(BitUtils, RotateLeft)
|
|
||||||
{
|
|
||||||
EXPECT_EQ(Common::RotateLeft(0xF0F0F0F0, 0), 0xF0F0F0F0U);
|
|
||||||
EXPECT_EQ(Common::RotateLeft(0xF0F0F0F0, 4), 0x0F0F0F0FU);
|
|
||||||
EXPECT_EQ(Common::RotateLeft(0xF0F0F0F0, 8), 0xF0F0F0F0U);
|
|
||||||
EXPECT_EQ(Common::RotateLeft(0xF0F0F0F0F0F0F0F0, 0), 0xF0F0F0F0F0F0F0F0U);
|
|
||||||
EXPECT_EQ(Common::RotateLeft(0xF0F0F0F0F0F0F0F0, 4), 0x0F0F0F0F0F0F0F0FU);
|
|
||||||
EXPECT_EQ(Common::RotateLeft(0xF0F0F0F0F0F0F0F0, 8), 0xF0F0F0F0F0F0F0F0U);
|
|
||||||
|
|
||||||
EXPECT_EQ(Common::RotateLeft(0xF1F1F1F1, 1), 0xE3E3E3E3U);
|
|
||||||
EXPECT_EQ(Common::RotateLeft(0xF1F1F1F1, 2), 0xC7C7C7C7U);
|
|
||||||
EXPECT_EQ(Common::RotateLeft(0xF1F1F1F1, 3), 0x8F8F8F8FU);
|
|
||||||
EXPECT_EQ(Common::RotateLeft(0xF1F1F1F1, 4), 0x1F1F1F1FU);
|
|
||||||
EXPECT_EQ(Common::RotateLeft(0xF1F1F1F1F1F1F1F1, 1), 0xE3E3E3E3E3E3E3E3U);
|
|
||||||
EXPECT_EQ(Common::RotateLeft(0xF1F1F1F1F1F1F1F1, 2), 0xC7C7C7C7C7C7C7C7U);
|
|
||||||
EXPECT_EQ(Common::RotateLeft(0xF1F1F1F1F1F1F1F1, 3), 0x8F8F8F8F8F8F8F8FU);
|
|
||||||
EXPECT_EQ(Common::RotateLeft(0xF1F1F1F1F1F1F1F1, 4), 0x1F1F1F1F1F1F1F1FU);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(BitUtils, RotateRight)
|
|
||||||
{
|
|
||||||
EXPECT_EQ(Common::RotateRight(0xF0F0F0F0, 0), 0xF0F0F0F0U);
|
|
||||||
EXPECT_EQ(Common::RotateRight(0xF0F0F0F0, 4), 0x0F0F0F0FU);
|
|
||||||
EXPECT_EQ(Common::RotateRight(0xF0F0F0F0, 8), 0xF0F0F0F0U);
|
|
||||||
EXPECT_EQ(Common::RotateRight(0xF0F0F0F0F0F0F0F0, 0), 0xF0F0F0F0F0F0F0F0U);
|
|
||||||
EXPECT_EQ(Common::RotateRight(0xF0F0F0F0F0F0F0F0, 4), 0x0F0F0F0F0F0F0F0FU);
|
|
||||||
EXPECT_EQ(Common::RotateRight(0xF0F0F0F0F0F0F0F0, 8), 0xF0F0F0F0F0F0F0F0U);
|
|
||||||
|
|
||||||
EXPECT_EQ(Common::RotateRight(0xF1F1F1F1, 1), 0xF8F8F8F8U);
|
|
||||||
EXPECT_EQ(Common::RotateRight(0xF1F1F1F1, 2), 0x7C7C7C7CU);
|
|
||||||
EXPECT_EQ(Common::RotateRight(0xF1F1F1F1, 3), 0x3E3E3E3EU);
|
|
||||||
EXPECT_EQ(Common::RotateRight(0xF1F1F1F1, 4), 0x1F1F1F1FU);
|
|
||||||
EXPECT_EQ(Common::RotateRight(0xF1F1F1F1F1F1F1F1, 1), 0xF8F8F8F8F8F8F8F8U);
|
|
||||||
EXPECT_EQ(Common::RotateRight(0xF1F1F1F1F1F1F1F1, 2), 0x7C7C7C7C7C7C7C7CU);
|
|
||||||
EXPECT_EQ(Common::RotateRight(0xF1F1F1F1F1F1F1F1, 3), 0x3E3E3E3E3E3E3E3EU);
|
|
||||||
EXPECT_EQ(Common::RotateRight(0xF1F1F1F1F1F1F1F1, 4), 0x1F1F1F1F1F1F1F1FU);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(BitUtils, IsValidLowMask)
|
TEST(BitUtils, IsValidLowMask)
|
||||||
{
|
{
|
||||||
EXPECT_TRUE(Common::IsValidLowMask(0b0u));
|
EXPECT_TRUE(Common::IsValidLowMask(0b0u));
|
||||||
|
|
Loading…
Reference in New Issue