| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #if V8_TARGET_ARCH_X64 | 5 #if V8_TARGET_ARCH_X64 |
| 6 | 6 |
| 7 #include "src/crankshaft/x64/lithium-codegen-x64.h" | 7 #include "src/crankshaft/x64/lithium-codegen-x64.h" |
| 8 | 8 |
| 9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
| 10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
| (...skipping 1946 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1957 __ cmpp(left_reg, right_op); | 1957 __ cmpp(left_reg, right_op); |
| 1958 } else { | 1958 } else { |
| 1959 __ cmpl(left_reg, right_op); | 1959 __ cmpl(left_reg, right_op); |
| 1960 } | 1960 } |
| 1961 __ j(condition, &return_left, Label::kNear); | 1961 __ j(condition, &return_left, Label::kNear); |
| 1962 __ movp(left_reg, right_op); | 1962 __ movp(left_reg, right_op); |
| 1963 } | 1963 } |
| 1964 __ bind(&return_left); | 1964 __ bind(&return_left); |
| 1965 } else { | 1965 } else { |
| 1966 DCHECK(instr->hydrogen()->representation().IsDouble()); | 1966 DCHECK(instr->hydrogen()->representation().IsDouble()); |
| 1967 Label check_nan_left, check_zero, return_left, return_right; | 1967 Label not_nan, distinct, return_left, return_right; |
| 1968 Condition condition = (operation == HMathMinMax::kMathMin) ? below : above; | 1968 Condition condition = (operation == HMathMinMax::kMathMin) ? below : above; |
| 1969 XMMRegister left_reg = ToDoubleRegister(left); | 1969 XMMRegister left_reg = ToDoubleRegister(left); |
| 1970 XMMRegister right_reg = ToDoubleRegister(right); | 1970 XMMRegister right_reg = ToDoubleRegister(right); |
| 1971 __ Ucomisd(left_reg, right_reg); | 1971 __ Ucomisd(left_reg, right_reg); |
| 1972 __ j(parity_even, &check_nan_left, Label::kNear); // At least one NaN. | 1972 __ j(parity_odd, ¬_nan, Label::kNear); // Both are not NaN. |
| 1973 __ j(equal, &check_zero, Label::kNear); // left == right. | |
| 1974 __ j(condition, &return_left, Label::kNear); | |
| 1975 __ jmp(&return_right, Label::kNear); | |
| 1976 | 1973 |
| 1977 __ bind(&check_zero); | 1974 // One of the numbers is NaN. Find which one and return it. |
| 1975 __ Ucomisd(left_reg, left_reg); |
| 1976 __ j(parity_even, &return_left, Label::kNear); // left is NaN. |
| 1977 __ jmp(&return_right, Label::kNear); // right is NaN. |
| 1978 |
| 1979 __ bind(¬_nan); |
| 1980 __ j(not_equal, &distinct, Label::kNear); // left != right. |
| 1981 |
| 1982 // left == right |
| 1978 XMMRegister xmm_scratch = double_scratch0(); | 1983 XMMRegister xmm_scratch = double_scratch0(); |
| 1979 __ Xorpd(xmm_scratch, xmm_scratch); | 1984 __ Xorpd(xmm_scratch, xmm_scratch); |
| 1980 __ Ucomisd(left_reg, xmm_scratch); | 1985 __ Ucomisd(left_reg, xmm_scratch); |
| 1981 __ j(not_equal, &return_left, Label::kNear); // left == right != 0. | 1986 __ j(not_equal, &return_left, Label::kNear); // left == right != 0. |
| 1982 // At this point, both left and right are either 0 or -0. | 1987 |
| 1988 // At this point, both left and right are either +0 or -0. |
| 1983 if (operation == HMathMinMax::kMathMin) { | 1989 if (operation == HMathMinMax::kMathMin) { |
| 1984 __ orps(left_reg, right_reg); | 1990 __ Orpd(left_reg, right_reg); |
| 1985 } else { | 1991 } else { |
| 1986 // Since we operate on +0 and/or -0, addsd and andsd have the same effect. | 1992 __ Andpd(left_reg, right_reg); |
| 1987 __ addsd(left_reg, right_reg); | |
| 1988 } | 1993 } |
| 1989 __ jmp(&return_left, Label::kNear); | 1994 __ jmp(&return_left, Label::kNear); |
| 1990 | 1995 |
| 1991 __ bind(&check_nan_left); | 1996 __ bind(&distinct); |
| 1992 __ Ucomisd(left_reg, left_reg); // NaN check. | 1997 __ j(condition, &return_left, Label::kNear); |
| 1993 __ j(parity_even, &return_left, Label::kNear); | 1998 |
| 1994 __ bind(&return_right); | 1999 __ bind(&return_right); |
| 1995 __ Movapd(left_reg, right_reg); | 2000 __ Movapd(left_reg, right_reg); |
| 1996 | 2001 |
| 1997 __ bind(&return_left); | 2002 __ bind(&return_left); |
| 1998 } | 2003 } |
| 1999 } | 2004 } |
| 2000 | 2005 |
| 2001 | 2006 |
| 2002 void LCodeGen::DoArithmeticD(LArithmeticD* instr) { | 2007 void LCodeGen::DoArithmeticD(LArithmeticD* instr) { |
| 2003 XMMRegister left = ToDoubleRegister(instr->left()); | 2008 XMMRegister left = ToDoubleRegister(instr->left()); |
| (...skipping 3860 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5864 RecordSafepoint(Safepoint::kNoLazyDeopt); | 5869 RecordSafepoint(Safepoint::kNoLazyDeopt); |
| 5865 } | 5870 } |
| 5866 | 5871 |
| 5867 | 5872 |
| 5868 #undef __ | 5873 #undef __ |
| 5869 | 5874 |
| 5870 } // namespace internal | 5875 } // namespace internal |
| 5871 } // namespace v8 | 5876 } // namespace v8 |
| 5872 | 5877 |
| 5873 #endif // V8_TARGET_ARCH_X64 | 5878 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |