From 115486e4312bbdaf132b0b99ee4ed6e4ab13e1fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 25 Dec 2014 10:28:07 +0100 Subject: [PATCH 1/4] Fix some fp instruction in/out flags --- Core/MIPS/MIPSTables.cpp | 4 ++-- Core/MIPS/MIPSTables.h | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Core/MIPS/MIPSTables.cpp b/Core/MIPS/MIPSTables.cpp index 1f86b0abc5a4..646757f1c673 100644 --- a/Core/MIPS/MIPSTables.cpp +++ b/Core/MIPS/MIPSTables.cpp @@ -166,7 +166,7 @@ const MIPSInstruction tableImmediate[64] = // xxxxxx ..... ..... ............... INSTR("cache", JITFUNC(Comp_Cache), Dis_Cache, Int_Cache, IN_MEM|IN_IMM16|IN_RS_ADDR), //48 INSTR("ll", JITFUNC(Comp_Generic), Dis_Generic, Int_StoreSync, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT|OUT_OTHER|MEMTYPE_WORD), - INSTR("lwc1", JITFUNC(Comp_FPULS), Dis_FPULS, Int_FPULS, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_OTHER|MEMTYPE_FLOAT|IS_FPU), + INSTR("lwc1", JITFUNC(Comp_FPULS), Dis_FPULS, Int_FPULS, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_FT|MEMTYPE_FLOAT|IS_FPU), INSTR("lv.s", JITFUNC(Comp_SV), Dis_SV, Int_SV, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_OTHER|IS_VFPU|VFPU_NO_PREFIX|MEMTYPE_FLOAT), INVALID, // HIT THIS IN WIPEOUT ENCODING(VFPU4Jump), @@ -175,7 +175,7 @@ const MIPSInstruction tableImmediate[64] = // xxxxxx ..... ..... ............... ENCODING(VFPU5), //56 INSTR("sc", JITFUNC(Comp_Generic), Dis_Generic, Int_StoreSync, IN_IMM16|IN_RS_ADDR|IN_OTHER|IN_RT|OUT_RT|OUT_MEM|MEMTYPE_WORD), - INSTR("swc1", JITFUNC(Comp_FPULS), Dis_FPULS, Int_FPULS, IN_IMM16|IN_RS_ADDR|IN_OTHER|OUT_MEM|MEMTYPE_FLOAT|IS_FPU), //copU + INSTR("swc1", JITFUNC(Comp_FPULS), Dis_FPULS, Int_FPULS, IN_IMM16|IN_RS_ADDR|IN_FT|OUT_MEM|MEMTYPE_FLOAT|IS_FPU), //copU INSTR("sv.s", JITFUNC(Comp_SV), Dis_SV, Int_SV, IN_IMM16|IN_RS_ADDR|IN_OTHER|OUT_MEM|IS_VFPU|VFPU_NO_PREFIX|MEMTYPE_FLOAT), INVALID, //60 diff --git a/Core/MIPS/MIPSTables.h b/Core/MIPS/MIPSTables.h index 1f70366eb2e3..5b916324083b 100644 --- a/Core/MIPS/MIPSTables.h +++ b/Core/MIPS/MIPSTables.h @@ -100,6 +100,7 @@ struct MIPSInfo { #define IN_VS 0x010000000000ULL #define IN_VT 0x020000000000ULL +#define OUT_FT 0x040000000000ULL #define OUT_VD 0x100000000000ULL From 59d0baca9375fa094d81fe465abd99efdcd97885 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 24 Nov 2014 21:57:27 +0100 Subject: [PATCH 2/4] Add way to print some block bloat stats. --- Core/MIPS/JitCommon/JitBlockCache.cpp | 28 +++++++++++++++++++++++++++ Core/MIPS/JitCommon/JitBlockCache.h | 11 +++++++++++ UI/DevScreens.cpp | 24 +++++++++++++++++++++++ UI/DevScreens.h | 1 + 4 files changed, 64 insertions(+) diff --git a/Core/MIPS/JitCommon/JitBlockCache.cpp b/Core/MIPS/JitCommon/JitBlockCache.cpp index 07e8b491f88b..04db18d33d48 100644 --- a/Core/MIPS/JitCommon/JitBlockCache.cpp +++ b/Core/MIPS/JitCommon/JitBlockCache.cpp @@ -654,3 +654,31 @@ int JitBlockCache::GetBlockExitSize() { return 0; #endif } + +void JitBlockCache::ComputeStats(BlockCacheStats &bcStats) { + double totalBloat = 0.0; + double maxBloat = 0.0; + double minBloat = 1000000000.0; + for (int i = 0; i < num_blocks_; i++) { + JitBlock *b = GetBlock(i); + double codeSize = (double)b->codeSize; + if (codeSize == 0) + continue; + double origSize = (double)(4 * b->originalSize); + double bloat = codeSize / origSize; + if (bloat < minBloat) { + minBloat = bloat; + bcStats.minBloatBlock = b->originalAddress; + } + if (bloat > maxBloat) { + maxBloat = bloat; + bcStats.maxBloatBlock = b->originalAddress; + } + totalBloat += bloat; + bcStats.bloatMap[bloat] = b->originalAddress; + } + bcStats.numBlocks = num_blocks_; + bcStats.minBloat = minBloat; + bcStats.maxBloat = maxBloat; + bcStats.avgBloat = totalBloat / (double)num_blocks_; +} diff --git a/Core/MIPS/JitCommon/JitBlockCache.h b/Core/MIPS/JitCommon/JitBlockCache.h index 65c6559cd9a1..168e101018e5 100644 --- a/Core/MIPS/JitCommon/JitBlockCache.h +++ b/Core/MIPS/JitCommon/JitBlockCache.h @@ -54,6 +54,16 @@ const int MAX_JIT_BLOCK_EXITS = 2; const int MAX_JIT_BLOCK_EXITS = 8; #endif +struct BlockCacheStats { + int numBlocks; + float avgBloat; // In code bytes, not instructions! + float minBloat; + u32 minBloatBlock; + float maxBloat; + u32 maxBloatBlock; + std::map bloatMap; +}; + // Define this in order to get VTune profile support for the Jit generated code. // Add the VTune include/lib directories to the project directories to get this to build. // #define USE_VTUNE @@ -114,6 +124,7 @@ class JitBlockCache { void Reset(); bool IsFull() const; + void ComputeStats(BlockCacheStats &bcStats); // Code Cache JitBlock *GetBlock(int block_num); diff --git a/UI/DevScreens.cpp b/UI/DevScreens.cpp index 23375b801f36..98d09baa1ef9 100644 --- a/UI/DevScreens.cpp +++ b/UI/DevScreens.cpp @@ -567,6 +567,7 @@ void JitCompareScreen::CreateViews() { leftColumn->Add(new Choice(de->T("Random")))->OnClick.Handle(this, &JitCompareScreen::OnRandomBlock); leftColumn->Add(new Choice(de->T("FPU")))->OnClick.Handle(this, &JitCompareScreen::OnRandomFPUBlock); leftColumn->Add(new Choice(de->T("VFPU")))->OnClick.Handle(this, &JitCompareScreen::OnRandomVFPUBlock); + leftColumn->Add(new Choice(d->T("Stats")))->OnClick.Handle(this, &JitCompareScreen::OnShowStats); leftColumn->Add(new Choice(d->T("Back")))->OnClick.Handle(this, &UIScreen::OnBack); blockName_ = leftColumn->Add(new TextView(de->T("No block"))); blockAddr_ = leftColumn->Add(new TextEdit("", "", new LayoutParams(FILL_PARENT, WRAP_CONTENT))); @@ -648,6 +649,29 @@ UI::EventReturn JitCompareScreen::OnAddressChange(UI::EventParams &e) { return UI::EVENT_DONE; } +UI::EventReturn JitCompareScreen::OnShowStats(UI::EventParams &e) { + JitBlockCache *blockCache = MIPSComp::jit->GetBlockCache(); + BlockCacheStats bcStats; + blockCache->ComputeStats(bcStats); + NOTICE_LOG(JIT, "Num blocks: %i", bcStats.numBlocks); + NOTICE_LOG(JIT, "Average Bloat: %0.2f%%", 100 * bcStats.avgBloat); + NOTICE_LOG(JIT, "Min Bloat: %0.2f%% (%08x)", 100 * bcStats.minBloat, bcStats.minBloatBlock); + NOTICE_LOG(JIT, "Max Bloat: %0.2f%% (%08x)", 100 * bcStats.maxBloat, bcStats.maxBloatBlock); + + int ctr = 0, sz = (int)bcStats.bloatMap.size(); + for (auto iter : bcStats.bloatMap) { + if (ctr < 10 || ctr > sz - 10) { + NOTICE_LOG(JIT, "%08x: %f", iter.second, iter.first); + } else if (ctr == 10) { + NOTICE_LOG(JIT, "..."); + } + ctr++; + } + + return UI::EVENT_DONE; +} + + UI::EventReturn JitCompareScreen::OnSelectBlock(UI::EventParams &e) { I18NCategory *de = GetI18NCategory("Developer"); diff --git a/UI/DevScreens.h b/UI/DevScreens.h index d527cd922b46..45a79073ca40 100644 --- a/UI/DevScreens.h +++ b/UI/DevScreens.h @@ -130,6 +130,7 @@ class JitCompareScreen : public UIDialogScreenWithBackground { UI::EventReturn OnNextBlock(UI::EventParams &e); UI::EventReturn OnBlockAddress(UI::EventParams &e); UI::EventReturn OnAddressChange(UI::EventParams &e); + UI::EventReturn OnShowStats(UI::EventParams &e); int currentBlock_; From a897723e6a70684b697b7232b5dc1e9c88758fe2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 11 Apr 2015 00:52:42 -0700 Subject: [PATCH 3/4] Separate out jit reading nearby instructions. This makes it easier to use an IR for these things, or remove them. --- Core/MIPS/ARM/ArmCompBranch.cpp | 10 +++++----- Core/MIPS/ARM/ArmCompFPU.cpp | 2 +- Core/MIPS/ARM/ArmCompLoadStore.cpp | 2 +- Core/MIPS/ARM/ArmCompVFPUNEON.cpp | 12 ++++++------ Core/MIPS/ARM/ArmJit.cpp | 4 ++++ Core/MIPS/ARM/ArmJit.h | 9 +++++---- Core/MIPS/ARM64/Arm64CompBranch.cpp | 10 +++++----- Core/MIPS/ARM64/Arm64CompLoadStore.cpp | 2 +- Core/MIPS/ARM64/Arm64Jit.cpp | 4 ++++ Core/MIPS/ARM64/Arm64Jit.h | 9 +++++---- Core/MIPS/x86/CompBranch.cpp | 10 +++++----- Core/MIPS/x86/CompLoadStore.cpp | 8 ++++---- Core/MIPS/x86/Jit.cpp | 4 ++++ Core/MIPS/x86/Jit.h | 1 + 14 files changed, 51 insertions(+), 36 deletions(-) diff --git a/Core/MIPS/ARM/ArmCompBranch.cpp b/Core/MIPS/ARM/ArmCompBranch.cpp index be067e1e74e9..8bec6e123a5d 100644 --- a/Core/MIPS/ARM/ArmCompBranch.cpp +++ b/Core/MIPS/ARM/ArmCompBranch.cpp @@ -104,7 +104,7 @@ void ArmJit::BranchRSRTComp(MIPSOpcode op, CCFlags cc, bool likely) return; } - MIPSOpcode delaySlotOp = Memory::Read_Instruction(js.compilerPC+4); + MIPSOpcode delaySlotOp = GetOffsetInstruction(1); bool delaySlotIsNice = IsDelaySlotNiceReg(op, delaySlotOp, rt, rs); CONDITIONAL_NICE_DELAYSLOT; @@ -220,7 +220,7 @@ void ArmJit::BranchRSZeroComp(MIPSOpcode op, CCFlags cc, bool andLink, bool like return; } - MIPSOpcode delaySlotOp = Memory::Read_Instruction(js.compilerPC + 4); + MIPSOpcode delaySlotOp = GetOffsetInstruction(1); bool delaySlotIsNice = IsDelaySlotNiceReg(op, delaySlotOp, rs); CONDITIONAL_NICE_DELAYSLOT; @@ -326,7 +326,7 @@ void ArmJit::BranchFPFlag(MIPSOpcode op, CCFlags cc, bool likely) int offset = _IMM16 << 2; u32 targetAddr = js.compilerPC + offset + 4; - MIPSOpcode delaySlotOp = Memory::Read_Instruction(js.compilerPC + 4); + MIPSOpcode delaySlotOp = GetOffsetInstruction(1); bool delaySlotIsNice = IsDelaySlotNiceFPU(op, delaySlotOp); CONDITIONAL_NICE_DELAYSLOT; if (!likely && delaySlotIsNice) @@ -384,7 +384,7 @@ void ArmJit::BranchVFPUFlag(MIPSOpcode op, CCFlags cc, bool likely) int offset = _IMM16 << 2; u32 targetAddr = js.compilerPC + offset + 4; - MIPSOpcode delaySlotOp = Memory::Read_Instruction(js.compilerPC + 4); + MIPSOpcode delaySlotOp = GetOffsetInstruction(1); // Sometimes there's a VFPU branch in a delay slot (Disgaea 2: Dark Hero Days, Zettai Hero Project, La Pucelle) // The behavior is undefined - the CPU may take the second branch even if the first one passes. @@ -511,7 +511,7 @@ void ArmJit::Comp_JumpReg(MIPSOpcode op) MIPSGPReg rd = _RD; bool andLink = (op & 0x3f) == 9 && rd != MIPS_REG_ZERO; - MIPSOpcode delaySlotOp = Memory::Read_Instruction(js.compilerPC + 4); + MIPSOpcode delaySlotOp = GetOffsetInstruction(1); bool delaySlotIsNice = IsDelaySlotNiceReg(op, delaySlotOp, rs); if (andLink && rs == rd) delaySlotIsNice = false; diff --git a/Core/MIPS/ARM/ArmCompFPU.cpp b/Core/MIPS/ARM/ArmCompFPU.cpp index 20d87cbfaa79..57178cd12ae1 100644 --- a/Core/MIPS/ARM/ArmCompFPU.cpp +++ b/Core/MIPS/ARM/ArmCompFPU.cpp @@ -63,7 +63,7 @@ void ArmJit::Comp_FPU3op(MIPSOpcode op) case 0: VADD(fpr.R(fd), fpr.R(fs), fpr.R(ft)); break; //F(fd) = F(fs) + F(ft); //add case 1: VSUB(fpr.R(fd), fpr.R(fs), fpr.R(ft)); break; //F(fd) = F(fs) - F(ft); //sub case 2: { //F(fd) = F(fs) * F(ft); //mul - MIPSOpcode nextOp = Memory::Read_Instruction(js.compilerPC + 4); + MIPSOpcode nextOp = GetOffsetInstruction(1); // Optimization possible if destination is the same if (fd == (int)((nextOp>>6) & 0x1F)) { // VMUL + VNEG -> VNMUL diff --git a/Core/MIPS/ARM/ArmCompLoadStore.cpp b/Core/MIPS/ARM/ArmCompLoadStore.cpp index 1e923989fa35..5a370d36a28d 100644 --- a/Core/MIPS/ARM/ArmCompLoadStore.cpp +++ b/Core/MIPS/ARM/ArmCompLoadStore.cpp @@ -139,7 +139,7 @@ namespace MIPSComp if (!js.inDelaySlot) { // Optimisation: Combine to single unaligned load/store bool isLeft = (o == 34 || o == 42); - MIPSOpcode nextOp = Memory::Read_Instruction(js.compilerPC + 4); + MIPSOpcode nextOp = GetOffsetInstruction(1); // Find a matching shift in opposite direction with opposite offset. if (nextOp == (isLeft ? (op.encoding + (4<<26) - 3) : (op.encoding - (4<<26) + 3))) diff --git a/Core/MIPS/ARM/ArmCompVFPUNEON.cpp b/Core/MIPS/ARM/ArmCompVFPUNEON.cpp index bb8c4b01e696..5a29addf743d 100644 --- a/Core/MIPS/ARM/ArmCompVFPUNEON.cpp +++ b/Core/MIPS/ARM/ArmCompVFPUNEON.cpp @@ -284,9 +284,9 @@ void ArmJit::CompNEON_SVQ(MIPSOpcode op) { // Check for four-in-a-row const u32 ops[4] = { op.encoding, - Memory::Read_Instruction(js.compilerPC + 4).encoding, - Memory::Read_Instruction(js.compilerPC + 8).encoding, - Memory::Read_Instruction(js.compilerPC + 12).encoding + GetOffsetInstruction(1).encoding, + GetOffsetInstruction(2).encoding, + GetOffsetInstruction(3).encoding }; if (g_Config.bFastMemory && (ops[1] >> 26) == 54 && (ops[2] >> 26) == 54 && (ops[3] >> 26) == 54) { int offsets[4] = {offset, (s16)(ops[1] & 0xFFFC), (s16)(ops[2] & 0xFFFC), (s16)(ops[3] & 0xFFFC)}; @@ -350,9 +350,9 @@ void ArmJit::CompNEON_SVQ(MIPSOpcode op) { { const u32 ops[4] = { op.encoding, - Memory::Read_Instruction(js.compilerPC + 4).encoding, - Memory::Read_Instruction(js.compilerPC + 8).encoding, - Memory::Read_Instruction(js.compilerPC + 12).encoding + GetOffsetInstruction(1).encoding, + GetOffsetInstruction(2).encoding, + GetOffsetInstruction(3).encoding }; if (g_Config.bFastMemory && (ops[1] >> 26) == 54 && (ops[2] >> 26) == 54 && (ops[3] >> 26) == 54) { int offsets[4] = { offset, (s16)(ops[1] & 0xFFFC), (s16)(ops[2] & 0xFFFC), (s16)(ops[3] & 0xFFFC) }; diff --git a/Core/MIPS/ARM/ArmJit.cpp b/Core/MIPS/ARM/ArmJit.cpp index ab9a936c9caf..6ee0af970309 100644 --- a/Core/MIPS/ARM/ArmJit.cpp +++ b/Core/MIPS/ARM/ArmJit.cpp @@ -235,6 +235,10 @@ void ArmJit::RunLoopUntil(u64 globalticks) ((void (*)())enterCode)(); } +MIPSOpcode ArmJit::GetOffsetInstruction(int offset) { + return Memory::Read_Instruction(js.compilerPC + 4 * offset); +} + const u8 *ArmJit::DoJit(u32 em_address, JitBlock *b) { js.cancel = false; diff --git a/Core/MIPS/ARM/ArmJit.h b/Core/MIPS/ARM/ArmJit.h index bdeed81784e6..8d14d5129c35 100644 --- a/Core/MIPS/ARM/ArmJit.h +++ b/Core/MIPS/ARM/ArmJit.h @@ -85,10 +85,6 @@ class ArmJit : public ArmGen::ARMXCodeBlock bool DescribeCodePtr(const u8 *ptr, std::string &name); - void CompileDelaySlot(int flags); - void EatInstruction(MIPSOpcode op); - void AddContinuedBlock(u32 dest); - void Comp_RunBlock(MIPSOpcode op); void Comp_ReplacementFunc(MIPSOpcode op); @@ -215,6 +211,11 @@ class ArmJit : public ArmGen::ARMXCodeBlock void FlushAll(); void FlushPrefixV(); + void CompileDelaySlot(int flags); + void EatInstruction(MIPSOpcode op); + void AddContinuedBlock(u32 dest); + MIPSOpcode GetOffsetInstruction(int offset); + void WriteDownCount(int offset = 0); void WriteDownCountR(ArmGen::ARMReg reg); void RestoreRoundingMode(bool force = false); diff --git a/Core/MIPS/ARM64/Arm64CompBranch.cpp b/Core/MIPS/ARM64/Arm64CompBranch.cpp index 9f1b2ad05a01..f2e49868a9af 100644 --- a/Core/MIPS/ARM64/Arm64CompBranch.cpp +++ b/Core/MIPS/ARM64/Arm64CompBranch.cpp @@ -104,7 +104,7 @@ void Arm64Jit::BranchRSRTComp(MIPSOpcode op, CCFlags cc, bool likely) return; } - MIPSOpcode delaySlotOp = Memory::Read_Instruction(js.compilerPC+4); + MIPSOpcode delaySlotOp = GetOffsetInstruction(1); bool delaySlotIsNice = IsDelaySlotNiceReg(op, delaySlotOp, rt, rs); CONDITIONAL_NICE_DELAYSLOT; @@ -208,7 +208,7 @@ void Arm64Jit::BranchRSZeroComp(MIPSOpcode op, CCFlags cc, bool andLink, bool li return; } - MIPSOpcode delaySlotOp = Memory::Read_Instruction(js.compilerPC + 4); + MIPSOpcode delaySlotOp = GetOffsetInstruction(1); bool delaySlotIsNice = IsDelaySlotNiceReg(op, delaySlotOp, rs); CONDITIONAL_NICE_DELAYSLOT; @@ -313,7 +313,7 @@ void Arm64Jit::BranchFPFlag(MIPSOpcode op, CCFlags cc, bool likely) { int offset = _IMM16 << 2; u32 targetAddr = js.compilerPC + offset + 4; - MIPSOpcode delaySlotOp = Memory::Read_Instruction(js.compilerPC + 4); + MIPSOpcode delaySlotOp = GetOffsetInstruction(1); bool delaySlotIsNice = IsDelaySlotNiceFPU(op, delaySlotOp); CONDITIONAL_NICE_DELAYSLOT; if (!likely && delaySlotIsNice) @@ -364,7 +364,7 @@ void Arm64Jit::BranchVFPUFlag(MIPSOpcode op, CCFlags cc, bool likely) { int offset = _IMM16 << 2; u32 targetAddr = js.compilerPC + offset + 4; - MIPSOpcode delaySlotOp = Memory::Read_Instruction(js.compilerPC + 4); + MIPSOpcode delaySlotOp = GetOffsetInstruction(1); // Sometimes there's a VFPU branch in a delay slot (Disgaea 2: Dark Hero Days, Zettai Hero Project, La Pucelle) // The behavior is undefined - the CPU may take the second branch even if the first one passes. @@ -491,7 +491,7 @@ void Arm64Jit::Comp_JumpReg(MIPSOpcode op) MIPSGPReg rd = _RD; bool andLink = (op & 0x3f) == 9 && rd != MIPS_REG_ZERO; - MIPSOpcode delaySlotOp = Memory::Read_Instruction(js.compilerPC + 4); + MIPSOpcode delaySlotOp = GetOffsetInstruction(1); bool delaySlotIsNice = IsDelaySlotNiceReg(op, delaySlotOp, rs); if (andLink && rs == rd) delaySlotIsNice = false; diff --git a/Core/MIPS/ARM64/Arm64CompLoadStore.cpp b/Core/MIPS/ARM64/Arm64CompLoadStore.cpp index dc9c85a2d151..6e87197270e4 100644 --- a/Core/MIPS/ARM64/Arm64CompLoadStore.cpp +++ b/Core/MIPS/ARM64/Arm64CompLoadStore.cpp @@ -95,7 +95,7 @@ namespace MIPSComp if (!js.inDelaySlot && false) { // Optimisation: Combine to single unaligned load/store bool isLeft = (o == 34 || o == 42); - MIPSOpcode nextOp = Memory::Read_Instruction(js.compilerPC + 4); + MIPSOpcode nextOp = GetOffsetInstruction(1); // Find a matching shift in opposite direction with opposite offset. if (nextOp == (isLeft ? (op.encoding + (4 << 26) - 3) : (op.encoding - (4 << 26) + 3))) { diff --git a/Core/MIPS/ARM64/Arm64Jit.cpp b/Core/MIPS/ARM64/Arm64Jit.cpp index d27f2ac90bf8..c37c254e411a 100644 --- a/Core/MIPS/ARM64/Arm64Jit.cpp +++ b/Core/MIPS/ARM64/Arm64Jit.cpp @@ -220,6 +220,10 @@ void Arm64Jit::RunLoopUntil(u64 globalticks) { ((void (*)())enterCode)(); } +MIPSOpcode Arm64Jit::GetOffsetInstruction(int offset) { + return Memory::Read_Instruction(js.compilerPC + 4 * offset); +} + const u8 *Arm64Jit::DoJit(u32 em_address, JitBlock *b) { js.cancel = false; js.blockStart = js.compilerPC = mips_->pc; diff --git a/Core/MIPS/ARM64/Arm64Jit.h b/Core/MIPS/ARM64/Arm64Jit.h index 77fa64fe4f2f..631e03cb5ee0 100644 --- a/Core/MIPS/ARM64/Arm64Jit.h +++ b/Core/MIPS/ARM64/Arm64Jit.h @@ -81,10 +81,6 @@ class Arm64Jit : public Arm64Gen::ARM64CodeBlock bool DescribeCodePtr(const u8 *ptr, std::string &name); - void CompileDelaySlot(int flags); - void EatInstruction(MIPSOpcode op); - void AddContinuedBlock(u32 dest); - void Comp_RunBlock(MIPSOpcode op); void Comp_ReplacementFunc(MIPSOpcode op); @@ -211,6 +207,11 @@ class Arm64Jit : public Arm64Gen::ARM64CodeBlock void FlushAll(); void FlushPrefixV(); + void CompileDelaySlot(int flags); + void EatInstruction(MIPSOpcode op); + void AddContinuedBlock(u32 dest); + MIPSOpcode GetOffsetInstruction(int offset); + void WriteDownCount(int offset = 0); void WriteDownCountR(Arm64Gen::ARM64Reg reg); void RestoreRoundingMode(bool force = false); diff --git a/Core/MIPS/x86/CompBranch.cpp b/Core/MIPS/x86/CompBranch.cpp index 9b7d999b8c9b..b53a5d2ae2ee 100644 --- a/Core/MIPS/x86/CompBranch.cpp +++ b/Core/MIPS/x86/CompBranch.cpp @@ -364,7 +364,7 @@ void Jit::BranchRSRTComp(MIPSOpcode op, Gen::CCFlags cc, bool likely) return; } - MIPSOpcode delaySlotOp = Memory::Read_Instruction(js.compilerPC+4); + MIPSOpcode delaySlotOp = GetOffsetInstruction(1); bool delaySlotIsNice = IsDelaySlotNiceReg(op, delaySlotOp, rt, rs); CONDITIONAL_NICE_DELAYSLOT; @@ -443,7 +443,7 @@ void Jit::BranchRSZeroComp(MIPSOpcode op, Gen::CCFlags cc, bool andLink, bool li return; } - MIPSOpcode delaySlotOp = Memory::Read_Instruction(js.compilerPC + 4); + MIPSOpcode delaySlotOp = GetOffsetInstruction(1); bool delaySlotIsNice = IsDelaySlotNiceReg(op, delaySlotOp, rs); CONDITIONAL_NICE_DELAYSLOT; @@ -514,7 +514,7 @@ void Jit::BranchFPFlag(MIPSOpcode op, Gen::CCFlags cc, bool likely) int offset = _IMM16 << 2; u32 targetAddr = js.compilerPC + offset + 4; - MIPSOpcode delaySlotOp = Memory::Read_Instruction(js.compilerPC + 4); + MIPSOpcode delaySlotOp = GetOffsetInstruction(1); bool delaySlotIsNice = IsDelaySlotNiceFPU(op, delaySlotOp); CONDITIONAL_NICE_DELAYSLOT; if (!likely && delaySlotIsNice) @@ -552,7 +552,7 @@ void Jit::BranchVFPUFlag(MIPSOpcode op, Gen::CCFlags cc, bool likely) int offset = _IMM16 << 2; u32 targetAddr = js.compilerPC + offset + 4; - MIPSOpcode delaySlotOp = Memory::Read_Instruction(js.compilerPC + 4); + MIPSOpcode delaySlotOp = GetOffsetInstruction(1); // Sometimes there's a VFPU branch in a delay slot (Disgaea 2: Dark Hero Days, Zettai Hero Project, La Pucelle) // The behavior is undefined - the CPU may take the second branch even if the first one passes. @@ -672,7 +672,7 @@ void Jit::Comp_JumpReg(MIPSOpcode op) MIPSGPReg rd = _RD; bool andLink = (op & 0x3f) == 9 && rd != MIPS_REG_ZERO; - MIPSOpcode delaySlotOp = Memory::Read_Instruction(js.compilerPC + 4); + MIPSOpcode delaySlotOp = GetOffsetInstruction(1); bool delaySlotIsNice = IsDelaySlotNiceReg(op, delaySlotOp, rs); if (andLink && rs == rd) delaySlotIsNice = false; diff --git a/Core/MIPS/x86/CompLoadStore.cpp b/Core/MIPS/x86/CompLoadStore.cpp index 37a1ac294c3d..fbbf4b0904f5 100644 --- a/Core/MIPS/x86/CompLoadStore.cpp +++ b/Core/MIPS/x86/CompLoadStore.cpp @@ -329,7 +329,7 @@ namespace MIPSComp { case 34: //lwl { - MIPSOpcode nextOp = Memory::Read_Instruction(js.compilerPC + 4); + MIPSOpcode nextOp = GetOffsetInstruction(1); // Looking for lwr rd, offset-3(rs) which makes a pair. u32 desiredOp = ((op & 0xFFFF0000) + (4 << 26)) + (offset - 3); if (!js.inDelaySlot && nextOp == desiredOp) @@ -345,7 +345,7 @@ namespace MIPSComp { case 38: //lwr { - MIPSOpcode nextOp = Memory::Read_Instruction(js.compilerPC + 4); + MIPSOpcode nextOp = GetOffsetInstruction(1); // Looking for lwl rd, offset+3(rs) which makes a pair. u32 desiredOp = ((op & 0xFFFF0000) - (4 << 26)) + (offset + 3); if (!js.inDelaySlot && nextOp == desiredOp) @@ -361,7 +361,7 @@ namespace MIPSComp { case 42: //swl { - MIPSOpcode nextOp = Memory::Read_Instruction(js.compilerPC + 4); + MIPSOpcode nextOp = GetOffsetInstruction(1); // Looking for swr rd, offset-3(rs) which makes a pair. u32 desiredOp = ((op & 0xFFFF0000) + (4 << 26)) + (offset - 3); if (!js.inDelaySlot && nextOp == desiredOp) @@ -377,7 +377,7 @@ namespace MIPSComp { case 46: //swr { - MIPSOpcode nextOp = Memory::Read_Instruction(js.compilerPC + 4); + MIPSOpcode nextOp = GetOffsetInstruction(1); // Looking for swl rd, offset+3(rs) which makes a pair. u32 desiredOp = ((op & 0xFFFF0000) - (4 << 26)) + (offset + 3); if (!js.inDelaySlot && nextOp == desiredOp) diff --git a/Core/MIPS/x86/Jit.cpp b/Core/MIPS/x86/Jit.cpp index 9474216ecf25..adbbf19c3a0e 100644 --- a/Core/MIPS/x86/Jit.cpp +++ b/Core/MIPS/x86/Jit.cpp @@ -402,6 +402,10 @@ void Jit::RunLoopUntil(u64 globalticks) ((void (*)())asm_.enterCode)(); } +MIPSOpcode Jit::GetOffsetInstruction(int offset) { + return Memory::Read_Instruction(js.compilerPC + 4 * offset); +} + const u8 *Jit::DoJit(u32 em_address, JitBlock *b) { js.cancel = false; diff --git a/Core/MIPS/x86/Jit.h b/Core/MIPS/x86/Jit.h index 3e3b20b6ec16..a58c979ef113 100644 --- a/Core/MIPS/x86/Jit.h +++ b/Core/MIPS/x86/Jit.h @@ -199,6 +199,7 @@ class Jit : public Gen::XCodeBlock } void EatInstruction(MIPSOpcode op); void AddContinuedBlock(u32 dest); + MIPSOpcode GetOffsetInstruction(int offset); void WriteExit(u32 destination, int exit_num); void WriteExitDestInReg(Gen::X64Reg reg); 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 4/4] 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 8bec6e123a5d..a7d5468937c5 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 d04884cdcb78..3862dec1fcb8 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 6ee0af970309..ae5e4101c16a 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 8d14d5129c35..1712ee025faf 100644 --- a/Core/MIPS/ARM/ArmJit.h +++ b/Core/MIPS/ARM/ArmJit.h @@ -211,6 +211,7 @@ class ArmJit : public ArmGen::ARMXCodeBlock 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 f2e49868a9af..e6ae97a78d63 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 70cfae1f663b..fd4640bcebd9 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 c37c254e411a..1285f8d04a3f 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 631e03cb5ee0..a9e9d16e84b4 100644 --- a/Core/MIPS/ARM64/Arm64Jit.h +++ b/Core/MIPS/ARM64/Arm64Jit.h @@ -207,6 +207,7 @@ class Arm64Jit : public Arm64Gen::ARM64CodeBlock 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 39e753039b8b..530332596739 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 b53a5d2ae2ee..a725a7012f8a 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 89f76fabce6f..7dd27d044341 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 adbbf19c3a0e..886a9e54e07a 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 a58c979ef113..cbafdb57cff7 100644 --- a/Core/MIPS/x86/Jit.h +++ b/Core/MIPS/x86/Jit.h @@ -192,6 +192,8 @@ class Jit : public Gen::XCodeBlock 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 481f1524a059..2334ff5b8fd8 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)