Thumb2 parsing and encoding of B instruction.

Tweak handling of IT blocks a bit to enable this. The differentiation between
B and Bcc needs special sauce.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@139049 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index 3a0c260..0c4bbac 100644
--- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -64,6 +64,14 @@
                               // ~0U if no active IT block.
   } ITState;
   bool inITBlock() { return ITState.CurPosition != ~0U;}
+  void forwardITPosition() {
+    if (!inITBlock()) return;
+    // Move to the next instruction in the IT block, if there is one. If not,
+    // mark the block as done.
+    unsigned TZ = CountTrailingZeros_32(ITState.Mask);
+    if (++ITState.CurPosition == 5 - TZ)
+      ITState.CurPosition = ~0U; // Done with the IT block after this.
+  }
 
 
   MCAsmParser &getParser() const { return Parser; }
@@ -3351,12 +3359,7 @@
     if (ITState.FirstCond)
       ITState.FirstCond = false;
     else
-      bit = (ITState.Mask >> (4 - ITState.CurPosition)) & 1;
-    // Increment our position in the IT block first thing, as we want to
-    // move forward even if we find an error in the IT block.
-    unsigned TZ = CountTrailingZeros_32(ITState.Mask);
-    if (++ITState.CurPosition == 4 - TZ)
-      ITState.CurPosition = ~0U; // Done with the IT block after this.
+      bit = (ITState.Mask >> (5 - ITState.CurPosition)) & 1;
     // The instruction must be predicable.
     if (!MCID.isPredicable())
       return Error(Loc, "instructions in IT block must be predicable");
@@ -3519,8 +3522,8 @@
       Inst.setOpcode(ARM::tADDi3);
     break;
   case ARM::t2Bcc:
-    // If the conditional is AL, we really want t2B.
-    if (Inst.getOperand(1).getImm() == ARMCC::AL)
+    // If the conditional is AL or we're in an IT block, we really want t2B.
+    if (Inst.getOperand(1).getImm() == ARMCC::AL || inITBlock())
       Inst.setOpcode(ARM::t2B);
     break;
   case ARM::tBcc:
@@ -3614,13 +3617,22 @@
   case Match_Success:
     // Context sensitive operand constraints aren't handled by the matcher,
     // so check them here.
-    if (validateInstruction(Inst, Operands))
+    if (validateInstruction(Inst, Operands)) {
+      // Still progress the IT block, otherwise one wrong condition causes
+      // nasty cascading errors.
+      forwardITPosition();
       return true;
+    }
 
     // Some instructions need post-processing to, for example, tweak which
     // encoding is selected.
     processInstruction(Inst, Operands);
 
+    // Only move forward at the very end so that everything in validate
+    // and process gets a consistent answer about whether we're in an IT
+    // block.
+    forwardITPosition();
+
     Out.EmitInstruction(Inst);
     return false;
   case Match_MissingFeature:
diff --git a/test/MC/ARM/basic-thumb2-instructions.s b/test/MC/ARM/basic-thumb2-instructions.s
index 0a22726..350fc4e 100644
--- a/test/MC/ARM/basic-thumb2-instructions.s
+++ b/test/MC/ARM/basic-thumb2-instructions.s
@@ -177,8 +177,19 @@
 @------------------------------------------------------------------------------
 @ B
 @------------------------------------------------------------------------------
+        b.w   _bar
+        beq.w   _bar
+        it eq
+        beq.w _bar
         bmi.w   #-183396
 
+@ CHECK: b.w	_bar                    @ encoding: [A,0xf0'A',A,0x90'A']
+          @   fixup A - offset: 0, value: _bar, kind: fixup_t2_uncondbranch
+@ CHECK: beq.w	_bar                    @ encoding: [A,0xf0'A',A,0x80'A']
+          @   fixup A - offset: 0, value: _bar, kind: fixup_t2_condbranch
+@ CHECK: it	eq                      @ encoding: [0x08,0xbf]
+@ CHECK: b.w	_bar                    @ encoding: [A,0xf0'A',A,0x90'A']
+          @   fixup A - offset: 0, value: _bar, kind: fixup_t2_uncondbranch
 @ CHECK: bmi.w   #-183396                @ encoding: [0x13,0xf5,0xce,0xa9]
 
 @------------------------------------------------------------------------------