OSDN Git Service

Quick: Fix out of temp regs in ArmMir2Lir::GenMulLong().
authorVladimir Marko <vmarko@google.com>
Thu, 23 Apr 2015 16:00:40 +0000 (17:00 +0100)
committerVladimir Marko <vmarko@google.com>
Thu, 23 Apr 2015 16:00:40 +0000 (17:00 +0100)
This fixes running out of temp registers for mul-long that
needs a temporary to store the result, i.e. when it's stored
to stack location [sp, #offset] with offset >= 1024. The bug
is currently not reproducible because ARM_R4_SUSPEND_FLAG is
off and thus we have the extra register available. However,
the code generation could be cleaned up and make use of that
extra register, so pre-emptively fix it anyway.

Bug: 20110806
Change-Id: I8362c349961dbe28fc3ec8a9299b66fd72f26779

compiler/dex/quick/arm/int_arm.cc

index 8d20f1b..7598e50 100644 (file)
@@ -1326,11 +1326,6 @@ void ArmMir2Lir::GenMulLong(Instruction::Code opcode, RegLocation rl_dest,
     }
   }
 
-  // Now, restore lr to its non-temp status.
-  FreeTemp(tmp1);
-  Clobber(rs_rARM_LR);
-  UnmarkTemp(rs_rARM_LR);
-
   if (reg_status != 0) {
     // We had manually allocated registers for rl_result.
     // Now construct a RegLocation.
@@ -1338,7 +1333,14 @@ void ArmMir2Lir::GenMulLong(Instruction::Code opcode, RegLocation rl_dest,
     rl_result.reg = RegStorage::MakeRegPair(res_lo, res_hi);
   }
 
+  // Free tmp1 but keep LR as temp for StoreValueWide() if needed.
+  FreeTemp(tmp1);
+
   StoreValueWide(rl_dest, rl_result);
+
+  // Now, restore lr to its non-temp status.
+  Clobber(rs_rARM_LR);
+  UnmarkTemp(rs_rARM_LR);
 }
 
 void ArmMir2Lir::GenArithOpLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,