Merge pull request #1874 from magumagu/remove-unchecked-reads

JIT: cleanup instrction merging for idle loop and dcbst.
This commit is contained in:
Fiora 2015-02-07 13:48:22 -08:00
commit 73d65f3ad3
3 changed files with 22 additions and 13 deletions

View File

@ -240,7 +240,7 @@ public:
void negx(UGeckoInstruction inst); void negx(UGeckoInstruction inst);
void slwx(UGeckoInstruction inst); void slwx(UGeckoInstruction inst);
void srwx(UGeckoInstruction inst); void srwx(UGeckoInstruction inst);
void dcbst(UGeckoInstruction inst); void dcbt(UGeckoInstruction inst);
void dcbz(UGeckoInstruction inst); void dcbz(UGeckoInstruction inst);
void subfic(UGeckoInstruction inst); void subfic(UGeckoInstruction inst);

View File

@ -197,10 +197,10 @@ static GekkoOPTemplate table31[] =
{824, &Jit64::srawix}, //"srawix", OPTYPE_INTEGER, FL_OUT_A | FL_IN_B | FL_IN_S | FL_SET_CA | FL_RC_BIT}}, {824, &Jit64::srawix}, //"srawix", OPTYPE_INTEGER, FL_OUT_A | FL_IN_B | FL_IN_S | FL_SET_CA | FL_RC_BIT}},
{24, &Jit64::slwx}, //"slwx", 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::dcbst}, //"dcbst", OPTYPE_DCACHE, 0, 4}}, {54, &Jit64::FallBackToInterpreter}, //"dcbst", OPTYPE_DCACHE, 0, 4}},
{86, &Jit64::FallBackToInterpreter}, //"dcbf", OPTYPE_DCACHE, 0, 4}}, {86, &Jit64::FallBackToInterpreter}, //"dcbf", OPTYPE_DCACHE, 0, 4}},
{246, &Jit64::DoNothing}, //"dcbtst", OPTYPE_DCACHE, 0, 1}}, {246, &Jit64::dcbt }, //"dcbtst", OPTYPE_DCACHE, 0, 1}},
{278, &Jit64::DoNothing}, //"dcbt", OPTYPE_DCACHE, 0, 1}}, {278, &Jit64::dcbt }, //"dcbt", OPTYPE_DCACHE, 0, 1}},
{470, &Jit64::FallBackToInterpreter}, //"dcbi", OPTYPE_DCACHE, 0, 4}}, {470, &Jit64::FallBackToInterpreter}, //"dcbi", OPTYPE_DCACHE, 0, 4}},
{758, &Jit64::DoNothing}, //"dcba", OPTYPE_DCACHE, 0, 4}}, {758, &Jit64::DoNothing}, //"dcba", OPTYPE_DCACHE, 0, 4}},
{1014, &Jit64::dcbz}, //"dcbz", OPTYPE_DCACHE, 0, 4}}, {1014, &Jit64::dcbz}, //"dcbz", OPTYPE_DCACHE, 0, 4}},

View File

@ -111,10 +111,11 @@ void Jit64::lXXx(UGeckoInstruction inst)
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bSkipIdle && if (SConfig::GetInstance().m_LocalCoreStartupParameter.bSkipIdle &&
PowerPC::GetState() != PowerPC::CPU_STEPPING && PowerPC::GetState() != PowerPC::CPU_STEPPING &&
inst.OPCD == 32 && inst.OPCD == 32 &&
MergeAllowedNextInstructions(2) &&
(inst.hex & 0xFFFF0000) == 0x800D0000 && (inst.hex & 0xFFFF0000) == 0x800D0000 &&
(Memory::ReadUnchecked_U32(js.compilerPC + 4) == 0x28000000 || (js.op[1].inst.hex == 0x28000000 ||
(SConfig::GetInstance().m_LocalCoreStartupParameter.bWii && Memory::ReadUnchecked_U32(js.compilerPC + 4) == 0x2C000000)) && (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii && js.op[1].inst.hex == 0x2C000000)) &&
Memory::ReadUnchecked_U32(js.compilerPC + 8) == 0x4182fff8) js.op[2].inst.hex == 0x4182fff8)
{ {
// TODO(LinesPrower): // TODO(LinesPrower):
// - Rewrite this! // - Rewrite this!
@ -284,16 +285,24 @@ void Jit64::lXXx(UGeckoInstruction inst)
gpr.UnlockAllX(); gpr.UnlockAllX();
} }
void Jit64::dcbst(UGeckoInstruction inst) void Jit64::dcbt(UGeckoInstruction inst)
{ {
INSTRUCTION_START INSTRUCTION_START
JITDISABLE(bJITLoadStoreOff); JITDISABLE(bJITLoadStoreOff);
// If the dcbst instruction is preceded by dcbt, it is flushing a prefetched // Prefetch. Since we don't emulate the data cache, we don't need to do anything.
// memory location. Do not invalidate the JIT cache in this case as the memory
// will be the same. // If a dcbst follows a dcbt, it probably isn't a case of dynamic code
// dcbt = 0x7c00022c // modification, so don't bother invalidating the jit block cache.
FALLBACK_IF((Memory::ReadUnchecked_U32(js.compilerPC - 4) & 0x7c00022c) != 0x7c00022c); // This is important because invalidating the block cache when we don't
// need to is terrible for performance.
// (Invalidating the jit block cache on dcbst is a heuristic.)
if (MergeAllowedNextInstructions(1) &&
js.op[1].inst.OPCD == 31 && js.op[1].inst.SUBOP10 == 54 &&
js.op[1].inst.RA == inst.RA && js.op[1].inst.RB == inst.RB)
{
js.skipInstructions = 1;
}
} }
// Zero cache line. // Zero cache line.