[Android] Add mapping temp register
This commit is contained in:
parent
8d836692a4
commit
93475500e2
|
@ -386,6 +386,41 @@ void CArmOps::PopArmReg(uint16_t Registers)
|
|||
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)
|
||||
{
|
||||
if (Reg > 0x7 || RegPointer > 0x7)
|
||||
|
|
|
@ -153,6 +153,7 @@ protected:
|
|||
static void MoveVariableToArmReg(void * Variable, const char * VariableName, ArmReg reg);
|
||||
static void PushArmReg(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 SubConstFromArmReg(ArmReg Reg, uint32_t Const);
|
||||
static void SubConstFromVariable(uint32_t Const, void * Variable, const char * VariableName);
|
||||
|
|
|
@ -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++)
|
||||
{
|
||||
m_ArmReg_MapOrder[i] = 0;
|
||||
m_ArmReg_Protected[i] = false;
|
||||
m_ArmReg_MappedTo[i] = NotMapped;
|
||||
m_Variable_MappedTo[i] = VARIABLE_UNKNOWN;
|
||||
|
@ -41,6 +42,7 @@ CArmRegInfo& CArmRegInfo::operator=(const CArmRegInfo& right)
|
|||
CRegBase::operator=(right);
|
||||
|
||||
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_MappedTo, &right.m_ArmReg_MappedTo, sizeof(m_ArmReg_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)
|
||||
{
|
||||
if (m_InCallDirect)
|
||||
|
|
|
@ -53,12 +53,16 @@ public:
|
|||
ArmReg FreeArmReg();
|
||||
void WriteBackRegisters();
|
||||
|
||||
ArmReg Map_TempReg(ArmReg Reg, int32_t MipsReg, bool LoadHiWord);
|
||||
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 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 SetArmRegMapped(ArmReg Reg, REG_MAPPED Mapping) { m_ArmReg_MappedTo[Reg] = Mapping; }
|
||||
private:
|
||||
uint32_t m_ArmReg_MapOrder[16];
|
||||
bool m_ArmReg_Protected[16];
|
||||
REG_MAPPED m_ArmReg_MappedTo[16];
|
||||
VARIABLE_MAPPED m_Variable_MappedTo[16];
|
||||
|
|
Loading…
Reference in New Issue