Add some helper methods to the EmulateInstructionARM class as a first step in the

refactorings of EmulateInstructionARM.cpp file, which will be modified later to
take advantage of these helper methods.

llvm-svn: 125148
This commit is contained in:
Johnny Chen 2011-02-09 01:00:31 +00:00
parent d3a7ee6bfc
commit 7eaacc517b
2 changed files with 61 additions and 12 deletions

View File

@ -2144,6 +2144,12 @@ EmulateInstructionARM::ReadInstruction ()
return success; return success;
} }
uint32_t
EmulateInstructionARM::ArchVersion ()
{
return m_arm_isa;
}
bool bool
EmulateInstructionARM::ConditionPassed () EmulateInstructionARM::ConditionPassed ()
{ {
@ -2222,25 +2228,17 @@ EmulateInstructionARM::CurrentCond ()
return UINT32_MAX; // Return invalid value return UINT32_MAX; // Return invalid value
} }
// API client must pass in a context whose arg2 field contains the target instruction set.
bool bool
EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr) EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr)
{ {
addr_t target; addr_t target;
// Chech the target instruction set. // Check the current instruction set.
switch (context.arg2) if (CurrentInstrSet() == eModeARM)
{
default:
assert(0 && "BranchWritePC expects context.arg1 with either eModeARM or eModeThumb");
return false;
case eModeARM:
target = addr & 0xfffffffc; target = addr & 0xfffffffc;
break; else
case eModeThumb:
target = addr & 0xfffffffe; target = addr & 0xfffffffe;
break;
}
if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
return false; return false;
@ -2255,11 +2253,13 @@ EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr)
if (BitIsSet(addr, 0)) if (BitIsSet(addr, 0))
{ {
SelectInstrSet(eModeThumb);
target = addr & 0xfffffffe; target = addr & 0xfffffffe;
context.arg2 = eModeThumb; context.arg2 = eModeThumb;
} }
else if (BitIsClear(addr, 1)) else if (BitIsClear(addr, 1))
{ {
SelectInstrSet(eModeARM);
target = addr & 0xfffffffc; target = addr & 0xfffffffc;
context.arg2 = eModeARM; context.arg2 = eModeARM;
} }
@ -2272,6 +2272,43 @@ EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr)
return true; return true;
} }
// Dispatches to either BXWritePC or BranchWritePC based on architecture versions.
bool
EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr)
{
if (ArchVersion() >= ARMv5T)
return BXWritePC(context, addr);
else
return BranchWritePC((const Context)context, addr);
}
EmulateInstructionARM::Mode
EmulateInstructionARM::CurrentInstrSet ()
{
return m_inst_mode;
}
// Set the 'T' bit of our CPSR. The m_inst_mode gets updated when the next
// ReadInstruction() is performed.
bool
EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb)
{
switch (arm_or_thumb)
{
default:
return false;
eModeARM:
// Clear the T bit.
m_inst_cpsr &= ~MASK_CPSR_T;
break;
eModeThumb:
// Set the T bit.
m_inst_cpsr |= MASK_CPSR_T;
break;
}
return true;
}
bool bool
EmulateInstructionARM::EvaluateInstruction () EmulateInstructionARM::EvaluateInstruction ()
{ {

View File

@ -139,6 +139,9 @@ public:
virtual bool virtual bool
EvaluateInstruction (); EvaluateInstruction ();
uint32_t
ArchVersion();
bool bool
ConditionPassed (); ConditionPassed ();
@ -151,6 +154,15 @@ public:
bool bool
BXWritePC(Context &context, uint32_t addr); BXWritePC(Context &context, uint32_t addr);
bool
LoadWritePC(Context &context, uint32_t addr);
Mode
CurrentInstrSet();
bool
SelectInstrSet(Mode arm_or_thumb);
protected: protected:
// Typedef for the callback function used during the emulation. // Typedef for the callback function used during the emulation.