Revision: 2581 Author: [email protected] Date: Thu Jul 30 00:31:54 2009 Log: X64: Fix error in division & modulus, adjust mjsunit test status, fix lint error in objects.h Review URL: http://codereview.chromium.org/159584 http://code.google.com/p/v8/source/detail?r=2581
Modified: /branches/bleeding_edge/src/objects.h /branches/bleeding_edge/src/x64/assembler-x64.cc /branches/bleeding_edge/src/x64/assembler-x64.h /branches/bleeding_edge/src/x64/codegen-x64.cc /branches/bleeding_edge/src/x64/macro-assembler-x64.cc /branches/bleeding_edge/test/mjsunit/mjsunit.status ======================================= --- /branches/bleeding_edge/src/objects.h Wed Jul 29 05:34:21 2009 +++ /branches/bleeding_edge/src/objects.h Thu Jul 30 00:31:54 2009 @@ -2437,11 +2437,13 @@ }; -// PixelArray represents a fixed size byte array with special sematics used for -// implementing the CanvasPixelArray object. Please see the specification at: -// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#canvaspixelarray -// In particular write access clamps the values to 0 or 255 if the value -// used is outside this range. +// A PixelArray represents a fixed-size byte array with special semantics +// used for implementing the CanvasPixelArray object. Please see the +// specification at: +// http://www.whatwg.org/specs/web-apps/current-work/ +// multipage/the-canvas-element.html#canvaspixelarray +// In particular, write access clamps the value written to 0 or 255 if the +// value written is outside this range. class PixelArray: public Array { public: // [external_pointer]: The pointer to the external memory area backing this ======================================= --- /branches/bleeding_edge/src/x64/assembler-x64.cc Fri Jul 24 04:22:35 2009 +++ /branches/bleeding_edge/src/x64/assembler-x64.cc Thu Jul 30 00:31:54 2009 @@ -685,6 +685,13 @@ emit(0xFF); emit_operand(2, op); } + + +void Assembler::cdq() { + EnsureSpace ensure_space(this); + last_pc_ = pc_; + emit(0x99); +} void Assembler::cmovq(Condition cc, Register dst, Register src) { @@ -807,13 +814,22 @@ } -void Assembler::idiv(Register src) { +void Assembler::idivq(Register src) { EnsureSpace ensure_space(this); last_pc_ = pc_; emit_rex_64(src); emit(0xF7); emit_modrm(0x7, src); } + + +void Assembler::idivl(Register src) { + EnsureSpace ensure_space(this); + last_pc_ = pc_; + emit_optional_rex_32(src); + emit(0xF7); + emit_modrm(0x7, src); +} void Assembler::imul(Register src) { ======================================= --- /branches/bleeding_edge/src/x64/assembler-x64.h Fri Jul 24 04:22:35 2009 +++ /branches/bleeding_edge/src/x64/assembler-x64.h Thu Jul 30 00:31:54 2009 @@ -632,9 +632,13 @@ // Sign-extends rax into rdx:rax. void cqo(); + // Sign-extends eax into edx:eax. + void cdq(); // Divide rdx:rax by src. Quotient in rax, remainder in rdx. - void idiv(Register src); + void idivq(Register src); + // Divide edx:eax by lower 32 bits of src. Quotient in eax, rem. in edx. + void idivl(Register src); // Signed multiply instructions. void imul(Register src); // rdx:rax = rax * src. ======================================= --- /branches/bleeding_edge/src/x64/codegen-x64.cc Tue Jul 28 07:11:09 2009 +++ /branches/bleeding_edge/src/x64/codegen-x64.cc Thu Jul 30 00:31:54 2009 @@ -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. 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)); ======================================= --- /branches/bleeding_edge/src/x64/macro-assembler-x64.cc Mon Jul 27 03:39:21 2009 +++ /branches/bleeding_edge/src/x64/macro-assembler-x64.cc Thu Jul 30 00:31:54 2009 @@ -71,9 +71,9 @@ Register op, Label* then_label) { Label ok; - testq(result, result); + testl(result, result); j(not_zero, &ok); - testq(op, op); + testl(op, op); j(sign, then_label); bind(&ok); } ======================================= --- /branches/bleeding_edge/test/mjsunit/mjsunit.status Tue Jul 28 23:58:00 2009 +++ /branches/bleeding_edge/test/mjsunit/mjsunit.status Thu Jul 30 00:31:54 2009 @@ -97,14 +97,10 @@ debug-stepin-constructor: CRASH || FAIL debug-stepin-function-call: CRASH || FAIL debug-stepin-accessor: CRASH || FAIL -new: PASS || CRASH || FAIL fuzz-natives: PASS || TIMEOUT -greedy: PASS || TIMEOUT debug-handle: CRASH || FAIL debug-clearbreakpointgroup: CRASH || FAIL regress/regress-269: CRASH || FAIL -div-mod: CRASH || FAIL -unicode-test: PASS || TIMEOUT regress/regress-392: CRASH || FAIL regress/regress-1200351: CRASH || FAIL regress/regress-998565: CRASH || FAIL --~--~---------~--~----~------------~-------~--~----~ v8-dev mailing list [email protected] http://groups.google.com/group/v8-dev -~----------~----~----~----~------~----~------~--~---
