summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorskidau <skidau@gmail.com>2013-03-28 19:36:37 +1100
committerskidau <skidau@gmail.com>2013-03-28 19:36:37 +1100
commite38e48923dcf496d92bccc87507a5b57533760e6 (patch)
tree59572e29bf42ebdff700bf82013ddea3dc28aa25 /Source/Core
parentb1dd14c319621bc4cbea2bfec1003c8c93d3e5eb (diff)
Readded the tracking of the FIFO Writes.
Fixes issue 6165.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/Src/HW/GPFifo.cpp14
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp24
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp2
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64IL/IR.h5
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp22
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp5
-rw-r--r--Source/Core/Core/Src/PowerPC/JitCommon/JitBase.h2
7 files changed, 72 insertions, 2 deletions
diff --git a/Source/Core/Core/Src/HW/GPFifo.cpp b/Source/Core/Core/Src/HW/GPFifo.cpp
index ab3058bd8d..a7f7bd967b 100644
--- a/Source/Core/Core/Src/HW/GPFifo.cpp
+++ b/Source/Core/Core/Src/HW/GPFifo.cpp
@@ -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);
+ }
+ }
}
}
diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp
index 3995fc9299..1ad545ec0a 100644
--- a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp
+++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp
@@ -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);
diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp
index fdec5b747d..2a830a03cf 100644
--- a/Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp
+++ b/Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp
@@ -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[] = {
diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/IR.h b/Source/Core/Core/Src/PowerPC/Jit64IL/IR.h
index 5bc7da9d8d..7fabd946f9 100644
--- a/Source/Core/Core/Src/PowerPC/Jit64IL/IR.h
+++ b/Source/Core/Core/Src/PowerPC/Jit64IL/IR.h
@@ -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);
}
diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp
index 88d815e33d..7c12d613a3 100644
--- a/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp
+++ b/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp
@@ -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));
diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp
index f10df33d99..a60becfad9 100644
--- a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp
+++ b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp
@@ -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));
diff --git a/Source/Core/Core/Src/PowerPC/JitCommon/JitBase.h b/Source/Core/Core/Src/PowerPC/JitCommon/JitBase.h
index 9b8c67474c..158171be0f 100644
--- a/Source/Core/Core/Src/PowerPC/JitCommon/JitBase.h
+++ b/Source/Core/Core/Src/PowerPC/JitCommon/JitBase.h
@@ -74,6 +74,8 @@ protected:
u8* rewriteStart;
JitBlock *curBlock;
+
+ std::set<u32> fifoWriteAddresses;
};
public: