OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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/arm/lithium-codegen-arm.h" | 5 #include "src/crankshaft/arm/lithium-codegen-arm.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/arm/lithium-gap-resolver-arm.h" | 10 #include "src/crankshaft/arm/lithium-gap-resolver-arm.h" |
(...skipping 2052 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2063 // Test the double value. Zero and NaN are false. | 2063 // Test the double value. Zero and NaN are false. |
2064 __ VFPCompareAndSetFlags(dbl_scratch, 0.0); | 2064 __ VFPCompareAndSetFlags(dbl_scratch, 0.0); |
2065 __ cmp(r0, r0, vs); // If NaN, set the Z flag. (NaN) | 2065 __ cmp(r0, r0, vs); // If NaN, set the Z flag. (NaN) |
2066 EmitBranch(instr, ne); | 2066 EmitBranch(instr, ne); |
2067 } else if (type.IsString()) { | 2067 } else if (type.IsString()) { |
2068 DCHECK(!info()->IsStub()); | 2068 DCHECK(!info()->IsStub()); |
2069 __ ldr(ip, FieldMemOperand(reg, String::kLengthOffset)); | 2069 __ ldr(ip, FieldMemOperand(reg, String::kLengthOffset)); |
2070 __ cmp(ip, Operand::Zero()); | 2070 __ cmp(ip, Operand::Zero()); |
2071 EmitBranch(instr, ne); | 2071 EmitBranch(instr, ne); |
2072 } else { | 2072 } else { |
2073 ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types(); | 2073 ToBooleanICStub::Types expected = |
| 2074 instr->hydrogen()->expected_input_types(); |
2074 // Avoid deopts in the case where we've never executed this path before. | 2075 // Avoid deopts in the case where we've never executed this path before. |
2075 if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic(); | 2076 if (expected.IsEmpty()) expected = ToBooleanICStub::Types::Generic(); |
2076 | 2077 |
2077 if (expected.Contains(ToBooleanStub::UNDEFINED)) { | 2078 if (expected.Contains(ToBooleanICStub::UNDEFINED)) { |
2078 // undefined -> false. | 2079 // undefined -> false. |
2079 __ CompareRoot(reg, Heap::kUndefinedValueRootIndex); | 2080 __ CompareRoot(reg, Heap::kUndefinedValueRootIndex); |
2080 __ b(eq, instr->FalseLabel(chunk_)); | 2081 __ b(eq, instr->FalseLabel(chunk_)); |
2081 } | 2082 } |
2082 if (expected.Contains(ToBooleanStub::BOOLEAN)) { | 2083 if (expected.Contains(ToBooleanICStub::BOOLEAN)) { |
2083 // Boolean -> its value. | 2084 // Boolean -> its value. |
2084 __ CompareRoot(reg, Heap::kTrueValueRootIndex); | 2085 __ CompareRoot(reg, Heap::kTrueValueRootIndex); |
2085 __ b(eq, instr->TrueLabel(chunk_)); | 2086 __ b(eq, instr->TrueLabel(chunk_)); |
2086 __ CompareRoot(reg, Heap::kFalseValueRootIndex); | 2087 __ CompareRoot(reg, Heap::kFalseValueRootIndex); |
2087 __ b(eq, instr->FalseLabel(chunk_)); | 2088 __ b(eq, instr->FalseLabel(chunk_)); |
2088 } | 2089 } |
2089 if (expected.Contains(ToBooleanStub::NULL_TYPE)) { | 2090 if (expected.Contains(ToBooleanICStub::NULL_TYPE)) { |
2090 // 'null' -> false. | 2091 // 'null' -> false. |
2091 __ CompareRoot(reg, Heap::kNullValueRootIndex); | 2092 __ CompareRoot(reg, Heap::kNullValueRootIndex); |
2092 __ b(eq, instr->FalseLabel(chunk_)); | 2093 __ b(eq, instr->FalseLabel(chunk_)); |
2093 } | 2094 } |
2094 | 2095 |
2095 if (expected.Contains(ToBooleanStub::SMI)) { | 2096 if (expected.Contains(ToBooleanICStub::SMI)) { |
2096 // Smis: 0 -> false, all other -> true. | 2097 // Smis: 0 -> false, all other -> true. |
2097 __ cmp(reg, Operand::Zero()); | 2098 __ cmp(reg, Operand::Zero()); |
2098 __ b(eq, instr->FalseLabel(chunk_)); | 2099 __ b(eq, instr->FalseLabel(chunk_)); |
2099 __ JumpIfSmi(reg, instr->TrueLabel(chunk_)); | 2100 __ JumpIfSmi(reg, instr->TrueLabel(chunk_)); |
2100 } else if (expected.NeedsMap()) { | 2101 } else if (expected.NeedsMap()) { |
2101 // If we need a map later and have a Smi -> deopt. | 2102 // If we need a map later and have a Smi -> deopt. |
2102 __ SmiTst(reg); | 2103 __ SmiTst(reg); |
2103 DeoptimizeIf(eq, instr, Deoptimizer::kSmi); | 2104 DeoptimizeIf(eq, instr, Deoptimizer::kSmi); |
2104 } | 2105 } |
2105 | 2106 |
2106 const Register map = scratch0(); | 2107 const Register map = scratch0(); |
2107 if (expected.NeedsMap()) { | 2108 if (expected.NeedsMap()) { |
2108 __ ldr(map, FieldMemOperand(reg, HeapObject::kMapOffset)); | 2109 __ ldr(map, FieldMemOperand(reg, HeapObject::kMapOffset)); |
2109 | 2110 |
2110 if (expected.CanBeUndetectable()) { | 2111 if (expected.CanBeUndetectable()) { |
2111 // Undetectable -> false. | 2112 // Undetectable -> false. |
2112 __ ldrb(ip, FieldMemOperand(map, Map::kBitFieldOffset)); | 2113 __ ldrb(ip, FieldMemOperand(map, Map::kBitFieldOffset)); |
2113 __ tst(ip, Operand(1 << Map::kIsUndetectable)); | 2114 __ tst(ip, Operand(1 << Map::kIsUndetectable)); |
2114 __ b(ne, instr->FalseLabel(chunk_)); | 2115 __ b(ne, instr->FalseLabel(chunk_)); |
2115 } | 2116 } |
2116 } | 2117 } |
2117 | 2118 |
2118 if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { | 2119 if (expected.Contains(ToBooleanICStub::SPEC_OBJECT)) { |
2119 // spec object -> true. | 2120 // spec object -> true. |
2120 __ CompareInstanceType(map, ip, FIRST_JS_RECEIVER_TYPE); | 2121 __ CompareInstanceType(map, ip, FIRST_JS_RECEIVER_TYPE); |
2121 __ b(ge, instr->TrueLabel(chunk_)); | 2122 __ b(ge, instr->TrueLabel(chunk_)); |
2122 } | 2123 } |
2123 | 2124 |
2124 if (expected.Contains(ToBooleanStub::STRING)) { | 2125 if (expected.Contains(ToBooleanICStub::STRING)) { |
2125 // String value -> false iff empty. | 2126 // String value -> false iff empty. |
2126 Label not_string; | 2127 Label not_string; |
2127 __ CompareInstanceType(map, ip, FIRST_NONSTRING_TYPE); | 2128 __ CompareInstanceType(map, ip, FIRST_NONSTRING_TYPE); |
2128 __ b(ge, ¬_string); | 2129 __ b(ge, ¬_string); |
2129 __ ldr(ip, FieldMemOperand(reg, String::kLengthOffset)); | 2130 __ ldr(ip, FieldMemOperand(reg, String::kLengthOffset)); |
2130 __ cmp(ip, Operand::Zero()); | 2131 __ cmp(ip, Operand::Zero()); |
2131 __ b(ne, instr->TrueLabel(chunk_)); | 2132 __ b(ne, instr->TrueLabel(chunk_)); |
2132 __ b(instr->FalseLabel(chunk_)); | 2133 __ b(instr->FalseLabel(chunk_)); |
2133 __ bind(¬_string); | 2134 __ bind(¬_string); |
2134 } | 2135 } |
2135 | 2136 |
2136 if (expected.Contains(ToBooleanStub::SYMBOL)) { | 2137 if (expected.Contains(ToBooleanICStub::SYMBOL)) { |
2137 // Symbol value -> true. | 2138 // Symbol value -> true. |
2138 __ CompareInstanceType(map, ip, SYMBOL_TYPE); | 2139 __ CompareInstanceType(map, ip, SYMBOL_TYPE); |
2139 __ b(eq, instr->TrueLabel(chunk_)); | 2140 __ b(eq, instr->TrueLabel(chunk_)); |
2140 } | 2141 } |
2141 | 2142 |
2142 if (expected.Contains(ToBooleanStub::SIMD_VALUE)) { | 2143 if (expected.Contains(ToBooleanICStub::SIMD_VALUE)) { |
2143 // SIMD value -> true. | 2144 // SIMD value -> true. |
2144 __ CompareInstanceType(map, ip, SIMD128_VALUE_TYPE); | 2145 __ CompareInstanceType(map, ip, SIMD128_VALUE_TYPE); |
2145 __ b(eq, instr->TrueLabel(chunk_)); | 2146 __ b(eq, instr->TrueLabel(chunk_)); |
2146 } | 2147 } |
2147 | 2148 |
2148 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { | 2149 if (expected.Contains(ToBooleanICStub::HEAP_NUMBER)) { |
2149 // heap number -> false iff +0, -0, or NaN. | 2150 // heap number -> false iff +0, -0, or NaN. |
2150 DwVfpRegister dbl_scratch = double_scratch0(); | 2151 DwVfpRegister dbl_scratch = double_scratch0(); |
2151 Label not_heap_number; | 2152 Label not_heap_number; |
2152 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex); | 2153 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex); |
2153 __ b(ne, ¬_heap_number); | 2154 __ b(ne, ¬_heap_number); |
2154 __ vldr(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset)); | 2155 __ vldr(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset)); |
2155 __ VFPCompareAndSetFlags(dbl_scratch, 0.0); | 2156 __ VFPCompareAndSetFlags(dbl_scratch, 0.0); |
2156 __ cmp(r0, r0, vs); // NaN -> false. | 2157 __ cmp(r0, r0, vs); // NaN -> false. |
2157 __ b(eq, instr->FalseLabel(chunk_)); // +0, -0 -> false. | 2158 __ b(eq, instr->FalseLabel(chunk_)); // +0, -0 -> false. |
2158 __ b(instr->TrueLabel(chunk_)); | 2159 __ b(instr->TrueLabel(chunk_)); |
(...skipping 3311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5470 void LCodeGen::DoStoreFrameContext(LStoreFrameContext* instr) { | 5471 void LCodeGen::DoStoreFrameContext(LStoreFrameContext* instr) { |
5471 Register context = ToRegister(instr->context()); | 5472 Register context = ToRegister(instr->context()); |
5472 __ str(context, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 5473 __ str(context, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
5473 } | 5474 } |
5474 | 5475 |
5475 | 5476 |
5476 #undef __ | 5477 #undef __ |
5477 | 5478 |
5478 } // namespace internal | 5479 } // namespace internal |
5479 } // namespace v8 | 5480 } // namespace v8 |
OLD | NEW |