Chromium Code Reviews| Index: runtime/vm/intermediate_language_ia32.cc |
| =================================================================== |
| --- runtime/vm/intermediate_language_ia32.cc (revision 14704) |
| +++ runtime/vm/intermediate_language_ia32.cc (working copy) |
| @@ -1732,15 +1732,13 @@ |
| summary->set_out(Location::SameAsFirstInput()); |
| return summary; |
| } else if (op_kind() == Token::kSHL) { |
| - // Two Smi operands can easily overflow into Mint. |
| - const intptr_t kNumTemps = 2; |
| + const intptr_t kNumTemps = 1; |
| LocationSummary* summary = |
| - new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| - summary->set_in(0, Location::RegisterLocation(EAX)); |
| - summary->set_in(1, Location::RegisterLocation(EDX)); |
| - summary->set_temp(0, Location::RegisterLocation(EBX)); |
| - summary->set_temp(1, Location::RegisterLocation(ECX)); |
| - summary->set_out(Location::RegisterLocation(EAX)); |
| + new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| + summary->set_in(0, Location::RequiresRegister()); |
| + summary->set_in(1, Location::FixedRegisterOrConstant(right(), ECX)); |
| + summary->set_temp(0, Location::RequiresRegister()); |
| + summary->set_out(Location::SameAsFirstInput()); |
| return summary; |
| } else { |
| const intptr_t kNumTemps = 0; |
| @@ -1822,6 +1820,25 @@ |
| __ SmiTag(left); |
| break; |
| } |
| + case Token::kSHL: { |
| + // shll operation masks the count to 5 bits. |
| + const intptr_t kCountLimit = 0x1F; |
| + intptr_t value = Smi::Cast(constant).Value(); |
| + if (value == 0) break; |
| + if (value < 0 || value >= kCountLimit) { |
|
srdjan
2012/11/08 21:37:27
Add parenthesis.
|
| + __ jmp(deopt); |
|
srdjan
2012/11/08 21:37:27
Make a note that this may not be known at instruct
Florian Schneider
2012/11/08 22:03:00
Done.
|
| + break; |
| + } |
| + Register temp = locs()->temp(0).reg(); |
| + __ movl(temp, left); |
| + __ shll(left, Immediate(value)); |
| + __ sarl(left, Immediate(value)); |
| + __ cmpl(left, temp); |
| + __ j(NOT_EQUAL, deopt); // Overflow. |
| + // Shift for result now we know there is no overflow. |
| + __ shll(left, Immediate(value)); |
| + break; |
| + } |
| default: |
| UNREACHABLE(); |
| @@ -1906,7 +1923,6 @@ |
| } |
| case Token::kSHL: { |
| Register temp = locs()->temp(0).reg(); |
| - Label call_method, done; |
| // Check if count too large for handling it inlined. |
| __ movl(temp, left); |
| Range* right_range = this->right()->definition()->range(); |
| @@ -1915,38 +1931,17 @@ |
| if (right_needs_check) { |
| __ cmpl(right, |
| Immediate(reinterpret_cast<int32_t>(Smi::New(Smi::kBits)))); |
| - __ j(ABOVE_EQUAL, &call_method, Assembler::kNearJump); |
| + __ j(ABOVE_EQUAL, deopt); |
| } |
| - Register right_temp = locs()->temp(1).reg(); |
| - ASSERT(right_temp == ECX); // Count must be in ECX |
| - __ movl(right_temp, right); |
| - __ SmiUntag(right_temp); |
| + ASSERT(right == ECX); // Count must be in ECX |
| + __ SmiUntag(right); |
| // Overflow test (preserve temp and right); |
| - __ shll(left, right_temp); |
| - __ sarl(left, right_temp); |
| + __ shll(left, right); |
| + __ sarl(left, right); |
| __ cmpl(left, temp); |
| - __ j(NOT_EQUAL, &call_method, Assembler::kNearJump); // Overflow. |
| + __ j(NOT_EQUAL, deopt); // Overflow. |
| // Shift for result now we know there is no overflow. |
| - __ shll(left, right_temp); |
| - __ jmp(&done); |
| - { |
| - __ Bind(&call_method); |
| - Function& target = Function::ZoneHandle( |
| - ic_data()->GetTargetForReceiverClassId(kSmiCid)); |
| - ASSERT(!target.IsNull()); |
| - const intptr_t kArgumentCount = 2; |
| - __ pushl(temp); |
| - __ pushl(right); |
| - compiler->GenerateStaticCall( |
| - deopt_id(), |
| - instance_call()->token_pos(), |
| - target, |
| - kArgumentCount, |
| - Array::Handle(), // No argument names. |
| - locs()); |
| - ASSERT(result == EAX); |
| - } |
| - __ Bind(&done); |
| + __ shll(left, right); |
| break; |
| } |
| case Token::kDIV: { |