From 89a6eaf9d1743f8fa4204e781a183dbb791d25db Mon Sep 17 00:00:00 2001 From: zilmar Date: Thu, 14 Dec 2023 13:52:15 +1030 Subject: [PATCH] Core: Add RecordLLAddress for 32bit register pointer --- .../Aarch64/Aarch64RecompilerOps.cpp | 5 ++ .../Recompiler/Aarch64/Aarch64RecompilerOps.h | 1 + .../Recompiler/Arm/ArmRecompilerOps.cpp | 5 ++ .../Recompiler/Arm/ArmRecompilerOps.h | 1 + .../N64System/Recompiler/CodeSection.cpp | 1 + .../Recompiler/x64-86/x64RecompilerOps.cpp | 5 ++ .../Recompiler/x64-86/x64RecompilerOps.h | 1 + .../Recompiler/x86/x86RecompilerOps.cpp | 53 +++++++++++++++---- .../Recompiler/x86/x86RecompilerOps.h | 4 +- 9 files changed, 65 insertions(+), 11 deletions(-) diff --git a/Source/Project64-core/N64System/Recompiler/Aarch64/Aarch64RecompilerOps.cpp b/Source/Project64-core/N64System/Recompiler/Aarch64/Aarch64RecompilerOps.cpp index 6c46824e59..d2c7615e20 100644 --- a/Source/Project64-core/N64System/Recompiler/Aarch64/Aarch64RecompilerOps.cpp +++ b/Source/Project64-core/N64System/Recompiler/Aarch64/Aarch64RecompilerOps.cpp @@ -319,6 +319,11 @@ void CAarch64RecompilerOps::SPECIAL_BREAK() g_Notify->BreakPoint(__FILE__, __LINE__); } +void CAarch64RecompilerOps::SPECIAL_SYNC() +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + void CAarch64RecompilerOps::SPECIAL_MFLO() { 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 572c32b00a..e1abcdc46a 100644 --- a/Source/Project64-core/N64System/Recompiler/Aarch64/Aarch64RecompilerOps.h +++ b/Source/Project64-core/N64System/Recompiler/Aarch64/Aarch64RecompilerOps.h @@ -87,6 +87,7 @@ class CAarch64RecompilerOps void SPECIAL_JALR(); void SPECIAL_SYSCALL(); void SPECIAL_BREAK(); + void SPECIAL_SYNC(); void SPECIAL_MFLO(); void SPECIAL_MTLO(); void SPECIAL_MFHI(); diff --git a/Source/Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.cpp b/Source/Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.cpp index c594023e1c..3f8d9d908f 100644 --- a/Source/Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.cpp +++ b/Source/Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.cpp @@ -320,6 +320,11 @@ void CArmRecompilerOps::SPECIAL_BREAK() g_Notify->BreakPoint(__FILE__, __LINE__); } +void CArmRecompilerOps::SPECIAL_SYNC() +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + void CArmRecompilerOps::SPECIAL_MFLO() { g_Notify->BreakPoint(__FILE__, __LINE__); diff --git a/Source/Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.h b/Source/Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.h index 5feae987cb..70356efdef 100644 --- a/Source/Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.h +++ b/Source/Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.h @@ -86,6 +86,7 @@ class CArmRecompilerOps void SPECIAL_JALR(); void SPECIAL_SYSCALL(); void SPECIAL_BREAK(); + void SPECIAL_SYNC(); void SPECIAL_MFLO(); void SPECIAL_MTLO(); void SPECIAL_MFHI(); diff --git a/Source/Project64-core/N64System/Recompiler/CodeSection.cpp b/Source/Project64-core/N64System/Recompiler/CodeSection.cpp index 4519bccfd9..3436bc03d1 100644 --- a/Source/Project64-core/N64System/Recompiler/CodeSection.cpp +++ b/Source/Project64-core/N64System/Recompiler/CodeSection.cpp @@ -429,6 +429,7 @@ bool CCodeSection::GenerateNativeCode(uint32_t Test) case R4300i_SPECIAL_MFLO: m_RecompilerOps->SPECIAL_MFLO(); break; case R4300i_SPECIAL_SYSCALL: m_RecompilerOps->SPECIAL_SYSCALL(); break; case R4300i_SPECIAL_BREAK: m_RecompilerOps->SPECIAL_BREAK(); break; + case R4300i_SPECIAL_SYNC: m_RecompilerOps->SPECIAL_SYNC(); break; case R4300i_SPECIAL_MTLO: m_RecompilerOps->SPECIAL_MTLO(); break; case R4300i_SPECIAL_MFHI: m_RecompilerOps->SPECIAL_MFHI(); break; case R4300i_SPECIAL_MTHI: m_RecompilerOps->SPECIAL_MTHI(); break; diff --git a/Source/Project64-core/N64System/Recompiler/x64-86/x64RecompilerOps.cpp b/Source/Project64-core/N64System/Recompiler/x64-86/x64RecompilerOps.cpp index 07fd68a07f..fcdc494786 100644 --- a/Source/Project64-core/N64System/Recompiler/x64-86/x64RecompilerOps.cpp +++ b/Source/Project64-core/N64System/Recompiler/x64-86/x64RecompilerOps.cpp @@ -321,6 +321,11 @@ void CX64RecompilerOps::SPECIAL_BREAK() g_Notify->BreakPoint(__FILE__, __LINE__); } +void CX64RecompilerOps::SPECIAL_SYNC() +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + void CX64RecompilerOps::SPECIAL_MFLO() { 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 6882442b27..9d0ac73254 100644 --- a/Source/Project64-core/N64System/Recompiler/x64-86/x64RecompilerOps.h +++ b/Source/Project64-core/N64System/Recompiler/x64-86/x64RecompilerOps.h @@ -84,6 +84,7 @@ class CX64RecompilerOps : void SPECIAL_JALR(); void SPECIAL_SYSCALL(); void SPECIAL_BREAK(); + void SPECIAL_SYNC(); void SPECIAL_MFLO(); void SPECIAL_MTLO(); void SPECIAL_MFHI(); diff --git a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp index 243528e44d..226f3c26ec 100644 --- a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp +++ b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp @@ -3158,7 +3158,8 @@ void CX86RecompilerOps::LB() } PreReadInstruction(); m_RegWorkingSet.Map_GPR_32bit(m_Opcode.rt, true, m_Opcode.base == m_Opcode.rt ? m_Opcode.rt : -1); - CompileLoadMemoryValue(x86Reg_Unknown, m_RegWorkingSet.GetMipsRegMapLo(m_Opcode.rt), x86Reg_Unknown, 8, true); + asmjit::x86::Gp AddressReg = x86Reg_Unknown; + CompileLoadMemoryValue(AddressReg, m_RegWorkingSet.GetMipsRegMapLo(m_Opcode.rt), x86Reg_Unknown, 8, true); } void CX86RecompilerOps::LH() @@ -3178,7 +3179,8 @@ void CX86RecompilerOps::LH() return; } PreReadInstruction(); - CompileLoadMemoryValue(x86Reg_Unknown, x86Reg_Unknown, x86Reg_Unknown, 16, true); + asmjit::x86::Gp AddressReg = x86Reg_Unknown; + CompileLoadMemoryValue(AddressReg, x86Reg_Unknown, x86Reg_Unknown, 16, true); } void CX86RecompilerOps::LWL() @@ -3269,10 +3271,12 @@ void CX86RecompilerOps::LW(bool ResultSigned, bool bRecordLLBit) else { PreReadInstruction(); - CompileLoadMemoryValue(x86Reg_Unknown, x86Reg_Unknown, x86Reg_Unknown, 32, false); + asmjit::x86::Gp AddressReg = x86Reg_Unknown; + CompileLoadMemoryValue(AddressReg, x86Reg_Unknown, x86Reg_Unknown, 32, false); if (bRecordLLBit) { - g_Notify->BreakPoint(__FILE__, __LINE__); + m_RegWorkingSet.SetX86Protected(GetIndexFromX86Reg(AddressReg), true); + RecordLLAddress(AddressReg); } } if (g_System->bFastSP() && m_Opcode.rt == 29) @@ -3539,7 +3543,8 @@ void CX86RecompilerOps::LBU() } PreReadInstruction(); m_RegWorkingSet.Map_GPR_32bit(m_Opcode.rt, true, m_Opcode.base == m_Opcode.rt ? m_Opcode.rt : -1); - CompileLoadMemoryValue(x86Reg_Unknown, m_RegWorkingSet.GetMipsRegMapLo(m_Opcode.rt), x86Reg_Unknown, 8, false); + asmjit::x86::Gp AddressReg = x86Reg_Unknown; + CompileLoadMemoryValue(AddressReg, m_RegWorkingSet.GetMipsRegMapLo(m_Opcode.rt), x86Reg_Unknown, 8, false); } void CX86RecompilerOps::LHU() @@ -3563,7 +3568,8 @@ void CX86RecompilerOps::LHU() } PreReadInstruction(); m_RegWorkingSet.Map_GPR_32bit(m_Opcode.rt, false, m_Opcode.base == m_Opcode.rt ? m_Opcode.rt : -1); - CompileLoadMemoryValue(x86Reg_Unknown, m_RegWorkingSet.GetMipsRegMapLo(m_Opcode.rt), x86Reg_Unknown, 16, false); + asmjit::x86::Gp AddressReg = x86Reg_Unknown; + CompileLoadMemoryValue(AddressReg, m_RegWorkingSet.GetMipsRegMapLo(m_Opcode.rt), x86Reg_Unknown, 16, false); } void CX86RecompilerOps::LWR() @@ -4013,7 +4019,8 @@ void CX86RecompilerOps::LWC1() } PreReadInstruction(); asmjit::x86::Gp ValueReg = m_RegWorkingSet.Map_TempReg(x86Reg_Unknown, -1, false, false); - CompileLoadMemoryValue(x86Reg_Unknown, ValueReg, x86Reg_Unknown, 32, false); + asmjit::x86::Gp AddressReg = x86Reg_Unknown; + CompileLoadMemoryValue(AddressReg, ValueReg, x86Reg_Unknown, 32, false); asmjit::x86::Gp FPR_SPtr = m_RegWorkingSet.Map_TempReg(x86Reg_Unknown, -1, false, false); m_Assembler.MoveVariableToX86reg(FPR_SPtr, &m_Reg.m_FPR_S[m_Opcode.ft], stdstr_f("m_FPR_S[%d]", m_Opcode.ft).c_str()); m_Assembler.mov(asmjit::x86::dword_ptr(FPR_SPtr), ValueReg); @@ -4050,7 +4057,8 @@ void CX86RecompilerOps::LDC1() m_RegWorkingSet.UnMap_FPR(m_Opcode.ft, true); asmjit::x86::Gp ValueRegHi = m_RegWorkingSet.Map_TempReg(x86Reg_Unknown, -1, false, false), ValueRegLo = m_RegWorkingSet.Map_TempReg(x86Reg_Unknown, -1, false, false); - CompileLoadMemoryValue(x86Reg_Unknown, ValueRegLo, ValueRegHi, 64, false); + asmjit::x86::Gp AddressReg = x86Reg_Unknown; + CompileLoadMemoryValue(AddressReg, ValueRegLo, ValueRegHi, 64, false); asmjit::x86::Gp FPR_DPtr = m_RegWorkingSet.Map_TempReg(x86Reg_Unknown, -1, false, false); m_Assembler.MoveVariableToX86reg(FPR_DPtr, &m_Reg.m_FPR_D[m_Opcode.ft], stdstr_f("_FPR_D[%d]", m_Opcode.ft).c_str()); @@ -4099,7 +4107,8 @@ void CX86RecompilerOps::LD() } m_RegWorkingSet.Map_GPR_64bit(m_Opcode.rt, m_Opcode.rt == m_Opcode.base ? m_Opcode.base : -1); - CompileLoadMemoryValue(x86Reg_Unknown, m_RegWorkingSet.GetMipsRegMapLo(m_Opcode.rt), m_RegWorkingSet.GetMipsRegMapHi(m_Opcode.rt), 64, false); + asmjit::x86::Gp AddressReg = x86Reg_Unknown; + CompileLoadMemoryValue(AddressReg, m_RegWorkingSet.GetMipsRegMapLo(m_Opcode.rt), m_RegWorkingSet.GetMipsRegMapHi(m_Opcode.rt), 64, false); } if (g_System->bFastSP() && m_Opcode.rt == 29) { @@ -4632,6 +4641,10 @@ void CX86RecompilerOps::SPECIAL_BREAK() m_PipelineStage = PIPELINE_STAGE_END_BLOCK; } +void CX86RecompilerOps::SPECIAL_SYNC() +{ +} + void CX86RecompilerOps::SPECIAL_MFLO() { if (m_Opcode.rd == 0) @@ -8455,6 +8468,26 @@ void CX86RecompilerOps::UnknownOpcode() } } +void CX86RecompilerOps::RecordLLAddress(const asmjit::x86::Gp & AddressReg) +{ + m_Assembler.MoveConstToVariable(&m_Reg.m_LLBit, "LLBit", 1); + + asmjit::x86::Gp TempReg = m_RegWorkingSet.Map_TempReg(x86Reg_Unknown, -1, false, false); + m_RegWorkingSet.BeforeCallDirect(); + m_Assembler.PushImm32("m_TempMemoryUsed", (uint32_t)&m_TempMemoryUsed); + m_Assembler.PushImm32("m_TempValue32", (uint32_t)&m_TempValue32); + m_Assembler.mov(TempReg, AddressReg); + m_Assembler.sar(TempReg, 31); + m_Assembler.push(TempReg); + m_Assembler.push(AddressReg); + m_Assembler.CallThis((uint32_t)&m_TLB, AddressOf(&CTLB::VAddrToPAddr), "CTLB::VAddrToPAddr", 20); + m_RegWorkingSet.AfterCallDirect(); + m_Assembler.MoveVariableToX86reg(TempReg, &m_TempValue32, "m_TempValue32"); + m_Assembler.shr(TempReg, 4); + m_Assembler.MoveX86regToVariable(&g_Reg->m_CP0[17], "m_CP0[17]", TempReg); + m_Assembler.MoveConstToVariable(((uint8_t *)&g_Reg->m_CP0[17]) + 4, "m_CP0[17] + 4", 0); +} + void CX86RecompilerOps::RecordLLAddress(uint64_t Address) { m_Assembler.MoveConstToVariable(&m_Reg.m_LLBit, "LLBit", 1); @@ -9860,7 +9893,7 @@ asmjit::x86::Gp CX86RecompilerOps::BaseOffsetAddress(bool UseBaseRegister) return AddressReg; } -void CX86RecompilerOps::CompileLoadMemoryValue(asmjit::x86::Gp AddressReg, asmjit::x86::Gp ValueReg, const asmjit::x86::Gp & ValueRegHi, uint8_t ValueSize, bool SignExtend) +void CX86RecompilerOps::CompileLoadMemoryValue(asmjit::x86::Gp & AddressReg, asmjit::x86::Gp ValueReg, const asmjit::x86::Gp & ValueRegHi, uint8_t ValueSize, bool SignExtend) { bool UnprotectAddressReg = !AddressReg.isValid(); if (UnprotectAddressReg) diff --git a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.h b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.h index e7ed596acc..7798fd792d 100644 --- a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.h +++ b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.h @@ -97,6 +97,7 @@ class CX86RecompilerOps : void SPECIAL_JALR(); void SPECIAL_SYSCALL(); void SPECIAL_BREAK(); + void SPECIAL_SYNC(); void SPECIAL_MFLO(); void SPECIAL_MTLO(); void SPECIAL_MFHI(); @@ -209,6 +210,7 @@ class CX86RecompilerOps : // Other functions void UnknownOpcode(); + void RecordLLAddress(const asmjit::x86::Gp & AddressReg); void RecordLLAddress(uint64_t Address); void ClearCachedInstructionInfo(); void FoundMemoryBreakpoint(); @@ -270,7 +272,7 @@ class CX86RecompilerOps : CX86RecompilerOps & operator=(const CX86RecompilerOps &); asmjit::x86::Gp BaseOffsetAddress(bool UseBaseRegister); - void CompileLoadMemoryValue(asmjit::x86::Gp AddressReg, asmjit::x86::Gp ValueReg, const asmjit::x86::Gp & ValueRegHi, uint8_t ValueSize, bool SignExtend); + void CompileLoadMemoryValue(asmjit::x86::Gp & AddressReg, asmjit::x86::Gp ValueReg, const asmjit::x86::Gp & ValueRegHi, uint8_t ValueSize, bool SignExtend); void CompileStoreMemoryValue(asmjit::x86::Gp AddressReg, asmjit::x86::Gp ValueReg, const asmjit::x86::Gp & ValueRegHi, uint64_t Value, uint8_t ValueSize); void SB_Const(uint32_t Value, uint32_t Addr);