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 |