Jit: Check the FIFO on EIEIO instructions
The gather pipe optimization postpones checking the FIFO until the end of the current block (or 32 bytes have been written). This is usually safe, but is not correct across EIEIO instructions. This is inferred from a block in NBA2K11 which synchronizes the FIFO by writing a byte to it, executing eieio, and checking if PI_FIFO_WPTR has changed. This is not currently an issue, but will become an issue if the gather pipe optimization is applied to more stores.
This commit is contained in:
parent
4c9c456846
commit
bbc0f0c744
|
@ -598,6 +598,7 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer* code_buf, JitBloc
|
|||
js.isLastInstruction = false;
|
||||
js.blockStart = em_address;
|
||||
js.fifoBytesThisBlock = 0;
|
||||
js.mustCheckFifo = false;
|
||||
js.curBlock = b;
|
||||
js.numLoadStoreInst = 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();
|
||||
|
||||
// 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();
|
||||
ABI_PushRegistersAndAdjustStack(registersInUse, 0);
|
||||
ABI_CallFunction((void*)&GPFifo::FastCheckGatherPipe);
|
||||
|
|
|
@ -241,4 +241,6 @@ public:
|
|||
void stmw(UGeckoInstruction inst);
|
||||
|
||||
void dcbx(UGeckoInstruction inst);
|
||||
|
||||
void eieio(UGeckoInstruction inst);
|
||||
};
|
||||
|
|
|
@ -309,7 +309,7 @@ static GekkoOPTemplate table31[] = {
|
|||
// Unused instructions on GC
|
||||
{310, &Jit64::FallBackToInterpreter}, // eciwx
|
||||
{438, &Jit64::FallBackToInterpreter}, // ecowx
|
||||
{854, &Jit64::DoNothing}, // eieio
|
||||
{854, &Jit64::eieio}, // eieio
|
||||
{306, &Jit64::FallBackToInterpreter}, // tlbie
|
||||
{566, &Jit64::DoNothing}, // tlbsync
|
||||
};
|
||||
|
|
|
@ -598,3 +598,15 @@ void Jit64::stmw(UGeckoInstruction inst)
|
|||
}
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -103,6 +103,7 @@ protected:
|
|||
bool generatingTrampoline = false;
|
||||
u8* trampolineExceptionHandler;
|
||||
|
||||
bool mustCheckFifo;
|
||||
int fifoBytesThisBlock;
|
||||
|
||||
PPCAnalyst::BlockStats st;
|
||||
|
|
Loading…
Reference in New Issue