Add a utility class ITSession to maintain the ITState for the Thumb ISA.
git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@124906 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp b/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
index 457cbaa..af81223 100644
--- a/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
+++ b/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
@@ -14,10 +14,74 @@
#include "ARMUtils.h"
#include "ARM_DWARF_Registers.h"
#include "llvm/Support/MathExtras.h" // for SignExtend32 template function
+ // and CountTrailingZeros_32 function
using namespace lldb;
using namespace lldb_private;
+// A8.6.50
+// Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition.
+static unsigned short CountITSize(unsigned ITMask) {
+ // First count the trailing zeros of the IT mask.
+ unsigned TZ = llvm::CountTrailingZeros_32(ITMask);
+ if (TZ > 3)
+ {
+ printf("Encoding error: IT Mask '0000'\n");
+ return 0;
+ }
+ return (4 - TZ);
+}
+
+// Init ITState. Note that at least one bit is always 1 in mask.
+bool ITSession::InitIT(unsigned short bits7_0)
+{
+ ITCounter = CountITSize(Bits32(bits7_0, 3, 0));
+ if (ITCounter == 0)
+ return false;
+
+ // A8.6.50 IT
+ unsigned short FirstCond = Bits32(bits7_0, 7, 4);
+ if (FirstCond == 0xF)
+ {
+ printf("Encoding error: IT FirstCond '1111'\n");
+ return false;
+ }
+ if (FirstCond == 0xE && ITCounter != 1)
+ {
+ printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n");
+ return false;
+ }
+
+ ITState = bits7_0;
+ return true;
+}
+
+// Update ITState if necessary.
+void ITSession::ITAdvance()
+{
+ assert(ITCounter);
+ --ITCounter;
+ if (ITCounter == 0)
+ ITState = 0;
+ else
+ {
+ unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1;
+ SetBits32(ITState, 4, 0, NewITState4_0);
+ }
+}
+
+// Return true if we're inside an IT Block.
+bool ITSession::InITBlock()
+{
+ return ITCounter != 0;
+}
+
+// Get condition bits for the current thumb instruction.
+uint32_t ITSession::GetCond()
+{
+ return Bits32(ITState, 7, 4);
+}
+
// ARM constants used during decoding
#define REG_RD 0
#define LDM_REGLIST 1