forked from OSchip/llvm-project
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:
parent
7c2dc3667f
commit
0cfda5bbb5
|
@ -503,6 +503,14 @@ EmulateInstructionARM::EmulateMovRdSP (ARMEncoding encoding)
|
||||||
// MOV (register)
|
// MOV (register)
|
||||||
bool
|
bool
|
||||||
EmulateInstructionARM::EmulateMovLowHigh (ARMEncoding encoding)
|
EmulateInstructionARM::EmulateMovLowHigh (ARMEncoding encoding)
|
||||||
|
{
|
||||||
|
return EmulateMovRdRm (encoding);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move from register to register.
|
||||||
|
// MOV (register)
|
||||||
|
bool
|
||||||
|
EmulateInstructionARM::EmulateMovRdRm (ARMEncoding encoding)
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
// ARM pseudo code...
|
// ARM pseudo code...
|
||||||
|
@ -531,15 +539,22 @@ EmulateInstructionARM::EmulateMovLowHigh (ARMEncoding encoding)
|
||||||
{
|
{
|
||||||
uint32_t Rm; // the source register
|
uint32_t Rm; // the source register
|
||||||
uint32_t Rd; // the destination register
|
uint32_t Rd; // the destination register
|
||||||
|
bool setflags;
|
||||||
switch (encoding) {
|
switch (encoding) {
|
||||||
case eEncodingT1:
|
case eEncodingT1:
|
||||||
Rm = Bits32(opcode, 6, 3);
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
return false;
|
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)
|
if (!success)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -549,8 +564,27 @@ EmulateInstructionARM::EmulateMovLowHigh (ARMEncoding encoding)
|
||||||
dwarf_r0 + Rm,
|
dwarf_r0 + Rm,
|
||||||
0 };
|
0 };
|
||||||
|
|
||||||
if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, reg_value))
|
if (Rd == 15)
|
||||||
return false;
|
{
|
||||||
|
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;
|
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.
|
// 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>"},
|
{ 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
|
// Load instructions
|
||||||
|
|
|
@ -273,6 +273,10 @@ protected:
|
||||||
bool
|
bool
|
||||||
EmulateLDRRtRnImm (ARMEncoding encoding);
|
EmulateLDRRtRnImm (ARMEncoding encoding);
|
||||||
|
|
||||||
|
// MOV (register)
|
||||||
|
bool
|
||||||
|
EmulateMovRdRm (ARMEncoding encoding);
|
||||||
|
|
||||||
uint32_t m_arm_isa;
|
uint32_t m_arm_isa;
|
||||||
Mode m_inst_mode;
|
Mode m_inst_mode;
|
||||||
uint32_t m_inst_cpsr;
|
uint32_t m_inst_cpsr;
|
||||||
|
|
|
@ -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
|
// Masks for CPSR
|
||||||
#define MASK_CPSR_MODE_MASK (0x0000001fu)
|
#define MASK_CPSR_MODE_MASK (0x0000001fu)
|
||||||
#define MASK_CPSR_T (1u << 5)
|
#define MASK_CPSR_T (1u << CPSR_T)
|
||||||
#define MASK_CPSR_F (1u << 6)
|
#define MASK_CPSR_F (1u << CPSR_F)
|
||||||
#define MASK_CPSR_I (1u << 7)
|
#define MASK_CPSR_I (1u << CPSR_I)
|
||||||
#define MASK_CPSR_A (1u << 8)
|
#define MASK_CPSR_A (1u << CPSR_A)
|
||||||
#define MASK_CPSR_E (1u << 9)
|
#define MASK_CPSR_E (1u << CPSR_E)
|
||||||
#define MASK_CPSR_GE_MASK (0x000f0000u)
|
#define MASK_CPSR_GE_MASK (0x000f0000u)
|
||||||
#define MASK_CPSR_J (1u << 24)
|
#define MASK_CPSR_J (1u << CPSR_J)
|
||||||
#define MASK_CPSR_Q (1u << 27)
|
#define MASK_CPSR_Q (1u << CPSR_Q)
|
||||||
#define MASK_CPSR_V (1u << 28)
|
#define MASK_CPSR_V (1u << CPSR_V)
|
||||||
#define MASK_CPSR_C (1u << 29)
|
#define MASK_CPSR_C (1u << CPSR_C)
|
||||||
#define MASK_CPSR_Z (1u << 30)
|
#define MASK_CPSR_Z (1u << CPSR_Z)
|
||||||
#define MASK_CPSR_N (1u << 31)
|
#define MASK_CPSR_N (1u << CPSR_N)
|
||||||
|
|
||||||
} // namespace lldb_private
|
} // namespace lldb_private
|
||||||
|
|
||||||
|
|
|
@ -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);
|
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
|
static inline void
|
||||||
SetBits32(uint32_t &bits, unsigned msbit, unsigned lsbit, unsigned val)
|
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;
|
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"
|
// Create a mask that starts at bit zero and includes "bit"
|
||||||
static inline uint64_t
|
static inline uint64_t
|
||||||
MaskUpToBit (const uint64_t bit)
|
MaskUpToBit (const uint64_t bit)
|
||||||
|
|
Loading…
Reference in New Issue