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;
}
uint32_t
EmulateInstructionARM::ArchVersion ()
{
return m_arm_isa;
}
bool
EmulateInstructionARM::ConditionPassed ()
{
@ -2222,25 +2228,17 @@ EmulateInstructionARM::CurrentCond ()
return UINT32_MAX; // Return invalid value
}
// API client must pass in a context whose arg2 field contains the target instruction set.
bool
EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr)
{
addr_t target;
// Chech the target instruction set.
switch (context.arg2)
{
default:
assert(0 && "BranchWritePC expects context.arg1 with either eModeARM or eModeThumb");
return false;
case eModeARM:
// Check the current instruction set.
if (CurrentInstrSet() == eModeARM)
target = addr & 0xfffffffc;
break;
case eModeThumb:
else
target = addr & 0xfffffffe;
break;
}
if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
return false;
@ -2255,11 +2253,13 @@ EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr)
if (BitIsSet(addr, 0))
{
SelectInstrSet(eModeThumb);
target = addr & 0xfffffffe;
context.arg2 = eModeThumb;
}
else if (BitIsClear(addr, 1))
{
SelectInstrSet(eModeARM);
target = addr & 0xfffffffc;
context.arg2 = eModeARM;
}
@ -2272,6 +2272,43 @@ EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr)
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
EmulateInstructionARM::EvaluateInstruction ()
{

View File

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