Fancy disassembly of Thumb2 IT blocks.

Example:

            0x60ce6ea4: 4291        cmp     r1, r2
            0x60ce6ea6: bf0e        itee    eq
            0x60ce6ea8: 2001        movseq  r0, #1
            0x60ce6eaa: 1c10        movne   r0, r2
            0x60ce6eac: 47f0        blxne   lr
            0x60ce6eae: 1c06        mov     r6, r0

Change-Id: I85deae2e471b8bfc513281be421e0bd46c1b60a0
diff --git a/src/disassembler_arm.cc b/src/disassembler_arm.cc
index 57fcec3..2492f50 100644
--- a/src/disassembler_arm.cc
+++ b/src/disassembler_arm.cc
@@ -899,9 +899,29 @@
               default: break;
             }
           } else {
+            uint32_t first_cond = opA;
+            uint32_t mask = opB;
             opcode << "it";
-            args << reinterpret_cast<void*>(opB) << " ";
-            DumpCond(args, opA);
+
+            // Flesh out the base "it" opcode with the specific collection of 't's and 'e's,
+            // and store up the actual condition codes we'll want to add to the next few opcodes.
+            size_t count = 3 - CTZ(mask);
+            it_conditions_.resize(count + 2); // Plus the implicit 't', plus the "" for the IT itself.
+            for (size_t i = 0; i < count; ++i) {
+              bool positive_cond = ((first_cond & 1) != 0);
+              bool positive_mask = ((mask & (1 << (3 - i))) != 0);
+              if (positive_mask == positive_cond) {
+                opcode << 't';
+                it_conditions_[i] = kConditionCodeNames[first_cond];
+              } else {
+                opcode << 'e';
+                it_conditions_[i] = kConditionCodeNames[first_cond ^ 1];
+              }
+            }
+            it_conditions_[count] = kConditionCodeNames[first_cond]; // The implicit 't'.
+
+            it_conditions_[count + 1] = ""; // No condition code for the IT itself...
+            DumpCond(args, first_cond); // ...because it's considered an argument.
           }
           break;
         }
@@ -943,6 +963,13 @@
       opcode << "b";
       DumpBranchTarget(args, instr_ptr + 4, imm32);
     }
+
+    // Apply any IT-block conditions to the opcode if necessary.
+    if (!it_conditions_.empty()) {
+      opcode << it_conditions_.back();
+      it_conditions_.pop_back();
+    }
+
     os << StringPrintf("\t\t\t%p: %04x    \t%-7s ", instr_ptr, instr, opcode.str().c_str()) << args.str() << '\n';
   }
   return 2;