Chromium Code Reviews| Index: runtime/vm/intermediate_language_ia32.cc |
| =================================================================== |
| --- runtime/vm/intermediate_language_ia32.cc (revision 30543) |
| +++ runtime/vm/intermediate_language_ia32.cc (working copy) |
| @@ -2420,6 +2420,7 @@ |
| // if locs()->in(1).IsRegister. |
| Register right = locs()->in(1).reg(); |
| + Range* right_range = this->right()->definition()->range(); |
| switch (op_kind()) { |
| case Token::kADD: { |
| __ addl(left, right); |
| @@ -2453,9 +2454,11 @@ |
| break; |
| } |
| case Token::kTRUNCDIV: { |
| - // Handle divide by zero in runtime. |
| - __ testl(right, right); |
| - __ j(ZERO, deopt); |
| + if ((right_range == NULL) || right_range->IsWithin(0, 0)) { |
|
Florian Schneider
2013/11/22 15:17:11
Please also make sure that there is test coverage
srdjan
2013/11/22 22:08:17
Added test coverage, added Range::Overlaps functio
|
| + // Handle divide by zero in runtime. |
| + __ testl(right, right); |
| + __ j(ZERO, deopt); |
| + } |
| ASSERT(left == EAX); |
| ASSERT((right != EDX) && (right != EAX)); |
| ASSERT(locs()->temp(0).reg() == EDX); |
| @@ -2472,9 +2475,11 @@ |
| break; |
| } |
| case Token::kMOD: { |
| - // Handle divide by zero in runtime. |
| - __ testl(right, right); |
| - __ j(ZERO, deopt); |
| + if ((right_range == NULL) || right_range->IsWithin(0, 0)) { |
| + // Handle divide by zero in runtime. |
| + __ testl(right, right); |
| + __ j(ZERO, deopt); |
| + } |
|
Florian Schneider
2013/11/22 15:17:11
In the case that the instruction can't deoptimize
srdjan
2013/11/22 22:08:17
Changed BinarySmiOperation::CanDeoptimize.
|
| ASSERT(left == EDX); |
| ASSERT((right != EDX) && (right != EAX)); |
| ASSERT(locs()->temp(0).reg() == EAX); |
| @@ -2492,16 +2497,25 @@ |
| // res = res + right; |
| // } |
| // } |
| - Label subtract, done; |
| + Label done; |
| __ cmpl(result, Immediate(0)); |
| __ j(GREATER_EQUAL, &done, Assembler::kNearJump); |
| // Result is negative, adjust it. |
| - __ cmpl(right, Immediate(0)); |
| - __ j(LESS, &subtract, Assembler::kNearJump); |
| - __ addl(result, right); |
| - __ jmp(&done, Assembler::kNearJump); |
| - __ Bind(&subtract); |
| - __ subl(result, right); |
| + if ((right_range == NULL) || right_range->IsWithin(-1, 1)) { |
| + Label subtract; |
| + __ cmpl(right, Immediate(0)); |
| + __ j(LESS, &subtract, Assembler::kNearJump); |
| + __ addl(result, right); |
| + __ jmp(&done, Assembler::kNearJump); |
| + __ Bind(&subtract); |
| + __ subl(result, right); |
| + } else if (right_range->IsWithin(0, RangeBoundary::kPlusInfinity)) { |
| + // Right is positive. |
| + __ addl(result, right); |
| + } else { |
| + // Right is negative. |
| + __ subl(result, right); |
| + } |
| __ Bind(&done); |
| __ SmiTag(result); |
| break; |
| @@ -2514,7 +2528,6 @@ |
| __ SmiUntag(right); |
| // sarl operation masks the count to 5 bits. |
| const intptr_t kCountLimit = 0x1F; |
| - Range* right_range = this->right()->definition()->range(); |
| if ((right_range == NULL) || |
| !right_range->IsWithin(RangeBoundary::kMinusInfinity, kCountLimit)) { |
| __ cmpl(right, Immediate(kCountLimit)); |
| @@ -4007,9 +4020,12 @@ |
| Register left = locs()->in(0).reg(); |
| Register right = locs()->in(1).reg(); |
| Register result = locs()->out().reg(); |
| - // Handle divide by zero in runtime. |
| - __ testl(right, right); |
| - __ j(ZERO, deopt); |
| + Range* right_range = InputAt(1)->definition()->range(); |
| + if ((right_range == NULL) || right_range->IsWithin(0, 0)) { |
| + // Handle divide by zero in runtime. |
| + __ testl(right, right); |
| + __ j(ZERO, deopt); |
| + } |
| ASSERT(left == EAX); |
| ASSERT((right != EDX) && (right != EAX)); |
| ASSERT(locs()->temp(0).reg() == EDX); |
| @@ -4034,16 +4050,25 @@ |
| // res = res + right; |
| // } |
| // } |
| - Label subtract, done; |
| + Label done; |
| __ cmpl(EDX, Immediate(0)); |
| __ j(GREATER_EQUAL, &done, Assembler::kNearJump); |
| // Result is negative, adjust it. |
| - __ cmpl(right, Immediate(0)); |
| - __ j(LESS, &subtract, Assembler::kNearJump); |
| - __ addl(EDX, right); |
| - __ jmp(&done, Assembler::kNearJump); |
| - __ Bind(&subtract); |
| - __ subl(EDX, right); |
| + if ((right_range == NULL) || right_range->IsWithin(-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->IsWithin(0, RangeBoundary::kPlusInfinity)) { |
| + // Right is positive. |
| + __ addl(EDX, right); |
| + } else { |
| + // Right is negative. |
| + __ subl(EDX, right); |
| + } |
| __ Bind(&done); |
| __ LoadObject(result, Array::ZoneHandle(Array::New(2, Heap::kOld))); |