diff --git a/Core/MIPS/ARM/ArmAsm.cpp b/Core/MIPS/ARM/ArmAsm.cpp index 73704340e2..43340ebe98 100644 --- a/Core/MIPS/ARM/ArmAsm.cpp +++ b/Core/MIPS/ARM/ArmAsm.cpp @@ -74,15 +74,21 @@ using namespace ArmJitConstants; void ArmJit::GenerateFixedCode() { const u8 *start = GetCodePtr(); + // LR == SCRATCHREG2.... Maybe we could find some other register to use to avoid having to + // push LR? + restoreRoundingMode = AlignCode16(); { + PUSH(1, R_LR); VMRS(SCRATCHREG2); // Assume we're always in round-to-nearest mode beforehand. Flush-to-zero is off. BIC(SCRATCHREG2, SCRATCHREG2, AssumeMakeOperand2((3 | 4) << 22)); VMSR(SCRATCHREG2); - B(R_LR); + POP(1, R_PC); } + // Must preserve SCRATCHREG1 (R0) applyRoundingMode = AlignCode16(); { + PUSH(2, SCRATCHREG1, R_LR); LDR(SCRATCHREG2, CTXREG, offsetof(MIPSState, fcr31)); TST(SCRATCHREG2, AssumeMakeOperand2(1 << 24)); @@ -93,9 +99,8 @@ void ArmJit::GenerateFixedCode() { // We can only skip if the rounding mode is zero and flush is not set. CMP(SCRATCHREG2, Operand2(3)); - // At this point, if it was zero, we can skip the rest. + // At this point, if it was zero, we can skip the rest. (could even return) FixupBranch skip = B_CC(CC_EQ); - PUSH(1, SCRATCHREG1); // MIPS Rounding Mode: ARM Rounding Mode // 0: Round nearest 0 @@ -116,12 +121,13 @@ void ArmJit::GenerateFixedCode() { ORR(SCRATCHREG1, SCRATCHREG1, Operand2(SCRATCHREG2, ST_LSL, 22)); VMSR(SCRATCHREG1); - POP(1, SCRATCHREG1); SetJumpTarget(skip); - B(R_LR); + POP(2, SCRATCHREG1, R_PC); } + // Must preserve SCRATCHREG1 (R0) updateRoundingMode = AlignCode16(); { + PUSH(2, SCRATCHREG1, R_LR); LDR(SCRATCHREG2, CTXREG, offsetof(MIPSState, fcr31)); TST(SCRATCHREG2, AssumeMakeOperand2(1 << 24)); @@ -133,15 +139,15 @@ void ArmJit::GenerateFixedCode() { CMP(SCRATCHREG2, Operand2(3)); FixupBranch skip = B_CC(CC_EQ); - PUSH(1, SCRATCHREG1); MOVI2R(SCRATCHREG2, 1); MOVP2R(SCRATCHREG1, &js.hasSetRounding); STRB(SCRATCHREG2, SCRATCHREG1, 0); - POP(1, SCRATCHREG1); SetJumpTarget(skip); - B(R_LR); + POP(2, SCRATCHREG1, R_PC); } + FlushLitPool(); + enterDispatcher = AlignCode16(); DEBUG_LOG(JIT, "Base: %08x", (u32)Memory::base); diff --git a/Core/MIPS/ARM/ArmJit.cpp b/Core/MIPS/ARM/ArmJit.cpp index 7acd017a47..19eae73884 100644 --- a/Core/MIPS/ARM/ArmJit.cpp +++ b/Core/MIPS/ARM/ArmJit.cpp @@ -593,7 +593,7 @@ void ArmJit::RestoreRoundingMode(bool force) { } } -// Does not destroy R0 (SCRATCHREG1). Destroys R1 (SCRATCHREG2). +// Does not destroy R0 (SCRATCHREG1). Destroys R14 (SCRATCHREG2). void ArmJit::ApplyRoundingMode(bool force) { // If the game has never set an interesting rounding mode, we can safely skip this. if (force || js.hasSetRounding) { @@ -601,7 +601,7 @@ void ArmJit::ApplyRoundingMode(bool force) { } } -// Does (must!) not destroy R0 (SCRATCHREG1). Destroys R1 (SCRATCHREG2). +// Does (must!) not destroy R0 (SCRATCHREG1). Destroys R14 (SCRATCHREG2). void ArmJit::UpdateRoundingMode() { QuickCallFunction(R1, updateRoundingMode); } diff --git a/Core/MIPS/ARM64/Arm64Asm.cpp b/Core/MIPS/ARM64/Arm64Asm.cpp index 5b8e7aba2c..8eb5d8e50a 100644 --- a/Core/MIPS/ARM64/Arm64Asm.cpp +++ b/Core/MIPS/ARM64/Arm64Asm.cpp @@ -251,7 +251,7 @@ void Arm64Jit::GenerateFixedCode(const JitOptions &jo) { LDR(INDEX_UNSIGNED, SCRATCH1, CTXREG, offsetof(MIPSState, pc)); LDR(SCRATCH1, MEMBASEREG, SCRATCH1_64); - LSR(SCRATCH2, SCRATCH1, 24); + LSR(SCRATCH2, SCRATCH1, 24); // or UBFX(SCRATCH2, SCRATCH1, 24, 8) ANDI2R(SCRATCH1, SCRATCH1, 0x00FFFFFF); CMP(SCRATCH2, MIPS_EMUHACK_OPCODE >> 24); FixupBranch skipJump = B(CC_NEQ);