Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
skidau committed Mar 25, 2013
2 parents ae146e8 + 0ccaaee commit b00201d
Show file tree
Hide file tree
Showing 11 changed files with 22 additions and 81 deletions.
10 changes: 9 additions & 1 deletion Source/Core/Core/Src/CoreTiming.cpp
Expand Up @@ -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;
Expand Down Expand Up @@ -468,7 +477,6 @@ void MoveEvents()

void Advance()
{

MoveEvents();

int cyclesExecuted = slicelength - downcount;
Expand Down
2 changes: 2 additions & 0 deletions Source/Core/Core/Src/CoreTiming.h
Expand Up @@ -92,6 +92,8 @@ void SetFakeTBStartValue(u64 val);
u64 GetFakeTBStartTicks();
void SetFakeTBStartTicks(u64 val);

void ForceExceptionCheck(int cycles);

extern int downcount;
extern int slicelength;

Expand Down
4 changes: 4 additions & 0 deletions Source/Core/Core/Src/HW/DSP.cpp
Expand Up @@ -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)
{
Expand Down
14 changes: 0 additions & 14 deletions Source/Core/Core/Src/HW/GPFifo.cpp
Expand Up @@ -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);
}
}
}
}

Expand Down
26 changes: 1 addition & 25 deletions Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp
Expand Up @@ -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()
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp
Expand Up @@ -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[] = {
Expand Down
5 changes: 1 addition & 4 deletions Source/Core/Core/Src/PowerPC/Jit64IL/IR.h
Expand Up @@ -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,
Expand Down Expand Up @@ -411,9 +411,6 @@ class IRBuilder {
InstLoc EmitISIException(InstLoc dest) {
return EmitUOp(ISIException, dest);
}
InstLoc EmitExtExceptionCheck(InstLoc pc) {
return EmitUOp(ExtExceptionCheck, pc);
}
InstLoc EmitBreakPointCheck(InstLoc pc) {
return EmitUOp(BreakPointCheck, pc);
}
Expand Down
22 changes: 0 additions & 22 deletions Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp
Expand Up @@ -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:
Expand Down Expand Up @@ -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));

Expand Down
5 changes: 0 additions & 5 deletions Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp
Expand Up @@ -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));
Expand Down
2 changes: 0 additions & 2 deletions Source/Core/Core/Src/PowerPC/JitCommon/JitBase.h
Expand Up @@ -74,8 +74,6 @@ class JitBase : public CPUCoreBase
u8* rewriteStart;

JitBlock *curBlock;

std::set<u32> fifoWriteAddresses;
};

public:
Expand Down
11 changes: 4 additions & 7 deletions Source/Core/VideoCommon/Src/CommandProcessor.cpp
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit b00201d

Please sign in to comment.