Skip to content

Commit

Permalink
CachedInterpreter: InterpretAndCheckExceptions Callback
Browse files Browse the repository at this point in the history
I tried making InterpretAndCheckExceptions test only the relevant exceptions (EXCEPTION_DSI, EXCEPTION_PROGRAM, or both) using templating, but didn't find a significant performance boost in it. As I am learning, the biggest bottleneck is the number of callbacks emitted, not usually the actual contents of them.
  • Loading branch information
mitaclaw committed May 7, 2024
1 parent 92adfe6 commit 1e55fd9
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 42 deletions.
66 changes: 30 additions & 36 deletions Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,21 @@ s32 CachedInterpreter::Interpret(PowerPC::PowerPCState& ppc_state,
return sizeof(AnyCallback) + sizeof(operands);
}

s32 CachedInterpreter::InterpretAndCheckExceptions(
PowerPC::PowerPCState& ppc_state, const InterpretAndCheckExceptionsOperands& operands)
{
const auto& [interpreter, func, current_pc, inst, power_pc, downcount] = operands;
func(interpreter, inst);
if ((ppc_state.Exceptions & (EXCEPTION_DSI | EXCEPTION_PROGRAM)) != 0)
{
ppc_state.pc = current_pc;
ppc_state.downcount -= downcount;
power_pc.CheckExceptions();
return 0;
}
return sizeof(AnyCallback) + sizeof(operands);
}

s32 CachedInterpreter::HLEFunction(PowerPC::PowerPCState& ppc_state,
const HLEFunctionOperands& operands)
{
Expand All @@ -131,8 +146,7 @@ s32 CachedInterpreter::WriteBrokenBlockNPC(PowerPC::PowerPCState& ppc_state,
return sizeof(AnyCallback) + sizeof(operands);
}

s32 CachedInterpreter::CheckFPU(PowerPC::PowerPCState& ppc_state,
const ExceptionCheckOperands& operands)
s32 CachedInterpreter::CheckFPU(PowerPC::PowerPCState& ppc_state, const CheckFPUOperands& operands)
{
const auto& [power_pc, current_pc, downcount] = operands;
if (!ppc_state.msr.FP)
Expand All @@ -146,34 +160,6 @@ s32 CachedInterpreter::CheckFPU(PowerPC::PowerPCState& ppc_state,
return sizeof(AnyCallback) + sizeof(operands);
}

s32 CachedInterpreter::CheckDSI(PowerPC::PowerPCState& ppc_state,
const ExceptionCheckOperands& operands)
{
const auto& [power_pc, current_pc, downcount] = operands;
if ((ppc_state.Exceptions & EXCEPTION_DSI) != 0)
{
ppc_state.pc = current_pc;
ppc_state.downcount -= downcount;
power_pc.CheckExceptions();
return 0;
}
return sizeof(AnyCallback) + sizeof(operands);
}

s32 CachedInterpreter::CheckProgramException(PowerPC::PowerPCState& ppc_state,
const ExceptionCheckOperands& operands)
{
const auto& [power_pc, current_pc, downcount] = operands;
if ((ppc_state.Exceptions & EXCEPTION_PROGRAM) != 0)
{
ppc_state.pc = current_pc;
ppc_state.downcount -= downcount;
power_pc.CheckExceptions();
return 0;
}
return sizeof(AnyCallback) + sizeof(operands);
}

s32 CachedInterpreter::CheckBreakpoint(PowerPC::PowerPCState& ppc_state,
const CheckBreakpointOperands& operands)
{
Expand Down Expand Up @@ -348,12 +334,20 @@ bool CachedInterpreter::DoJit(u32 em_address, JitBlock* b, u32 nextPC)

if (op.canEndBlock)
Write(WritePC, {js.compilerPC});
Write(Interpret,
{interpreter, Interpreter::GetInterpreterOp(op.inst), js.compilerPC, op.inst});
if (jo.memcheck && (op.opinfo->flags & FL_LOADSTORE) != 0)
Write(CheckDSI, {power_pc, js.compilerPC, js.downcountAmount});
if (!op.canEndBlock && ShouldHandleFPExceptionForInstruction(&op))
Write(CheckProgramException, {power_pc, js.compilerPC, js.downcountAmount});

// Instruction may cause a DSI Exception or Program Exception.
if ((jo.memcheck && (op.opinfo->flags & FL_LOADSTORE) != 0) ||
(!op.canEndBlock && ShouldHandleFPExceptionForInstruction(&op)))
{
Write(InterpretAndCheckExceptions, {interpreter, Interpreter::GetInterpreterOp(op.inst),
js.compilerPC, op.inst, power_pc, js.downcountAmount});
}
else
{
Write(Interpret,
{interpreter, Interpreter::GetInterpreterOp(op.inst), js.compilerPC, op.inst});
}

if (op.branchIsIdleLoop)
Write(CheckIdle, {m_system.GetCoreTiming(), js.blockStart});
}
Expand Down
22 changes: 16 additions & 6 deletions Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,21 +64,21 @@ class CachedInterpreter : public JitBase, public CachedInterpreterCodeBlock

struct EndBlockOperands;
struct InterpretOperands;
struct InterpretAndCheckExceptionsOperands;
struct HLEFunctionOperands;
struct WritePCOperands;
struct ExceptionCheckOperands;
struct CheckFPUOperands;
struct CheckBreakpointOperands;
struct CheckIdleOperands;

static s32 EndBlock(PowerPC::PowerPCState& ppc_state, const EndBlockOperands& operands);
static s32 Interpret(PowerPC::PowerPCState& ppc_state, const InterpretOperands& operands);
static s32 InterpretAndCheckExceptions(PowerPC::PowerPCState& ppc_state,
const InterpretAndCheckExceptionsOperands& operands);
static s32 HLEFunction(PowerPC::PowerPCState& ppc_state, const HLEFunctionOperands& operands);
static s32 WritePC(PowerPC::PowerPCState& ppc_state, const WritePCOperands& operands);
static s32 WriteBrokenBlockNPC(PowerPC::PowerPCState& ppc_state, const WritePCOperands& operands);
static s32 CheckFPU(PowerPC::PowerPCState& ppc_state, const ExceptionCheckOperands& operands);
static s32 CheckDSI(PowerPC::PowerPCState& ppc_state, const ExceptionCheckOperands& operands);
static s32 CheckProgramException(PowerPC::PowerPCState& ppc_state,
const ExceptionCheckOperands& operands);
static s32 CheckFPU(PowerPC::PowerPCState& ppc_state, const CheckFPUOperands& operands);
static s32 CheckBreakpoint(PowerPC::PowerPCState& ppc_state,
const CheckBreakpointOperands& operands);
static s32 CheckIdle(PowerPC::PowerPCState& ppc_state, const CheckIdleOperands& operands);
Expand All @@ -103,6 +103,16 @@ struct CachedInterpreter::InterpretOperands
UGeckoInstruction inst;
};

struct CachedInterpreter::InterpretAndCheckExceptionsOperands
{
Interpreter& interpreter;
void (*func)(Interpreter&, UGeckoInstruction); // Interpreter::Instruction
u32 current_pc;
UGeckoInstruction inst;
PowerPC::PowerPCManager& power_pc;
u32 downcount;
};

struct CachedInterpreter::HLEFunctionOperands
{
Core::System& system;
Expand All @@ -116,7 +126,7 @@ struct CachedInterpreter::WritePCOperands
u32 : 32;
};

struct CachedInterpreter::ExceptionCheckOperands
struct CachedInterpreter::CheckFPUOperands
{
PowerPC::PowerPCManager& power_pc;
u32 current_pc;
Expand Down

0 comments on commit 1e55fd9

Please sign in to comment.