Fix quick mode bugs for Mips.

This patch enable quick mode for Mips and allows the emulator to boot.
However the emulator is still not 100% functional. It still have problems
launching some apps.

Change-Id: Id46a39a649a2fd431a9f13b06ecf34cbd1d20930
Signed-off-by: Douglas Leung <douglas@mips.com>
diff --git a/compiler/dex/quick/mips/utility_mips.cc b/compiler/dex/quick/mips/utility_mips.cc
index b49f436..d28abbf 100644
--- a/compiler/dex/quick/mips/utility_mips.cc
+++ b/compiler/dex/quick/mips/utility_mips.cc
@@ -342,6 +342,10 @@
 
 LIR* MipsMir2Lir::LoadConstantWide(RegStorage r_dest, int64_t value) {
   LIR *res;
+  if (!r_dest.IsPair()) {
+    // Form 64-bit pair
+    r_dest = Solo64ToPair64(r_dest);
+  }
   res = LoadConstantNoClobber(r_dest.GetLow(), Low32Bits(value));
   LoadConstantNoClobber(r_dest.GetHigh(), High32Bits(value));
   return res;
@@ -448,7 +452,7 @@
 
 // FIXME: don't split r_dest into 2 containers.
 LIR* MipsMir2Lir::LoadBaseDispBody(RegStorage r_base, int displacement, RegStorage r_dest,
-                                   RegStorage r_dest_hi, OpSize size) {
+                                   OpSize size) {
 /*
  * Load value from base + displacement.  Optionally perform null check
  * on base (which must have an associated s_reg and MIR).  If not
@@ -462,23 +466,21 @@
   LIR *load2 = NULL;
   MipsOpCode opcode = kMipsNop;
   bool short_form = IS_SIMM16(displacement);
-  bool pair = false;
+  bool pair = r_dest.IsPair();
 
   switch (size) {
     case k64:
     case kDouble:
-      pair = true;
-      opcode = kMipsLw;
+      if (!pair) {
+        // Form 64-bit pair
+        r_dest = Solo64ToPair64(r_dest);
+        pair = 1;
+      }
       if (r_dest.IsFloat()) {
+        DCHECK_EQ(r_dest.GetLowReg(), r_dest.GetHighReg() - 1);
         opcode = kMipsFlwc1;
-        if (r_dest.IsDouble()) {
-          int reg_num = (r_dest.GetRegNum() << 1) | RegStorage::kFloatingPoint;
-          r_dest = RegStorage(RegStorage::k64BitSolo, reg_num, reg_num + 1);
-        } else {
-          DCHECK(r_dest_hi.IsFloat());
-          DCHECK_EQ(r_dest.GetReg(), r_dest_hi.GetReg() - 1);
-          r_dest_hi.SetReg(r_dest.GetReg() + 1);
-        }
+      } else {
+        opcode = kMipsLw;
       }
       short_form = IS_SIMM16_2WORD(displacement);
       DCHECK_EQ((displacement & 0x3), 0);
@@ -515,15 +517,15 @@
     if (!pair) {
       load = res = NewLIR3(opcode, r_dest.GetReg(), displacement, r_base.GetReg());
     } else {
-      load = res = NewLIR3(opcode, r_dest.GetReg(), displacement + LOWORD_OFFSET, r_base.GetReg());
-      load2 = NewLIR3(opcode, r_dest_hi.GetReg(), displacement + HIWORD_OFFSET, r_base.GetReg());
+      load = res = NewLIR3(opcode, r_dest.GetLowReg(), displacement + LOWORD_OFFSET, r_base.GetReg());
+      load2 = NewLIR3(opcode, r_dest.GetHighReg(), displacement + HIWORD_OFFSET, r_base.GetReg());
     }
   } else {
     if (pair) {
       RegStorage r_tmp = AllocTemp();
       res = OpRegRegImm(kOpAdd, r_tmp, r_base, displacement);
-      load = NewLIR3(opcode, r_dest.GetReg(), LOWORD_OFFSET, r_tmp.GetReg());
-      load2 = NewLIR3(opcode, r_dest_hi.GetReg(), HIWORD_OFFSET, r_tmp.GetReg());
+      load = NewLIR3(opcode, r_dest.GetLowReg(), LOWORD_OFFSET, r_tmp.GetReg());
+      load2 = NewLIR3(opcode, r_dest.GetHighReg(), HIWORD_OFFSET, r_tmp.GetReg());
       FreeTemp(r_tmp);
     } else {
       RegStorage r_tmp = (r_base == r_dest) ? AllocTemp() : r_dest;
@@ -557,11 +559,7 @@
     size = k32;
   }
   LIR* load;
-  if (size == k64 || size == kDouble) {
-    load = LoadBaseDispBody(r_base, displacement, r_dest.GetLow(), r_dest.GetHigh(), size);
-  } else {
-    load = LoadBaseDispBody(r_base, displacement, r_dest, RegStorage::InvalidReg(), size);
-  }
+  load = LoadBaseDispBody(r_base, displacement, r_dest, size);
 
   if (UNLIKELY(is_volatile == kVolatile)) {
     // Without context sensitive analysis, we must issue the most conservative barriers.
@@ -575,7 +573,7 @@
 
 // FIXME: don't split r_dest into 2 containers.
 LIR* MipsMir2Lir::StoreBaseDispBody(RegStorage r_base, int displacement,
-                                    RegStorage r_src, RegStorage r_src_hi, OpSize size) {
+                                    RegStorage r_src, OpSize size) {
   LIR *res;
   LIR *store = NULL;
   LIR *store2 = NULL;
@@ -586,17 +584,16 @@
   switch (size) {
     case k64:
     case kDouble:
-      opcode = kMipsSw;
+      if (!pair) {
+        // Form 64-bit pair
+        r_src = Solo64ToPair64(r_src);
+        pair = 1;
+      }
       if (r_src.IsFloat()) {
+        DCHECK_EQ(r_src.GetLowReg(), r_src.GetHighReg() - 1);
         opcode = kMipsFswc1;
-        if (r_src.IsDouble()) {
-          int reg_num = (r_src.GetRegNum() << 1) | RegStorage::kFloatingPoint;
-          r_src = RegStorage(RegStorage::k64BitPair, reg_num, reg_num + 1);
-        } else {
-          DCHECK(r_src_hi.IsFloat());
-          DCHECK_EQ(r_src.GetReg(), (r_src_hi.GetReg() - 1));
-          r_src_hi.SetReg(r_src.GetReg() + 1);
-        }
+      } else {
+        opcode = kMipsSw;
       }
       short_form = IS_SIMM16_2WORD(displacement);
       DCHECK_EQ((displacement & 0x3), 0);
@@ -628,8 +625,8 @@
     if (!pair) {
       store = res = NewLIR3(opcode, r_src.GetReg(), displacement, r_base.GetReg());
     } else {
-      store = res = NewLIR3(opcode, r_src.GetReg(), displacement + LOWORD_OFFSET, r_base.GetReg());
-      store2 = NewLIR3(opcode, r_src_hi.GetReg(), displacement + HIWORD_OFFSET, r_base.GetReg());
+      store = res = NewLIR3(opcode, r_src.GetLowReg(), displacement + LOWORD_OFFSET, r_base.GetReg());
+      store2 = NewLIR3(opcode, r_src.GetHighReg(), displacement + HIWORD_OFFSET, r_base.GetReg());
     }
   } else {
     RegStorage r_scratch = AllocTemp();
@@ -637,8 +634,8 @@
     if (!pair) {
       store =  NewLIR3(opcode, r_src.GetReg(), 0, r_scratch.GetReg());
     } else {
-      store =  NewLIR3(opcode, r_src.GetReg(), LOWORD_OFFSET, r_scratch.GetReg());
-      store2 = NewLIR3(opcode, r_src_hi.GetReg(), HIWORD_OFFSET, r_scratch.GetReg());
+      store =  NewLIR3(opcode, r_src.GetLowReg(), LOWORD_OFFSET, r_scratch.GetReg());
+      store2 = NewLIR3(opcode, r_src.GetHighReg(), HIWORD_OFFSET, r_scratch.GetReg());
     }
     FreeTemp(r_scratch);
   }
@@ -669,11 +666,7 @@
     size = k32;
   }
   LIR* store;
-  if (size == k64 || size == kDouble) {
-    store = StoreBaseDispBody(r_base, displacement, r_src.GetLow(), r_src.GetHigh(), size);
-  } else {
-    store = StoreBaseDispBody(r_base, displacement, r_src, RegStorage::InvalidReg(), size);
-  }
+  store = StoreBaseDispBody(r_base, displacement, r_src, size);
 
   if (UNLIKELY(is_volatile == kVolatile)) {
     // A load might follow the volatile store so insert a StoreLoad barrier.