diff options
| author | Johnny Chen <johnny.chen@apple.com> | 2011-02-17 22:03:29 +0000 |
|---|---|---|
| committer | Johnny Chen <johnny.chen@apple.com> | 2011-02-17 22:03:29 +0000 |
| commit | fc5c19dec5c97694a043009b65883657fcb818c0 (patch) | |
| tree | a6e830908b3193f495c232ce6260b8066af890a5 | |
| parent | 48d9626055df18ab22ce07dea8880a5317d71e11 (diff) | |
| download | bcm5719-llvm-fc5c19dec5c97694a043009b65883657fcb818c0.tar.gz bcm5719-llvm-fc5c19dec5c97694a043009b65883657fcb818c0.zip | |
A8.6.6 ADD (register)
Renamed EmulateAddRdnRm() to EmulateAddReg(), and added Encoding T1 to it.
Where Encoding T2 can potentially modify the PC, causing a brnach.
llvm-svn: 125782
| -rw-r--r-- | lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp | 38 | ||||
| -rw-r--r-- | lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h | 4 |
2 files changed, 34 insertions, 8 deletions
diff --git a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp index 36608508662..2495937a356 100644 --- a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp +++ b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp @@ -1912,11 +1912,10 @@ EmulateInstructionARM::EmulateTB (ARMEncoding encoding) return true; } -// ADD <Rdn>, <Rm> -// where <Rdn> the destination register is also the first operand register -// and <Rm> is the second operand register. +// This instruction adds a register value and an optionally-shifted register value, and writes the result +// to the destination register. It can optionally update the condition flags based on the result. bool -EmulateInstructionARM::EmulateAddRdnRm (ARMEncoding encoding) +EmulateInstructionARM::EmulateAddReg (ARMEncoding encoding) { #if 0 // ARM pseudo code... @@ -1943,15 +1942,28 @@ EmulateInstructionARM::EmulateAddRdnRm (ARMEncoding encoding) if (ConditionPassed()) { uint32_t Rd, Rn, Rm; + ARM_ShifterType shift_t; + uint32_t shift_n; // the shift applied to the value read from Rm bool setflags; switch (encoding) { + case eEncodingT1: + Rd = Bits32(opcode, 2, 0); + Rn = Bits32(opcode, 5, 3); + Rm = Bits32(opcode, 8, 6); + setflags = !InITBlock(); + shift_t = SRType_LSL; + shift_n = 0; case eEncodingT2: Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); Rm = Bits32(opcode, 6, 3); setflags = false; + shift_t = SRType_LSL; + shift_n = 0; if (Rn == 15 && Rm == 15) return false; + if (Rd == 15 && InITBlock() && !LastInITBlock()) + return false; break; default: return false; @@ -1960,7 +1972,13 @@ EmulateInstructionARM::EmulateAddRdnRm (ARMEncoding encoding) int32_t result, val1, val2; // Read the first operand. if (Rn == 15) + { val1 = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); + if (encoding == eEncodingT1 || encoding == eEncodingT2) + val1 += 4; + else + val1 += 8; + } else val1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success); if (!success) @@ -1968,13 +1986,19 @@ EmulateInstructionARM::EmulateAddRdnRm (ARMEncoding encoding) // Read the second operand. if (Rm == 15) + { val2 = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); + if (encoding == eEncodingT1 || encoding == eEncodingT2) + val1 += 4; + else + val1 += 8; + } else val2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success); if (!success) return false; - // TODO: Handle the case where Rm needs to be shifted properly. + val2 = Shift(val2, shift_t, shift_n, Bit32(m_inst_cpsr, CPSR_C)); AddWithCarryResult res = AddWithCarry(val1, val2, 0); result = val1 + val2; @@ -4371,8 +4395,10 @@ EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode) //---------------------------------------------------------------------- // Data-processing instructions //---------------------------------------------------------------------- + { 0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateAddReg, "adds|add<c> <Rd>, <Rn>, <Rm>"}, // 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>"}, + // Can update PC! + { 0xffffff00, 0x00004400, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateAddReg, "add<c> <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 diff --git a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h index bf79a26dc71..013a84560a2 100644 --- a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h +++ b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h @@ -388,9 +388,9 @@ protected: bool EmulateTB (ARMEncoding encoding); - // A8.6.6 ADD (register) -- Encoding T2 + // A8.6.6 ADD (register) bool - EmulateAddRdnRm (ARMEncoding encoding); + EmulateAddReg (ARMEncoding encoding); // A8.6.97 MOV (register) bool |

