| 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/cpu.h" | 9 #include "vm/cpu.h" |
| 10 #include "vm/longjump.h" | 10 #include "vm/longjump.h" |
| (...skipping 2358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2369 // Use a fixed size code sequence, since a function prologue may be patched | 2369 // Use a fixed size code sequence, since a function prologue may be patched |
| 2370 // with this branch sequence. | 2370 // with this branch sequence. |
| 2371 // Contrarily to BranchLinkPatchable, BranchPatchable requires an instruction | 2371 // Contrarily to BranchLinkPatchable, BranchPatchable requires an instruction |
| 2372 // cache flush upon patching. | 2372 // cache flush upon patching. |
| 2373 LoadPatchableImmediate(IP, label->address()); | 2373 LoadPatchableImmediate(IP, label->address()); |
| 2374 bx(IP); | 2374 bx(IP); |
| 2375 } | 2375 } |
| 2376 | 2376 |
| 2377 | 2377 |
| 2378 void Assembler::BranchLink(const ExternalLabel* label) { | 2378 void Assembler::BranchLink(const ExternalLabel* label) { |
| 2379 LoadImmediate(IP, label->address()); // Target address is never patched. | 2379 LoadImmediate(LR, label->address()); // Target address is never patched. |
| 2380 blx(IP); // Use blx instruction so that the return branch prediction works. | 2380 blx(LR); // Use blx instruction so that the return branch prediction works. |
| 2381 } | 2381 } |
| 2382 | 2382 |
| 2383 | 2383 |
| 2384 void Assembler::BranchLinkPatchable(const ExternalLabel* label) { | 2384 void Assembler::BranchLinkPatchable(const ExternalLabel* label) { |
| 2385 // Make sure that class CallPattern is able to patch the label referred | 2385 // Make sure that class CallPattern is able to patch the label referred |
| 2386 // to by this code sequence. | 2386 // to by this code sequence. |
| 2387 // For added code robustness, use 'blx lr' in a patchable sequence and | 2387 // For added code robustness, use 'blx lr' in a patchable sequence and |
| 2388 // use 'blx ip' in a non-patchable sequence (see other BranchLink flavors). | 2388 // use 'blx ip' in a non-patchable sequence (see other BranchLink flavors). |
| 2389 const int32_t offset = | 2389 const int32_t offset = |
| 2390 Array::data_offset() + 4*AddExternalLabel(label) - kHeapObjectTag; | 2390 Array::data_offset() + 4*AddExternalLabel(label) - kHeapObjectTag; |
| (...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2942 // the C++ world. | 2942 // the C++ world. |
| 2943 AddImmediate(SP, -frame_space); | 2943 AddImmediate(SP, -frame_space); |
| 2944 if (OS::ActivationFrameAlignment() > 1) { | 2944 if (OS::ActivationFrameAlignment() > 1) { |
| 2945 bic(SP, SP, Operand(OS::ActivationFrameAlignment() - 1)); | 2945 bic(SP, SP, Operand(OS::ActivationFrameAlignment() - 1)); |
| 2946 } | 2946 } |
| 2947 } | 2947 } |
| 2948 | 2948 |
| 2949 | 2949 |
| 2950 void Assembler::EnterCallRuntimeFrame(intptr_t frame_space) { | 2950 void Assembler::EnterCallRuntimeFrame(intptr_t frame_space) { |
| 2951 // Preserve volatile CPU registers. | 2951 // Preserve volatile CPU registers. |
| 2952 EnterFrame(kDartVolatileCpuRegs | (1 << FP) | (1 << LR), 0); | 2952 EnterFrame(kDartVolatileCpuRegs | (1 << FP), 0); |
| 2953 | 2953 |
| 2954 // Preserve all volatile FPU registers. | 2954 // Preserve all volatile FPU registers. |
| 2955 if (TargetCPUFeatures::vfp_supported()) { | 2955 if (TargetCPUFeatures::vfp_supported()) { |
| 2956 DRegister firstv = EvenDRegisterOf(kDartFirstVolatileFpuReg); | 2956 DRegister firstv = EvenDRegisterOf(kDartFirstVolatileFpuReg); |
| 2957 DRegister lastv = OddDRegisterOf(kDartLastVolatileFpuReg); | 2957 DRegister lastv = OddDRegisterOf(kDartLastVolatileFpuReg); |
| 2958 if ((lastv - firstv + 1) >= 16) { | 2958 if ((lastv - firstv + 1) >= 16) { |
| 2959 DRegister mid = static_cast<DRegister>(firstv + 16); | 2959 DRegister mid = static_cast<DRegister>(firstv + 16); |
| 2960 vstmd(DB_W, SP, mid, lastv - mid + 1); | 2960 vstmd(DB_W, SP, mid, lastv - mid + 1); |
| 2961 vstmd(DB_W, SP, firstv, 16); | 2961 vstmd(DB_W, SP, firstv, 16); |
| 2962 } else { | 2962 } else { |
| 2963 vstmd(DB_W, SP, firstv, lastv - firstv + 1); | 2963 vstmd(DB_W, SP, firstv, lastv - firstv + 1); |
| 2964 } | 2964 } |
| 2965 } | 2965 } |
| 2966 | 2966 |
| 2967 ReserveAlignedFrameSpace(frame_space); | 2967 ReserveAlignedFrameSpace(frame_space); |
| 2968 } | 2968 } |
| 2969 | 2969 |
| 2970 | 2970 |
| 2971 void Assembler::LeaveCallRuntimeFrame() { | 2971 void Assembler::LeaveCallRuntimeFrame() { |
| 2972 // SP might have been modified to reserve space for arguments | 2972 // SP might have been modified to reserve space for arguments |
| 2973 // and ensure proper alignment of the stack frame. | 2973 // and ensure proper alignment of the stack frame. |
| 2974 // We need to restore it before restoring registers. | 2974 // We need to restore it before restoring registers. |
| 2975 const intptr_t kPushedFpuRegisterSize = | 2975 const intptr_t kPushedFpuRegisterSize = |
| 2976 TargetCPUFeatures::vfp_supported() ? | 2976 TargetCPUFeatures::vfp_supported() ? |
| 2977 kDartVolatileFpuRegCount * kFpuRegisterSize : 0; | 2977 kDartVolatileFpuRegCount * kFpuRegisterSize : 0; |
| 2978 | 2978 |
| 2979 // We subtract one from the volatile cpu register count because, even though |
| 2980 // LR is volatile, it is pushed ahead of FP. |
| 2979 const intptr_t kPushedRegistersSize = | 2981 const intptr_t kPushedRegistersSize = |
| 2980 kDartVolatileCpuRegCount * kWordSize + kPushedFpuRegisterSize; | 2982 (kDartVolatileCpuRegCount - 1) * kWordSize + kPushedFpuRegisterSize; |
| 2981 AddImmediate(SP, FP, -kPushedRegistersSize); | 2983 AddImmediate(SP, FP, -kPushedRegistersSize); |
| 2982 | 2984 |
| 2983 // Restore all volatile FPU registers. | 2985 // Restore all volatile FPU registers. |
| 2984 if (TargetCPUFeatures::vfp_supported()) { | 2986 if (TargetCPUFeatures::vfp_supported()) { |
| 2985 DRegister firstv = EvenDRegisterOf(kDartFirstVolatileFpuReg); | 2987 DRegister firstv = EvenDRegisterOf(kDartFirstVolatileFpuReg); |
| 2986 DRegister lastv = OddDRegisterOf(kDartLastVolatileFpuReg); | 2988 DRegister lastv = OddDRegisterOf(kDartLastVolatileFpuReg); |
| 2987 if ((lastv - firstv + 1) >= 16) { | 2989 if ((lastv - firstv + 1) >= 16) { |
| 2988 DRegister mid = static_cast<DRegister>(firstv + 16); | 2990 DRegister mid = static_cast<DRegister>(firstv + 16); |
| 2989 vldmd(IA_W, SP, firstv, 16); | 2991 vldmd(IA_W, SP, firstv, 16); |
| 2990 vldmd(IA_W, SP, mid, lastv - mid + 1); | 2992 vldmd(IA_W, SP, mid, lastv - mid + 1); |
| 2991 } else { | 2993 } else { |
| 2992 vldmd(IA_W, SP, firstv, lastv - firstv + 1); | 2994 vldmd(IA_W, SP, firstv, lastv - firstv + 1); |
| 2993 } | 2995 } |
| 2994 } | 2996 } |
| 2995 | 2997 |
| 2996 // Restore volatile CPU registers. | 2998 // Restore volatile CPU registers. |
| 2997 LeaveFrame(kDartVolatileCpuRegs | (1 << FP) | (1 << LR)); | 2999 LeaveFrame(kDartVolatileCpuRegs | (1 << FP)); |
| 2998 } | 3000 } |
| 2999 | 3001 |
| 3000 | 3002 |
| 3001 void Assembler::CallRuntime(const RuntimeEntry& entry, | 3003 void Assembler::CallRuntime(const RuntimeEntry& entry, |
| 3002 intptr_t argument_count) { | 3004 intptr_t argument_count) { |
| 3003 entry.Call(this, argument_count); | 3005 entry.Call(this, argument_count); |
| 3004 } | 3006 } |
| 3005 | 3007 |
| 3006 | 3008 |
| 3007 void Assembler::EnterDartFrame(intptr_t frame_size) { | 3009 void Assembler::EnterDartFrame(intptr_t frame_size) { |
| (...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3394 | 3396 |
| 3395 | 3397 |
| 3396 const char* Assembler::FpuRegisterName(FpuRegister reg) { | 3398 const char* Assembler::FpuRegisterName(FpuRegister reg) { |
| 3397 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); | 3399 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); |
| 3398 return fpu_reg_names[reg]; | 3400 return fpu_reg_names[reg]; |
| 3399 } | 3401 } |
| 3400 | 3402 |
| 3401 } // namespace dart | 3403 } // namespace dart |
| 3402 | 3404 |
| 3403 #endif // defined TARGET_ARCH_ARM | 3405 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |