| 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 |