Chromium Code Reviews| Index: src/x64/codegen-x64.cc |
| =================================================================== |
| --- src/x64/codegen-x64.cc (revision 2580) |
| +++ src/x64/codegen-x64.cc (working copy) |
| @@ -4851,10 +4851,8 @@ |
| 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; |
| @@ -4965,35 +4963,36 @@ |
| } |
| deferred->Branch(not_zero); |
| - if (!left_is_in_rax) __ movq(rax, left->reg()); |
| - // Sign extend rax into rdx:rax. |
| - __ cqo(); |
| + // All operations on the smi values are on 32-bit registers, which are |
| + // zero-extended into 64-bits by all 32-bit operations. |
| + if (!left_is_in_rax) __ movl(rax, left->reg()); |
| + // Sign extend eax into edx:eax. |
| + __ cdq(); |
| // Check for 0 divisor. |
| - __ testq(right->reg(), right->reg()); |
| + __ testl(right->reg(), right->reg()); |
| deferred->Branch(zero); |
| // Divide rdx:rax by the right operand. |
| - __ idiv(right->reg()); |
| + __ idivl(right->reg()); |
| // Complete the operation. |
| if (op == Token::DIV) { |
| // Check for negative zero result. If result is zero, and divisor |
| - // is negative, return a floating point negative zero. The |
| - // virtual frame is unchanged in this block, so local control flow |
| - // can use a Label rather than a JumpTarget. |
| + // is negative, return a floating point negative zero. The jump |
| + // to non_zero_result is safe w.r.t. the frame. |
| Label non_zero_result; |
| - __ testq(left->reg(), left->reg()); |
| + __ testl(left->reg(), left->reg()); |
| __ j(not_zero, &non_zero_result); |
| - __ testq(right->reg(), right->reg()); |
| + __ testl(right->reg(), right->reg()); |
| deferred->Branch(negative); |
| __ bind(&non_zero_result); |
| // Check for the corner case of dividing the most negative smi by |
| // -1. We cannot use the overflow flag, since it is not set by |
| // idiv instruction. |
| ASSERT(kSmiTag == 0 && kSmiTagSize == 1); |
| - __ cmpq(rax, Immediate(0x40000000)); |
| + __ cmpl(rax, Immediate(0x40000000)); |
| deferred->Branch(equal); |
| // Check that the remainder is zero. |
| - __ testq(rdx, rdx); |
| + __ testl(rdx, rdx); |
| deferred->Branch(not_zero); |
| // Tag the result and store it in the quotient register. |
| ASSERT(kSmiTagSize == times_2); // adjust code if not the case |
| @@ -5006,12 +5005,12 @@ |
| ASSERT(op == Token::MOD); |
| // Check for a negative zero result. If the result is zero, and |
| // the dividend is negative, return a floating point negative |
| - // zero. The frame is unchanged in this block, so local control |
| - // flow can use a Label rather than a JumpTarget. |
| + // zero. The frame is unchanged between the jump to &non_zero_result |
| + // and the target, so a Label can be used. |
|
Kevin Millikin (Chromium)
2009/07/30 07:52:05
To me this is less precise than what was before.
|
| Label non_zero_result; |
| - __ testq(rdx, rdx); |
| + __ testl(rdx, rdx); |
| __ j(not_zero, &non_zero_result); |
| - __ testq(left->reg(), left->reg()); |
| + __ testl(left->reg(), left->reg()); |
| deferred->Branch(negative); |
| __ bind(&non_zero_result); |
| deferred->BindExit(); |
| @@ -5056,9 +5055,9 @@ |
| deferred->Branch(not_zero); |
| // Untag both operands. |
| - __ movq(answer.reg(), left->reg()); |
| - __ sar(answer.reg(), Immediate(kSmiTagSize)); |
| - __ sar(rcx, Immediate(kSmiTagSize)); |
| + __ movl(answer.reg(), left->reg()); |
| + __ sarl(answer.reg(), Immediate(kSmiTagSize)); |
| + __ sarl(rcx, Immediate(kSmiTagSize)); |
| // Perform the operation. |
| switch (op) { |
| case Token::SAR: |
| @@ -5164,7 +5163,7 @@ |
| // in this block, so local control flow can use a Label rather |
| // than a JumpTarget. |
| Label non_zero_result; |
| - __ testq(answer.reg(), answer.reg()); |
| + __ testl(answer.reg(), answer.reg()); |
| __ j(not_zero, &non_zero_result); |
| __ movq(answer.reg(), left->reg()); |
| __ or_(answer.reg(), right->reg()); |
| @@ -6564,7 +6563,7 @@ |
| // Smi check both operands. |
| __ movq(rcx, rbx); |
| - __ or_(rcx, rax); |
| + __ or_(rcx, rax); // The value in ecx is used for negative zero test later. |
| __ testl(rcx, Immediate(kSmiTagMask)); |
| __ j(not_zero, slow); |
| @@ -6572,14 +6571,12 @@ |
| 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); |
| __ j(overflow, slow); // The slow case rereads operands from the stack. |
| - __ movsxlq(rax, rax); // Sign extend eax into rax. |
| break; |
| } |
| @@ -6593,21 +6590,19 @@ |
| // Go slow on overflows. |
| __ j(overflow, slow); |
| // Check for negative zero result. |
| - __ movsxlq(rax, rax); // Sign extend eax into rax. |
| - __ NegativeZeroTest(rax, rcx, slow); // use rcx = x | y |
| + __ NegativeZeroTest(rax, rcx, slow); // ecx (not rcx) holds x | y. |
| break; |
| case Token::DIV: |
| - // Sign extend rax into rdx:rax |
| - // (also sign extends eax into edx if eax is Smi). |
| - __ cqo(); |
| + // Sign extend eax into edx:eax. |
| + __ cdq(); |
| // Check for 0 divisor. |
| - __ testq(rbx, rbx); |
| + __ testl(rbx, rbx); |
| __ j(zero, slow); |
| - // Divide rdx:rax by rbx (where rdx:rax is equivalent to the smi in eax). |
| - __ idiv(rbx); |
| + // Divide edx:eax by ebx (where edx:eax is equivalent to the smi in eax). |
| + __ idivl(rbx); |
| // Check that the remainder is zero. |
| - __ testq(rdx, rdx); |
| + __ testl(rdx, rdx); |
| __ j(not_zero, slow); |
| // Check for the corner case of dividing the most negative smi |
| // by -1. We cannot use the overflow flag, since it is not set |
| @@ -6615,28 +6610,27 @@ |
| ASSERT(kSmiTag == 0 && kSmiTagSize == 1); |
| // TODO(X64): TODO(Smi): Smi implementation dependent constant. |
| // Value is Smi::fromInt(-(1<<31)) / Smi::fromInt(-1) |
| - __ cmpq(rax, Immediate(0x40000000)); |
| + __ cmpl(rax, Immediate(0x40000000)); |
| __ j(equal, slow); |
| // Check for negative zero result. |
| - __ NegativeZeroTest(rax, rcx, slow); // use ecx = x | y |
| + __ NegativeZeroTest(rax, rcx, slow); // ecx (not rcx) holds x | y. |
| // Tag the result and store it in register rax. |
| ASSERT(kSmiTagSize == times_2); // adjust code if not the case |
| __ lea(rax, Operand(rax, rax, times_1, kSmiTag)); |
| break; |
| case Token::MOD: |
| - // Sign extend rax into rdx:rax |
| - // (also sign extends eax into edx if eax is Smi). |
| - __ cqo(); |
| + // Sign extend eax into edx:eax |
| + __ cdq(); |
| // Check for 0 divisor. |
| - __ testq(rbx, rbx); |
| + __ testl(rbx, rbx); |
| __ j(zero, slow); |
| - // Divide rdx:rax by rbx. |
| - __ idiv(rbx); |
| + // Divide edx:eax by ebx. |
| + __ idivl(rbx); |
| // Check for negative zero result. |
| - __ NegativeZeroTest(rdx, rcx, slow); // use ecx = x | y |
| + __ NegativeZeroTest(rdx, rcx, slow); // ecx (not rcx) holds x | y. |
| // Move remainder to register rax. |
| - __ movq(rax, rdx); |
| + __ movl(rax, rdx); |
| break; |
| case Token::BIT_OR: |
| @@ -6656,7 +6650,7 @@ |
| case Token::SHR: |
| case Token::SAR: |
| // Move the second operand into register ecx. |
| - __ movq(rcx, rbx); |
| + __ movl(rcx, rbx); |
| // Remove tags from operands (but keep sign). |
| __ sarl(rax, Immediate(kSmiTagSize)); |
| __ sarl(rcx, Immediate(kSmiTagSize)); |