Merge branch 'Fast-EE'

* Fast-EE:
  Forced the exception check only for ARAM DMA transfers. Removed the Eternal Darkness boot hack and replaced it with an exception check.
  Reverted rd76ca5783743 as it was made obsolete by r1d550f4496e4.
  Removed the tracking of the FIFO Writes as it was made obsolete by r1d550f4496e4.
  Forced the external exception check to occur sooner by changing the downcount.
This commit is contained in:
skidau 2013-03-26 08:24:21 +11:00
commit b00201dcbd
11 changed files with 22 additions and 81 deletions

View File

@ -413,6 +413,15 @@ void SetMaximumSlice(int maximumSliceLength)
maxSliceLength = maximumSliceLength;
}
void ForceExceptionCheck(int cycles)
{
if (downcount > cycles)
{
slicelength -= (downcount - cycles); // Account for cycles already executed by adjusting the slicelength
downcount = cycles;
}
}
void ResetSliceLength()
{
maxSliceLength = MAX_SLICE_LENGTH;
@ -468,7 +477,6 @@ void MoveEvents()
void Advance()
{
MoveEvents();
int cyclesExecuted = slicelength - downcount;

View File

@ -92,6 +92,8 @@ void SetFakeTBStartValue(u64 val);
u64 GetFakeTBStartTicks();
void SetFakeTBStartTicks(u64 val);
void ForceExceptionCheck(int cycles);
extern int downcount;
extern int slicelength;

View File

@ -696,6 +696,10 @@ void Do_ARAM_DMA()
g_dspState.DSPControl.DMAState = 1;
CoreTiming::ScheduleEvent_Threadsafe(0, et_GenerateDSPInterrupt, INT_ARAM | (1<<16));
// Force an early exception check. Fixes RE2 audio.
if (g_arDMA.Cnt.count == 4096)
CoreTiming::ForceExceptionCheck(100);
// Real hardware DMAs in 32byte chunks, but we can get by with 8byte chunks
if (g_arDMA.Cnt.dir)
{

View File

@ -96,20 +96,6 @@ 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);
}
}
}
}

View File

@ -341,7 +341,7 @@ void Jit64::WriteRfiExitDestInEAX()
Cleanup();
ABI_CallFunction(reinterpret_cast<void *>(&PowerPC::CheckExceptions));
SUB(32, M(&CoreTiming::downcount), js.downcountAmount > 127 ? Imm32(js.downcountAmount) : Imm8(js.downcountAmount));
JMP(asm_routines.outerLoop, true);
JMP(asm_routines.dispatcher, true);
}
void Jit64::WriteExceptionExit()
@ -611,30 +611,6 @@ 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);

View File

@ -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, ExtExceptionCheck, BreakPointCheck,
DSIExceptionCheck, ISIException, BreakPointCheck,
Int3, Tramp, Nop
};
static const unsigned extra8RegList[] = {

View File

@ -168,7 +168,7 @@ enum Opcode {
// used for exception checking, at least until someone
// has a better idea of integrating it
FPExceptionCheck, DSIExceptionCheck,
ISIException, ExtExceptionCheck, BreakPointCheck,
ISIException, BreakPointCheck,
// "Opcode" representing a register too far away to
// reference directly; this is a size optimization
Tramp,
@ -411,9 +411,6 @@ 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);
}

View File

@ -762,7 +762,6 @@ 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:
@ -1941,27 +1940,6 @@ 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));

View File

@ -679,11 +679,6 @@ 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));

View File

@ -74,8 +74,6 @@ protected:
u8* rewriteStart;
JitBlock *curBlock;
std::set<u32> fifoWriteAddresses;
};
public:

View File

@ -144,7 +144,7 @@ void Init()
isHiWatermarkActive = false;
isLoWatermarkActive = false;
et_UpdateInterrupts = CoreTiming::RegisterEvent("UpdateInterrupts", UpdateInterrupts_Wrapper);
et_UpdateInterrupts = CoreTiming::RegisterEvent("CPInterrupt", UpdateInterrupts_Wrapper);
}
void Read16(u16& _rReturnValue, const u32 _Address)
@ -642,14 +642,11 @@ void SetCpStatusRegister()
void SetCpControlRegister()
{
// If the new fifo is being attached We make sure there wont be SetFinish event pending.
// This protection fix eternal darkness booting, because the second SetFinish event when it is booting
// seems invalid or has a bug and hang the game.
// If the new fifo is being attached, force an exception check
// This fixes the hang while booting Eternal Darkness
if (!fifo.bFF_GPReadEnable && m_CPCtrlReg.GPReadEnable && !m_CPCtrlReg.BPEnable)
{
ProcessFifoEvents();
PixelEngine::ResetSetFinish();
CoreTiming::ForceExceptionCheck(0);
}
fifo.bFF_BPInt = m_CPCtrlReg.BPInt;