diff options
author | Pavel Vyssotski <pavel.n.vyssotski@intel.com> | 2014-11-11 12:37:56 +0600 |
---|---|---|
committer | Pavel Vyssotski <pavel.n.vyssotski@intel.com> | 2014-11-11 12:37:56 +0600 |
commit | d4812a97de5d54d29c2964b2db7c2d52217be60e (patch) | |
tree | cfeb33d9da9f085efefb0c3add993e61b54cc08d /compiler/dex/quick | |
parent | bb5b390c3b7c1d6571e73672124f82cc40026f6a (diff) | |
download | art-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-x | compiler/dex/quick/x86/fp_x86.cc | 6 |
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); } |