| Index: runtime/vm/intermediate_language_mips.cc
|
| ===================================================================
|
| --- runtime/vm/intermediate_language_mips.cc (revision 30543)
|
| +++ runtime/vm/intermediate_language_mips.cc (working copy)
|
| @@ -2479,6 +2479,7 @@
|
| }
|
|
|
| Register right = locs()->in(1).reg();
|
| + Range* right_range = this->right()->definition()->range();
|
| switch (op_kind()) {
|
| case Token::kADD: {
|
| if (deopt == NULL) {
|
| @@ -2528,8 +2529,10 @@
|
| break;
|
| }
|
| case Token::kTRUNCDIV: {
|
| - // Handle divide by zero in runtime.
|
| - __ beq(right, ZR, deopt);
|
| + if ((right_range == NULL) || right_range->IsWithin(0, 0)) {
|
| + // Handle divide by zero in runtime.
|
| + __ beq(right, ZR, deopt);
|
| + }
|
| Register temp = locs()->temp(0).reg();
|
| __ sra(temp, left, kSmiTagSize); // SmiUntag left into temp.
|
| __ sra(TMP, right, kSmiTagSize); // SmiUntag right into TMP.
|
| @@ -2542,8 +2545,10 @@
|
| break;
|
| }
|
| case Token::kMOD: {
|
| - // Handle divide by zero in runtime.
|
| - __ beq(right, ZR, deopt);
|
| + if ((right_range == NULL) || right_range->IsWithin(0, 0)) {
|
| + // Handle divide by zero in runtime.
|
| + __ beq(right, ZR, deopt);
|
| + }
|
| Register temp = locs()->temp(0).reg();
|
| __ sra(temp, left, kSmiTagSize); // SmiUntag left into temp.
|
| __ sra(TMP, right, kSmiTagSize); // SmiUntag right into TMP.
|
| @@ -2557,13 +2562,22 @@
|
| // res = res + right;
|
| // }
|
| // }
|
| - Label done, subtract;
|
| - __ bgez(result, &done);
|
| - __ bltz(right, &subtract);
|
| - __ addu(result, result, TMP);
|
| - __ b(&done);
|
| - __ Bind(&subtract);
|
| - __ subu(result, result, TMP);
|
| + Label done;
|
| + if ((right_range == NULL) || right_range->IsWithin(-1, 1)) {
|
| + Label subtract;
|
| + __ bgez(result, &done);
|
| + __ bltz(right, &subtract);
|
| + __ addu(result, result, TMP);
|
| + __ b(&done);
|
| + __ Bind(&subtract);
|
| + __ subu(result, result, TMP);
|
| + } else if (right_range->IsWithin(0, RangeBoundary::kPlusInfinity)) {
|
| + // Right is positive.
|
| + __ addu(result, result, TMP);
|
| + } else {
|
| + // Right is negative.
|
| + __ subu(result, result, TMP);
|
| + }
|
| __ Bind(&done);
|
| __ SmiTag(result);
|
| break;
|
| @@ -2576,7 +2590,6 @@
|
| __ sra(temp, right, kSmiTagSize); // SmiUntag right into temp.
|
| // sra 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)) {
|
| Label ok;
|
| @@ -3428,8 +3441,11 @@
|
| Register temp = locs()->temp(0).reg();
|
| Register result_div = locs()->temp(1).reg();
|
| Register result_mod = locs()->temp(2).reg();
|
| - // Handle divide by zero in runtime.
|
| - __ beq(right, ZR, deopt);
|
| + Range* right_range = InputAt(1)->definition()->range();
|
| + if ((right_range == NULL) || right_range->IsWithin(0, 0)) {
|
| + // Handle divide by zero in runtime.
|
| + __ beq(right, ZR, deopt);
|
| + }
|
| __ sra(temp, left, kSmiTagSize); // SmiUntag left into temp.
|
| __ sra(TMP, right, kSmiTagSize); // SmiUntag right into TMP.
|
| __ div(temp, TMP);
|
| @@ -3446,13 +3462,22 @@
|
| // res = res + right;
|
| // }
|
| // }
|
| - Label done, subtract;
|
| + Label done;
|
| __ bgez(result_mod, &done);
|
| - __ bltz(right, &subtract);
|
| - __ addu(result_mod, result_mod, TMP);
|
| - __ b(&done);
|
| - __ Bind(&subtract);
|
| - __ subu(result_mod, result_mod, TMP);
|
| + if ((right_range == NULL) || right_range->IsWithin(-1, 1)) {
|
| + Label subtract;
|
| + __ bltz(right, &subtract);
|
| + __ addu(result_mod, result_mod, TMP);
|
| + __ b(&done);
|
| + __ Bind(&subtract);
|
| + __ subu(result_mod, result_mod, TMP);
|
| + } else if (right_range->IsWithin(0, RangeBoundary::kPlusInfinity)) {
|
| + // Right is positive.
|
| + __ addu(result_mod, result_mod, TMP);
|
| + } else {
|
| + // Right is negative.
|
| + __ subu(result_mod, result_mod, TMP);
|
| + }
|
| __ Bind(&done);
|
|
|
| __ SmiTag(result_div);
|
|
|