Revert "Use LIRSlowPath for throwing ArrayOutOfBoundsException."

This reverts commit 9d46314a309aff327f9913789b5f61200c162609.
diff --git a/compiler/dex/quick/gen_common.cc b/compiler/dex/quick/gen_common.cc
index bb19516..1847921 100644
--- a/compiler/dex/quick/gen_common.cc
+++ b/compiler/dex/quick/gen_common.cc
@@ -91,62 +91,6 @@
   AddSlowPath(new (arena_) DivZeroCheckSlowPath(this, branch));
 }
 
-void Mir2Lir::GenArrayBoundsCheck(RegStorage index, RegStorage length) {
-  class ArrayBoundsCheckSlowPath : public Mir2Lir::LIRSlowPath {
-   public:
-    ArrayBoundsCheckSlowPath(Mir2Lir* m2l, LIR* branch, RegStorage index, RegStorage length)
-        : LIRSlowPath(m2l, m2l->GetCurrentDexPc(), branch),
-          index_(index), length_(length) {
-    }
-
-    void Compile() OVERRIDE {
-      m2l_->ResetRegPool();
-      m2l_->ResetDefTracking();
-      GenerateTargetLabel();
-      m2l_->CallRuntimeHelperRegReg(QUICK_ENTRYPOINT_OFFSET(4, pThrowArrayBounds),
-                                    index_, length_, true);
-    }
-
-   private:
-    RegStorage index_;
-    RegStorage length_;
-  };
-
-  LIR* branch = OpCmpBranch(kCondUge, index, length, nullptr);
-  AddSlowPath(new (arena_) ArrayBoundsCheckSlowPath(this, branch, index, length));
-}
-
-void Mir2Lir::GenArrayBoundsCheck(int index, RegStorage length) {
-  class ArrayBoundsCheckSlowPath : public Mir2Lir::LIRSlowPath {
-   public:
-    ArrayBoundsCheckSlowPath(Mir2Lir* m2l, LIR* branch, int index, RegStorage length)
-        : LIRSlowPath(m2l, m2l->GetCurrentDexPc(), branch),
-          index_(index), length_(length) {
-    }
-
-    void Compile() OVERRIDE {
-      m2l_->ResetRegPool();
-      m2l_->ResetDefTracking();
-      GenerateTargetLabel();
-      // kArg0 will be used to hold the constant index.
-      if (length_.GetReg() == m2l_->TargetReg(kArg0).GetReg()) {
-        m2l_->OpRegCopy(m2l_->TargetReg(kArg1), length_);
-        length_ = m2l_->TargetReg(kArg1);
-      }
-      m2l_->LoadConstant(m2l_->TargetReg(kArg0), index_);
-      m2l_->CallRuntimeHelperRegReg(QUICK_ENTRYPOINT_OFFSET(4, pThrowArrayBounds),
-                                    m2l_->TargetReg(kArg0), length_, true);
-    }
-
-   private:
-    int index_;
-    RegStorage length_;
-  };
-
-  LIR* branch = OpCmpImmBranch(kCondLs, length, index, nullptr);
-  AddSlowPath(new (arena_) ArrayBoundsCheckSlowPath(this, branch, index, length));
-}
-
 LIR* Mir2Lir::GenNullCheck(RegStorage reg) {
   class NullCheckSlowPath : public Mir2Lir::LIRSlowPath {
    public:
@@ -741,7 +685,58 @@
     AppendLIR(lab);
     ThreadOffset<4> func_offset(-1);
     int v1 = lab->operands[2];
+    int v2 = lab->operands[3];
+    const bool target_x86 = cu_->instruction_set == kX86 || cu_->instruction_set == kX86_64;
     switch (lab->operands[0]) {
+      case kThrowConstantArrayBounds:  // v1 is length reg (for Arm/Mips), v2 constant index
+        // v1 holds the constant array index.  Mips/Arm uses v2 for length, x86 reloads.
+        if (target_x86) {
+          OpRegMem(kOpMov, TargetReg(kArg1), RegStorage::Solo32(v1),
+                   mirror::Array::LengthOffset().Int32Value());
+        } else {
+          OpRegCopy(TargetReg(kArg1), RegStorage::Solo32(v1));
+        }
+        // Make sure the following LoadConstant doesn't mess with kArg1.
+        LockTemp(TargetReg(kArg1));
+        LoadConstant(TargetReg(kArg0), v2);
+        func_offset = QUICK_ENTRYPOINT_OFFSET(4, pThrowArrayBounds);
+        break;
+      case kThrowArrayBounds:
+        // Move v1 (array index) to kArg0 and v2 (array length) to kArg1
+        if (v2 != TargetReg(kArg0).GetReg()) {
+          OpRegCopy(TargetReg(kArg0), RegStorage::Solo32(v1));
+          if (target_x86) {
+            // x86 leaves the array pointer in v2, so load the array length that the handler expects
+            OpRegMem(kOpMov, TargetReg(kArg1), RegStorage::Solo32(v2),
+                     mirror::Array::LengthOffset().Int32Value());
+          } else {
+            OpRegCopy(TargetReg(kArg1), RegStorage::Solo32(v2));
+          }
+        } else {
+          if (v1 == TargetReg(kArg1).GetReg()) {
+            // Swap v1 and v2, using kArg2 as a temp
+            OpRegCopy(TargetReg(kArg2), RegStorage::Solo32(v1));
+            if (target_x86) {
+              // x86 leaves the array pointer in v2; load the array length that the handler expects
+              OpRegMem(kOpMov, TargetReg(kArg1), RegStorage::Solo32(v2),
+                       mirror::Array::LengthOffset().Int32Value());
+            } else {
+              OpRegCopy(TargetReg(kArg1), RegStorage::Solo32(v2));
+            }
+            OpRegCopy(TargetReg(kArg0), TargetReg(kArg2));
+          } else {
+            if (target_x86) {
+              // x86 leaves the array pointer in v2; load the array length that the handler expects
+              OpRegMem(kOpMov, TargetReg(kArg1), RegStorage::Solo32(v2),
+                       mirror::Array::LengthOffset().Int32Value());
+            } else {
+              OpRegCopy(TargetReg(kArg1), RegStorage::Solo32(v2));
+            }
+            OpRegCopy(TargetReg(kArg0), RegStorage::Solo32(v1));
+          }
+        }
+        func_offset = QUICK_ENTRYPOINT_OFFSET(4, pThrowArrayBounds);
+        break;
       case kThrowNoSuchMethod:
         OpRegCopy(TargetReg(kArg0), RegStorage::Solo32(v1));
         func_offset =