diff options
author | Alexei Zavjalov <alexei.zavjalov@intel.com> | 2014-02-13 13:55:50 +0700 |
---|---|---|
committer | buzbee <buzbee@google.com> | 2014-02-13 15:31:02 -0800 |
commit | 79aa423fce400db3f551a3874e69e7cc4fb4f68f (patch) | |
tree | 54b53ac63d73e0e6614770b383c89a3a6b3169d3 /compiler | |
parent | 68bb649b128cd8760732524bd7ba58b49780d9d3 (diff) | |
download | art-79aa423fce400db3f551a3874e69e7cc4fb4f68f.zip art-79aa423fce400db3f551a3874e69e7cc4fb4f68f.tar.gz art-79aa423fce400db3f551a3874e69e7cc4fb4f68f.tar.bz2 |
x86 compiler should handle the "div/rem by 1" case
The current implementation of the (div/rem)/imm algorithm in
ART's x86 compiler (X86Mir2Lir::GenDivRemLit) handles the only
case when imm == -1, imm >= 2 and imm <= -2, but in the case
when imm == 1, the result of calculation is incorrect.
This patch adds handler of the "div/rem by 1" case.
Change-Id: I4bcdcd9c17f5ccb6c60e7c359c00e04cd07f5bee
Signed-off-by: Alexei Zavjalov <alexei.zavjalov@intel.com>
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/dex/quick/x86/int_x86.cc | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/compiler/dex/quick/x86/int_x86.cc b/compiler/dex/quick/x86/int_x86.cc index 9dd6116..1df9254 100644 --- a/compiler/dex/quick/x86/int_x86.cc +++ b/compiler/dex/quick/x86/int_x86.cc @@ -456,10 +456,20 @@ RegLocation X86Mir2Lir::GenDivRemLit(RegLocation rl_dest, RegLocation rl_src, RegLocation rl_result = {kLocPhysReg, 0, 0, 0, 0, 0, 0, 0, 1, kVectorNotUsed, r2, INVALID_REG, INVALID_SREG, INVALID_SREG}; - // handle 0x80000000 / -1 special case. - LIR *minint_branch = 0; - if (imm == -1) { + // handle div/rem by 1 special case. + if (imm == 1) { if (is_div) { + // x / 1 == x. + StoreValue(rl_result, rl_src); + } else { + // x % 1 == 0. + LoadConstantNoClobber(r0, 0); + // For this case, return the result in EAX. + rl_result.low_reg = r0; + } + } else if (imm == -1) { // handle 0x80000000 / -1 special case. + if (is_div) { + LIR *minint_branch = 0; LoadValueDirectFixed(rl_src, r0); OpRegImm(kOpCmp, r0, 0x80000000); minint_branch = NewLIR2(kX86Jcc8, 0, kX86CondEq); @@ -479,7 +489,7 @@ RegLocation X86Mir2Lir::GenDivRemLit(RegLocation rl_dest, RegLocation rl_src, // For this case, return the result in EAX. rl_result.low_reg = r0; } else { - DCHECK(imm <= -2 || imm >= 2); + CHECK(imm <= -2 || imm >= 2); // Use H.S.Warren's Hacker's Delight Chapter 10 and // T,Grablund, P.L.Montogomery's Division by invariant integers using multiplication. int magic, shift; |