From 2a3a07121640cfa7fb286f0e7eb7e149c0dfabef Mon Sep 17 00:00:00 2001 From: jdp_ <42700985+jdpatdiscord@users.noreply.github.com> Date: Mon, 28 Aug 2023 14:01:15 -0400 Subject: [PATCH] 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 --- src/CRC32.cpp | 23 +++--- src/CRC32.h | 2 + src/DSi.cpp | 64 +++++++-------- src/DSi_AES.cpp | 27 +++---- src/DSi_AES.h | 20 ++++- src/DSi_NAND.cpp | 65 +++++++--------- src/FreeBIOS.h | 2 - src/NDS.cpp | 7 +- src/NDSCart.cpp | 4 +- src/ROMList.cpp | 2 +- src/ROMList.h | 2 +- src/Wifi.cpp | 2 - src/dolphin/BitSet.h | 116 +++++++++++++++------------- src/frontend/qt_sdl/RAMInfoDialog.h | 2 +- src/frontend/qt_sdl/main.cpp | 4 + src/frontend/qt_sdl/main.h | 2 +- src/sha1/sha1.c | 4 +- src/sha1/sha1.h | 2 +- 18 files changed, 177 insertions(+), 173 deletions(-) diff --git a/src/CRC32.cpp b/src/CRC32.cpp index 1d0deb9b..4dec9595 100644 --- a/src/CRC32.cpp +++ b/src/CRC32.cpp @@ -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 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); } diff --git a/src/CRC32.h b/src/CRC32.h index 5bb5637c..133cf51d 100644 --- a/src/CRC32.h +++ b/src/CRC32.h @@ -19,6 +19,8 @@ #ifndef CRC32_H #define CRC32_H +#include + #include "types.h" u32 CRC32(const u8* data, int len, u32 start=0); diff --git a/src/DSi.cpp b/src/DSi.cpp index 2f92a5df..dc066a76 100644 --- a/src/DSi.cpp +++ b/src/DSi.cpp @@ -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; } } diff --git a/src/DSi_AES.cpp b/src/DSi_AES.cpp index eca778ab..5b1fc539 100644 --- a/src/DSi_AES.cpp +++ b/src/DSi_AES.cpp @@ -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) { diff --git a/src/DSi_AES.h b/src/DSi_AES.h index d8ef98a4..9baf747e 100644 --- a/src/DSi_AES.h +++ b/src/DSi_AES.h @@ -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); } diff --git a/src/DSi_NAND.cpp b/src/DSi_NAND.cpp index 38f8c52b..21da7ed3 100644 --- a/src/DSi_NAND.cpp +++ b/src/DSi_NAND.cpp @@ -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]; diff --git a/src/FreeBIOS.h b/src/FreeBIOS.h index 965d43b7..20c99b04 100644 --- a/src/FreeBIOS.h +++ b/src/FreeBIOS.h @@ -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 diff --git a/src/NDS.cpp b/src/NDS.cpp index b329c10c..2f1759fa 100644 --- a/src/NDS.cpp +++ b/src/NDS.cpp @@ -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 diff --git a/src/NDSCart.cpp b/src/NDSCart.cpp index cda0bf4c..f1598eb2 100644 --- a/src/NDSCart.cpp +++ b/src/NDSCart.cpp @@ -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; } diff --git a/src/ROMList.cpp b/src/ROMList.cpp index 5f7d95a2..725190aa 100644 --- a/src/ROMList.cpp +++ b/src/ROMList.cpp @@ -6800,4 +6800,4 @@ const ROMListEntry ROMList[] = {0x5A5A5242, 0x04000000, 0x00000003}, }; -const size_t ROMListSize = sizeof(ROMList) / sizeof(ROMListEntry); \ No newline at end of file +const size_t ROMListEntryCount = sizeof(ROMList) / sizeof(ROMListEntry); \ No newline at end of file diff --git a/src/ROMList.h b/src/ROMList.h index 82bd4693..c1bce154 100644 --- a/src/ROMList.h +++ b/src/ROMList.h @@ -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 diff --git a/src/Wifi.cpp b/src/Wifi.cpp index 298ba9dd..fa05a651 100644 --- a/src/Wifi.cpp +++ b/src/Wifi.cpp @@ -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; diff --git a/src/dolphin/BitSet.h b/src/dolphin/BitSet.h index d32b020e..09cc1ce6 100644 --- a/src/dolphin/BitSet.h +++ b/src/dolphin/BitSet.h @@ -3,86 +3,98 @@ #pragma once #include +#include #include #include #include "../types.h" -#ifdef _WIN32 - -#include - namespace Common { -template -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 +// 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); } diff --git a/src/frontend/qt_sdl/RAMInfoDialog.h b/src/frontend/qt_sdl/RAMInfoDialog.h index f44ae93d..33afd988 100644 --- a/src/frontend/qt_sdl/RAMInfoDialog.h +++ b/src/frontend/qt_sdl/RAMInfoDialog.h @@ -142,7 +142,7 @@ public: void Stop(); private: - void run(); + virtual void run() override; RAMInfoDialog* Dialog; bool SearchRunning = false; diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 12a99067..7f0c0ef8 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -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; } } diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index 44283a92..073a4da0 100644 --- a/src/frontend/qt_sdl/main.h +++ b/src/frontend/qt_sdl/main.h @@ -354,7 +354,7 @@ private slots: void onScreenEmphasisToggled(); private: - void closeEvent(QCloseEvent* event); + virtual void closeEvent(QCloseEvent* event) override; QStringList currentROM; QStringList currentGBAROM; diff --git a/src/sha1/sha1.c b/src/sha1/sha1.c index 3729550f..c0052b70 100644 --- a/src/sha1/sha1.c +++ b/src/sha1/sha1.c @@ -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; } diff --git a/src/sha1/sha1.h b/src/sha1/sha1.h index 56ffa566..dd8f84a6 100644 --- a/src/sha1/sha1.h +++ b/src/sha1/sha1.h @@ -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);