summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorskidau <skidau@gmail.com>2012-05-31 22:09:33 +1000
committerskidau <skidau@gmail.com>2012-05-31 22:09:33 +1000
commit99b7c91df5dbfe2d3b0d8fd273e416420eabf514 (patch)
tree6f5f7243f6b58f76c9cb4c529b11d32707a6a209 /Source/Core
parent372e00632dbe7e02ef67fdf3daa7ebfb3d607edb (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')
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64/Jit.h1
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64/Jit64_Tables.cpp2
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStore.cpp15
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.h1
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_LoadStore.cpp15
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_Tables.cpp2
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}},