diff options
author | Yixin Shou <yixin.shou@intel.com> | 2014-08-26 15:15:13 -0400 |
---|---|---|
committer | Yixin Shou <yixin.shou@intel.com> | 2014-08-27 20:36:09 -0400 |
commit | 2ddd175d74acc316293f5949746c637260437a49 (patch) | |
tree | 2cafdc8199d6d3785783de6019807e53306f19e9 /compiler | |
parent | 0038fcaa6f2457f5de5544fc93cd57a305e466de (diff) | |
download | art-2ddd175d74acc316293f5949746c637260437a49.zip art-2ddd175d74acc316293f5949746c637260437a49.tar.gz art-2ddd175d74acc316293f5949746c637260437a49.tar.bz2 |
Add numerator check for integer divide and modulo
Implemented numerator == 0 optimization for integer divide and modulo
Change-Id: I6e3bff4a9f68d2790394f7df6106a948003a04c4
Signed-off-by: Yixin Shou <yixin.shou@intel.com>
Diffstat (limited to 'compiler')
-rwxr-xr-x | compiler/dex/quick/x86/int_x86.cc | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/compiler/dex/quick/x86/int_x86.cc b/compiler/dex/quick/x86/int_x86.cc index cc51538..3463c54 100755 --- a/compiler/dex/quick/x86/int_x86.cc +++ b/compiler/dex/quick/x86/int_x86.cc @@ -607,6 +607,12 @@ RegLocation X86Mir2Lir::GenDivRemLit(RegLocation rl_dest, RegLocation rl_src, rl_result = EvalLoc(rl_dest, kCoreReg, true); if (is_div) { LoadValueDirectFixed(rl_src, rl_result.reg); + + // Check if numerator is 0 + OpRegImm(kOpCmp, rl_result.reg, 0); + LIR* branch = NewLIR2(kX86Jcc8, 0, kX86CondEq); + + // handle 0x80000000 / -1 OpRegImm(kOpCmp, rl_result.reg, 0x80000000); LIR *minint_branch = NewLIR2(kX86Jcc8, 0, kX86CondEq); @@ -615,6 +621,7 @@ RegLocation X86Mir2Lir::GenDivRemLit(RegLocation rl_dest, RegLocation rl_src, // EAX already contains the right value (0x80000000), minint_branch->target = NewLIR0(kPseudoTargetLabel); + branch->target = NewLIR0(kPseudoTargetLabel); } else { // x % -1 == 0. LoadConstantNoClobber(rl_result.reg, 0); @@ -627,6 +634,14 @@ RegLocation X86Mir2Lir::GenDivRemLit(RegLocation rl_dest, RegLocation rl_src, RegStorage rs_temp = AllocTypedTemp(false, kCoreReg); rl_result.reg.SetReg(rs_temp.GetReg()); } + + // Check if numerator is 0 + OpRegImm(kOpCmp, rl_src.reg, 0); + LIR* branch = NewLIR2(kX86Jcc8, 0, kX86CondNe); + LoadConstantNoClobber(rl_result.reg, 0); + LIR* done = NewLIR1(kX86Jmp8, 0); + branch->target = NewLIR0(kPseudoTargetLabel); + NewLIR3(kX86Lea32RM, rl_result.reg.GetReg(), rl_src.reg.GetReg(), std::abs(imm) - 1); NewLIR2(kX86Test32RR, rl_src.reg.GetReg(), rl_src.reg.GetReg()); OpCondRegReg(kOpCmov, kCondPl, rl_result.reg, rl_src.reg); @@ -635,6 +650,7 @@ RegLocation X86Mir2Lir::GenDivRemLit(RegLocation rl_dest, RegLocation rl_src, if (imm < 0) { OpReg(kOpNeg, rl_result.reg); } + done->target = NewLIR0(kPseudoTargetLabel); } else { CHECK(imm <= -2 || imm >= 2); @@ -682,6 +698,13 @@ RegLocation X86Mir2Lir::GenDivRemLit(RegLocation rl_dest, RegLocation rl_src, LoadValueDirectFixed(rl_src, rs_r0); } + // Check if numerator is 0 + OpRegImm(kOpCmp, rs_r0, 0); + LIR* branch = NewLIR2(kX86Jcc8, 0, kX86CondNe); + LoadConstantNoClobber(rs_r2, 0); + LIR* done = NewLIR1(kX86Jmp8, 0); + branch->target = NewLIR0(kPseudoTargetLabel); + // EDX = magic. LoadConstantNoClobber(rs_r2, magic); @@ -730,6 +753,7 @@ RegLocation X86Mir2Lir::GenDivRemLit(RegLocation rl_dest, RegLocation rl_src, // For this case, return the result in EAX. rl_result.reg.SetReg(r0); } + done->target = NewLIR0(kPseudoTargetLabel); } return rl_result; @@ -761,6 +785,10 @@ RegLocation X86Mir2Lir::GenDivRem(RegLocation rl_dest, RegLocation rl_src1, GenDivZeroCheck(rs_r1); } + // Check if numerator is 0 + OpRegImm(kOpCmp, rs_r0, 0); + LIR* branch = NewLIR2(kX86Jcc8, 0, kX86CondEq); + // Have to catch 0x80000000/-1 case, or we will get an exception! OpRegImm(kOpCmp, rs_r1, -1); LIR *minus_one_branch = NewLIR2(kX86Jcc8, 0, kX86CondNe); @@ -769,6 +797,8 @@ RegLocation X86Mir2Lir::GenDivRem(RegLocation rl_dest, RegLocation rl_src1, OpRegImm(kOpCmp, rs_r0, 0x80000000); LIR * minint_branch = NewLIR2(kX86Jcc8, 0, kX86CondNe); + branch->target = NewLIR0(kPseudoTargetLabel); + // In 0x80000000/-1 case. if (!is_div) { // For DIV, EAX is already right. For REM, we need EDX 0. |