[Android] Add mapping temp register

This commit is contained in:
zilmar 2016-10-01 05:58:04 +10:00
parent 8d836692a4
commit 93475500e2
4 changed files with 162 additions and 1 deletions

View File

@ -386,6 +386,41 @@ void CArmOps::PopArmReg(uint16_t Registers)
AddCode16(op.Hex); AddCode16(op.Hex);
} }
void CArmOps::ShiftRightSignImmed(ArmReg DestReg, ArmReg SourceReg, uint32_t shift)
{
if ((shift & (~0x1F)) != 0)
{
g_Notify->BreakPoint(__FILE__,__LINE__);
}
else if (DestReg > 0x7 || SourceReg > 0x7)
{
CPU_Message(" asrs.w\t%s, %s, #%d", ArmRegName(DestReg), ArmRegName(SourceReg), (uint32_t)shift);
Arm32Opcode op = {0};
op.imm5.rn = 0xF;
op.imm5.s = 0;
op.imm5.opcode = 0x752;
op.imm5.rm = SourceReg;
op.imm5.type = 2;
op.imm5.imm2 = shift & 3;
op.imm5.rd = DestReg;
op.imm5.imm3 = (shift >> 2) & 7;
op.imm5.opcode2 = 0;
AddCode32(op.Hex);
}
else
{
CPU_Message(" asrs\t%s, %s, #%d", ArmRegName(DestReg), ArmRegName(SourceReg), (uint32_t)shift);
ArmThumbOpcode op = {0};
op.Imm5.rt = DestReg;
op.Imm5.rn = SourceReg;
op.Imm5.imm5 = shift;
op.Imm5.opcode = 0x2;
AddCode16(op.Hex);
}
}
void CArmOps::StoreArmRegToArmRegPointer(ArmReg Reg, ArmReg RegPointer, uint8_t offset) void CArmOps::StoreArmRegToArmRegPointer(ArmReg Reg, ArmReg RegPointer, uint8_t offset)
{ {
if (Reg > 0x7 || RegPointer > 0x7) if (Reg > 0x7 || RegPointer > 0x7)

View File

@ -153,6 +153,7 @@ protected:
static void MoveVariableToArmReg(void * Variable, const char * VariableName, ArmReg reg); static void MoveVariableToArmReg(void * Variable, const char * VariableName, ArmReg reg);
static void PushArmReg(uint16_t Registers); static void PushArmReg(uint16_t Registers);
static void PopArmReg(uint16_t Registers); static void PopArmReg(uint16_t Registers);
static void ShiftRightSignImmed(ArmReg DestReg, ArmReg SourceReg, uint32_t shift);
static void StoreArmRegToArmRegPointer(ArmReg Reg, ArmReg RegPointer, uint8_t offset); static void StoreArmRegToArmRegPointer(ArmReg Reg, ArmReg RegPointer, uint8_t offset);
static void SubConstFromArmReg(ArmReg Reg, uint32_t Const); static void SubConstFromArmReg(ArmReg Reg, uint32_t Const);
static void SubConstFromVariable(uint32_t Const, void * Variable, const char * VariableName); static void SubConstFromVariable(uint32_t Const, void * Variable, const char * VariableName);

View File

@ -21,6 +21,7 @@ m_InCallDirect(false)
{ {
for (int32_t i = 0, n = sizeof(m_ArmReg_MappedTo) / sizeof(m_ArmReg_MappedTo[0]); i < n; i++) for (int32_t i = 0, n = sizeof(m_ArmReg_MappedTo) / sizeof(m_ArmReg_MappedTo[0]); i < n; i++)
{ {
m_ArmReg_MapOrder[i] = 0;
m_ArmReg_Protected[i] = false; m_ArmReg_Protected[i] = false;
m_ArmReg_MappedTo[i] = NotMapped; m_ArmReg_MappedTo[i] = NotMapped;
m_Variable_MappedTo[i] = VARIABLE_UNKNOWN; m_Variable_MappedTo[i] = VARIABLE_UNKNOWN;
@ -41,6 +42,7 @@ CArmRegInfo& CArmRegInfo::operator=(const CArmRegInfo& right)
CRegBase::operator=(right); CRegBase::operator=(right);
m_InCallDirect = right.m_InCallDirect; m_InCallDirect = right.m_InCallDirect;
memcpy(&m_ArmReg_MapOrder, &right.m_ArmReg_MapOrder, sizeof(m_ArmReg_MapOrder));
memcpy(&m_ArmReg_Protected, &right.m_ArmReg_Protected, sizeof(m_ArmReg_Protected)); 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_ArmReg_MappedTo, &right.m_ArmReg_MappedTo, sizeof(m_ArmReg_MappedTo));
memcpy(&m_Variable_MappedTo, &right.m_Variable_MappedTo, sizeof(m_Variable_MappedTo)); memcpy(&m_Variable_MappedTo, &right.m_Variable_MappedTo, sizeof(m_Variable_MappedTo));
@ -105,6 +107,125 @@ void CArmRegInfo::WriteBackRegisters()
{ {
} }
CArmOps::ArmReg CArmRegInfo::Map_TempReg(ArmReg Reg, int32_t MipsReg, bool LoadHiWord)
{
if (m_InCallDirect)
{
CPU_Message("%s: in CallDirect",__FUNCTION__);
g_Notify->BreakPoint(__FILE__, __LINE__);
return Arm_Unknown;
}
ArmReg GprReg = MipsReg >= 0 ? Map_Variable(VARIABLE_GPR) : Arm_Unknown;
if (Reg == CArmOps::Arm_Any)
{
if (GetArmRegMapped(Arm_R7) == Temp_Mapped && !GetArmRegProtected(Arm_R7)) { Reg = Arm_R7; }
else if (GetArmRegMapped(Arm_R6) == Temp_Mapped && !GetArmRegProtected(Arm_R6)) { Reg = Arm_R6; }
else if (GetArmRegMapped(Arm_R5) == Temp_Mapped && !GetArmRegProtected(Arm_R5)) { Reg = Arm_R5; }
else if (GetArmRegMapped(Arm_R4) == Temp_Mapped && !GetArmRegProtected(Arm_R4)) { Reg = Arm_R4; }
else if (GetArmRegMapped(Arm_R3) == Temp_Mapped && !GetArmRegProtected(Arm_R3)) { Reg = Arm_R3; }
else if (GetArmRegMapped(Arm_R2) == Temp_Mapped && !GetArmRegProtected(Arm_R2)) { Reg = Arm_R2; }
else if (GetArmRegMapped(Arm_R1) == Temp_Mapped && !GetArmRegProtected(Arm_R1)) { Reg = Arm_R1; }
else if (GetArmRegMapped(Arm_R0) == Temp_Mapped && !GetArmRegProtected(Arm_R0)) { Reg = Arm_R0; }
else if (GetArmRegMapped(Arm_R12) == Temp_Mapped && !GetArmRegProtected(Arm_R12)) { Reg = Arm_R12; }
else if (GetArmRegMapped(Arm_R11) == Temp_Mapped && !GetArmRegProtected(Arm_R11)) { Reg = Arm_R11; }
else if (GetArmRegMapped(Arm_R10) == Temp_Mapped && !GetArmRegProtected(Arm_R10)) { Reg = Arm_R10; }
else if (GetArmRegMapped(Arm_R9) == Temp_Mapped && !GetArmRegProtected(Arm_R9)) { Reg = Arm_R9; }
else if (GetArmRegMapped(Arm_R8) == Temp_Mapped && !GetArmRegProtected(Arm_R8)) { Reg = Arm_R8; }
if (Reg == Arm_Any)
{
Reg = FreeArmReg();
if (Reg == Arm_Unknown)
{
WriteTrace(TraceRegisterCache, TraceError, "Failed to find a free register");
g_Notify->BreakPoint(__FILE__, __LINE__);
return Arm_Unknown;
}
}
}
else if (GetArmRegMapped(Reg) == NotMapped || GetArmRegMapped(Reg) == Temp_Mapped)
{
if (GetArmRegProtected(Reg))
{
g_Notify->BreakPoint(__FILE__, __LINE__);
}
}
else if (GetArmRegMapped(Reg) == GPR_Mapped)
{
g_Notify->BreakPoint(__FILE__, __LINE__);
}
else
{
g_Notify->BreakPoint(__FILE__, __LINE__);
}
if (MipsReg < 0)
{
CPU_Message(" regcache: allocate %s as temp storage", ArmRegName(Reg));
}
else
{
CPU_Message(" regcache: allocate %s as temp storage (%s)", ArmRegName(Reg), LoadHiWord ? CRegName::GPR_Hi[MipsReg] : CRegName::GPR_Lo[MipsReg]);
if (GprReg == Arm_Unknown)
{
g_Notify->BreakPoint(__FILE__, __LINE__);
}
if (LoadHiWord)
{
if (IsUnknown(MipsReg))
{
LoadArmRegPointerToArmReg(Reg, GprReg, (uint8_t)(MipsReg << 3) + 4);
}
else if (IsMapped(MipsReg))
{
g_Notify->BreakPoint(__FILE__, __LINE__);
}
else
{
if (Is64Bit(MipsReg))
{
g_Notify->BreakPoint(__FILE__, __LINE__);
//MoveConstToArmReg(Reg, GetMipsRegHi(MipsReg));
}
else
{
g_Notify->BreakPoint(__FILE__, __LINE__);
//MoveConstToArmReg(Reg, GetMipsRegLo_S(MipsReg) >> 31);
}
}
}
else
{
if (IsUnknown(MipsReg))
{
LoadArmRegPointerToArmReg(Reg, GprReg, (uint8_t)(MipsReg << 3));
}
else if (IsMapped(MipsReg))
{
g_Notify->BreakPoint(__FILE__, __LINE__);
//MoveArmRegToArmReg(GetMipsRegMapLo(MipsReg), Reg);
}
else
{
MoveConstToArmReg(GetMipsRegLo(MipsReg), Reg );
}
}
}
SetArmRegMapped(Reg, Temp_Mapped);
SetArmRegProtected(Reg, true);
for (int32_t i = 0, n = sizeof(m_ArmReg_MappedTo) / sizeof(m_ArmReg_MappedTo[0]); i < n; i++)
{
int32_t MapOrder = GetArmRegMapOrder((ArmReg)i);
if (MapOrder > 0)
{
SetArmRegMapOrder((ArmReg)i, MapOrder + 1);
}
}
SetArmRegMapOrder(Reg, 1);
SetArmRegProtected(GprReg, false);
return Reg;
}
CArmOps::ArmReg CArmRegInfo::Map_Variable(VARIABLE_MAPPED variable) CArmOps::ArmReg CArmRegInfo::Map_Variable(VARIABLE_MAPPED variable)
{ {
if (m_InCallDirect) if (m_InCallDirect)

View File

@ -46,19 +46,23 @@ public:
bool operator==(const CArmRegInfo& right) const; bool operator==(const CArmRegInfo& right) const;
bool operator!=(const CArmRegInfo& right) const; bool operator!=(const CArmRegInfo& right) const;
void BeforeCallDirect(void); void BeforeCallDirect(void);
void AfterCallDirect(void); void AfterCallDirect(void);
ArmReg FreeArmReg(); ArmReg FreeArmReg();
void WriteBackRegisters(); void WriteBackRegisters();
ArmReg Map_TempReg(ArmReg Reg, int32_t MipsReg, bool LoadHiWord);
ArmReg Map_Variable(VARIABLE_MAPPED variable); ArmReg Map_Variable(VARIABLE_MAPPED variable);
inline uint32_t GetArmRegMapOrder(ArmReg Reg) const { return m_ArmReg_MapOrder[Reg]; }
inline bool GetArmRegProtected(ArmReg Reg) const { return m_ArmReg_Protected[Reg]; } inline bool GetArmRegProtected(ArmReg Reg) const { return m_ArmReg_Protected[Reg]; }
inline REG_MAPPED GetArmRegMapped(ArmReg Reg) const { return m_ArmReg_MappedTo[Reg]; } inline REG_MAPPED GetArmRegMapped(ArmReg Reg) const { return m_ArmReg_MappedTo[Reg]; }
inline void SetArmRegMapOrder(ArmReg Reg, uint32_t Order) { m_ArmReg_MapOrder[Reg] = Order; }
inline void SetArmRegProtected(ArmReg Reg, bool Protected) { m_ArmReg_Protected[Reg] = Protected; } 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; } inline void SetArmRegMapped(ArmReg Reg, REG_MAPPED Mapping) { m_ArmReg_MappedTo[Reg] = Mapping; }
private: private:
uint32_t m_ArmReg_MapOrder[16];
bool m_ArmReg_Protected[16]; bool m_ArmReg_Protected[16];
REG_MAPPED m_ArmReg_MappedTo[16]; REG_MAPPED m_ArmReg_MappedTo[16];
VARIABLE_MAPPED m_Variable_MappedTo[16]; VARIABLE_MAPPED m_Variable_MappedTo[16];