mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-14 21:37:52 -07:00
Jit64/JitArm64: Check Breakpoints Before FPU Availability
CachedInterpreter already does it in the expected order.
This commit is contained in:
parent
b6f0e8876e
commit
307a1e3ab8
@ -1035,6 +1035,30 @@ bool Jit64::DoJit(u32 em_address, JitBlock* b, u32 nextPC)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
auto& cpu = m_system.GetCPU();
|
||||||
|
auto& power_pc = m_system.GetPowerPC();
|
||||||
|
if (m_enable_debugging && power_pc.GetBreakPoints().IsAddressBreakPoint(op.address) &&
|
||||||
|
!cpu.IsStepping())
|
||||||
|
{
|
||||||
|
gpr.Flush();
|
||||||
|
fpr.Flush();
|
||||||
|
|
||||||
|
MOV(32, PPCSTATE(pc), Imm32(op.address));
|
||||||
|
ABI_PushRegistersAndAdjustStack({}, 0);
|
||||||
|
ABI_CallFunctionP(PowerPC::CheckBreakPointsFromJIT, &power_pc);
|
||||||
|
ABI_PopRegistersAndAdjustStack({}, 0);
|
||||||
|
MOV(64, R(RSCRATCH), ImmPtr(cpu.GetStatePtr()));
|
||||||
|
TEST(32, MatR(RSCRATCH), Imm32(0xFFFFFFFF));
|
||||||
|
FixupBranch noBreakpoint = J_CC(CC_Z);
|
||||||
|
|
||||||
|
Cleanup();
|
||||||
|
MOV(32, PPCSTATE(npc), Imm32(op.address));
|
||||||
|
SUB(32, PPCSTATE(downcount), Imm32(js.downcountAmount));
|
||||||
|
JMP(asm_routines.dispatcher_exit, Jump::Near);
|
||||||
|
|
||||||
|
SetJumpTarget(noBreakpoint);
|
||||||
|
}
|
||||||
|
|
||||||
if ((opinfo->flags & FL_USE_FPU) && !js.firstFPInstructionFound)
|
if ((opinfo->flags & FL_USE_FPU) && !js.firstFPInstructionFound)
|
||||||
{
|
{
|
||||||
// This instruction uses FPU - needs to add FP exception bailout
|
// This instruction uses FPU - needs to add FP exception bailout
|
||||||
@ -1061,30 +1085,6 @@ bool Jit64::DoJit(u32 em_address, JitBlock* b, u32 nextPC)
|
|||||||
js.firstFPInstructionFound = true;
|
js.firstFPInstructionFound = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& cpu = m_system.GetCPU();
|
|
||||||
auto& power_pc = m_system.GetPowerPC();
|
|
||||||
if (m_enable_debugging && power_pc.GetBreakPoints().IsAddressBreakPoint(op.address) &&
|
|
||||||
!cpu.IsStepping())
|
|
||||||
{
|
|
||||||
gpr.Flush();
|
|
||||||
fpr.Flush();
|
|
||||||
|
|
||||||
MOV(32, PPCSTATE(pc), Imm32(op.address));
|
|
||||||
ABI_PushRegistersAndAdjustStack({}, 0);
|
|
||||||
ABI_CallFunctionP(PowerPC::CheckBreakPointsFromJIT, &power_pc);
|
|
||||||
ABI_PopRegistersAndAdjustStack({}, 0);
|
|
||||||
MOV(64, R(RSCRATCH), ImmPtr(cpu.GetStatePtr()));
|
|
||||||
TEST(32, MatR(RSCRATCH), Imm32(0xFFFFFFFF));
|
|
||||||
FixupBranch noBreakpoint = J_CC(CC_Z);
|
|
||||||
|
|
||||||
Cleanup();
|
|
||||||
MOV(32, PPCSTATE(npc), Imm32(op.address));
|
|
||||||
SUB(32, PPCSTATE(downcount), Imm32(js.downcountAmount));
|
|
||||||
JMP(asm_routines.dispatcher_exit, Jump::Near);
|
|
||||||
|
|
||||||
SetJumpTarget(noBreakpoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bJITRegisterCacheOff)
|
if (bJITRegisterCacheOff)
|
||||||
{
|
{
|
||||||
gpr.Flush();
|
gpr.Flush();
|
||||||
|
@ -1169,35 +1169,6 @@ bool JitArm64::DoJit(u32 em_address, JitBlock* b, u32 nextPC)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((opinfo->flags & FL_USE_FPU) && !js.firstFPInstructionFound)
|
|
||||||
{
|
|
||||||
// This instruction uses FPU - needs to add FP exception bailout
|
|
||||||
ARM64Reg WA = gpr.GetReg();
|
|
||||||
LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(msr));
|
|
||||||
FixupBranch b1 = TBNZ(WA, 13); // Test FP enabled bit
|
|
||||||
|
|
||||||
FixupBranch far_addr = B();
|
|
||||||
SwitchToFarCode();
|
|
||||||
SetJumpTarget(far_addr);
|
|
||||||
|
|
||||||
gpr.Flush(FlushMode::MaintainState, WA);
|
|
||||||
fpr.Flush(FlushMode::MaintainState, ARM64Reg::INVALID_REG);
|
|
||||||
|
|
||||||
LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(Exceptions));
|
|
||||||
ORR(WA, WA, LogicalImm(EXCEPTION_FPU_UNAVAILABLE, GPRSize::B32));
|
|
||||||
STR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(Exceptions));
|
|
||||||
|
|
||||||
gpr.Unlock(WA);
|
|
||||||
|
|
||||||
WriteExceptionExit(js.compilerPC, false, true);
|
|
||||||
|
|
||||||
SwitchToNearCode();
|
|
||||||
|
|
||||||
SetJumpTarget(b1);
|
|
||||||
|
|
||||||
js.firstFPInstructionFound = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_enable_debugging && !cpu.IsStepping() &&
|
if (m_enable_debugging && !cpu.IsStepping() &&
|
||||||
m_system.GetPowerPC().GetBreakPoints().IsAddressBreakPoint(op.address))
|
m_system.GetPowerPC().GetBreakPoints().IsAddressBreakPoint(op.address))
|
||||||
{
|
{
|
||||||
@ -1228,6 +1199,35 @@ bool JitArm64::DoJit(u32 em_address, JitBlock* b, u32 nextPC)
|
|||||||
SetJumpTarget(no_breakpoint);
|
SetJumpTarget(no_breakpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((opinfo->flags & FL_USE_FPU) && !js.firstFPInstructionFound)
|
||||||
|
{
|
||||||
|
// This instruction uses FPU - needs to add FP exception bailout
|
||||||
|
ARM64Reg WA = gpr.GetReg();
|
||||||
|
LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(msr));
|
||||||
|
FixupBranch b1 = TBNZ(WA, 13); // Test FP enabled bit
|
||||||
|
|
||||||
|
FixupBranch far_addr = B();
|
||||||
|
SwitchToFarCode();
|
||||||
|
SetJumpTarget(far_addr);
|
||||||
|
|
||||||
|
gpr.Flush(FlushMode::MaintainState, WA);
|
||||||
|
fpr.Flush(FlushMode::MaintainState, ARM64Reg::INVALID_REG);
|
||||||
|
|
||||||
|
LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(Exceptions));
|
||||||
|
ORR(WA, WA, LogicalImm(EXCEPTION_FPU_UNAVAILABLE, GPRSize::B32));
|
||||||
|
STR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(Exceptions));
|
||||||
|
|
||||||
|
gpr.Unlock(WA);
|
||||||
|
|
||||||
|
WriteExceptionExit(js.compilerPC, false, true);
|
||||||
|
|
||||||
|
SwitchToNearCode();
|
||||||
|
|
||||||
|
SetJumpTarget(b1);
|
||||||
|
|
||||||
|
js.firstFPInstructionFound = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (bJITRegisterCacheOff)
|
if (bJITRegisterCacheOff)
|
||||||
{
|
{
|
||||||
FlushCarry();
|
FlushCarry();
|
||||||
|
Loading…
Reference in New Issue
Block a user