diff --git a/Source/Core/Common/Src/ABI.cpp b/Source/Core/Common/Src/ABI.cpp index 1976294f1e..08e021f083 100644 --- a/Source/Core/Common/Src/ABI.cpp +++ b/Source/Core/Common/Src/ABI.cpp @@ -124,6 +124,15 @@ void XEmitter::ABI_CallFunctionCCCP(void *func, u32 param1, u32 param2,u32 param ABI_RestoreStack(4 * 4); } +void XEmitter::ABI_CallFunctionPPC(void *func, void *param1, void *param2,u32 param3) { + ABI_AlignStack(3 * 4); + PUSH(32, Imm32(param3)); + PUSH(32, Imm32((u32)param2)); + PUSH(32, Imm32((u32)param1)); + CALL(func); + ABI_RestoreStack(3 * 4); +} + // Pass a register as a parameter. void XEmitter::ABI_CallFunctionR(void *func, X64Reg reg1) { ABI_AlignStack(1 * 4); @@ -326,6 +335,21 @@ void XEmitter::ABI_CallFunctionCCCP(void *func, u32 param1, u32 param2, u32 para } } +void XEmitter::ABI_CallFunctionPPC(void *func, void *param1, void *param2, u32 param3) { + MOV(64, R(ABI_PARAM1), Imm64((u64)param1)); + MOV(64, R(ABI_PARAM2), Imm64((u64)param2)); + MOV(32, R(ABI_PARAM3), Imm32(param3)); + u64 distance = u64(func) - (u64(code) + 5); + if (distance >= 0x0000000080000000ULL + && distance < 0xFFFFFFFF80000000ULL) { + // Far call + MOV(64, R(RAX), Imm64((u64)func)); + CALLptr(R(RAX)); + } else { + CALL(func); + } +} + // Pass a register as a parameter. void XEmitter::ABI_CallFunctionR(void *func, X64Reg reg1) { if (reg1 != ABI_PARAM1) diff --git a/Source/Core/Common/Src/MemoryUtil.cpp b/Source/Core/Common/Src/MemoryUtil.cpp index 0a5a64322a..45e3a4f3a0 100644 --- a/Source/Core/Common/Src/MemoryUtil.cpp +++ b/Source/Core/Common/Src/MemoryUtil.cpp @@ -74,18 +74,53 @@ void* AllocateMemoryPages(size_t size) return ptr; } -void FreeMemoryPages(void* ptr, size_t size) +void* AllocateAlignedMemory(size_t size,size_t alignment) { #ifdef _WIN32 + void* ptr = _aligned_malloc(size,alignment); +#else + void* ptr = NULL; + posix_memalign(&ptr, alignment, size); +; +#endif + + // printf("Mapped memory at %p (size %ld)\n", ptr, + // (unsigned long)size); + + if (ptr == NULL) + PanicAlert("Failed to allocate aligned memory"); + + return ptr; +} + +void FreeMemoryPages(void* ptr, size_t size) +{ if (ptr) { +#ifdef _WIN32 + if (!VirtualFree(ptr, 0, MEM_RELEASE)) PanicAlert("FreeMemoryPages failed!\n%s", GetLastErrorMsg()); ptr = NULL; // Is this our responsibility? - } + #else - munmap(ptr, size); + munmap(ptr, size); #endif + } +} + +void FreeAlignedMemory(void* ptr) +{ + if (ptr) + { +#ifdef _WIN32 + + _aligned_free(ptr); + +#else + free(ptr); +#endif + } } void WriteProtectMemory(void* ptr, size_t size, bool allowExecute) diff --git a/Source/Core/Common/Src/MemoryUtil.h b/Source/Core/Common/Src/MemoryUtil.h index 3736a8c4bb..9df44169c0 100644 --- a/Source/Core/Common/Src/MemoryUtil.h +++ b/Source/Core/Common/Src/MemoryUtil.h @@ -26,6 +26,8 @@ void* AllocateExecutableMemory(size_t size, bool low = true); void* AllocateMemoryPages(size_t size); void FreeMemoryPages(void* ptr, size_t size); +void* AllocateAlignedMemory(size_t size,size_t alignment); +void FreeAlignedMemory(void* ptr); void WriteProtectMemory(void* ptr, size_t size, bool executable = false); void UnWriteProtectMemory(void* ptr, size_t size, bool allowExecute = false); std::string MemUsage(); diff --git a/Source/Core/Common/Src/x64Emitter.h b/Source/Core/Common/Src/x64Emitter.h index d7decf0f38..2a506d42db 100644 --- a/Source/Core/Common/Src/x64Emitter.h +++ b/Source/Core/Common/Src/x64Emitter.h @@ -625,6 +625,7 @@ public: void ABI_CallFunctionCCC(void *func, u32 param1, u32 param2, u32 param3); void ABI_CallFunctionCCP(void *func, u32 param1, u32 param2, void *param3); void ABI_CallFunctionCCCP(void *func, u32 param1, u32 param2,u32 param3, void *param4); + void ABI_CallFunctionPPC(void *func, void *param1, void *param2,u32 param3); void ABI_CallFunctionAC(void *func, const Gen::OpArg &arg1, u32 param2); void ABI_CallFunctionA(void *func, const Gen::OpArg &arg1); diff --git a/Source/Core/VideoCommon/Src/Statistics.h b/Source/Core/VideoCommon/Src/Statistics.h index b102741753..7238398b42 100644 --- a/Source/Core/VideoCommon/Src/Statistics.h +++ b/Source/Core/VideoCommon/Src/Statistics.h @@ -90,6 +90,7 @@ extern Statistics stats; #ifdef STATISTICS #define INCSTAT(a) (a)++; +#define DECSTAT(a) (a)--; #define ADDSTAT(a,b) (a)+=(b); #define SETSTAT(a,x) (a)=(int)(x); #define SETSTAT_UINT(a,x) (a)=(u32)(x); diff --git a/Source/Core/VideoCommon/Src/TextureCacheBase.cpp b/Source/Core/VideoCommon/Src/TextureCacheBase.cpp index 47d2cf56c8..47525af3fa 100644 --- a/Source/Core/VideoCommon/Src/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/Src/TextureCacheBase.cpp @@ -23,7 +23,7 @@ enum TextureCache *g_texture_cache; -u8 *TextureCache::temp = NULL; + GC_ALIGNED16(u8 *TextureCache::temp) = NULL; TextureCache::TexCache TextureCache::textures; bool TextureCache::DeferredInvalidate; @@ -44,7 +44,7 @@ TextureCache::TCacheEntryBase::~TCacheEntryBase() TextureCache::TextureCache() { if (!temp) - temp = (u8*)AllocateMemoryPages(TEMP_SIZE); + temp =(u8*) AllocateAlignedMemory(TEMP_SIZE,16); TexDecoder_SetTexFmtOverlayOptions(g_ActiveConfig.bTexFmtOverlayEnable, g_ActiveConfig.bTexFmtOverlayCenter); if(g_ActiveConfig.bHiresTextures && !g_ActiveConfig.bDumpTextures) HiresTextures::Init(SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str()); @@ -81,7 +81,7 @@ TextureCache::~TextureCache() Invalidate(true); if (temp) { - FreeMemoryPages(temp, TEMP_SIZE); + FreeAlignedMemory(temp); temp = NULL; } } diff --git a/Source/Core/VideoCommon/Src/TextureCacheBase.h b/Source/Core/VideoCommon/Src/TextureCacheBase.h index c8cb25134e..0a57d0a486 100644 --- a/Source/Core/VideoCommon/Src/TextureCacheBase.h +++ b/Source/Core/VideoCommon/Src/TextureCacheBase.h @@ -95,7 +95,7 @@ public: protected: TextureCache(); - static u8 *temp; + static GC_ALIGNED16(u8 *temp); private: typedef std::map TexCache; diff --git a/Source/Core/VideoCommon/Src/TextureDecoder.cpp b/Source/Core/VideoCommon/Src/TextureDecoder.cpp index edfcc3bebc..5f75242496 100644 --- a/Source/Core/VideoCommon/Src/TextureDecoder.cpp +++ b/Source/Core/VideoCommon/Src/TextureDecoder.cpp @@ -44,7 +44,7 @@ extern const unsigned char sfont_raw[][9*10]; // TRAM // STATE_TO_SAVE -u8 texMem[TMEM_SIZE]; + GC_ALIGNED16(u8 texMem[TMEM_SIZE]); // Gamecube/Wii texture decoder diff --git a/Source/Core/VideoCommon/Src/TextureDecoder.h b/Source/Core/VideoCommon/Src/TextureDecoder.h index 15e19c4389..d990d21545 100644 --- a/Source/Core/VideoCommon/Src/TextureDecoder.h +++ b/Source/Core/VideoCommon/Src/TextureDecoder.h @@ -23,7 +23,7 @@ enum TMEM_SIZE = 1024*1024, HALFTMEM_SIZE = 512*1024 }; -extern u8 texMem[TMEM_SIZE]; +extern GC_ALIGNED16(u8 texMem[TMEM_SIZE]); enum TextureFormat {