Use the thumb2 assembler for the optimizing compiler.

Change-Id: I2b058f4433504dc3299c06f5cb0b5ab12f34aa82
diff --git a/compiler/utils/arm/assembler_arm.cc b/compiler/utils/arm/assembler_arm.cc
index 8a34928..5fe8246 100644
--- a/compiler/utils/arm/assembler_arm.cc
+++ b/compiler/utils/arm/assembler_arm.cc
@@ -169,9 +169,7 @@
       return ArmAssembler::ModifiedImmediate(immediate) != kInvalidModifiedImmediate;
 
     case MOV:
-      if (immediate < (1 << 12)) {    // Less than (or equal to) 12 bits can always be done.
-        return true;
-      }
+      // TODO: Support less than or equal to 12bits.
       return ArmAssembler::ModifiedImmediate(immediate) != kInvalidModifiedImmediate;
     case MVN:
     default:
diff --git a/compiler/utils/arm/assembler_thumb2.cc b/compiler/utils/arm/assembler_thumb2.cc
index 604f59e..2ce4fd2 100644
--- a/compiler/utils/arm/assembler_thumb2.cc
+++ b/compiler/utils/arm/assembler_thumb2.cc
@@ -877,6 +877,7 @@
            rn_shift = 8;
         } else {
           thumb_opcode = 0b1010;
+          rd = rn;
           rn = so.GetRegister();
         }
 
@@ -1470,6 +1471,7 @@
     // branch the size may change if it so happens that other branches change size that change
     // the distance to the target and that distance puts this branch over the limit for 16 bits.
     if (size == Branch::k16Bit) {
+      DCHECK(!force_32bit_branches_);
       Emit16(0);          // Space for a 16 bit branch.
     } else {
       Emit32(0);            // Space for a 32 bit branch.
@@ -1477,7 +1479,7 @@
   } else {
     // Branch is to an unbound label.  Emit space for it.
     uint16_t branch_id = AddBranch(branch_type, pc, cond);    // Unresolved branch.
-    if (force_32bit_) {
+    if (force_32bit_branches_ || force_32bit_) {
       Emit16(static_cast<uint16_t>(label->position_));    // Emit current label link.
       Emit16(0);                   // another 16 bits.
     } else {
@@ -2073,6 +2075,7 @@
     uint32_t branch_location = branch->GetLocation();
     uint16_t next = buffer_.Load<uint16_t>(branch_location);       // Get next in chain.
     if (changed) {
+      DCHECK(!force_32bit_branches_);
       MakeHoleForBranch(branch->GetLocation(), 2);
       if (branch->IsCompareAndBranch()) {
         // A cbz/cbnz instruction has changed size.  There is no valid encoding for
diff --git a/compiler/utils/arm/assembler_thumb2.h b/compiler/utils/arm/assembler_thumb2.h
index 5f24e4e..f1ae3d8 100644
--- a/compiler/utils/arm/assembler_thumb2.h
+++ b/compiler/utils/arm/assembler_thumb2.h
@@ -29,10 +29,13 @@
 namespace art {
 namespace arm {
 
-
 class Thumb2Assembler FINAL : public ArmAssembler {
  public:
-  Thumb2Assembler() : force_32bit_(false), it_cond_index_(kNoItCondition), next_condition_(AL) {
+  Thumb2Assembler(bool force_32bit_branches = false)
+      : force_32bit_branches_(force_32bit_branches),
+        force_32bit_(false),
+        it_cond_index_(kNoItCondition),
+        next_condition_(AL) {
   }
 
   virtual ~Thumb2Assembler() {
@@ -49,6 +52,10 @@
     return force_32bit_;
   }
 
+  bool IsForced32BitBranches() const {
+    return force_32bit_branches_;
+  }
+
   void FinalizeInstructions(const MemoryRegion& region) OVERRIDE {
     EmitBranches();
     Assembler::FinalizeInstructions(region);
@@ -412,7 +419,8 @@
   void EmitShift(Register rd, Register rm, Shift shift, uint8_t amount, bool setcc = false);
   void EmitShift(Register rd, Register rn, Shift shift, Register rm, bool setcc = false);
 
-  bool force_32bit_;      // Force the assembler to use 32 bit thumb2 instructions.
+  bool force_32bit_branches_; // Force the assembler to use 32 bit branch instructions.
+  bool force_32bit_;          // Force the assembler to use 32 bit thumb2 instructions.
 
   // IfThen conditions.  Used to check that conditional instructions match the preceding IT.
   Condition it_conditions_[4];
@@ -605,6 +613,9 @@
    private:
     // Calculate the size of the branch instruction based on its type and offset.
     Size CalculateSize() const {
+      if (assembler_->IsForced32BitBranches()) {
+        return k32Bit;
+      }
       if (target_ == kUnresolved) {
         if (assembler_->IsForced32Bit() && (type_ == kUnconditional || type_ == kConditional)) {
           return k32Bit;