OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/globals.h" | 5 #include "vm/globals.h" |
6 #if defined(TARGET_ARCH_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
7 | 7 |
8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
10 #include "vm/cpu.h" | 10 #include "vm/cpu.h" |
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
472 | 472 |
473 if (TargetCPUFeatures::vfp_supported()) { | 473 if (TargetCPUFeatures::vfp_supported()) { |
474 ASSERT(kFpuRegisterSize == 4 * kWordSize); | 474 ASSERT(kFpuRegisterSize == 4 * kWordSize); |
475 if (kNumberOfDRegisters > 16) { | 475 if (kNumberOfDRegisters > 16) { |
476 __ vstmd(DB_W, SP, D16, kNumberOfDRegisters - 16); | 476 __ vstmd(DB_W, SP, D16, kNumberOfDRegisters - 16); |
477 __ vstmd(DB_W, SP, D0, 16); | 477 __ vstmd(DB_W, SP, D0, 16); |
478 } else { | 478 } else { |
479 __ vstmd(DB_W, SP, D0, kNumberOfDRegisters); | 479 __ vstmd(DB_W, SP, D0, kNumberOfDRegisters); |
480 } | 480 } |
481 } else { | 481 } else { |
482 __ AddImmediate(SP, SP, -kNumberOfFpuRegisters * kFpuRegisterSize); | 482 __ AddImmediate(SP, -kNumberOfFpuRegisters * kFpuRegisterSize); |
483 } | 483 } |
484 | 484 |
485 __ mov(R0, Operand(SP)); // Pass address of saved registers block. | 485 __ mov(R0, Operand(SP)); // Pass address of saved registers block. |
486 bool is_lazy = | 486 bool is_lazy = |
487 (kind == kLazyDeoptFromReturn) || (kind == kLazyDeoptFromThrow); | 487 (kind == kLazyDeoptFromReturn) || (kind == kLazyDeoptFromThrow); |
488 __ mov(R1, Operand(is_lazy ? 1 : 0)); | 488 __ mov(R1, Operand(is_lazy ? 1 : 0)); |
489 __ ReserveAlignedFrameSpace(0); | 489 __ ReserveAlignedFrameSpace(0); |
490 __ CallRuntime(kDeoptimizeCopyFrameRuntimeEntry, 2); | 490 __ CallRuntime(kDeoptimizeCopyFrameRuntimeEntry, 2); |
491 // Result (R0) is stack-size (FP - SP) in bytes. | 491 // Result (R0) is stack-size (FP - SP) in bytes. |
492 | 492 |
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
838 | 838 |
839 // Load arguments descriptor array into R4, which is passed to Dart code. | 839 // Load arguments descriptor array into R4, which is passed to Dart code. |
840 __ ldr(R4, Address(R1, VMHandles::kOffsetOfRawPtrInHandle)); | 840 __ ldr(R4, Address(R1, VMHandles::kOffsetOfRawPtrInHandle)); |
841 | 841 |
842 // Load number of arguments into R9. | 842 // Load number of arguments into R9. |
843 __ ldr(R9, FieldAddress(R4, ArgumentsDescriptor::count_offset())); | 843 __ ldr(R9, FieldAddress(R4, ArgumentsDescriptor::count_offset())); |
844 __ SmiUntag(R9); | 844 __ SmiUntag(R9); |
845 | 845 |
846 // Compute address of 'arguments array' data area into R2. | 846 // Compute address of 'arguments array' data area into R2. |
847 __ ldr(R2, Address(R2, VMHandles::kOffsetOfRawPtrInHandle)); | 847 __ ldr(R2, Address(R2, VMHandles::kOffsetOfRawPtrInHandle)); |
848 __ AddImmediate(R2, R2, Array::data_offset() - kHeapObjectTag); | 848 __ AddImmediate(R2, Array::data_offset() - kHeapObjectTag); |
849 | 849 |
850 // Set up arguments for the Dart call. | 850 // Set up arguments for the Dart call. |
851 Label push_arguments; | 851 Label push_arguments; |
852 Label done_push_arguments; | 852 Label done_push_arguments; |
853 __ CompareImmediate(R9, 0); // check if there are arguments. | 853 __ CompareImmediate(R9, 0); // check if there are arguments. |
854 __ b(&done_push_arguments, EQ); | 854 __ b(&done_push_arguments, EQ); |
855 __ LoadImmediate(R1, 0); | 855 __ LoadImmediate(R1, 0); |
856 __ Bind(&push_arguments); | 856 __ Bind(&push_arguments); |
857 __ ldr(R3, Address(R2)); | 857 __ ldr(R3, Address(R2)); |
858 __ Push(R3); | 858 __ Push(R3); |
(...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1330 __ LoadObject(R0, Bool::True(), EQ); | 1330 __ LoadObject(R0, Bool::True(), EQ); |
1331 __ LoadObject(R0, Bool::False(), NE); | 1331 __ LoadObject(R0, Bool::False(), NE); |
1332 break; | 1332 break; |
1333 } | 1333 } |
1334 default: | 1334 default: |
1335 UNIMPLEMENTED(); | 1335 UNIMPLEMENTED(); |
1336 } | 1336 } |
1337 // R9: IC data object (preserved). | 1337 // R9: IC data object (preserved). |
1338 __ ldr(R8, FieldAddress(R9, ICData::ic_data_offset())); | 1338 __ ldr(R8, FieldAddress(R9, ICData::ic_data_offset())); |
1339 // R8: ic_data_array with check entries: classes and target functions. | 1339 // R8: ic_data_array with check entries: classes and target functions. |
1340 __ AddImmediate(R8, R8, Array::data_offset() - kHeapObjectTag); | 1340 __ AddImmediate(R8, Array::data_offset() - kHeapObjectTag); |
1341 // R8: points directly to the first ic data array element. | 1341 // R8: points directly to the first ic data array element. |
1342 #if defined(DEBUG) | 1342 #if defined(DEBUG) |
1343 // Check that first entry is for Smi/Smi. | 1343 // Check that first entry is for Smi/Smi. |
1344 Label error, ok; | 1344 Label error, ok; |
1345 const intptr_t imm_smi_cid = reinterpret_cast<intptr_t>(Smi::New(kSmiCid)); | 1345 const intptr_t imm_smi_cid = reinterpret_cast<intptr_t>(Smi::New(kSmiCid)); |
1346 __ ldr(R1, Address(R8, 0)); | 1346 __ ldr(R1, Address(R8, 0)); |
1347 __ CompareImmediate(R1, imm_smi_cid); | 1347 __ CompareImmediate(R1, imm_smi_cid); |
1348 __ b(&error, NE); | 1348 __ b(&error, NE); |
1349 __ ldr(R1, Address(R8, kWordSize)); | 1349 __ ldr(R1, Address(R8, kWordSize)); |
1350 __ CompareImmediate(R1, imm_smi_cid); | 1350 __ CompareImmediate(R1, imm_smi_cid); |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1629 __ LoadIsolate(R8); | 1629 __ LoadIsolate(R8); |
1630 __ ldrb(R8, Address(R8, Isolate::single_step_offset())); | 1630 __ ldrb(R8, Address(R8, Isolate::single_step_offset())); |
1631 __ CompareImmediate(R8, 0); | 1631 __ CompareImmediate(R8, 0); |
1632 __ b(&stepping, NE); | 1632 __ b(&stepping, NE); |
1633 __ Bind(&done_stepping); | 1633 __ Bind(&done_stepping); |
1634 } | 1634 } |
1635 | 1635 |
1636 // R9: IC data object (preserved). | 1636 // R9: IC data object (preserved). |
1637 __ ldr(R8, FieldAddress(R9, ICData::ic_data_offset())); | 1637 __ ldr(R8, FieldAddress(R9, ICData::ic_data_offset())); |
1638 // R8: ic_data_array with entries: target functions and count. | 1638 // R8: ic_data_array with entries: target functions and count. |
1639 __ AddImmediate(R8, R8, Array::data_offset() - kHeapObjectTag); | 1639 __ AddImmediate(R8, Array::data_offset() - kHeapObjectTag); |
1640 // R8: points directly to the first ic data array element. | 1640 // R8: points directly to the first ic data array element. |
1641 const intptr_t target_offset = ICData::TargetIndexFor(0) * kWordSize; | 1641 const intptr_t target_offset = ICData::TargetIndexFor(0) * kWordSize; |
1642 const intptr_t count_offset = ICData::CountIndexFor(0) * kWordSize; | 1642 const intptr_t count_offset = ICData::CountIndexFor(0) * kWordSize; |
1643 | 1643 |
1644 if (FLAG_optimization_counter_threshold >= 0) { | 1644 if (FLAG_optimization_counter_threshold >= 0) { |
1645 // Increment count for this call, ignore overflow. | 1645 // Increment count for this call, ignore overflow. |
1646 __ LoadFromOffset(kWord, R1, R8, count_offset); | 1646 __ LoadFromOffset(kWord, R1, R8, count_offset); |
1647 __ adds(R1, R1, Operand(Smi::RawValue(1))); | 1647 __ adds(R1, R1, Operand(Smi::RawValue(1))); |
1648 __ StoreIntoSmiField(Address(R8, count_offset), R1); | 1648 __ StoreIntoSmiField(Address(R8, count_offset), R1); |
1649 } | 1649 } |
(...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2148 // Called from switchable IC calls. | 2148 // Called from switchable IC calls. |
2149 // R0: receiver | 2149 // R0: receiver |
2150 // R9: ICData (preserved) | 2150 // R9: ICData (preserved) |
2151 // Passed to target: | 2151 // Passed to target: |
2152 // CODE_REG: target Code object | 2152 // CODE_REG: target Code object |
2153 // R4: arguments descriptor | 2153 // R4: arguments descriptor |
2154 void StubCode::GenerateICCallThroughFunctionStub(Assembler* assembler) { | 2154 void StubCode::GenerateICCallThroughFunctionStub(Assembler* assembler) { |
2155 Label loop, found, miss; | 2155 Label loop, found, miss; |
2156 __ ldr(R4, FieldAddress(R9, ICData::arguments_descriptor_offset())); | 2156 __ ldr(R4, FieldAddress(R9, ICData::arguments_descriptor_offset())); |
2157 __ ldr(R8, FieldAddress(R9, ICData::ic_data_offset())); | 2157 __ ldr(R8, FieldAddress(R9, ICData::ic_data_offset())); |
2158 __ AddImmediate(R8, R8, Array::data_offset() - kHeapObjectTag); | 2158 __ AddImmediate(R8, Array::data_offset() - kHeapObjectTag); |
2159 // R8: first IC entry | 2159 // R8: first IC entry |
2160 __ LoadTaggedClassIdMayBeSmi(R1, R0); | 2160 __ LoadTaggedClassIdMayBeSmi(R1, R0); |
2161 // R1: receiver cid as Smi | 2161 // R1: receiver cid as Smi |
2162 | 2162 |
2163 __ Bind(&loop); | 2163 __ Bind(&loop); |
2164 __ ldr(R2, Address(R8, 0)); | 2164 __ ldr(R2, Address(R8, 0)); |
2165 __ cmp(R1, Operand(R2)); | 2165 __ cmp(R1, Operand(R2)); |
2166 __ b(&found, EQ); | 2166 __ b(&found, EQ); |
2167 __ CompareImmediate(R2, Smi::RawValue(kIllegalCid)); | 2167 __ CompareImmediate(R2, Smi::RawValue(kIllegalCid)); |
2168 __ b(&miss, EQ); | 2168 __ b(&miss, EQ); |
(...skipping 14 matching lines...) Expand all Loading... |
2183 __ ldr(CODE_REG, Address(R2, Isolate::ic_miss_code_offset())); | 2183 __ ldr(CODE_REG, Address(R2, Isolate::ic_miss_code_offset())); |
2184 __ ldr(R1, FieldAddress(CODE_REG, Code::entry_point_offset())); | 2184 __ ldr(R1, FieldAddress(CODE_REG, Code::entry_point_offset())); |
2185 __ bx(R1); | 2185 __ bx(R1); |
2186 } | 2186 } |
2187 | 2187 |
2188 | 2188 |
2189 void StubCode::GenerateICCallThroughCodeStub(Assembler* assembler) { | 2189 void StubCode::GenerateICCallThroughCodeStub(Assembler* assembler) { |
2190 Label loop, found, miss; | 2190 Label loop, found, miss; |
2191 __ ldr(R4, FieldAddress(R9, ICData::arguments_descriptor_offset())); | 2191 __ ldr(R4, FieldAddress(R9, ICData::arguments_descriptor_offset())); |
2192 __ ldr(R8, FieldAddress(R9, ICData::ic_data_offset())); | 2192 __ ldr(R8, FieldAddress(R9, ICData::ic_data_offset())); |
2193 __ AddImmediate(R8, R8, Array::data_offset() - kHeapObjectTag); | 2193 __ AddImmediate(R8, Array::data_offset() - kHeapObjectTag); |
2194 // R8: first IC entry | 2194 // R8: first IC entry |
2195 __ LoadTaggedClassIdMayBeSmi(R1, R0); | 2195 __ LoadTaggedClassIdMayBeSmi(R1, R0); |
2196 // R1: receiver cid as Smi | 2196 // R1: receiver cid as Smi |
2197 | 2197 |
2198 __ Bind(&loop); | 2198 __ Bind(&loop); |
2199 __ ldr(R2, Address(R8, 0)); | 2199 __ ldr(R2, Address(R8, 0)); |
2200 __ cmp(R1, Operand(R2)); | 2200 __ cmp(R1, Operand(R2)); |
2201 __ b(&found, EQ); | 2201 __ b(&found, EQ); |
2202 __ CompareImmediate(R2, Smi::RawValue(kIllegalCid)); | 2202 __ CompareImmediate(R2, Smi::RawValue(kIllegalCid)); |
2203 __ b(&miss, EQ); | 2203 __ b(&miss, EQ); |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2313 } | 2313 } |
2314 | 2314 |
2315 | 2315 |
2316 void StubCode::GenerateAsynchronousGapMarkerStub(Assembler* assembler) { | 2316 void StubCode::GenerateAsynchronousGapMarkerStub(Assembler* assembler) { |
2317 __ bkpt(0); | 2317 __ bkpt(0); |
2318 } | 2318 } |
2319 | 2319 |
2320 } // namespace dart | 2320 } // namespace dart |
2321 | 2321 |
2322 #endif // defined TARGET_ARCH_ARM | 2322 #endif // defined TARGET_ARCH_ARM |
OLD | NEW |