diff --git a/Source/Core/Core/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/PowerPC/Jit64/Jit.cpp index 6cee5b971e3..1cdaf8c55ac 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit.cpp @@ -351,6 +351,7 @@ void Jit64::Shutdown() void Jit64::FallBackToInterpreter(UGeckoInstruction inst) { + FlushCarry(); gpr.Flush(BitSet32(0xFFFFFFFF), RegCache::IgnoreDiscardedRegisters::Yes); fpr.Flush(BitSet32(0xFFFFFFFF), RegCache::IgnoreDiscardedRegisters::Yes); diff --git a/Source/Core/Core/PowerPC/Jit64/Jit.h b/Source/Core/Core/PowerPC/Jit64/Jit.h index 8b96fda107a..ad5db1fa103 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit.h +++ b/Source/Core/Core/PowerPC/Jit64/Jit.h @@ -124,6 +124,7 @@ public: void FinalizeCarryOverflow(bool oe, bool inv = false); void FinalizeCarry(Gen::CCFlags cond); void FinalizeCarry(bool ca); + void FlushCarry(); void ComputeRC(preg_t preg, bool needs_test = true, bool needs_sext = true); void FinalizeImmediateRC(s32 value); diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp index 03bf2fc7867..8ce73201f08 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp @@ -137,6 +137,25 @@ void Jit64::FinalizeCarryOverflow(bool oe, bool inv) FinalizeCarry(inv ? CC_NC : CC_C); } +void Jit64::FlushCarry() +{ + switch (js.carryFlag) + { + case CarryFlag::InPPCState: + break; + case CarryFlag::InHostCarry: + JitSetCAIf(CC_C); + UnlockFlags(); + break; + case CarryFlag::InHostCarryInverted: + JitSetCAIf(CC_NC); + UnlockFlags(); + break; + } + + js.carryFlag = CarryFlag::InPPCState; +} + // Be careful; only set needs_test to false if we can be absolutely sure flags don't need // to be recalculated and haven't been clobbered. Keep in mind not all instructions set // sufficient flags -- for example, the flags from SHL/SHR are *not* sufficient for LT/GT