Pass along (ARMEncoding)encoding as the callback data, which allows us to abstract

the EmulateCallback routine without too much duplication.  Add an entry for emulating
ARM PUSH with encoding A2.

llvm-svn: 124009
This commit is contained in:
Johnny Chen 2011-01-22 00:47:08 +00:00
parent d14777a2f2
commit 7aeb12b848
1 changed files with 20 additions and 8 deletions

View File

@ -66,9 +66,6 @@ using namespace lldb_private;
#define ARMv8 (1u << 8) #define ARMv8 (1u << 8)
#define ARMvAll (0xffffffffu) #define ARMvAll (0xffffffffu)
typedef bool (*EmulateCallback) (EmulateInstructionARM *emulator);
typedef enum ARMEncoding typedef enum ARMEncoding
{ {
eEncodingA1, eEncodingA1,
@ -83,7 +80,9 @@ typedef enum ARMEncoding
eEncodingT5, eEncodingT5,
} ARMEncoding; } ARMEncoding;
// Pass along (ARMEncoding)encoding as the callback data.
typedef bool (*EmulateCallback) (EmulateInstructionARM *emulator, ARMEncoding encoding);
typedef struct ARMOpcode typedef struct ARMOpcode
{ {
uint32_t mask; uint32_t mask;
@ -95,7 +94,7 @@ typedef struct ARMOpcode
}; };
static bool static bool
EmulateARMPushEncodingA1 (EmulateInstructionARM *emulator) EmulateARMPushEncoding (EmulateInstructionARM *emulator, ARMEncoding encoding)
{ {
#if 0 #if 0
// ARM pseudo code... // ARM pseudo code...
@ -135,7 +134,19 @@ EmulateARMPushEncodingA1 (EmulateInstructionARM *emulator)
const addr_t sp = emulator->ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); const addr_t sp = emulator->ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
if (!success) if (!success)
return false; return false;
const uint32_t registers = EmulateInstruction::UnsignedBits (opcode, 15, 0); uint32_t registers = 0;
switch (encoding) {
case eEncodingA1:
registers = EmulateInstruction::UnsignedBits (opcode, 15, 0);
break;
case eEncodingA2:
const uint32_t Rt = EmulateInstruction::UnsignedBits (opcode, 15, 12);
// if t == 13 then UNPREDICTABLE
if (Rt == dwarf_sp)
return false;
registers = (1u << Rt);
break;
}
addr_t sp_offset = addr_byte_size * EmulateInstruction::BitCount (registers); addr_t sp_offset = addr_byte_size * EmulateInstruction::BitCount (registers);
addr_t addr = sp - sp_offset; addr_t addr = sp - sp_offset;
uint32_t i; uint32_t i;
@ -159,7 +170,7 @@ EmulateARMPushEncodingA1 (EmulateInstructionARM *emulator)
if (EmulateInstruction::BitIsSet (registers, 1u << 15)) if (EmulateInstruction::BitIsSet (registers, 1u << 15))
{ {
context.arg1 = dwarf_pc; // arg1 in the context is the DWARF register number context.arg1 = dwarf_pc; // arg1 in the context is the DWARF register number
context.arg2 = addr - sp; // arg2 in the context is the stack pointer offset context.arg2 = addr - sp; // arg2 in the context is the stack pointer offset
const uint32_t pc = emulator->ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); const uint32_t pc = emulator->ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
if (!success) if (!success)
return false; return false;
@ -180,7 +191,8 @@ EmulateARMPushEncodingA1 (EmulateInstructionARM *emulator)
static ARMOpcode g_arm_opcodes[] = static ARMOpcode g_arm_opcodes[] =
{ {
{ 0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, "PUSH<c> <registers>", EmulateARMPushEncodingA1 } { 0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, "PUSH<c> <registers>", EmulateARMPushEncoding },
{ 0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, "PUSH<c> <registers>", EmulateARMPushEncoding }
}; };
static const size_t k_num_arm_opcodes = sizeof(g_arm_opcodes)/sizeof(ARMOpcode); static const size_t k_num_arm_opcodes = sizeof(g_arm_opcodes)/sizeof(ARMOpcode);