Add a generic EmulateMovRdRm() method and modify/add entries to the g_thumb_opcodes

table.  Also add some more defines and convenience functions.

llvm-svn: 125300
This commit is contained in:
Johnny Chen 2011-02-10 19:29:03 +00:00
parent 7c2dc3667f
commit 0cfda5bbb5
4 changed files with 82 additions and 15 deletions

View File

@ -503,6 +503,14 @@ EmulateInstructionARM::EmulateMovRdSP (ARMEncoding encoding)
// MOV (register)
bool
EmulateInstructionARM::EmulateMovLowHigh (ARMEncoding encoding)
{
return EmulateMovRdRm (encoding);
}
// Move from register to register.
// MOV (register)
bool
EmulateInstructionARM::EmulateMovRdRm (ARMEncoding encoding)
{
#if 0
// ARM pseudo code...
@ -531,15 +539,22 @@ EmulateInstructionARM::EmulateMovLowHigh (ARMEncoding encoding)
{
uint32_t Rm; // the source register
uint32_t Rd; // the destination register
bool setflags;
switch (encoding) {
case eEncodingT1:
Rm = Bits32(opcode, 6, 3);
Rd = Bits32(opcode, 2, 1); // bits(7) == 0
Rd = Bits32(opcode, 7, 7) << 3 | Bits32(opcode, 2, 1);
setflags = false;
break;
case eEncodingT2:
Rm = Bits32(opcode, 5, 3);
Rd = Bits32(opcode, 2, 1);
setflags = true;
break;
default:
return false;
}
int32_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success);
uint32_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success);
if (!success)
return false;
@ -549,8 +564,27 @@ EmulateInstructionARM::EmulateMovLowHigh (ARMEncoding encoding)
dwarf_r0 + Rm,
0 };
if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, reg_value))
return false;
if (Rd == 15)
{
if (!ALUWritePC (context, reg_value))
return false;
}
else
{
if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, reg_value))
return false;
if (setflags)
{
m_new_inst_cpsr = m_inst_cpsr;
SetBits32(m_new_inst_cpsr, CPSR_N, Bits32(reg_value, CPSR_N));
SetBits32(m_new_inst_cpsr, CPSR_Z, reg_value == 0 ? 1 : 0);
if (m_new_inst_cpsr != m_inst_cpsr)
{
if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
return false;
}
}
}
}
return true;
}
@ -2238,6 +2272,10 @@ EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode)
//----------------------------------------------------------------------
// Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two.
{ 0xffffff00, 0x00004400, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateAddRdnRm, "add <Rdn>, <Rm>"},
// move from high register to high register
{ 0xffffff00, 0x00004600, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMovRdRm, "mov<c> <Rd>, <Rm>"},
// move from low register to low register
{ 0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateMovRdRm, "movs <Rd>, <Rm>"},
//----------------------------------------------------------------------
// Load instructions

View File

@ -273,6 +273,10 @@ protected:
bool
EmulateLDRRtRnImm (ARMEncoding encoding);
// MOV (register)
bool
EmulateMovRdRm (ARMEncoding encoding);
uint32_t m_arm_isa;
Mode m_inst_mode;
uint32_t m_inst_cpsr;

View File

@ -58,20 +58,33 @@ static inline const char *ARMCondCodeToString(uint32_t CC)
}
}
// Bit positions for CPSR
#define CPSR_T 5
#define CPSR_F 6
#define CPSR_I 7
#define CPSR_A 8
#define CPSR_E 9
#define CPSR_J 24
#define CPSR_Q 27
#define CPSR_V 28
#define CPSR_C 29
#define CPSR_Z 30
#define CPSR_N 31
// Masks for CPSR
#define MASK_CPSR_MODE_MASK (0x0000001fu)
#define MASK_CPSR_T (1u << 5)
#define MASK_CPSR_F (1u << 6)
#define MASK_CPSR_I (1u << 7)
#define MASK_CPSR_A (1u << 8)
#define MASK_CPSR_E (1u << 9)
#define MASK_CPSR_T (1u << CPSR_T)
#define MASK_CPSR_F (1u << CPSR_F)
#define MASK_CPSR_I (1u << CPSR_I)
#define MASK_CPSR_A (1u << CPSR_A)
#define MASK_CPSR_E (1u << CPSR_E)
#define MASK_CPSR_GE_MASK (0x000f0000u)
#define MASK_CPSR_J (1u << 24)
#define MASK_CPSR_Q (1u << 27)
#define MASK_CPSR_V (1u << 28)
#define MASK_CPSR_C (1u << 29)
#define MASK_CPSR_Z (1u << 30)
#define MASK_CPSR_N (1u << 31)
#define MASK_CPSR_J (1u << CPSR_J)
#define MASK_CPSR_Q (1u << CPSR_Q)
#define MASK_CPSR_V (1u << CPSR_V)
#define MASK_CPSR_C (1u << CPSR_C)
#define MASK_CPSR_Z (1u << CPSR_Z)
#define MASK_CPSR_N (1u << CPSR_N)
} // namespace lldb_private

View File

@ -21,6 +21,12 @@ Bits32 (const uint32_t value, const uint32_t msbit, const uint32_t lsbit)
return (value >> lsbit) & ((1u << (msbit - lsbit + 1)) - 1);
}
static inline uint32_t
Bits32 (const uint32_t value, const uint32_t bit)
{
return Bits32(value, bit, bit);
}
static inline void
SetBits32(uint32_t &bits, unsigned msbit, unsigned lsbit, unsigned val)
{
@ -30,6 +36,12 @@ SetBits32(uint32_t &bits, unsigned msbit, unsigned lsbit, unsigned val)
bits |= (val & mask) << lsbit;
}
static inline void
SetBits32(uint32_t &bits, unsigned bit, unsigned val)
{
SetBits32(bits, bit, val);
}
// Create a mask that starts at bit zero and includes "bit"
static inline uint64_t
MaskUpToBit (const uint64_t bit)