diff options
author | Johnny Chen <johnny.chen@apple.com> | 2011-02-05 00:46:10 +0000 |
---|---|---|
committer | Johnny Chen <johnny.chen@apple.com> | 2011-02-05 00:46:10 +0000 |
commit | 6e2acff0be75f35e4337d8a2bffff5bec1d22b24 (patch) | |
tree | d1f0d0eb542b77259bc310f2fbf1e15f9284c0b5 | |
parent | c0d344651627d4cdb00ebf4ce343aceb366243f9 (diff) | |
download | bcm5719-llvm-6e2acff0be75f35e4337d8a2bffff5bec1d22b24.tar.gz bcm5719-llvm-6e2acff0be75f35e4337d8a2bffff5bec1d22b24.zip |
Add EmulateInstructionARM::EmulateIT() to the g_thumb_opcodes table,
to represent the the 'If Then' instruction which makes up to four following
instructions (the IT block)conditional.
Hook up ITSession utility class as a member variable of EmulateInstructionARM.
llvm-svn: 124915
-rw-r--r-- | lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp | 43 | ||||
-rw-r--r-- | lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h | 10 |
2 files changed, 49 insertions, 4 deletions
diff --git a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp index af81223a39f..faa1d39d1e1 100644 --- a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp +++ b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp @@ -76,10 +76,19 @@ bool ITSession::InITBlock() return ITCounter != 0; } +// Return true if we're the last instruction inside an IT Block. +bool ITSession::LastInITBlock() +{ + return ITCounter == 1; +} + // Get condition bits for the current thumb instruction. uint32_t ITSession::GetCond() { - return Bits32(ITState, 7, 4); + if (InITBlock()) + return Bits32(ITState, 7, 4); + else + return COND_AL; } // ARM constants used during decoding @@ -1348,6 +1357,25 @@ EmulateInstructionARM::EmulateSVC (ARMEncoding encoding) return true; } +// If Then makes up to four following instructions (the IT block) conditional. +bool +EmulateInstructionARM::EmulateIT (ARMEncoding encoding) +{ +#if 0 + // ARM pseudo code... + EncodingSpecificOperations(); + ITSTATE.IT<7:0> = firstcond:mask; +#endif + + bool success = false; + const uint32_t opcode = OpcodeAsUnsigned (&success); + if (!success) + return false; + + m_it_session.InitIT(Bits32(opcode, 7, 0)); + return true; +} + EmulateInstructionARM::ARMOpcode* EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode) { @@ -1463,7 +1491,12 @@ EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode) //---------------------------------------------------------------------- // Supervisor Call (previously Software Interrupt) //---------------------------------------------------------------------- - { 0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"} + { 0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"}, + + //---------------------------------------------------------------------- + // If Then makes up to four following instructions conditional. + //---------------------------------------------------------------------- + { 0xffffff00, 0x0000bf00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"} }; @@ -1573,7 +1606,7 @@ EmulateInstructionARM::CurrentCond () return UnsignedBits(m_inst.opcode.inst32, 31, 28); case eModeThumb: - return 0x0000000Eu; // Return always for now, we need to handl IT instructions later + return m_it_session.GetCond(); } return UINT32_MAX; // Return invalid value } @@ -1624,5 +1657,9 @@ EmulateInstructionARM::ConditionPassed () bool EmulateInstructionARM::EvaluateInstruction () { + // Advance the ITSTATE bits to their values for the next instruction. + if (m_inst_mode == eModeThumb && m_it_session.InITBlock()) + m_it_session.ITAdvance(); + return false; } diff --git a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h index dc0cf7233fd..b6ba71e28c7 100644 --- a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h +++ b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h @@ -31,6 +31,9 @@ public: // InITBlock - Returns true if we're inside an IT Block. bool InITBlock(); + // LastInITBlock - Returns true if we're the last instruction inside an IT Block. + bool LastInITBlock(); + // GetCond - Gets condition bits for the current thumb instruction. uint32_t GetCond(); @@ -121,7 +124,8 @@ public: write_reg_callback), m_arm_isa (0), m_inst_mode (eModeInvalid), - m_inst_cpsr (0) + m_inst_cpsr (0), + m_it_session () { } @@ -220,9 +224,13 @@ protected: bool EmulateSVC (ARMEncoding encoding); + bool + EmulateIT (ARMEncoding encoding); + uint32_t m_arm_isa; Mode m_inst_mode; uint32_t m_inst_cpsr; + ITSession m_it_session; }; } // namespace lldb_private |