Chromium Code Reviews| Index: runtime/vm/intermediate_language_x64.cc |
| =================================================================== |
| --- runtime/vm/intermediate_language_x64.cc (revision 14704) |
| +++ runtime/vm/intermediate_language_x64.cc (working copy) |
| @@ -1612,15 +1612,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(RAX)); |
| - summary->set_in(1, Location::RegisterLocation(RDX)); |
| - summary->set_out(Location::RegisterLocation(RAX)); |
| - summary->set_temp(0, Location::RegisterLocation(RBX)); |
| - summary->set_temp(1, Location::RegisterLocation(RCX)); |
| + new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| + summary->set_in(0, Location::RequiresRegister()); |
| + summary->set_in(1, Location::FixedRegisterOrConstant(right(), RCX)); |
| + summary->set_temp(0, Location::RequiresRegister()); |
| + summary->set_out(Location::SameAsFirstInput()); |
| return summary; |
| } else { |
| const intptr_t kNumTemps = 0; |
| @@ -1697,6 +1695,26 @@ |
| __ SmiTag(left); |
| break; |
| } |
| + case Token::kSHL: { |
| + // shlq operation masks the count to 6 bits. |
| + const intptr_t kCountLimit = 0x3F; |
| + intptr_t value = Smi::Cast(constant).Value(); |
| + if (value == 0) break; |
| + if (value < 0 || value >= kCountLimit) { |
|
srdjan
2012/11/08 21:37:27
Same comments as from ia32.
Florian Schneider
2012/11/08 22:03:00
Done.
|
| + __ jmp(deopt); |
| + break; |
| + } |
| + Register temp = locs()->temp(0).reg(); |
| + __ movq(temp, left); |
| + __ shlq(left, Immediate(value)); |
| + __ sarq(left, Immediate(value)); |
| + __ cmpq(left, temp); |
| + __ j(NOT_EQUAL, deopt); // Overflow. |
| + // Shift for result now we know there is no overflow. |
| + __ shlq(left, Immediate(value)); |
| + break; |
| + } |
| + |
| default: |
| UNREACHABLE(); |
| break; |
| @@ -1780,7 +1798,6 @@ |
| } |
| case Token::kSHL: { |
| Register temp = locs()->temp(0).reg(); |
| - Label call_method, done; |
| // Check if count too large for handling it inlined. |
| __ movq(temp, left); |
| Range* right_range = this->right()->definition()->range(); |
| @@ -1789,38 +1806,17 @@ |
| if (right_needs_check) { |
| __ cmpq(right, |
| Immediate(reinterpret_cast<int64_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 == RCX); // Count must be in RCX |
| - __ movq(right_temp, right); |
| - __ SmiUntag(right_temp); |
| + ASSERT(right == RCX); // Count must be in RCX |
| + __ SmiUntag(right); |
| // Overflow test (preserve temp and right); |
| - __ shlq(left, right_temp); |
| - __ sarq(left, right_temp); |
| + __ shlq(left, right); |
| + __ sarq(left, right); |
| __ cmpq(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. |
| - __ shlq(left, right_temp); |
| - __ jmp(&done); |
| - { |
| - __ Bind(&call_method); |
| - Function& target = Function::ZoneHandle( |
| - ic_data()->GetTargetForReceiverClassId(kSmiCid)); |
| - ASSERT(!target.IsNull()); |
| - const intptr_t kArgumentCount = 2; |
| - __ pushq(temp); |
| - __ pushq(right); |
| - compiler->GenerateStaticCall( |
| - deopt_id(), |
| - instance_call()->token_pos(), |
| - target, |
| - kArgumentCount, |
| - Array::Handle(), // No argument names. |
| - locs()); |
| - ASSERT(result == RAX); |
| - } |
| - __ Bind(&done); |
| + __ shlq(left, right); |
| break; |
| } |
| case Token::kDIV: { |