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".
This commit is contained in:
parent
372e00632d
commit
99b7c91df5
|
@ -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);
|
||||
|
||||
|
|
|
@ -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}},
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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}},
|
||||
|
|
Loading…
Reference in New Issue