| Index: bleeding_edge/src/ia32/codegen-ia32.cc
|
| ===================================================================
|
| --- bleeding_edge/src/ia32/codegen-ia32.cc (revision 3494)
|
| +++ bleeding_edge/src/ia32/codegen-ia32.cc (working copy)
|
| @@ -1731,9 +1731,42 @@
|
|
|
| case Token::SHL:
|
| if (reversed) {
|
| - Result constant_operand(value);
|
| - LikelySmiBinaryOperation(op, &constant_operand, operand,
|
| - overwrite_mode);
|
| + Result right;
|
| + Result right_copy_in_ecx;
|
| +
|
| + // Make sure to get a copy of the right operand into ecx. This
|
| + // allows us to modify it without having to restore it in the
|
| + // deferred code.
|
| + operand->ToRegister();
|
| + if (operand->reg().is(ecx)) {
|
| + right = allocator()->Allocate();
|
| + __ mov(right.reg(), ecx);
|
| + frame_->Spill(ecx);
|
| + right_copy_in_ecx = *operand;
|
| + } else {
|
| + right_copy_in_ecx = allocator()->Allocate(ecx);
|
| + __ mov(ecx, operand->reg());
|
| + right = *operand;
|
| + }
|
| + operand->Unuse();
|
| +
|
| + Result answer = allocator()->Allocate();
|
| + DeferredInlineSmiOperation* deferred =
|
| + new DeferredInlineSmiOperation(op,
|
| + answer.reg(),
|
| + right.reg(),
|
| + smi_value,
|
| + overwrite_mode);
|
| + __ mov(answer.reg(), Immediate(int_value));
|
| + __ sar(ecx, kSmiTagSize);
|
| + deferred->Branch(carry);
|
| + __ shl_cl(answer.reg());
|
| + __ cmp(answer.reg(), 0xc0000000);
|
| + deferred->Branch(sign);
|
| + __ SmiTag(answer.reg());
|
| +
|
| + deferred->BindExit();
|
| + frame_->Push(&answer);
|
| } else {
|
| // Only the least significant 5 bits of the shift value are used.
|
| // In the slow case, this masking is done inside the runtime call.
|
|
|