diff --git a/Source/Core/Core/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/PowerPC/Jit64/Jit.cpp index 4ebd633331..736855826e 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit.cpp @@ -623,12 +623,13 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc CMP(32, PPCSTATE(spr[SPR_GQR0 + gqr]), Imm8(0)); FixupBranch failure = J_CC(CC_NZ, true); SwitchToFarCode(); - SetJumpTarget(failure); - MOV(32, PPCSTATE(pc), Imm32(js.blockStart)); - ABI_PushRegistersAndAdjustStack({}, 0); - ABI_CallFunctionC((void *)&JitInterface::CompileExceptionCheck, (u32)JitInterface::ExceptionType::EXCEPTIONS_PAIRED_QUANTIZE); - ABI_PopRegistersAndAdjustStack({}, 0); - JMP(asm_routines.dispatcher, true); + SetJumpTarget(failure); + MOV(32, PPCSTATE(pc), Imm32(js.blockStart)); + ABI_PushRegistersAndAdjustStack({}, 0); + ABI_CallFunctionC((void *)&JitInterface::CompileExceptionCheck, + (u32)JitInterface::ExceptionType::EXCEPTIONS_PAIRED_QUANTIZE); + ABI_PopRegistersAndAdjustStack({}, 0); + JMP(asm_routines.dispatcher, true); SwitchToNearCode(); js.assumeNoPairedQuantize = true; } @@ -684,19 +685,21 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc { TEST(32, PPCSTATE(Exceptions), Imm32(EXCEPTION_EXTERNAL_INT)); FixupBranch extException = J_CC(CC_NZ, true); + SwitchToFarCode(); - SetJumpTarget(extException); - TEST(32, PPCSTATE(msr), Imm32(0x0008000)); - FixupBranch noExtIntEnable = J_CC(CC_Z, true); - TEST(32, M(&ProcessorInterface::m_InterruptCause), Imm32(ProcessorInterface::INT_CAUSE_CP | ProcessorInterface::INT_CAUSE_PE_TOKEN | ProcessorInterface::INT_CAUSE_PE_FINISH)); - FixupBranch noCPInt = J_CC(CC_Z, true); + SetJumpTarget(extException); + TEST(32, PPCSTATE(msr), Imm32(0x0008000)); + FixupBranch noExtIntEnable = J_CC(CC_Z, true); + TEST(32, M(&ProcessorInterface::m_InterruptCause), Imm32(ProcessorInterface::INT_CAUSE_CP | + ProcessorInterface::INT_CAUSE_PE_TOKEN | + ProcessorInterface::INT_CAUSE_PE_FINISH)); + FixupBranch noCPInt = J_CC(CC_Z, true); - gpr.Flush(FLUSH_MAINTAIN_STATE); - fpr.Flush(FLUSH_MAINTAIN_STATE); - - MOV(32, PPCSTATE(pc), Imm32(ops[i].address)); - WriteExternalExceptionExit(); + gpr.Flush(FLUSH_MAINTAIN_STATE); + fpr.Flush(FLUSH_MAINTAIN_STATE); + MOV(32, PPCSTATE(pc), Imm32(ops[i].address)); + WriteExternalExceptionExit(); SwitchToNearCode(); SetJumpTarget(noCPInt); @@ -731,18 +734,19 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc //This instruction uses FPU - needs to add FP exception bailout TEST(32, PPCSTATE(msr), Imm32(1 << 13)); // Test FP enabled bit FixupBranch b1 = J_CC(CC_Z, true); + SwitchToFarCode(); - SetJumpTarget(b1); - gpr.Flush(FLUSH_MAINTAIN_STATE); - fpr.Flush(FLUSH_MAINTAIN_STATE); - - // If a FPU exception occurs, the exception handler will read - // from PC. Update PC with the latest value in case that happens. - MOV(32, PPCSTATE(pc), Imm32(ops[i].address)); - OR(32, PPCSTATE(Exceptions), Imm32(EXCEPTION_FPU_UNAVAILABLE)); - WriteExceptionExit(); + SetJumpTarget(b1); + gpr.Flush(FLUSH_MAINTAIN_STATE); + fpr.Flush(FLUSH_MAINTAIN_STATE); + // If a FPU exception occurs, the exception handler will read + // from PC. Update PC with the latest value in case that happens. + MOV(32, PPCSTATE(pc), Imm32(ops[i].address)); + OR(32, PPCSTATE(Exceptions), Imm32(EXCEPTION_FPU_UNAVAILABLE)); + WriteExceptionExit(); SwitchToNearCode(); + js.firstFPInstructionFound = true; } @@ -802,29 +806,29 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc } SwitchToFarCode(); - if (!js.fastmemLoadStore) - { - exceptionHandlerAtLoc[js.fastmemLoadStore] = nullptr; - SetJumpTarget(js.fixupExceptionHandler ? js.exceptionHandler : memException); - } - else - { - exceptionHandlerAtLoc[js.fastmemLoadStore] = GetWritableCodePtr(); - } + if (!js.fastmemLoadStore) + { + exceptionHandlerAtLoc[js.fastmemLoadStore] = nullptr; + SetJumpTarget(js.fixupExceptionHandler ? js.exceptionHandler : memException); + } + else + { + exceptionHandlerAtLoc[js.fastmemLoadStore] = GetWritableCodePtr(); + } - BitSet32 gprToFlush = BitSet32::AllTrue(32); - BitSet32 fprToFlush = BitSet32::AllTrue(32); - if (js.revertGprLoad >= 0) - gprToFlush[js.revertGprLoad] = false; - if (js.revertFprLoad >= 0) - fprToFlush[js.revertFprLoad] = false; - gpr.Flush(FLUSH_MAINTAIN_STATE, gprToFlush); - fpr.Flush(FLUSH_MAINTAIN_STATE, fprToFlush); + BitSet32 gprToFlush = BitSet32::AllTrue(32); + BitSet32 fprToFlush = BitSet32::AllTrue(32); + if (js.revertGprLoad >= 0) + gprToFlush[js.revertGprLoad] = false; + if (js.revertFprLoad >= 0) + fprToFlush[js.revertFprLoad] = false; + gpr.Flush(FLUSH_MAINTAIN_STATE, gprToFlush); + fpr.Flush(FLUSH_MAINTAIN_STATE, fprToFlush); - // If a memory exception occurs, the exception handler will read - // from PC. Update PC with the latest value in case that happens. - MOV(32, PPCSTATE(pc), Imm32(ops[i].address)); - WriteExceptionExit(); + // If a memory exception occurs, the exception handler will read + // from PC. Update PC with the latest value in case that happens. + MOV(32, PPCSTATE(pc), Imm32(ops[i].address)); + WriteExceptionExit(); SwitchToNearCode(); } diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp index d1d89dcea8..e1e476a50d 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp @@ -336,15 +336,15 @@ void Jit64::dcbz(UGeckoInstruction inst) // Should this code ever run? I can't find any games that use DCBZ on non-physical addresses, but // supposedly there are, at least for some MMU titles. Let's be careful and support it to be sure. SwitchToFarCode(); - SetJumpTarget(slow); - MOV(32, M(&PC), Imm32(jit->js.compilerPC)); - BitSet32 registersInUse = CallerSavedRegistersInUse(); - ABI_PushRegistersAndAdjustStack(registersInUse, 0); - ABI_CallFunctionR((void *)&PowerPC::ClearCacheLine, RSCRATCH); - ABI_PopRegistersAndAdjustStack(registersInUse, 0); - FixupBranch exit = J(true); - + SetJumpTarget(slow); + MOV(32, M(&PC), Imm32(jit->js.compilerPC)); + BitSet32 registersInUse = CallerSavedRegistersInUse(); + ABI_PushRegistersAndAdjustStack(registersInUse, 0); + ABI_CallFunctionR((void *)&PowerPC::ClearCacheLine, RSCRATCH); + ABI_PopRegistersAndAdjustStack(registersInUse, 0); + FixupBranch exit = J(true); SwitchToNearCode(); + // Mask out the address so we don't write to MEM1 out of bounds // FIXME: Work out why the AGP disc writes out of bounds if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bWii) diff --git a/Source/Core/Core/PowerPC/JitCommon/Jit_Util.cpp b/Source/Core/Core/PowerPC/JitCommon/Jit_Util.cpp index a0a86faf50..8d0f917ac5 100644 --- a/Source/Core/Core/PowerPC/JitCommon/Jit_Util.cpp +++ b/Source/Core/Core/PowerPC/JitCommon/Jit_Util.cpp @@ -895,22 +895,22 @@ void EmuCodeBlock::ConvertDoubleToSingle(X64Reg dst, X64Reg src) CVTSD2SS(dst, R(src)); SwitchToFarCode(); - SetJumpTarget(nanConversion); - MOVQ_xmm(R(RSCRATCH), src); - // Put the quiet bit into CF. - BT(64, R(RSCRATCH), Imm8(51)); - CVTSD2SS(dst, R(src)); - FixupBranch continue1 = J_CC(CC_C, true); - // Clear the quiet bit of the SNaN, which was 0 (signalling) but got set to 1 (quiet) by conversion. - ANDPS(dst, M(&single_qnan_bit)); - FixupBranch continue2 = J(true); + SetJumpTarget(nanConversion); + MOVQ_xmm(R(RSCRATCH), src); + // Put the quiet bit into CF. + BT(64, R(RSCRATCH), Imm8(51)); + CVTSD2SS(dst, R(src)); + FixupBranch continue1 = J_CC(CC_C, true); + // Clear the quiet bit of the SNaN, which was 0 (signalling) but got set to 1 (quiet) by conversion. + ANDPS(dst, M(&single_qnan_bit)); + FixupBranch continue2 = J(true); - SetJumpTarget(denormalConversion); - MOVSD(M(&temp64), src); - FLD(64, M(&temp64)); - FSTP(32, M(&temp32)); - MOVSS(dst, M(&temp32)); - FixupBranch continue3 = J(true); + SetJumpTarget(denormalConversion); + MOVSD(M(&temp64), src); + FLD(64, M(&temp64)); + FSTP(32, M(&temp32)); + MOVSS(dst, M(&temp32)); + FixupBranch continue3 = J(true); SwitchToNearCode(); SetJumpTarget(continue1); @@ -941,11 +941,11 @@ void EmuCodeBlock::ConvertSingleToDouble(X64Reg dst, X64Reg src, bool src_is_gpr FixupBranch nanConversion = J_CC(CC_P, true); SwitchToFarCode(); - SetJumpTarget(nanConversion); - TEST(32, R(gprsrc), Imm32(0x00400000)); - FixupBranch continue1 = J_CC(CC_NZ, true); - ANDPD(dst, M(&double_qnan_bit)); - FixupBranch continue2 = J(true); + SetJumpTarget(nanConversion); + TEST(32, R(gprsrc), Imm32(0x00400000)); + FixupBranch continue1 = J_CC(CC_NZ, true); + ANDPD(dst, M(&double_qnan_bit)); + FixupBranch continue2 = J(true); SwitchToNearCode(); SetJumpTarget(continue1);