diff --git a/Core/MIPS/ARM/ArmCompBranch.cpp b/Core/MIPS/ARM/ArmCompBranch.cpp index be067e1e74..8bec6e123a 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 20d87cbfaa..57178cd12a 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 1e923989fa..5a370d36a2 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 bb8c4b01e6..5a29addf74 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 ab9a936c9c..6ee0af9703 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 bdeed81784..8d14d5129c 100644 --- a/Core/MIPS/ARM/ArmJit.h +++ b/Core/MIPS/ARM/ArmJit.h @@ -85,10 +85,6 @@ public: 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 @@ private: 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 9f1b2ad05a..f2e49868a9 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 dc9c85a2d1..6e87197270 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 d27f2ac90b..c37c254e41 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 77fa64fe4f..631e03cb5e 100644 --- a/Core/MIPS/ARM64/Arm64Jit.h +++ b/Core/MIPS/ARM64/Arm64Jit.h @@ -81,10 +81,6 @@ public: 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 @@ private: 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 9b7d999b8c..b53a5d2ae2 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 37a1ac294c..fbbf4b0904 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 9474216ecf..adbbf19c3a 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 3e3b20b6ec..a58c979ef1 100644 --- a/Core/MIPS/x86/Jit.h +++ b/Core/MIPS/x86/Jit.h @@ -199,6 +199,7 @@ private: } void EatInstruction(MIPSOpcode op); void AddContinuedBlock(u32 dest); + MIPSOpcode GetOffsetInstruction(int offset); void WriteExit(u32 destination, int exit_num); void WriteExitDestInReg(Gen::X64Reg reg);