From 297b19214c527678eca4b0f38a84832e52d4b242 Mon Sep 17 00:00:00 2001 From: aliaspider Date: Fri, 2 Oct 2020 21:13:29 +0100 Subject: [PATCH] Swap.h: add parameter pack templates to automatically cast swap_t<> values to their basic types when passed as parameters to *_LOG calls. plus some refactors. --- Common/Serialize/SerializeFuncs.h | 2 +- Common/Swap.h | 139 ++++++++++++++--------------- Core/FileSystems/BlockDevices.cpp | 2 +- Core/FileSystems/ISOFileSystem.cpp | 2 +- Core/HLE/ReplaceTables.cpp | 2 +- Core/HLE/proAdhoc.h | 2 +- Core/HLE/sceAtrac.cpp | 2 +- Core/HLE/sceAudiocodec.cpp | 2 +- Core/HLE/sceMp3.cpp | 4 +- Core/HLE/sceNetAdhoc.cpp | 3 +- Core/HLE/scePsmf.cpp | 4 +- Core/HW/SimpleAudioDec.cpp | 2 +- Core/MIPS/MIPSIntVFPU.cpp | 4 +- Core/Screenshot.cpp | 8 +- 14 files changed, 87 insertions(+), 91 deletions(-) diff --git a/Common/Serialize/SerializeFuncs.h b/Common/Serialize/SerializeFuncs.h index e1c893cf2ab5..86dff2feed02 100644 --- a/Common/Serialize/SerializeFuncs.h +++ b/Common/Serialize/SerializeFuncs.h @@ -35,7 +35,7 @@ void Do(PointerWrap &p, tm &t); // Which also can be a problem, for example struct tm is non-POD on linux, for whatever reason... #ifdef _MSC_VER template::value, bool isPointer = std::is_pointer::value> -#elif defined (COMMON_BIG_ENDIAN) // treat swapped types as pod. +#elif defined (__BIG_ENDIAN__) // treat swapped types as pod. template::value> #else template::value> diff --git a/Common/Swap.h b/Common/Swap.h index 8727e1234a9a..2f06321472e7 100644 --- a/Common/Swap.h +++ b/Common/Swap.h @@ -21,81 +21,27 @@ #include #include +#include "base/basictypes.h" #include "Common/CommonTypes.h" +#include "Common/Log.h" -// Android -#if defined(__ANDROID__) -#include - -#if _BYTE_ORDER == _LITTLE_ENDIAN && !defined(COMMON_LITTLE_ENDIAN) -#define COMMON_LITTLE_ENDIAN 1 -#elif _BYTE_ORDER == _BIG_ENDIAN && !defined(COMMON_BIG_ENDIAN) -#define COMMON_BIG_ENDIAN 1 -#endif - -// GCC 4.6+ -#elif __GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) - -#if __BYTE_ORDER__ && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) && !defined(COMMON_LITTLE_ENDIAN) -#define COMMON_LITTLE_ENDIAN 1 -#elif __BYTE_ORDER__ && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) && !defined(COMMON_BIG_ENDIAN) -#define COMMON_BIG_ENDIAN 1 -#endif - -// LLVM/clang -#elif __clang__ - -#if __LITTLE_ENDIAN__ && !defined(COMMON_LITTLE_ENDIAN) -#define COMMON_LITTLE_ENDIAN 1 -#elif __BIG_ENDIAN__ && !defined(COMMON_BIG_ENDIAN) -#define COMMON_BIG_ENDIAN 1 +#if !defined(__BIG_ENDIAN__) && defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) +#define __BIG_ENDIAN__ 1 #endif -// MSVC -#elif defined(_MSC_VER) && !defined(COMMON_BIG_ENDIAN) && !defined(COMMON_LITTLE_ENDIAN) - -#define COMMON_LITTLE_ENDIAN 1 - -#endif - -// Worst case, default to little endian. -#if !COMMON_BIG_ENDIAN && !COMMON_LITTLE_ENDIAN -#define COMMON_LITTLE_ENDIAN 1 -#endif - -#ifdef _MSC_VER -inline unsigned long long bswap64(unsigned long long x) { return _byteswap_uint64(x); } -inline unsigned int bswap32(unsigned int x) { return _byteswap_ulong(x); } -inline unsigned short bswap16(unsigned short x) { return _byteswap_ushort(x); } -#elif defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) -#include -#ifdef __OpenBSD__ -#define bswap16 swap16 -#define bswap32 swap32 -#define bswap64 swap64 -#endif -#elif defined(__GNUC__) -#define bswap16 __builtin_bswap16 -#define bswap32 __builtin_bswap32 -#define bswap64 __builtin_bswap64 -#else -// TODO: speedup -inline unsigned short bswap16(unsigned short x) { return (x << 8) | (x >> 8); } -inline unsigned int bswap32(unsigned int x) { return (x >> 24) | ((x & 0xFF0000) >> 8) | ((x & 0xFF00) << 8) | (x << 24); } -inline unsigned long long bswap64(unsigned long long x) { return ((unsigned long long)bswap32(x) << 32) | bswap32(x >> 32); } +#if !defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__) +#define __LITTLE_ENDIAN__ 1 #endif template struct swap_t { static_assert(std::is_scalar::value && (sizeof(T) > 1), "swap_t used with an invalid type"); private: - T swapped; - static T swap(T val) { switch (sizeof(T)) { - case 2: *(u16 *)&val = bswap16(*(u16 *)&val); break; - case 4: *(u32 *)&val = bswap32(*(u32 *)&val); break; - case 8: *(u64 *)&val = bswap64(*(u64 *)&val); break; + case 2: *(u16 *)&val = swap16(*(u16 *)&val); break; + case 4: *(u32 *)&val = swap32(*(u32 *)&val); break; + case 8: *(u64 *)&val = swap64(*(u64 *)&val); break; default: break; } return val; @@ -133,9 +79,12 @@ template struct swap_t { } operator T() const { return swap(swapped); } + +private: + T swapped; }; -#if COMMON_LITTLE_ENDIAN +#ifdef __LITTLE_ENDIAN__ template using LEndian = T; template using BEndian = swap_t; #else @@ -165,20 +114,66 @@ typedef BEndian s64_be; typedef BEndian float_be; typedef BEndian double_be; -template static inline void endian_convert(swap_t *dst, const T *src, size_t count) { +template +static inline void ToLEndian(BEndian *ptr, size_t count) { for (int i = 0; i < count; i++) { - dst[i] = src[i]; + ((LEndian*)ptr)[i] = ptr[i]; } } -template static inline void endian_convert(T *dst, const swap_t *src, size_t count) { +template +static inline void ToLEndian(LEndian *ptr, size_t count) { + return; +} + +template +static inline void ToBEndian(LEndian *ptr, size_t count) { for (int i = 0; i < count; i++) { - dst[i] = src[i]; + ((BEndian*)ptr)[i] = ptr[i]; } } -template static inline void endian_convert(T *dst, const T *src, size_t count) { - if (src == dst) - return; - memcpy(dst, src, count * sizeof(T)); +template +static inline void ToBEndian(BEndian *ptr, size_t count) { + return; +} + +template +static inline void GenericLog(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, const char *file, int line, const char *fmt, swap_t v, Targs... args) { + GenericLog(level, type, file, line, fmt, (T)v, args...); +} + +template +static inline void GenericLog(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, const char *file, int line, const char *fmt, T0 v0, swap_t v, Targs... args) { + GenericLog(level, type, file, line, fmt, v0, (T)v, args...); +} + +template +static inline void GenericLog(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, const char *file, int line, const char *fmt, T0 v0, T1 v1, swap_t v, Targs... args) { + GenericLog(level, type, file, line, fmt, v0, v1, (T)v, args...); +} + +template +static inline void GenericLog(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, const char *file, int line, const char *fmt, T0 v0, T1 v1, T2 v2, swap_t v, Targs... args) { + GenericLog(level, type, file, line, fmt, v0, v1, v2, (T)v, args...); +} + +template +static inline void GenericLog(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, const char *file, int line, const char *fmt, T0 v0, T1 v1, T2 v2, T3 v3, swap_t v, Targs... args) { + GenericLog(level, type, file, line, fmt, v0, v1, v2, v3, (T)v, args...); +} + +template +static inline void GenericLog(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, const char *file, int line, const char *fmt, T0 v0, T1 v1, T2 v2, T3 v3, T4 v4, swap_t v, Targs... args) { + GenericLog(level, type, file, line, fmt, v0, v1, v2, v3, v4, (T)v, args...); +} + +template +static inline void GenericLog(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, const char *file, int line, const char *fmt, T0 v0, T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, swap_t v, Targs... args) { + GenericLog(level, type, file, line, fmt, v0, v1, v2, v3, v4, v5, (T)v, args...); +} + +template +static inline void GenericLog(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, const char *file, int line, const char *fmt, T0 v0, T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, swap_t v, Targs... args) { + GenericLog(level, type, file, line, fmt, v0, v1, v2, v3, v4, v5, v6, (T)v, args...); } diff --git a/Core/FileSystems/BlockDevices.cpp b/Core/FileSystems/BlockDevices.cpp index 983a8e7958aa..2059c94ba0eb 100644 --- a/Core/FileSystems/BlockDevices.cpp +++ b/Core/FileSystems/BlockDevices.cpp @@ -169,7 +169,7 @@ CISOFileBlockDevice::CISOFileBlockDevice(FileLoader *fileLoader) const u32 indexSize = numFrames + 1; const size_t headerEnd = hdr.ver > 1 ? (size_t)hdr.header_size : sizeof(hdr); -#if COMMON_LITTLE_ENDIAN +#if __LITTLE_ENDIAN__ index = new u32[indexSize]; if (fileLoader->ReadAt(headerEnd, sizeof(u32), indexSize, index) != indexSize) { NotifyReadError(); diff --git a/Core/FileSystems/ISOFileSystem.cpp b/Core/FileSystems/ISOFileSystem.cpp index b6c91e4b6a3c..6469f310187b 100644 --- a/Core/FileSystems/ISOFileSystem.cpp +++ b/Core/FileSystems/ISOFileSystem.cpp @@ -85,7 +85,7 @@ struct DirectoryEntry { u8 identifierLength; //identifier comes right after u8 firstIdChar; -#if COMMON_LITTLE_ENDIAN +#if __LITTLE_ENDIAN__ u32 firstDataSector() const { return firstDataSectorLE; diff --git a/Core/HLE/ReplaceTables.cpp b/Core/HLE/ReplaceTables.cpp index 0ba0a2bb8c15..918088701a21 100644 --- a/Core/HLE/ReplaceTables.cpp +++ b/Core/HLE/ReplaceTables.cpp @@ -406,7 +406,7 @@ static int Replace_fabsf() { } static int Replace_vmmul_q_transp() { -#ifdef COMMON_BIG_ENDIAN +#ifdef __BIG_ENDIAN__ Crash(); // TODO #endif float *out = (float *)Memory::GetPointer(PARAM(0)); diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index 65f0b883ebfa..c7ff22a20c30 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -41,7 +41,7 @@ #ifdef _MSC_VER #define PACK // on MSVC we use #pragma pack() instead so let's kill this. -#elif defined(COMMON_BIG_ENDIAN) +#elif defined(__BIG_ENDIAN__) // packed cannot be used with non-POD *_le types. // TODO: find a real solution for the couple of structs that actually need this #define PACK diff --git a/Core/HLE/sceAtrac.cpp b/Core/HLE/sceAtrac.cpp index 8f801b201f93..7c4965fbf708 100644 --- a/Core/HLE/sceAtrac.cpp +++ b/Core/HLE/sceAtrac.cpp @@ -1227,7 +1227,7 @@ u32 _AtracDecodeData(int atracID, u8 *outbuf, u32 outbufPtr, u32 *SamplesNum, u3 if (avret < 0) { ERROR_LOG(ME, "swr_convert: Error while converting %d", avret); } else { - endian_convert((s16_le*)out, (s16*)out, avret * atrac->outputChannels_); + ToLEndian((s16*)out, avret * atrac->outputChannels_); } } #endif // USE_FFMPEG diff --git a/Core/HLE/sceAudiocodec.cpp b/Core/HLE/sceAudiocodec.cpp index 974c28258815..ea7de2ab13f1 100644 --- a/Core/HLE/sceAudiocodec.cpp +++ b/Core/HLE/sceAudiocodec.cpp @@ -118,7 +118,7 @@ static int sceAudiocodecDecode(u32 ctxPtr, int codec) { // Decode audio u8* outbuf = Memory::GetPointer(ctx->outDataPtr); decoder->Decode(Memory::GetPointer(ctx->inDataPtr), ctx->inDataSize, outbuf, &outbytes); - endian_convert((s16_le*)outbuf, (s16*)outbuf, outbytes / 2); + ToLEndian((s16*)outbuf, outbytes / 2); } DEBUG_LOG(ME, "sceAudiocodecDec(%08x, %i (%s))", ctxPtr, codec, GetCodecName(codec)); return 0; diff --git a/Core/HLE/sceMp3.cpp b/Core/HLE/sceMp3.cpp index 7f05c74a0b1c..7e47b8af72f2 100644 --- a/Core/HLE/sceMp3.cpp +++ b/Core/HLE/sceMp3.cpp @@ -367,7 +367,7 @@ static int FindMp3Header(AuCtx *ctx, int &header, int end) { for (int offset = 0; offset < end; ++offset) { // If we hit valid sync bits, then we've found a header. if (ptr[offset] == 0xFF && (ptr[offset + 1] & 0xC0) == 0xC0) { - header = bswap32(Memory::Read_U32(addr + offset)); + header = swap32(Memory::Read_U32(addr + offset)); return offset; } } @@ -685,7 +685,7 @@ static u32 sceMp3LowLevelDecode(u32 mp3, u32 sourceAddr, u32 sourceBytesConsumed int outpcmbytes = 0; ctx->decoder->Decode((void*)inbuff, 4096, outbuff, &outpcmbytes); - endian_convert((s16_le*)outbuff, (s16*)outbuff, outpcmbytes / 2); + ToLEndian((s16*)outbuff, outpcmbytes / 2); Memory::Write_U32(ctx->decoder->GetSourcePos(), sourceBytesConsumedAddr); Memory::Write_U32(outpcmbytes, sampleBytesAddr); diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 55adc4d50c4c..dc66ae10d0fb 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -4646,7 +4646,8 @@ void __NetMatchingCallbacks() //(int matchingId) if (params != matchingEvents.end()) { u32 args[6]; - endian_convert(args, (u32_le*)&(*params), 6); + for (int i = 0; i < 6; i++) + args[i] = params->data[i]; //auto context = findMatchingContext(args[0]); if (actionAfterMatchingMipsCall < 0) { diff --git a/Core/HLE/scePsmf.cpp b/Core/HLE/scePsmf.cpp index 0842a2977dac..2bdbca70e7fc 100644 --- a/Core/HLE/scePsmf.cpp +++ b/Core/HLE/scePsmf.cpp @@ -889,7 +889,7 @@ static u32 scePsmfQueryStreamOffset(u32 bufferAddr, u32 offsetAddr) { WARN_LOG(ME, "scePsmfQueryStreamOffset(%08x, %08x)", bufferAddr, offsetAddr); if (Memory::IsValidAddress(offsetAddr)) { - Memory::Write_U32(bswap32(Memory::Read_U32(bufferAddr + PSMF_STREAM_OFFSET_OFFSET)), offsetAddr); + Memory::Write_U32(swap32(Memory::Read_U32(bufferAddr + PSMF_STREAM_OFFSET_OFFSET)), offsetAddr); } return 0; } @@ -898,7 +898,7 @@ static u32 scePsmfQueryStreamSize(u32 bufferAddr, u32 sizeAddr) { WARN_LOG(ME, "scePsmfQueryStreamSize(%08x, %08x)", bufferAddr, sizeAddr); if (Memory::IsValidAddress(sizeAddr)) { - Memory::Write_U32(bswap32(Memory::Read_U32(bufferAddr + PSMF_STREAM_SIZE_OFFSET)), sizeAddr); + Memory::Write_U32(swap32(Memory::Read_U32(bufferAddr + PSMF_STREAM_SIZE_OFFSET)), sizeAddr); } return 0; } diff --git a/Core/HW/SimpleAudioDec.cpp b/Core/HW/SimpleAudioDec.cpp index 05842285a2f0..0c1908754f61 100644 --- a/Core/HW/SimpleAudioDec.cpp +++ b/Core/HW/SimpleAudioDec.cpp @@ -340,7 +340,7 @@ u32 AuCtx::AuDecode(u32 pcmAddr) { // FFmpeg doesn't seem to search for a sync for us, so let's do that. int nextSync = (int)FindNextMp3Sync(); decoder->Decode(&sourcebuff[nextSync], (int)sourcebuff.size() - nextSync, outbuf, &outpcmbufsize); - endian_convert((u16_le*)outbuf, (u16*)outbuf, outpcmbufsize / 2); + ToLEndian((u16*)outbuf, outpcmbufsize / 2); if (outpcmbufsize == 0) { // Nothing was output, hopefully we're at the end of the stream. diff --git a/Core/MIPS/MIPSIntVFPU.cpp b/Core/MIPS/MIPSIntVFPU.cpp index bc8d698c59a0..83953ef208cb 100644 --- a/Core/MIPS/MIPSIntVFPU.cpp +++ b/Core/MIPS/MIPSIntVFPU.cpp @@ -243,7 +243,7 @@ namespace MIPSInt { _dbg_assert_msg_( 0, "Misaligned lv.q at %08x (pc = %08x)", addr, PC); } -#ifndef COMMON_BIG_ENDIAN +#ifndef __BIG_ENDIAN__ WriteVector((const float*)Memory::GetPointer(addr), V_Quad, vt); #else float lvqd[4]; @@ -290,7 +290,7 @@ namespace MIPSInt { _dbg_assert_msg_( 0, "Misaligned sv.q at %08x (pc = %08x)", addr, PC); } -#ifndef COMMON_BIG_ENDIAN +#ifndef __BIG_ENDIAN__ ReadVector(reinterpret_cast(Memory::GetPointer(addr)), V_Quad, vt); #else float svqd[4]; diff --git a/Core/Screenshot.cpp b/Core/Screenshot.cpp index 7cf03ad35ded..5342d5525a42 100644 --- a/Core/Screenshot.cpp +++ b/Core/Screenshot.cpp @@ -133,7 +133,7 @@ static bool ConvertPixelTo8888RGBA(GPUDebugBufferFormat fmt, u8 &r, u8 &g, u8 &b case GPU_DBG_FORMAT_565: src = buf16[offset]; if (rev) { - src = bswap16(src); + src = swap16(src); } a = 255; r = Convert5To8((src >> 0) & 0x1F); @@ -143,7 +143,7 @@ static bool ConvertPixelTo8888RGBA(GPUDebugBufferFormat fmt, u8 &r, u8 &g, u8 &b case GPU_DBG_FORMAT_5551: src = buf16[offset]; if (rev) { - src = bswap16(src); + src = swap16(src); } a = (src >> 15) ? 255 : 0; r = Convert5To8((src >> 0) & 0x1F); @@ -153,7 +153,7 @@ static bool ConvertPixelTo8888RGBA(GPUDebugBufferFormat fmt, u8 &r, u8 &g, u8 &b case GPU_DBG_FORMAT_4444: src = buf16[offset]; if (rev) { - src = bswap16(src); + src = swap16(src); } a = Convert4To8((src >> 12) & 0xF); r = Convert4To8((src >> 0) & 0xF); @@ -163,7 +163,7 @@ static bool ConvertPixelTo8888RGBA(GPUDebugBufferFormat fmt, u8 &r, u8 &g, u8 &b case GPU_DBG_FORMAT_8888: src = buf32[offset]; if (rev) { - src = bswap32(src); + src = swap32(src); } a = (src >> 24) & 0xFF; r = (src >> 0) & 0xFF;