diff options
| author | skidau <skidau@gmail.com> | 2012-05-31 22:09:33 +1000 |
|---|---|---|
| committer | skidau <skidau@gmail.com> | 2012-05-31 22:09:33 +1000 |
| commit | 99b7c91df5dbfe2d3b0d8fd273e416420eabf514 (patch) | |
| tree | 6f5f7243f6b58f76c9cb4c529b11d32707a6a209 /Source/Core | |
| parent | 372e00632dbe7e02ef67fdf3daa7ebfb3d607edb (diff) | |
Checked if dcbst instructions are preceded by dcbt. If it is, the game is prefetching memory into the data cache, and not loading new code. In these cases, the JIT cache will no longer be flushed. Fixes the frequent "Clearing code cache" issue in games like "The Last Story".
Diffstat (limited to 'Source/Core')
6 files changed, 34 insertions, 2 deletions
diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit.h b/Source/Core/Core/Src/PowerPC/Jit64/Jit.h index 791934bd18..1ebd476134 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit.h +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit.h @@ -222,6 +222,7 @@ public: void negx(UGeckoInstruction inst); void slwx(UGeckoInstruction inst); void srwx(UGeckoInstruction inst); + void dcbst(UGeckoInstruction inst); void dcbz(UGeckoInstruction inst); void lfsx(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 1c654a4a9a..8d593a6742 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::Default}, //"dcbst", OPTYPE_DCACHE, 0, 4}}, + {54, &Jit64::dcbst}, //"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/Jit64/Jit_LoadStore.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStore.cpp index e9de594465..1dae2ec17e 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStore.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStore.cpp @@ -235,6 +235,21 @@ void Jit64::lXXx(UGeckoInstruction inst) gpr.UnlockAllX(); } +void Jit64::dcbst(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(LoadStore) + + // If the dcbst instruction is preceded by dcbt, it is flushing a prefetched + // memory location. Do not invalidate the JIT cache in this case as the memory + // will be the same. + // dcbt = 0x7c00022c + if ((Memory::ReadUnchecked_U32(js.compilerPC - 4) & 0x7c00022c) != 0x7c00022c) + { + Default(inst); return; + } +} + // Zero cache line. void Jit64::dcbz(UGeckoInstruction inst) { diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.h b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.h index bb4c2d8ee1..fdda098e44 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.h +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.h @@ -212,6 +212,7 @@ public: void negx(UGeckoInstruction inst); void slwx(UGeckoInstruction inst); void srwx(UGeckoInstruction inst); + void dcbst(UGeckoInstruction inst); void dcbz(UGeckoInstruction inst); void lfsx(UGeckoInstruction inst); diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_LoadStore.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_LoadStore.cpp index 65e2c4097f..45ceda694a 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_LoadStore.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_LoadStore.cpp @@ -114,6 +114,21 @@ void JitIL::lXzx(UGeckoInstruction inst) ibuild.EmitStoreGReg(val, inst.RD); } +void JitIL::dcbst(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(LoadStore) + + // If the dcbst instruction is preceded by dcbt, it is flushing a prefetched + // memory location. Do not invalidate the JIT cache in this case as the memory + // will be the same. + // dcbt = 0x7c00022c + if ((Memory::ReadUnchecked_U32(js.compilerPC - 4) & 0x7c00022c) != 0x7c00022c) + { + Default(inst); return; + } +} + // Zero cache line. void JitIL::dcbz(UGeckoInstruction inst) { diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_Tables.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_Tables.cpp index 9b2e3ff466..9e8e36f9c3 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::Default}, //"dcbst", OPTYPE_DCACHE, 0, 4}}, + {54, &JitIL::dcbst}, //"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}}, |
