Reduce code stink (#1818)

CRC32.cpp:
Make table initialization compile time

DSi_NAND.cpp:
Fix file close / unmount / disk close on error
~L427: Remove redundant calls, as they are immediately rendered useless by `rem` being overwritten

NDS.cpp / FreeBIOS.h:
Remove unneeded size values in header
Remove unneeded memset's as they are initialized anyway

sha1.c / sha1.h:
Fix useless warning

Wifi.cpp:
Remove unneeded includes

DSi.cpp:
Reduce ugly casts
Deduplicate code

qt_sdl/main.cpp:
silence clang switch statement warning

qt_sdl/main.h:
fix override warnings

dolphin/BitSet.h:
use msvc extensions only when appropriate, fix broken bit set count under _WIN32
This commit is contained in:
jdp_ 2023-08-28 14:01:15 -04:00 committed by GitHub
parent b4aa7fafc9
commit 2a3a071216
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 177 additions and 173 deletions

View File

@ -20,10 +20,7 @@
// http://www.codeproject.com/KB/recipes/crc32_large.aspx
u32 crctable[256];
bool tableinited = false;
u32 _reflect(u32 refl, char ch)
constexpr u32 _reflect(u32 refl, char ch)
{
u32 value = 0;
@ -37,33 +34,31 @@ u32 _reflect(u32 refl, char ch)
return value;
}
void _inittable()
constexpr auto GetCRC32Table()
{
std::array<u32, 256> Crc32Table { 0 };
u32 polynomial = 0x04C11DB7;
for (int i = 0; i < 0x100; i++)
{
crctable[i] = _reflect(i, 8) << 24;
Crc32Table[i] = _reflect(i, 8) << 24;
for (int j = 0; j < 8; j++)
crctable[i] = (crctable[i] << 1) ^ (crctable[i] & (1 << 31) ? polynomial : 0);
Crc32Table[i] = (Crc32Table[i] << 1) ^ (Crc32Table[i] & (1 << 31) ? polynomial : 0);
crctable[i] = _reflect(crctable[i], 32);
Crc32Table[i] = _reflect(Crc32Table[i], 32);
}
return Crc32Table;
}
u32 CRC32(const u8 *data, int len, u32 start)
{
if (!tableinited)
{
_inittable();
tableinited = true;
}
auto Crc32Table = GetCRC32Table();
u32 crc = start ^ 0xFFFFFFFF;
while (len--)
crc = (crc >> 8) ^ crctable[(crc & 0xFF) ^ *data++];
crc = (crc >> 8) ^ Crc32Table[(crc & 0xFF) ^ *data++];
return (crc ^ 0xFFFFFFFF);
}

View File

@ -19,6 +19,8 @@
#ifndef CRC32_H
#define CRC32_H
#include <array>
#include "types.h"
u32 CRC32(const u8* data, int len, u32 start=0);

View File

@ -55,8 +55,8 @@ u32 SCFG_EXT[2];
u32 SCFG_MC;
u16 SCFG_RST;
u8 ARM9iBIOS[0x10000];
u8 ARM7iBIOS[0x10000];
u8 ARM9iBIOS[0x10000] = { 0 };
u8 ARM7iBIOS[0x10000] = { 0 };
u32 MBK[2][9];
@ -324,8 +324,8 @@ void DecryptModcryptArea(u32 offset, u32 size, u8* iv)
DSi_AES::DeriveNormalKey(keyX, keyY, tmp);
}
DSi_AES::Swap16(key, tmp);
DSi_AES::Swap16(tmp, iv);
Bswap128(key, tmp);
Bswap128(tmp, iv);
AES_init_ctx_iv(&ctx, key, tmp);
// find a matching binary area
@ -367,21 +367,21 @@ void DecryptModcryptArea(u32 offset, u32 size, u8* iv)
for (u32 i = 0; i < size; i+=16)
{
u8 data[16];
u32 data[4];
*(u32*)&data[0] = ARM9Read32(binaryaddr+i);
*(u32*)&data[4] = ARM9Read32(binaryaddr+i+4);
*(u32*)&data[8] = ARM9Read32(binaryaddr+i+8);
*(u32*)&data[12] = ARM9Read32(binaryaddr+i+12);
data[0] = ARM9Read32(binaryaddr+i);
data[1] = ARM9Read32(binaryaddr+i+4);
data[2] = ARM9Read32(binaryaddr+i+8);
data[3] = ARM9Read32(binaryaddr+i+12);
DSi_AES::Swap16(tmp, data);
AES_CTR_xcrypt_buffer(&ctx, tmp, 16);
DSi_AES::Swap16(data, tmp);
Bswap128(tmp, data);
AES_CTR_xcrypt_buffer(&ctx, tmp, sizeof(tmp));
Bswap128(data, tmp);
ARM9Write32(binaryaddr+i, *(u32*)&data[0]);
ARM9Write32(binaryaddr+i+4, *(u32*)&data[4]);
ARM9Write32(binaryaddr+i+8, *(u32*)&data[8]);
ARM9Write32(binaryaddr+i+12, *(u32*)&data[12]);
ARM9Write32(binaryaddr+i, data[0]);
ARM9Write32(binaryaddr+i+4, data[1]);
ARM9Write32(binaryaddr+i+8, data[2]);
ARM9Write32(binaryaddr+i+12, data[3]);
}
}
@ -893,7 +893,7 @@ bool LoadNAND()
*(u32*)&tmp[4] = -bootparams[3];
*(u32*)&tmp[8] = ~bootparams[3];
*(u32*)&tmp[12] = 0;
for (int i = 0; i < 16; i++) boot2iv[i] = tmp[15-i];
Bswap128(boot2iv, tmp);
AES_init_ctx_iv(&ctx, boot2key, boot2iv);
@ -901,24 +901,24 @@ bool LoadNAND()
dstaddr = bootparams[2];
for (u32 i = 0; i < bootparams[3]; i += 16)
{
u8 data[16];
u32 data[4];
FileRead(data, 16, 1, nand);
for (int j = 0; j < 16; j++) tmp[j] = data[15-j];
Bswap128(tmp, data);
AES_CTR_xcrypt_buffer(&ctx, tmp, 16);
for (int j = 0; j < 16; j++) data[j] = tmp[15-j];
Bswap128(data, tmp);
ARM9Write32(dstaddr, *(u32*)&data[0]); dstaddr += 4;
ARM9Write32(dstaddr, *(u32*)&data[4]); dstaddr += 4;
ARM9Write32(dstaddr, *(u32*)&data[8]); dstaddr += 4;
ARM9Write32(dstaddr, *(u32*)&data[12]); dstaddr += 4;
ARM9Write32(dstaddr, data[0]); dstaddr += 4;
ARM9Write32(dstaddr, data[1]); dstaddr += 4;
ARM9Write32(dstaddr, data[2]); dstaddr += 4;
ARM9Write32(dstaddr, data[3]); dstaddr += 4;
}
*(u32*)&tmp[0] = bootparams[7];
*(u32*)&tmp[4] = -bootparams[7];
*(u32*)&tmp[8] = ~bootparams[7];
*(u32*)&tmp[12] = 0;
for (int i = 0; i < 16; i++) boot2iv[i] = tmp[15-i];
Bswap128(boot2iv, tmp);
AES_init_ctx_iv(&ctx, boot2key, boot2iv);
@ -926,17 +926,17 @@ bool LoadNAND()
dstaddr = bootparams[6];
for (u32 i = 0; i < bootparams[7]; i += 16)
{
u8 data[16];
u32 data[4];
FileRead(data, 16, 1, nand);
for (int j = 0; j < 16; j++) tmp[j] = data[15-j];
Bswap128(tmp, data);
AES_CTR_xcrypt_buffer(&ctx, tmp, 16);
for (int j = 0; j < 16; j++) data[j] = tmp[15-j];
Bswap128(data, tmp);
ARM7Write32(dstaddr, *(u32*)&data[0]); dstaddr += 4;
ARM7Write32(dstaddr, *(u32*)&data[4]); dstaddr += 4;
ARM7Write32(dstaddr, *(u32*)&data[8]); dstaddr += 4;
ARM7Write32(dstaddr, *(u32*)&data[12]); dstaddr += 4;
ARM7Write32(dstaddr, data[0]); dstaddr += 4;
ARM7Write32(dstaddr, data[1]); dstaddr += 4;
ARM7Write32(dstaddr, data[2]); dstaddr += 4;
ARM7Write32(dstaddr, data[3]); dstaddr += 4;
}
}

View File

@ -61,13 +61,6 @@ bool OutputMACDue;
AES_ctx Ctx;
void Swap16(u8* dst, u8* src)
{
for (int i = 0; i < 16; i++)
dst[i] = src[15-i];
}
void ROL16(u8* val, u32 n)
{
u32 n_coarse = n >> 3;
@ -205,7 +198,7 @@ void ProcessBlock_CCM_Extra()
*(u32*)&data[8] = InputFIFO.Read();
*(u32*)&data[12] = InputFIFO.Read();
Swap16(data_rev, data);
Bswap128(data_rev, data);
for (int i = 0; i < 16; i++) CurMAC[i] ^= data_rev[i];
AES_ECB_encrypt(&Ctx, CurMAC);
@ -223,13 +216,13 @@ void ProcessBlock_CCM_Decrypt()
//printf("AES-CCM: "); _printhex2(data, 16);
Swap16(data_rev, data);
Bswap128(data_rev, data);
AES_CTR_xcrypt_buffer(&Ctx, data_rev, 16);
for (int i = 0; i < 16; i++) CurMAC[i] ^= data_rev[i];
AES_ECB_encrypt(&Ctx, CurMAC);
Swap16(data, data_rev);
Bswap128(data, data_rev);
//printf(" -> "); _printhex2(data, 16);
@ -251,13 +244,13 @@ void ProcessBlock_CCM_Encrypt()
//printf("AES-CCM: "); _printhex2(data, 16);
Swap16(data_rev, data);
Bswap128(data_rev, data);
for (int i = 0; i < 16; i++) CurMAC[i] ^= data_rev[i];
AES_CTR_xcrypt_buffer(&Ctx, data_rev, 16);
AES_ECB_encrypt(&Ctx, CurMAC);
Swap16(data, data_rev);
Bswap128(data, data_rev);
//printf(" -> "); _printhex2(data, 16);
@ -279,9 +272,9 @@ void ProcessBlock_CTR()
//printf("AES-CTR: "); _printhex2(data, 16);
Swap16(data_rev, data);
Bswap128(data_rev, data);
AES_CTR_xcrypt_buffer(&Ctx, data_rev, 16);
Swap16(data, data_rev);
Bswap128(data, data_rev);
//printf(" -> "); _printhex(data, 16);
@ -341,8 +334,8 @@ void WriteCnt(u32 val)
u8 key[16];
u8 iv[16];
Swap16(key, CurKey);
Swap16(iv, IV);
Bswap128(key, CurKey);
Bswap128(iv, IV);
if (AESMode < 2)
{
@ -510,7 +503,7 @@ void Update()
Ctx.Iv[15] = 0x00;
AES_CTR_xcrypt_buffer(&Ctx, CurMAC, 16);
Swap16(OutputMAC, CurMAC);
Bswap128(OutputMAC, CurMAC);
if (OutputFIFO.Level() <= 12)
{

View File

@ -22,6 +22,25 @@
#include "types.h"
#include "Savestate.h"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wattributes"
#if defined(__GNUC__) && (__GNUC__ >= 11) // gcc 11.*
// NOTE: Yes, the compiler does *not* recognize this code pattern, so it is indeed an optimization.
__attribute((always_inline)) static void Bswap128(void* Dst, void* Src)
{
*(__int128*)&Dst = __builtin_bswap128(*(__int128*)&Src);
}
#else
__attribute((always_inline)) static void Bswap128(void* Dst, void* Src)
{
for (int i = 0; i < 16; ++i)
{
((char*)Src)[i] = ((char*)Src)[15 - i];
}
}
#endif
#pragma GCC diagnostic pop
namespace DSi_AES
{
@ -49,7 +68,6 @@ void WriteKeyNormal(u32 slot, u32 offset, u32 val, u32 mask);
void WriteKeyX(u32 slot, u32 offset, u32 val, u32 mask);
void WriteKeyY(u32 slot, u32 offset, u32 val, u32 mask);
void Swap16(u8* dst, u8* src);
void DeriveNormalKey(u8* keyX, u8* keyY, u8* normalkey);
}

View File

@ -124,6 +124,9 @@ bool Init(u8* es_keyY)
if (memcmp(nand_footer, nand_footer_ref, 16))
{
Log(LogLevel::Error, "ERROR: NAND missing nocash footer\n");
CloseFile(nandfile);
f_unmount("0:");
ff_disk_close();
return false;
}
}
@ -141,7 +144,7 @@ bool Init(u8* es_keyY)
SHA1Update(&sha, eMMC_CID, 16);
SHA1Final(tmp, &sha);
DSi_AES::Swap16(FATIV, tmp);
Bswap128(FATIV, tmp);
*(u32*)&keyX[0] = (u32)ConsoleID;
*(u32*)&keyX[4] = (u32)ConsoleID ^ 0x24EE6906;
@ -154,7 +157,7 @@ bool Init(u8* es_keyY)
*(u32*)&keyY[12] = 0xE1A00005;
DSi_AES::DeriveNormalKey(keyX, keyY, tmp);
DSi_AES::Swap16(FATKey, tmp);
Bswap128(FATKey, tmp);
*(u32*)&keyX[0] = 0x4E00004A;
@ -165,7 +168,7 @@ bool Init(u8* es_keyY)
memcpy(keyY, es_keyY, 16);
DSi_AES::DeriveNormalKey(keyX, keyY, tmp);
DSi_AES::Swap16(ESKey, tmp);
Bswap128(ESKey, tmp);
CurFile = nandfile;
return true;
@ -197,7 +200,7 @@ void GetIDs(u8* emmc_cid, u64& consoleid)
void SetupFATCrypto(AES_ctx* ctx, u32 ctr)
{
u8 iv[16];
memcpy(iv, FATIV, 16);
memcpy(iv, FATIV, sizeof(iv));
u32 res;
res = iv[15] + (ctr & 0xFF);
@ -232,9 +235,9 @@ u32 ReadFATBlock(u64 addr, u32 len, u8* buf)
for (u32 i = 0; i < len; i += 16)
{
u8 tmp[16];
DSi_AES::Swap16(tmp, &buf[i]);
AES_CTR_xcrypt_buffer(&ctx, tmp, 16);
DSi_AES::Swap16(&buf[i], tmp);
Bswap128(tmp, &buf[i]);
AES_CTR_xcrypt_buffer(&ctx, tmp, sizeof(tmp));
Bswap128(&buf[i], tmp);
}
return len;
@ -256,9 +259,9 @@ u32 WriteFATBlock(u64 addr, u32 len, u8* buf)
for (u32 i = 0; i < 0x200; i += 16)
{
u8 tmp[16];
DSi_AES::Swap16(tmp, &buf[s+i]);
AES_CTR_xcrypt_buffer(&ctx, tmp, 16);
DSi_AES::Swap16(&tempbuf[i], tmp);
Bswap128(tmp, &buf[s+i]);
AES_CTR_xcrypt_buffer(&ctx, tmp, sizeof(tmp));
Bswap128(&tempbuf[i], tmp);
}
u32 res = FileWrite(tempbuf, sizeof(tempbuf), 1, CurFile);
@ -320,13 +323,13 @@ bool ESEncrypt(u8* data, u32 len)
{
u8 tmp[16];
DSi_AES::Swap16(tmp, &data[i]);
Bswap128(tmp, &data[i]);
for (int i = 0; i < 16; i++) mac[i] ^= tmp[i];
AES_CTR_xcrypt_buffer(&ctx, tmp, 16);
AES_ECB_encrypt(&ctx, mac);
DSi_AES::Swap16(&data[i], tmp);
Bswap128(&data[i], tmp);
}
u32 remlen = len - coarselen;
@ -334,26 +337,21 @@ bool ESEncrypt(u8* data, u32 len)
{
u8 rem[16];
memset(rem, 0, 16);
for (int i = 0; i < remlen; i++)
rem[15-i] = data[coarselen+i];
Bswap128(rem, &data[coarselen]);
for (int i = 0; i < 16; i++) mac[i] ^= rem[i];
AES_CTR_xcrypt_buffer(&ctx, rem, 16);
AES_CTR_xcrypt_buffer(&ctx, rem, sizeof(rem));
AES_ECB_encrypt(&ctx, mac);
for (int i = 0; i < remlen; i++)
data[coarselen+i] = rem[15-i];
Bswap128(&data[coarselen], rem);
}
ctx.Iv[13] = 0x00;
ctx.Iv[14] = 0x00;
ctx.Iv[15] = 0x00;
AES_CTR_xcrypt_buffer(&ctx, mac, 16);
AES_CTR_xcrypt_buffer(&ctx, mac, sizeof(mac));
for (int i = 0; i < 16; i++)
data[len+i] = mac[15-i];
Bswap128(&data[len], mac);
u8 footer[16];
@ -369,7 +367,7 @@ bool ESEncrypt(u8* data, u32 len)
footer[0] = len & 0xFF;
AES_ctx_set_iv(&ctx, iv);
AES_CTR_xcrypt_buffer(&ctx, footer, 16);
AES_CTR_xcrypt_buffer(&ctx, footer, sizeof(footer));
data[len+0x10] = footer[15];
data[len+0x1D] = footer[2];
@ -407,13 +405,13 @@ bool ESDecrypt(u8* data, u32 len)
{
u8 tmp[16];
DSi_AES::Swap16(tmp, &data[i]);
Bswap128(tmp, &data[i]);
AES_CTR_xcrypt_buffer(&ctx, tmp, 16);
AES_CTR_xcrypt_buffer(&ctx, tmp, sizeof(tmp));
for (int i = 0; i < 16; i++) mac[i] ^= tmp[i];
AES_ECB_encrypt(&ctx, mac);
DSi_AES::Swap16(&data[i], tmp);
Bswap128(&data[i], tmp);
}
u32 remlen = len - coarselen;
@ -426,20 +424,14 @@ bool ESDecrypt(u8* data, u32 len)
iv[14] = (ivnum >> 8) & 0xFF;
iv[15] = ivnum & 0xFF;
memset(rem, 0, 16);
AES_ctx_set_iv(&ctx, iv);
AES_CTR_xcrypt_buffer(&ctx, rem, 16);
for (int i = 0; i < remlen; i++)
rem[15-i] = data[coarselen+i];
Bswap128(rem, &data[coarselen]);
AES_ctx_set_iv(&ctx, iv);
AES_CTR_xcrypt_buffer(&ctx, rem, 16);
for (int i = 0; i < 16; i++) mac[i] ^= rem[i];
AES_ECB_encrypt(&ctx, mac);
for (int i = 0; i < remlen; i++)
data[coarselen+i] = rem[15-i];
Bswap128(&data[coarselen], rem);
}
ctx.Iv[13] = 0x00;
@ -455,11 +447,10 @@ bool ESDecrypt(u8* data, u32 len)
for (int i = 0; i < 12; i++) iv[3+i] = data[len+0x1C-i];
iv[15] = 0x00;
for (int i = 0; i < 16; i++)
footer[15-i] = data[len+0x10+i];
Bswap128(footer, &data[len+0x10]);
AES_ctx_set_iv(&ctx, iv);
AES_CTR_xcrypt_buffer(&ctx, footer, 16);
AES_CTR_xcrypt_buffer(&ctx, footer, sizeof(footer));
data[len+0x10] = footer[15];
data[len+0x1D] = footer[2];

View File

@ -1396,7 +1396,6 @@ unsigned char bios_arm7_bin[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
};
unsigned int bios_arm7_bin_len = 16384;
unsigned char bios_arm9_bin[] = {
0x3e, 0x00, 0x00, 0xea, 0x3e, 0x00, 0x00, 0xea, 0x3e, 0x00, 0x00, 0xea,
@ -1742,6 +1741,5 @@ unsigned char bios_arm9_bin[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
};
unsigned int bios_arm9_bin_len = 4096;
#endif // FREEBIOS_H

View File

@ -518,9 +518,6 @@ void Reset()
RunningGame = false;
LastSysClockCycles = 0;
memset(ARM9BIOS, 0, 0x1000);
memset(ARM7BIOS, 0, 0x4000);
// DS BIOSes are always loaded, even in DSi mode
// we need them for DS-compatible mode
@ -562,8 +559,8 @@ void Reset()
}
else
{
memcpy(ARM9BIOS, bios_arm9_bin, bios_arm9_bin_len);
memcpy(ARM7BIOS, bios_arm7_bin, bios_arm7_bin_len);
memcpy(ARM9BIOS, bios_arm9_bin, sizeof(bios_arm9_bin));
memcpy(ARM7BIOS, bios_arm7_bin, sizeof(bios_arm7_bin));
}
#ifdef JIT_ENABLED

View File

@ -1539,7 +1539,7 @@ void DoSavestate(Savestate* file)
bool ReadROMParams(u32 gamecode, ROMListEntry* params)
{
u32 offset = 0;
u32 chk_size = ROMListSize >> 1;
u32 chk_size = ROMListEntryCount >> 1;
for (;;)
{
u32 key = 0;
@ -1568,7 +1568,7 @@ bool ReadROMParams(u32 gamecode, ROMListEntry* params)
chk_size >>= 1;
}
if (offset >= ROMListSize)
if (offset >= ROMListEntryCount)
{
return false;
}

View File

@ -6800,4 +6800,4 @@ const ROMListEntry ROMList[] =
{0x5A5A5242, 0x04000000, 0x00000003},
};
const size_t ROMListSize = sizeof(ROMList) / sizeof(ROMListEntry);
const size_t ROMListEntryCount = sizeof(ROMList) / sizeof(ROMListEntry);

View File

@ -34,6 +34,6 @@ struct ROMListEntry
extern const ROMListEntry ROMList[];
/// The number of elements in \c ROMList.
extern const size_t ROMListSize;
extern const size_t ROMListEntryCount;
#endif // ROMLIST_H

View File

@ -23,8 +23,6 @@
#include "Wifi.h"
#include "WifiAP.h"
#include "Platform.h"
#include "ARM.h"
#include "GPU.h"
using Platform::Log;
using Platform::LogLevel;

View File

@ -3,86 +3,98 @@
#pragma once
#include <cstddef>
#include <bitset>
#include <initializer_list>
#include <type_traits>
#include "../types.h"
#ifdef _WIN32
#include <intrin.h>
namespace Common
{
template <typename T>
constexpr int CountSetBits(T v)
{
// from https://graphics.stanford.edu/~seander/bithacks.html
// GCC has this built in, but MSVC's intrinsic will only emit the actual
// POPCNT instruction, which we're not depending on
v = v - ((v >> 1) & (T) ~(T)0 / 3);
v = (v & (T) ~(T)0 / 15 * 3) + ((v >> 2) & (T) ~(T)0 / 15 * 3);
v = (v + (v >> 4)) & (T) ~(T)0 / 255 * 15;
return (T)(v * ((T) ~(T)0 / 255)) >> (sizeof(T) - 1) * 8;
}
inline int LeastSignificantSetBit(u8 val)
{
unsigned long index;
_BitScanForward(&index, val);
return (int)index;
}
inline int LeastSignificantSetBit(u16 val)
{
unsigned long index;
_BitScanForward(&index, val);
return (int)index;
}
inline int LeastSignificantSetBit(u32 val)
{
unsigned long index;
_BitScanForward(&index, val);
return (int)index;
}
inline int LeastSignificantSetBit(u64 val)
{
unsigned long index;
_BitScanForward64(&index, val);
return (int)index;
}
#else
namespace Common
{
constexpr int CountSetBits(u8 val)
#if defined(__GNUC__) || defined(__clang__)
__attribute((always_inline)) static constexpr int CountSetBits(u8 val)
{
return __builtin_popcount(val);
}
constexpr int CountSetBits(u16 val)
__attribute((always_inline)) static constexpr int CountSetBits(u16 val)
{
return __builtin_popcount(val);
}
constexpr int CountSetBits(u32 val)
__attribute((always_inline)) static constexpr int CountSetBits(u32 val)
{
return __builtin_popcount(val);
}
constexpr int CountSetBits(u64 val)
__attribute((always_inline)) static constexpr int CountSetBits(u64 val)
{
return __builtin_popcountll(val);
}
inline int LeastSignificantSetBit(u8 val)
__attribute((always_inline)) static constexpr int LeastSignificantSetBit(u8 val)
{
return __builtin_ctz(val);
}
inline int LeastSignificantSetBit(u16 val)
__attribute((always_inline)) static constexpr int LeastSignificantSetBit(u16 val)
{
return __builtin_ctz(val);
}
inline int LeastSignificantSetBit(u32 val)
__attribute((always_inline)) static constexpr int LeastSignificantSetBit(u32 val)
{
return __builtin_ctz(val);
}
inline int LeastSignificantSetBit(u64 val)
__attribute((always_inline)) static constexpr int LeastSignificantSetBit(u64 val)
{
return __builtin_ctzll(val);
}
#elif defined(_MSC_VER)
#include <intrin.h>
// MSVC __popcnt doesn't switch between hardware availability like gcc does, can't use it, let C++ implementation handle it
__forceinline static int CountSetBits(u8 val)
{
return std::bitset<8>(val).count();
}
__forceinline static int CountSetBits(u16 val)
{
return std::bitset<16>(val).count();
}
__forceinline static int CountSetBits(u32 val)
{
return std::bitset<32>(val).count();
}
__forceinline static int CountSetBits(u64 val)
{
return std::bitset<64>(val).count();
}
__forceinline static int LeastSignificantSetBit(u8 val)
{
unsigned long count;
_BitScanForward(&count, val);
return count;
}
__forceinline static int LeastSignificantSetBit(u16 val)
{
unsigned long count;
_BitScanForward(&count, val);
return count;
}
__forceinline static int LeastSignificantSetBit(u32 val)
{
unsigned long count;
_BitScanForward(&count, val);
return count;
}
__forceinline static int LeastSignificantSetBit(u64 val)
{
#if defined(_WIN64)
unsigned long count;
_BitScanForward64(&count, val);
return count;
#else
unsigned long tmp;
_BitScanForward(&tmp, (u32)(val & 0x00000000FFFFFFFFull));
if (tmp)
return tmp;
_BitScanForward(&tmp, (u32)((val & 0xFFFFFFFF00000000ull) >> 32));
return tmp ? tmp + 32 : 0;
#endif
}
#endif
// Similar to std::bitset, this is a class which encapsulates a bitset, i.e.
@ -201,10 +213,6 @@ public:
BitSet& operator^=(BitSet other) { return *this = *this ^ other; }
BitSet& operator<<=(IntTy shift) { return *this = *this << shift; }
BitSet& operator>>=(IntTy shift) { return *this = *this >> shift; }
// Warning: Even though on modern CPUs this is a single fast instruction,
// Dolphin's official builds do not currently assume POPCNT support on x86,
// so slower explicit bit twiddling is generated. Still should generally
// be faster than a loop.
constexpr unsigned int Count() const { return CountSetBits(m_val); }
constexpr Iterator begin() const { return ++Iterator(m_val, 0); }
constexpr Iterator end() const { return Iterator(m_val, -1); }

View File

@ -142,7 +142,7 @@ public:
void Stop();
private:
void run();
virtual void run() override;
RAMInfoDialog* Dialog;
bool SearchRunning = false;

View File

@ -957,6 +957,8 @@ void ScreenHandler::screenHandleTablet(QTabletEvent* event)
touching = false;
}
break;
default:
break;
}
}
@ -988,6 +990,8 @@ void ScreenHandler::screenHandleTouch(QTouchEvent* event)
touching = false;
}
break;
default:
break;
}
}

View File

@ -354,7 +354,7 @@ private slots:
void onScreenEmphasisToggled();
private:
void closeEvent(QCloseEvent* event);
virtual void closeEvent(QCloseEvent* event) override;
QStringList currentROM;
QStringList currentGBAROM;

View File

@ -104,7 +104,7 @@ A million repetitions of "a"
/* Hash a single 512-bit block. This is the core of the algorithm. */
void SHA1Transform(uint32_t state[5], const unsigned char buffer[64])
void SHA1Transform(uint32_t state[5], const unsigned char* buffer)
{
uint32_t a, b, c, d, e;
typedef union {
@ -193,7 +193,7 @@ uint32_t j;
memcpy(&context->buffer[j], data, (i = 64-j));
SHA1Transform(context->state, context->buffer);
for ( ; i + 63 < len; i += 64) {
SHA1Transform(context->state, &data[i]);
SHA1Transform(context->state, data + i);
}
j = 0;
}

View File

@ -13,7 +13,7 @@ typedef struct {
unsigned char buffer[64];
} SHA1_CTX;
void SHA1Transform(uint32_t state[5], const unsigned char buffer[64]);
void SHA1Transform(uint32_t state[5], const unsigned char* buffer);
void SHA1Init(SHA1_CTX* context);
void SHA1Update(SHA1_CTX* context, const unsigned char* data, uint32_t len);
void SHA1Final(unsigned char digest[20], SHA1_CTX* context);