From 81dec36da84c0ddf834e72d2813d87e5d29eb07f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 11 Apr 2015 01:07:10 -0700 Subject: [PATCH] Use an accessor to read the compilerPC. In the IR it will be read from the block. --- Core/MIPS/ARM/ArmCompBranch.cpp | 50 +++++++++++------------ Core/MIPS/ARM/ArmCompVFPU.cpp | 4 +- Core/MIPS/ARM/ArmJit.cpp | 34 +++++++++------- Core/MIPS/ARM/ArmJit.h | 1 + Core/MIPS/ARM64/Arm64CompBranch.cpp | 50 +++++++++++------------ Core/MIPS/ARM64/Arm64CompVFPU.cpp | 4 +- Core/MIPS/ARM64/Arm64Jit.cpp | 34 +++++++++------- Core/MIPS/ARM64/Arm64Jit.h | 1 + Core/MIPS/x86/CompALU.cpp | 4 +- Core/MIPS/x86/CompBranch.cpp | 62 ++++++++++++++--------------- Core/MIPS/x86/CompVFPU.cpp | 2 +- Core/MIPS/x86/Jit.cpp | 54 +++++++++++++------------ Core/MIPS/x86/Jit.h | 2 + Core/MIPS/x86/JitSafeMem.cpp | 12 +++--- 14 files changed, 164 insertions(+), 150 deletions(-) diff --git a/Core/MIPS/ARM/ArmCompBranch.cpp b/Core/MIPS/ARM/ArmCompBranch.cpp index 8bec6e123a..a7d5468937 100644 --- a/Core/MIPS/ARM/ArmCompBranch.cpp +++ b/Core/MIPS/ARM/ArmCompBranch.cpp @@ -60,13 +60,13 @@ namespace MIPSComp void ArmJit::BranchRSRTComp(MIPSOpcode op, CCFlags cc, bool likely) { if (js.inDelaySlot) { - ERROR_LOG_REPORT(JIT, "Branch in RSRTComp delay slot at %08x in block starting at %08x", js.compilerPC, js.blockStart); + ERROR_LOG_REPORT(JIT, "Branch in RSRTComp delay slot at %08x in block starting at %08x", GetCompilerPC(), js.blockStart); return; } int offset = _IMM16 << 2; MIPSGPReg rt = _RT; MIPSGPReg rs = _RS; - u32 targetAddr = js.compilerPC + offset + 4; + u32 targetAddr = GetCompilerPC() + offset + 4; bool immBranch = false; bool immBranchTaken = false; @@ -115,7 +115,7 @@ void ArmJit::BranchRSRTComp(MIPSOpcode op, CCFlags cc, bool likely) else FlushAll(); - const u32 destAddr = immBranchTaken ? targetAddr : js.compilerPC + 8; + const u32 destAddr = immBranchTaken ? targetAddr : GetCompilerPC() + 8; WriteExit(destAddr, js.nextExit++); } else { if (!likely && delaySlotIsNice) @@ -163,7 +163,7 @@ void ArmJit::BranchRSRTComp(MIPSOpcode op, CCFlags cc, bool likely) SetJumpTarget(ptr); // Not taken - WriteExit(js.compilerPC + 8, js.nextExit++); + WriteExit(GetCompilerPC() + 8, js.nextExit++); } js.compiling = false; @@ -173,12 +173,12 @@ void ArmJit::BranchRSRTComp(MIPSOpcode op, CCFlags cc, bool likely) void ArmJit::BranchRSZeroComp(MIPSOpcode op, CCFlags cc, bool andLink, bool likely) { if (js.inDelaySlot) { - ERROR_LOG_REPORT(JIT, "Branch in RSZeroComp delay slot at %08x in block starting at %08x", js.compilerPC, js.blockStart); + ERROR_LOG_REPORT(JIT, "Branch in RSZeroComp delay slot at %08x in block starting at %08x", GetCompilerPC(), js.blockStart); return; } int offset = _IMM16 << 2; MIPSGPReg rs = _RS; - u32 targetAddr = js.compilerPC + offset + 4; + u32 targetAddr = GetCompilerPC() + offset + 4; bool immBranch = false; bool immBranchTaken = false; @@ -210,7 +210,7 @@ void ArmJit::BranchRSZeroComp(MIPSOpcode op, CCFlags cc, bool andLink, bool like // Branch taken. Always compile the delay slot, and then go to dest. CompileDelaySlot(DELAYSLOT_NICE); if (andLink) - gpr.SetImm(MIPS_REG_RA, js.compilerPC + 8); + gpr.SetImm(MIPS_REG_RA, GetCompilerPC() + 8); AddContinuedBlock(targetAddr); // Account for the increment in the loop. @@ -227,13 +227,13 @@ void ArmJit::BranchRSZeroComp(MIPSOpcode op, CCFlags cc, bool andLink, bool like if (immBranch) { // Continuing is handled above, this is just static jumping. if (immBranchTaken && andLink) - gpr.SetImm(MIPS_REG_RA, js.compilerPC + 8); + gpr.SetImm(MIPS_REG_RA, GetCompilerPC() + 8); if (immBranchTaken || !likely) CompileDelaySlot(DELAYSLOT_FLUSH); else FlushAll(); - const u32 destAddr = immBranchTaken ? targetAddr : js.compilerPC + 8; + const u32 destAddr = immBranchTaken ? targetAddr : GetCompilerPC() + 8; WriteExit(destAddr, js.nextExit++); } else { if (!likely && delaySlotIsNice) @@ -261,7 +261,7 @@ void ArmJit::BranchRSZeroComp(MIPSOpcode op, CCFlags cc, bool andLink, bool like // Take the branch if (andLink) { - gpr.SetRegImm(SCRATCHREG1, js.compilerPC + 8); + gpr.SetRegImm(SCRATCHREG1, GetCompilerPC() + 8); STR(SCRATCHREG1, CTXREG, MIPS_REG_RA * 4); } @@ -269,7 +269,7 @@ void ArmJit::BranchRSZeroComp(MIPSOpcode op, CCFlags cc, bool andLink, bool like SetJumpTarget(ptr); // Not taken - WriteExit(js.compilerPC + 8, js.nextExit++); + WriteExit(GetCompilerPC() + 8, js.nextExit++); } js.compiling = false; } @@ -320,11 +320,11 @@ void ArmJit::Comp_RelBranchRI(MIPSOpcode op) void ArmJit::BranchFPFlag(MIPSOpcode op, CCFlags cc, bool likely) { if (js.inDelaySlot) { - ERROR_LOG_REPORT(JIT, "Branch in FPFlag delay slot at %08x in block starting at %08x", js.compilerPC, js.blockStart); + ERROR_LOG_REPORT(JIT, "Branch in FPFlag delay slot at %08x in block starting at %08x", GetCompilerPC(), js.blockStart); return; } int offset = _IMM16 << 2; - u32 targetAddr = js.compilerPC + offset + 4; + u32 targetAddr = GetCompilerPC() + offset + 4; MIPSOpcode delaySlotOp = GetOffsetInstruction(1); bool delaySlotIsNice = IsDelaySlotNiceFPU(op, delaySlotOp); @@ -356,7 +356,7 @@ void ArmJit::BranchFPFlag(MIPSOpcode op, CCFlags cc, bool likely) SetJumpTarget(ptr); // Not taken - WriteExit(js.compilerPC + 8, js.nextExit++); + WriteExit(GetCompilerPC() + 8, js.nextExit++); js.compiling = false; } @@ -378,11 +378,11 @@ void ArmJit::Comp_FPUBranch(MIPSOpcode op) void ArmJit::BranchVFPUFlag(MIPSOpcode op, CCFlags cc, bool likely) { if (js.inDelaySlot) { - ERROR_LOG_REPORT(JIT, "Branch in VFPU delay slot at %08x in block starting at %08x", js.compilerPC, js.blockStart); + ERROR_LOG_REPORT(JIT, "Branch in VFPU delay slot at %08x in block starting at %08x", GetCompilerPC(), js.blockStart); return; } int offset = _IMM16 << 2; - u32 targetAddr = js.compilerPC + offset + 4; + u32 targetAddr = GetCompilerPC() + offset + 4; MIPSOpcode delaySlotOp = GetOffsetInstruction(1); @@ -395,7 +395,7 @@ void ArmJit::BranchVFPUFlag(MIPSOpcode op, CCFlags cc, bool likely) if (!likely && delaySlotIsNice) CompileDelaySlot(DELAYSLOT_NICE); if (delaySlotIsBranch && (signed short)(delaySlotOp & 0xFFFF) != (signed short)(op & 0xFFFF) - 1) - ERROR_LOG_REPORT(JIT, "VFPU branch in VFPU delay slot at %08x with different target", js.compilerPC); + ERROR_LOG_REPORT(JIT, "VFPU branch in VFPU delay slot at %08x with different target", GetCompilerPC()); int imm3 = (op >> 18) & 7; @@ -426,7 +426,7 @@ void ArmJit::BranchVFPUFlag(MIPSOpcode op, CCFlags cc, bool likely) SetJumpTarget(ptr); // Not taken - u32 notTakenTarget = js.compilerPC + (delaySlotIsBranch ? 4 : 8); + u32 notTakenTarget = GetCompilerPC() + (delaySlotIsBranch ? 4 : 8); WriteExit(notTakenTarget, js.nextExit++); js.compiling = false; } @@ -444,11 +444,11 @@ void ArmJit::Comp_VBranch(MIPSOpcode op) void ArmJit::Comp_Jump(MIPSOpcode op) { if (js.inDelaySlot) { - ERROR_LOG_REPORT(JIT, "Branch in Jump delay slot at %08x in block starting at %08x", js.compilerPC, js.blockStart); + ERROR_LOG_REPORT(JIT, "Branch in Jump delay slot at %08x in block starting at %08x", GetCompilerPC(), js.blockStart); return; } u32 off = _IMM26 << 2; - u32 targetAddr = (js.compilerPC & 0xF0000000) | off; + u32 targetAddr = (GetCompilerPC() & 0xF0000000) | off; // Might be a stubbed address or something? if (!Memory::IsValidAddress(targetAddr)) { @@ -480,7 +480,7 @@ void ArmJit::Comp_Jump(MIPSOpcode op) { if (ReplaceJalTo(targetAddr)) return; - gpr.SetImm(MIPS_REG_RA, js.compilerPC + 8); + gpr.SetImm(MIPS_REG_RA, GetCompilerPC() + 8); CompileDelaySlot(DELAYSLOT_NICE); if (jo.continueJumps && js.numInstructions < jo.continueMaxInstructions) { AddContinuedBlock(targetAddr); @@ -504,7 +504,7 @@ void ArmJit::Comp_Jump(MIPSOpcode op) { void ArmJit::Comp_JumpReg(MIPSOpcode op) { if (js.inDelaySlot) { - ERROR_LOG_REPORT(JIT, "Branch in JumpReg delay slot at %08x in block starting at %08x", js.compilerPC, js.blockStart); + ERROR_LOG_REPORT(JIT, "Branch in JumpReg delay slot at %08x in block starting at %08x", GetCompilerPC(), js.blockStart); return; } MIPSGPReg rs = _RS; @@ -522,12 +522,12 @@ void ArmJit::Comp_JumpReg(MIPSOpcode op) gpr.MapReg(rs); MovToPC(gpr.R(rs)); // For syscall to be able to return. if (andLink) - gpr.SetImm(rd, js.compilerPC + 8); + gpr.SetImm(rd, GetCompilerPC() + 8); CompileDelaySlot(DELAYSLOT_FLUSH); return; // Syscall wrote exit code. } else if (delaySlotIsNice) { if (andLink) - gpr.SetImm(rd, js.compilerPC + 8); + gpr.SetImm(rd, GetCompilerPC() + 8); CompileDelaySlot(DELAYSLOT_NICE); if (!andLink && rs == MIPS_REG_RA && g_Config.bDiscardRegsOnJRRA) { @@ -559,7 +559,7 @@ void ArmJit::Comp_JumpReg(MIPSOpcode op) gpr.MapReg(rs); MOV(R8, gpr.R(rs)); if (andLink) - gpr.SetImm(rd, js.compilerPC + 8); + gpr.SetImm(rd, GetCompilerPC() + 8); CompileDelaySlot(DELAYSLOT_NICE); FlushAll(); } diff --git a/Core/MIPS/ARM/ArmCompVFPU.cpp b/Core/MIPS/ARM/ArmCompVFPU.cpp index d04884cdcb..3862dec1fc 100644 --- a/Core/MIPS/ARM/ArmCompVFPU.cpp +++ b/Core/MIPS/ARM/ArmCompVFPU.cpp @@ -136,7 +136,7 @@ namespace MIPSComp // Prefix may say "z, z, z, z" but if this is a pair, we force to x. // TODO: But some ops seem to use const 0 instead? if (regnum >= n) { - WARN_LOG(CPU, "JIT: Invalid VFPU swizzle: %08x : %d / %d at PC = %08x (%s)", prefix, regnum, n, js.compilerPC, MIPSDisasmAt(js.compilerPC)); + WARN_LOG(CPU, "JIT: Invalid VFPU swizzle: %08x : %d / %d at PC = %08x (%s)", prefix, regnum, n, GetCompilerPC(), MIPSDisasmAt(js.compilerPC)); regnum = 0; } @@ -2028,7 +2028,7 @@ namespace MIPSComp u8 dregs[4]; u8 dregs2[4]; - u32 nextOp = Memory::Read_Opcode_JIT(js.compilerPC + 4).encoding; + u32 nextOp = GetOffsetInstruction(1).encoding; int vd2 = -1; int imm2 = -1; if ((nextOp >> 26) == 60 && ((nextOp >> 21) & 0x1F) == 29 && _VS == MIPS_GET_VS(nextOp)) { diff --git a/Core/MIPS/ARM/ArmJit.cpp b/Core/MIPS/ARM/ArmJit.cpp index 6ee0af9703..ae5e4101c1 100644 --- a/Core/MIPS/ARM/ArmJit.cpp +++ b/Core/MIPS/ARM/ArmJit.cpp @@ -183,7 +183,7 @@ void ArmJit::CompileDelaySlot(int flags) MRS(R8); // Save flags register. R8 is preserved through function calls and is not allocated. js.inDelaySlot = true; - MIPSOpcode op = Memory::Read_Opcode_JIT(js.compilerPC + 4); + MIPSOpcode op = GetOffsetInstruction(1); MIPSCompileOp(op); js.inDelaySlot = false; @@ -215,7 +215,7 @@ void ArmJit::Compile(u32 em_address) { // Drat. The VFPU hit an uneaten prefix at the end of a block. if (js.startDefaultPrefix && js.MayHavePrefix()) { - WARN_LOG(JIT, "An uneaten prefix at end of block: %08x", js.compilerPC - 4); + WARN_LOG(JIT, "An uneaten prefix at end of block: %08x", GetCompilerPC() - 4); js.LogPrefix(); // Let's try that one more time. We won't get back here because we toggled the value. @@ -235,8 +235,12 @@ void ArmJit::RunLoopUntil(u64 globalticks) ((void (*)())enterCode)(); } +u32 ArmJit::GetCompilerPC() { + return js.compilerPC; +} + MIPSOpcode ArmJit::GetOffsetInstruction(int offset) { - return Memory::Read_Instruction(js.compilerPC + 4 * offset); + return Memory::Read_Instruction(GetCompilerPC() + 4 * offset); } const u8 *ArmJit::DoJit(u32 em_address, JitBlock *b) @@ -294,8 +298,8 @@ const u8 *ArmJit::DoJit(u32 em_address, JitBlock *b) js.numInstructions = 0; while (js.compiling) { - gpr.SetCompilerPC(js.compilerPC); // Let it know for log messages - MIPSOpcode inst = Memory::Read_Opcode_JIT(js.compilerPC); + gpr.SetCompilerPC(GetCompilerPC()); // Let it know for log messages + MIPSOpcode inst = Memory::Read_Opcode_JIT(GetCompilerPC()); //MIPSInfo info = MIPSGetInfo(inst); //if (info & IS_VFPU) { // logBlocks = 1; @@ -322,7 +326,7 @@ const u8 *ArmJit::DoJit(u32 em_address, JitBlock *b) if (GetSpaceLeft() < 0x800 || js.numInstructions >= JitBlockCache::MAX_BLOCK_INSTRUCTIONS) { FlushAll(); - WriteExit(js.compilerPC, js.nextExit++); + WriteExit(GetCompilerPC(), js.nextExit++); js.compiling = false; } } @@ -338,7 +342,7 @@ const u8 *ArmJit::DoJit(u32 em_address, JitBlock *b) char temp[256]; if (logBlocks > 0 && dontLogBlocks == 0) { INFO_LOG(JIT, "=============== mips ==============="); - for (u32 cpc = em_address; cpc != js.compilerPC + 4; cpc += 4) { + for (u32 cpc = em_address; cpc != GetCompilerPC() + 4; cpc += 4) { MIPSDisAsm(Memory::Read_Opcode_JIT(cpc), cpc, temp, true); INFO_LOG(JIT, "M: %08x %s", cpc, temp); } @@ -363,7 +367,7 @@ const u8 *ArmJit::DoJit(u32 em_address, JitBlock *b) else { // We continued at least once. Add the last proxy and set the originalSize correctly. - blocks.ProxyBlock(js.blockStart, js.lastContinuedPC, (js.compilerPC - js.lastContinuedPC) / sizeof(u32), GetCodePtr()); + blocks.ProxyBlock(js.blockStart, js.lastContinuedPC, (GetCompilerPC() - js.lastContinuedPC) / sizeof(u32), GetCodePtr()); b->originalSize = js.initialBlockSize; } return b->normalEntry; @@ -375,7 +379,7 @@ void ArmJit::AddContinuedBlock(u32 dest) if (js.lastContinuedPC == 0) js.initialBlockSize = js.numInstructions; else - blocks.ProxyBlock(js.blockStart, js.lastContinuedPC, (js.compilerPC - js.lastContinuedPC) / sizeof(u32), GetCodePtr()); + blocks.ProxyBlock(js.blockStart, js.lastContinuedPC, (GetCompilerPC() - js.lastContinuedPC) / sizeof(u32), GetCodePtr()); js.lastContinuedPC = dest; } @@ -420,7 +424,7 @@ bool ArmJit::ReplaceJalTo(u32 dest) { int cycles = (this->*repl)(); js.downcountAmount += cycles; } else { - gpr.SetImm(MIPS_REG_RA, js.compilerPC + 8); + gpr.SetImm(MIPS_REG_RA, GetCompilerPC() + 8); CompileDelaySlot(DELAYSLOT_NICE); FlushAll(); RestoreRoundingMode(); @@ -459,14 +463,14 @@ void ArmJit::Comp_ReplacementFunc(MIPSOpcode op) } if (entry->flags & REPFLAG_DISABLED) { - MIPSCompileOp(Memory::Read_Instruction(js.compilerPC, true)); + MIPSCompileOp(Memory::Read_Instruction(GetCompilerPC(), true)); } else if (entry->jitReplaceFunc) { MIPSReplaceFunc repl = entry->jitReplaceFunc; int cycles = (this->*repl)(); if (entry->flags & (REPFLAG_HOOKENTER | REPFLAG_HOOKEXIT)) { // Compile the original instruction at this address. We ignore cycles for hooks. - MIPSCompileOp(Memory::Read_Instruction(js.compilerPC, true)); + MIPSCompileOp(Memory::Read_Instruction(GetCompilerPC(), true)); } else { FlushAll(); // Flushed, so R1 is safe. @@ -478,7 +482,7 @@ void ArmJit::Comp_ReplacementFunc(MIPSOpcode op) } else if (entry->replaceFunc) { FlushAll(); RestoreRoundingMode(); - gpr.SetRegImm(SCRATCHREG1, js.compilerPC); + gpr.SetRegImm(SCRATCHREG1, GetCompilerPC()); MovToPC(SCRATCHREG1); // Standard function call, nothing fancy. @@ -493,7 +497,7 @@ void ArmJit::Comp_ReplacementFunc(MIPSOpcode op) if (entry->flags & (REPFLAG_HOOKENTER | REPFLAG_HOOKEXIT)) { // Compile the original instruction at this address. We ignore cycles for hooks. ApplyRoundingMode(); - MIPSCompileOp(Memory::Read_Instruction(js.compilerPC, true)); + MIPSCompileOp(Memory::Read_Instruction(GetCompilerPC(), true)); } else { ApplyRoundingMode(); LDR(R1, CTXREG, MIPS_REG_RA * 4); @@ -515,7 +519,7 @@ void ArmJit::Comp_Generic(MIPSOpcode op) SaveDowncount(); // TODO: Perhaps keep the rounding mode for interp? RestoreRoundingMode(); - gpr.SetRegImm(SCRATCHREG1, js.compilerPC); + gpr.SetRegImm(SCRATCHREG1, GetCompilerPC()); MovToPC(SCRATCHREG1); gpr.SetRegImm(R0, op.encoding); QuickCallFunction(R1, (void *)func); diff --git a/Core/MIPS/ARM/ArmJit.h b/Core/MIPS/ARM/ArmJit.h index 8d14d5129c..1712ee025f 100644 --- a/Core/MIPS/ARM/ArmJit.h +++ b/Core/MIPS/ARM/ArmJit.h @@ -211,6 +211,7 @@ private: void FlushAll(); void FlushPrefixV(); + u32 GetCompilerPC(); void CompileDelaySlot(int flags); void EatInstruction(MIPSOpcode op); void AddContinuedBlock(u32 dest); diff --git a/Core/MIPS/ARM64/Arm64CompBranch.cpp b/Core/MIPS/ARM64/Arm64CompBranch.cpp index f2e49868a9..e6ae97a78d 100644 --- a/Core/MIPS/ARM64/Arm64CompBranch.cpp +++ b/Core/MIPS/ARM64/Arm64CompBranch.cpp @@ -60,13 +60,13 @@ namespace MIPSComp void Arm64Jit::BranchRSRTComp(MIPSOpcode op, CCFlags cc, bool likely) { if (js.inDelaySlot) { - ERROR_LOG_REPORT(JIT, "Branch in RSRTComp delay slot at %08x in block starting at %08x", js.compilerPC, js.blockStart); + ERROR_LOG_REPORT(JIT, "Branch in RSRTComp delay slot at %08x in block starting at %08x", GetCompilerPC(), js.blockStart); return; } int offset = _IMM16 << 2; MIPSGPReg rt = _RT; MIPSGPReg rs = _RS; - u32 targetAddr = js.compilerPC + offset + 4; + u32 targetAddr = GetCompilerPC() + offset + 4; bool immBranch = false; bool immBranchTaken = false; @@ -115,7 +115,7 @@ void Arm64Jit::BranchRSRTComp(MIPSOpcode op, CCFlags cc, bool likely) else FlushAll(); - const u32 destAddr = immBranchTaken ? targetAddr : js.compilerPC + 8; + const u32 destAddr = immBranchTaken ? targetAddr : GetCompilerPC() + 8; WriteExit(destAddr, js.nextExit++); } else { if (!likely && delaySlotIsNice) @@ -151,7 +151,7 @@ void Arm64Jit::BranchRSRTComp(MIPSOpcode op, CCFlags cc, bool likely) SetJumpTarget(ptr); // Not taken - WriteExit(js.compilerPC + 8, js.nextExit++); + WriteExit(GetCompilerPC() + 8, js.nextExit++); } js.compiling = false; @@ -161,12 +161,12 @@ void Arm64Jit::BranchRSRTComp(MIPSOpcode op, CCFlags cc, bool likely) void Arm64Jit::BranchRSZeroComp(MIPSOpcode op, CCFlags cc, bool andLink, bool likely) { if (js.inDelaySlot) { - ERROR_LOG_REPORT(JIT, "Branch in RSZeroComp delay slot at %08x in block starting at %08x", js.compilerPC, js.blockStart); + ERROR_LOG_REPORT(JIT, "Branch in RSZeroComp delay slot at %08x in block starting at %08x", GetCompilerPC(), js.blockStart); return; } int offset = _IMM16 << 2; MIPSGPReg rs = _RS; - u32 targetAddr = js.compilerPC + offset + 4; + u32 targetAddr = GetCompilerPC() + offset + 4; bool immBranch = false; bool immBranchTaken = false; @@ -198,7 +198,7 @@ void Arm64Jit::BranchRSZeroComp(MIPSOpcode op, CCFlags cc, bool andLink, bool li // Branch taken. Always compile the delay slot, and then go to dest. CompileDelaySlot(DELAYSLOT_NICE); if (andLink) - gpr.SetImm(MIPS_REG_RA, js.compilerPC + 8); + gpr.SetImm(MIPS_REG_RA, GetCompilerPC() + 8); AddContinuedBlock(targetAddr); // Account for the increment in the loop. @@ -215,13 +215,13 @@ void Arm64Jit::BranchRSZeroComp(MIPSOpcode op, CCFlags cc, bool andLink, bool li if (immBranch) { // Continuing is handled above, this is just static jumping. if (immBranchTaken && andLink) - gpr.SetImm(MIPS_REG_RA, js.compilerPC + 8); + gpr.SetImm(MIPS_REG_RA, GetCompilerPC() + 8); if (immBranchTaken || !likely) CompileDelaySlot(DELAYSLOT_FLUSH); else FlushAll(); - const u32 destAddr = immBranchTaken ? targetAddr : js.compilerPC + 8; + const u32 destAddr = immBranchTaken ? targetAddr : GetCompilerPC() + 8; WriteExit(destAddr, js.nextExit++); } else { if (!likely && delaySlotIsNice) @@ -249,7 +249,7 @@ void Arm64Jit::BranchRSZeroComp(MIPSOpcode op, CCFlags cc, bool andLink, bool li // Take the branch if (andLink) { - gpr.SetRegImm(SCRATCH1, js.compilerPC + 8); + gpr.SetRegImm(SCRATCH1, GetCompilerPC() + 8); STR(INDEX_UNSIGNED, SCRATCH1, CTXREG, MIPS_REG_RA * 4); } @@ -257,7 +257,7 @@ void Arm64Jit::BranchRSZeroComp(MIPSOpcode op, CCFlags cc, bool andLink, bool li SetJumpTarget(ptr); // Not taken - WriteExit(js.compilerPC + 8, js.nextExit++); + WriteExit(GetCompilerPC() + 8, js.nextExit++); } js.compiling = false; } @@ -307,11 +307,11 @@ void Arm64Jit::Comp_RelBranchRI(MIPSOpcode op) // If likely is set, discard the branch slot if NOT taken. void Arm64Jit::BranchFPFlag(MIPSOpcode op, CCFlags cc, bool likely) { if (js.inDelaySlot) { - ERROR_LOG_REPORT(JIT, "Branch in FPFlag delay slot at %08x in block starting at %08x", js.compilerPC, js.blockStart); + ERROR_LOG_REPORT(JIT, "Branch in FPFlag delay slot at %08x in block starting at %08x", GetCompilerPC(), js.blockStart); return; } int offset = _IMM16 << 2; - u32 targetAddr = js.compilerPC + offset + 4; + u32 targetAddr = GetCompilerPC() + offset + 4; MIPSOpcode delaySlotOp = GetOffsetInstruction(1); bool delaySlotIsNice = IsDelaySlotNiceFPU(op, delaySlotOp); @@ -339,7 +339,7 @@ void Arm64Jit::BranchFPFlag(MIPSOpcode op, CCFlags cc, bool likely) { SetJumpTarget(ptr); // Not taken - WriteExit(js.compilerPC + 8, js.nextExit++); + WriteExit(GetCompilerPC() + 8, js.nextExit++); js.compiling = false; } @@ -358,11 +358,11 @@ void Arm64Jit::Comp_FPUBranch(MIPSOpcode op) { // If likely is set, discard the branch slot if NOT taken. void Arm64Jit::BranchVFPUFlag(MIPSOpcode op, CCFlags cc, bool likely) { if (js.inDelaySlot) { - ERROR_LOG_REPORT(JIT, "Branch in VFPU delay slot at %08x in block starting at %08x", js.compilerPC, js.blockStart); + ERROR_LOG_REPORT(JIT, "Branch in VFPU delay slot at %08x in block starting at %08x", GetCompilerPC(), js.blockStart); return; } int offset = _IMM16 << 2; - u32 targetAddr = js.compilerPC + offset + 4; + u32 targetAddr = GetCompilerPC() + offset + 4; MIPSOpcode delaySlotOp = GetOffsetInstruction(1); @@ -375,7 +375,7 @@ void Arm64Jit::BranchVFPUFlag(MIPSOpcode op, CCFlags cc, bool likely) { if (!likely && delaySlotIsNice) CompileDelaySlot(DELAYSLOT_NICE); if (delaySlotIsBranch && (signed short)(delaySlotOp & 0xFFFF) != (signed short)(op & 0xFFFF) - 1) - ERROR_LOG_REPORT(JIT, "VFPU branch in VFPU delay slot at %08x with different target", js.compilerPC); + ERROR_LOG_REPORT(JIT, "VFPU branch in VFPU delay slot at %08x with different target", GetCompilerPC()); int imm3 = (op >> 18) & 7; @@ -406,7 +406,7 @@ void Arm64Jit::BranchVFPUFlag(MIPSOpcode op, CCFlags cc, bool likely) { SetJumpTarget(ptr); // Not taken - u32 notTakenTarget = js.compilerPC + (delaySlotIsBranch ? 4 : 8); + u32 notTakenTarget = GetCompilerPC() + (delaySlotIsBranch ? 4 : 8); WriteExit(notTakenTarget, js.nextExit++); js.compiling = false; } @@ -424,11 +424,11 @@ void Arm64Jit::Comp_VBranch(MIPSOpcode op) void Arm64Jit::Comp_Jump(MIPSOpcode op) { if (js.inDelaySlot) { - ERROR_LOG_REPORT(JIT, "Branch in Jump delay slot at %08x in block starting at %08x", js.compilerPC, js.blockStart); + ERROR_LOG_REPORT(JIT, "Branch in Jump delay slot at %08x in block starting at %08x", GetCompilerPC(), js.blockStart); return; } u32 off = _IMM26 << 2; - u32 targetAddr = (js.compilerPC & 0xF0000000) | off; + u32 targetAddr = (GetCompilerPC() & 0xF0000000) | off; // Might be a stubbed address or something? if (!Memory::IsValidAddress(targetAddr)) { @@ -460,7 +460,7 @@ void Arm64Jit::Comp_Jump(MIPSOpcode op) { if (ReplaceJalTo(targetAddr)) return; - gpr.SetImm(MIPS_REG_RA, js.compilerPC + 8); + gpr.SetImm(MIPS_REG_RA, GetCompilerPC() + 8); CompileDelaySlot(DELAYSLOT_NICE); if (jo.continueJumps && js.numInstructions < jo.continueMaxInstructions) { AddContinuedBlock(targetAddr); @@ -484,7 +484,7 @@ void Arm64Jit::Comp_Jump(MIPSOpcode op) { void Arm64Jit::Comp_JumpReg(MIPSOpcode op) { if (js.inDelaySlot) { - ERROR_LOG_REPORT(JIT, "Branch in JumpReg delay slot at %08x in block starting at %08x", js.compilerPC, js.blockStart); + ERROR_LOG_REPORT(JIT, "Branch in JumpReg delay slot at %08x in block starting at %08x", GetCompilerPC(), js.blockStart); return; } MIPSGPReg rs = _RS; @@ -502,12 +502,12 @@ void Arm64Jit::Comp_JumpReg(MIPSOpcode op) gpr.MapReg(rs); MovToPC(gpr.R(rs)); // For syscall to be able to return. if (andLink) - gpr.SetImm(rd, js.compilerPC + 8); + gpr.SetImm(rd, GetCompilerPC() + 8); CompileDelaySlot(DELAYSLOT_FLUSH); return; // Syscall (delay slot) wrote exit code. } else if (delaySlotIsNice) { if (andLink) - gpr.SetImm(rd, js.compilerPC + 8); + gpr.SetImm(rd, GetCompilerPC() + 8); CompileDelaySlot(DELAYSLOT_NICE); if (!andLink && rs == MIPS_REG_RA && g_Config.bDiscardRegsOnJRRA) { @@ -539,7 +539,7 @@ void Arm64Jit::Comp_JumpReg(MIPSOpcode op) gpr.MapReg(rs); MOV(destReg, gpr.R(rs)); if (andLink) - gpr.SetImm(rd, js.compilerPC + 8); + gpr.SetImm(rd, GetCompilerPC() + 8); CompileDelaySlot(DELAYSLOT_NICE); FlushAll(); } diff --git a/Core/MIPS/ARM64/Arm64CompVFPU.cpp b/Core/MIPS/ARM64/Arm64CompVFPU.cpp index 70cfae1f66..fd4640bceb 100644 --- a/Core/MIPS/ARM64/Arm64CompVFPU.cpp +++ b/Core/MIPS/ARM64/Arm64CompVFPU.cpp @@ -130,7 +130,7 @@ namespace MIPSComp // Prefix may say "z, z, z, z" but if this is a pair, we force to x. // TODO: But some ops seem to use const 0 instead? if (regnum >= n) { - WARN_LOG(CPU, "JIT: Invalid VFPU swizzle: %08x : %d / %d at PC = %08x (%s)", prefix, regnum, n, js.compilerPC, MIPSDisasmAt(js.compilerPC)); + WARN_LOG(CPU, "JIT: Invalid VFPU swizzle: %08x : %d / %d at PC = %08x (%s)", prefix, regnum, n, GetCompilerPC(), MIPSDisasmAt(js.compilerPC)); regnum = 0; } @@ -1695,7 +1695,7 @@ namespace MIPSComp u8 dregs[4]; u8 dregs2[4]; - u32 nextOp = Memory::Read_Opcode_JIT(js.compilerPC + 4).encoding; + u32 nextOp = GetOffsetInstruction(1).encoding; int vd2 = -1; int imm2 = -1; if ((nextOp >> 26) == 60 && ((nextOp >> 21) & 0x1F) == 29 && _VS == MIPS_GET_VS(nextOp)) { diff --git a/Core/MIPS/ARM64/Arm64Jit.cpp b/Core/MIPS/ARM64/Arm64Jit.cpp index c37c254e41..1285f8d04a 100644 --- a/Core/MIPS/ARM64/Arm64Jit.cpp +++ b/Core/MIPS/ARM64/Arm64Jit.cpp @@ -167,7 +167,7 @@ void Arm64Jit::CompileDelaySlot(int flags) { MRS(FLAGTEMPREG, FIELD_NZCV); // Save flags register. FLAGTEMPREG is preserved through function calls and is not allocated. js.inDelaySlot = true; - MIPSOpcode op = Memory::Read_Opcode_JIT(js.compilerPC + 4); + MIPSOpcode op = GetOffsetInstruction(1); MIPSCompileOp(op); js.inDelaySlot = false; @@ -200,7 +200,7 @@ void Arm64Jit::Compile(u32 em_address) { // Drat. The VFPU hit an uneaten prefix at the end of a block. if (js.startDefaultPrefix && js.MayHavePrefix()) { - WARN_LOG(JIT, "An uneaten prefix at end of block: %08x", js.compilerPC - 4); + WARN_LOG(JIT, "An uneaten prefix at end of block: %08x", GetCompilerPC() - 4); js.LogPrefix(); // Let's try that one more time. We won't get back here because we toggled the value. @@ -220,8 +220,12 @@ void Arm64Jit::RunLoopUntil(u64 globalticks) { ((void (*)())enterCode)(); } +u32 Arm64Jit::GetCompilerPC() { + return js.compilerPC; +} + MIPSOpcode Arm64Jit::GetOffsetInstruction(int offset) { - return Memory::Read_Instruction(js.compilerPC + 4 * offset); + return Memory::Read_Instruction(GetCompilerPC() + 4 * offset); } const u8 *Arm64Jit::DoJit(u32 em_address, JitBlock *b) { @@ -275,8 +279,8 @@ const u8 *Arm64Jit::DoJit(u32 em_address, JitBlock *b) { js.numInstructions = 0; while (js.compiling) { - gpr.SetCompilerPC(js.compilerPC); // Let it know for log messages - MIPSOpcode inst = Memory::Read_Opcode_JIT(js.compilerPC); + gpr.SetCompilerPC(GetCompilerPC()); // Let it know for log messages + MIPSOpcode inst = Memory::Read_Opcode_JIT(GetCompilerPC()); js.downcountAmount += MIPSGetInstructionCycleEstimate(inst); @@ -288,7 +292,7 @@ const u8 *Arm64Jit::DoJit(u32 em_address, JitBlock *b) { // Safety check, in case we get a bunch of really large jit ops without a lot of branching. if (GetSpaceLeft() < 0x800 || js.numInstructions >= JitBlockCache::MAX_BLOCK_INSTRUCTIONS) { FlushAll(); - WriteExit(js.compilerPC, js.nextExit++); + WriteExit(GetCompilerPC(), js.nextExit++); js.compiling = false; } } @@ -302,7 +306,7 @@ const u8 *Arm64Jit::DoJit(u32 em_address, JitBlock *b) { char temp[256]; if (logBlocks > 0 && dontLogBlocks == 0) { ILOG("=============== mips ==============="); - for (u32 cpc = em_address; cpc != js.compilerPC + 4; cpc += 4) { + for (u32 cpc = em_address; cpc != GetCompilerPC() + 4; cpc += 4) { MIPSDisAsm(Memory::Read_Opcode_JIT(cpc), cpc, temp, true); ILOG("M: %08x %s", cpc, temp); } @@ -325,7 +329,7 @@ const u8 *Arm64Jit::DoJit(u32 em_address, JitBlock *b) { b->originalSize = js.numInstructions; } else { // We continued at least once. Add the last proxy and set the originalSize correctly. - blocks.ProxyBlock(js.blockStart, js.lastContinuedPC, (js.compilerPC - js.lastContinuedPC) / sizeof(u32), GetCodePtr()); + blocks.ProxyBlock(js.blockStart, js.lastContinuedPC, (GetCompilerPC() - js.lastContinuedPC) / sizeof(u32), GetCodePtr()); b->originalSize = js.initialBlockSize; } @@ -337,7 +341,7 @@ void Arm64Jit::AddContinuedBlock(u32 dest) { if (js.lastContinuedPC == 0) js.initialBlockSize = js.numInstructions; else - blocks.ProxyBlock(js.blockStart, js.lastContinuedPC, (js.compilerPC - js.lastContinuedPC) / sizeof(u32), GetCodePtr()); + blocks.ProxyBlock(js.blockStart, js.lastContinuedPC, (GetCompilerPC() - js.lastContinuedPC) / sizeof(u32), GetCodePtr()); js.lastContinuedPC = dest; } @@ -380,7 +384,7 @@ bool Arm64Jit::ReplaceJalTo(u32 dest) { int cycles = (this->*repl)(); js.downcountAmount += cycles; } else { - gpr.SetImm(MIPS_REG_RA, js.compilerPC + 8); + gpr.SetImm(MIPS_REG_RA, GetCompilerPC() + 8); CompileDelaySlot(DELAYSLOT_NICE); FlushAll(); RestoreRoundingMode(); @@ -414,7 +418,7 @@ void Arm64Jit::Comp_ReplacementFunc(MIPSOpcode op) } if (entry->flags & REPFLAG_DISABLED) { - MIPSCompileOp(Memory::Read_Instruction(js.compilerPC, true)); + MIPSCompileOp(Memory::Read_Instruction(GetCompilerPC(), true)); } else if (entry->jitReplaceFunc) { INFO_LOG(HLE, "JitReplaceFunc to %s", entry->name); MIPSReplaceFunc repl = entry->jitReplaceFunc; @@ -422,7 +426,7 @@ void Arm64Jit::Comp_ReplacementFunc(MIPSOpcode op) if (entry->flags & (REPFLAG_HOOKENTER | REPFLAG_HOOKEXIT)) { // Compile the original instruction at this address. We ignore cycles for hooks. - MIPSCompileOp(Memory::Read_Instruction(js.compilerPC, true)); + MIPSCompileOp(Memory::Read_Instruction(GetCompilerPC(), true)); } else { FlushAll(); // Flushed, so R1 is safe. @@ -435,7 +439,7 @@ void Arm64Jit::Comp_ReplacementFunc(MIPSOpcode op) INFO_LOG(HLE, "ReplaceFunc to %s", entry->name); FlushAll(); RestoreRoundingMode(); - gpr.SetRegImm(SCRATCH1, js.compilerPC); + gpr.SetRegImm(SCRATCH1, GetCompilerPC()); MovToPC(SCRATCH1); // Standard function call, nothing fancy. @@ -445,7 +449,7 @@ void Arm64Jit::Comp_ReplacementFunc(MIPSOpcode op) if (entry->flags & (REPFLAG_HOOKENTER | REPFLAG_HOOKEXIT)) { // Compile the original instruction at this address. We ignore cycles for hooks. ApplyRoundingMode(); - MIPSCompileOp(Memory::Read_Instruction(js.compilerPC, true)); + MIPSCompileOp(Memory::Read_Instruction(GetCompilerPC(), true)); } else { ApplyRoundingMode(); LDR(INDEX_UNSIGNED, W1, CTXREG, MIPS_REG_RA * 4); @@ -465,7 +469,7 @@ void Arm64Jit::Comp_Generic(MIPSOpcode op) { SaveDowncount(); // TODO: Perhaps keep the rounding mode for interp? RestoreRoundingMode(); - MOVI2R(SCRATCH1, js.compilerPC); + MOVI2R(SCRATCH1, GetCompilerPC()); MovToPC(SCRATCH1); MOVI2R(W0, op.encoding); QuickCallFunction(SCRATCH2_64, (void *)func); diff --git a/Core/MIPS/ARM64/Arm64Jit.h b/Core/MIPS/ARM64/Arm64Jit.h index 631e03cb5e..a9e9d16e84 100644 --- a/Core/MIPS/ARM64/Arm64Jit.h +++ b/Core/MIPS/ARM64/Arm64Jit.h @@ -207,6 +207,7 @@ private: void FlushAll(); void FlushPrefixV(); + u32 GetCompilerPC(); void CompileDelaySlot(int flags); void EatInstruction(MIPSOpcode op); void AddContinuedBlock(u32 dest); diff --git a/Core/MIPS/x86/CompALU.cpp b/Core/MIPS/x86/CompALU.cpp index 39e753039b..5303325967 100644 --- a/Core/MIPS/x86/CompALU.cpp +++ b/Core/MIPS/x86/CompALU.cpp @@ -485,7 +485,7 @@ namespace MIPSComp cc = SwapCCFlag(cc); } else if (!gpr.R(lhs).CanDoOpWith(gpr.R(rhs))) { // Let's try to pick which makes more sense to load. - if (MIPSAnalyst::IsRegisterUsed(rhs, js.compilerPC + 4, 3)) { + if (MIPSAnalyst::IsRegisterUsed(rhs, GetCompilerPC() + 4, 3)) { std::swap(lhs, rhs); cc = SwapCCFlag(cc); } @@ -525,7 +525,7 @@ namespace MIPSComp cc = SwapCCFlag(cc); } else if (!gpr.R(lhs).CanDoOpWith(gpr.R(rhs))) { // Let's try to pick which makes more sense to load. - if (MIPSAnalyst::IsRegisterUsed(rhs, js.compilerPC + 4, 3)) { + if (MIPSAnalyst::IsRegisterUsed(rhs, GetCompilerPC() + 4, 3)) { std::swap(lhs, rhs); cc = SwapCCFlag(cc); } diff --git a/Core/MIPS/x86/CompBranch.cpp b/Core/MIPS/x86/CompBranch.cpp index b53a5d2ae2..a725a7012f 100644 --- a/Core/MIPS/x86/CompBranch.cpp +++ b/Core/MIPS/x86/CompBranch.cpp @@ -112,7 +112,7 @@ static void JitBranchLogMismatch(MIPSOpcode op, u32 pc) void Jit::BranchLog(MIPSOpcode op) { FlushAll(); - ABI_CallFunctionCC(thunks.ProtectFunction(&JitBranchLog), op.encoding, js.compilerPC); + ABI_CallFunctionCC(thunks.ProtectFunction(&JitBranchLog), op.encoding, GetCompilerPC()); } void Jit::BranchLogExit(MIPSOpcode op, u32 dest, bool useEAX) @@ -123,7 +123,7 @@ void Jit::BranchLogExit(MIPSOpcode op, u32 dest, bool useEAX) FixupBranch skip = J_CC(CC_E); MOV(32, M(&jitBranchExit), destArg); - ABI_CallFunctionCC(thunks.ProtectFunction(&JitBranchLogMismatch), op.encoding, js.compilerPC); + ABI_CallFunctionCC(thunks.ProtectFunction(&JitBranchLogMismatch), op.encoding, GetCompilerPC()); // Restore EAX, we probably ruined it. if (useEAX) MOV(32, R(EAX), M(&jitBranchExit)); @@ -190,7 +190,7 @@ bool Jit::PredictTakeBranch(u32 targetAddr, bool likely) { // TODO: Normal branch prediction would be to take branches going upward to lower addresses. // However, this results in worse performance as of this comment's writing. // The reverse check generally gives better or same performance. - return targetAddr > js.compilerPC; + return targetAddr > GetCompilerPC(); } void Jit::CompBranchExits(CCFlags cc, u32 targetAddr, u32 notTakenAddr, bool delaySlotIsNice, bool likely, bool andLink) { @@ -236,7 +236,7 @@ void Jit::CompBranchExits(CCFlags cc, u32 targetAddr, u32 notTakenAddr, bool del CONDITIONAL_LOG_EXIT(targetAddr); if (andLink) - gpr.SetImm(MIPS_REG_RA, js.compilerPC + 8); + gpr.SetImm(MIPS_REG_RA, GetCompilerPC() + 8); // Don't forget to run the delay slot if likely. if (likely) @@ -252,7 +252,7 @@ void Jit::CompBranchExits(CCFlags cc, u32 targetAddr, u32 notTakenAddr, bool del { // Take the branch if (andLink) - MOV(32, gpr.GetDefaultLocation(MIPS_REG_RA), Imm32(js.compilerPC + 8)); + MOV(32, gpr.GetDefaultLocation(MIPS_REG_RA), Imm32(GetCompilerPC() + 8)); CONDITIONAL_LOG_EXIT(targetAddr); WriteExit(targetAddr, js.nextExit++); @@ -287,7 +287,7 @@ void Jit::CompBranchExits(CCFlags cc, u32 targetAddr, u32 notTakenAddr, bool del // Take the branch if (andLink) - MOV(32, gpr.GetDefaultLocation(MIPS_REG_RA), Imm32(js.compilerPC + 8)); + MOV(32, gpr.GetDefaultLocation(MIPS_REG_RA), Imm32(GetCompilerPC() + 8)); CONDITIONAL_LOG_EXIT(targetAddr); WriteExit(targetAddr, js.nextExit++); @@ -302,7 +302,7 @@ void Jit::CompBranchExits(CCFlags cc, u32 targetAddr, u32 notTakenAddr, bool del void Jit::CompBranchExit(bool taken, u32 targetAddr, u32 notTakenAddr, bool delaySlotIsNice, bool likely, bool andLink) { // Continuing is handled in the imm branch case... TODO: move it here? if (taken && andLink) - gpr.SetImm(MIPS_REG_RA, js.compilerPC + 8); + gpr.SetImm(MIPS_REG_RA, GetCompilerPC() + 8); if (taken || !likely) CompileDelaySlot(DELAYSLOT_FLUSH); else @@ -318,13 +318,13 @@ void Jit::BranchRSRTComp(MIPSOpcode op, Gen::CCFlags cc, bool likely) { CONDITIONAL_LOG; if (js.inDelaySlot) { - ERROR_LOG_REPORT(JIT, "Branch in RSRTComp delay slot at %08x in block starting at %08x", js.compilerPC, js.blockStart); + ERROR_LOG_REPORT(JIT, "Branch in RSRTComp delay slot at %08x in block starting at %08x", GetCompilerPC(), js.blockStart); return; } int offset = _IMM16 << 2; MIPSGPReg rt = _RT; MIPSGPReg rs = _RS; - u32 targetAddr = js.compilerPC + offset + 4; + u32 targetAddr = GetCompilerPC() + offset + 4; bool immBranch = false; bool immBranchTaken = false; @@ -369,7 +369,7 @@ void Jit::BranchRSRTComp(MIPSOpcode op, Gen::CCFlags cc, bool likely) CONDITIONAL_NICE_DELAYSLOT; if (immBranch) - CompBranchExit(immBranchTaken, targetAddr, js.compilerPC + 8, delaySlotIsNice, likely, false); + CompBranchExit(immBranchTaken, targetAddr, GetCompilerPC() + 8, delaySlotIsNice, likely, false); else { if (!likely && delaySlotIsNice) @@ -386,7 +386,7 @@ void Jit::BranchRSRTComp(MIPSOpcode op, Gen::CCFlags cc, bool likely) CMP(32, gpr.R(rs), gpr.R(rt)); } - CompBranchExits(cc, targetAddr, js.compilerPC + 8, delaySlotIsNice, likely, false); + CompBranchExits(cc, targetAddr, GetCompilerPC() + 8, delaySlotIsNice, likely, false); } } @@ -394,12 +394,12 @@ void Jit::BranchRSZeroComp(MIPSOpcode op, Gen::CCFlags cc, bool andLink, bool li { CONDITIONAL_LOG; if (js.inDelaySlot) { - ERROR_LOG_REPORT(JIT, "Branch in RSZeroComp delay slot at %08x in block starting at %08x", js.compilerPC, js.blockStart); + ERROR_LOG_REPORT(JIT, "Branch in RSZeroComp delay slot at %08x in block starting at %08x", GetCompilerPC(), js.blockStart); return; } int offset = _IMM16 << 2; MIPSGPReg rs = _RS; - u32 targetAddr = js.compilerPC + offset + 4; + u32 targetAddr = GetCompilerPC() + offset + 4; bool immBranch = false; bool immBranchTaken = false; @@ -433,7 +433,7 @@ void Jit::BranchRSZeroComp(MIPSOpcode op, Gen::CCFlags cc, bool andLink, bool li // Branch taken. Always compile the delay slot, and then go to dest. CompileDelaySlot(DELAYSLOT_NICE); if (andLink) - gpr.SetImm(MIPS_REG_RA, js.compilerPC + 8); + gpr.SetImm(MIPS_REG_RA, GetCompilerPC() + 8); AddContinuedBlock(targetAddr); // Account for the increment in the loop. @@ -448,7 +448,7 @@ void Jit::BranchRSZeroComp(MIPSOpcode op, Gen::CCFlags cc, bool andLink, bool li CONDITIONAL_NICE_DELAYSLOT; if (immBranch) - CompBranchExit(immBranchTaken, targetAddr, js.compilerPC + 8, delaySlotIsNice, likely, andLink); + CompBranchExit(immBranchTaken, targetAddr, GetCompilerPC() + 8, delaySlotIsNice, likely, andLink); else { if (!likely && delaySlotIsNice) @@ -457,7 +457,7 @@ void Jit::BranchRSZeroComp(MIPSOpcode op, Gen::CCFlags cc, bool andLink, bool li gpr.MapReg(rs, true, false); CMP(32, gpr.R(rs), Imm32(0)); - CompBranchExits(cc, targetAddr, js.compilerPC + 8, delaySlotIsNice, likely, andLink); + CompBranchExits(cc, targetAddr, GetCompilerPC() + 8, delaySlotIsNice, likely, andLink); } } @@ -508,11 +508,11 @@ void Jit::BranchFPFlag(MIPSOpcode op, Gen::CCFlags cc, bool likely) { CONDITIONAL_LOG; if (js.inDelaySlot) { - ERROR_LOG_REPORT(JIT, "Branch in FPFlag delay slot at %08x in block starting at %08x", js.compilerPC, js.blockStart); + ERROR_LOG_REPORT(JIT, "Branch in FPFlag delay slot at %08x in block starting at %08x", GetCompilerPC(), js.blockStart); return; } int offset = _IMM16 << 2; - u32 targetAddr = js.compilerPC + offset + 4; + u32 targetAddr = GetCompilerPC() + offset + 4; MIPSOpcode delaySlotOp = GetOffsetInstruction(1); bool delaySlotIsNice = IsDelaySlotNiceFPU(op, delaySlotOp); @@ -523,7 +523,7 @@ void Jit::BranchFPFlag(MIPSOpcode op, Gen::CCFlags cc, bool likely) gpr.KillImmediate(MIPS_REG_FPCOND, true, false); TEST(32, gpr.R(MIPS_REG_FPCOND), Imm32(1)); - CompBranchExits(cc, targetAddr, js.compilerPC + 8, delaySlotIsNice, likely, false); + CompBranchExits(cc, targetAddr, GetCompilerPC() + 8, delaySlotIsNice, likely, false); } @@ -546,11 +546,11 @@ void Jit::BranchVFPUFlag(MIPSOpcode op, Gen::CCFlags cc, bool likely) { CONDITIONAL_LOG; if (js.inDelaySlot) { - ERROR_LOG_REPORT(JIT, "Branch in VFPU delay slot at %08x in block starting at %08x", js.compilerPC, js.blockStart); + ERROR_LOG_REPORT(JIT, "Branch in VFPU delay slot at %08x in block starting at %08x", GetCompilerPC(), js.blockStart); return; } int offset = _IMM16 << 2; - u32 targetAddr = js.compilerPC + offset + 4; + u32 targetAddr = GetCompilerPC() + offset + 4; MIPSOpcode delaySlotOp = GetOffsetInstruction(1); @@ -563,7 +563,7 @@ void Jit::BranchVFPUFlag(MIPSOpcode op, Gen::CCFlags cc, bool likely) if (!likely && delaySlotIsNice) CompileDelaySlot(DELAYSLOT_NICE); if (delaySlotIsBranch && (signed short)(delaySlotOp & 0xFFFF) != (signed short)(op & 0xFFFF) - 1) - ERROR_LOG_REPORT(JIT, "VFPU branch in VFPU delay slot at %08x with different target %d / %d", js.compilerPC, (signed short)(delaySlotOp & 0xFFFF), (signed short)(op & 0xFFFF) - 1); + ERROR_LOG_REPORT(JIT, "VFPU branch in VFPU delay slot at %08x with different target %d / %d", GetCompilerPC(), (signed short)(delaySlotOp & 0xFFFF), (signed short)(op & 0xFFFF) - 1); // THE CONDITION int imm3 = (op >> 18) & 7; @@ -571,7 +571,7 @@ void Jit::BranchVFPUFlag(MIPSOpcode op, Gen::CCFlags cc, bool likely) gpr.KillImmediate(MIPS_REG_VFPUCC, true, false); TEST(32, gpr.R(MIPS_REG_VFPUCC), Imm32(1 << imm3)); - u32 notTakenTarget = js.compilerPC + (delaySlotIsBranch ? 4 : 8); + u32 notTakenTarget = GetCompilerPC() + (delaySlotIsBranch ? 4 : 8); CompBranchExits(cc, targetAddr, notTakenTarget, delaySlotIsNice, likely, false); } @@ -593,16 +593,16 @@ void Jit::Comp_VBranch(MIPSOpcode op) void Jit::Comp_Jump(MIPSOpcode op) { CONDITIONAL_LOG; if (js.inDelaySlot) { - ERROR_LOG_REPORT(JIT, "Branch in Jump delay slot at %08x in block starting at %08x", js.compilerPC, js.blockStart); + ERROR_LOG_REPORT(JIT, "Branch in Jump delay slot at %08x in block starting at %08x", GetCompilerPC(), js.blockStart); return; } u32 off = _IMM26 << 2; - u32 targetAddr = (js.compilerPC & 0xF0000000) | off; + u32 targetAddr = (GetCompilerPC() & 0xF0000000) | off; // Might be a stubbed address or something? if (!Memory::IsValidAddress(targetAddr)) { if (js.nextExit == 0) { - ERROR_LOG_REPORT(JIT, "Jump to invalid address: %08x PC %08x LR %08x", targetAddr, js.compilerPC, currentMIPS->r[MIPS_REG_RA]); + ERROR_LOG_REPORT(JIT, "Jump to invalid address: %08x PC %08x LR %08x", targetAddr, GetCompilerPC(), currentMIPS->r[MIPS_REG_RA]); } else { js.compiling = false; } @@ -636,7 +636,7 @@ void Jit::Comp_Jump(MIPSOpcode op) { // Save return address - might be overwritten by delay slot. - gpr.SetImm(MIPS_REG_RA, js.compilerPC + 8); + gpr.SetImm(MIPS_REG_RA, GetCompilerPC() + 8); CompileDelaySlot(DELAYSLOT_NICE); if (CanContinueJump(targetAddr)) { @@ -665,7 +665,7 @@ void Jit::Comp_JumpReg(MIPSOpcode op) { CONDITIONAL_LOG; if (js.inDelaySlot) { - ERROR_LOG_REPORT(JIT, "Branch in JumpReg delay slot at %08x in block starting at %08x", js.compilerPC, js.blockStart); + ERROR_LOG_REPORT(JIT, "Branch in JumpReg delay slot at %08x in block starting at %08x", GetCompilerPC(), js.blockStart); return; } MIPSGPReg rs = _RS; @@ -684,7 +684,7 @@ void Jit::Comp_JumpReg(MIPSOpcode op) gpr.MapReg(rs, true, false); MOV(32, M(&mips_->pc), gpr.R(rs)); if (andLink) - gpr.SetImm(rd, js.compilerPC + 8); + gpr.SetImm(rd, GetCompilerPC() + 8); CompileDelaySlot(DELAYSLOT_FLUSH); // Syscalls write the exit code for us. @@ -694,7 +694,7 @@ void Jit::Comp_JumpReg(MIPSOpcode op) else if (delaySlotIsNice) { if (andLink) - gpr.SetImm(rd, js.compilerPC + 8); + gpr.SetImm(rd, GetCompilerPC() + 8); CompileDelaySlot(DELAYSLOT_NICE); if (!andLink && rs == MIPS_REG_RA && g_Config.bDiscardRegsOnJRRA) { @@ -728,7 +728,7 @@ void Jit::Comp_JumpReg(MIPSOpcode op) gpr.MapReg(rs, true, false); MOV(32, M(&savedPC), gpr.R(rs)); if (andLink) - gpr.SetImm(rd, js.compilerPC + 8); + gpr.SetImm(rd, GetCompilerPC() + 8); CompileDelaySlot(DELAYSLOT_NICE); MOV(32, R(EAX), M(&savedPC)); FlushAll(); diff --git a/Core/MIPS/x86/CompVFPU.cpp b/Core/MIPS/x86/CompVFPU.cpp index 89f76fabce..7dd27d0443 100644 --- a/Core/MIPS/x86/CompVFPU.cpp +++ b/Core/MIPS/x86/CompVFPU.cpp @@ -3394,7 +3394,7 @@ void Jit::Comp_VRot(MIPSOpcode op) { u8 dregs[4]; u8 dregs2[4]; - u32 nextOp = Memory::Read_Opcode_JIT(js.compilerPC + 4).encoding; + u32 nextOp = GetOffsetInstruction(1).encoding; int vd2 = -1; int imm2 = -1; if ((nextOp >> 26) == 60 && ((nextOp >> 21) & 0x1F) == 29 && _VS == MIPS_GET_VS(nextOp)) { diff --git a/Core/MIPS/x86/Jit.cpp b/Core/MIPS/x86/Jit.cpp index adbbf19c3a..886a9e54e0 100644 --- a/Core/MIPS/x86/Jit.cpp +++ b/Core/MIPS/x86/Jit.cpp @@ -319,16 +319,14 @@ void Jit::InvalidateCache() void Jit::CompileDelaySlot(int flags, RegCacheState *state) { - const u32 addr = js.compilerPC + 4; - // Need to offset the downcount which was already incremented for the branch + delay slot. - CheckJitBreakpoint(addr, -2); + CheckJitBreakpoint(GetCompilerPC() + 4, -2); if (flags & DELAYSLOT_SAFE) SAVE_FLAGS; // preserve flag around the delay slot! js.inDelaySlot = true; - MIPSOpcode op = Memory::Read_Opcode_JIT(addr); + MIPSOpcode op = GetOffsetInstruction(1); MIPSCompileOp(op); js.inDelaySlot = false; @@ -353,7 +351,7 @@ void Jit::EatInstruction(MIPSOpcode op) ERROR_LOG_REPORT_ONCE(ateInDelaySlot, JIT, "Ate an instruction inside a delay slot."); } - CheckJitBreakpoint(js.compilerPC + 4, 0); + CheckJitBreakpoint(GetCompilerPC() + 4, 0); js.numInstructions++; js.compilerPC += 4; js.downcountAmount += MIPSGetInstructionCycleEstimate(op); @@ -382,7 +380,7 @@ void Jit::Compile(u32 em_address) // Drat. The VFPU hit an uneaten prefix at the end of a block. if (js.startDefaultPrefix && js.MayHavePrefix()) { - WARN_LOG(JIT, "An uneaten prefix at end of block: %08x", js.compilerPC - 4); + WARN_LOG(JIT, "An uneaten prefix at end of block: %08x", GetCompilerPC() - 4); js.LogPrefix(); // Let's try that one more time. We won't get back here because we toggled the value. @@ -402,8 +400,12 @@ void Jit::RunLoopUntil(u64 globalticks) ((void (*)())asm_.enterCode)(); } +u32 Jit::GetCompilerPC() { + return js.compilerPC; +} + MIPSOpcode Jit::GetOffsetInstruction(int offset) { - return Memory::Read_Instruction(js.compilerPC + 4 * offset); + return Memory::Read_Instruction(GetCompilerPC() + 4 * offset); } const u8 *Jit::DoJit(u32 em_address, JitBlock *b) @@ -438,9 +440,9 @@ const u8 *Jit::DoJit(u32 em_address, JitBlock *b) js.numInstructions = 0; while (js.compiling) { // Jit breakpoints are quite fast, so let's do them in release too. - CheckJitBreakpoint(js.compilerPC, 0); + CheckJitBreakpoint(GetCompilerPC(), 0); - MIPSOpcode inst = Memory::Read_Opcode_JIT(js.compilerPC); + MIPSOpcode inst = Memory::Read_Opcode_JIT(GetCompilerPC()); js.downcountAmount += MIPSGetInstructionCycleEstimate(inst); MIPSCompileOp(inst); @@ -455,9 +457,9 @@ const u8 *Jit::DoJit(u32 em_address, JitBlock *b) CMP(32, M(&coreState), Imm32(CORE_NEXTFRAME)); FixupBranch skipCheck = J_CC(CC_LE); if (js.afterOp & JitState::AFTER_REWIND_PC_BAD_STATE) - MOV(32, M(&mips_->pc), Imm32(js.compilerPC)); + MOV(32, M(&mips_->pc), Imm32(GetCompilerPC())); else - MOV(32, M(&mips_->pc), Imm32(js.compilerPC + 4)); + MOV(32, M(&mips_->pc), Imm32(GetCompilerPC() + 4)); WriteSyscallExit(); SetJumpTarget(skipCheck); @@ -474,7 +476,7 @@ const u8 *Jit::DoJit(u32 em_address, JitBlock *b) if (GetSpaceLeft() < 0x800 || js.numInstructions >= JitBlockCache::MAX_BLOCK_INSTRUCTIONS) { FlushAll(); - WriteExit(js.compilerPC, js.nextExit++); + WriteExit(GetCompilerPC(), js.nextExit++); js.compiling = false; } } @@ -487,7 +489,7 @@ const u8 *Jit::DoJit(u32 em_address, JitBlock *b) else { // We continued at least once. Add the last proxy and set the originalSize correctly. - blocks.ProxyBlock(js.blockStart, js.lastContinuedPC, (js.compilerPC - js.lastContinuedPC) / sizeof(u32), GetCodePtr()); + blocks.ProxyBlock(js.blockStart, js.lastContinuedPC, (GetCompilerPC() - js.lastContinuedPC) / sizeof(u32), GetCodePtr()); b->originalSize = js.initialBlockSize; } return b->normalEntry; @@ -499,7 +501,7 @@ void Jit::AddContinuedBlock(u32 dest) if (js.lastContinuedPC == 0) js.initialBlockSize = js.numInstructions; else - blocks.ProxyBlock(js.blockStart, js.lastContinuedPC, (js.compilerPC - js.lastContinuedPC) / sizeof(u32), GetCodePtr()); + blocks.ProxyBlock(js.blockStart, js.lastContinuedPC, (GetCompilerPC() - js.lastContinuedPC) / sizeof(u32), GetCodePtr()); js.lastContinuedPC = dest; } @@ -583,10 +585,10 @@ bool Jit::ReplaceJalTo(u32 dest) { int cycles = (this->*repl)(); js.downcountAmount += cycles; } else { - gpr.SetImm(MIPS_REG_RA, js.compilerPC + 8); + gpr.SetImm(MIPS_REG_RA, GetCompilerPC() + 8); CompileDelaySlot(DELAYSLOT_NICE); FlushAll(); - MOV(32, M(&mips_->pc), Imm32(js.compilerPC)); + MOV(32, M(&mips_->pc), Imm32(GetCompilerPC())); RestoreRoundingMode(); ABI_CallFunction(entry->replaceFunc); SUB(32, M(&mips_->downcount), R(EAX)); @@ -616,26 +618,26 @@ void Jit::Comp_ReplacementFunc(MIPSOpcode op) return; } - u32 funcSize = symbolMap.GetFunctionSize(js.compilerPC); + u32 funcSize = symbolMap.GetFunctionSize(GetCompilerPC()); bool disabled = (entry->flags & REPFLAG_DISABLED) != 0; if (!disabled && funcSize != SymbolMap::INVALID_ADDRESS && funcSize > sizeof(u32)) { // We don't need to disable hooks, the code will still run. if ((entry->flags & (REPFLAG_HOOKENTER | REPFLAG_HOOKEXIT)) == 0) { // Any breakpoint at the func entry was already tripped, so we can still run the replacement. // That's a common case - just to see how often the replacement hits. - disabled = CBreakPoints::RangeContainsBreakPoint(js.compilerPC + sizeof(u32), funcSize - sizeof(u32)); + disabled = CBreakPoints::RangeContainsBreakPoint(GetCompilerPC() + sizeof(u32), funcSize - sizeof(u32)); } } if (disabled) { - MIPSCompileOp(Memory::Read_Instruction(js.compilerPC, true)); + MIPSCompileOp(Memory::Read_Instruction(GetCompilerPC(), true)); } else if (entry->jitReplaceFunc) { MIPSReplaceFunc repl = entry->jitReplaceFunc; int cycles = (this->*repl)(); if (entry->flags & (REPFLAG_HOOKENTER | REPFLAG_HOOKEXIT)) { // Compile the original instruction at this address. We ignore cycles for hooks. - MIPSCompileOp(Memory::Read_Instruction(js.compilerPC, true)); + MIPSCompileOp(Memory::Read_Instruction(GetCompilerPC(), true)); } else { FlushAll(); MOV(32, R(ECX), M(&mips_->r[MIPS_REG_RA])); @@ -648,14 +650,14 @@ void Jit::Comp_ReplacementFunc(MIPSOpcode op) // Standard function call, nothing fancy. // The function returns the number of cycles it took in EAX. - MOV(32, M(&mips_->pc), Imm32(js.compilerPC)); + MOV(32, M(&mips_->pc), Imm32(GetCompilerPC())); RestoreRoundingMode(); ABI_CallFunction(entry->replaceFunc); if (entry->flags & (REPFLAG_HOOKENTER | REPFLAG_HOOKEXIT)) { // Compile the original instruction at this address. We ignore cycles for hooks. ApplyRoundingMode(); - MIPSCompileOp(Memory::Read_Instruction(js.compilerPC, true)); + MIPSCompileOp(Memory::Read_Instruction(GetCompilerPC(), true)); } else { MOV(32, R(ECX), M(&mips_->r[MIPS_REG_RA])); SUB(32, M(&mips_->downcount), R(EAX)); @@ -680,7 +682,7 @@ void Jit::Comp_Generic(MIPSOpcode op) { // TODO: Maybe we'd be better off keeping the rounding mode within interp? RestoreRoundingMode(); - MOV(32, M(&mips_->pc), Imm32(js.compilerPC)); + MOV(32, M(&mips_->pc), Imm32(GetCompilerPC())); if (USE_JIT_MISSMAP) ABI_CallFunctionC(&JitLogMiss, op.encoding); else @@ -712,7 +714,7 @@ void Jit::WriteExit(u32 destination, int exit_num) // CORE_RUNNING is <= CORE_NEXTFRAME. CMP(32, M(&coreState), Imm32(CORE_NEXTFRAME)); FixupBranch skipCheck = J_CC(CC_LE); - MOV(32, M(&mips_->pc), Imm32(js.compilerPC)); + MOV(32, M(&mips_->pc), Imm32(GetCompilerPC())); WriteSyscallExit(); SetJumpTarget(skipCheck); } @@ -753,7 +755,7 @@ void Jit::WriteExitDestInReg(X64Reg reg) // CORE_RUNNING is <= CORE_NEXTFRAME. CMP(32, M(&coreState), Imm32(CORE_NEXTFRAME)); FixupBranch skipCheck = J_CC(CC_LE); - MOV(32, M(&mips_->pc), Imm32(js.compilerPC)); + MOV(32, M(&mips_->pc), Imm32(GetCompilerPC())); WriteSyscallExit(); SetJumpTarget(skipCheck); } @@ -818,7 +820,7 @@ bool Jit::CheckJitBreakpoint(u32 addr, int downcountOffset) { SAVE_FLAGS; FlushAll(); - MOV(32, M(&mips_->pc), Imm32(js.compilerPC)); + MOV(32, M(&mips_->pc), Imm32(GetCompilerPC())); RestoreRoundingMode(); ABI_CallFunction(&JitBreakpoint); diff --git a/Core/MIPS/x86/Jit.h b/Core/MIPS/x86/Jit.h index a58c979ef1..cbafdb57cf 100644 --- a/Core/MIPS/x86/Jit.h +++ b/Core/MIPS/x86/Jit.h @@ -192,6 +192,8 @@ private: void FlushPrefixV(); void WriteDowncount(int offset = 0); bool ReplaceJalTo(u32 dest); + + u32 GetCompilerPC(); // See CompileDelaySlotFlags for flags. void CompileDelaySlot(int flags, RegCacheState *state = NULL); void CompileDelaySlot(int flags, RegCacheState &state) { diff --git a/Core/MIPS/x86/JitSafeMem.cpp b/Core/MIPS/x86/JitSafeMem.cpp index 481f1524a0..2334ff5b8f 100644 --- a/Core/MIPS/x86/JitSafeMem.cpp +++ b/Core/MIPS/x86/JitSafeMem.cpp @@ -61,7 +61,7 @@ JitSafeMem::JitSafeMem(Jit *jit, MIPSGPReg raddr, s32 offset, u32 alignMask) // If raddr_ is going to get loaded soon, load it now for more optimal code. // We assume that it was already locked. const int LOOKAHEAD_OPS = 3; - if (!jit_->gpr.R(raddr_).IsImm() && MIPSAnalyst::IsRegisterUsed(raddr_, jit_->js.compilerPC + 4, LOOKAHEAD_OPS)) + if (!jit_->gpr.R(raddr_).IsImm() && MIPSAnalyst::IsRegisterUsed(raddr_, jit_->GetCompilerPC() + 4, LOOKAHEAD_OPS)) jit_->gpr.MapReg(raddr_, true, false); } @@ -252,7 +252,7 @@ void JitSafeMem::DoSlowWrite(const void *safeFunc, const OpArg& src, int suboffs jit_->MOV(32, R(EDX), src); } if (!g_Config.bIgnoreBadMemAccess) { - jit_->MOV(32, M(&jit_->mips_->pc), Imm32(jit_->js.compilerPC)); + jit_->MOV(32, M(&jit_->mips_->pc), Imm32(jit_->GetCompilerPC())); } // This is a special jit-ABI'd function. jit_->CALL(safeFunc); @@ -282,7 +282,7 @@ bool JitSafeMem::PrepareSlowRead(const void *safeFunc) } if (!g_Config.bIgnoreBadMemAccess) { - jit_->MOV(32, M(&jit_->mips_->pc), Imm32(jit_->js.compilerPC)); + jit_->MOV(32, M(&jit_->mips_->pc), Imm32(jit_->GetCompilerPC())); } // This is a special jit-ABI'd function. jit_->CALL(safeFunc); @@ -316,7 +316,7 @@ void JitSafeMem::NextSlowRead(const void *safeFunc, int suboffset) } if (!g_Config.bIgnoreBadMemAccess) { - jit_->MOV(32, M(&jit_->mips_->pc), Imm32(jit_->js.compilerPC)); + jit_->MOV(32, M(&jit_->mips_->pc), Imm32(jit_->GetCompilerPC())); } // This is a special jit-ABI'd function. jit_->CALL(safeFunc); @@ -348,7 +348,7 @@ void JitSafeMem::MemCheckImm(MemoryOpType type) if (!(check->cond & MEMCHECK_WRITE) && type == MEM_WRITE) return; - jit_->MOV(32, M(&jit_->mips_->pc), Imm32(jit_->js.compilerPC)); + jit_->MOV(32, M(&jit_->mips_->pc), Imm32(jit_->GetCompilerPC())); jit_->CallProtectedFunction(&JitMemCheck, iaddr_, size_, type == MEM_WRITE ? 1 : 0); // CORE_RUNNING is <= CORE_NEXTFRAME. @@ -388,7 +388,7 @@ void JitSafeMem::MemCheckAsm(MemoryOpType type) // Keep the stack 16-byte aligned, just PUSH/POP 4 times. for (int i = 0; i < 4; ++i) jit_->PUSH(xaddr_); - jit_->MOV(32, M(&jit_->mips_->pc), Imm32(jit_->js.compilerPC)); + jit_->MOV(32, M(&jit_->mips_->pc), Imm32(jit_->GetCompilerPC())); jit_->ADD(32, R(xaddr_), Imm32(offset_)); jit_->CallProtectedFunction(&JitMemCheck, R(xaddr_), size_, type == MEM_WRITE ? 1 : 0); for (int i = 0; i < 4; ++i)