Revision: 4927
Author: whe...@chromium.org
Date: Wed Jun 23 02:21:32 2010
Log: Use SSE2 registers when comparing identical heap numbers on X64.
Review URL: http://codereview.chromium.org/2850018
http://code.google.com/p/v8/source/detail?r=4927

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

=======================================
--- /branches/bleeding_edge/src/x64/codegen-x64.cc      Mon Jun 21 05:39:37 2010
+++ /branches/bleeding_edge/src/x64/codegen-x64.cc      Wed Jun 23 02:21:32 2010
@@ -8951,48 +8951,31 @@
     // Test for NaN. Sadly, we can't just compare to Factory::nan_value(),
     // so we do the second best thing - test it ourselves.
     // Note: if cc_ != equal, never_nan_nan_ is not used.
+    __ Set(rax, EQUAL);
     if (never_nan_nan_ && (cc_ == equal)) {
-      __ Set(rax, EQUAL);
       __ ret(0);
     } else {
-      Label return_equal;
       Label heap_number;
       // If it's not a heap number, then return equal.
       __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset),
              Factory::heap_number_map());
       __ j(equal, &heap_number);
-      __ bind(&return_equal);
-      __ Set(rax, EQUAL);
       __ ret(0);

       __ bind(&heap_number);
-      // It is a heap number, so return non-equal if it's NaN and equal if
-      // it's not NaN.
- // The representation of NaN values has all exponent bits (52..62) set,
-      // and not all mantissa bits (0..51) clear.
-      // We only allow QNaNs, which have bit 51 set (which also rules out
-      // the value being Infinity).
-
-      // Value is a QNaN if value & kQuietNaNMask == kQuietNaNMask, i.e.,
-      // all bits in the mask are set. We only need to check the word
-      // that contains the exponent and high bit of the mantissa.
-      ASSERT_NE(0, (kQuietNaNHighBitsMask << 1) & 0x80000000u);
-      __ movl(rdx, FieldOperand(rdx, HeapNumber::kExponentOffset));
-      __ xorl(rax, rax);
- __ addl(rdx, rdx); // Shift value and mask so mask applies to top bits.
-      __ cmpl(rdx, Immediate(kQuietNaNHighBitsMask << 1));
-      if (cc_ == equal) {
-        __ setcc(above_equal, rax);
-        __ ret(0);
-      } else {
-        Label nan;
-        __ j(above_equal, &nan);
-        __ Set(rax, EQUAL);
-        __ ret(0);
-        __ bind(&nan);
-        __ Set(rax, NegativeComparisonResult(cc_));
-        __ ret(0);
-      }
+      // It is a heap number, so return  equal if it's not NaN.
+      // For NaN, return 1 for every condition except greater and
+      // greater-equal.  Return -1 for them, so the comparison yields
+      // false for all conditions except not-equal.
+
+      __ movsd(xmm0, FieldOperand(rdx, HeapNumber::kValueOffset));
+      __ ucomisd(xmm0, xmm0);
+      __ setcc(parity_even, rax);
+      // rax is 0 for equal non-NaN heapnumbers, 1 for NaNs.
+      if (cc_ == greater_equal || cc_ == greater) {
+        __ neg(rax);
+      }
+      __ ret(0);
     }

     __ bind(&not_identical);

--
v8-dev mailing list
v8-dev@googlegroups.com
http://groups.google.com/group/v8-dev

Reply via email to