diff --git a/Core/MIPS/ARM/ArmCompBranch.cpp b/Core/MIPS/ARM/ArmCompBranch.cpp index 00dac7fa08..4577a46048 100644 --- a/Core/MIPS/ARM/ArmCompBranch.cpp +++ b/Core/MIPS/ARM/ArmCompBranch.cpp @@ -461,23 +461,28 @@ void Jit::Comp_JumpReg(MIPSOpcode op) } MIPSGPReg rs = _RS; MIPSGPReg rd = _RD; + bool andLink = (op & 0x3f) == 9; MIPSOpcode delaySlotOp = Memory::Read_Instruction(js.compilerPC + 4); bool delaySlotIsNice = IsDelaySlotNiceReg(op, delaySlotOp, rs); + if (andLink && rs == rd) + delaySlotIsNice = false; CONDITIONAL_NICE_DELAYSLOT; ARMReg destReg = R8; if (IsSyscall(delaySlotOp)) { - _dbg_assert_msg_(JIT, (op & 0x3f) == 8, "jalr followed by syscall not supported."); - gpr.MapReg(rs); MovToPC(gpr.R(rs)); // For syscall to be able to return. + if (andLink) + gpr.SetImm(rd, js.compilerPC + 8); CompileDelaySlot(DELAYSLOT_FLUSH); return; // Syscall wrote exit code. } else if (delaySlotIsNice) { + if (andLink) + gpr.SetImm(rd, js.compilerPC + 8); CompileDelaySlot(DELAYSLOT_NICE); - if (rs == MIPS_REG_RA && g_Config.bDiscardRegsOnJRRA) { + if (!andLink && rs == MIPS_REG_RA && g_Config.bDiscardRegsOnJRRA) { // According to the MIPS ABI, there are some regs we don't need to preserve. // Let's discard them so we don't need to write them back. // NOTE: Not all games follow the MIPS ABI! Tekken 6, for example, will crash @@ -492,9 +497,6 @@ void Jit::Comp_JumpReg(MIPSOpcode op) if (jo.continueJumps && gpr.IsImm(rs) && js.numInstructions < jo.continueMaxInstructions) { // Account for the increment in the loop. js.compilerPC = gpr.GetImm(rs) - 4; - if ((op & 0x3f) == 9) { - gpr.SetImm(rd, js.compilerPC + 8); - } // In case the delay slot was a break or something. js.compiling = true; return; @@ -507,6 +509,8 @@ void Jit::Comp_JumpReg(MIPSOpcode op) // Delay slot - this case is very rare, might be able to free up R8. gpr.MapReg(rs); MOV(R8, gpr.R(rs)); + if (andLink) + gpr.SetImm(rd, js.compilerPC + 8); CompileDelaySlot(DELAYSLOT_NICE); FlushAll(); } @@ -516,8 +520,6 @@ void Jit::Comp_JumpReg(MIPSOpcode op) case 8: //jr break; case 9: //jalr - gpr.SetRegImm(R0, js.compilerPC + 8); - STR(R0, CTXREG, (int)rd * 4); break; default: _dbg_assert_msg_(CPU,0,"Trying to compile instruction that can't be compiled"); diff --git a/Core/MIPS/x86/CompBranch.cpp b/Core/MIPS/x86/CompBranch.cpp index 20763a6cb2..9f96118cb1 100644 --- a/Core/MIPS/x86/CompBranch.cpp +++ b/Core/MIPS/x86/CompBranch.cpp @@ -587,18 +587,21 @@ void Jit::Comp_JumpReg(MIPSOpcode op) } MIPSGPReg rs = _RS; MIPSGPReg rd = _RD; + bool andLink = (op & 0x3f) == 9; MIPSOpcode delaySlotOp = Memory::Read_Instruction(js.compilerPC + 4); bool delaySlotIsNice = IsDelaySlotNiceReg(op, delaySlotOp, rs); + if (andLink && rs == rd) + delaySlotIsNice = false; CONDITIONAL_NICE_DELAYSLOT; if (IsSyscall(delaySlotOp)) { - _dbg_assert_msg_(JIT, (op & 0x3f) == 8, "jalr followed by syscall not supported."); - // If this is a syscall, write the pc (for thread switching and other good reasons.) gpr.MapReg(rs, true, false); MOV(32, M(¤tMIPS->pc), gpr.R(rs)); + if (andLink) + gpr.SetImm(rd, js.compilerPC + 8); CompileDelaySlot(DELAYSLOT_FLUSH); // Syscalls write the exit code for us. @@ -607,9 +610,11 @@ void Jit::Comp_JumpReg(MIPSOpcode op) } else if (delaySlotIsNice) { + if (andLink) + gpr.SetImm(rd, js.compilerPC + 8); CompileDelaySlot(DELAYSLOT_NICE); - if (rs == MIPS_REG_RA && g_Config.bDiscardRegsOnJRRA) { + if (!andLink && rs == MIPS_REG_RA && g_Config.bDiscardRegsOnJRRA) { // According to the MIPS ABI, there are some regs we don't need to preserve. // Let's discard them so we don't need to write them back. // NOTE: Not all games follow the MIPS ABI! Tekken 6, for example, will crash @@ -625,8 +630,6 @@ void Jit::Comp_JumpReg(MIPSOpcode op) { // Account for the increment in the loop. js.compilerPC = gpr.GetImm(rs) - 4; - if ((op & 0x3f) == 9) - gpr.SetImm(rd, js.compilerPC + 8); // In case the delay slot was a break or something. js.compiling = true; return; @@ -640,6 +643,8 @@ void Jit::Comp_JumpReg(MIPSOpcode op) // Latch destination now - save it in memory. gpr.MapReg(rs, true, false); MOV(32, M(&savedPC), gpr.R(rs)); + if (andLink) + gpr.SetImm(rd, js.compilerPC + 8); CompileDelaySlot(DELAYSLOT_NICE); MOV(32, R(EAX), M(&savedPC)); FlushAll(); @@ -650,7 +655,6 @@ void Jit::Comp_JumpReg(MIPSOpcode op) case 8: //jr break; case 9: //jalr - MOV(32, M(&mips_->r[rd]), Imm32(js.compilerPC + 8)); break; default: _dbg_assert_msg_(CPU,0,"Trying to compile instruction that can't be compiled");