diff --git a/Source/Project64-core/N64System/Recompiler/CodeSection.cpp b/Source/Project64-core/N64System/Recompiler/CodeSection.cpp index fd28410af..495975f09 100644 --- a/Source/Project64-core/N64System/Recompiler/CodeSection.cpp +++ b/Source/Project64-core/N64System/Recompiler/CodeSection.cpp @@ -960,20 +960,20 @@ bool CCodeSection::GenerateNativeCode(uint32_t Test) case R4300i_REGIMM: switch (m_Opcode.rt) { - case R4300i_REGIMM_BLTZ:Compile_Branch(BLTZ_Compare, BranchTypeRs, false); break; - case R4300i_REGIMM_BGEZ:Compile_Branch(BGEZ_Compare, BranchTypeRs, false); break; - case R4300i_REGIMM_BLTZL:Compile_BranchLikely(BLTZ_Compare, false); break; - case R4300i_REGIMM_BGEZL:Compile_BranchLikely(BGEZ_Compare, false); break; - case R4300i_REGIMM_BLTZAL:Compile_Branch(BLTZ_Compare, BranchTypeRs, true); break; - case R4300i_REGIMM_BGEZAL:Compile_Branch(BGEZ_Compare, BranchTypeRs, true); break; + case R4300i_REGIMM_BLTZ:Compile_Branch(CRecompilerOps::CompareTypeBLTZ, BranchTypeRs, false); break; + case R4300i_REGIMM_BGEZ:Compile_Branch(CRecompilerOps::CompareTypeBGEZ, BranchTypeRs, false); break; + case R4300i_REGIMM_BLTZL:Compile_BranchLikely(CRecompilerOps::CompareTypeBLTZ, false); break; + case R4300i_REGIMM_BGEZL:Compile_BranchLikely(CRecompilerOps::CompareTypeBGEZ, false); break; + case R4300i_REGIMM_BLTZAL:Compile_Branch(CRecompilerOps::CompareTypeBLTZ, BranchTypeRs, true); break; + case R4300i_REGIMM_BGEZAL:Compile_Branch(CRecompilerOps::CompareTypeBGEZ, BranchTypeRs, true); break; default: UnknownOpcode(); break; } break; - case R4300i_BEQ: Compile_Branch(BEQ_Compare, BranchTypeRsRt, false); break; - case R4300i_BNE: Compile_Branch(BNE_Compare, BranchTypeRsRt, false); break; - case R4300i_BGTZ:Compile_Branch(BGTZ_Compare, BranchTypeRs, false); break; - case R4300i_BLEZ:Compile_Branch(BLEZ_Compare, BranchTypeRs, false); break; + case R4300i_BEQ: Compile_Branch(CRecompilerOps::CompareTypeBEQ, BranchTypeRsRt, false); break; + case R4300i_BNE: Compile_Branch(CRecompilerOps::CompareTypeBNE, BranchTypeRsRt, false); break; + case R4300i_BGTZ:Compile_Branch(CRecompilerOps::CompareTypeBGTZ, BranchTypeRs, false); break; + case R4300i_BLEZ:Compile_Branch(CRecompilerOps::CompareTypeBLEZ, BranchTypeRs, false); break; case R4300i_J: J(); break; case R4300i_JAL: JAL(); break; case R4300i_ADDI: ADDI(); break; @@ -1020,10 +1020,10 @@ bool CCodeSection::GenerateNativeCode(uint32_t Test) case R4300i_COP1_BC: switch (m_Opcode.ft) { - case R4300i_COP1_BC_BCF: Compile_Branch(COP1_BCF_Compare, BranchTypeCop1, false); break; - case R4300i_COP1_BC_BCT: Compile_Branch(COP1_BCT_Compare, BranchTypeCop1, false); break; - case R4300i_COP1_BC_BCFL: Compile_BranchLikely(COP1_BCF_Compare, false); break; - case R4300i_COP1_BC_BCTL: Compile_BranchLikely(COP1_BCT_Compare, false); break; + case R4300i_COP1_BC_BCF: Compile_Branch(CRecompilerOps::CompareTypeCOP1BCF, BranchTypeCop1, false); break; + case R4300i_COP1_BC_BCT: Compile_Branch(CRecompilerOps::CompareTypeCOP1BCT, BranchTypeCop1, false); break; + case R4300i_COP1_BC_BCFL: Compile_BranchLikely(CRecompilerOps::CompareTypeCOP1BCF, false); break; + case R4300i_COP1_BC_BCTL: Compile_BranchLikely(CRecompilerOps::CompareTypeCOP1BCT, false); break; default: UnknownOpcode(); break; } @@ -1120,10 +1120,10 @@ bool CCodeSection::GenerateNativeCode(uint32_t Test) UnknownOpcode(); break; } break; - case R4300i_BEQL: Compile_BranchLikely(BEQ_Compare, false); break; - case R4300i_BNEL: Compile_BranchLikely(BNE_Compare, false); break; - case R4300i_BGTZL:Compile_BranchLikely(BGTZ_Compare, false); break; - case R4300i_BLEZL:Compile_BranchLikely(BLEZ_Compare, false); break; + case R4300i_BEQL: Compile_BranchLikely(CRecompilerOps::CompareTypeBEQ, false); break; + case R4300i_BNEL: Compile_BranchLikely(CRecompilerOps::CompareTypeBNE, false); break; + case R4300i_BGTZL:Compile_BranchLikely(CRecompilerOps::CompareTypeBGTZ, false); break; + case R4300i_BLEZL:Compile_BranchLikely(CRecompilerOps::CompareTypeBLEZ, false); break; case R4300i_DADDIU: DADDIU(); break; case R4300i_LDL: LDL(); break; case R4300i_LDR: LDR(); break; diff --git a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp index 26b6e6b51..7eb878ea0 100644 --- a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp +++ b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp @@ -106,7 +106,24 @@ void CRecompilerOps::CompileWriteTLBMiss(x86Reg AddressReg, x86Reg LookUpReg) bool DelaySlotEffectsCompare(uint32_t PC, uint32_t Reg1, uint32_t Reg2); /************************** Branch functions ************************/ -void CRecompilerOps::Compile_Branch(CRecompilerOps::BranchFunction CompareFunc, BRANCH_TYPE BranchType, bool Link) +void CRecompilerOps::Compile_BranchCompare(BRANCH_COMPARE CompareType) +{ + switch (CompareType) + { + case CompareTypeBEQ: BEQ_Compare(); break; + case CompareTypeBNE: BNE_Compare(); break; + case CompareTypeBLTZ: BLTZ_Compare(); break; + case CompareTypeBLEZ: BLEZ_Compare(); break; + case CompareTypeBGTZ: BGTZ_Compare(); break; + case CompareTypeBGEZ: BGEZ_Compare(); break; + case CompareTypeCOP1BCF: COP1_BCF_Compare(); break; + case CompareTypeCOP1BCT: COP1_BCT_Compare(); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } +} + +void CRecompilerOps::Compile_Branch(BRANCH_COMPARE CompareType, BRANCH_TYPE BranchType, bool Link) { static CRegInfo RegBeforeDelay; static bool EffectDelaySlot; @@ -114,7 +131,10 @@ void CRecompilerOps::Compile_Branch(CRecompilerOps::BranchFunction CompareFunc, if (m_NextInstruction == NORMAL) { CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - + if (CompareType == CompareTypeCOP1BCF || CompareType == CompareTypeCOP1BCT) + { + m_Section->CompileCop1Test(); + } if (m_CompilePC + ((int16_t)m_Opcode.offset << 2) + 4 == m_CompilePC + 8) { return; @@ -127,25 +147,25 @@ void CRecompilerOps::Compile_Branch(CRecompilerOps::BranchFunction CompareFunc, case BranchTypeRs: EffectDelaySlot = DelaySlotEffectsCompare(m_CompilePC, m_Opcode.rs, 0); break; case BranchTypeRsRt: EffectDelaySlot = DelaySlotEffectsCompare(m_CompilePC, m_Opcode.rs, m_Opcode.rt); break; case BranchTypeCop1: - { - OPCODE Command; - - if (!g_MMU->LW_VAddr(m_CompilePC + 4, Command.Hex)) { - g_Notify->FatalError(GS(MSG_FAIL_LOAD_WORD)); - } + OPCODE Command; - EffectDelaySlot = false; - if (Command.op == R4300i_CP1) - { - if ((Command.fmt == R4300i_COP1_S && (Command.funct & 0x30) == 0x30) || - (Command.fmt == R4300i_COP1_D && (Command.funct & 0x30) == 0x30)) + if (!g_MMU->LW_VAddr(m_CompilePC + 4, Command.Hex)) { - EffectDelaySlot = true; + g_Notify->FatalError(GS(MSG_FAIL_LOAD_WORD)); + } + + EffectDelaySlot = false; + if (Command.op == R4300i_CP1) + { + if ((Command.fmt == R4300i_COP1_S && (Command.funct & 0x30) == 0x30) || + (Command.fmt == R4300i_COP1_D && (Command.funct & 0x30) == 0x30)) + { + EffectDelaySlot = true; + } } } - } - break; + break; default: if (bHaveDebugger()) { g_Notify->DisplayError("Unknown branch type"); } } @@ -211,7 +231,7 @@ void CRecompilerOps::Compile_Branch(CRecompilerOps::BranchFunction CompareFunc, } if (m_Section->m_Jump.TargetPC != m_Section->m_Cont.TargetPC) { - CompareFunc(); + Compile_BranchCompare(CompareType); } if (!m_Section->m_Jump.FallThrough && !m_Section->m_Cont.FallThrough) { @@ -381,7 +401,7 @@ void CRecompilerOps::Compile_Branch(CRecompilerOps::BranchFunction CompareFunc, { if (m_Section->m_Jump.TargetPC != m_Section->m_Cont.TargetPC) { - CompareFunc(); + Compile_BranchCompare(CompareType); ResetX86Protection(); m_Section->m_Cont.RegSet = m_RegWorkingSet; m_Section->m_Jump.RegSet = m_RegWorkingSet; @@ -418,12 +438,16 @@ void CRecompilerOps::Compile_Branch(CRecompilerOps::BranchFunction CompareFunc, } } -void CRecompilerOps::Compile_BranchLikely(BranchFunction CompareFunc, bool Link) +void CRecompilerOps::Compile_BranchLikely(BRANCH_COMPARE CompareType, bool Link) { if (m_NextInstruction == NORMAL) { CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + if (CompareType == CompareTypeCOP1BCF || CompareType == CompareTypeCOP1BCT) + { + m_Section->CompileCop1Test();; + } if (!g_System->bLinkBlocks() || (m_CompilePC & 0xFFC) == 0xFFC) { m_Section->m_Jump.JumpPC = m_CompilePC; @@ -479,7 +503,7 @@ void CRecompilerOps::Compile_BranchLikely(BranchFunction CompareFunc, bool Link) m_RegWorkingSet.SetMipsRegState(31, CRegInfo::STATE_CONST_32_SIGN); } - CompareFunc(); + Compile_BranchCompare(CompareType); ResetX86Protection(); m_Section->m_Cont.RegSet = m_RegWorkingSet; diff --git a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.h b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.h index 7bc2cf1aa..632c99c4f 100644 --- a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.h +++ b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.h @@ -31,22 +31,34 @@ class CRecompilerOps : public: enum BRANCH_TYPE { - BranchTypeCop1, BranchTypeRs, BranchTypeRsRt + BranchTypeCop1, + BranchTypeRs, + BranchTypeRsRt + }; + enum BRANCH_COMPARE + { + CompareTypeBEQ, + CompareTypeBNE, + CompareTypeBLTZ, + CompareTypeBLEZ, + CompareTypeBGTZ, + CompareTypeBGEZ, + CompareTypeCOP1BCF, + CompareTypeCOP1BCT, }; - typedef void ( * BranchFunction )(); - /************************** Branch functions ************************/ - void Compile_Branch ( BranchFunction CompareFunc, BRANCH_TYPE BranchType, bool Link); - void Compile_BranchLikely ( BranchFunction CompareFunc, bool Link); - static void BNE_Compare(); - static void BEQ_Compare(); - static void BGTZ_Compare(); - static void BLEZ_Compare(); - static void BLTZ_Compare(); - static void BGEZ_Compare(); - static void COP1_BCF_Compare(); - static void COP1_BCT_Compare(); + void Compile_BranchCompare(BRANCH_COMPARE CompareType); + void Compile_Branch(BRANCH_COMPARE CompareType, BRANCH_TYPE BranchType, bool Link); + void Compile_BranchLikely(BRANCH_COMPARE CompareType, bool Link); + void BNE_Compare(); + void BEQ_Compare(); + void BGTZ_Compare(); + void BLEZ_Compare(); + void BLTZ_Compare(); + void BGEZ_Compare(); + void COP1_BCF_Compare(); + void COP1_BCT_Compare(); /************************* OpCode functions *************************/ static void J ();