Revision: 2808
Author: [email protected]
Date: Wed Sep  2 00:49:53 2009
Log: X64: Added missing optimization of unary negate.

Review URL: http://codereview.chromium.org/174214

http://code.google.com/p/v8/source/detail?r=2808

Modified:
  /branches/bleeding_edge/src/x64/codegen-x64.cc

=======================================
--- /branches/bleeding_edge/src/x64/codegen-x64.cc      Tue Sep  1 04:32:20 2009
+++ /branches/bleeding_edge/src/x64/codegen-x64.cc      Wed Sep  2 00:49:53 2009
@@ -6386,7 +6386,7 @@
          if (answer >= Smi::kMinValue && answer <= Smi::kMaxValue) {
            // If the product is zero and the non-zero factor is negative,
            // the spec requires us to return floating point negative zero.
-          if (answer != 0 || (left >= 0 && right >= 0)) {
+          if (answer != 0 || (left + right) >= 0) {
              answer_object = Smi::FromInt(static_cast<int>(answer));
            }
          }
@@ -6454,24 +6454,54 @@
  void UnarySubStub::Generate(MacroAssembler* masm) {
    Label slow;
    Label done;
-
+  Label try_float;
+  Label special;
    // Check whether the value is a smi.
    __ testl(rax, Immediate(kSmiTagMask));
-  // TODO(X64): Add inline code that handles floats, as on ia32 platform.
-  __ j(not_zero, &slow);
+  __ j(not_zero, &try_float);
+
    // Enter runtime system if the value of the smi is zero
    // to make sure that we switch between 0 and -0.
    // Also enter it if the value of the smi is Smi::kMinValue
    __ testl(rax, Immediate(0x7FFFFFFE));
-  __ j(zero, &slow);
+  __ j(zero, &special);
    __ neg(rax);
    __ jmp(&done);
+
+  __ bind(&special);
+  // Either zero or -0x4000000, neither of which become a smi when negated.
+  __ testl(rax, rax);
+  __ j(not_zero, &slow);
+  __ Move(rax, Factory::minus_zero_value());
+  __ jmp(&done);
+
    // Enter runtime system.
    __ bind(&slow);
    __ pop(rcx);  // pop return address
    __ push(rax);
    __ push(rcx);  // push return address
    __ InvokeBuiltin(Builtins::UNARY_MINUS, JUMP_FUNCTION);
+  __ jmp(&done);
+
+  // Try floating point case.
+  __ bind(&try_float);
+  __ movq(rdx, FieldOperand(rax, HeapObject::kMapOffset));
+  __ Cmp(rdx, Factory::heap_number_map());
+  __ j(not_equal, &slow);
+  // Operand is a float, negate its value by flipping sign bit.
+  __ movq(rdx, FieldOperand(rax, HeapNumber::kValueOffset));
+  __ movq(kScratchRegister, Immediate(0x01));
+  __ shl(kScratchRegister, Immediate(63));
+  __ xor_(rdx, kScratchRegister);  // Flip sign.
+  // rdx is value to store.
+  if (overwrite_) {
+    __ movq(FieldOperand(rax, HeapNumber::kValueOffset), rdx);
+  } else {
+    FloatingPointHelper::AllocateHeapNumber(masm, &slow, rbx, rcx);
+    // rcx: allocated 'empty' number
+    __ movq(FieldOperand(rcx, HeapNumber::kValueOffset), rdx);
+    __ movq(rax, rcx);
+  }

    __ bind(&done);
    __ StubReturn(1);

--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---

Reply via email to