diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp index 0dfb75f441..43397d0355 100644 --- a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp @@ -452,13 +452,16 @@ void JitArm64::WriteExceptionExit(u32 destination, bool only_external) MOVI2R(DISPATCHER_PC, destination); FixupBranch no_exceptions = CBZ(W30); - STR(IndexType::Unsigned, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(pc)); - STR(IndexType::Unsigned, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(npc)); + static_assert(PPCSTATE_OFF(pc) <= 252); + static_assert(PPCSTATE_OFF(pc) + 4 == PPCSTATE_OFF(npc)); + STP(IndexType::Signed, DISPATCHER_PC, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(pc)); + if (only_external) MOVP2R(X8, &PowerPC::CheckExternalExceptions); else MOVP2R(X8, &PowerPC::CheckExceptions); BLR(X8); + LDR(IndexType::Unsigned, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(npc)); SetJumpTarget(no_exceptions); @@ -479,13 +482,16 @@ void JitArm64::WriteExceptionExit(ARM64Reg dest, bool only_external) LDR(IndexType::Unsigned, W30, PPC_REG, PPCSTATE_OFF(Exceptions)); FixupBranch no_exceptions = CBZ(W30); - STR(IndexType::Unsigned, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(pc)); - STR(IndexType::Unsigned, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(npc)); + static_assert(PPCSTATE_OFF(pc) <= 252); + static_assert(PPCSTATE_OFF(pc) + 4 == PPCSTATE_OFF(npc)); + STP(IndexType::Signed, DISPATCHER_PC, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(pc)); + if (only_external) MOVP2R(EncodeRegTo64(DISPATCHER_PC), &PowerPC::CheckExternalExceptions); else MOVP2R(EncodeRegTo64(DISPATCHER_PC), &PowerPC::CheckExceptions); BLR(EncodeRegTo64(DISPATCHER_PC)); + LDR(IndexType::Unsigned, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(npc)); SetJumpTarget(no_exceptions); diff --git a/Source/Core/Core/PowerPC/PowerPC.h b/Source/Core/Core/PowerPC/PowerPC.h index 3579d7a19e..34804dfb12 100644 --- a/Source/Core/Core/PowerPC/PowerPC.h +++ b/Source/Core/Core/PowerPC/PowerPC.h @@ -102,12 +102,16 @@ static_assert(std::is_standard_layout(), "PairedSingle must be sta // // On AArch64, most load/store instructions support fairly large immediate offsets, // but not LDP/STP, which we want to use for accessing certain things. +// These must be in the first 260 bytes: pc, npc // These must be in the first 520 bytes: gather_pipe_ptr, gather_pipe_base_ptr // Better code is generated if these are in the first 260 bytes: gpr // Better code is generated if these are in the first 520 bytes: ps // Unfortunately not all of those fit in 520 bytes, but we can fit most of ps and all of the rest. struct PowerPCState { + u32 pc; // program counter + u32 npc; + // gather pipe pointer for JIT access u8* gather_pipe_ptr; u8* gather_pipe_base_ptr; @@ -121,9 +125,6 @@ struct PowerPCState alignas(16) PairedSingle ps[32]; #endif - u32 pc; // program counter - u32 npc; - ConditionRegister cr; UReg_MSR msr; // machine state register