| 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/code_generator.h" | 9 #include "vm/code_generator.h" |
| 10 #include "vm/cpu.h" | 10 #include "vm/cpu.h" |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 203 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. | 203 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. |
| 204 ASSERT(argc_tag_offset == 1 * kWordSize); | 204 ASSERT(argc_tag_offset == 1 * kWordSize); |
| 205 // Set argc in NativeArguments: R1 already contains argc. | 205 // Set argc in NativeArguments: R1 already contains argc. |
| 206 | 206 |
| 207 ASSERT(argv_offset == 2 * kWordSize); | 207 ASSERT(argv_offset == 2 * kWordSize); |
| 208 // Set argv in NativeArguments: R2 already contains argv. | 208 // Set argv in NativeArguments: R2 already contains argv. |
| 209 | 209 |
| 210 ASSERT(retval_offset == 3 * kWordSize); | 210 ASSERT(retval_offset == 3 * kWordSize); |
| 211 __ add(R3, FP, Operand(3 * kWordSize)); // Set retval in NativeArgs. | 211 __ add(R3, FP, Operand(3 * kWordSize)); // Set retval in NativeArgs. |
| 212 | 212 |
| 213 // TODO(regis): Should we pass the structure by value as in runtime calls? | 213 // Passing the structure by value as in runtime calls would require changing |
| 214 // It would require changing Dart API for native functions. | 214 // Dart API for native functions. |
| 215 // For now, space is reserved on the stack and we pass a pointer to it. | 215 // For now, space is reserved on the stack and we pass a pointer to it. |
| 216 __ stm(IA, SP, (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3)); | 216 __ stm(IA, SP, (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3)); |
| 217 __ mov(R0, Operand(SP)); // Pass the pointer to the NativeArguments. | 217 __ mov(R0, Operand(SP)); // Pass the pointer to the NativeArguments. |
| 218 | 218 |
| 219 // Call native function (setsup scope if not leaf function). | 219 // Call native function (setsup scope if not leaf function). |
| 220 Label leaf_call; | 220 Label leaf_call; |
| 221 Label done; | 221 Label done; |
| 222 __ TestImmediate(R1, NativeArguments::AutoSetupScopeMask()); | 222 __ TestImmediate(R1, NativeArguments::AutoSetupScopeMask()); |
| 223 __ b(&leaf_call, EQ); | 223 __ b(&leaf_call, EQ); |
| 224 | 224 |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 324 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. | 324 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. |
| 325 ASSERT(argc_tag_offset == 1 * kWordSize); | 325 ASSERT(argc_tag_offset == 1 * kWordSize); |
| 326 // Set argc in NativeArguments: R1 already contains argc. | 326 // Set argc in NativeArguments: R1 already contains argc. |
| 327 | 327 |
| 328 ASSERT(argv_offset == 2 * kWordSize); | 328 ASSERT(argv_offset == 2 * kWordSize); |
| 329 // Set argv in NativeArguments: R2 already contains argv. | 329 // Set argv in NativeArguments: R2 already contains argv. |
| 330 | 330 |
| 331 ASSERT(retval_offset == 3 * kWordSize); | 331 ASSERT(retval_offset == 3 * kWordSize); |
| 332 __ add(R3, FP, Operand(3 * kWordSize)); // Set retval in NativeArgs. | 332 __ add(R3, FP, Operand(3 * kWordSize)); // Set retval in NativeArgs. |
| 333 | 333 |
| 334 // TODO(regis): Should we pass the structure by value as in runtime calls? | 334 // Passing the structure by value as in runtime calls would require changing |
| 335 // It would require changing Dart API for native functions. | 335 // Dart API for native functions. |
| 336 // For now, space is reserved on the stack and we pass a pointer to it. | 336 // For now, space is reserved on the stack and we pass a pointer to it. |
| 337 __ stm(IA, SP, (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3)); | 337 __ stm(IA, SP, (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3)); |
| 338 __ mov(R0, Operand(SP)); // Pass the pointer to the NativeArguments. | 338 __ mov(R0, Operand(SP)); // Pass the pointer to the NativeArguments. |
| 339 | 339 |
| 340 // Call native function or redirection via simulator. | 340 // Call native function or redirection via simulator. |
| 341 __ blx(R5); | 341 __ blx(R5); |
| 342 | 342 |
| 343 // Mark that the isolate is executing Dart code. | 343 // Mark that the isolate is executing Dart code. |
| 344 __ LoadImmediate(R2, VMTag::kScriptTagId); | 344 __ LoadImmediate(R2, VMTag::kScriptTagId); |
| 345 __ StoreToOffset(kWord, R2, CTX, Isolate::vm_tag_offset()); | 345 __ StoreToOffset(kWord, R2, CTX, Isolate::vm_tag_offset()); |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 473 // is no need to set the correct PC marker or load PP, since they get patched. | 473 // is no need to set the correct PC marker or load PP, since they get patched. |
| 474 __ mov(IP, Operand(LR)); | 474 __ mov(IP, Operand(LR)); |
| 475 __ mov(LR, Operand(0)); | 475 __ mov(LR, Operand(0)); |
| 476 __ EnterFrame((1 << PP) | (1 << FP) | (1 << IP) | (1 << LR), 0); | 476 __ EnterFrame((1 << PP) | (1 << FP) | (1 << IP) | (1 << LR), 0); |
| 477 // The code in this frame may not cause GC. kDeoptimizeCopyFrameRuntimeEntry | 477 // The code in this frame may not cause GC. kDeoptimizeCopyFrameRuntimeEntry |
| 478 // and kDeoptimizeFillFrameRuntimeEntry are leaf runtime calls. | 478 // and kDeoptimizeFillFrameRuntimeEntry are leaf runtime calls. |
| 479 const intptr_t saved_result_slot_from_fp = | 479 const intptr_t saved_result_slot_from_fp = |
| 480 kFirstLocalSlotFromFp + 1 - (kNumberOfCpuRegisters - R0); | 480 kFirstLocalSlotFromFp + 1 - (kNumberOfCpuRegisters - R0); |
| 481 // Result in R0 is preserved as part of pushing all registers below. | 481 // Result in R0 is preserved as part of pushing all registers below. |
| 482 | 482 |
| 483 // TODO(regis): Should we align the stack before pushing the fpu registers? | |
| 484 // If we do, saved_r0_offset_from_fp is not constant anymore. | |
| 485 | |
| 486 // Push registers in their enumeration order: lowest register number at | 483 // Push registers in their enumeration order: lowest register number at |
| 487 // lowest address. | 484 // lowest address. |
| 488 __ PushList(kAllCpuRegistersList); | 485 __ PushList(kAllCpuRegistersList); |
| 489 | 486 |
| 490 if (TargetCPUFeatures::vfp_supported()) { | 487 if (TargetCPUFeatures::vfp_supported()) { |
| 491 ASSERT(kFpuRegisterSize == 4 * kWordSize); | 488 ASSERT(kFpuRegisterSize == 4 * kWordSize); |
| 492 if (kNumberOfDRegisters > 16) { | 489 if (kNumberOfDRegisters > 16) { |
| 493 __ vstmd(DB_W, SP, D16, kNumberOfDRegisters - 16); | 490 __ vstmd(DB_W, SP, D16, kNumberOfDRegisters - 16); |
| 494 __ vstmd(DB_W, SP, D0, 16); | 491 __ vstmd(DB_W, SP, D0, 16); |
| 495 } else { | 492 } else { |
| (...skipping 1365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1861 const Register right = R0; | 1858 const Register right = R0; |
| 1862 __ ldr(left, Address(SP, 1 * kWordSize)); | 1859 __ ldr(left, Address(SP, 1 * kWordSize)); |
| 1863 __ ldr(right, Address(SP, 0 * kWordSize)); | 1860 __ ldr(right, Address(SP, 0 * kWordSize)); |
| 1864 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 1861 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); |
| 1865 __ Ret(); | 1862 __ Ret(); |
| 1866 } | 1863 } |
| 1867 | 1864 |
| 1868 } // namespace dart | 1865 } // namespace dart |
| 1869 | 1866 |
| 1870 #endif // defined TARGET_ARCH_ARM | 1867 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |