OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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 #include "src/crankshaft/ppc/lithium-codegen-ppc.h" | 5 #include "src/crankshaft/ppc/lithium-codegen-ppc.h" |
6 | 6 |
7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/crankshaft/hydrogen-osr.h" | 10 #include "src/crankshaft/hydrogen-osr.h" |
(...skipping 2085 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2096 __ fcmpu(dbl_scratch, kDoubleRegZero, cr7); | 2096 __ fcmpu(dbl_scratch, kDoubleRegZero, cr7); |
2097 __ mfcr(r0); | 2097 __ mfcr(r0); |
2098 __ andi(r0, r0, Operand(crZOrNaNBits)); | 2098 __ andi(r0, r0, Operand(crZOrNaNBits)); |
2099 EmitBranch(instr, eq, cr0); | 2099 EmitBranch(instr, eq, cr0); |
2100 } else if (type.IsString()) { | 2100 } else if (type.IsString()) { |
2101 DCHECK(!info()->IsStub()); | 2101 DCHECK(!info()->IsStub()); |
2102 __ LoadP(ip, FieldMemOperand(reg, String::kLengthOffset)); | 2102 __ LoadP(ip, FieldMemOperand(reg, String::kLengthOffset)); |
2103 __ cmpi(ip, Operand::Zero()); | 2103 __ cmpi(ip, Operand::Zero()); |
2104 EmitBranch(instr, ne); | 2104 EmitBranch(instr, ne); |
2105 } else { | 2105 } else { |
2106 ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types(); | 2106 ToBooleanICStub::Types expected = |
| 2107 instr->hydrogen()->expected_input_types(); |
2107 // Avoid deopts in the case where we've never executed this path before. | 2108 // Avoid deopts in the case where we've never executed this path before. |
2108 if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic(); | 2109 if (expected.IsEmpty()) expected = ToBooleanICStub::Types::Generic(); |
2109 | 2110 |
2110 if (expected.Contains(ToBooleanStub::UNDEFINED)) { | 2111 if (expected.Contains(ToBooleanICStub::UNDEFINED)) { |
2111 // undefined -> false. | 2112 // undefined -> false. |
2112 __ CompareRoot(reg, Heap::kUndefinedValueRootIndex); | 2113 __ CompareRoot(reg, Heap::kUndefinedValueRootIndex); |
2113 __ beq(instr->FalseLabel(chunk_)); | 2114 __ beq(instr->FalseLabel(chunk_)); |
2114 } | 2115 } |
2115 if (expected.Contains(ToBooleanStub::BOOLEAN)) { | 2116 if (expected.Contains(ToBooleanICStub::BOOLEAN)) { |
2116 // Boolean -> its value. | 2117 // Boolean -> its value. |
2117 __ CompareRoot(reg, Heap::kTrueValueRootIndex); | 2118 __ CompareRoot(reg, Heap::kTrueValueRootIndex); |
2118 __ beq(instr->TrueLabel(chunk_)); | 2119 __ beq(instr->TrueLabel(chunk_)); |
2119 __ CompareRoot(reg, Heap::kFalseValueRootIndex); | 2120 __ CompareRoot(reg, Heap::kFalseValueRootIndex); |
2120 __ beq(instr->FalseLabel(chunk_)); | 2121 __ beq(instr->FalseLabel(chunk_)); |
2121 } | 2122 } |
2122 if (expected.Contains(ToBooleanStub::NULL_TYPE)) { | 2123 if (expected.Contains(ToBooleanICStub::NULL_TYPE)) { |
2123 // 'null' -> false. | 2124 // 'null' -> false. |
2124 __ CompareRoot(reg, Heap::kNullValueRootIndex); | 2125 __ CompareRoot(reg, Heap::kNullValueRootIndex); |
2125 __ beq(instr->FalseLabel(chunk_)); | 2126 __ beq(instr->FalseLabel(chunk_)); |
2126 } | 2127 } |
2127 | 2128 |
2128 if (expected.Contains(ToBooleanStub::SMI)) { | 2129 if (expected.Contains(ToBooleanICStub::SMI)) { |
2129 // Smis: 0 -> false, all other -> true. | 2130 // Smis: 0 -> false, all other -> true. |
2130 __ cmpi(reg, Operand::Zero()); | 2131 __ cmpi(reg, Operand::Zero()); |
2131 __ beq(instr->FalseLabel(chunk_)); | 2132 __ beq(instr->FalseLabel(chunk_)); |
2132 __ JumpIfSmi(reg, instr->TrueLabel(chunk_)); | 2133 __ JumpIfSmi(reg, instr->TrueLabel(chunk_)); |
2133 } else if (expected.NeedsMap()) { | 2134 } else if (expected.NeedsMap()) { |
2134 // If we need a map later and have a Smi -> deopt. | 2135 // If we need a map later and have a Smi -> deopt. |
2135 __ TestIfSmi(reg, r0); | 2136 __ TestIfSmi(reg, r0); |
2136 DeoptimizeIf(eq, instr, Deoptimizer::kSmi, cr0); | 2137 DeoptimizeIf(eq, instr, Deoptimizer::kSmi, cr0); |
2137 } | 2138 } |
2138 | 2139 |
2139 const Register map = scratch0(); | 2140 const Register map = scratch0(); |
2140 if (expected.NeedsMap()) { | 2141 if (expected.NeedsMap()) { |
2141 __ LoadP(map, FieldMemOperand(reg, HeapObject::kMapOffset)); | 2142 __ LoadP(map, FieldMemOperand(reg, HeapObject::kMapOffset)); |
2142 | 2143 |
2143 if (expected.CanBeUndetectable()) { | 2144 if (expected.CanBeUndetectable()) { |
2144 // Undetectable -> false. | 2145 // Undetectable -> false. |
2145 __ lbz(ip, FieldMemOperand(map, Map::kBitFieldOffset)); | 2146 __ lbz(ip, FieldMemOperand(map, Map::kBitFieldOffset)); |
2146 __ TestBit(ip, Map::kIsUndetectable, r0); | 2147 __ TestBit(ip, Map::kIsUndetectable, r0); |
2147 __ bne(instr->FalseLabel(chunk_), cr0); | 2148 __ bne(instr->FalseLabel(chunk_), cr0); |
2148 } | 2149 } |
2149 } | 2150 } |
2150 | 2151 |
2151 if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { | 2152 if (expected.Contains(ToBooleanICStub::SPEC_OBJECT)) { |
2152 // spec object -> true. | 2153 // spec object -> true. |
2153 __ CompareInstanceType(map, ip, FIRST_JS_RECEIVER_TYPE); | 2154 __ CompareInstanceType(map, ip, FIRST_JS_RECEIVER_TYPE); |
2154 __ bge(instr->TrueLabel(chunk_)); | 2155 __ bge(instr->TrueLabel(chunk_)); |
2155 } | 2156 } |
2156 | 2157 |
2157 if (expected.Contains(ToBooleanStub::STRING)) { | 2158 if (expected.Contains(ToBooleanICStub::STRING)) { |
2158 // String value -> false iff empty. | 2159 // String value -> false iff empty. |
2159 Label not_string; | 2160 Label not_string; |
2160 __ CompareInstanceType(map, ip, FIRST_NONSTRING_TYPE); | 2161 __ CompareInstanceType(map, ip, FIRST_NONSTRING_TYPE); |
2161 __ bge(¬_string); | 2162 __ bge(¬_string); |
2162 __ LoadP(ip, FieldMemOperand(reg, String::kLengthOffset)); | 2163 __ LoadP(ip, FieldMemOperand(reg, String::kLengthOffset)); |
2163 __ cmpi(ip, Operand::Zero()); | 2164 __ cmpi(ip, Operand::Zero()); |
2164 __ bne(instr->TrueLabel(chunk_)); | 2165 __ bne(instr->TrueLabel(chunk_)); |
2165 __ b(instr->FalseLabel(chunk_)); | 2166 __ b(instr->FalseLabel(chunk_)); |
2166 __ bind(¬_string); | 2167 __ bind(¬_string); |
2167 } | 2168 } |
2168 | 2169 |
2169 if (expected.Contains(ToBooleanStub::SYMBOL)) { | 2170 if (expected.Contains(ToBooleanICStub::SYMBOL)) { |
2170 // Symbol value -> true. | 2171 // Symbol value -> true. |
2171 __ CompareInstanceType(map, ip, SYMBOL_TYPE); | 2172 __ CompareInstanceType(map, ip, SYMBOL_TYPE); |
2172 __ beq(instr->TrueLabel(chunk_)); | 2173 __ beq(instr->TrueLabel(chunk_)); |
2173 } | 2174 } |
2174 | 2175 |
2175 if (expected.Contains(ToBooleanStub::SIMD_VALUE)) { | 2176 if (expected.Contains(ToBooleanICStub::SIMD_VALUE)) { |
2176 // SIMD value -> true. | 2177 // SIMD value -> true. |
2177 Label not_simd; | 2178 Label not_simd; |
2178 __ CompareInstanceType(map, ip, SIMD128_VALUE_TYPE); | 2179 __ CompareInstanceType(map, ip, SIMD128_VALUE_TYPE); |
2179 __ beq(instr->TrueLabel(chunk_)); | 2180 __ beq(instr->TrueLabel(chunk_)); |
2180 } | 2181 } |
2181 | 2182 |
2182 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { | 2183 if (expected.Contains(ToBooleanICStub::HEAP_NUMBER)) { |
2183 // heap number -> false iff +0, -0, or NaN. | 2184 // heap number -> false iff +0, -0, or NaN. |
2184 Label not_heap_number; | 2185 Label not_heap_number; |
2185 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex); | 2186 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex); |
2186 __ bne(¬_heap_number); | 2187 __ bne(¬_heap_number); |
2187 __ lfd(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset)); | 2188 __ lfd(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset)); |
2188 // Test the double value. Zero and NaN are false. | 2189 // Test the double value. Zero and NaN are false. |
2189 __ fcmpu(dbl_scratch, kDoubleRegZero, cr7); | 2190 __ fcmpu(dbl_scratch, kDoubleRegZero, cr7); |
2190 __ mfcr(r0); | 2191 __ mfcr(r0); |
2191 __ andi(r0, r0, Operand(crZOrNaNBits)); | 2192 __ andi(r0, r0, Operand(crZOrNaNBits)); |
2192 __ bne(instr->FalseLabel(chunk_), cr0); | 2193 __ bne(instr->FalseLabel(chunk_), cr0); |
(...skipping 3491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5684 | 5685 |
5685 void LCodeGen::DoStoreFrameContext(LStoreFrameContext* instr) { | 5686 void LCodeGen::DoStoreFrameContext(LStoreFrameContext* instr) { |
5686 Register context = ToRegister(instr->context()); | 5687 Register context = ToRegister(instr->context()); |
5687 __ StoreP(context, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 5688 __ StoreP(context, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
5688 } | 5689 } |
5689 | 5690 |
5690 | 5691 |
5691 #undef __ | 5692 #undef __ |
5692 } // namespace internal | 5693 } // namespace internal |
5693 } // namespace v8 | 5694 } // namespace v8 |
OLD | NEW |