From a8add093d1ef558eed8b778e2f1e66d1cb9e212c Mon Sep 17 00:00:00 2001 From: zilmar Date: Mon, 10 Oct 2022 11:38:55 +1030 Subject: [PATCH] Core: Add CPO_DMF/CPO_DMT to recompiler --- .../Aarch64/Aarch64RecompilerOps.cpp | 10 + .../Recompiler/Aarch64/Aarch64RecompilerOps.h | 2 + .../Recompiler/Arm/ArmRecompilerOps.cpp | 10 + .../Recompiler/Arm/ArmRecompilerOps.h | 2 + .../N64System/Recompiler/CodeBlock.cpp | 2 + .../N64System/Recompiler/CodeSection.cpp | 2 + .../Recompiler/x64-86/x64RecompilerOps.cpp | 10 + .../Recompiler/x64-86/x64RecompilerOps.h | 2 + .../Recompiler/x86/x86RecompilerOps.cpp | 217 ++++++------------ .../Recompiler/x86/x86RecompilerOps.h | 2 + 10 files changed, 114 insertions(+), 145 deletions(-) diff --git a/Source/Project64-core/N64System/Recompiler/Aarch64/Aarch64RecompilerOps.cpp b/Source/Project64-core/N64System/Recompiler/Aarch64/Aarch64RecompilerOps.cpp index 595b63048..91169843e 100644 --- a/Source/Project64-core/N64System/Recompiler/Aarch64/Aarch64RecompilerOps.cpp +++ b/Source/Project64-core/N64System/Recompiler/Aarch64/Aarch64RecompilerOps.cpp @@ -489,11 +489,21 @@ void CAarch64RecompilerOps::COP0_MF() g_Notify->BreakPoint(__FILE__, __LINE__); } +void CAarch64RecompilerOps::COP0_DMF() +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + void CAarch64RecompilerOps::COP0_MT() { g_Notify->BreakPoint(__FILE__, __LINE__); } +void CAarch64RecompilerOps::COP0_DMT() +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + void CAarch64RecompilerOps::COP0_CO_TLBR() { g_Notify->BreakPoint(__FILE__, __LINE__); diff --git a/Source/Project64-core/N64System/Recompiler/Aarch64/Aarch64RecompilerOps.h b/Source/Project64-core/N64System/Recompiler/Aarch64/Aarch64RecompilerOps.h index 4ee36d8e3..c3f978bd0 100644 --- a/Source/Project64-core/N64System/Recompiler/Aarch64/Aarch64RecompilerOps.h +++ b/Source/Project64-core/N64System/Recompiler/Aarch64/Aarch64RecompilerOps.h @@ -123,7 +123,9 @@ public: // COP0 functions void COP0_MF(); + void COP0_DMF(); void COP0_MT(); + void COP0_DMT(); // COP0 CO functions void COP0_CO_TLBR(); diff --git a/Source/Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.cpp b/Source/Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.cpp index 1c82872c8..39cd880c5 100644 --- a/Source/Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.cpp +++ b/Source/Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.cpp @@ -4232,6 +4232,11 @@ void CArmRecompilerOps::COP0_MF() } } +void CArmRecompilerOps::COP0_DMF() +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + void CArmRecompilerOps::COP0_MT() { if (m_Opcode.rt != 0) @@ -4285,6 +4290,11 @@ void CArmRecompilerOps::COP0_MT() } } +void CArmRecompilerOps::COP0_DMT() +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + void CArmRecompilerOps::COP0_CO_TLBR() { if (g_Settings->LoadBool(Game_32Bit)) diff --git a/Source/Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.h b/Source/Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.h index 7166bacbc..8be2164d6 100644 --- a/Source/Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.h +++ b/Source/Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.h @@ -130,7 +130,9 @@ public: // COP0 functions void COP0_MF(); + void COP0_DMF(); void COP0_MT(); + void COP0_DMT(); // COP0 CO functions void COP0_CO_TLBR(); diff --git a/Source/Project64-core/N64System/Recompiler/CodeBlock.cpp b/Source/Project64-core/N64System/Recompiler/CodeBlock.cpp index b94861f81..827af486f 100644 --- a/Source/Project64-core/N64System/Recompiler/CodeBlock.cpp +++ b/Source/Project64-core/N64System/Recompiler/CodeBlock.cpp @@ -676,7 +676,9 @@ bool CCodeBlock::AnalyzeInstruction(uint32_t PC, uint32_t & TargetPC, uint32_t & switch (Command.rs) { case R4300i_COP0_MT: + case R4300i_COP0_DMT: case R4300i_COP0_MF: + case R4300i_COP0_DMF: break; default: if ((Command.rs & 0x10) != 0) diff --git a/Source/Project64-core/N64System/Recompiler/CodeSection.cpp b/Source/Project64-core/N64System/Recompiler/CodeSection.cpp index 701155c22..66ebdb750 100644 --- a/Source/Project64-core/N64System/Recompiler/CodeSection.cpp +++ b/Source/Project64-core/N64System/Recompiler/CodeSection.cpp @@ -479,7 +479,9 @@ bool CCodeSection::GenerateNativeCode(uint32_t Test) switch (Opcode.rs) { case R4300i_COP0_MF: m_RecompilerOps->COP0_MF(); break; + case R4300i_COP0_DMF: m_RecompilerOps->COP0_DMF(); break; case R4300i_COP0_MT: m_RecompilerOps->COP0_MT(); break; + case R4300i_COP0_DMT: m_RecompilerOps->COP0_DMT(); break; default: if ((Opcode.rs & 0x10) != 0) { diff --git a/Source/Project64-core/N64System/Recompiler/x64-86/x64RecompilerOps.cpp b/Source/Project64-core/N64System/Recompiler/x64-86/x64RecompilerOps.cpp index a019ab710..7a30fd736 100644 --- a/Source/Project64-core/N64System/Recompiler/x64-86/x64RecompilerOps.cpp +++ b/Source/Project64-core/N64System/Recompiler/x64-86/x64RecompilerOps.cpp @@ -488,11 +488,21 @@ void CX64RecompilerOps::COP0_MF() g_Notify->BreakPoint(__FILE__, __LINE__); } +void CX64RecompilerOps::COP0_DMF() +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + void CX64RecompilerOps::COP0_MT() { g_Notify->BreakPoint(__FILE__, __LINE__); } +void CX64RecompilerOps::COP0_DMT() +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + void CX64RecompilerOps::COP0_CO_TLBR() { g_Notify->BreakPoint(__FILE__, __LINE__); diff --git a/Source/Project64-core/N64System/Recompiler/x64-86/x64RecompilerOps.h b/Source/Project64-core/N64System/Recompiler/x64-86/x64RecompilerOps.h index 24b4e732d..eca86a242 100644 --- a/Source/Project64-core/N64System/Recompiler/x64-86/x64RecompilerOps.h +++ b/Source/Project64-core/N64System/Recompiler/x64-86/x64RecompilerOps.h @@ -123,7 +123,9 @@ public: // COP0 functions void COP0_MF(); + void COP0_DMF(); void COP0_MT(); + void COP0_DMT(); // COP0 CO functions void COP0_CO_TLBR(); diff --git a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp index b4b86567c..5e51a6312 100644 --- a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp +++ b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp @@ -7197,166 +7197,93 @@ void CX86RecompilerOps::SPECIAL_DSRA32() // COP0 functions void CX86RecompilerOps::COP0_MF() { - switch (m_Opcode.rd) - { - case 9: // Count - UpdateCounters(m_RegWorkingSet, false, true); - m_RegWorkingSet.BeforeCallDirect(); - m_Assembler.CallThis((uint32_t)g_SystemTimer, AddressOf(&CSystemTimer::UpdateTimers), "CSystemTimer::UpdateTimers", 4); - m_RegWorkingSet.AfterCallDirect(); - } Map_GPR_32bit(m_Opcode.rt, true, -1); - m_Assembler.MoveVariableToX86reg(&_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd], GetMipsRegMapLo(m_Opcode.rt)); + m_RegWorkingSet.BeforeCallDirect(); + m_Assembler.PushImm32(m_Opcode.rd); + m_Assembler.CallThis((uint32_t)g_Reg, AddressOf(&CRegisters::Cop0_MF), "CRegisters::Cop0_MF", 8); + m_Assembler.MoveX86regToVariable(CX86Ops::x86_EAX, &_GPR[m_Opcode.rt].UW[0], CRegName::GPR_Lo[m_Opcode.rt]); + m_RegWorkingSet.AfterCallDirect(); + m_Assembler.MoveVariableToX86reg(&_GPR[m_Opcode.rt].UW[0], CRegName::GPR_Lo[m_Opcode.rt], GetMipsRegMapLo(m_Opcode.rt)); +} + +void CX86RecompilerOps::COP0_DMF() +{ + Map_GPR_64bit(m_Opcode.rt, -1); + m_RegWorkingSet.BeforeCallDirect(); + m_Assembler.PushImm32(m_Opcode.rd); + m_Assembler.CallThis((uint32_t)g_Reg, AddressOf(&CRegisters::Cop0_MF), "CRegisters::Cop0_MF", 8); + m_Assembler.MoveX86regToVariable(CX86Ops::x86_EAX, &_GPR[m_Opcode.rt].UW[0], CRegName::GPR_Lo[m_Opcode.rt]); + m_Assembler.MoveX86regToVariable(CX86Ops::x86_EDX, &_GPR[m_Opcode.rt].UW[1], CRegName::GPR_Hi[m_Opcode.rt]); + m_RegWorkingSet.AfterCallDirect(); + m_Assembler.MoveVariableToX86reg(&_GPR[m_Opcode.rt].UW[0], CRegName::GPR_Lo[m_Opcode.rt], GetMipsRegMapLo(m_Opcode.rt)); + m_Assembler.MoveVariableToX86reg(&_GPR[m_Opcode.rt].UW[1], CRegName::GPR_Hi[m_Opcode.rt], GetMipsRegMapHi(m_Opcode.rt)); } void CX86RecompilerOps::COP0_MT() { - uint8_t * Jump; - - switch (m_Opcode.rd) + m_RegWorkingSet.BeforeCallDirect(); + if (IsConst(m_Opcode.rt)) { - case 0: // Index - case 2: // EntryLo0 - case 3: // EntryLo1 - case 4: // Context - case 5: // PageMask - case 10: // Entry Hi - case 14: // EPC - case 16: // Config - case 18: // WatchLo - case 19: // WatchHi - case 28: // Tag Lo - case 29: // Tag Hi - case 30: // ErrEPC - if (IsConst(m_Opcode.rt)) - { - m_Assembler.MoveConstToVariable(GetMipsRegLo(m_Opcode.rt), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); - } - else if (IsMapped(m_Opcode.rt)) - { - m_Assembler.MoveX86regToVariable(GetMipsRegMapLo(m_Opcode.rt), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); - } - else - { - m_Assembler.MoveX86regToVariable(Map_TempReg(CX86Ops::x86_Unknown, m_Opcode.rt, false, false), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); - } - if (m_Opcode.rd == 4) // Context - { - m_Assembler.AndConstToVariable(0xFF800000, &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); - } - break; - case 11: // Compare - UpdateCounters(m_RegWorkingSet, false, true); - m_RegWorkingSet.BeforeCallDirect(); - m_Assembler.CallThis((uint32_t)g_SystemTimer, AddressOf(&CSystemTimer::UpdateTimers), "CSystemTimer::UpdateTimers", 4); - m_RegWorkingSet.AfterCallDirect(); - if (IsConst(m_Opcode.rt)) - { - m_Assembler.MoveConstToVariable(GetMipsRegLo(m_Opcode.rt), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); - } - else if (IsMapped(m_Opcode.rt)) - { - m_Assembler.MoveX86regToVariable(GetMipsRegMapLo(m_Opcode.rt), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); - } - else - { - m_Assembler.MoveX86regToVariable(Map_TempReg(CX86Ops::x86_Unknown, m_Opcode.rt, false, false), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); - } - m_Assembler.AndConstToVariable((uint32_t)~CAUSE_IP7, &g_Reg->FAKE_CAUSE_REGISTER, "FAKE_CAUSE_REGISTER"); - m_RegWorkingSet.BeforeCallDirect(); - m_Assembler.CallThis((uint32_t)g_SystemTimer, AddressOf(&CSystemTimer::UpdateCompareTimer), "CSystemTimer::UpdateCompareTimer", 4); - m_RegWorkingSet.AfterCallDirect(); - break; - case 9: // Count - UpdateCounters(m_RegWorkingSet, false, true); - m_RegWorkingSet.BeforeCallDirect(); - m_Assembler.CallThis((uint32_t)g_SystemTimer, AddressOf(&CSystemTimer::UpdateTimers), "CSystemTimer::UpdateTimers", 4); - m_RegWorkingSet.AfterCallDirect(); - if (IsConst(m_Opcode.rt)) - { - m_Assembler.MoveConstToVariable(GetMipsRegLo(m_Opcode.rt), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); - } - else if (IsMapped(m_Opcode.rt)) - { - m_Assembler.MoveX86regToVariable(GetMipsRegMapLo(m_Opcode.rt), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); - } - else - { - m_Assembler.MoveX86regToVariable(Map_TempReg(CX86Ops::x86_Unknown, m_Opcode.rt, false, false), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); - } - m_RegWorkingSet.BeforeCallDirect(); - m_Assembler.CallThis((uint32_t)g_SystemTimer, AddressOf(&CSystemTimer::UpdateCompareTimer), "CSystemTimer::UpdateCompareTimer", 4); - m_RegWorkingSet.AfterCallDirect(); - break; - case 12: // Status + m_Assembler.PushImm32(GetMipsRegLo_S(m_Opcode.rt) >> 31); + m_Assembler.PushImm32(GetMipsRegLo(m_Opcode.rt)); + } + else if (IsMapped(m_Opcode.rt)) { - CX86Ops::x86Reg OldStatusReg = Map_TempReg(CX86Ops::x86_Unknown, -1, false, false); - m_Assembler.MoveVariableToX86reg(&_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd], OldStatusReg); - if (IsConst(m_Opcode.rt)) - { - m_Assembler.MoveConstToVariable(GetMipsRegLo(m_Opcode.rt), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); - } - else if (IsMapped(m_Opcode.rt)) - { - m_Assembler.MoveX86regToVariable(GetMipsRegMapLo(m_Opcode.rt), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); - } - else - { - m_Assembler.MoveX86regToVariable(Map_TempReg(CX86Ops::x86_Unknown, m_Opcode.rt, false, false), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); - } - m_Assembler.XorVariableToX86reg(&_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd], OldStatusReg); - m_Assembler.TestConstToX86Reg(STATUS_FR, OldStatusReg); - m_Assembler.JeLabel8("FpuFlagFine", 0); - Jump = *g_RecompPos - 1; - m_RegWorkingSet.BeforeCallDirect(); - m_Assembler.CallThis((uint32_t)g_Reg, AddressOf(&CRegisters::FixFpuLocations), "CRegisters::FixFpuLocations", 4); - m_RegWorkingSet.AfterCallDirect(); - m_Assembler.SetJump8(Jump, *g_RecompPos); + CX86Ops::x86Reg HiReg = GetMipsRegMapLo(m_Opcode.rt) != CX86Ops::x86_EDX ? CX86Ops::x86_EDX : CX86Ops::x86_EAX; + m_Assembler.MoveX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rt), HiReg); + m_Assembler.ShiftRightSignImmed(HiReg, 0x1F); + m_Assembler.Push(HiReg); + m_Assembler.Push(GetMipsRegMapLo(m_Opcode.rt)); + } + else + { + m_Assembler.MoveVariableToX86reg(&_GPR[m_Opcode.rt].UW[0], CRegName::GPR_Lo[m_Opcode.rt], CX86Ops::x86_EAX); + m_Assembler.MoveX86RegToX86Reg(CX86Ops::x86_EAX, CX86Ops::x86_EDX); + m_Assembler.ShiftRightSignImmed(CX86Ops::x86_EDX, 0x1F); + m_Assembler.Push(CX86Ops::x86_EDX); + m_Assembler.Push(CX86Ops::x86_EAX); + } + m_Assembler.PushImm32(m_Opcode.rd); + m_Assembler.CallThis((uint32_t)g_Reg, AddressOf(&CRegisters::Cop0_MT), "CRegisters::Cop0_MT", 16); + m_Assembler.MoveX86regToVariable(CX86Ops::x86_EAX, &_GPR[m_Opcode.rt].UW[0], CRegName::GPR_Lo[m_Opcode.rt]); + m_RegWorkingSet.AfterCallDirect(); +} - m_RegWorkingSet.BeforeCallDirect(); - m_Assembler.CallThis((uint32_t)g_Reg, AddressOf(&CRegisters::CheckInterrupts), "CRegisters::CheckInterrupts", 4); - m_RegWorkingSet.AfterCallDirect(); - break; +void CX86RecompilerOps::COP0_DMT() +{ + m_RegWorkingSet.BeforeCallDirect(); + if (IsConst(m_Opcode.rt)) + { + m_Assembler.PushImm32(Is64Bit(m_Opcode.rt) ? GetMipsRegHi(m_Opcode.rt) : GetMipsRegLo_S(m_Opcode.rt) >> 31); + m_Assembler.PushImm32(GetMipsRegLo(m_Opcode.rt)); } - case 6: // Wired - UpdateCounters(m_RegWorkingSet, false, true); - m_RegWorkingSet.BeforeCallDirect(); - m_Assembler.CallThis((uint32_t)g_SystemTimer, AddressOf(&CSystemTimer::UpdateTimers), "CSystemTimer::UpdateTimers", 4); - m_RegWorkingSet.AfterCallDirect(); - if (IsConst(m_Opcode.rt)) + else if (IsMapped(m_Opcode.rt)) + { + if (Is64Bit(m_Opcode.rt)) { - m_Assembler.MoveConstToVariable(GetMipsRegLo(m_Opcode.rt), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); - } - else if (IsMapped(m_Opcode.rt)) - { - m_Assembler.MoveX86regToVariable(GetMipsRegMapLo(m_Opcode.rt), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); + m_Assembler.Push(GetMipsRegMapHi(m_Opcode.rt)); } else { - m_Assembler.MoveX86regToVariable(Map_TempReg(CX86Ops::x86_Unknown, m_Opcode.rt, false, false), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); + CX86Ops::x86Reg HiReg = GetMipsRegMapLo(m_Opcode.rt) != CX86Ops::x86_EDX ? CX86Ops::x86_EDX : CX86Ops::x86_EAX; + m_Assembler.MoveX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rt), HiReg); + m_Assembler.ShiftRightSignImmed(HiReg, 0x1F); + m_Assembler.Push(HiReg); } - break; - case 13: // Cause - m_Assembler.AndConstToVariable(0xFFFFCFF, &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); - if (IsConst(m_Opcode.rt)) - { - if ((GetMipsRegLo(m_Opcode.rt) & 0x300) != 0 && HaveDebugger()) - { - g_Notify->DisplayError("Set IP0 or IP1"); - } - } - /*else if (HaveDebugger()) - { - UnknownOpcode(); - return; - }*/ - m_RegWorkingSet.BeforeCallDirect(); - m_Assembler.CallThis((uint32_t)g_Reg, AddressOf(&CRegisters::CheckInterrupts), "CRegisters::CheckInterrupts", 4); - m_RegWorkingSet.AfterCallDirect(); - break; - default: - UnknownOpcode(); + m_Assembler.Push(GetMipsRegMapLo(m_Opcode.rt)); } + else + { + m_Assembler.MoveVariableToX86reg(&_GPR[m_Opcode.rt].UW[0], CRegName::GPR_Lo[m_Opcode.rt], CX86Ops::x86_EAX); + m_Assembler.MoveVariableToX86reg(&_GPR[m_Opcode.rt].UW[1], CRegName::GPR_Hi[m_Opcode.rt], CX86Ops::x86_EDX); + m_Assembler.Push(CX86Ops::x86_EDX); + m_Assembler.Push(CX86Ops::x86_EAX); + } + m_Assembler.PushImm32(m_Opcode.rd); + m_Assembler.CallThis((uint32_t)g_Reg, AddressOf(&CRegisters::Cop0_MT), "CRegisters::Cop0_MT", 16); + m_Assembler.MoveX86regToVariable(CX86Ops::x86_EAX, &_GPR[m_Opcode.rt].UW[0], CRegName::GPR_Lo[m_Opcode.rt]); + m_Assembler.MoveX86regToVariable(CX86Ops::x86_EDX, &_GPR[m_Opcode.rt].UW[1], CRegName::GPR_Hi[m_Opcode.rt]); + m_RegWorkingSet.AfterCallDirect(); } // COP0 CO functions diff --git a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.h b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.h index dc354f70b..482a3784b 100644 --- a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.h +++ b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.h @@ -130,7 +130,9 @@ public: // COP0 functions void COP0_MF(); + void COP0_DMF(); void COP0_MT(); + void COP0_DMT(); // COP0 CO functions void COP0_CO_TLBR();