Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(767)

Side by Side Diff: runtime/vm/assembler_x64.cc

Issue 317773002: Fix Win64 build of Dart VM. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: address comments Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/assembler_x64.h ('k') | runtime/vm/assembler_x64_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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_X64) 6 #if defined(TARGET_ARCH_X64)
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/heap.h" 10 #include "vm/heap.h"
11 #include "vm/locations.h"
11 #include "vm/memory_region.h" 12 #include "vm/memory_region.h"
12 #include "vm/runtime_entry.h" 13 #include "vm/runtime_entry.h"
13 #include "vm/stack_frame.h" 14 #include "vm/stack_frame.h"
14 #include "vm/stub_code.h" 15 #include "vm/stub_code.h"
15 16
16 namespace dart { 17 namespace dart {
17 18
18 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message."); 19 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message.");
19 DECLARE_FLAG(bool, inline_alloc); 20 DECLARE_FLAG(bool, inline_alloc);
20 21
(...skipping 2788 matching lines...) Expand 10 before | Expand all | Expand 10 after
2809 // the C++ world. 2810 // the C++ world.
2810 if (frame_space != 0) { 2811 if (frame_space != 0) {
2811 subq(RSP, Immediate(frame_space)); 2812 subq(RSP, Immediate(frame_space));
2812 } 2813 }
2813 if (OS::ActivationFrameAlignment() > 1) { 2814 if (OS::ActivationFrameAlignment() > 1) {
2814 andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1))); 2815 andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1)));
2815 } 2816 }
2816 } 2817 }
2817 2818
2818 2819
2819 // TODO(srdjan): Add XMM registers once they are used by the compiler. 2820 void Assembler::PushRegisters(intptr_t cpu_register_set,
2820 // Based on http://x86-64.org/documentation/abi.pdf Fig. 3.4 2821 intptr_t xmm_register_set) {
2821 static const intptr_t kNumberOfVolatileCpuRegisters = 9; 2822 const intptr_t xmm_regs_count = RegisterSet::RegisterCount(xmm_register_set);
2822 static const Register volatile_cpu_registers[kNumberOfVolatileCpuRegisters] = { 2823 if (xmm_regs_count > 0) {
2823 RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11 2824 AddImmediate(RSP, Immediate(-xmm_regs_count * kFpuRegisterSize), PP);
2824 }; 2825 // Store XMM registers with the lowest register number at the lowest
2826 // address.
2827 intptr_t offset = 0;
2828 for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) {
2829 XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx);
2830 if (RegisterSet::Contains(xmm_register_set, xmm_reg)) {
2831 movups(Address(RSP, offset), xmm_reg);
2832 offset += kFpuRegisterSize;
2833 }
2834 }
2835 ASSERT(offset == (xmm_regs_count * kFpuRegisterSize));
2836 }
2825 2837
2826 // XMM0 is used only as a scratch register in the optimized code. No need to 2838 // Store general purpose registers with the highest register number at the
2827 // save it. 2839 // lowest address.
2828 static const intptr_t kNumberOfVolatileXmmRegisters = 2840 for (intptr_t reg_idx = 0; reg_idx < kNumberOfCpuRegisters; ++reg_idx) {
2829 kNumberOfXmmRegisters - 1; 2841 Register reg = static_cast<Register>(reg_idx);
2842 if (RegisterSet::Contains(cpu_register_set, reg)) {
2843 pushq(reg);
2844 }
2845 }
2846 }
2847
2848
2849 void Assembler::PopRegisters(intptr_t cpu_register_set,
2850 intptr_t xmm_register_set) {
2851 // General purpose registers have the highest register number at the
2852 // lowest address.
2853 for (intptr_t reg_idx = kNumberOfCpuRegisters - 1; reg_idx >= 0; --reg_idx) {
2854 Register reg = static_cast<Register>(reg_idx);
2855 if (RegisterSet::Contains(cpu_register_set, reg)) {
2856 popq(reg);
2857 }
2858 }
2859
2860 const intptr_t xmm_regs_count = RegisterSet::RegisterCount(xmm_register_set);
2861 if (xmm_regs_count > 0) {
2862 // XMM registers have the lowest register number at the lowest address.
2863 intptr_t offset = 0;
2864 for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) {
2865 XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx);
2866 if (RegisterSet::Contains(xmm_register_set, xmm_reg)) {
2867 movups(xmm_reg, Address(RSP, offset));
2868 offset += kFpuRegisterSize;
2869 }
2870 }
2871 ASSERT(offset == (xmm_regs_count * kFpuRegisterSize));
2872 AddImmediate(RSP, Immediate(offset), PP);
2873 }
2874 }
2830 2875
2831 2876
2832 void Assembler::EnterCallRuntimeFrame(intptr_t frame_space) { 2877 void Assembler::EnterCallRuntimeFrame(intptr_t frame_space) {
2833 EnterFrame(0); 2878 EnterFrame(0);
2834 2879
2835 // Preserve volatile CPU registers. 2880 // TODO(vegorov): avoid saving FpuTMP, it is used only as scratch.
2836 for (intptr_t i = 0; i < kNumberOfVolatileCpuRegisters; i++) { 2881 PushRegisters(CallingConventions::kVolatileCpuRegisters,
2837 pushq(volatile_cpu_registers[i]); 2882 CallingConventions::kVolatileXmmRegisters);
2838 }
2839
2840 // Preserve all XMM registers except XMM0
2841 subq(RSP, Immediate((kNumberOfXmmRegisters - 1) * kFpuRegisterSize));
2842 // Store XMM registers with the lowest register number at the lowest
2843 // address.
2844 intptr_t offset = 0;
2845 for (intptr_t reg_idx = 1; reg_idx < kNumberOfXmmRegisters; ++reg_idx) {
2846 XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx);
2847 movups(Address(RSP, offset), xmm_reg);
2848 offset += kFpuRegisterSize;
2849 }
2850 2883
2851 ReserveAlignedFrameSpace(frame_space); 2884 ReserveAlignedFrameSpace(frame_space);
2852 } 2885 }
2853 2886
2854 2887
2855 void Assembler::LeaveCallRuntimeFrame() { 2888 void Assembler::LeaveCallRuntimeFrame() {
2856 // RSP might have been modified to reserve space for arguments 2889 // RSP might have been modified to reserve space for arguments
2857 // and ensure proper alignment of the stack frame. 2890 // and ensure proper alignment of the stack frame.
2858 // We need to restore it before restoring registers. 2891 // We need to restore it before restoring registers.
2892 const intptr_t kPushedCpuRegistersCount =
2893 RegisterSet::RegisterCount(CallingConventions::kVolatileCpuRegisters);
2894 const intptr_t kPushedXmmRegistersCount =
2895 RegisterSet::RegisterCount(CallingConventions::kVolatileXmmRegisters);
2859 const intptr_t kPushedRegistersSize = 2896 const intptr_t kPushedRegistersSize =
2860 kNumberOfVolatileCpuRegisters * kWordSize + 2897 kPushedCpuRegistersCount * kWordSize +
2861 kNumberOfVolatileXmmRegisters * kFpuRegisterSize; 2898 kPushedXmmRegistersCount * kFpuRegisterSize;
2862 leaq(RSP, Address(RBP, -kPushedRegistersSize)); 2899 leaq(RSP, Address(RBP, -kPushedRegistersSize));
2863 2900
2864 // Restore all XMM registers except XMM0 2901 // TODO(vegorov): avoid saving FpuTMP, it is used only as scratch.
2865 // XMM registers have the lowest register number at the lowest address. 2902 PopRegisters(CallingConventions::kVolatileCpuRegisters,
2866 intptr_t offset = 0; 2903 CallingConventions::kVolatileXmmRegisters);
2867 for (intptr_t reg_idx = 1; reg_idx < kNumberOfXmmRegisters; ++reg_idx) {
2868 XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx);
2869 movups(xmm_reg, Address(RSP, offset));
2870 offset += kFpuRegisterSize;
2871 }
2872 addq(RSP, Immediate(offset));
2873
2874 // Restore volatile CPU registers.
2875 for (intptr_t i = kNumberOfVolatileCpuRegisters - 1; i >= 0; i--) {
2876 popq(volatile_cpu_registers[i]);
2877 }
2878 2904
2879 leave(); 2905 leave();
2880 } 2906 }
2881 2907
2882 2908
2909 void Assembler::CallCFunction(const ExternalLabel* label) {
2910 // Reserve shadow space for outgoing arguments.
2911 if (CallingConventions::kShadowSpaceBytes != 0) {
2912 subq(RSP, Immediate(CallingConventions::kShadowSpaceBytes));
2913 }
2914 call(label);
2915 }
2916
2917
2918 void Assembler::CallCFunction(Register reg) {
2919 // Reserve shadow space for outgoing arguments.
2920 if (CallingConventions::kShadowSpaceBytes != 0) {
2921 subq(RSP, Immediate(CallingConventions::kShadowSpaceBytes));
2922 }
2923 call(reg);
2924 }
2925
2926
2883 void Assembler::CallRuntime(const RuntimeEntry& entry, 2927 void Assembler::CallRuntime(const RuntimeEntry& entry,
2884 intptr_t argument_count) { 2928 intptr_t argument_count) {
2885 entry.Call(this, argument_count); 2929 entry.Call(this, argument_count);
2886 } 2930 }
2887 2931
2888 2932
2889 void Assembler::LoadPoolPointer(Register pp) { 2933 void Assembler::LoadPoolPointer(Register pp) {
2890 Label next; 2934 Label next;
2891 call(&next); 2935 call(&next);
2892 Bind(&next); 2936 Bind(&next);
(...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after
3310 3354
3311 3355
3312 const char* Assembler::FpuRegisterName(FpuRegister reg) { 3356 const char* Assembler::FpuRegisterName(FpuRegister reg) {
3313 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); 3357 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters));
3314 return xmm_reg_names[reg]; 3358 return xmm_reg_names[reg];
3315 } 3359 }
3316 3360
3317 } // namespace dart 3361 } // namespace dart
3318 3362
3319 #endif // defined TARGET_ARCH_X64 3363 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/assembler_x64.h ('k') | runtime/vm/assembler_x64_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698