Readded the tracking of the FIFO Writes.
Fixes issue 6165.
This commit is contained in:
parent
b1dd14c319
commit
e38e48923d
|
@ -96,6 +96,20 @@ void STACKALIGN CheckGatherPipe()
|
|||
|
||||
// move back the spill bytes
|
||||
memmove(m_gatherPipe, m_gatherPipe + cnt, m_gatherPipeCount);
|
||||
|
||||
// Profile where the FIFO writes are occurring.
|
||||
if (jit && PC != 0 && (jit->js.fifoWriteAddresses.find(PC)) == (jit->js.fifoWriteAddresses.end()))
|
||||
{
|
||||
// Log only stores, fp stores and ps stores, filtering out other instructions arrived via optimizeGatherPipe
|
||||
int type = GetOpInfo(Memory::ReadUnchecked_U32(PC))->type;
|
||||
if (type == OPTYPE_STORE || type == OPTYPE_STOREFP || (type == OPTYPE_PS && !strcmp(GetOpInfo(Memory::ReadUnchecked_U32(PC))->opname, "psq_st")))
|
||||
{
|
||||
jit->js.fifoWriteAddresses.insert(PC);
|
||||
|
||||
// Invalidate the JIT block so that it gets recompiled with the external exception check included.
|
||||
jit->GetBlockCache()->InvalidateICache(PC, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -611,6 +611,30 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
|
|||
js.firstFPInstructionFound = true;
|
||||
}
|
||||
|
||||
// Add an external exception check if the instruction writes to the FIFO.
|
||||
if (jit->js.fifoWriteAddresses.find(ops[i].address) != jit->js.fifoWriteAddresses.end())
|
||||
{
|
||||
gpr.Flush(FLUSH_ALL);
|
||||
fpr.Flush(FLUSH_ALL);
|
||||
|
||||
TEST(32, M((void *)&PowerPC::ppcState.Exceptions), Imm32(EXCEPTION_ISI | EXCEPTION_PROGRAM | EXCEPTION_SYSCALL | EXCEPTION_FPU_UNAVAILABLE | EXCEPTION_DSI | EXCEPTION_ALIGNMENT));
|
||||
FixupBranch clearInt = J_CC(CC_NZ, true);
|
||||
TEST(32, M((void *)&PowerPC::ppcState.Exceptions), Imm32(EXCEPTION_EXTERNAL_INT));
|
||||
FixupBranch noExtException = J_CC(CC_Z, true);
|
||||
TEST(32, M((void *)&PowerPC::ppcState.msr), Imm32(0x0008000));
|
||||
FixupBranch noExtIntEnable = J_CC(CC_Z, true);
|
||||
TEST(32, M((void *)&ProcessorInterface::m_InterruptCause), Imm32(ProcessorInterface::INT_CAUSE_CP | ProcessorInterface::INT_CAUSE_PE_TOKEN | ProcessorInterface::INT_CAUSE_PE_FINISH));
|
||||
FixupBranch noCPInt = J_CC(CC_Z, true);
|
||||
|
||||
MOV(32, M(&PC), Imm32(ops[i].address));
|
||||
WriteExternalExceptionExit();
|
||||
|
||||
SetJumpTarget(noCPInt);
|
||||
SetJumpTarget(noExtIntEnable);
|
||||
SetJumpTarget(noExtException);
|
||||
SetJumpTarget(clearInt);
|
||||
}
|
||||
|
||||
if (Core::g_CoreStartupParameter.bEnableDebugging && breakpoints.IsAddressBreakPoint(ops[i].address) && GetState() != CPU_STEPPING)
|
||||
{
|
||||
gpr.Flush(FLUSH_ALL);
|
||||
|
|
|
@ -1269,7 +1269,7 @@ static const unsigned alwaysUsedList[] = {
|
|||
Store16, Store32, StoreSingle, StoreDouble, StorePaired, StoreFReg, FDCmpCR,
|
||||
BlockStart, BlockEnd, IdleBranch, BranchCond, BranchUncond, ShortIdleLoop,
|
||||
SystemCall, InterpreterBranch, RFIExit, FPExceptionCheck,
|
||||
DSIExceptionCheck, ISIException, BreakPointCheck,
|
||||
DSIExceptionCheck, ISIException, ExtExceptionCheck, BreakPointCheck,
|
||||
Int3, Tramp, Nop
|
||||
};
|
||||
static const unsigned extra8RegList[] = {
|
||||
|
|
|
@ -168,7 +168,7 @@ enum Opcode {
|
|||
// used for exception checking, at least until someone
|
||||
// has a better idea of integrating it
|
||||
FPExceptionCheck, DSIExceptionCheck,
|
||||
ISIException, BreakPointCheck,
|
||||
ISIException, ExtExceptionCheck, BreakPointCheck,
|
||||
// "Opcode" representing a register too far away to
|
||||
// reference directly; this is a size optimization
|
||||
Tramp,
|
||||
|
@ -411,6 +411,9 @@ public:
|
|||
InstLoc EmitISIException(InstLoc dest) {
|
||||
return EmitUOp(ISIException, dest);
|
||||
}
|
||||
InstLoc EmitExtExceptionCheck(InstLoc pc) {
|
||||
return EmitUOp(ExtExceptionCheck, pc);
|
||||
}
|
||||
InstLoc EmitBreakPointCheck(InstLoc pc) {
|
||||
return EmitUOp(BreakPointCheck, pc);
|
||||
}
|
||||
|
|
|
@ -762,6 +762,7 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, bool UseProfile, bool Mak
|
|||
case FPExceptionCheck:
|
||||
case DSIExceptionCheck:
|
||||
case ISIException:
|
||||
case ExtExceptionCheck:
|
||||
case BreakPointCheck:
|
||||
case Int3:
|
||||
case Tramp:
|
||||
|
@ -1940,6 +1941,27 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, bool UseProfile, bool Mak
|
|||
Jit->WriteExceptionExit();
|
||||
break;
|
||||
}
|
||||
case ExtExceptionCheck: {
|
||||
unsigned InstLoc = ibuild->GetImmValue(getOp1(I));
|
||||
|
||||
Jit->TEST(32, M((void *)&PowerPC::ppcState.Exceptions), Imm32(EXCEPTION_ISI | EXCEPTION_PROGRAM | EXCEPTION_SYSCALL | EXCEPTION_FPU_UNAVAILABLE | EXCEPTION_DSI | EXCEPTION_ALIGNMENT));
|
||||
FixupBranch clearInt = Jit->J_CC(CC_NZ);
|
||||
Jit->TEST(32, M((void *)&PowerPC::ppcState.Exceptions), Imm32(EXCEPTION_EXTERNAL_INT));
|
||||
FixupBranch noExtException = Jit->J_CC(CC_Z);
|
||||
Jit->TEST(32, M((void *)&PowerPC::ppcState.msr), Imm32(0x0008000));
|
||||
FixupBranch noExtIntEnable = Jit->J_CC(CC_Z);
|
||||
Jit->TEST(32, M((void *)&ProcessorInterface::m_InterruptCause), Imm32(ProcessorInterface::INT_CAUSE_CP | ProcessorInterface::INT_CAUSE_PE_TOKEN | ProcessorInterface::INT_CAUSE_PE_FINISH));
|
||||
FixupBranch noCPInt = Jit->J_CC(CC_Z);
|
||||
|
||||
Jit->MOV(32, M(&PC), Imm32(InstLoc));
|
||||
Jit->WriteExceptionExit();
|
||||
|
||||
Jit->SetJumpTarget(noCPInt);
|
||||
Jit->SetJumpTarget(noExtIntEnable);
|
||||
Jit->SetJumpTarget(noExtException);
|
||||
Jit->SetJumpTarget(clearInt);
|
||||
break;
|
||||
}
|
||||
case BreakPointCheck: {
|
||||
unsigned InstLoc = ibuild->GetImmValue(getOp1(I));
|
||||
|
||||
|
|
|
@ -679,6 +679,11 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
|
|||
ibuild.EmitFPExceptionCheck(ibuild.EmitIntConst(ops[i].address));
|
||||
}
|
||||
|
||||
if (jit->js.fifoWriteAddresses.find(js.compilerPC) != jit->js.fifoWriteAddresses.end())
|
||||
{
|
||||
ibuild.EmitExtExceptionCheck(ibuild.EmitIntConst(ops[i].address));
|
||||
}
|
||||
|
||||
if (Core::g_CoreStartupParameter.bEnableDebugging && breakpoints.IsAddressBreakPoint(ops[i].address) && GetState() != CPU_STEPPING)
|
||||
{
|
||||
ibuild.EmitBreakPointCheck(ibuild.EmitIntConst(ops[i].address));
|
||||
|
|
|
@ -74,6 +74,8 @@ protected:
|
|||
u8* rewriteStart;
|
||||
|
||||
JitBlock *curBlock;
|
||||
|
||||
std::set<u32> fifoWriteAddresses;
|
||||
};
|
||||
|
||||
public:
|
||||
|
|
Loading…
Reference in New Issue