Extra Thumb2 disassembly, including strb.

Change-Id: Ic36a5836e2c79ff412466b1dada1622df4b7fd8a
diff --git a/src/disassembler_arm.cc b/src/disassembler_arm.cc
index 79123e5..7cde7b0 100644
--- a/src/disassembler_arm.cc
+++ b/src/disassembler_arm.cc
@@ -336,6 +336,81 @@
           }
           break;
         }
+        case 0x20: case 0x21: case 0x22: case 0x23:  // 01xxxxx
+        case 0x24: case 0x25: case 0x26: case 0x27:
+        case 0x28: case 0x29: case 0x2A: case 0x2B:
+        case 0x2C: case 0x2D: case 0x2E: case 0x2F:
+        case 0x30: case 0x31: case 0x32: case 0x33:
+        case 0x34: case 0x35: case 0x36: case 0x37:
+        case 0x38: case 0x39: case 0x3A: case 0x3B:
+        case 0x3C: case 0x3D: case 0x3E: case 0x3F: {
+          // Data-processing (shifted register)
+          // |111|1110|0000|0|0000|1111|1100|0000|0000|
+          // |5 3|2109|8765|4|3  0|5   |10 8|7 5 |3  0|
+          // |---|----|----|-|----|----|----|----|----|
+          // |332|2222|2222|2|1111|1111|1100|0000|0000|
+          // |1 9|8765|4321|0|9  6|5   |10 8|7 5 |3  0|
+          // |---|----|----|-|----|----|----|----|----|
+          // |111|0101| op3|S| Rn |    | Rd |    | Rm |
+          uint32_t op3 = (instr >> 21) & 0xF;
+          uint32_t S = (instr >> 20) & 1;
+          uint32_t Rn = (instr >> 16) & 0xF;
+          uint32_t Rd = (instr >> 8) & 0xF;
+          uint32_t Rm = instr & 0xF;
+          switch (op3) {
+            case 0x0:
+              if (Rn != 0xF) {
+                opcode << "and";
+              } else {
+                opcode << "tst";
+                S = 0;  // don't print 's'
+              }
+              break;
+            case 0x1: opcode << "bic"; break;
+            case 0x2:
+              if (Rn != 0xF) {
+                opcode << "orr";
+              } else {
+                opcode << "mov";
+              }
+              break;
+            case 0x3:
+              if (Rn != 0xF) {
+                opcode << "orn";
+              } else {
+                opcode << "mvn";
+              }
+              break;
+            case 0x4:
+              if (Rn != 0xF) {
+                opcode << "eor";
+              } else {
+                opcode << "teq";
+                S = 0;  // don't print 's'
+              }
+              break;
+            case 0x6: opcode << "pkh"; break;
+            case 0x8:
+              if (Rn != 0xF) {
+                opcode << "add";
+              } else {
+                opcode << "cmn";
+                S = 0;  // don't print 's'
+              }
+              break;
+            case 0xA: opcode << "adc"; break;
+            case 0xB: opcode << "sbc"; break;
+          }
+
+          if (S == 1) {
+            opcode << "s";
+          }
+          opcode << ".w";
+          DumpReg(args, Rd);
+          args << ", ";
+          DumpReg(args, Rm);
+          break;
+        }
         default:
           break;
       }
@@ -503,10 +578,36 @@
           // |1 9|87|654|321|0|9  6|5  2|10   6|5    0|
           // |---|--|---|---|-|----|----|------|------|
           // |111|11|000|op3|0|    |    |  op4 |      |
-
           uint32_t op3 = (instr >> 21) & 7;
           //uint32_t op4 = (instr >> 6) & 0x3F;
           switch (op3) {
+            case 0x0: case 0x4: {
+              // STRB Rt,[Rn,#+/-imm8]     - 111 11 00 0 0 00 0 nnnn tttt 1 PUWii ii iiii
+              // STRB Rt,[Rn,Rm,lsl #imm2] - 111 11 00 0 0 00 0 nnnn tttt 0 00000 ii mmmm
+              uint32_t Rn = (instr >> 16) & 0xF;
+              uint32_t Rt = (instr >> 12) & 0xF;
+              opcode << "strb";
+              if ((instr & 0x800) != 0) {
+                uint32_t imm8 = instr & 0xFF;
+                DumpReg(args, Rt);
+                args << ", [";
+                DumpReg(args, Rn);
+                args << ",#" << imm8 << "]";
+              } else {
+                uint32_t imm2 = (instr >> 4) & 3;
+                uint32_t Rm = instr & 0xF;
+                DumpReg(args, Rt);
+                args << ", [";
+                DumpReg(args, Rn);
+                args << ", ";
+                DumpReg(args, Rm);
+                if (imm2 != 0) {
+                  args << ", " << "lsl #" << imm2;
+                }
+                args << "]";
+              }
+              break;
+            }
             case 0x2: case 0x6: {
               // STR.W Rt, [Rn, #imm12] - 111 11 000 110 0 nnnn tttt iiiiiiiiiiii
               // STR Rt, [Rn, #imm8]    - 111 11 000 010 0 nnnn tttt 1PUWiiiiiiii
@@ -778,6 +879,20 @@
           args << "sp, sp, #" << (imm7 << 2);
           break;
         }
+        case 0x08: case 0x09: case 0x0A: case 0x0B:  // 0001xxx
+        case 0x0C: case 0x0D: case 0x0E: case 0x0F: {
+          // CBNZ, CBZ
+          uint16_t op = (instr >> 11) & 1;
+          uint16_t i = (instr >> 9) & 1;
+          uint16_t imm5 = (instr >> 3) & 0x1F;
+          uint16_t Rn = instr & 7;
+          opcode << (op != 0 ? "cbnz" : "cbz");
+          uint32_t imm32 = (i << 7) | (imm5 << 1);
+          DumpReg(args, Rn);
+          args << ", ";
+          DumpBranchTarget(args, instr_ptr + 4, imm32);
+          break;
+        }
         case 0x78: case 0x79: case 0x7A: case 0x7B:  // 1111xxx
         case 0x7C: case 0x7D: case 0x7E: case 0x7F: {
           // If-Then, and hints