| Index: src/x64/codegen-x64.cc
|
| ===================================================================
|
| --- src/x64/codegen-x64.cc (revision 2337)
|
| +++ src/x64/codegen-x64.cc (working copy)
|
| @@ -4671,8 +4671,6 @@
|
|
|
|
|
| void DeferredInlineSmiAdd::Generate() {
|
| - // Undo the optimistic add operation and call the shared stub.
|
| - __ subq(dst_, Immediate(value_));
|
| __ push(dst_);
|
| __ push(Immediate(value_));
|
| GenericBinaryOpStub igostub(Token::ADD, overwrite_mode_, SMI_CODE_INLINED);
|
| @@ -4703,8 +4701,6 @@
|
|
|
|
|
| void DeferredInlineSmiAddReversed::Generate() {
|
| - // Undo the optimistic add operation and call the shared stub.
|
| - __ subq(dst_, Immediate(value_));
|
| __ push(Immediate(value_));
|
| __ push(dst_);
|
| GenericBinaryOpStub igostub(Token::ADD, overwrite_mode_, SMI_CODE_INLINED);
|
| @@ -4736,8 +4732,6 @@
|
|
|
|
|
| void DeferredInlineSmiSub::Generate() {
|
| - // Undo the optimistic sub operation and call the shared stub.
|
| - __ addq(dst_, Immediate(value_));
|
| __ push(dst_);
|
| __ push(Immediate(value_));
|
| GenericBinaryOpStub igostub(Token::SUB, overwrite_mode_, SMI_CODE_INLINED);
|
| @@ -4779,9 +4773,6 @@
|
| case Token::ADD: {
|
| operand->ToRegister();
|
| frame_->Spill(operand->reg());
|
| -
|
| - // Optimistically add. Call the specialized add stub if the
|
| - // result is not a smi or overflows.
|
| DeferredCode* deferred = NULL;
|
| if (reversed) {
|
| deferred = new DeferredInlineSmiAddReversed(operand->reg(),
|
| @@ -4792,11 +4783,17 @@
|
| smi_value,
|
| overwrite_mode);
|
| }
|
| - __ movq(kScratchRegister, value, RelocInfo::NONE);
|
| - __ addl(operand->reg(), kScratchRegister);
|
| - deferred->Branch(overflow);
|
| __ testl(operand->reg(), Immediate(kSmiTagMask));
|
| deferred->Branch(not_zero);
|
| + // A smi currently fits in a 32-bit Immediate.
|
| + __ addl(operand->reg(), Immediate(smi_value));
|
| + Label add_success;
|
| + __ j(no_overflow, &add_success);
|
| + __ subl(operand->reg(), Immediate(smi_value));
|
| + __ movsxlq(operand->reg(), operand->reg());
|
| + deferred->Jump();
|
| + __ bind(&add_success);
|
| + __ movsxlq(operand->reg(), operand->reg());
|
| deferred->BindExit();
|
| frame_->Push(operand);
|
| break;
|
| @@ -5082,12 +5079,12 @@
|
| __ movq(answer.reg(), left->reg());
|
| switch (op) {
|
| case Token::ADD:
|
| - __ addl(answer.reg(), right->reg()); // Add optimistically.
|
| + __ addl(answer.reg(), right->reg());
|
| deferred->Branch(overflow);
|
| break;
|
|
|
| case Token::SUB:
|
| - __ subl(answer.reg(), right->reg()); // Subtract optimistically.
|
| + __ subl(answer.reg(), right->reg());
|
| deferred->Branch(overflow);
|
| break;
|
|
|
| @@ -6500,50 +6497,27 @@
|
| // Perform fast-case smi code for the operation (rax <op> rbx) and
|
| // leave result in register rax.
|
|
|
| - // Prepare the smi check of both operands by or'ing them together
|
| - // before checking against the smi mask.
|
| + // Smi check both operands.
|
| __ movq(rcx, rbx);
|
| __ or_(rcx, rax);
|
| + __ testl(rcx, Immediate(kSmiTagMask));
|
| + __ j(not_zero, slow);
|
|
|
| switch (op_) {
|
| - case Token::ADD:
|
| - __ addl(rax, rbx); // add optimistically
|
| - __ j(overflow, slow);
|
| + case Token::ADD: {
|
| + __ addl(rax, rbx);
|
| + __ j(overflow, slow); // The slow case rereads operands from the stack.
|
| __ movsxlq(rax, rax); // Sign extend eax into rax.
|
| break;
|
| + }
|
|
|
| - case Token::SUB:
|
| - __ subl(rax, rbx); // subtract optimistically
|
| - __ j(overflow, slow);
|
| + case Token::SUB: {
|
| + __ subl(rax, rbx);
|
| + __ j(overflow, slow); // The slow case rereads operands from the stack.
|
| __ movsxlq(rax, rax); // Sign extend eax into rax.
|
| break;
|
| + }
|
|
|
| - case Token::DIV:
|
| - case Token::MOD:
|
| - // Sign extend rax into rdx:rax
|
| - // (also sign extends eax into edx if eax is Smi).
|
| - __ cqo();
|
| - // Check for 0 divisor.
|
| - __ testq(rbx, rbx);
|
| - __ j(zero, slow);
|
| - break;
|
| -
|
| - default:
|
| - // Fall-through to smi check.
|
| - break;
|
| - }
|
| -
|
| - // Perform the actual smi check.
|
| - ASSERT(kSmiTag == 0); // adjust zero check if not the case
|
| - __ testl(rcx, Immediate(kSmiTagMask));
|
| - __ j(not_zero, slow);
|
| -
|
| - switch (op_) {
|
| - case Token::ADD:
|
| - case Token::SUB:
|
| - // Do nothing here.
|
| - break;
|
| -
|
| case Token::MUL:
|
| // If the smi tag is 0 we can just leave the tag on one operand.
|
| ASSERT(kSmiTag == 0); // adjust code below if not the case
|
| @@ -6559,6 +6533,12 @@
|
| break;
|
|
|
| case Token::DIV:
|
| + // Sign extend rax into rdx:rax
|
| + // (also sign extends eax into edx if eax is Smi).
|
| + __ cqo();
|
| + // Check for 0 divisor.
|
| + __ testq(rbx, rbx);
|
| + __ j(zero, slow);
|
| // Divide rdx:rax by rbx (where rdx:rax is equivalent to the smi in eax).
|
| __ idiv(rbx);
|
| // Check that the remainder is zero.
|
| @@ -6580,6 +6560,12 @@
|
| break;
|
|
|
| case Token::MOD:
|
| + // Sign extend rax into rdx:rax
|
| + // (also sign extends eax into edx if eax is Smi).
|
| + __ cqo();
|
| + // Check for 0 divisor.
|
| + __ testq(rbx, rbx);
|
| + __ j(zero, slow);
|
| // Divide rdx:rax by rbx.
|
| __ idiv(rbx);
|
| // Check for negative zero result.
|
|
|