diff --git a/Core/MIPS/ARM64/Arm64Asm.cpp b/Core/MIPS/ARM64/Arm64Asm.cpp index 61bdbb4ef..d069d121c 100644 --- a/Core/MIPS/ARM64/Arm64Asm.cpp +++ b/Core/MIPS/ARM64/Arm64Asm.cpp @@ -99,11 +99,11 @@ void Arm64Jit::GenerateFixedCode(const JitOptions &jo) { if (jo.useStaticAlloc) { saveStaticRegisters = AlignCode16(); STR(INDEX_UNSIGNED, DOWNCOUNTREG, CTXREG, offsetof(MIPSState, downcount)); - gpr.EmitSaveStaticAllocs(); + gpr.EmitSaveStaticRegisters(); RET(); loadStaticRegisters = AlignCode16(); - gpr.EmitLoadStaticAllocs(); + gpr.EmitLoadStaticRegisters(); LDR(INDEX_UNSIGNED, DOWNCOUNTREG, CTXREG, offsetof(MIPSState, downcount)); RET(); @@ -172,7 +172,7 @@ void Arm64Jit::GenerateFixedCode(const JitOptions &jo) { MOV(W0, DOWNCOUNTREG); MOV(X1, MEMBASEREG); MOV(X2, JITBASEREG); - QuickCallFunction(SCRATCH1, (void *)&ShowPC); + QuickCallFunction(SCRATCH1_64, (void *)&ShowPC); } LDR(INDEX_UNSIGNED, SCRATCH1, CTXREG, offsetof(MIPSState, pc)); @@ -186,6 +186,7 @@ void Arm64Jit::GenerateFixedCode(const JitOptions &jo) { SetJumpTarget(skipJump); // No block found, let's jit. I don't think we actually need to save static regs that are in callee-save regs here but whatever. + // Also, rounding mode gotta be irrelevant here.. SaveStaticRegisters(); RestoreRoundingMode(true); QuickCallFunction(SCRATCH1_64, (void *)&MIPSComp::JitAt); diff --git a/Core/MIPS/ARM64/Arm64CompBranch.cpp b/Core/MIPS/ARM64/Arm64CompBranch.cpp index 7d943c42b..688faef0f 100644 --- a/Core/MIPS/ARM64/Arm64CompBranch.cpp +++ b/Core/MIPS/ARM64/Arm64CompBranch.cpp @@ -354,7 +354,7 @@ void Arm64Jit::Comp_FPUBranch(MIPSOpcode op) { case 2: BranchFPFlag(op, CC_NEQ, true); break; // bc1fl case 3: BranchFPFlag(op, CC_EQ, true); break; // bc1tl default: - _dbg_assert_msg_(CPU,0,"Trying to interpret instruction that can't be interpreted"); + _dbg_assert_msg_(CPU, 0, "Trying to interpret instruction that can't be interpreted"); break; } } @@ -585,7 +585,7 @@ void Arm64Jit::Comp_Syscall(MIPSOpcode op) // If we're in a delay slot, this is off by one. const int offset = js.inDelaySlot ? -1 : 0; - WriteDownCount(offset); + WriteDownCount(offset, false); RestoreRoundingMode(); js.downcountAmount = -offset; diff --git a/Core/MIPS/ARM64/Arm64Jit.cpp b/Core/MIPS/ARM64/Arm64Jit.cpp index 880bdda20..9ab45e396 100644 --- a/Core/MIPS/ARM64/Arm64Jit.cpp +++ b/Core/MIPS/ARM64/Arm64Jit.cpp @@ -463,7 +463,7 @@ void Arm64Jit::Comp_Generic(MIPSOpcode op) { MIPSInterpretFunc func = MIPSGetInterpretFunc(op); if (func) { SaveStaticRegisters(); - // TODO: Perhaps keep the rounding mode for interp? + // TODO: Perhaps keep the rounding mode for interp? Should probably, right? RestoreRoundingMode(); MOVI2R(SCRATCH1, GetCompilerPC()); MovToPC(SCRATCH1); @@ -507,13 +507,21 @@ void Arm64Jit::LoadStaticRegisters() { } } -void Arm64Jit::WriteDownCount(int offset) { +void Arm64Jit::WriteDownCount(int offset, bool updateFlags) { int theDowncount = js.downcountAmount + offset; - SUBSI2R(DOWNCOUNTREG, DOWNCOUNTREG, theDowncount, SCRATCH1); + if (updateFlags) { + SUBSI2R(DOWNCOUNTREG, DOWNCOUNTREG, theDowncount, SCRATCH1); + } else { + SUBI2R(DOWNCOUNTREG, DOWNCOUNTREG, theDowncount, SCRATCH1); + } } -void Arm64Jit::WriteDownCountR(ARM64Reg reg) { - SUBS(DOWNCOUNTREG, DOWNCOUNTREG, reg); +void Arm64Jit::WriteDownCountR(ARM64Reg reg, bool updateFlags) { + if (updateFlags) { + SUBS(DOWNCOUNTREG, DOWNCOUNTREG, reg); + } else { + SUB(DOWNCOUNTREG, DOWNCOUNTREG, reg); + } } void Arm64Jit::RestoreRoundingMode(bool force) { @@ -631,7 +639,7 @@ void Arm64Jit::WriteExit(u32 destination, int exit_num) { // Link opportunity! int block = blocks.GetBlockNumberFromStartAddress(destination); if (block >= 0 && jo.enableBlocklink) { - // It exists! Joy of joy! + // The target block exists! Directly link to its checked entrypoint. B(blocks.GetBlock(block)->checkedEntry); b->linkStatus[exit_num] = true; } else { diff --git a/Core/MIPS/ARM64/Arm64Jit.h b/Core/MIPS/ARM64/Arm64Jit.h index f4f277392..a0f41f118 100644 --- a/Core/MIPS/ARM64/Arm64Jit.h +++ b/Core/MIPS/ARM64/Arm64Jit.h @@ -187,8 +187,8 @@ private: void AddContinuedBlock(u32 dest); MIPSOpcode GetOffsetInstruction(int offset); - void WriteDownCount(int offset = 0); - void WriteDownCountR(Arm64Gen::ARM64Reg reg); + void WriteDownCount(int offset = 0, bool updateFlags = true); + void WriteDownCountR(Arm64Gen::ARM64Reg reg, bool updateFlags = true); void RestoreRoundingMode(bool force = false); void ApplyRoundingMode(bool force = false); void UpdateRoundingMode(); diff --git a/Core/MIPS/ARM64/Arm64RegCache.cpp b/Core/MIPS/ARM64/Arm64RegCache.cpp index 0e318cbb6..9be867887 100644 --- a/Core/MIPS/ARM64/Arm64RegCache.cpp +++ b/Core/MIPS/ARM64/Arm64RegCache.cpp @@ -58,6 +58,7 @@ void Arm64RegCache::Start(MIPSAnalyst::AnalysisResults &stats) { mr[statics[i].mr].loc = ML_ARMREG; mr[statics[i].mr].reg = statics[i].ar; mr[statics[i].mr].isStatic = true; + mr[statics[i].mr].spillLock = true; } } @@ -99,11 +100,10 @@ const Arm64RegCache::StaticAllocation *Arm64RegCache::GetStaticAllocations(int & } } -void Arm64RegCache::EmitLoadStaticAllocs() { +void Arm64RegCache::EmitLoadStaticRegisters() { int count; const StaticAllocation *allocs = GetStaticAllocations(count); // TODO: Use LDP when possible. - // This only needs to run once (by Asm) so checks don't need to be fast. for (int i = 0; i < count; i++) { int offset = GetMipsRegOffset(allocs[i].mr); emit_->LDR(INDEX_UNSIGNED, allocs[i].ar, CTXREG, offset); @@ -113,10 +113,10 @@ void Arm64RegCache::EmitLoadStaticAllocs() { } } -void Arm64RegCache::EmitSaveStaticAllocs() { +void Arm64RegCache::EmitSaveStaticRegisters() { int count; const StaticAllocation *allocs = GetStaticAllocations(count); - // TODO: Use LDP when possible. + // TODO: Use STP when possible. // This only needs to run once (by Asm) so checks don't need to be fast. for (int i = 0; i < count; i++) { int offset = GetMipsRegOffset(allocs[i].mr); diff --git a/Core/MIPS/ARM64/Arm64RegCache.h b/Core/MIPS/ARM64/Arm64RegCache.h index 5225c8bfb..dd759c432 100644 --- a/Core/MIPS/ARM64/Arm64RegCache.h +++ b/Core/MIPS/ARM64/Arm64RegCache.h @@ -134,9 +134,9 @@ public: int GetMipsRegOffset(MIPSGPReg r); - // Call these when leaving/entering the JIT - void EmitLoadStaticAllocs(); - void EmitSaveStaticAllocs(); + // These are called once on startup to generate functions, that you should then call. + void EmitLoadStaticRegisters(); + void EmitSaveStaticRegisters(); private: struct StaticAllocation {