summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authormagumagu <magumagu9@gmail.com>2015-01-11 12:53:23 -0800
committermagumagu <magumagu9@gmail.com>2015-01-11 12:53:23 -0800
commit90d00966532fb2a142b82d2dfec67b220334d665 (patch)
treef7f450306465763e657de99fec12797af5a69b03 /Source
parent90c6ebfd86bb08d3426a390dfa94433a6e3dc024 (diff)
JIT: cleanup instrction merging for idle loop and dcbst.
Use MergeAllowedNextInstructions where appropriate, and read from the instruction buffer rather than poking directly into memory.
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/Core/PowerPC/Jit64/Jit.h2
-rw-r--r--Source/Core/Core/PowerPC/Jit64/Jit64_Tables.cpp6
-rw-r--r--Source/Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp27
3 files changed, 22 insertions, 13 deletions
diff --git a/Source/Core/Core/PowerPC/Jit64/Jit.h b/Source/Core/Core/PowerPC/Jit64/Jit.h
index a2d6c3026f..2352d90c03 100644
--- a/Source/Core/Core/PowerPC/Jit64/Jit.h
+++ b/Source/Core/Core/PowerPC/Jit64/Jit.h
@@ -241,7 +241,7 @@ public:
void negx(UGeckoInstruction inst);
void slwx(UGeckoInstruction inst);
void srwx(UGeckoInstruction inst);
- void dcbst(UGeckoInstruction inst);
+ void dcbt(UGeckoInstruction inst);
void dcbz(UGeckoInstruction inst);
void subfic(UGeckoInstruction inst);
diff --git a/Source/Core/Core/PowerPC/Jit64/Jit64_Tables.cpp b/Source/Core/Core/PowerPC/Jit64/Jit64_Tables.cpp
index 636a9b2396..c33f22e8d5 100644
--- a/Source/Core/Core/PowerPC/Jit64/Jit64_Tables.cpp
+++ b/Source/Core/Core/PowerPC/Jit64/Jit64_Tables.cpp
@@ -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}},
{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}},
- {246, &Jit64::DoNothing}, //"dcbtst", OPTYPE_DCACHE, 0, 1}},
- {278, &Jit64::DoNothing}, //"dcbt", OPTYPE_DCACHE, 0, 1}},
+ {246, &Jit64::dcbt }, //"dcbtst", OPTYPE_DCACHE, 0, 1}},
+ {278, &Jit64::dcbt }, //"dcbt", OPTYPE_DCACHE, 0, 1}},
{470, &Jit64::FallBackToInterpreter}, //"dcbi", OPTYPE_DCACHE, 0, 4}},
{758, &Jit64::DoNothing}, //"dcba", OPTYPE_DCACHE, 0, 4}},
{1014, &Jit64::dcbz}, //"dcbz", OPTYPE_DCACHE, 0, 4}},
diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp
index 0c0a23acfc..29e83e034d 100644
--- a/Source/Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp
+++ b/Source/Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp
@@ -111,10 +111,11 @@ void Jit64::lXXx(UGeckoInstruction inst)
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bSkipIdle &&
PowerPC::GetState() != PowerPC::CPU_STEPPING &&
inst.OPCD == 32 &&
+ MergeAllowedNextInstructions(2) &&
(inst.hex & 0xFFFF0000) == 0x800D0000 &&
- (Memory::ReadUnchecked_U32(js.compilerPC + 4) == 0x28000000 ||
- (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii && Memory::ReadUnchecked_U32(js.compilerPC + 4) == 0x2C000000)) &&
- Memory::ReadUnchecked_U32(js.compilerPC + 8) == 0x4182fff8)
+ (js.op[1].inst.hex == 0x28000000 ||
+ (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii && js.op[1].inst.hex == 0x2C000000)) &&
+ js.op[2].inst.hex == 0x4182fff8)
{
// TODO(LinesPrower):
// - Rewrite this!
@@ -284,16 +285,24 @@ void Jit64::lXXx(UGeckoInstruction inst)
gpr.UnlockAllX();
}
-void Jit64::dcbst(UGeckoInstruction inst)
+void Jit64::dcbt(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(bJITLoadStoreOff);
- // 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
- FALLBACK_IF((Memory::ReadUnchecked_U32(js.compilerPC - 4) & 0x7c00022c) != 0x7c00022c);
+ // Prefetch. Since we don't emulate the data cache, we don't need to do anything.
+
+ // If a dcbst follows a dcbt, it probably isn't a case of dynamic code
+ // modification, so don't bother invalidating the jit block cache.
+ // 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.