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. |