summaryrefslogtreecommitdiffstats
path: root/compiler
diff options
context:
space:
mode:
authorSerguei Katkov <serguei.i.katkov@intel.com>2014-03-14 13:33:33 +0700
committerbuzbee <buzbee@google.com>2014-03-20 07:03:52 -0700
commit66da1364425df90e6a03b032ee0a401375e45c39 (patch)
tree3899f14b7945de135e77827acd6b6323a7d1e0ce /compiler
parent77bef430373a56f7dd9ba99ab8471bf5f571253a (diff)
downloadart-66da1364425df90e6a03b032ee0a401375e45c39.zip
art-66da1364425df90e6a03b032ee0a401375e45c39.tar.gz
art-66da1364425df90e6a03b032ee0a401375e45c39.tar.bz2
Fix GenArithOpInt to work with RA correctly
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>
Diffstat (limited to 'compiler')
-rw-r--r--compiler/dex/quick/x86/int_x86.cc12
1 files changed, 10 insertions, 2 deletions
diff --git a/compiler/dex/quick/x86/int_x86.cc b/compiler/dex/quick/x86/int_x86.cc
index a67c43c..dcbaad9 100644
--- a/compiler/dex/quick/x86/int_x86.cc
+++ b/compiler/dex/quick/x86/int_x86.cc
@@ -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.