diff --git a/Core/MIPS/ARM64/Arm64Asm.cpp b/Core/MIPS/ARM64/Arm64Asm.cpp index 8e452b8ff2..9b1104d1c6 100644 --- a/Core/MIPS/ARM64/Arm64Asm.cpp +++ b/Core/MIPS/ARM64/Arm64Asm.cpp @@ -151,24 +151,14 @@ void Arm64Jit::GenerateFixedCode(const JitOptions &jo) { SUBI2R(SCRATCH2, SCRATCH2, 1); SetJumpTarget(skipsub); + // Actually change the system FPCR register MRS(SCRATCH1_64, FIELD_FPCR); - // Clear both flush-to-zero and rounding before re-setting them. ANDI2R(SCRATCH1, SCRATCH1, ~((4 | 3) << 22)); ORR(SCRATCH1, SCRATCH1, SCRATCH2, ArithOption(SCRATCH2, ST_LSL, 22)); _MSR(FIELD_FPCR, SCRATCH1_64); SetJumpTarget(skip); - - // !! Can't skip this part at all, unless we restore it in restoreRoundingMode (which would not really be cheaper) - - // Let's update js.currentRoundingFunc with the right convertS0ToSCRATCH1 func. - MOVP2R(SCRATCH1_64, convertS0ToSCRATCH1); - // We already index this array including the FZ bit. Easy. - LSL(SCRATCH2, SCRATCH2, 3); - LDR(SCRATCH2_64, SCRATCH1_64, SCRATCH2); - MOVP2R(SCRATCH1_64, &js.currentRoundingFunc); - STR(INDEX_UNSIGNED, SCRATCH2_64, SCRATCH1_64, 0); RET(); } @@ -181,6 +171,7 @@ void Arm64Jit::GenerateFixedCode(const JitOptions &jo) { ADDI2R(SCRATCH2, SCRATCH2, 4); SetJumpTarget(skip); + PUSH(SCRATCH2); // We can only skip if the rounding mode is zero and flush is not set. // TODO: This actually seems to compare against 3?? CMPI2R(SCRATCH2, 0); @@ -189,6 +180,14 @@ void Arm64Jit::GenerateFixedCode(const JitOptions &jo) { MOVP2R(SCRATCH1_64, &js.hasSetRounding); STRB(INDEX_UNSIGNED, SCRATCH2, SCRATCH1_64, 0); SetJumpTarget(skip2); + POP(SCRATCH2); + + // Let's update js.currentRoundingFunc with the right convertS0ToSCRATCH1 func. + MOVP2R(SCRATCH1_64, convertS0ToSCRATCH1); + LSL(SCRATCH2, SCRATCH2, 3); + LDR(SCRATCH2_64, SCRATCH1_64, SCRATCH2); + MOVP2R(SCRATCH1_64, &js.currentRoundingFunc); + STR(INDEX_UNSIGNED, SCRATCH2_64, SCRATCH1_64, 0); RET(); } @@ -292,7 +291,8 @@ void Arm64Jit::GenerateFixedCode(const JitOptions &jo) { RET(); // Generate some integer conversion funcs. - static const RoundingMode roundModes[8] = {ROUND_N, ROUND_P, ROUND_M, ROUND_Z, ROUND_N, ROUND_P, ROUND_M, ROUND_Z,}; + // MIPS order! + static const RoundingMode roundModes[8] = { ROUND_N, ROUND_Z, ROUND_P, ROUND_M, ROUND_N, ROUND_Z, ROUND_P, ROUND_M }; for (size_t i = 0; i < ARRAY_SIZE(roundModes); ++i) { convertS0ToSCRATCH1[i] = AlignCode16(); diff --git a/Core/MIPS/ARM64/Arm64Jit.cpp b/Core/MIPS/ARM64/Arm64Jit.cpp index caf882a384..96dd7eb1bb 100644 --- a/Core/MIPS/ARM64/Arm64Jit.cpp +++ b/Core/MIPS/ARM64/Arm64Jit.cpp @@ -89,6 +89,10 @@ void Arm64Jit::DoState(PointerWrap &p) { } else { js.hasSetRounding = 1; } + + if (p.GetMode() == PointerWrap::MODE_READ) { + js.currentRoundingFunc = convertS0ToSCRATCH1[(mips_->fcr31) & 3]; + } } // This is here so the savestate matches between jit and non-jit.