Revert "Revert "Introduce a NearLabel in thumb2.""

This reverts commit 1f277e3cef6c33cd35e91123978491d83338d2ad.

- Fix CompareAndBranch to not use cbz/cbnz with high registers.
- Add a test for CompareAndBranch with the *inc file, as the
  other assembler test infrastructure does not handle labels.

Change-Id: If552bf1112b96caa3b9bb6c73c4b40bb90a33db7
diff --git a/compiler/utils/arm/assembler_thumb2.cc b/compiler/utils/arm/assembler_thumb2.cc
index 75f2b77..4ff3aeb 100644
--- a/compiler/utils/arm/assembler_thumb2.cc
+++ b/compiler/utils/arm/assembler_thumb2.cc
@@ -671,11 +671,17 @@
   EmitVFPddd(cond, B23 | B21 | B20 | B18 | B16 | B6, dd, D0, D0);
 }
 
+
 void Thumb2Assembler::b(Label* label, Condition cond) {
   EmitBranch(cond, label, false, false);
 }
 
 
+void Thumb2Assembler::b(NearLabel* label, Condition cond) {
+  EmitBranch(cond, label, false, false, /* is_near */ true);
+}
+
+
 void Thumb2Assembler::bl(Label* label, Condition cond) {
   CheckCondition(cond);
   EmitBranch(cond, label, true, false);
@@ -1369,6 +1375,7 @@
 
 
 uint16_t Thumb2Assembler::EmitCompareAndBranch(Register rn, uint16_t prev, bool n) {
+  CHECK(IsLowRegister(rn));
   uint32_t location = buffer_.Size();
 
   // This is always unresolved as it must be a forward branch.
@@ -1613,7 +1620,7 @@
 }
 
 
-void Thumb2Assembler::EmitBranch(Condition cond, Label* label, bool link, bool x) {
+void Thumb2Assembler::EmitBranch(Condition cond, Label* label, bool link, bool x, bool is_near) {
   uint32_t pc = buffer_.Size();
   Branch::Type branch_type;
   if (cond == AL) {
@@ -1644,8 +1651,8 @@
     }
   } else {
     // Branch is to an unbound label.  Emit space for it.
-    uint16_t branch_id = AddBranch(branch_type, pc, cond);    // Unresolved branch.
-    if (!CanRelocateBranches() || force_32bit_) {
+    uint16_t branch_id = AddBranch(branch_type, pc, cond, is_near);    // Unresolved branch.
+    if (force_32bit_ || (!CanRelocateBranches() && !is_near)) {
       Emit16(static_cast<uint16_t>(label->position_));    // Emit current label link.
       Emit16(0);                   // another 16 bits.
     } else {
@@ -2199,6 +2206,9 @@
   if (label->IsBound()) {
     LOG(FATAL) << "cbz can only be used to branch forwards";
     UNREACHABLE();
+  } else if (IsHighRegister(rn)) {
+    LOG(FATAL) << "cbz can only be used with low registers";
+    UNREACHABLE();
   } else {
     uint16_t branchid = EmitCompareAndBranch(rn, static_cast<uint16_t>(label->position_), false);
     label->LinkTo(branchid);
@@ -2211,6 +2221,9 @@
   if (label->IsBound()) {
     LOG(FATAL) << "cbnz can only be used to branch forwards";
     UNREACHABLE();
+  } else if (IsHighRegister(rn)) {
+    LOG(FATAL) << "cbnz can only be used with low registers";
+    UNREACHABLE();
   } else {
     uint16_t branchid = EmitCompareAndBranch(rn, static_cast<uint16_t>(label->position_), true);
     label->LinkTo(branchid);
@@ -2741,7 +2754,17 @@
 
 
 void Thumb2Assembler::CompareAndBranchIfZero(Register r, Label* label) {
-  if (CanRelocateBranches()) {
+  if (CanRelocateBranches() && IsLowRegister(r)) {
+    cbz(r, label);
+  } else {
+    cmp(r, ShifterOperand(0));
+    b(label, EQ);
+  }
+}
+
+
+void Thumb2Assembler::CompareAndBranchIfZero(Register r, NearLabel* label) {
+  if (IsLowRegister(r)) {
     cbz(r, label);
   } else {
     cmp(r, ShifterOperand(0));
@@ -2751,7 +2774,7 @@
 
 
 void Thumb2Assembler::CompareAndBranchIfNonZero(Register r, Label* label) {
-  if (CanRelocateBranches()) {
+  if (CanRelocateBranches() && IsLowRegister(r)) {
     cbnz(r, label);
   } else {
     cmp(r, ShifterOperand(0));