mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-25 15:19:42 -06:00
Merge pull request #3894 from hthh/optimize-fifo-bug
Jit: Check the FIFO on EIEIO instructions
This commit is contained in:
@ -598,6 +598,7 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer* code_buf, JitBloc
|
|||||||
js.isLastInstruction = false;
|
js.isLastInstruction = false;
|
||||||
js.blockStart = em_address;
|
js.blockStart = em_address;
|
||||||
js.fifoBytesThisBlock = 0;
|
js.fifoBytesThisBlock = 0;
|
||||||
|
js.mustCheckFifo = false;
|
||||||
js.curBlock = b;
|
js.curBlock = b;
|
||||||
js.numLoadStoreInst = 0;
|
js.numLoadStoreInst = 0;
|
||||||
js.numFloatingPointInst = 0;
|
js.numFloatingPointInst = 0;
|
||||||
@ -723,9 +724,11 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer* code_buf, JitBloc
|
|||||||
js.fifoWriteAddresses.find(ops[i].address) != js.fifoWriteAddresses.end();
|
js.fifoWriteAddresses.find(ops[i].address) != js.fifoWriteAddresses.end();
|
||||||
|
|
||||||
// Gather pipe writes using an immediate address are explicitly tracked.
|
// Gather pipe writes using an immediate address are explicitly tracked.
|
||||||
if (jo.optimizeGatherPipe && js.fifoBytesThisBlock >= 32)
|
if (jo.optimizeGatherPipe && (js.fifoBytesThisBlock >= 32 || js.mustCheckFifo))
|
||||||
{
|
{
|
||||||
js.fifoBytesThisBlock -= 32;
|
if (js.fifoBytesThisBlock >= 32)
|
||||||
|
js.fifoBytesThisBlock -= 32;
|
||||||
|
js.mustCheckFifo = false;
|
||||||
BitSet32 registersInUse = CallerSavedRegistersInUse();
|
BitSet32 registersInUse = CallerSavedRegistersInUse();
|
||||||
ABI_PushRegistersAndAdjustStack(registersInUse, 0);
|
ABI_PushRegistersAndAdjustStack(registersInUse, 0);
|
||||||
ABI_CallFunction((void*)&GPFifo::FastCheckGatherPipe);
|
ABI_CallFunction((void*)&GPFifo::FastCheckGatherPipe);
|
||||||
|
@ -241,4 +241,6 @@ public:
|
|||||||
void stmw(UGeckoInstruction inst);
|
void stmw(UGeckoInstruction inst);
|
||||||
|
|
||||||
void dcbx(UGeckoInstruction inst);
|
void dcbx(UGeckoInstruction inst);
|
||||||
|
|
||||||
|
void eieio(UGeckoInstruction inst);
|
||||||
};
|
};
|
||||||
|
@ -309,7 +309,7 @@ static GekkoOPTemplate table31[] = {
|
|||||||
// Unused instructions on GC
|
// Unused instructions on GC
|
||||||
{310, &Jit64::FallBackToInterpreter}, // eciwx
|
{310, &Jit64::FallBackToInterpreter}, // eciwx
|
||||||
{438, &Jit64::FallBackToInterpreter}, // ecowx
|
{438, &Jit64::FallBackToInterpreter}, // ecowx
|
||||||
{854, &Jit64::DoNothing}, // eieio
|
{854, &Jit64::eieio}, // eieio
|
||||||
{306, &Jit64::FallBackToInterpreter}, // tlbie
|
{306, &Jit64::FallBackToInterpreter}, // tlbie
|
||||||
{566, &Jit64::DoNothing}, // tlbsync
|
{566, &Jit64::DoNothing}, // tlbsync
|
||||||
};
|
};
|
||||||
|
@ -598,3 +598,15 @@ void Jit64::stmw(UGeckoInstruction inst)
|
|||||||
}
|
}
|
||||||
gpr.UnlockAllX();
|
gpr.UnlockAllX();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Jit64::eieio(UGeckoInstruction inst)
|
||||||
|
{
|
||||||
|
INSTRUCTION_START
|
||||||
|
JITDISABLE(bJITLoadStoreOff);
|
||||||
|
|
||||||
|
// optimizeGatherPipe generally postpones FIFO checks to the end of the JIT block,
|
||||||
|
// which is generally safe. However postponing FIFO writes across eieio instructions
|
||||||
|
// is incorrect (would crash NBA2K11 strap screen if we improve our FIFO detection).
|
||||||
|
if (jo.optimizeGatherPipe && js.fifoBytesThisBlock > 0)
|
||||||
|
js.mustCheckFifo = true;
|
||||||
|
}
|
||||||
|
@ -405,6 +405,7 @@ const u8* JitArm64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer* code_buf, JitB
|
|||||||
js.assumeNoPairedQuantize = false;
|
js.assumeNoPairedQuantize = false;
|
||||||
js.blockStart = em_address;
|
js.blockStart = em_address;
|
||||||
js.fifoBytesThisBlock = 0;
|
js.fifoBytesThisBlock = 0;
|
||||||
|
js.mustCheckFifo = false;
|
||||||
js.downcountAmount = 0;
|
js.downcountAmount = 0;
|
||||||
js.skipInstructions = 0;
|
js.skipInstructions = 0;
|
||||||
js.curBlock = b;
|
js.curBlock = b;
|
||||||
@ -491,9 +492,11 @@ const u8* JitArm64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer* code_buf, JitB
|
|||||||
bool gatherPipeIntCheck =
|
bool gatherPipeIntCheck =
|
||||||
jit->js.fifoWriteAddresses.find(ops[i].address) != jit->js.fifoWriteAddresses.end();
|
jit->js.fifoWriteAddresses.find(ops[i].address) != jit->js.fifoWriteAddresses.end();
|
||||||
|
|
||||||
if (jo.optimizeGatherPipe && js.fifoBytesThisBlock >= 32)
|
if (jo.optimizeGatherPipe && (js.fifoBytesThisBlock >= 32 || js.mustCheckFifo))
|
||||||
{
|
{
|
||||||
js.fifoBytesThisBlock -= 32;
|
if (js.fifoBytesThisBlock >= 32)
|
||||||
|
js.fifoBytesThisBlock -= 32;
|
||||||
|
js.mustCheckFifo = false;
|
||||||
|
|
||||||
gpr.Lock(W30);
|
gpr.Lock(W30);
|
||||||
BitSet32 regs_in_use = gpr.GetCallerSavedUsed();
|
BitSet32 regs_in_use = gpr.GetCallerSavedUsed();
|
||||||
|
@ -116,6 +116,7 @@ public:
|
|||||||
void dcbx(UGeckoInstruction inst);
|
void dcbx(UGeckoInstruction inst);
|
||||||
void dcbt(UGeckoInstruction inst);
|
void dcbt(UGeckoInstruction inst);
|
||||||
void dcbz(UGeckoInstruction inst);
|
void dcbz(UGeckoInstruction inst);
|
||||||
|
void eieio(UGeckoInstruction inst);
|
||||||
|
|
||||||
// LoadStore floating point
|
// LoadStore floating point
|
||||||
void lfXX(UGeckoInstruction inst);
|
void lfXX(UGeckoInstruction inst);
|
||||||
|
@ -853,3 +853,15 @@ void JitArm64::dcbz(UGeckoInstruction inst)
|
|||||||
|
|
||||||
gpr.Unlock(W0);
|
gpr.Unlock(W0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void JitArm64::eieio(UGeckoInstruction inst)
|
||||||
|
{
|
||||||
|
INSTRUCTION_START
|
||||||
|
JITDISABLE(bJITLoadStoreOff);
|
||||||
|
|
||||||
|
// optimizeGatherPipe generally postpones FIFO checks to the end of the JIT block,
|
||||||
|
// which is generally safe. However postponing FIFO writes across eieio instructions
|
||||||
|
// is incorrect (would crash NBA2K11 strap screen if we improve our FIFO detection).
|
||||||
|
if (jo.optimizeGatherPipe && js.fifoBytesThisBlock > 0)
|
||||||
|
js.mustCheckFifo = true;
|
||||||
|
}
|
||||||
|
@ -314,7 +314,7 @@ static GekkoOPTemplate table31[] = {
|
|||||||
// Unused instructions on GC
|
// Unused instructions on GC
|
||||||
{310, &JitArm64::FallBackToInterpreter}, // eciwx
|
{310, &JitArm64::FallBackToInterpreter}, // eciwx
|
||||||
{438, &JitArm64::FallBackToInterpreter}, // ecowx
|
{438, &JitArm64::FallBackToInterpreter}, // ecowx
|
||||||
{854, &JitArm64::DoNothing}, // eieio
|
{854, &JitArm64::eieio}, // eieio
|
||||||
{306, &JitArm64::FallBackToInterpreter}, // tlbie
|
{306, &JitArm64::FallBackToInterpreter}, // tlbie
|
||||||
{566, &JitArm64::DoNothing}, // tlbsync
|
{566, &JitArm64::DoNothing}, // tlbsync
|
||||||
};
|
};
|
||||||
|
@ -103,6 +103,7 @@ protected:
|
|||||||
bool generatingTrampoline = false;
|
bool generatingTrampoline = false;
|
||||||
u8* trampolineExceptionHandler;
|
u8* trampolineExceptionHandler;
|
||||||
|
|
||||||
|
bool mustCheckFifo;
|
||||||
int fifoBytesThisBlock;
|
int fifoBytesThisBlock;
|
||||||
|
|
||||||
PPCAnalyst::BlockStats st;
|
PPCAnalyst::BlockStats st;
|
||||||
|
Reference in New Issue
Block a user