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 |