OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 8937 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8948 __ bind(&check_for_nan); | 8948 __ bind(&check_for_nan); |
8949 } | 8949 } |
8950 | 8950 |
8951 // Test for NaN. Sadly, we can't just compare to Factory::nan_value(), | 8951 // Test for NaN. Sadly, we can't just compare to Factory::nan_value(), |
8952 // so we do the second best thing - test it ourselves. | 8952 // so we do the second best thing - test it ourselves. |
8953 // Note: if cc_ != equal, never_nan_nan_ is not used. | 8953 // Note: if cc_ != equal, never_nan_nan_ is not used. |
8954 if (never_nan_nan_ && (cc_ == equal)) { | 8954 if (never_nan_nan_ && (cc_ == equal)) { |
8955 __ Set(rax, EQUAL); | 8955 __ Set(rax, EQUAL); |
8956 __ ret(0); | 8956 __ ret(0); |
8957 } else { | 8957 } else { |
8958 Label return_equal; | |
8959 Label heap_number; | 8958 Label heap_number; |
8960 // If it's not a heap number, then return equal. | 8959 // If it's not a heap number, then return equal. |
8961 __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset), | 8960 __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset), |
8962 Factory::heap_number_map()); | 8961 Factory::heap_number_map()); |
8963 __ j(equal, &heap_number); | 8962 __ j(equal, &heap_number); |
8964 __ bind(&return_equal); | |
8965 __ Set(rax, EQUAL); | 8963 __ Set(rax, EQUAL); |
8966 __ ret(0); | 8964 __ ret(0); |
8967 | 8965 |
8968 __ bind(&heap_number); | 8966 __ bind(&heap_number); |
8969 // It is a heap number, so return non-equal if it's NaN and equal if | 8967 // It is a heap number, so return equal if it's not NaN. |
8970 // it's not NaN. | 8968 // For NaN, return 1 for every condition except greater and |
8971 // The representation of NaN values has all exponent bits (52..62) set, | 8969 // greater-equal. Return -1 for them, so the comparison yields |
8972 // and not all mantissa bits (0..51) clear. | 8970 // false for all conditions except not-equal. |
8973 // We only allow QNaNs, which have bit 51 set (which also rules out | |
8974 // the value being Infinity). | |
8975 | 8971 |
8976 // Value is a QNaN if value & kQuietNaNMask == kQuietNaNMask, i.e., | 8972 __ movsd(xmm0, FieldOperand(rdx, HeapNumber::kValueOffset)); |
8977 // all bits in the mask are set. We only need to check the word | 8973 __ xorl(rax, rax); // Clear rax because setcc only modifies al. |
8978 // that contains the exponent and high bit of the mantissa. | 8974 __ ucomisd(xmm0, xmm0); |
8979 ASSERT_NE(0, (kQuietNaNHighBitsMask << 1) & 0x80000000u); | 8975 __ setcc(parity_even, rax); |
8980 __ movl(rdx, FieldOperand(rdx, HeapNumber::kExponentOffset)); | 8976 // rax is 0 for equal non-NaN heapnumbers, 1 for NaNs. |
8981 __ xorl(rax, rax); | 8977 if (cc_ == greater_equal || cc_ == greater) { |
8982 __ addl(rdx, rdx); // Shift value and mask so mask applies to top bits. | 8978 __ neg(rax); |
8983 __ cmpl(rdx, Immediate(kQuietNaNHighBitsMask << 1)); | |
8984 if (cc_ == equal) { | |
8985 __ setcc(above_equal, rax); | |
8986 __ ret(0); | |
8987 } else { | |
8988 Label nan; | |
8989 __ j(above_equal, &nan); | |
8990 __ Set(rax, EQUAL); | |
8991 __ ret(0); | |
8992 __ bind(&nan); | |
8993 __ Set(rax, NegativeComparisonResult(cc_)); | |
8994 __ ret(0); | |
8995 } | 8979 } |
| 8980 __ ret(0); |
8996 } | 8981 } |
8997 | 8982 |
8998 __ bind(¬_identical); | 8983 __ bind(¬_identical); |
8999 } | 8984 } |
9000 | 8985 |
9001 if (cc_ == equal) { // Both strict and non-strict. | 8986 if (cc_ == equal) { // Both strict and non-strict. |
9002 Label slow; // Fallthrough label. | 8987 Label slow; // Fallthrough label. |
9003 | 8988 |
9004 // If we're doing a strict equality comparison, we don't have to do | 8989 // If we're doing a strict equality comparison, we don't have to do |
9005 // type conversion, so we generate code to do fast comparison for objects | 8990 // type conversion, so we generate code to do fast comparison for objects |
(...skipping 2905 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11911 } | 11896 } |
11912 | 11897 |
11913 #endif | 11898 #endif |
11914 | 11899 |
11915 | 11900 |
11916 #undef __ | 11901 #undef __ |
11917 | 11902 |
11918 } } // namespace v8::internal | 11903 } } // namespace v8::internal |
11919 | 11904 |
11920 #endif // V8_TARGET_ARCH_X64 | 11905 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |