Reviewers: William Hesse,

Message:
Smallish review.

Description:
X64: Added missing optimization of unary negate.

Please review this at http://codereview.chromium.org/174214

Affected files:
   M src/x64/codegen-x64.cc


Index: src/x64/codegen-x64.cc
diff --git a/src/x64/codegen-x64.cc b/src/x64/codegen-x64.cc
index  
462b9600eed66b337b6f388d051ab98ebbe50974..f271860961a42be68ef471bed3b8d9874bd9e140
  
100644
--- a/src/x64/codegen-x64.cc
+++ b/src/x64/codegen-x64.cc
@@ -6217,7 +6217,7 @@ bool CodeGenerator::FoldConstantSmis(Token::Value op,  
int left, int right) {
          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));
            }
          }
@@ -6285,24 +6285,54 @@ bool CodeGenerator::FoldConstantSmis(Token::Value  
op, int left, int right) {
  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