[Android] Add check for ShouldPushPopReg

This commit is contained in:
zilmar 2016-10-01 14:38:45 +10:00
parent ccf7f7feda
commit 512d2e7825
2 changed files with 95 additions and 2 deletions

View File

@ -63,25 +63,84 @@ CArmRegInfo& CArmRegInfo::operator=(const CArmRegInfo& right)
return *this;
}
bool CArmRegInfo::ShouldPushPopReg (ArmReg Reg)
{
if (m_ArmReg_MappedTo[Reg] == NotMapped)
{
return false;
}
if (m_ArmReg_MappedTo[Reg] == Temp_Mapped && !GetArmRegProtected(Reg))
{
return false;
}
return true;
}
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;
}
UnMap_AllFPRs();
m_InCallDirect = true;
int PushPopRegisters = 0;
if (ShouldPushPopReg(Arm_R0)) { PushPopRegisters |= ArmPushPop_R0; }
if (ShouldPushPopReg(Arm_R1)) { PushPopRegisters |= ArmPushPop_R1; }
if (ShouldPushPopReg(Arm_R2)) { PushPopRegisters |= ArmPushPop_R2; }
if (ShouldPushPopReg(Arm_R3)) { PushPopRegisters |= ArmPushPop_R3; }
if (ShouldPushPopReg(Arm_R4)) { PushPopRegisters |= ArmPushPop_R4; }
if (ShouldPushPopReg(Arm_R5)) { PushPopRegisters |= ArmPushPop_R5; }
if (ShouldPushPopReg(Arm_R6)) { PushPopRegisters |= ArmPushPop_R6; }
if (ShouldPushPopReg(Arm_R7)) { PushPopRegisters |= ArmPushPop_R7; }
if (ShouldPushPopReg(Arm_R8)) { PushPopRegisters |= ArmPushPop_R8; }
if (ShouldPushPopReg(Arm_R9)) { PushPopRegisters |= ArmPushPop_R9; }
if (ShouldPushPopReg(Arm_R10)) { PushPopRegisters |= ArmPushPop_R10; }
if (ShouldPushPopReg(Arm_R11)) { PushPopRegisters |= ArmPushPop_R11; }
if (ShouldPushPopReg(Arm_R12)) { PushPopRegisters |= ArmPushPop_R12; }
if (ShouldPushPopReg(Arm_R13)) { PushPopRegisters |= ArmPushPop_R13; }
if (ShouldPushPopReg(Arm_R14)) { PushPopRegisters |= ArmPushPop_R14; }
if (ShouldPushPopReg(Arm_R15)) { PushPopRegisters |= ArmPushPop_R15; }
if (PushPopRegisters != 0)
{
PushArmReg(PushPopRegisters);
}
}
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;
}
int PushPopRegisters = 0;
if (ShouldPushPopReg(Arm_R0)) { PushPopRegisters |= ArmPushPop_R0; }
if (ShouldPushPopReg(Arm_R1)) { PushPopRegisters |= ArmPushPop_R1; }
if (ShouldPushPopReg(Arm_R2)) { PushPopRegisters |= ArmPushPop_R2; }
if (ShouldPushPopReg(Arm_R3)) { PushPopRegisters |= ArmPushPop_R3; }
if (ShouldPushPopReg(Arm_R4)) { PushPopRegisters |= ArmPushPop_R4; }
if (ShouldPushPopReg(Arm_R5)) { PushPopRegisters |= ArmPushPop_R5; }
if (ShouldPushPopReg(Arm_R6)) { PushPopRegisters |= ArmPushPop_R6; }
if (ShouldPushPopReg(Arm_R7)) { PushPopRegisters |= ArmPushPop_R7; }
if (ShouldPushPopReg(Arm_R8)) { PushPopRegisters |= ArmPushPop_R8; }
if (ShouldPushPopReg(Arm_R9)) { PushPopRegisters |= ArmPushPop_R9; }
if (ShouldPushPopReg(Arm_R10)) { PushPopRegisters |= ArmPushPop_R10; }
if (ShouldPushPopReg(Arm_R11)) { PushPopRegisters |= ArmPushPop_R11; }
if (ShouldPushPopReg(Arm_R12)) { PushPopRegisters |= ArmPushPop_R12; }
if (ShouldPushPopReg(Arm_R13)) { PushPopRegisters |= ArmPushPop_R13; }
if (ShouldPushPopReg(Arm_R14)) { PushPopRegisters |= ArmPushPop_R14; }
if (ShouldPushPopReg(Arm_R15)) { PushPopRegisters |= ArmPushPop_R15; }
if (PushPopRegisters != 0)
{
PopArmReg(PushPopRegisters);
}
SetRoundingModel(CRegInfo::RoundUnknown);
m_InCallDirect = false;
}
@ -342,6 +401,17 @@ void CArmRegInfo::Map_GPR_64bit(int32_t MipsReg, int32_t MipsRegToLoad)
SetMipsRegState(MipsReg, STATE_MAPPED_64);
}
void CArmRegInfo::UnMap_AllFPRs()
{
if (m_InCallDirect)
{
CPU_Message("%s: in CallDirect",__FUNCTION__);
g_Notify->BreakPoint(__FILE__, __LINE__);
return;
}
CPU_Message("%s", __FUNCTION__);
}
CArmOps::ArmReg CArmRegInfo::FreeArmReg()
{
if (m_InCallDirect)
@ -547,4 +617,23 @@ CArmOps::ArmReg CArmRegInfo::Map_Variable(VARIABLE_MAPPED variable)
return Reg;
}
void CArmRegInfo::ProtectGPR(uint32_t Reg)
{
if (m_InCallDirect)
{
CPU_Message("%s: in CallDirect",__FUNCTION__);
g_Notify->BreakPoint(__FILE__, __LINE__);
return;
}
if (IsUnknown(Reg) || IsConst(Reg))
{
return;
}
if (Is64Bit(Reg))
{
SetArmRegProtected(GetMipsRegMapHi(Reg), true);
}
SetArmRegProtected(GetMipsRegMapLo(Reg), true);
}
#endif

View File

@ -60,6 +60,8 @@ public:
ArmReg Map_TempReg(ArmReg Reg, int32_t MipsReg, bool LoadHiWord);
ArmReg Map_Variable(VARIABLE_MAPPED variable);
void ProtectGPR(uint32_t Reg);
void UnMap_AllFPRs();
inline ArmReg GetMipsRegMapLo(int32_t Reg) const { return m_RegMapLo[Reg]; }
inline ArmReg GetMipsRegMapHi(int32_t Reg) const { return m_RegMapHi[Reg]; }
@ -73,6 +75,8 @@ public:
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 ShouldPushPopReg (ArmReg Reg);
ArmReg m_RegMapHi[32];
ArmReg m_RegMapLo[32];
uint32_t m_ArmReg_MapOrder[16];