diff options
Diffstat (limited to 'compiler/dex/quick/gen_common.cc')
-rw-r--r-- | compiler/dex/quick/gen_common.cc | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/compiler/dex/quick/gen_common.cc b/compiler/dex/quick/gen_common.cc index c5aa27c324..061ee0747a 100644 --- a/compiler/dex/quick/gen_common.cc +++ b/compiler/dex/quick/gen_common.cc @@ -1785,6 +1785,34 @@ bool Mir2Lir::HandleEasyMultiply(RegLocation rl_src, RegLocation rl_dest, int li return true; } +// Returns true if it generates instructions. +bool Mir2Lir::HandleEasyFloatingPointDiv(RegLocation rl_dest, RegLocation rl_src1, + RegLocation rl_src2) { + if (!rl_src2.is_const || + ((cu_->instruction_set != kThumb2) && (cu_->instruction_set != kArm64))) { + return false; + } + + if (!rl_src2.wide) { + int32_t divisor = mir_graph_->ConstantValue(rl_src2); + if (CanDivideByReciprocalMultiplyFloat(divisor)) { + // Generate multiply by reciprocal instead of div. + float recip = 1.0f/bit_cast<int32_t, float>(divisor); + GenMultiplyByConstantFloat(rl_dest, rl_src1, bit_cast<float, int32_t>(recip)); + return true; + } + } else { + int64_t divisor = mir_graph_->ConstantValueWide(rl_src2); + if (CanDivideByReciprocalMultiplyDouble(divisor)) { + // Generate multiply by reciprocal instead of div. + double recip = 1.0/bit_cast<double, int64_t>(divisor); + GenMultiplyByConstantDouble(rl_dest, rl_src1, bit_cast<double, int64_t>(recip)); + return true; + } + } + return false; +} + void Mir2Lir::GenArithOpIntLit(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src, int lit) { RegLocation rl_result; |