diff --git a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_LoadStore.cpp b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_LoadStore.cpp index cad4761e55..10c8fc2e58 100644 --- a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_LoadStore.cpp +++ b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_LoadStore.cpp @@ -363,7 +363,7 @@ void Interpreter::dcbf(UGeckoInstruction _inst) { NPC = PC + 12; }*/ - // Invalidate the icache on dcbf + // Invalidate the jit block cache on dcbf if (jit) { u32 address = Helper_Get_EA_X(_inst); @@ -374,7 +374,7 @@ void Interpreter::dcbf(UGeckoInstruction _inst) void Interpreter::dcbi(UGeckoInstruction _inst) { // Removes a block from data cache. Since we don't emulate the data cache, we don't need to do anything to the data cache - // However, we invalidate the icache on dcbi + // However, we invalidate the jit block cache on dcbi if (jit) { u32 address = Helper_Get_EA_X(_inst); @@ -385,6 +385,12 @@ void Interpreter::dcbi(UGeckoInstruction _inst) void Interpreter::dcbst(UGeckoInstruction _inst) { // Cache line flush. Since we don't emulate the data cache, we don't need to do anything. + // Invalidate the jit block cache on dcbst in case new code has been loaded via the data cache + if (jit) + { + u32 address = Helper_Get_EA_X(_inst); + jit->GetBlockCache()->InvalidateICache(address & ~0x1f, 32); + } } void Interpreter::dcbt(UGeckoInstruction _inst) diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit64_Tables.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit64_Tables.cpp index 93963513ee..1c654a4a9a 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit64_Tables.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit64_Tables.cpp @@ -210,7 +210,7 @@ static GekkoOPTemplate table31[] = {824, &Jit64::srawix}, //"srawix", OPTYPE_INTEGER, FL_OUT_A | FL_IN_B | FL_IN_S | FL_RC_BIT}}, {24, &Jit64::slwx}, //"slwx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_B | FL_IN_S | FL_RC_BIT}}, - {54, &Jit64::DoNothing}, //"dcbst", OPTYPE_DCACHE, 0, 4}}, + {54, &Jit64::Default}, //"dcbst", OPTYPE_DCACHE, 0, 4}}, {86, &Jit64::Default}, //"dcbf", OPTYPE_DCACHE, 0, 4}}, {246, &Jit64::DoNothing}, //"dcbtst", OPTYPE_DCACHE, 0, 1}}, {278, &Jit64::DoNothing}, //"dcbt", OPTYPE_DCACHE, 0, 1}}, diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_Tables.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_Tables.cpp index 68e3e7493c..9b2e3ff466 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_Tables.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_Tables.cpp @@ -212,7 +212,7 @@ static GekkoOPTemplate table31[] = {824, &JitIL::srawix}, //"srawix", OPTYPE_INTEGER, FL_OUT_A | FL_IN_B | FL_IN_S | FL_RC_BIT}}, {24, &JitIL::slwx}, //"slwx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_B | FL_IN_S | FL_RC_BIT}}, - {54, &JitIL::DoNothing}, //"dcbst", OPTYPE_DCACHE, 0, 4}}, + {54, &JitIL::Default}, //"dcbst", OPTYPE_DCACHE, 0, 4}}, {86, &JitIL::Default}, //"dcbf", OPTYPE_DCACHE, 0, 4}}, {246, &JitIL::DoNothing}, //"dcbtst", OPTYPE_DCACHE, 0, 1}}, {278, &JitIL::DoNothing}, //"dcbt", OPTYPE_DCACHE, 0, 1}}, diff --git a/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp b/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp index 303945e965..0e06c1f762 100644 --- a/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp +++ b/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp @@ -208,23 +208,9 @@ bool JitBlock::ContainsAddress(u32 em_address) JitBlock &b = blocks[block_num]; b.originalFirstOpcode = Memory::Read_Opcode_JIT(b.originalAddress); Memory::Write_Opcode_JIT(b.originalAddress, (JIT_OPCODE << 26) | block_num); - u32 pAddr = 0; // Convert the logical address to a physical address for the block map - switch ((b.originalAddress >> 24) & 0xFC) - { - case 0x00: - case 0x80: - case 0xC0: - pAddr = b.originalAddress & 0x0FFFFFFF; - case 0x10: - case 0x90: - case 0xD0: - pAddr = b.originalAddress & 0x1FFFFFFF; - default: - // Translate address? - pAddr = b.originalAddress & 0x0FFFFFFF; - } + u32 pAddr = b.originalAddress & 0x1FFFFFFF; block_map[std::make_pair(pAddr + 4 * b.originalSize - 1, pAddr)] = block_num; if (block_link) @@ -430,21 +416,7 @@ bool JitBlock::ContainsAddress(u32 em_address) void JitBlockCache::InvalidateICache(u32 address, const u32 length) { // Convert the logical address to a physical address for the block map - u32 pAddr = 0; - switch ((address >> 24) & 0xFC) - { - case 0x00: - case 0x80: - case 0xC0: - pAddr = address & 0x0FFFFFFF; - case 0x10: - case 0x90: - case 0xD0: - pAddr = address & 0x1FFFFFFF; - default: - // Translate address? - pAddr = address & 0x0FFFFFFF; - } + u32 pAddr = address & 0x1FFFFFFF; // destroy JIT blocks // !! this works correctly under assumption that any two overlapping blocks end at the same address diff --git a/Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp b/Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp index c3aa56acd0..433192b23f 100644 --- a/Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp +++ b/Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp @@ -559,7 +559,9 @@ u32 Flatten(u32 address, int *realsize, BlockStats *st, BlockRegStats *gpa, } else { - // Memory exception occurred + // Critical memory exception occurred (game over) + address = LR; + broken_block = true; break; } }