Index: runtime/vm/intermediate_language_arm64.cc |
diff --git a/runtime/vm/intermediate_language_arm64.cc b/runtime/vm/intermediate_language_arm64.cc |
index 5c5b274c139ff753038701f99c2aebe58a99b04c..b7eac29cb8608bae0e3724c6970c66074a276dff 100644 |
--- a/runtime/vm/intermediate_language_arm64.cc |
+++ b/runtime/vm/intermediate_language_arm64.cc |
@@ -2795,7 +2795,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. |
@@ -2826,9 +2826,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()); |
__ CompareRegisters(right, ZR); |
__ b(deopt, MI); |
@@ -3278,7 +3276,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) { |
@@ -3327,7 +3324,7 @@ void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
break; |
} |
case Token::kTRUNCDIV: { |
- if ((right_range == NULL) || right_range->Overlaps(0, 0)) { |
+ if (RangeUtils::CanBeZero(right_range())) { |
// Handle divide by zero in runtime. |
__ CompareRegisters(right, ZR); |
__ b(deopt, EQ); |
@@ -3346,7 +3343,7 @@ void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
break; |
} |
case Token::kMOD: { |
- if ((right_range == NULL) || right_range->Overlaps(0, 0)) { |
+ if (RangeUtils::CanBeZero(right_range())) { |
// Handle divide by zero in runtime. |
__ CompareRegisters(right, ZR); |
__ b(deopt, EQ); |
@@ -3387,8 +3384,7 @@ void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
__ SmiUntag(TMP, right); |
// sarl operation masks the count to 6 bits. |
const intptr_t kCountLimit = 0x3F; |
- if ((right_range == NULL) || |
- !right_range->OnlyLessThanOrEqualTo(kCountLimit)) { |
+ if (!RangeUtils::OnlyLessThanOrEqualTo(right_range(), kCountLimit)) { |
__ LoadImmediate(TMP2, kCountLimit); |
__ CompareRegisters(TMP, TMP2); |
__ csel(TMP, TMP2, TMP, GT); |
@@ -5382,78 +5378,67 @@ 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 = 0; |
- LocationSummary* summary = new (zone) |
- LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
- summary->set_in(0, Location::RequiresRegister()); |
- summary->set_in(1, Location::RequiresRegister()); |
- // 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 = 0; |
+ LocationSummary* summary = new (zone) |
+ LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
+ summary->set_in(0, Location::RequiresRegister()); |
+ summary->set_in(1, Location::RequiresRegister()); |
+ // 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); |
+void TruncDivModInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
+ ASSERT(CanDeoptimize()); |
+ Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinarySmiOp); |
+ const Register left = locs()->in(0).reg(); |
+ const Register right = locs()->in(1).reg(); |
+ ASSERT(locs()->out(0).IsPairLocation()); |
+ const 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. |
+ __ CompareRegisters(right, ZR); |
+ __ b(deopt, EQ); |
} |
- if (kind() == MergedMathInstr::kTruncDivMod) { |
- const Register left = locs()->in(0).reg(); |
- const Register right = locs()->in(1).reg(); |
- ASSERT(locs()->out(0).IsPairLocation()); |
- const PairLocation* pair = locs()->out(0).AsPairLocation(); |
- const Register result_div = pair->At(0).reg(); |
- const Register result_mod = pair->At(1).reg(); |
- const Range* right_range = InputAt(1)->definition()->range(); |
- if ((right_range == NULL) || right_range->Overlaps(0, 0)) { |
- // Handle divide by zero in runtime. |
- __ CompareRegisters(right, ZR); |
- __ b(deopt, EQ); |
- } |
- __ SmiUntag(result_mod, left); |
- __ SmiUntag(TMP, right); |
+ __ SmiUntag(result_mod, left); |
+ __ SmiUntag(TMP, right); |
- __ sdiv(result_div, result_mod, TMP); |
+ __ sdiv(result_div, result_mod, TMP); |
- // Check the corner case of dividing the 'MIN_SMI' with -1, in which |
- // case we cannot tag the result. |
- __ CompareImmediate(result_div, 0x4000000000000000); |
- __ b(deopt, EQ); |
- // result_mod <- left - right * result_div. |
- __ msub(result_mod, TMP, result_div, result_mod); |
- __ 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; |
- __ CompareRegisters(result_mod, ZR); |
- __ b(&done, GE); |
- // Result is negative, adjust it. |
- __ CompareRegisters(right, ZR); |
- __ sub(TMP2, result_mod, Operand(right)); |
- __ add(TMP, result_mod, Operand(right)); |
- __ csel(result_mod, TMP, TMP2, GE); |
- __ Bind(&done); |
- return; |
- } |
- UNIMPLEMENTED(); |
+ // Check the corner case of dividing the 'MIN_SMI' with -1, in which |
+ // case we cannot tag the result. |
+ __ CompareImmediate(result_div, 0x4000000000000000); |
+ __ b(deopt, EQ); |
+ // result_mod <- left - right * result_div. |
+ __ msub(result_mod, TMP, result_div, result_mod); |
+ __ 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; |
+ __ CompareRegisters(result_mod, ZR); |
+ __ b(&done, GE); |
+ // Result is negative, adjust it. |
+ __ CompareRegisters(right, ZR); |
+ __ sub(TMP2, result_mod, Operand(right)); |
+ __ add(TMP, result_mod, Operand(right)); |
+ __ csel(result_mod, TMP, TMP2, GE); |
+ __ Bind(&done); |
} |
@@ -5732,12 +5717,6 @@ void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
} |
-bool ShiftMintOpInstr::has_shift_count_check() const { |
- UNREACHABLE(); |
- return false; |
-} |
- |
- |
LocationSummary* ShiftMintOpInstr::MakeLocationSummary(Zone* zone, |
bool opt) const { |
UNIMPLEMENTED(); |