Chromium Code Reviews| Index: runtime/vm/intermediate_language_ia32.cc |
| =================================================================== |
| --- runtime/vm/intermediate_language_ia32.cc (revision 8998) |
| +++ runtime/vm/intermediate_language_ia32.cc (working copy) |
| @@ -1407,9 +1407,11 @@ |
| summary->set_temp(0, Location::RequiresRegister()); |
| return summary; |
| } else if (op_kind() == Token::kSHL) { |
| + // Two Smi operands can easily overflow into Mint. |
| const intptr_t kNumTemps = 2; |
| - LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); |
| - summary->set_in(0, Location::RequiresRegister()); |
| + LocationSummary* summary = |
| + new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| + summary->set_in(0, Location::RegisterLocation(EAX)); |
| summary->set_in(1, Location::RequiresRegister()); |
| summary->set_out(Location::SameAsFirstInput()); |
| summary->set_temp(0, Location::RequiresRegister()); |
| @@ -1519,10 +1521,11 @@ |
| break; |
| } |
| case Token::kSHL: { |
| + Label call_method, done; |
| // Check if count too large for handling it inlined. |
| __ cmpl(right, |
| Immediate(reinterpret_cast<int64_t>(Smi::New(Smi::kBits)))); |
| - __ j(ABOVE_EQUAL, deopt); |
| + __ j(ABOVE_EQUAL, &call_method, Assembler::kNearJump); |
| Register right_temp = comp->locs()->temp(1).reg(); |
| ASSERT(right_temp == ECX); // Count must be in ECX |
| __ movl(right_temp, right); |
| @@ -1531,9 +1534,27 @@ |
| __ shll(left, right_temp); |
| __ sarl(left, right_temp); |
| __ cmpl(left, temp); |
| - __ j(NOT_EQUAL, deopt); // Overflow. |
| + __ j(NOT_EQUAL, &call_method, Assembler::kNearJump); // Overflow. |
| // Shift for result now we know there is no overflow. |
| __ shll(left, right_temp); |
| + __ jmp(&done); |
| + { |
| + __ Bind(&call_method); |
| + Function& target = Function::ZoneHandle( |
| + comp->ic_data()->GetTargetForReceiverClassId(kSmi)); |
| + ASSERT(!target.IsNull()); |
| + const intptr_t kArgumentCount = 2; |
| + __ pushl(left); |
| + __ pushl(right); |
| + compiler->GenerateStaticCall(comp->instance_call()->cid(), |
| + comp->instance_call()->token_index(), |
| + comp->instance_call()->try_index(), |
| + target, |
| + kArgumentCount, |
| + Array::Handle()); // No argument names. |
| + ASSERT(result == EAX); |
| + } |
| + __ Bind(&done); |
| break; |
| } |
| case Token::kDIV: { |
| @@ -1741,7 +1762,7 @@ |
| Label* deopt = compiler->AddDeoptStub(instance_call()->cid(), |
| instance_call()->token_index(), |
| instance_call()->try_index(), |
| - kDeoptSmiBinaryOp, |
| + kDeoptUnaryOp, |
|
regis
2012/06/21 22:43:57
This is also wrong on the x64 side.
srdjan
2012/06/21 22:56:36
Done.
|
| value); |
| if (test_class_id == kSmi) { |
| __ testl(value, Immediate(kSmiTagMask)); |
| @@ -1794,7 +1815,7 @@ |
| Label* deopt = compiler->AddDeoptStub(instance_call()->cid(), |
| instance_call()->token_index(), |
| instance_call()->try_index(), |
| - kDeoptSmiBinaryOp, |
| + kDeoptUnaryOp, |
|
regis
2012/06/21 22:43:57
This is also wrong on the x64 side.
srdjan
2012/06/21 22:56:36
Done.
|
| value); |
| if (test_class_id == kDouble) { |
| Register temp = locs()->temp(0).reg(); |