Index: runtime/vm/intermediate_language_ia32.cc |
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc |
index 967fb56d95a4b85d5e2db722ff141b9e0e2d0c5d..7f690f2e1139e1a99aef742acd5829e10f54ff58 100644 |
--- a/runtime/vm/intermediate_language_ia32.cc |
+++ b/runtime/vm/intermediate_language_ia32.cc |
@@ -2734,7 +2734,7 @@ static void EmitSmiShiftLeft(FlowGraphCompiler* compiler, |
// Right (locs.in(1)) is not constant. |
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 can_overflow(). |
// If left is constant, we know the maximal allowed size for right. |
@@ -2765,9 +2765,7 @@ static void EmitSmiShiftLeft(FlowGraphCompiler* compiler, |
ASSERT(right == ECX); // Count must be in ECX |
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()); |
__ cmpl(right, Immediate(0)); |
__ j(NEGATIVE, deopt); |
@@ -3043,7 +3041,6 @@ void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
// if locs()->in(1).IsRegister. |
Register right = locs()->in(1).reg(); |
- Range* right_range = this->right()->definition()->range(); |
switch (op_kind()) { |
case Token::kADD: |
case Token::kSUB: |
@@ -3059,7 +3056,7 @@ void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
case Token::kTRUNCDIV: { |
- if ((right_range == NULL) || right_range->Overlaps(0, 0)) { |
+ if (RangeUtils::CanBeZero(right_range())) { |
// Handle divide by zero in runtime. |
__ testl(right, right); |
__ j(ZERO, deopt); |
@@ -3080,7 +3077,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. |
__ testl(right, right); |
__ j(ZERO, deopt); |
@@ -3106,7 +3103,7 @@ void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
__ cmpl(result, Immediate(0)); |
__ j(GREATER_EQUAL, &done, Assembler::kNearJump); |
// Result is negative, adjust it. |
- if ((right_range == NULL) || right_range->Overlaps(-1, 1)) { |
+ if (RangeUtils::Overlaps(right_range(), -1, 1)) { |
// Right can be positive and negative. |
Label subtract; |
__ cmpl(right, Immediate(0)); |
@@ -3115,7 +3112,7 @@ void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
__ jmp(&done, Assembler::kNearJump); |
__ Bind(&subtract); |
__ subl(result, right); |
- } else if (right_range->IsPositive()) { |
+ } else if (right_range()->IsPositive()) { |
// Right is positive. |
__ addl(result, right); |
} else { |
@@ -3134,8 +3131,7 @@ void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
__ SmiUntag(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)) { |
__ cmpl(right, Immediate(kCountLimit)); |
Label count_ok; |
__ j(LESS, &count_ok, Assembler::kNearJump); |
@@ -5708,95 +5704,83 @@ 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); |
- // Both inputs must be writable because they will be untagged. |
- summary->set_in(0, Location::RegisterLocation(EAX)); |
- summary->set_in(1, Location::WritableRegister()); |
- // Output is a pair of registers. |
- summary->set_out(0, Location::Pair(Location::RegisterLocation(EAX), |
- Location::RegisterLocation(EDX))); |
- 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); |
+ // Both inputs must be writable because they will be untagged. |
+ summary->set_in(0, Location::RegisterLocation(EAX)); |
+ summary->set_in(1, Location::WritableRegister()); |
+ // Output is a pair of registers. |
+ summary->set_out(0, Location::Pair(Location::RegisterLocation(EAX), |
+ Location::RegisterLocation(EDX))); |
+ 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); |
+ Register left = locs()->in(0).reg(); |
+ Register right = locs()->in(1).reg(); |
+ ASSERT(locs()->out(0).IsPairLocation()); |
+ PairLocation* pair = locs()->out(0).AsPairLocation(); |
+ Register result1 = pair->At(0).reg(); |
+ Register result2 = pair->At(1).reg(); |
+ if (RangeUtils::CanBeZero(divisor_range())) { |
+ // Handle divide by zero in runtime. |
+ __ testl(right, right); |
+ __ j(ZERO, deopt); |
+ } |
+ ASSERT(left == EAX); |
+ ASSERT((right != EDX) && (right != EAX)); |
+ ASSERT(result1 == EAX); |
+ ASSERT(result2 == EDX); |
+ __ SmiUntag(left); |
+ __ SmiUntag(right); |
+ __ cdq(); // Sign extend EAX -> EDX:EAX. |
+ __ idivl(right); // EAX: quotient, EDX: remainder. |
+ // Check the corner case of dividing the 'MIN_SMI' with -1, in which |
+ // case we cannot tag the result. |
+ // TODO(srdjan): We could store instead untagged intermediate results in a |
+ // typed array, but then the load indexed instructions would need to be |
+ // able to deoptimize. |
+ __ cmpl(EAX, Immediate(0x40000000)); |
+ __ j(EQUAL, deopt); |
+ // Modulo result (EDX) correction: |
+ // res = left % right; |
+ // if (res < 0) { |
+ // if (right < 0) { |
+ // res = res - right; |
+ // } else { |
+ // res = res + right; |
+ // } |
+ // } |
+ Label done; |
+ __ cmpl(EDX, Immediate(0)); |
+ __ j(GREATER_EQUAL, &done, Assembler::kNearJump); |
+ // Result is negative, adjust it. |
+ if (RangeUtils::Overlaps(divisor_range(), -1, 1)) { |
+ Label subtract; |
+ __ cmpl(right, Immediate(0)); |
+ __ j(LESS, &subtract, Assembler::kNearJump); |
+ __ addl(EDX, right); |
+ __ jmp(&done, Assembler::kNearJump); |
+ __ Bind(&subtract); |
+ __ subl(EDX, right); |
+ } else if (divisor_range()->IsPositive()) { |
+ // Right is positive. |
+ __ addl(EDX, right); |
+ } else { |
+ // Right is negative. |
+ __ subl(EDX, right); |
} |
+ __ Bind(&done); |
- if (kind() == MergedMathInstr::kTruncDivMod) { |
- Register left = locs()->in(0).reg(); |
- Register right = locs()->in(1).reg(); |
- ASSERT(locs()->out(0).IsPairLocation()); |
- PairLocation* pair = locs()->out(0).AsPairLocation(); |
- Register result1 = pair->At(0).reg(); |
- Register result2 = 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. |
- __ testl(right, right); |
- __ j(ZERO, deopt); |
- } |
- ASSERT(left == EAX); |
- ASSERT((right != EDX) && (right != EAX)); |
- ASSERT(result1 == EAX); |
- ASSERT(result2 == EDX); |
- __ SmiUntag(left); |
- __ SmiUntag(right); |
- __ cdq(); // Sign extend EAX -> EDX:EAX. |
- __ idivl(right); // EAX: quotient, EDX: remainder. |
- // Check the corner case of dividing the 'MIN_SMI' with -1, in which |
- // case we cannot tag the result. |
- // TODO(srdjan): We could store instead untagged intermediate results in a |
- // typed array, but then the load indexed instructions would need to be |
- // able to deoptimize. |
- __ cmpl(EAX, Immediate(0x40000000)); |
- __ j(EQUAL, deopt); |
- // Modulo result (EDX) correction: |
- // res = left % right; |
- // if (res < 0) { |
- // if (right < 0) { |
- // res = res - right; |
- // } else { |
- // res = res + right; |
- // } |
- // } |
- Label done; |
- __ cmpl(EDX, Immediate(0)); |
- __ j(GREATER_EQUAL, &done, Assembler::kNearJump); |
- // Result is negative, adjust it. |
- if ((right_range == NULL) || right_range->Overlaps(-1, 1)) { |
- Label subtract; |
- __ cmpl(right, Immediate(0)); |
- __ j(LESS, &subtract, Assembler::kNearJump); |
- __ addl(EDX, right); |
- __ jmp(&done, Assembler::kNearJump); |
- __ Bind(&subtract); |
- __ subl(EDX, right); |
- } else if (right_range->IsPositive()) { |
- // Right is positive. |
- __ addl(EDX, right); |
- } else { |
- // Right is negative. |
- __ subl(EDX, right); |
- } |
- __ Bind(&done); |
- |
- __ SmiTag(EAX); |
- __ SmiTag(EDX); |
- return; |
- } |
- UNIMPLEMENTED(); |
+ __ SmiTag(EAX); |
+ __ SmiTag(EDX); |
} |
@@ -6157,14 +6141,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(); |