Merge pull request #12143 from JosJuice/jitarm64-loadstore-pc
JitArm64: Write PC when calling MMU.cpp
This commit is contained in:
commit
b53ecd73fb
|
@ -69,7 +69,7 @@ void Jit64::psq_stXX(UGeckoInstruction inst)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Stash PC in case asm_routine causes exception
|
// Stash PC in case asm routine needs to call into C++
|
||||||
MOV(32, PPCSTATE(pc), Imm32(js.compilerPC));
|
MOV(32, PPCSTATE(pc), Imm32(js.compilerPC));
|
||||||
// We know what GQR is here, so we can load RSCRATCH2 and call into the store method directly
|
// We know what GQR is here, so we can load RSCRATCH2 and call into the store method directly
|
||||||
// with just the scale bits.
|
// with just the scale bits.
|
||||||
|
@ -83,7 +83,7 @@ void Jit64::psq_stXX(UGeckoInstruction inst)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Stash PC incase asm_routine causes exception
|
// Stash PC in case asm routine needs to call into C++
|
||||||
MOV(32, PPCSTATE(pc), Imm32(js.compilerPC));
|
MOV(32, PPCSTATE(pc), Imm32(js.compilerPC));
|
||||||
// Some games (e.g. Dirt 2) incorrectly set the unused bits which breaks the lookup table code.
|
// Some games (e.g. Dirt 2) incorrectly set the unused bits which breaks the lookup table code.
|
||||||
// Hence, we need to mask out the unused bits. The layout of the GQR register is
|
// Hence, we need to mask out the unused bits. The layout of the GQR register is
|
||||||
|
@ -144,7 +144,7 @@ void Jit64::psq_lXX(UGeckoInstruction inst)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Stash PC in case asm_routine causes exception
|
// Stash PC in case asm routine needs to call into C++
|
||||||
MOV(32, PPCSTATE(pc), Imm32(js.compilerPC));
|
MOV(32, PPCSTATE(pc), Imm32(js.compilerPC));
|
||||||
// Get the high part of the GQR register
|
// Get the high part of the GQR register
|
||||||
OpArg gqr = PPCSTATE_SPR(SPR_GQR0 + i);
|
OpArg gqr = PPCSTATE_SPR(SPR_GQR0 + i);
|
||||||
|
|
|
@ -385,8 +385,11 @@ void EmuCodeBlock::SafeLoadToReg(X64Reg reg_value, const Gen::OpArg& opAddress,
|
||||||
SetJumpTarget(slow);
|
SetJumpTarget(slow);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helps external systems know which instruction triggered the read.
|
// PC is used by memory watchpoints (if enabled), profiling where to insert gather pipe
|
||||||
// Invalid for calls from Jit64AsmCommon routines
|
// interrupt checks, and printing accurate PC locations in debug logs.
|
||||||
|
//
|
||||||
|
// In the case of Jit64AsmCommon routines, we don't know the PC here,
|
||||||
|
// so the caller has to store the PC themselves.
|
||||||
if (!(flags & SAFE_LOADSTORE_NO_UPDATE_PC))
|
if (!(flags & SAFE_LOADSTORE_NO_UPDATE_PC))
|
||||||
{
|
{
|
||||||
MOV(32, PPCSTATE(pc), Imm32(js.compilerPC));
|
MOV(32, PPCSTATE(pc), Imm32(js.compilerPC));
|
||||||
|
@ -555,8 +558,11 @@ void EmuCodeBlock::SafeWriteRegToReg(OpArg reg_value, X64Reg reg_addr, int acces
|
||||||
SetJumpTarget(slow);
|
SetJumpTarget(slow);
|
||||||
}
|
}
|
||||||
|
|
||||||
// PC is used by memory watchpoints (if enabled) or to print accurate PC locations in debug logs
|
// PC is used by memory watchpoints (if enabled), profiling where to insert gather pipe
|
||||||
// Invalid for calls from Jit64AsmCommon routines
|
// interrupt checks, and printing accurate PC locations in debug logs.
|
||||||
|
//
|
||||||
|
// In the case of Jit64AsmCommon routines, we don't know the PC here,
|
||||||
|
// so the caller has to store the PC themselves.
|
||||||
if (!(flags & SAFE_LOADSTORE_NO_UPDATE_PC))
|
if (!(flags & SAFE_LOADSTORE_NO_UPDATE_PC))
|
||||||
{
|
{
|
||||||
MOV(32, PPCSTATE(pc), Imm32(js.compilerPC));
|
MOV(32, PPCSTATE(pc), Imm32(js.compilerPC));
|
||||||
|
|
|
@ -189,6 +189,17 @@ void JitArm64::EmitBackpatchRoutine(u32 flags, MemAccessMode mode, ARM64Reg RS,
|
||||||
ABI_PushRegisters(gprs_to_push & ~gprs_to_push_early);
|
ABI_PushRegisters(gprs_to_push & ~gprs_to_push_early);
|
||||||
m_float_emit.ABI_PushRegisters(fprs_to_push, ARM64Reg::X30);
|
m_float_emit.ABI_PushRegisters(fprs_to_push, ARM64Reg::X30);
|
||||||
|
|
||||||
|
// PC is used by memory watchpoints (if enabled), profiling where to insert gather pipe
|
||||||
|
// interrupt checks, and printing accurate PC locations in debug logs.
|
||||||
|
//
|
||||||
|
// In the case of JitAsm routines, we don't know the PC here,
|
||||||
|
// so the caller has to store the PC themselves.
|
||||||
|
if (!emitting_routine)
|
||||||
|
{
|
||||||
|
MOVI2R(ARM64Reg::W30, js.compilerPC);
|
||||||
|
STR(IndexType::Unsigned, ARM64Reg::W30, PPC_REG, PPCSTATE_OFF(pc));
|
||||||
|
}
|
||||||
|
|
||||||
if (flags & BackPatchInfo::FLAG_STORE)
|
if (flags & BackPatchInfo::FLAG_STORE)
|
||||||
{
|
{
|
||||||
ARM64Reg src_reg = RS;
|
ARM64Reg src_reg = RS;
|
||||||
|
|
|
@ -102,6 +102,11 @@ void JitArm64::psq_lXX(UGeckoInstruction inst)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LDR(IndexType::Unsigned, scale_reg, PPC_REG, PPCSTATE_OFF_SPR(SPR_GQR0 + i));
|
LDR(IndexType::Unsigned, scale_reg, PPC_REG, PPCSTATE_OFF_SPR(SPR_GQR0 + i));
|
||||||
|
|
||||||
|
// Stash PC in case asm routine needs to call into C++
|
||||||
|
MOVI2R(ARM64Reg::W30, js.compilerPC);
|
||||||
|
STR(IndexType::Unsigned, ARM64Reg::W30, PPC_REG, PPCSTATE_OFF(pc));
|
||||||
|
|
||||||
UBFM(type_reg, scale_reg, 16, 18); // Type
|
UBFM(type_reg, scale_reg, 16, 18); // Type
|
||||||
UBFM(scale_reg, scale_reg, 24, 29); // Scale
|
UBFM(scale_reg, scale_reg, 24, 29); // Scale
|
||||||
|
|
||||||
|
@ -254,6 +259,11 @@ void JitArm64::psq_stXX(UGeckoInstruction inst)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LDR(IndexType::Unsigned, scale_reg, PPC_REG, PPCSTATE_OFF_SPR(SPR_GQR0 + i));
|
LDR(IndexType::Unsigned, scale_reg, PPC_REG, PPCSTATE_OFF_SPR(SPR_GQR0 + i));
|
||||||
|
|
||||||
|
// Stash PC in case asm routine needs to call into C++
|
||||||
|
MOVI2R(ARM64Reg::W30, js.compilerPC);
|
||||||
|
STR(IndexType::Unsigned, ARM64Reg::W30, PPC_REG, PPCSTATE_OFF(pc));
|
||||||
|
|
||||||
UBFM(type_reg, scale_reg, 0, 2); // Type
|
UBFM(type_reg, scale_reg, 0, 2); // Type
|
||||||
UBFM(scale_reg, scale_reg, 8, 13); // Scale
|
UBFM(scale_reg, scale_reg, 8, 13); // Scale
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue