| 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 1994 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2005 DCHECK(!info()->IsStub()); | 2005 DCHECK(!info()->IsStub()); |
| 2006 XMMRegister xmm_scratch = double_scratch0(); | 2006 XMMRegister xmm_scratch = double_scratch0(); |
| 2007 __ Xorpd(xmm_scratch, xmm_scratch); | 2007 __ Xorpd(xmm_scratch, xmm_scratch); |
| 2008 __ Ucomisd(xmm_scratch, FieldOperand(reg, HeapNumber::kValueOffset)); | 2008 __ Ucomisd(xmm_scratch, FieldOperand(reg, HeapNumber::kValueOffset)); |
| 2009 EmitBranch(instr, not_equal); | 2009 EmitBranch(instr, not_equal); |
| 2010 } else if (type.IsString()) { | 2010 } else if (type.IsString()) { |
| 2011 DCHECK(!info()->IsStub()); | 2011 DCHECK(!info()->IsStub()); |
| 2012 __ cmpp(FieldOperand(reg, String::kLengthOffset), Immediate(0)); | 2012 __ cmpp(FieldOperand(reg, String::kLengthOffset), Immediate(0)); |
| 2013 EmitBranch(instr, not_equal); | 2013 EmitBranch(instr, not_equal); |
| 2014 } else { | 2014 } else { |
| 2015 ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types(); | 2015 ToBooleanICStub::Types expected = |
| 2016 instr->hydrogen()->expected_input_types(); |
| 2016 // Avoid deopts in the case where we've never executed this path before. | 2017 // Avoid deopts in the case where we've never executed this path before. |
| 2017 if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic(); | 2018 if (expected.IsEmpty()) expected = ToBooleanICStub::Types::Generic(); |
| 2018 | 2019 |
| 2019 if (expected.Contains(ToBooleanStub::UNDEFINED)) { | 2020 if (expected.Contains(ToBooleanICStub::UNDEFINED)) { |
| 2020 // undefined -> false. | 2021 // undefined -> false. |
| 2021 __ CompareRoot(reg, Heap::kUndefinedValueRootIndex); | 2022 __ CompareRoot(reg, Heap::kUndefinedValueRootIndex); |
| 2022 __ j(equal, instr->FalseLabel(chunk_)); | 2023 __ j(equal, instr->FalseLabel(chunk_)); |
| 2023 } | 2024 } |
| 2024 if (expected.Contains(ToBooleanStub::BOOLEAN)) { | 2025 if (expected.Contains(ToBooleanICStub::BOOLEAN)) { |
| 2025 // true -> true. | 2026 // true -> true. |
| 2026 __ CompareRoot(reg, Heap::kTrueValueRootIndex); | 2027 __ CompareRoot(reg, Heap::kTrueValueRootIndex); |
| 2027 __ j(equal, instr->TrueLabel(chunk_)); | 2028 __ j(equal, instr->TrueLabel(chunk_)); |
| 2028 // false -> false. | 2029 // false -> false. |
| 2029 __ CompareRoot(reg, Heap::kFalseValueRootIndex); | 2030 __ CompareRoot(reg, Heap::kFalseValueRootIndex); |
| 2030 __ j(equal, instr->FalseLabel(chunk_)); | 2031 __ j(equal, instr->FalseLabel(chunk_)); |
| 2031 } | 2032 } |
| 2032 if (expected.Contains(ToBooleanStub::NULL_TYPE)) { | 2033 if (expected.Contains(ToBooleanICStub::NULL_TYPE)) { |
| 2033 // 'null' -> false. | 2034 // 'null' -> false. |
| 2034 __ CompareRoot(reg, Heap::kNullValueRootIndex); | 2035 __ CompareRoot(reg, Heap::kNullValueRootIndex); |
| 2035 __ j(equal, instr->FalseLabel(chunk_)); | 2036 __ j(equal, instr->FalseLabel(chunk_)); |
| 2036 } | 2037 } |
| 2037 | 2038 |
| 2038 if (expected.Contains(ToBooleanStub::SMI)) { | 2039 if (expected.Contains(ToBooleanICStub::SMI)) { |
| 2039 // Smis: 0 -> false, all other -> true. | 2040 // Smis: 0 -> false, all other -> true. |
| 2040 __ Cmp(reg, Smi::FromInt(0)); | 2041 __ Cmp(reg, Smi::FromInt(0)); |
| 2041 __ j(equal, instr->FalseLabel(chunk_)); | 2042 __ j(equal, instr->FalseLabel(chunk_)); |
| 2042 __ JumpIfSmi(reg, instr->TrueLabel(chunk_)); | 2043 __ JumpIfSmi(reg, instr->TrueLabel(chunk_)); |
| 2043 } else if (expected.NeedsMap()) { | 2044 } else if (expected.NeedsMap()) { |
| 2044 // If we need a map later and have a Smi -> deopt. | 2045 // If we need a map later and have a Smi -> deopt. |
| 2045 __ testb(reg, Immediate(kSmiTagMask)); | 2046 __ testb(reg, Immediate(kSmiTagMask)); |
| 2046 DeoptimizeIf(zero, instr, Deoptimizer::kSmi); | 2047 DeoptimizeIf(zero, instr, Deoptimizer::kSmi); |
| 2047 } | 2048 } |
| 2048 | 2049 |
| 2049 const Register map = kScratchRegister; | 2050 const Register map = kScratchRegister; |
| 2050 if (expected.NeedsMap()) { | 2051 if (expected.NeedsMap()) { |
| 2051 __ movp(map, FieldOperand(reg, HeapObject::kMapOffset)); | 2052 __ movp(map, FieldOperand(reg, HeapObject::kMapOffset)); |
| 2052 | 2053 |
| 2053 if (expected.CanBeUndetectable()) { | 2054 if (expected.CanBeUndetectable()) { |
| 2054 // Undetectable -> false. | 2055 // Undetectable -> false. |
| 2055 __ testb(FieldOperand(map, Map::kBitFieldOffset), | 2056 __ testb(FieldOperand(map, Map::kBitFieldOffset), |
| 2056 Immediate(1 << Map::kIsUndetectable)); | 2057 Immediate(1 << Map::kIsUndetectable)); |
| 2057 __ j(not_zero, instr->FalseLabel(chunk_)); | 2058 __ j(not_zero, instr->FalseLabel(chunk_)); |
| 2058 } | 2059 } |
| 2059 } | 2060 } |
| 2060 | 2061 |
| 2061 if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { | 2062 if (expected.Contains(ToBooleanICStub::SPEC_OBJECT)) { |
| 2062 // spec object -> true. | 2063 // spec object -> true. |
| 2063 __ CmpInstanceType(map, FIRST_JS_RECEIVER_TYPE); | 2064 __ CmpInstanceType(map, FIRST_JS_RECEIVER_TYPE); |
| 2064 __ j(above_equal, instr->TrueLabel(chunk_)); | 2065 __ j(above_equal, instr->TrueLabel(chunk_)); |
| 2065 } | 2066 } |
| 2066 | 2067 |
| 2067 if (expected.Contains(ToBooleanStub::STRING)) { | 2068 if (expected.Contains(ToBooleanICStub::STRING)) { |
| 2068 // String value -> false iff empty. | 2069 // String value -> false iff empty. |
| 2069 Label not_string; | 2070 Label not_string; |
| 2070 __ CmpInstanceType(map, FIRST_NONSTRING_TYPE); | 2071 __ CmpInstanceType(map, FIRST_NONSTRING_TYPE); |
| 2071 __ j(above_equal, ¬_string, Label::kNear); | 2072 __ j(above_equal, ¬_string, Label::kNear); |
| 2072 __ cmpp(FieldOperand(reg, String::kLengthOffset), Immediate(0)); | 2073 __ cmpp(FieldOperand(reg, String::kLengthOffset), Immediate(0)); |
| 2073 __ j(not_zero, instr->TrueLabel(chunk_)); | 2074 __ j(not_zero, instr->TrueLabel(chunk_)); |
| 2074 __ jmp(instr->FalseLabel(chunk_)); | 2075 __ jmp(instr->FalseLabel(chunk_)); |
| 2075 __ bind(¬_string); | 2076 __ bind(¬_string); |
| 2076 } | 2077 } |
| 2077 | 2078 |
| 2078 if (expected.Contains(ToBooleanStub::SYMBOL)) { | 2079 if (expected.Contains(ToBooleanICStub::SYMBOL)) { |
| 2079 // Symbol value -> true. | 2080 // Symbol value -> true. |
| 2080 __ CmpInstanceType(map, SYMBOL_TYPE); | 2081 __ CmpInstanceType(map, SYMBOL_TYPE); |
| 2081 __ j(equal, instr->TrueLabel(chunk_)); | 2082 __ j(equal, instr->TrueLabel(chunk_)); |
| 2082 } | 2083 } |
| 2083 | 2084 |
| 2084 if (expected.Contains(ToBooleanStub::SIMD_VALUE)) { | 2085 if (expected.Contains(ToBooleanICStub::SIMD_VALUE)) { |
| 2085 // SIMD value -> true. | 2086 // SIMD value -> true. |
| 2086 __ CmpInstanceType(map, SIMD128_VALUE_TYPE); | 2087 __ CmpInstanceType(map, SIMD128_VALUE_TYPE); |
| 2087 __ j(equal, instr->TrueLabel(chunk_)); | 2088 __ j(equal, instr->TrueLabel(chunk_)); |
| 2088 } | 2089 } |
| 2089 | 2090 |
| 2090 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { | 2091 if (expected.Contains(ToBooleanICStub::HEAP_NUMBER)) { |
| 2091 // heap number -> false iff +0, -0, or NaN. | 2092 // heap number -> false iff +0, -0, or NaN. |
| 2092 Label not_heap_number; | 2093 Label not_heap_number; |
| 2093 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex); | 2094 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex); |
| 2094 __ j(not_equal, ¬_heap_number, Label::kNear); | 2095 __ j(not_equal, ¬_heap_number, Label::kNear); |
| 2095 XMMRegister xmm_scratch = double_scratch0(); | 2096 XMMRegister xmm_scratch = double_scratch0(); |
| 2096 __ Xorpd(xmm_scratch, xmm_scratch); | 2097 __ Xorpd(xmm_scratch, xmm_scratch); |
| 2097 __ Ucomisd(xmm_scratch, FieldOperand(reg, HeapNumber::kValueOffset)); | 2098 __ Ucomisd(xmm_scratch, FieldOperand(reg, HeapNumber::kValueOffset)); |
| 2098 __ j(zero, instr->FalseLabel(chunk_)); | 2099 __ j(zero, instr->FalseLabel(chunk_)); |
| 2099 __ jmp(instr->TrueLabel(chunk_)); | 2100 __ jmp(instr->TrueLabel(chunk_)); |
| 2100 __ bind(¬_heap_number); | 2101 __ bind(¬_heap_number); |
| (...skipping 3413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5514 __ movp(Operand(rbp, StandardFrameConstants::kContextOffset), context); | 5515 __ movp(Operand(rbp, StandardFrameConstants::kContextOffset), context); |
| 5515 } | 5516 } |
| 5516 | 5517 |
| 5517 | 5518 |
| 5518 #undef __ | 5519 #undef __ |
| 5519 | 5520 |
| 5520 } // namespace internal | 5521 } // namespace internal |
| 5521 } // namespace v8 | 5522 } // namespace v8 |
| 5522 | 5523 |
| 5523 #endif // V8_TARGET_ARCH_X64 | 5524 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |