From 8d836692a4ac0eeb889fd55bc6c0ffdd15fa5085 Mon Sep 17 00:00:00 2001 From: zilmar Date: Fri, 30 Sep 2016 23:33:07 +1000 Subject: [PATCH] [Project64] Add map variable --- .../N64System/Recompiler/Arm/ArmOps.h | 3 + .../N64System/Recompiler/Arm/ArmRegInfo.cpp | 98 ++++++++++++++++++- .../N64System/Recompiler/Arm/ArmRegInfo.h | 31 +++++- 3 files changed, 129 insertions(+), 3 deletions(-) diff --git a/Source/Project64-core/N64System/Recompiler/Arm/ArmOps.h b/Source/Project64-core/N64System/Recompiler/Arm/ArmOps.h index 2a9df3347..c54b63b9f 100644 --- a/Source/Project64-core/N64System/Recompiler/Arm/ArmOps.h +++ b/Source/Project64-core/N64System/Recompiler/Arm/ArmOps.h @@ -35,6 +35,9 @@ public: ArmRegLR = 14, Arm_R15 = 15, ArmRegPC = 15, + + Arm_Unknown = -1, + Arm_Any = -2, }; enum ArmFpuSingle diff --git a/Source/Project64-core/N64System/Recompiler/Arm/ArmRegInfo.cpp b/Source/Project64-core/N64System/Recompiler/Arm/ArmRegInfo.cpp index ee3ff1e36..564a622ce 100644 --- a/Source/Project64-core/N64System/Recompiler/Arm/ArmRegInfo.cpp +++ b/Source/Project64-core/N64System/Recompiler/Arm/ArmRegInfo.cpp @@ -11,12 +11,20 @@ #include "stdafx.h" #if defined(__arm__) || defined(_M_ARM) +#include +#include #include #include CArmRegInfo::CArmRegInfo() : m_InCallDirect(false) { + for (int32_t i = 0, n = sizeof(m_ArmReg_MappedTo) / sizeof(m_ArmReg_MappedTo[0]); i < n; i++) + { + m_ArmReg_Protected[i] = false; + m_ArmReg_MappedTo[i] = NotMapped; + m_Variable_MappedTo[i] = VARIABLE_UNKNOWN; + } } CArmRegInfo::CArmRegInfo(const CArmRegInfo& rhs) @@ -33,6 +41,9 @@ CArmRegInfo& CArmRegInfo::operator=(const CArmRegInfo& right) CRegBase::operator=(right); m_InCallDirect = right.m_InCallDirect; + memcpy(&m_ArmReg_Protected, &right.m_ArmReg_Protected, sizeof(m_ArmReg_Protected)); + memcpy(&m_ArmReg_MappedTo, &right.m_ArmReg_MappedTo, sizeof(m_ArmReg_MappedTo)); + memcpy(&m_Variable_MappedTo, &right.m_Variable_MappedTo, sizeof(m_Variable_MappedTo)); #ifdef _DEBUG if (*this != right) { @@ -46,7 +57,7 @@ void CArmRegInfo::BeforeCallDirect(void) { if (m_InCallDirect) { - CPU_Message("%s: in CallDirect",__FUNCTION__); + CPU_Message("%s: in CallDirect", __FUNCTION__); g_Notify->BreakPoint(__FILE__, __LINE__); return; } @@ -57,14 +68,97 @@ void CArmRegInfo::AfterCallDirect(void) { if (!m_InCallDirect) { - CPU_Message("%s: Not in CallDirect",__FUNCTION__); + CPU_Message("%s: Not in CallDirect", __FUNCTION__); g_Notify->BreakPoint(__FILE__, __LINE__); return; } m_InCallDirect = false; } +CArmOps::ArmReg CArmRegInfo::FreeArmReg() +{ + if (m_InCallDirect) + { + CPU_Message("%s: in CallDirect",__FUNCTION__); + g_Notify->BreakPoint(__FILE__, __LINE__); + return Arm_Unknown; + } + if ((GetArmRegMapped(Arm_R7) == NotMapped || GetArmRegMapped(Arm_R7) == Temp_Mapped) && !GetArmRegProtected(Arm_R7)) { return Arm_R7; } + if ((GetArmRegMapped(Arm_R6) == NotMapped || GetArmRegMapped(Arm_R6) == Temp_Mapped) && !GetArmRegProtected(Arm_R6)) { return Arm_R6; } + if ((GetArmRegMapped(Arm_R5) == NotMapped || GetArmRegMapped(Arm_R5) == Temp_Mapped) && !GetArmRegProtected(Arm_R5)) { return Arm_R5; } + if ((GetArmRegMapped(Arm_R4) == NotMapped || GetArmRegMapped(Arm_R4) == Temp_Mapped) && !GetArmRegProtected(Arm_R4)) { return Arm_R4; } + if ((GetArmRegMapped(Arm_R3) == NotMapped || GetArmRegMapped(Arm_R3) == Temp_Mapped) && !GetArmRegProtected(Arm_R3)) { return Arm_R3; } + if ((GetArmRegMapped(Arm_R2) == NotMapped || GetArmRegMapped(Arm_R2) == Temp_Mapped) && !GetArmRegProtected(Arm_R2)) { return Arm_R2; } + if ((GetArmRegMapped(Arm_R1) == NotMapped || GetArmRegMapped(Arm_R1) == Temp_Mapped) && !GetArmRegProtected(Arm_R1)) { return Arm_R1; } + if ((GetArmRegMapped(Arm_R0) == NotMapped || GetArmRegMapped(Arm_R0) == Temp_Mapped) && !GetArmRegProtected(Arm_R0)) { return Arm_R0; } + if ((GetArmRegMapped(Arm_R12) == NotMapped || GetArmRegMapped(Arm_R12) == Temp_Mapped) && !GetArmRegProtected(Arm_R12)) { return Arm_R12; } + if ((GetArmRegMapped(Arm_R11) == NotMapped || GetArmRegMapped(Arm_R11) == Temp_Mapped) && !GetArmRegProtected(Arm_R11)) { return Arm_R11; } + if ((GetArmRegMapped(Arm_R10) == NotMapped || GetArmRegMapped(Arm_R10) == Temp_Mapped) && !GetArmRegProtected(Arm_R10)) { return Arm_R10; } + if ((GetArmRegMapped(Arm_R9) == NotMapped || GetArmRegMapped(Arm_R9) == Temp_Mapped) && !GetArmRegProtected(Arm_R9)) { return Arm_R9; } + if ((GetArmRegMapped(Arm_R8) == NotMapped || GetArmRegMapped(Arm_R8) == Temp_Mapped) && !GetArmRegProtected(Arm_R8)) { return Arm_R8; } + + g_Notify->BreakPoint(__FILE__, __LINE__); + return Arm_Unknown; +} + void CArmRegInfo::WriteBackRegisters() { } + +CArmOps::ArmReg CArmRegInfo::Map_Variable(VARIABLE_MAPPED variable) +{ + if (m_InCallDirect) + { + CPU_Message("%s: in CallDirect", __FUNCTION__); + g_Notify->BreakPoint(__FILE__, __LINE__); + return Arm_Unknown; + } + for (int32_t i = 0, n = sizeof(m_ArmReg_MappedTo) / sizeof(m_ArmReg_MappedTo[0]); i < n; i++) + { + if (m_ArmReg_MappedTo[i] == Variable_Mapped && m_Variable_MappedTo[i] == variable) + { + SetArmRegProtected((ArmReg)i, true); + return (ArmReg)i; + } + } + + ArmReg Reg = FreeArmReg(); + if (Reg == Arm_Unknown) + { + WriteTrace(TraceRegisterCache, TraceError, "Failed to find a free register"); + g_Notify->BreakPoint(__FILE__, __LINE__); + return Arm_Unknown; + } + SetArmRegMapped(Reg, Variable_Mapped); + SetArmRegProtected(Reg, true); + + switch (variable) + { + case VARIABLE_GPR: + CPU_Message(" regcache: allocate %s as pointer to GPR", ArmRegName(Reg)); + m_Variable_MappedTo[Reg] = variable; + MoveConstToArmReg((uint32_t)_GPR, Reg, "_GPR"); + break; + case VARIABLE_FPR: + CPU_Message(" regcache: allocate %s as pointer to _FPR_S", ArmRegName(Reg)); + m_Variable_MappedTo[Reg] = variable; + MoveConstToArmReg((uint32_t)_FPR_S, Reg, "_FPR_S"); + break; + case VARIABLE_TLB_READMAP: + CPU_Message(" regcache: allocate %s as pointer to TLB_READMAP", ArmRegName(Reg)); + m_Variable_MappedTo[Reg] = variable; + MoveConstToArmReg((uint32_t)(g_MMU->m_TLB_ReadMap), Reg, "MMU->TLB_ReadMap"); + break; + case VARIABLE_NEXT_TIMER: + CPU_Message(" regcache: allocate %s as pointer to g_NextTimer", ArmRegName(Reg)); + m_Variable_MappedTo[Reg] = variable; + MoveConstToArmReg((uint32_t)(g_NextTimer), Reg, "g_NextTimer"); + break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + return Arm_Unknown; + } + return Reg; +} + #endif \ No newline at end of file diff --git a/Source/Project64-core/N64System/Recompiler/Arm/ArmRegInfo.h b/Source/Project64-core/N64System/Recompiler/Arm/ArmRegInfo.h index 082a385a2..8f20d7c1c 100644 --- a/Source/Project64-core/N64System/Recompiler/Arm/ArmRegInfo.h +++ b/Source/Project64-core/N64System/Recompiler/Arm/ArmRegInfo.h @@ -12,12 +12,32 @@ #if defined(__arm__) || defined(_M_ARM) #include #include +#include class CArmRegInfo : public CRegBase, - public CArmOps + public CArmOps, + private CSystemRegisters { public: + //enums + enum REG_MAPPED + { + NotMapped = 0, + GPR_Mapped = 1, + Temp_Mapped = 2, + Variable_Mapped = 3, + }; + + enum VARIABLE_MAPPED + { + VARIABLE_UNKNOWN = 0, + VARIABLE_GPR = 1, + VARIABLE_FPR = 2, + VARIABLE_TLB_READMAP = 3, + VARIABLE_NEXT_TIMER = 4, + }; + CArmRegInfo(); CArmRegInfo(const CArmRegInfo&); ~CArmRegInfo(); @@ -30,9 +50,18 @@ public: void BeforeCallDirect(void); void AfterCallDirect(void); + ArmReg FreeArmReg(); void WriteBackRegisters(); + ArmReg Map_Variable(VARIABLE_MAPPED variable); + inline bool GetArmRegProtected(ArmReg Reg) const { return m_ArmReg_Protected[Reg]; } + inline REG_MAPPED GetArmRegMapped(ArmReg Reg) const { return m_ArmReg_MappedTo[Reg]; } + inline void SetArmRegProtected(ArmReg Reg, bool Protected) { m_ArmReg_Protected[Reg] = Protected; } + inline void SetArmRegMapped(ArmReg Reg, REG_MAPPED Mapping) { m_ArmReg_MappedTo[Reg] = Mapping; } private: + bool m_ArmReg_Protected[16]; + REG_MAPPED m_ArmReg_MappedTo[16]; + VARIABLE_MAPPED m_Variable_MappedTo[16]; bool m_InCallDirect; }; #endif