summaryrefslogtreecommitdiffstats
path: root/compiler/dex/quick
diff options
context:
space:
mode:
authorPavel Vyssotski <pavel.n.vyssotski@intel.com>2014-11-11 12:37:56 +0600
committerPavel Vyssotski <pavel.n.vyssotski@intel.com>2014-11-11 12:37:56 +0600
commitd4812a97de5d54d29c2964b2db7c2d52217be60e (patch)
treecfeb33d9da9f085efefb0c3add993e61b54cc08d /compiler/dex/quick
parentbb5b390c3b7c1d6571e73672124f82cc40026f6a (diff)
downloadart-d4812a97de5d54d29c2964b2db7c2d52217be60e.zip
art-d4812a97de5d54d29c2964b2db7c2d52217be60e.tar.gz
art-d4812a97de5d54d29c2964b2db7c2d52217be60e.tar.bz2
ART: Fix clobbering low part in 32-bit version of X86Mir2Lir::GenNegDouble
If source registers overlap destination registers the low part of result can be clobbered in current implementation. For example, for 'neg-double v5, v6' bytecode compiler can generates the following instructions: lea ecx, [edx + 0x80000000] mov eax, ecx The fix forces source registers to be temp so there is no need to copy the low part. Change-Id: I986ca17d1dc45c9e9d44a66e501cd354af496fde Signed-off-by: Pavel Vyssotski <pavel.n.vyssotski@intel.com>
Diffstat (limited to 'compiler/dex/quick')
-rwxr-xr-xcompiler/dex/quick/x86/fp_x86.cc6
1 files changed, 3 insertions, 3 deletions
diff --git a/compiler/dex/quick/x86/fp_x86.cc b/compiler/dex/quick/x86/fp_x86.cc
index bc02eee..4825db6 100755
--- a/compiler/dex/quick/x86/fp_x86.cc
+++ b/compiler/dex/quick/x86/fp_x86.cc
@@ -584,16 +584,16 @@ void X86Mir2Lir::GenNegFloat(RegLocation rl_dest, RegLocation rl_src) {
void X86Mir2Lir::GenNegDouble(RegLocation rl_dest, RegLocation rl_src) {
RegLocation rl_result;
rl_src = LoadValueWide(rl_src, kCoreReg);
- rl_result = EvalLocWide(rl_dest, kCoreReg, true);
if (cu_->target64) {
+ rl_result = EvalLocWide(rl_dest, kCoreReg, true);
OpRegCopy(rl_result.reg, rl_src.reg);
// Flip sign bit.
NewLIR2(kX86Rol64RI, rl_result.reg.GetReg(), 1);
NewLIR2(kX86Xor64RI, rl_result.reg.GetReg(), 1);
NewLIR2(kX86Ror64RI, rl_result.reg.GetReg(), 1);
} else {
- OpRegRegImm(kOpAdd, rl_result.reg.GetHigh(), rl_src.reg.GetHigh(), 0x80000000);
- OpRegCopy(rl_result.reg, rl_src.reg);
+ rl_result = ForceTempWide(rl_src);
+ OpRegRegImm(kOpAdd, rl_result.reg.GetHigh(), rl_result.reg.GetHigh(), 0x80000000);
}
StoreValueWide(rl_dest, rl_result);
}