From 123b89b67f4b49f5e125dd306f75e481be365586 Mon Sep 17 00:00:00 2001 From: Caroline Tice Date: Tue, 8 Feb 2011 23:56:10 +0000 Subject: [PATCH] Add code to emulate the LDMIB Arm instruction. Modify code for LDM and LDMDB instructions to only create one context and to reuse it, rather than creating multiple contexts. llvm-svn: 125139 --- .../Instruction/ARM/EmulateInstructionARM.cpp | 154 ++++++++++++++---- .../Instruction/ARM/EmulateInstructionARM.h | 3 + 2 files changed, 127 insertions(+), 30 deletions(-) diff --git a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp index 2f6cdc881ded..21756f34d05a 100644 --- a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp +++ b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp @@ -1607,16 +1607,18 @@ EmulateInstructionARM::EmulateLDM (ARMEncoding encoding) const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); if (!success) return false; + + EmulateInstruction::Context context = { EmulateInstruction::eContextRegisterPlusOffset, + eRegisterKindDWARF, + dwarf_r0 + n, + offset }; for (int i = 0; i < 14; ++i) { if (BitIsSet (registers, i)) { - EmulateInstruction::Context context = { EmulateInstruction::eContextRegisterPlusOffset, - eRegisterKindDWARF, - dwarf_r0 + n, - offset }; - + context.type = EmulateInstruction::eContextRegisterPlusOffset; + context.arg2 = offset; if (wback && (n == 13)) // Pop Instruction context.type = EmulateInstruction::eContextPopRegisterOffStack; @@ -1635,11 +1637,8 @@ EmulateInstructionARM::EmulateLDM (ARMEncoding encoding) if (BitIsSet (registers, 15)) { //LoadWritePC (MemA [address, 4]); - EmulateInstruction::Context context = { EmulateInstruction::eContextRegisterPlusOffset, - eRegisterKindDWARF, - dwarf_r0 + n, - offset }; - + context.type = EmulateInstruction::eContextRegisterPlusOffset; + context.arg2 = offset; uint32_t data = ReadMemoryUnsigned (context, base_address + offset, addr_byte_size, 0, &success); if (!success) return false; @@ -1650,10 +1649,8 @@ EmulateInstructionARM::EmulateLDM (ARMEncoding encoding) if (wback && BitIsClear (registers, n)) { addr_t offset = addr_byte_size * BitCount (registers); - EmulateInstruction::Context context = { EmulateInstruction::eContextRegisterPlusOffset, - eRegisterKindDWARF, - dwarf_r0 + n, - offset }; + context.type = EmulateInstruction::eContextRegisterPlusOffset; + context.arg2 = offset; // R[n] = R[n] + 4 * BitCount (registers) if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset)) @@ -1741,17 +1738,17 @@ EmulateInstructionARM::EmulateLDMDB (ARMEncoding encoding) int32_t offset = 0; addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success) - (addr_byte_size * BitCount (registers)); + EmulateInstruction::Context context = { EmulateInstruction::eContextRegisterPlusOffset, + eRegisterKindDWARF, + dwarf_r0 + n, + offset }; for (int i = 0; i < 14; ++i) { if (BitIsSet (registers, i)) { // R[i] = MemA[address,4]; address = address + 4; - EmulateInstruction::Context context = { EmulateInstruction::eContextRegisterPlusOffset, - eRegisterKindDWARF, - dwarf_r0 + n, - offset }; - + context.arg2 = offset; uint32_t data = ReadMemoryUnsigned (context, address + offset, addr_byte_size, 0, &success); if (!success) return false; @@ -1767,11 +1764,7 @@ EmulateInstructionARM::EmulateLDMDB (ARMEncoding encoding) // LoadWritePC(MemA[address,4]); if (BitIsSet (registers, 15)) { - EmulateInstruction::Context context = { EmulateInstruction::eContextRegisterPlusOffset, - eRegisterKindDWARF, - dwarf_r0 + n, - offset }; - + context.arg2 = offset; uint32_t data = ReadMemoryUnsigned (context, address + offset, addr_byte_size, 0, &success); if (!success) return false; @@ -1782,11 +1775,7 @@ EmulateInstructionARM::EmulateLDMDB (ARMEncoding encoding) // if wback && registers == ’0’ then R[n] = R[n] - 4*BitCount(registers); if (wback && BitIsClear (registers, n)) { - EmulateInstruction::Context context = { EmulateInstruction::eContextRegisterPlusOffset, - eRegisterKindDWARF, - dwarf_r0 + n, - offset }; - + context.arg2 = offset; addr_t addr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); if (!success) return false; @@ -1801,6 +1790,110 @@ EmulateInstructionARM::EmulateLDMDB (ARMEncoding encoding) } return true; } + +bool +EmulateInstructionARM::EmulateLDMIB (ARMEncoding encoding) +{ +#if 0 + if ConditionPassed() then + EncodingSpecificOperations(); + address = R[n] + 4; + + for i = 0 to 14 + if registers == ’1’ then + R[i] = MemA[address,4]; address = address + 4; + if registers<15> == ’1’ then + LoadWritePC(MemA[address,4]); + + if wback && registers == ’0’ then R[n] = R[n] + 4*BitCount(registers); + if wback && registers == ’1’ then R[n] = bits(32) UNKNOWN; +#endif + + bool success = false; + const uint32_t opcode = OpcodeAsUnsigned (&success); + if (!success) + return false; + + if (ConditionPassed()) + { + uint32_t n; + uint32_t registers = 0; + bool wback; + const uint32_t addr_byte_size = GetAddressByteSize(); + switch (encoding) + { + case eEncodingA1: + // n = UInt(Rn); registers = register_list; wback = (W == ’1’); + n = Bits32 (opcode, 19, 16); + registers = Bits32 (opcode, 15, 0); + wback = BitIsSet (opcode, 21); + + // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; + if ((n == 15) || (BitCount (registers) < 1)) + return false; + + break; + default: + return false; + } + // address = R[n] + 4; + + int32_t offset = 0; + addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success) + addr_byte_size; + + EmulateInstruction::Context context = { EmulateInstruction::eContextRegisterPlusOffset, + eRegisterKindDWARF, + dwarf_r0 + n, + offset }; + + for (int i = 0; i < 14; ++i) + { + if (BitIsSet (registers, i)) + { + // R[i] = MemA[address,4]; address = address + 4; + + context.arg2 = offset; + uint32_t data = ReadMemoryUnsigned (context, address + offset, addr_byte_size, 0, &success); + if (!success) + return false; + + if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) + return false; + + offset += addr_byte_size; + } + } + + // if registers<15> == ’1’ then + // LoadWritePC(MemA[address,4]); + if (BitIsSet (registers, 15)) + { + context.arg2 = offset; + uint32_t data = ReadMemoryUnsigned (context, address + offset, addr_byte_size, 0, &success); + if (!success) + return false; + if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, data)) + return false; + } + + // if wback && registers == ’0’ then R[n] = R[n] + 4*BitCount(registers); + if (wback && BitIsClear (registers, n)) + { + context.arg2 = offset; + addr_t addr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); + if (!success) + return false; + addr = addr + (addr_byte_size * BitCount (registers)); + if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) + return false; + } + + // if wback && registers == ’1’ then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 + if (wback && BitIsSet (registers, n)) + return false; // I'm not sure this is right; how do I set R[n] to bits(32) UNKNOWN. + } + return true; +} EmulateInstructionARM::ARMOpcode* EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode) @@ -1862,7 +1955,8 @@ EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode) // Load instructions //---------------------------------------------------------------------- { 0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm {!} " }, - { 0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb {!} " } + { 0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb {!} " }, + { 0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib " } }; static const size_t k_num_arm_opcodes = sizeof(g_arm_opcodes)/sizeof(ARMOpcode); diff --git a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h index 0e39ccf41271..5c450f3660b1 100644 --- a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h +++ b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h @@ -245,6 +245,9 @@ protected: bool EmulateLDMDB (ARMEncoding encoding); + + bool + EmulateLDMIB (ARMEncoding encoding); uint32_t m_arm_isa; Mode m_inst_mode;