OSDN Git Service

Fix GenArithOpInt to work with RA correctly
authorSerguei Katkov <serguei.i.katkov@intel.com>
Fri, 14 Mar 2014 06:33:33 +0000 (13:33 +0700)
committerbuzbee <buzbee@google.com>
Thu, 20 Mar 2014 14:03:52 +0000 (07:03 -0700)
In a case of mul-int/2addr bytecode when source operand is in
memory implementation should first load value of destination
and then evaluate location for destination. Otherwise load will
be skipped because after evaluation of physical register for
destination load will be ignored due to register allocator
thinks that value is already in register.

Change-Id: Iecee5a07d0fba16b421b8c49d42c5d8623794ad7
Signed-off-by: Serguei Katkov <serguei.i.katkov@intel.com>
compiler/dex/quick/x86/int_x86.cc

index a67c43c..dcbaad9 100644 (file)
@@ -2050,8 +2050,16 @@ void X86Mir2Lir::GenArithOpInt(Instruction::Code opcode, RegLocation rl_dest,
           // We can optimize by moving to result and using memory operands.
           if (rl_rhs.location != kLocPhysReg) {
             // Force LHS into result.
-            rl_result = EvalLoc(rl_dest, kCoreReg, true);
-            LoadValueDirect(rl_lhs, rl_result.reg.GetReg());
+            // We should be careful with order here
+            // If rl_dest and rl_lhs points to the same VR we should load first
+            // If the are different we should find a register first for dest
+            if (mir_graph_->SRegToVReg(rl_dest.s_reg_low) == mir_graph_->SRegToVReg(rl_lhs.s_reg_low)) {
+              rl_lhs = LoadValue(rl_lhs, kCoreReg);
+              rl_result = EvalLoc(rl_dest, kCoreReg, true);
+            } else {
+              rl_result = EvalLoc(rl_dest, kCoreReg, true);
+              LoadValueDirect(rl_lhs, rl_result.reg.GetReg());
+            }
             OpRegMem(op, rl_result.reg.GetReg(), rl_rhs);
           } else if (rl_lhs.location != kLocPhysReg) {
             // RHS is in a register; LHS is in memory.