Fix Quick compiler "out of registers"

There are a few places in the Arm backend that expect to be
able to survive on a single temp register - in particular
entry code generation and argument passing.  However, in the
case of a very large frame and floating point ld/st, the
existing code could end up using 2 temps.

In short, if there is a displacement overflow we try to use
indexed load/store instructions (slightly more efficient).
However, there are none for floating point - so we ended up
burning yet another register to construct a direct pointer.
This CL detects this case and doesn't try to use the indexed
load/store mechanism for floats.

Fix for https://code.google.com/p/android/issues/detail?id=67349

Change-Id: I1ea596ea660e4add89fd4fddb8cbf99a54fbd343
diff --git a/compiler/dex/quick/arm/utility_arm.cc b/compiler/dex/quick/arm/utility_arm.cc
index 882a3bb..1a7f2fc 100644
--- a/compiler/dex/quick/arm/utility_arm.cc
+++ b/compiler/dex/quick/arm/utility_arm.cc
@@ -923,7 +923,13 @@
     } else {
       int reg_offset = AllocTemp();
       LoadConstant(reg_offset, encoded_disp);
-      load = LoadBaseIndexed(rBase, reg_offset, r_dest, 0, size);
+      if (ARM_FPREG(r_dest)) {
+        // No index ops - must use a long sequence.  Turn the offset into a direct pointer.
+        OpRegReg(kOpAdd, reg_offset, rBase);
+        load = LoadBaseDispBody(reg_offset, 0, r_dest, r_dest_hi, size, s_reg);
+      } else {
+        load = LoadBaseIndexed(rBase, reg_offset, r_dest, 0, size);
+      }
       FreeTemp(reg_offset);
     }
   }
@@ -1037,7 +1043,13 @@
     } else {
       int r_scratch = AllocTemp();
       LoadConstant(r_scratch, encoded_disp);
-      store = StoreBaseIndexed(rBase, r_scratch, r_src, 0, size);
+      if (ARM_FPREG(r_src)) {
+        // No index ops - must use a long sequence.  Turn the offset into a direct pointer.
+        OpRegReg(kOpAdd, r_scratch, rBase);
+        store = StoreBaseDispBody(r_scratch, 0, r_src, r_src_hi, size);
+      } else {
+        store = StoreBaseIndexed(rBase, r_scratch, r_src, 0, size);
+      }
       FreeTemp(r_scratch);
     }
   }