| 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();
|
|
|