diff options
author | Johnny Chen <johnny.chen@apple.com> | 2011-02-10 19:29:03 +0000 |
---|---|---|
committer | Johnny Chen <johnny.chen@apple.com> | 2011-02-10 19:29:03 +0000 |
commit | 0cfda5bbb55bbc9da5ec17df09ac4c6140ce9373 (patch) | |
tree | 301baf82b6f8e462210f569897c68b949fe2274c | |
parent | 7c2dc3667f74c0d7ed36c3d38ad5c7c99275e0f8 (diff) | |
download | bcm5719-llvm-0cfda5bbb55bbc9da5ec17df09ac4c6140ce9373.tar.gz bcm5719-llvm-0cfda5bbb55bbc9da5ec17df09ac4c6140ce9373.zip |
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
4 files changed, 82 insertions, 15 deletions
diff --git a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp index c9c3758a38c..bf984415f5f 100644 --- a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp +++ b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp @@ -504,6 +504,14 @@ EmulateInstructionARM::EmulateMovRdSP (ARMEncoding encoding) 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... if (ConditionPassed()) @@ -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 diff --git a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h index eca630a7a58..ed58c45bc92 100644 --- a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h +++ b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h @@ -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; diff --git a/lldb/source/Plugins/Process/Utility/ARMDefines.h b/lldb/source/Plugins/Process/Utility/ARMDefines.h index c4614f69311..6453a3c1a4b 100644 --- a/lldb/source/Plugins/Process/Utility/ARMDefines.h +++ b/lldb/source/Plugins/Process/Utility/ARMDefines.h @@ -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 diff --git a/lldb/source/Plugins/Process/Utility/InstructionUtils.h b/lldb/source/Plugins/Process/Utility/InstructionUtils.h index 8ed2a71e36c..a7e32b3306f 100644 --- a/lldb/source/Plugins/Process/Utility/InstructionUtils.h +++ b/lldb/source/Plugins/Process/Utility/InstructionUtils.h @@ -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) |