Rework Quick compiler's register handling

For historical reasons, the Quick backend found it convenient
to consider all 64-bit Dalvik values held in registers
to be contained in a pair of 32-bit registers.  Though this
worked well for ARM (with double-precision registers also
treated as a pair of 32-bit single-precision registers) it doesn't
play well with other targets.  And, it is somewhat problematic
for 64-bit architectures.

This is the first of several CLs that will rework the way the
Quick backend deals with physical registers.  The goal is to
eliminate the "64-bit value backed with 32-bit register pair"
requirement from the target-indendent portions of the backend
and support 64-bit registers throughout.

The key RegLocation struct, which describes the location of
Dalvik virtual register & register pairs, previously contained
fields for high and low physical registers.  The low_reg and
high_reg fields are being replaced with a new type: RegStorage.
There will be a single instance of RegStorage for each RegLocation.
Note that RegStorage does not increase the space used.  It is
16 bits wide, the same as the sum of the 8-bit low_reg and
high_reg fields.

At a target-independent level, it will describe whether the physical
register storage associated with the Dalvik value is a single 32
bit, single 64 bit, pair of 32 bit or vector.  The actual register
number encoding is left to the target-dependent code layer.

Because physical register handling is pervasive throughout the
backend, this restructuring necessarily involves large CLs with
lots of changes.  I'm going to roll these out in stages, and
attempt to segregate the CLs with largely mechanical changes from
those which restructure or rework the logic.

This CL is of the mechanical change variety - it replaces low_reg
and high_reg from RegLocation and introduces RegStorage.  It also
includes a lot of new code (such as many calls to GetReg())
that should go away in upcoming CLs.

The tentative plan for the subsequent CLs is:

   o Rework standard register utilities such as AllocReg() and
     FreeReg() to use RegStorage instead of ints.
   o Rework the target-independent GenXXX, OpXXX, LoadValue,
     StoreValue, etc. routines to take RegStorage rather than
     int register encodings.
   o Take advantage of the vector representation and eliminate
     the current vector field in RegLocation.
   o Replace the "wide" variants of codegen utilities that take
     low_reg/high_reg pairs with versions that use RegStorage.
   o Add 64-bit register target independent codegen utilities
     where possible, and where not virtualize with 32-bit general
     register and 64-bit general register variants in the target
     dependent layer.
   o Expand/rework the LIR def/use flags to allow for more registers
     (currently, we lose out on 16 MIPS floating point regs as
     well as ARM's D16..D31 for lack of space in the masks).
   o [Possibly] move the float/non-float determination of a register
     from the target-dependent encoding to RegStorage.  In other
     words, replace IsFpReg(register_encoding_bits).

At the end of the day, all code in the target independent layer
should be using RegStorage, as should much of the target dependent
layer.  Ideally, we won't be using the physical register number
encoding extracted from RegStorage (i.e. GetReg()) until the
NewLIRx() layer.

Change-Id: Idc5c741478f720bdd1d7123b94e4288be5ce52cb
diff --git a/compiler/dex/quick/mips/call_mips.cc b/compiler/dex/quick/mips/call_mips.cc
index a663519..88f46fd 100644
--- a/compiler/dex/quick/mips/call_mips.cc
+++ b/compiler/dex/quick/mips/call_mips.cc
@@ -114,7 +114,7 @@
   LIR* exit_branch = OpCmpBranch(kCondEq, rBase, rEnd, NULL);
   LoadWordDisp(rBase, 0, r_key);
   OpRegImm(kOpAdd, rBase, 8);
-  OpCmpBranch(kCondNe, rl_src.low_reg, r_key, loop_label);
+  OpCmpBranch(kCondNe, rl_src.reg.GetReg(), r_key, loop_label);
   int r_disp = AllocTemp();
   LoadWordDisp(rBase, -4, r_disp);
   OpRegRegReg(kOpAdd, r_RA, r_RA, r_disp);
@@ -162,7 +162,7 @@
   bool large_bias = false;
   int r_key;
   if (low_key == 0) {
-    r_key = rl_src.low_reg;
+    r_key = rl_src.reg.GetReg();
   } else if ((low_key & 0xffff) != low_key) {
     r_key = AllocTemp();
     LoadConstant(r_key, low_key);
@@ -179,9 +179,9 @@
     NewLIR0(kMipsNop);
   } else {
     if (large_bias) {
-      OpRegRegReg(kOpSub, r_key, rl_src.low_reg, r_key);
+      OpRegRegReg(kOpSub, r_key, rl_src.reg.GetReg(), r_key);
     } else {
-      OpRegRegImm(kOpSub, r_key, rl_src.low_reg, low_key);
+      OpRegRegImm(kOpSub, r_key, rl_src.reg.GetReg(), low_key);
     }
   }
   GenBarrier();  // Scheduling barrier
@@ -263,7 +263,7 @@
   int ex_offset = Thread::ExceptionOffset().Int32Value();
   RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
   int reset_reg = AllocTemp();
-  LoadWordDisp(rMIPS_SELF, ex_offset, rl_result.low_reg);
+  LoadWordDisp(rMIPS_SELF, ex_offset, rl_result.reg.GetReg());
   LoadConstant(reset_reg, 0);
   StoreWordDisp(rMIPS_SELF, ex_offset, reset_reg);
   FreeTemp(reset_reg);
diff --git a/compiler/dex/quick/mips/codegen_mips.h b/compiler/dex/quick/mips/codegen_mips.h
index dad8a3b..61eb68d 100644
--- a/compiler/dex/quick/mips/codegen_mips.h
+++ b/compiler/dex/quick/mips/codegen_mips.h
@@ -49,7 +49,7 @@
     bool IsFpReg(int reg);
     bool SameRegType(int reg1, int reg2);
     int AllocTypedTemp(bool fp_hint, int reg_class);
-    int AllocTypedTempPair(bool fp_hint, int reg_class);
+    RegStorage AllocTypedTempWide(bool fp_hint, int reg_class);
     int S2d(int low_reg, int high_reg);
     int TargetReg(SpecialTargetRegister reg);
     int GetArgMappingToPhysicalReg(int arg_num);
diff --git a/compiler/dex/quick/mips/fp_mips.cc b/compiler/dex/quick/mips/fp_mips.cc
index 9e2fea9..cf4f19f 100644
--- a/compiler/dex/quick/mips/fp_mips.cc
+++ b/compiler/dex/quick/mips/fp_mips.cc
@@ -64,7 +64,7 @@
   rl_src1 = LoadValue(rl_src1, kFPReg);
   rl_src2 = LoadValue(rl_src2, kFPReg);
   rl_result = EvalLoc(rl_dest, kFPReg, true);
-  NewLIR3(op, rl_result.low_reg, rl_src1.low_reg, rl_src2.low_reg);
+  NewLIR3(op, rl_result.reg.GetReg(), rl_src1.reg.GetReg(), rl_src2.reg.GetReg());
   StoreValue(rl_dest, rl_result);
 }
 
@@ -111,8 +111,8 @@
   rl_result = EvalLoc(rl_dest, kFPReg, true);
   DCHECK(rl_dest.wide);
   DCHECK(rl_result.wide);
-  NewLIR3(op, S2d(rl_result.low_reg, rl_result.high_reg), S2d(rl_src1.low_reg, rl_src1.high_reg),
-          S2d(rl_src2.low_reg, rl_src2.high_reg));
+  NewLIR3(op, S2d(rl_result.reg.GetReg(), rl_result.reg.GetHighReg()), S2d(rl_src1.reg.GetReg(), rl_src1.reg.GetHighReg()),
+          S2d(rl_src2.reg.GetReg(), rl_src2.reg.GetHighReg()));
   StoreValueWide(rl_dest, rl_result);
 }
 
@@ -157,18 +157,18 @@
   }
   if (rl_src.wide) {
     rl_src = LoadValueWide(rl_src, kFPReg);
-    src_reg = S2d(rl_src.low_reg, rl_src.high_reg);
+    src_reg = S2d(rl_src.reg.GetReg(), rl_src.reg.GetHighReg());
   } else {
     rl_src = LoadValue(rl_src, kFPReg);
-    src_reg = rl_src.low_reg;
+    src_reg = rl_src.reg.GetReg();
   }
   if (rl_dest.wide) {
     rl_result = EvalLoc(rl_dest, kFPReg, true);
-    NewLIR2(op, S2d(rl_result.low_reg, rl_result.high_reg), src_reg);
+    NewLIR2(op, S2d(rl_result.reg.GetReg(), rl_result.reg.GetHighReg()), src_reg);
     StoreValueWide(rl_dest, rl_result);
   } else {
     rl_result = EvalLoc(rl_dest, kFPReg, true);
-    NewLIR2(op, rl_result.low_reg, src_reg);
+    NewLIR2(op, rl_result.reg.GetReg(), src_reg);
     StoreValue(rl_dest, rl_result);
   }
 }
@@ -221,7 +221,7 @@
   RegLocation rl_result;
   rl_src = LoadValue(rl_src, kCoreReg);
   rl_result = EvalLoc(rl_dest, kCoreReg, true);
-  OpRegRegImm(kOpAdd, rl_result.low_reg, rl_src.low_reg, 0x80000000);
+  OpRegRegImm(kOpAdd, rl_result.reg.GetReg(), rl_src.reg.GetReg(), 0x80000000);
   StoreValue(rl_dest, rl_result);
 }
 
@@ -229,8 +229,8 @@
   RegLocation rl_result;
   rl_src = LoadValueWide(rl_src, kCoreReg);
   rl_result = EvalLoc(rl_dest, kCoreReg, true);
-  OpRegRegImm(kOpAdd, rl_result.high_reg, rl_src.high_reg, 0x80000000);
-  OpRegCopy(rl_result.low_reg, rl_src.low_reg);
+  OpRegRegImm(kOpAdd, rl_result.reg.GetHighReg(), rl_src.reg.GetHighReg(), 0x80000000);
+  OpRegCopy(rl_result.reg.GetReg(), rl_src.reg.GetReg());
   StoreValueWide(rl_dest, rl_result);
 }
 
diff --git a/compiler/dex/quick/mips/int_mips.cc b/compiler/dex/quick/mips/int_mips.cc
index 013041a..fec801b 100644
--- a/compiler/dex/quick/mips/int_mips.cc
+++ b/compiler/dex/quick/mips/int_mips.cc
@@ -47,13 +47,13 @@
   int t0 = AllocTemp();
   int t1 = AllocTemp();
   RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
-  NewLIR3(kMipsSlt, t0, rl_src1.high_reg, rl_src2.high_reg);
-  NewLIR3(kMipsSlt, t1, rl_src2.high_reg, rl_src1.high_reg);
-  NewLIR3(kMipsSubu, rl_result.low_reg, t1, t0);
-  LIR* branch = OpCmpImmBranch(kCondNe, rl_result.low_reg, 0, NULL);
-  NewLIR3(kMipsSltu, t0, rl_src1.low_reg, rl_src2.low_reg);
-  NewLIR3(kMipsSltu, t1, rl_src2.low_reg, rl_src1.low_reg);
-  NewLIR3(kMipsSubu, rl_result.low_reg, t1, t0);
+  NewLIR3(kMipsSlt, t0, rl_src1.reg.GetHighReg(), rl_src2.reg.GetHighReg());
+  NewLIR3(kMipsSlt, t1, rl_src2.reg.GetHighReg(), rl_src1.reg.GetHighReg());
+  NewLIR3(kMipsSubu, rl_result.reg.GetReg(), t1, t0);
+  LIR* branch = OpCmpImmBranch(kCondNe, rl_result.reg.GetReg(), 0, NULL);
+  NewLIR3(kMipsSltu, t0, rl_src1.reg.GetReg(), rl_src2.reg.GetReg());
+  NewLIR3(kMipsSltu, t1, rl_src2.reg.GetReg(), rl_src1.reg.GetReg());
+  NewLIR3(kMipsSubu, rl_result.reg.GetReg(), t1, t0);
   FreeTemp(t0);
   FreeTemp(t1);
   LIR* target = NewLIR0(kPseudoTargetLabel);
@@ -228,9 +228,9 @@
   NewLIR4(kMipsDiv, r_HI, r_LO, reg1, reg2);
   RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
   if (is_div) {
-    NewLIR2(kMipsMflo, rl_result.low_reg, r_LO);
+    NewLIR2(kMipsMflo, rl_result.reg.GetReg(), r_LO);
   } else {
-    NewLIR2(kMipsMfhi, rl_result.low_reg, r_HI);
+    NewLIR2(kMipsMfhi, rl_result.reg.GetReg(), r_HI);
   }
   return rl_result;
 }
@@ -242,9 +242,9 @@
   NewLIR4(kMipsDiv, r_HI, r_LO, reg1, t_reg);
   RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
   if (is_div) {
-    NewLIR2(kMipsMflo, rl_result.low_reg, r_LO);
+    NewLIR2(kMipsMflo, rl_result.reg.GetReg(), r_LO);
   } else {
-    NewLIR2(kMipsMfhi, rl_result.low_reg, r_HI);
+    NewLIR2(kMipsMfhi, rl_result.reg.GetReg(), r_HI);
   }
   FreeTemp(t_reg);
   return rl_result;
@@ -290,7 +290,7 @@
   RegLocation rl_address = LoadValue(rl_src_address, kCoreReg);
   RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
   DCHECK(size == kSignedByte);
-  LoadBaseDisp(rl_address.low_reg, 0, rl_result.low_reg, size, INVALID_SREG);
+  LoadBaseDisp(rl_address.reg.GetReg(), 0, rl_result.reg.GetReg(), size, INVALID_SREG);
   StoreValue(rl_dest, rl_result);
   return true;
 }
@@ -306,7 +306,7 @@
   RegLocation rl_address = LoadValue(rl_src_address, kCoreReg);
   DCHECK(size == kSignedByte);
   RegLocation rl_value = LoadValue(rl_src_value, kCoreReg);
-  StoreBaseDisp(rl_address.low_reg, 0, rl_value.low_reg, size);
+  StoreBaseDisp(rl_address.reg.GetReg(), 0, rl_value.reg.GetReg(), size);
   return true;
 }
 
@@ -329,11 +329,11 @@
                                                 RegLocation rl_result, int lit,
                                                 int first_bit, int second_bit) {
   int t_reg = AllocTemp();
-  OpRegRegImm(kOpLsl, t_reg, rl_src.low_reg, second_bit - first_bit);
-  OpRegRegReg(kOpAdd, rl_result.low_reg, rl_src.low_reg, t_reg);
+  OpRegRegImm(kOpLsl, t_reg, rl_src.reg.GetReg(), second_bit - first_bit);
+  OpRegRegReg(kOpAdd, rl_result.reg.GetReg(), rl_src.reg.GetReg(), t_reg);
   FreeTemp(t_reg);
   if (first_bit != 0) {
-    OpRegRegImm(kOpLsl, rl_result.low_reg, rl_result.low_reg, first_bit);
+    OpRegRegImm(kOpLsl, rl_result.reg.GetReg(), rl_result.reg.GetReg(), first_bit);
   }
 }
 
@@ -385,11 +385,11 @@
    *  addu v1,v1,t1
    */
 
-  OpRegRegReg(kOpAdd, rl_result.low_reg, rl_src2.low_reg, rl_src1.low_reg);
+  OpRegRegReg(kOpAdd, rl_result.reg.GetReg(), rl_src2.reg.GetReg(), rl_src1.reg.GetReg());
   int t_reg = AllocTemp();
-  OpRegRegReg(kOpAdd, t_reg, rl_src2.high_reg, rl_src1.high_reg);
-  NewLIR3(kMipsSltu, rl_result.high_reg, rl_result.low_reg, rl_src2.low_reg);
-  OpRegRegReg(kOpAdd, rl_result.high_reg, rl_result.high_reg, t_reg);
+  OpRegRegReg(kOpAdd, t_reg, rl_src2.reg.GetHighReg(), rl_src1.reg.GetHighReg());
+  NewLIR3(kMipsSltu, rl_result.reg.GetHighReg(), rl_result.reg.GetReg(), rl_src2.reg.GetReg());
+  OpRegRegReg(kOpAdd, rl_result.reg.GetHighReg(), rl_result.reg.GetHighReg(), t_reg);
   FreeTemp(t_reg);
   StoreValueWide(rl_dest, rl_result);
 }
@@ -408,10 +408,10 @@
    */
 
   int t_reg = AllocTemp();
-  NewLIR3(kMipsSltu, t_reg, rl_src1.low_reg, rl_src2.low_reg);
-  OpRegRegReg(kOpSub, rl_result.low_reg, rl_src1.low_reg, rl_src2.low_reg);
-  OpRegRegReg(kOpSub, rl_result.high_reg, rl_src1.high_reg, rl_src2.high_reg);
-  OpRegRegReg(kOpSub, rl_result.high_reg, rl_result.high_reg, t_reg);
+  NewLIR3(kMipsSltu, t_reg, rl_src1.reg.GetReg(), rl_src2.reg.GetReg());
+  OpRegRegReg(kOpSub, rl_result.reg.GetReg(), rl_src1.reg.GetReg(), rl_src2.reg.GetReg());
+  OpRegRegReg(kOpSub, rl_result.reg.GetHighReg(), rl_src1.reg.GetHighReg(), rl_src2.reg.GetHighReg());
+  OpRegRegReg(kOpSub, rl_result.reg.GetHighReg(), rl_result.reg.GetHighReg(), t_reg);
   FreeTemp(t_reg);
   StoreValueWide(rl_dest, rl_result);
 }
@@ -427,11 +427,11 @@
    *  subu  v1,v1,t1
    */
 
-  OpRegReg(kOpNeg, rl_result.low_reg, rl_src.low_reg);
-  OpRegReg(kOpNeg, rl_result.high_reg, rl_src.high_reg);
+  OpRegReg(kOpNeg, rl_result.reg.GetReg(), rl_src.reg.GetReg());
+  OpRegReg(kOpNeg, rl_result.reg.GetHighReg(), rl_src.reg.GetHighReg());
   int t_reg = AllocTemp();
-  NewLIR3(kMipsSltu, t_reg, r_ZERO, rl_result.low_reg);
-  OpRegRegReg(kOpSub, rl_result.high_reg, rl_result.high_reg, t_reg);
+  NewLIR3(kMipsSltu, t_reg, r_ZERO, rl_result.reg.GetReg());
+  OpRegRegReg(kOpSub, rl_result.reg.GetHighReg(), rl_result.reg.GetHighReg(), t_reg);
   FreeTemp(t_reg);
   StoreValueWide(rl_dest, rl_result);
 }
@@ -471,7 +471,7 @@
   }
 
   /* null object? */
-  GenNullCheck(rl_array.s_reg_low, rl_array.low_reg, opt_flags);
+  GenNullCheck(rl_array.s_reg_low, rl_array.reg.GetReg(), opt_flags);
 
   int reg_ptr = AllocTemp();
   bool needs_range_check = (!(opt_flags & MIR_IGNORE_RANGE_CHECK));
@@ -479,28 +479,28 @@
   if (needs_range_check) {
     reg_len = AllocTemp();
     /* Get len */
-    LoadWordDisp(rl_array.low_reg, len_offset, reg_len);
+    LoadWordDisp(rl_array.reg.GetReg(), len_offset, reg_len);
   }
   /* reg_ptr -> array data */
-  OpRegRegImm(kOpAdd, reg_ptr, rl_array.low_reg, data_offset);
-  FreeTemp(rl_array.low_reg);
+  OpRegRegImm(kOpAdd, reg_ptr, rl_array.reg.GetReg(), data_offset);
+  FreeTemp(rl_array.reg.GetReg());
   if ((size == kLong) || (size == kDouble)) {
     if (scale) {
       int r_new_index = AllocTemp();
-      OpRegRegImm(kOpLsl, r_new_index, rl_index.low_reg, scale);
+      OpRegRegImm(kOpLsl, r_new_index, rl_index.reg.GetReg(), scale);
       OpRegReg(kOpAdd, reg_ptr, r_new_index);
       FreeTemp(r_new_index);
     } else {
-      OpRegReg(kOpAdd, reg_ptr, rl_index.low_reg);
+      OpRegReg(kOpAdd, reg_ptr, rl_index.reg.GetReg());
     }
-    FreeTemp(rl_index.low_reg);
+    FreeTemp(rl_index.reg.GetReg());
     rl_result = EvalLoc(rl_dest, reg_class, true);
 
     if (needs_range_check) {
-      GenRegRegCheck(kCondUge, rl_index.low_reg, reg_len, kThrowArrayBounds);
+      GenRegRegCheck(kCondUge, rl_index.reg.GetReg(), reg_len, kThrowArrayBounds);
       FreeTemp(reg_len);
     }
-    LoadBaseDispWide(reg_ptr, 0, rl_result.low_reg, rl_result.high_reg, INVALID_SREG);
+    LoadBaseDispWide(reg_ptr, 0, rl_result.reg.GetReg(), rl_result.reg.GetHighReg(), INVALID_SREG);
 
     FreeTemp(reg_ptr);
     StoreValueWide(rl_dest, rl_result);
@@ -508,10 +508,10 @@
     rl_result = EvalLoc(rl_dest, reg_class, true);
 
     if (needs_range_check) {
-      GenRegRegCheck(kCondUge, rl_index.low_reg, reg_len, kThrowArrayBounds);
+      GenRegRegCheck(kCondUge, rl_index.reg.GetReg(), reg_len, kThrowArrayBounds);
       FreeTemp(reg_len);
     }
-    LoadBaseIndexed(reg_ptr, rl_index.low_reg, rl_result.low_reg, scale, size);
+    LoadBaseIndexed(reg_ptr, rl_index.reg.GetReg(), rl_result.reg.GetReg(), scale, size);
 
     FreeTemp(reg_ptr);
     StoreValue(rl_dest, rl_result);
@@ -538,17 +538,17 @@
   rl_index = LoadValue(rl_index, kCoreReg);
   int reg_ptr = INVALID_REG;
   bool allocated_reg_ptr_temp = false;
-  if (IsTemp(rl_array.low_reg) && !card_mark) {
-    Clobber(rl_array.low_reg);
-    reg_ptr = rl_array.low_reg;
+  if (IsTemp(rl_array.reg.GetReg()) && !card_mark) {
+    Clobber(rl_array.reg.GetReg());
+    reg_ptr = rl_array.reg.GetReg();
   } else {
     reg_ptr = AllocTemp();
-    OpRegCopy(reg_ptr, rl_array.low_reg);
+    OpRegCopy(reg_ptr, rl_array.reg.GetReg());
     allocated_reg_ptr_temp = true;
   }
 
   /* null object? */
-  GenNullCheck(rl_array.s_reg_low, rl_array.low_reg, opt_flags);
+  GenNullCheck(rl_array.s_reg_low, rl_array.reg.GetReg(), opt_flags);
 
   bool needs_range_check = (!(opt_flags & MIR_IGNORE_RANGE_CHECK));
   int reg_len = INVALID_REG;
@@ -556,7 +556,7 @@
     reg_len = AllocTemp();
     // NOTE: max live temps(4) here.
     /* Get len */
-    LoadWordDisp(rl_array.low_reg, len_offset, reg_len);
+    LoadWordDisp(rl_array.reg.GetReg(), len_offset, reg_len);
   }
   /* reg_ptr -> array data */
   OpRegImm(kOpAdd, reg_ptr, data_offset);
@@ -565,34 +565,34 @@
     // TUNING: specific wide routine that can handle fp regs
     if (scale) {
       int r_new_index = AllocTemp();
-      OpRegRegImm(kOpLsl, r_new_index, rl_index.low_reg, scale);
+      OpRegRegImm(kOpLsl, r_new_index, rl_index.reg.GetReg(), scale);
       OpRegReg(kOpAdd, reg_ptr, r_new_index);
       FreeTemp(r_new_index);
     } else {
-      OpRegReg(kOpAdd, reg_ptr, rl_index.low_reg);
+      OpRegReg(kOpAdd, reg_ptr, rl_index.reg.GetReg());
     }
     rl_src = LoadValueWide(rl_src, reg_class);
 
     if (needs_range_check) {
-      GenRegRegCheck(kCondUge, rl_index.low_reg, reg_len, kThrowArrayBounds);
+      GenRegRegCheck(kCondUge, rl_index.reg.GetReg(), reg_len, kThrowArrayBounds);
       FreeTemp(reg_len);
     }
 
-    StoreBaseDispWide(reg_ptr, 0, rl_src.low_reg, rl_src.high_reg);
+    StoreBaseDispWide(reg_ptr, 0, rl_src.reg.GetReg(), rl_src.reg.GetHighReg());
   } else {
     rl_src = LoadValue(rl_src, reg_class);
     if (needs_range_check) {
-      GenRegRegCheck(kCondUge, rl_index.low_reg, reg_len, kThrowArrayBounds);
+      GenRegRegCheck(kCondUge, rl_index.reg.GetReg(), reg_len, kThrowArrayBounds);
       FreeTemp(reg_len);
     }
-    StoreBaseIndexed(reg_ptr, rl_index.low_reg, rl_src.low_reg,
+    StoreBaseIndexed(reg_ptr, rl_index.reg.GetReg(), rl_src.reg.GetReg(),
                      scale, size);
   }
   if (allocated_reg_ptr_temp) {
     FreeTemp(reg_ptr);
   }
   if (card_mark) {
-    MarkGCCard(rl_src.low_reg, rl_array.low_reg);
+    MarkGCCard(rl_src.reg.GetReg(), rl_array.reg.GetReg());
   }
 }
 
diff --git a/compiler/dex/quick/mips/mips_lir.h b/compiler/dex/quick/mips/mips_lir.h
index 00eef96..59f442c 100644
--- a/compiler/dex/quick/mips/mips_lir.h
+++ b/compiler/dex/quick/mips/mips_lir.h
@@ -141,16 +141,6 @@
 #define rMIPS_LR INVALID_REG
 #define rMIPS_PC INVALID_REG
 
-// RegisterLocation templates return values (r_V0, or r_V0/r_V1).
-#define MIPS_LOC_C_RETURN {kLocPhysReg, 0, 0, 0, 0, 0, 0, 0, 1, kVectorNotUsed, r_V0, INVALID_REG, \
-                           INVALID_SREG, INVALID_SREG}
-#define MIPS_LOC_C_RETURN_FLOAT {kLocPhysReg, 0, 0, 0, 0, 0, 0, 0, 1, kVectorNotUsed, r_FRESULT0, \
-                                 INVALID_REG, INVALID_SREG, INVALID_SREG}
-#define MIPS_LOC_C_RETURN_WIDE {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1, kVectorNotUsed, r_RESULT0, \
-                                r_RESULT1, INVALID_SREG, INVALID_SREG}
-#define MIPS_LOC_C_RETURN_DOUBLE {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1, kVectorNotUsed, r_FRESULT0, \
-                                  r_FRESULT1, INVALID_SREG, INVALID_SREG}
-
 enum MipsResourceEncodingPos {
   kMipsGPReg0   = 0,
   kMipsRegSP    = 29,
@@ -279,6 +269,20 @@
 #define rMIPS_INVOKE_TGT r_T9
 #define rMIPS_COUNT INVALID_REG
 
+// RegisterLocation templates return values (r_V0, or r_V0/r_V1).
+const RegLocation mips_loc_c_return
+    {kLocPhysReg, 0, 0, 0, 0, 0, 0, 0, 1, kVectorNotUsed,
+     RegStorage(RegStorage::k32BitSolo, r_V0), INVALID_SREG, INVALID_SREG};
+const RegLocation mips_loc_c_return_wide
+    {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1, kVectorNotUsed,
+     RegStorage(RegStorage::k64BitPair, r_V0, r_V1), INVALID_SREG, INVALID_SREG};
+const RegLocation mips_loc_c_return_float
+    {kLocPhysReg, 0, 0, 0, 1, 0, 0, 0, 1, kVectorNotUsed,
+     RegStorage(RegStorage::k32BitSolo, r_F0), INVALID_SREG, INVALID_SREG};
+const RegLocation mips_loc_c_return_double
+    {kLocPhysReg, 1, 0, 0, 1, 0, 0, 0, 1, kVectorNotUsed,
+     RegStorage(RegStorage::k64BitPair, r_F0, r_F1), INVALID_SREG, INVALID_SREG};
+
 enum MipsShiftEncodings {
   kMipsLsl = 0x0,
   kMipsLsr = 0x1,
diff --git a/compiler/dex/quick/mips/target_mips.cc b/compiler/dex/quick/mips/target_mips.cc
index 224e8f2..85c250d 100644
--- a/compiler/dex/quick/mips/target_mips.cc
+++ b/compiler/dex/quick/mips/target_mips.cc
@@ -40,23 +40,19 @@
                          r_F8, r_F9, r_F10, r_F11, r_F12, r_F13, r_F14, r_F15};
 
 RegLocation MipsMir2Lir::LocCReturn() {
-  RegLocation res = MIPS_LOC_C_RETURN;
-  return res;
+  return mips_loc_c_return;
 }
 
 RegLocation MipsMir2Lir::LocCReturnWide() {
-  RegLocation res = MIPS_LOC_C_RETURN_WIDE;
-  return res;
+  return mips_loc_c_return_wide;
 }
 
 RegLocation MipsMir2Lir::LocCReturnFloat() {
-  RegLocation res = MIPS_LOC_C_RETURN_FLOAT;
-  return res;
+  return mips_loc_c_return_float;
 }
 
 RegLocation MipsMir2Lir::LocCReturnDouble() {
-  RegLocation res = MIPS_LOC_C_RETURN_DOUBLE;
-  return res;
+  return mips_loc_c_return_double;
 }
 
 // Return a target-dependent special register.
@@ -441,27 +437,20 @@
 #endif
 }
 
-/*
- * Alloc a pair of core registers, or a double.  Low reg in low byte,
- * high reg in next byte.
- */
-int MipsMir2Lir::AllocTypedTempPair(bool fp_hint,
-                  int reg_class) {
+// Alloc a pair of core registers, or a double.
+RegStorage MipsMir2Lir::AllocTypedTempWide(bool fp_hint, int reg_class) {
   int high_reg;
   int low_reg;
-  int res = 0;
 
   if (((reg_class == kAnyReg) && fp_hint) || (reg_class == kFPReg)) {
     low_reg = AllocTempDouble();
     high_reg = low_reg + 1;
-    res = (low_reg & 0xff) | ((high_reg & 0xff) << 8);
-    return res;
+    return RegStorage(RegStorage::k64BitPair, low_reg, high_reg);
   }
 
   low_reg = AllocTemp();
   high_reg = AllocTemp();
-  res = (low_reg & 0xff) | ((high_reg & 0xff) << 8);
-  return res;
+  return RegStorage(RegStorage::k64BitPair, low_reg, high_reg);
 }
 
 int MipsMir2Lir::AllocTypedTemp(bool fp_hint, int reg_class) {
@@ -505,11 +494,11 @@
 }
 
 void MipsMir2Lir::FreeRegLocTemps(RegLocation rl_keep, RegLocation rl_free) {
-  if ((rl_free.low_reg != rl_keep.low_reg) && (rl_free.low_reg != rl_keep.high_reg) &&
-    (rl_free.high_reg != rl_keep.low_reg) && (rl_free.high_reg != rl_keep.high_reg)) {
+  if ((rl_free.reg.GetReg() != rl_keep.reg.GetReg()) && (rl_free.reg.GetReg() != rl_keep.reg.GetHighReg()) &&
+    (rl_free.reg.GetHighReg() != rl_keep.reg.GetReg()) && (rl_free.reg.GetHighReg() != rl_keep.reg.GetHighReg())) {
     // No overlap, free both
-    FreeTemp(rl_free.low_reg);
-    FreeTemp(rl_free.high_reg);
+    FreeTemp(rl_free.reg.GetReg());
+    FreeTemp(rl_free.reg.GetHighReg());
   }
 }
 /*