From ff4093938fd5c24556c17f866076dcdefb75cfe2 Mon Sep 17 00:00:00 2001 From: zilmar Date: Sat, 1 Oct 2016 18:16:11 +1000 Subject: [PATCH] [Android] get CArmRecompilerOps::BEQ_Compare to use register caching --- .../Recompiler/Arm/ArmRecompilerOps.cpp | 269 +++++++++++++++++- 1 file changed, 255 insertions(+), 14 deletions(-) diff --git a/Source/Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.cpp b/Source/Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.cpp index 9b815344d..5d5b4b296 100644 --- a/Source/Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.cpp +++ b/Source/Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.cpp @@ -803,22 +803,262 @@ void CArmRecompilerOps::BNE_Compare() void CArmRecompilerOps::BEQ_Compare() { - if (IsKnown(m_Opcode.rs) || IsKnown(m_Opcode.rt)) + uint8_t *Jump = NULL; + + if (IsKnown(m_Opcode.rs) && IsKnown(m_Opcode.rt)) { - g_Notify->BreakPoint(__FILE__, __LINE__); - CArmRecompilerOps::UnknownOpcode(); + if (IsConst(m_Opcode.rs) && IsConst(m_Opcode.rt)) + { + if (Is64Bit(m_Opcode.rs) || Is64Bit(m_Opcode.rt)) + { + CArmRecompilerOps::UnknownOpcode(); + } + else if (GetMipsRegLo(m_Opcode.rs) == GetMipsRegLo(m_Opcode.rt)) + { + m_Section->m_Jump.FallThrough = true; + m_Section->m_Cont.FallThrough = false; + } + else + { + m_Section->m_Jump.FallThrough = false; + m_Section->m_Cont.FallThrough = true; + } + } + else if (IsMapped(m_Opcode.rs) && IsMapped(m_Opcode.rt)) + { + if ((Is64Bit(m_Opcode.rs) || Is64Bit(m_Opcode.rt)) && !g_System->b32BitCore()) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + CArmRecompilerOps::UnknownOpcode(); + + /*ProtectGPR(m_Opcode.rs); + ProtectGPR(m_Opcode.rt); + + CompX86RegToX86Reg( + Is32Bit(m_Opcode.rs) ? Map_TempReg(x86_Any, m_Opcode.rs, true) : GetMipsRegMapHi(m_Opcode.rs), + Is32Bit(m_Opcode.rt) ? Map_TempReg(x86_Any, m_Opcode.rt, true) : GetMipsRegMapHi(m_Opcode.rt) + ); + if (m_Section->m_Cont.FallThrough) + { + Jump = *g_RecompPos; + BranchLabel8(ArmBranch_Notequal, "continue"); + } + else + { + BranchLabel20(ArmBranch_Notequal, m_Section->m_Cont.BranchLabel.c_str()); + m_Section->m_Cont.LinkLocation = (uint32_t *)(*g_RecompPos - 4); + } + CompX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rs), GetMipsRegMapLo(m_Opcode.rt)); + if (m_Section->m_Cont.FallThrough) + { + BranchLabel20(ArmBranch_Equal, m_Section->m_Jump.BranchLabel.c_str()); + m_Section->m_Jump.LinkLocation = (uint32_t *)(*g_RecompPos - 4); + CPU_Message(" "); + CPU_Message(" continue:"); + SetJump8(Jump, *g_RecompPos); + } + else if (m_Section->m_Jump.FallThrough) + { + BranchLabel20(ArmBranch_Notequal, m_Section->m_Cont.BranchLabel.c_str()); + m_Section->m_Cont.LinkLocation2 = (uint32_t *)(*g_RecompPos - 4); + } + else + { + BranchLabel20(ArmBranch_Notequal, m_Section->m_Cont.BranchLabel.c_str()); + m_Section->m_Cont.LinkLocation2 = (uint32_t *)(*g_RecompPos - 4); + BranchLabel20(ArmBranch_Always, m_Section->m_Jump.BranchLabel.c_str()); + m_Section->m_Jump.LinkLocation = (uint32_t *)(*g_RecompPos - 4); + }*/ + } + else + { + CompareArmRegToArmReg(GetMipsRegMapLo(m_Opcode.rs), GetMipsRegMapLo(m_Opcode.rt)); + if (m_Section->m_Cont.FallThrough) + { + BranchLabel20(ArmBranch_Equal, m_Section->m_Jump.BranchLabel.c_str()); + m_Section->m_Jump.LinkLocation = (uint32_t *)(*g_RecompPos - 4); + } + else if (m_Section->m_Jump.FallThrough) + { + BranchLabel20(ArmBranch_Notequal, m_Section->m_Cont.BranchLabel.c_str()); + m_Section->m_Cont.LinkLocation = (uint32_t *)(*g_RecompPos - 4); + } + else + { + BranchLabel20(ArmBranch_Notequal, m_Section->m_Cont.BranchLabel.c_str()); + m_Section->m_Cont.LinkLocation = (uint32_t *)(*g_RecompPos - 4); + BranchLabel20(ArmBranch_Always, m_Section->m_Jump.BranchLabel.c_str()); + m_Section->m_Jump.LinkLocation = (uint32_t *)(*g_RecompPos - 4); + } + } + } + else + { + uint32_t ConstReg = IsConst(m_Opcode.rt) ? m_Opcode.rt : m_Opcode.rs; + uint32_t MappedReg = IsConst(m_Opcode.rt) ? m_Opcode.rs : m_Opcode.rt; + + if (Is64Bit(ConstReg) || Is64Bit(MappedReg)) + { + if (Is32Bit(ConstReg) || Is32Bit(MappedReg)) + { + if (Is32Bit(MappedReg)) + { + ProtectGPR(MappedReg); + CompareArmRegToConst(Map_TempReg(Arm_Any, MappedReg, true), GetMipsRegHi(ConstReg)); + } + else + { + CompareArmRegToConst(GetMipsRegMapHi(MappedReg), GetMipsRegLo_S(ConstReg) >> 31); + } + } + else + { + CompareArmRegToConst(GetMipsRegMapHi(MappedReg), GetMipsRegHi(ConstReg)); + } + if (m_Section->m_Cont.FallThrough) + { + Jump = *g_RecompPos; + BranchLabel8(ArmBranch_Notequal, "continue"); + } + else + { + BranchLabel20(ArmBranch_Notequal, m_Section->m_Cont.BranchLabel.c_str()); + m_Section->m_Cont.LinkLocation = (uint32_t *)(*g_RecompPos - 4); + } + CompareArmRegToConst(GetMipsRegMapLo(MappedReg), GetMipsRegLo(ConstReg)); + if (m_Section->m_Cont.FallThrough) + { + BranchLabel20(ArmBranch_Equal, m_Section->m_Jump.BranchLabel.c_str()); + m_Section->m_Jump.LinkLocation = (uint32_t *)(*g_RecompPos - 4); + CPU_Message(" "); + CPU_Message(" continue:"); + SetJump8(Jump, *g_RecompPos); + } + else if (m_Section->m_Jump.FallThrough) + { + BranchLabel20(ArmBranch_Notequal, m_Section->m_Cont.BranchLabel.c_str()); + m_Section->m_Cont.LinkLocation2 = (uint32_t *)(*g_RecompPos - 4); + } + else + { + BranchLabel20(ArmBranch_Notequal, m_Section->m_Cont.BranchLabel.c_str()); + m_Section->m_Cont.LinkLocation2 = (uint32_t *)(*g_RecompPos - 4); + BranchLabel20(ArmBranch_Always, m_Section->m_Jump.BranchLabel.c_str()); + m_Section->m_Jump.LinkLocation = (uint32_t *)(*g_RecompPos - 4); + } + } + else + { + CompareArmRegToConst(GetMipsRegMapLo(MappedReg), GetMipsRegLo(ConstReg)); + if (m_Section->m_Cont.FallThrough) + { + BranchLabel20(ArmBranch_Equal, m_Section->m_Jump.BranchLabel.c_str()); + m_Section->m_Jump.LinkLocation = (uint32_t *)(*g_RecompPos - 4); + } + else if (m_Section->m_Jump.FallThrough) + { + BranchLabel20(ArmBranch_Notequal, m_Section->m_Cont.BranchLabel.c_str()); + m_Section->m_Cont.LinkLocation = (uint32_t *)(*g_RecompPos - 4); + } + else + { + BranchLabel20(ArmBranch_Notequal, m_Section->m_Cont.BranchLabel.c_str()); + m_Section->m_Cont.LinkLocation = (uint32_t *)(*g_RecompPos - 4); + BranchLabel20(ArmBranch_Always, m_Section->m_Jump.BranchLabel.c_str()); + m_Section->m_Jump.LinkLocation = (uint32_t *)(*g_RecompPos - 4); + } + } + } + } + else if (IsKnown(m_Opcode.rs) || IsKnown(m_Opcode.rt)) + { + uint32_t KnownReg = IsKnown(m_Opcode.rt) ? m_Opcode.rt : m_Opcode.rs; + uint32_t UnknownReg = IsKnown(m_Opcode.rt) ? m_Opcode.rs : m_Opcode.rt; + + if (!g_System->b32BitCore()) + { + ArmReg TempReg = Map_TempReg(Arm_Any, UnknownReg, true); + if (IsConst(KnownReg)) + { + if (Is32Bit(KnownReg) && IsSigned(KnownReg)) + { + CompareArmRegToConst(TempReg, (GetMipsRegLo_S(KnownReg) >> 31)); + } + else if (Is32Bit(KnownReg)) + { + CompareArmRegToConst(TempReg, 0); + } + else + { + CompareArmRegToConst(TempReg, GetMipsRegHi(KnownReg)); + } + } + else + { + ProtectGPR(KnownReg); + CompareArmRegToArmReg(TempReg, Is32Bit(KnownReg) ? Map_TempReg(Arm_Any, KnownReg, true) : GetMipsRegMapHi(KnownReg)); + } + if (m_Section->m_Cont.FallThrough) + { + Jump = *g_RecompPos; + BranchLabel8(ArmBranch_Notequal, "continue"); + } + else + { + BranchLabel20(ArmBranch_Notequal, m_Section->m_Cont.BranchLabel.c_str()); + m_Section->m_Cont.LinkLocation = (uint32_t *)(*g_RecompPos - 4); + } + } + ArmReg TempReg = Map_TempReg(Arm_Any, UnknownReg, false); + if (IsConst(KnownReg)) + { + CompareArmRegToConst(TempReg, GetMipsRegLo(KnownReg)); + } + else + { + CompareArmRegToArmReg(TempReg, GetMipsRegMapLo(KnownReg)); + } + m_RegWorkingSet.SetArmRegProtected(TempReg, false); + if (m_Section->m_Cont.FallThrough) + { + BranchLabel20(ArmBranch_Equal, m_Section->m_Jump.BranchLabel.c_str()); + m_Section->m_Jump.LinkLocation = (uint32_t *)(*g_RecompPos - 4); + if (Jump) + { + CPU_Message(" "); + CPU_Message(" continue:"); + SetJump8(Jump, *g_RecompPos); + } + } + else if (m_Section->m_Jump.FallThrough) + { + BranchLabel20(ArmBranch_Notequal, m_Section->m_Cont.BranchLabel.c_str()); + if (g_System->b32BitCore()) + { + m_Section->m_Cont.LinkLocation = (uint32_t *)(*g_RecompPos - 4); + } + else + { + m_Section->m_Cont.LinkLocation2 = (uint32_t *)(*g_RecompPos - 4); + } + } + else + { + BranchLabel20(ArmBranch_Notequal, m_Section->m_Cont.BranchLabel.c_str()); + m_Section->m_Cont.LinkLocation2 = (uint32_t *)(*g_RecompPos - 4); + BranchLabel20(ArmBranch_Always, m_Section->m_Jump.BranchLabel.c_str()); + m_Section->m_Jump.LinkLocation = (uint32_t *)(*g_RecompPos - 4); + } } else { - uint8_t * Jump = NULL; - - //r0 = low, r1 = high - //r2 = low, r3 = high if (!g_System->b32BitCore()) { - MoveVariableToArmReg(&_GPR[m_Opcode.rs].UW[1],CRegName::GPR_Hi[m_Opcode.rs], Arm_R1); - MoveVariableToArmReg(&_GPR[m_Opcode.rt].UW[1],CRegName::GPR_Hi[m_Opcode.rt], Arm_R3); - CompareArmRegToArmReg(Arm_R1,Arm_R3); + ArmReg TempRegRs = Map_TempReg(Arm_Any, m_Opcode.rs, true); + ArmReg TempRegRt = Map_TempReg(Arm_Any, m_Opcode.rt, true); + CompareArmRegToArmReg(TempRegRs,TempRegRt); + m_RegWorkingSet.SetArmRegProtected(TempRegRs, false); + m_RegWorkingSet.SetArmRegProtected(TempRegRt, false); if (m_Section->m_Cont.FallThrough) { @@ -831,14 +1071,15 @@ void CArmRecompilerOps::BEQ_Compare() m_Section->m_Cont.LinkLocation = (uint32_t *)(*g_RecompPos - 4); } } - MoveVariableToArmReg(&_GPR[m_Opcode.rs].UW[0], CRegName::GPR_Lo[m_Opcode.rs], Arm_R0); - MoveVariableToArmReg(&_GPR[m_Opcode.rt].UW[0], CRegName::GPR_Lo[m_Opcode.rt], Arm_R2); - CompareArmRegToArmReg(Arm_R0, Arm_R2); + ArmReg TempRegRs = Map_TempReg(Arm_Any, m_Opcode.rs, false); + ArmReg TempRegRt = Map_TempReg(Arm_Any, m_Opcode.rt, false); + CompareArmRegToArmReg(TempRegRs,TempRegRt); + m_RegWorkingSet.SetArmRegProtected(TempRegRs, false); + m_RegWorkingSet.SetArmRegProtected(TempRegRt, false); if (m_Section->m_Cont.FallThrough) { BranchLabel20(ArmBranch_Equal, m_Section->m_Jump.BranchLabel.c_str()); m_Section->m_Jump.LinkLocation = (uint32_t *)(*g_RecompPos - 4); - if (Jump) { CPU_Message(" ");