From 8962b9606b7896159e65685a7074c757fabdc177 Mon Sep 17 00:00:00 2001 From: comex Date: Wed, 9 Oct 2013 16:44:20 -0400 Subject: [PATCH] One shudders to imagine what inhuman thoughts lie behind that code. (Read_Opcode_JIT and Write_Opcode_JIT read/write from unrelated memory areas.* Rename the latter and refactor.) *except at the one specific exception handler where it doesn't. I have no idea what this is supposed to do, but it probably doesn't do it correctly. For now, remove the exception. --- Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp | 14 +---- Source/Core/Core/Src/PowerPC/Jit64/JitAsm.cpp | 5 +- .../Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp | 15 +---- .../Core/Src/PowerPC/Jit64IL/JitILAsm.cpp | 5 +- .../Core/Core/Src/PowerPC/JitCommon/JitBase.h | 2 - .../Core/Src/PowerPC/JitCommon/JitCache.cpp | 45 +++++---------- .../Core/Src/PowerPC/JitCommon/JitCache.h | 6 +- Source/Core/Core/Src/PowerPC/JitInterface.cpp | 57 +------------------ Source/Core/Core/Src/PowerPC/JitInterface.h | 2 - 9 files changed, 30 insertions(+), 121 deletions(-) diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp index e411823429..bb41ac9b7a 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp @@ -704,19 +704,9 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc // Remove the invalid instruction from the icache, forcing a recompile #ifdef _M_IX86 - if (js.compilerPC & JIT_ICACHE_VMEM_BIT) - MOV(32, M((jit->GetBlockCache()->iCacheVMEM + (js.compilerPC & JIT_ICACHE_MASK))), Imm32(JIT_ICACHE_INVALID_WORD)); - else if (js.compilerPC & JIT_ICACHE_EXRAM_BIT) - MOV(32, M((jit->GetBlockCache()->iCacheEx + (js.compilerPC & JIT_ICACHEEX_MASK))), Imm32(JIT_ICACHE_INVALID_WORD)); - else - MOV(32, M((jit->GetBlockCache()->iCache + (js.compilerPC & JIT_ICACHE_MASK))), Imm32(JIT_ICACHE_INVALID_WORD)); + MOV(32, M(jit->GetBlockCache()->GetICachePtr(js.compilerPC)), Imm32(JIT_ICACHE_INVALID_WORD)); #else - if (js.compilerPC & JIT_ICACHE_VMEM_BIT) - MOV(64, R(RAX), ImmPtr(jit->GetBlockCache()->iCacheVMEM + (js.compilerPC & JIT_ICACHE_MASK))); - else if (js.compilerPC & JIT_ICACHE_EXRAM_BIT) - MOV(64, R(RAX), ImmPtr(jit->GetBlockCache()->iCacheEx + (js.compilerPC & JIT_ICACHEEX_MASK))); - else - MOV(64, R(RAX), ImmPtr(jit->GetBlockCache()->iCache + (js.compilerPC & JIT_ICACHE_MASK))); + MOV(64, R(RAX), ImmPtr(jit->GetBlockCache()->GetICachePtr(js.compilerPC))); MOV(32,MatR(RAX),Imm32(JIT_ICACHE_INVALID_WORD)); #endif diff --git a/Source/Core/Core/Src/PowerPC/Jit64/JitAsm.cpp b/Source/Core/Core/Src/PowerPC/Jit64/JitAsm.cpp index 1be6b1318e..103ab8346b 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/JitAsm.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/JitAsm.cpp @@ -142,9 +142,8 @@ void Jit64AsmRoutineManager::Generate() if (Core::g_CoreStartupParameter.bWii && (Core::g_CoreStartupParameter.bMMU || Core::g_CoreStartupParameter.bTLBHack)) SetJumpTarget(exit_vmem); - TEST(32, R(EAX), Imm32(0xFC)); - FixupBranch notfound = J_CC(CC_NZ); - BSWAP(32, EAX); + TEST(32, R(EAX), R(EAX)); + FixupBranch notfound = J_CC(CC_L); //IDEA - we have 26 bits, why not just use offsets from base of code? if (enableDebug) { diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp index a81d1308be..f92607658b 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp @@ -1764,20 +1764,9 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit) { // Remove the invalid instruction from the icache, forcing a recompile #ifdef _M_IX86 - if (InstLoc & JIT_ICACHE_VMEM_BIT) - Jit->MOV(32, M((jit->GetBlockCache()->iCacheVMEM + (InstLoc & JIT_ICACHE_MASK))), Imm32(JIT_ICACHE_INVALID_WORD)); - else if (InstLoc & JIT_ICACHE_EXRAM_BIT) - Jit->MOV(32, M((jit->GetBlockCache()->iCacheEx + (InstLoc & JIT_ICACHEEX_MASK))), Imm32(JIT_ICACHE_INVALID_WORD)); - else - Jit->MOV(32, M((jit->GetBlockCache()->iCache + (InstLoc & JIT_ICACHE_MASK))), Imm32(JIT_ICACHE_INVALID_WORD)); - + Jit->MOV(32, M(jit->GetBlockCache()->GetICachePtr(InstLoc)), Imm32(JIT_ICACHE_INVALID_WORD)); #else - if (InstLoc & JIT_ICACHE_VMEM_BIT) - Jit->MOV(64, R(RAX), ImmPtr(jit->GetBlockCache()->iCacheVMEM + (InstLoc & JIT_ICACHE_MASK))); - else if (InstLoc & JIT_ICACHE_EXRAM_BIT) - Jit->MOV(64, R(RAX), ImmPtr(jit->GetBlockCache()->iCacheEx + (InstLoc & JIT_ICACHEEX_MASK))); - else - Jit->MOV(64, R(RAX), ImmPtr(jit->GetBlockCache()->iCache + (InstLoc & JIT_ICACHE_MASK))); + Jit->MOV(64, R(RAX), ImmPtr(jit->GetBlockCache()->GetICachePtr(InstLoc))); Jit->MOV(32, MatR(RAX), Imm32(JIT_ICACHE_INVALID_WORD)); #endif Jit->WriteExceptionExit(); diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/JitILAsm.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/JitILAsm.cpp index 3fcafa2b83..b833b06747 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/JitILAsm.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/JitILAsm.cpp @@ -143,9 +143,8 @@ void JitILAsmRoutineManager::Generate() if (Core::g_CoreStartupParameter.bWii && (Core::g_CoreStartupParameter.bMMU || Core::g_CoreStartupParameter.bTLBHack)) SetJumpTarget(exit_vmem); - TEST(32, R(EAX), Imm32(0xFC)); - FixupBranch notfound = J_CC(CC_NZ); - BSWAP(32, EAX); + TEST(32, R(EAX), R(EAX)); + FixupBranch notfound = J_CC(CC_L); //IDEA - we have 26 bits, why not just use offsets from base of code? if (enableDebug) { diff --git a/Source/Core/Core/Src/PowerPC/JitCommon/JitBase.h b/Source/Core/Core/Src/PowerPC/JitCommon/JitBase.h index a5f7bd62be..0260cf35b6 100644 --- a/Source/Core/Core/Src/PowerPC/JitCommon/JitBase.h +++ b/Source/Core/Core/Src/PowerPC/JitCommon/JitBase.h @@ -17,8 +17,6 @@ #include -#define JIT_OPCODE 0 - class JitBase : public CPUCoreBase { protected: diff --git a/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp b/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp index 7962fe847d..8cf9b309d3 100644 --- a/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp +++ b/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp @@ -198,7 +198,8 @@ bool JitBlock::ContainsAddress(u32 em_address) { blockCodePointers[block_num] = code_ptr; JitBlock &b = blocks[block_num]; - JitInterface::Write_Opcode_JIT(b.originalAddress, (JIT_OPCODE << 26) | block_num); + u32* icp = GetICachePtr(b.originalAddress); + *icp = block_num; // Convert the logical address to a physical address for the block map u32 pAddr = b.originalAddress & 0x1FFFFFFF; @@ -247,24 +248,22 @@ bool JitBlock::ContainsAddress(u32 em_address) return blockCodePointers; } + u32* JitBaseBlockCache::GetICachePtr(u32 addr) + { + if (addr & JIT_ICACHE_VMEM_BIT) + return (u32*)(jit->GetBlockCache()->iCacheVMEM + (addr & JIT_ICACHE_MASK)); + else if (addr & JIT_ICACHE_EXRAM_BIT) + return (u32*)(jit->GetBlockCache()->iCacheEx + (addr & JIT_ICACHEEX_MASK)); + else + return (u32*)(jit->GetBlockCache()->iCache + (addr & JIT_ICACHE_MASK)); + } + int JitBaseBlockCache::GetBlockNumberFromStartAddress(u32 addr) { if (!blocks) return -1; u32 inst; - if (addr & JIT_ICACHE_VMEM_BIT) - { - inst = *(u32*)(iCacheVMEM + (addr & JIT_ICACHE_MASK)); - } - else if (addr & JIT_ICACHE_EXRAM_BIT) - { - inst = *(u32*)(iCacheEx + (addr & JIT_ICACHEEX_MASK)); - } - else - { - inst = *(u32*)(iCache + (addr & JIT_ICACHE_MASK)); - } - inst = Common::swap32(inst); + inst = *GetICachePtr(addr); if (inst & 0xfc000000) // definitely not a JIT block return -1; if ((int)inst >= num_blocks) @@ -364,7 +363,7 @@ bool JitBlock::ContainsAddress(u32 em_address) return; } b.invalid = true; - JitInterface::Write_Opcode_JIT(b.originalAddress, JIT_ICACHE_INVALID_WORD); + *GetICachePtr(b.originalAddress) = JIT_ICACHE_INVALID_WORD; UnlinkBlock(block_num); @@ -397,21 +396,7 @@ bool JitBlock::ContainsAddress(u32 em_address) while (it2 != block_map.end() && it2->first.second < pAddr + length) { JitBlock &b = blocks[it2->second]; - if (b.originalAddress & JIT_ICACHE_VMEM_BIT) - { - u32 cacheaddr = b.originalAddress & JIT_ICACHE_MASK; - memset(iCacheVMEM + cacheaddr, JIT_ICACHE_INVALID_BYTE, 4); - } - else if (b.originalAddress & JIT_ICACHE_EXRAM_BIT) - { - u32 cacheaddr = b.originalAddress & JIT_ICACHEEX_MASK; - memset(iCacheEx + cacheaddr, JIT_ICACHE_INVALID_BYTE, 4); - } - else - { - u32 cacheaddr = b.originalAddress & JIT_ICACHE_MASK; - memset(iCache + cacheaddr, JIT_ICACHE_INVALID_BYTE, 4); - } + *GetICachePtr(b.originalAddress) = JIT_ICACHE_INVALID_WORD; DestroyBlock(it2->second, true); it2++; } diff --git a/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.h b/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.h index 2e50dc7a66..d5c980a20c 100644 --- a/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.h +++ b/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.h @@ -27,8 +27,8 @@ #define JIT_ICACHE_EXRAM_BIT 0x10000000 #define JIT_ICACHE_VMEM_BIT 0x20000000 // this corresponds to opcode 5 which is invalid in PowerPC -#define JIT_ICACHE_INVALID_BYTE 0x14 -#define JIT_ICACHE_INVALID_WORD 0x14141414 +#define JIT_ICACHE_INVALID_BYTE 0x80 +#define JIT_ICACHE_INVALID_WORD 0x80808080 struct JitBlock { @@ -110,6 +110,8 @@ public: u8 *iCacheEx; u8 *iCacheVMEM; + u32* GetICachePtr(u32 addr); + // Fast way to get a block. Only works on the first ppc instruction of a block. int GetBlockNumberFromStartAddress(u32 em_address); diff --git a/Source/Core/Core/Src/PowerPC/JitInterface.cpp b/Source/Core/Core/Src/PowerPC/JitInterface.cpp index 283637a842..568de59a6f 100644 --- a/Source/Core/Core/Src/PowerPC/JitInterface.cpp +++ b/Source/Core/Core/Src/PowerPC/JitInterface.cpp @@ -209,41 +209,6 @@ namespace JitInterface jit->GetBlockCache()->InvalidateICache(address, size); } - - // Memory functions - u32 Read_Opcode_JIT_Uncached(const u32 _Address) - { - u8* iCache; - u32 addr; - if (_Address & JIT_ICACHE_VMEM_BIT) - { - iCache = jit->GetBlockCache()->iCacheVMEM; - addr = _Address & JIT_ICACHE_MASK; - } - else if (_Address & JIT_ICACHE_EXRAM_BIT) - { - iCache = jit->GetBlockCache()->iCacheEx; - addr = _Address & JIT_ICACHEEX_MASK; - } - else - { - iCache = jit->GetBlockCache()->iCache; - addr = _Address & JIT_ICACHE_MASK; - } - u32 inst = *(u32*)(iCache + addr); - if (inst == JIT_ICACHE_INVALID_WORD) - { - u32 cache_block_start = addr & ~0x1f; - u32 mem_block_start = _Address & ~0x1f; - u8 *pMem = Memory::GetPointer(mem_block_start); - memcpy(iCache + cache_block_start, pMem, 32); - inst = *(u32*)(iCache + addr); - } - inst = Common::swap32(inst); - - return inst; - } - u32 Read_Opcode_JIT(u32 _Address) { #ifdef FAST_ICACHE @@ -255,11 +220,12 @@ namespace JitInterface return 0; } } - u32 inst = 0; + u32 inst; // Bypass the icache for the external interrupt exception handler + // -- this is stupid, should respect HID0 if ( (_Address & 0x0FFFFF00) == 0x00000500 ) - inst = Read_Opcode_JIT_Uncached(_Address); + inst = Memory::ReadUnchecked_U32(_Address); else inst = PowerPC::ppcState.iCache.ReadInstruction(_Address); #else @@ -267,23 +233,6 @@ namespace JitInterface #endif return inst; } - - // WARNING! No checks! - // We assume that _Address is cached - void Write_Opcode_JIT(const u32 _Address, const u32 _Value) - { - if (_Address & JIT_ICACHE_VMEM_BIT) - { - *(u32*)(jit->GetBlockCache()->iCacheVMEM + (_Address & JIT_ICACHE_MASK)) = Common::swap32(_Value); - } - else if (_Address & JIT_ICACHE_EXRAM_BIT) - { - *(u32*)(jit->GetBlockCache()->iCacheEx + (_Address & JIT_ICACHEEX_MASK)) = Common::swap32(_Value); - } - else - *(u32*)(jit->GetBlockCache()->iCache + (_Address & JIT_ICACHE_MASK)) = Common::swap32(_Value); - } - void Shutdown() { diff --git a/Source/Core/Core/Src/PowerPC/JitInterface.h b/Source/Core/Core/Src/PowerPC/JitInterface.h index 31d0a60c21..81764b3182 100644 --- a/Source/Core/Core/Src/PowerPC/JitInterface.h +++ b/Source/Core/Core/Src/PowerPC/JitInterface.h @@ -22,8 +22,6 @@ namespace JitInterface // used by JIT to read instructions u32 Read_Opcode_JIT(const u32 _Address); - // used by JIT. uses iCacheJIT. Reads in the "Locked cache" mode - void Write_Opcode_JIT(const u32 _Address, const u32 _Value); // Clearing CodeCache void ClearCache();