| Index: runtime/vm/intermediate_language_arm.cc
|
| diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc
|
| index 14e341e54d3285843578e5f7cb48561bc1606fc0..18950caac20bf2ac73a3bf9e5830395631882277 100644
|
| --- a/runtime/vm/intermediate_language_arm.cc
|
| +++ b/runtime/vm/intermediate_language_arm.cc
|
| @@ -3071,7 +3071,7 @@ static void EmitSmiShiftLeft(FlowGraphCompiler* compiler,
|
|
|
| // Right (locs.in(1)) is not constant.
|
| const Register right = locs.in(1).reg();
|
| - Range* right_range = shift_left->right()->definition()->range();
|
| + Range* right_range = shift_left->right_range();
|
| if (shift_left->left()->BindsToConstant() && shift_left->can_overflow()) {
|
| // TODO(srdjan): Implement code below for is_truncating().
|
| // If left is constant, we know the maximal allowed size for right.
|
| @@ -3101,9 +3101,7 @@ static void EmitSmiShiftLeft(FlowGraphCompiler* compiler,
|
| !RangeUtils::IsWithin(right_range, 0, (Smi::kBits - 1));
|
| if (!shift_left->can_overflow()) {
|
| if (right_needs_check) {
|
| - const bool right_may_be_negative =
|
| - (right_range == NULL) || !right_range->IsPositive();
|
| - if (right_may_be_negative) {
|
| + if (!RangeUtils::IsPositive(right_range)) {
|
| ASSERT(shift_left->CanDeoptimize());
|
| __ cmp(right, Operand(0));
|
| __ b(deopt, MI);
|
| @@ -3582,7 +3580,6 @@ void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| }
|
|
|
| const Register right = locs()->in(1).reg();
|
| - Range* right_range = this->right()->definition()->range();
|
| switch (op_kind()) {
|
| case Token::kADD: {
|
| if (deopt == NULL) {
|
| @@ -3631,7 +3628,7 @@ void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| }
|
| case Token::kTRUNCDIV: {
|
| ASSERT(TargetCPUFeatures::can_divide());
|
| - if ((right_range == NULL) || right_range->Overlaps(0, 0)) {
|
| + if (RangeUtils::CanBeZero(right_range())) {
|
| // Handle divide by zero in runtime.
|
| __ cmp(right, Operand(0));
|
| __ b(deopt, EQ);
|
| @@ -3651,7 +3648,7 @@ void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| }
|
| case Token::kMOD: {
|
| ASSERT(TargetCPUFeatures::can_divide());
|
| - if ((right_range == NULL) || right_range->Overlaps(0, 0)) {
|
| + if (RangeUtils::CanBeZero(right_range())) {
|
| // Handle divide by zero in runtime.
|
| __ cmp(right, Operand(0));
|
| __ b(deopt, EQ);
|
| @@ -3690,8 +3687,7 @@ void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| __ SmiUntag(IP, right);
|
| // sarl operation masks the count to 5 bits.
|
| const intptr_t kCountLimit = 0x1F;
|
| - if ((right_range == NULL) ||
|
| - !right_range->OnlyLessThanOrEqualTo(kCountLimit)) {
|
| + if (!RangeUtils::OnlyLessThanOrEqualTo(right_range(), kCountLimit)) {
|
| __ CompareImmediate(IP, kCountLimit);
|
| __ LoadImmediate(IP, kCountLimit, GT);
|
| }
|
| @@ -6203,82 +6199,71 @@ void ExtractNthOutputInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| }
|
|
|
|
|
| -LocationSummary* MergedMathInstr::MakeLocationSummary(Zone* zone,
|
| - bool opt) const {
|
| - if (kind() == MergedMathInstr::kTruncDivMod) {
|
| - const intptr_t kNumInputs = 2;
|
| - const intptr_t kNumTemps = 2;
|
| - LocationSummary* summary = new (zone)
|
| - LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
|
| - summary->set_in(0, Location::RequiresRegister());
|
| - summary->set_in(1, Location::RequiresRegister());
|
| - summary->set_temp(0, Location::RequiresRegister());
|
| - summary->set_temp(1, Location::RequiresFpuRegister());
|
| - // Output is a pair of registers.
|
| - summary->set_out(0, Location::Pair(Location::RequiresRegister(),
|
| - Location::RequiresRegister()));
|
| - return summary;
|
| - }
|
| - UNIMPLEMENTED();
|
| - return NULL;
|
| +LocationSummary* TruncDivModInstr::MakeLocationSummary(Zone* zone,
|
| + bool opt) const {
|
| + const intptr_t kNumInputs = 2;
|
| + const intptr_t kNumTemps = 2;
|
| + LocationSummary* summary = new (zone)
|
| + LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
|
| + summary->set_in(0, Location::RequiresRegister());
|
| + summary->set_in(1, Location::RequiresRegister());
|
| + summary->set_temp(0, Location::RequiresRegister());
|
| + summary->set_temp(1, Location::RequiresFpuRegister());
|
| + // Output is a pair of registers.
|
| + summary->set_out(0, Location::Pair(Location::RequiresRegister(),
|
| + Location::RequiresRegister()));
|
| + return summary;
|
| }
|
|
|
|
|
| -void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| - Label* deopt = NULL;
|
| - if (CanDeoptimize()) {
|
| - deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinarySmiOp);
|
| - }
|
| - if (kind() == MergedMathInstr::kTruncDivMod) {
|
| - ASSERT(TargetCPUFeatures::can_divide());
|
| - const Register left = locs()->in(0).reg();
|
| - const Register right = locs()->in(1).reg();
|
| - ASSERT(locs()->out(0).IsPairLocation());
|
| - PairLocation* pair = locs()->out(0).AsPairLocation();
|
| - const Register result_div = pair->At(0).reg();
|
| - const Register result_mod = pair->At(1).reg();
|
| - Range* right_range = InputAt(1)->definition()->range();
|
| - if ((right_range == NULL) || right_range->Overlaps(0, 0)) {
|
| - // Handle divide by zero in runtime.
|
| - __ cmp(right, Operand(0));
|
| - __ b(deopt, EQ);
|
| - }
|
| - const Register temp = locs()->temp(0).reg();
|
| - const DRegister dtemp = EvenDRegisterOf(locs()->temp(1).fpu_reg());
|
| - __ SmiUntag(temp, left);
|
| - __ SmiUntag(IP, right);
|
| - __ IntegerDivide(result_div, temp, IP, dtemp, DTMP);
|
| +void TruncDivModInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| + ASSERT(CanDeoptimize());
|
| + Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinarySmiOp);
|
|
|
| - // Check the corner case of dividing the 'MIN_SMI' with -1, in which
|
| - // case we cannot tag the result.
|
| - __ CompareImmediate(result_div, 0x40000000);
|
| - __ b(deopt, EQ);
|
| - __ SmiUntag(IP, right);
|
| - // result_mod <- left - right * result_div.
|
| - __ mls(result_mod, IP, result_div, temp);
|
| - __ SmiTag(result_div);
|
| - __ SmiTag(result_mod);
|
| - // Correct MOD result:
|
| - // res = left % right;
|
| - // if (res < 0) {
|
| - // if (right < 0) {
|
| - // res = res - right;
|
| - // } else {
|
| - // res = res + right;
|
| - // }
|
| - // }
|
| - Label done;
|
| - __ cmp(result_mod, Operand(0));
|
| - __ b(&done, GE);
|
| - // Result is negative, adjust it.
|
| + ASSERT(TargetCPUFeatures::can_divide());
|
| + const Register left = locs()->in(0).reg();
|
| + const Register right = locs()->in(1).reg();
|
| + ASSERT(locs()->out(0).IsPairLocation());
|
| + PairLocation* pair = locs()->out(0).AsPairLocation();
|
| + const Register result_div = pair->At(0).reg();
|
| + const Register result_mod = pair->At(1).reg();
|
| + if (RangeUtils::CanBeZero(divisor_range())) {
|
| + // Handle divide by zero in runtime.
|
| __ cmp(right, Operand(0));
|
| - __ sub(result_mod, result_mod, Operand(right), LT);
|
| - __ add(result_mod, result_mod, Operand(right), GE);
|
| - __ Bind(&done);
|
| -
|
| - return;
|
| + __ b(deopt, EQ);
|
| }
|
| - UNIMPLEMENTED();
|
| + const Register temp = locs()->temp(0).reg();
|
| + const DRegister dtemp = EvenDRegisterOf(locs()->temp(1).fpu_reg());
|
| + __ SmiUntag(temp, left);
|
| + __ SmiUntag(IP, right);
|
| + __ IntegerDivide(result_div, temp, IP, dtemp, DTMP);
|
| +
|
| + // Check the corner case of dividing the 'MIN_SMI' with -1, in which
|
| + // case we cannot tag the result.
|
| + __ CompareImmediate(result_div, 0x40000000);
|
| + __ b(deopt, EQ);
|
| + __ SmiUntag(IP, right);
|
| + // result_mod <- left - right * result_div.
|
| + __ mls(result_mod, IP, result_div, temp);
|
| + __ SmiTag(result_div);
|
| + __ SmiTag(result_mod);
|
| + // Correct MOD result:
|
| + // res = left % right;
|
| + // if (res < 0) {
|
| + // if (right < 0) {
|
| + // res = res - right;
|
| + // } else {
|
| + // res = res + right;
|
| + // }
|
| + // }
|
| + Label done;
|
| + __ cmp(result_mod, Operand(0));
|
| + __ b(&done, GE);
|
| + // Result is negative, adjust it.
|
| + __ cmp(right, Operand(0));
|
| + __ sub(result_mod, result_mod, Operand(right), LT);
|
| + __ add(result_mod, result_mod, Operand(right), GE);
|
| + __ Bind(&done);
|
| }
|
|
|
|
|
| @@ -6633,14 +6618,6 @@ LocationSummary* ShiftMintOpInstr::MakeLocationSummary(Zone* zone,
|
| }
|
|
|
|
|
| -static const intptr_t kMintShiftCountLimit = 63;
|
| -
|
| -bool ShiftMintOpInstr::has_shift_count_check() const {
|
| - return !RangeUtils::IsWithin(right()->definition()->range(), 0,
|
| - kMintShiftCountLimit);
|
| -}
|
| -
|
| -
|
| void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| PairLocation* left_pair = locs()->in(0).AsPairLocation();
|
| Register left_lo = left_pair->At(0).reg();
|
|
|