OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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_ARM64) | 6 #if defined(TARGET_ARCH_ARM64) |
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/compiler.h" | 10 #include "vm/compiler.h" |
(...skipping 30 matching lines...) Expand all Loading... |
41 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); | 41 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
42 const intptr_t argv_offset = NativeArguments::argv_offset(); | 42 const intptr_t argv_offset = NativeArguments::argv_offset(); |
43 const intptr_t retval_offset = NativeArguments::retval_offset(); | 43 const intptr_t retval_offset = NativeArguments::retval_offset(); |
44 const intptr_t exitframe_last_param_slot_from_fp = 1; | 44 const intptr_t exitframe_last_param_slot_from_fp = 1; |
45 | 45 |
46 __ SetPrologueOffset(); | 46 __ SetPrologueOffset(); |
47 __ Comment("CallToRuntimeStub"); | 47 __ Comment("CallToRuntimeStub"); |
48 __ EnterStubFrame(); | 48 __ EnterStubFrame(); |
49 | 49 |
50 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R28)) != 0); | 50 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R28)) != 0); |
51 __ LoadIsolate(R28, kNoPP); | 51 __ LoadIsolate(R28); |
52 | 52 |
53 // Save exit frame information to enable stack walking as we are about | 53 // Save exit frame information to enable stack walking as we are about |
54 // to transition to Dart VM C++ code. | 54 // to transition to Dart VM C++ code. |
55 __ StoreToOffset(FP, THR, Thread::top_exit_frame_info_offset(), kNoPP); | 55 __ StoreToOffset(FP, THR, Thread::top_exit_frame_info_offset(), kNoPP); |
56 | 56 |
57 #if defined(DEBUG) | 57 #if defined(DEBUG) |
58 { Label ok; | 58 { Label ok; |
59 // Check that we are always entering from Dart code. | 59 // Check that we are always entering from Dart code. |
60 __ LoadFromOffset(R8, R28, Isolate::vm_tag_offset(), kNoPP); | 60 __ LoadFromOffset(R8, R28, Isolate::vm_tag_offset(), kNoPP); |
61 __ CompareImmediate(R8, VMTag::kDartTagId, kNoPP); | 61 __ CompareImmediate(R8, VMTag::kDartTagId, kNoPP); |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 // R1 : argc_tag including number of arguments and function kind. | 141 // R1 : argc_tag including number of arguments and function kind. |
142 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) { | 142 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) { |
143 const intptr_t thread_offset = NativeArguments::thread_offset(); | 143 const intptr_t thread_offset = NativeArguments::thread_offset(); |
144 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); | 144 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
145 const intptr_t argv_offset = NativeArguments::argv_offset(); | 145 const intptr_t argv_offset = NativeArguments::argv_offset(); |
146 const intptr_t retval_offset = NativeArguments::retval_offset(); | 146 const intptr_t retval_offset = NativeArguments::retval_offset(); |
147 | 147 |
148 __ EnterStubFrame(); | 148 __ EnterStubFrame(); |
149 | 149 |
150 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R28)) != 0); | 150 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R28)) != 0); |
151 __ LoadIsolate(R28, kNoPP); | 151 __ LoadIsolate(R28); |
152 | 152 |
153 // Save exit frame information to enable stack walking as we are about | 153 // Save exit frame information to enable stack walking as we are about |
154 // to transition to native code. | 154 // to transition to native code. |
155 __ StoreToOffset(FP, THR, Thread::top_exit_frame_info_offset(), kNoPP); | 155 __ StoreToOffset(FP, THR, Thread::top_exit_frame_info_offset(), kNoPP); |
156 | 156 |
157 #if defined(DEBUG) | 157 #if defined(DEBUG) |
158 { Label ok; | 158 { Label ok; |
159 // Check that we are always entering from Dart code. | 159 // Check that we are always entering from Dart code. |
160 __ LoadFromOffset(R6, R28, Isolate::vm_tag_offset(), kNoPP); | 160 __ LoadFromOffset(R6, R28, Isolate::vm_tag_offset(), kNoPP); |
161 __ CompareImmediate(R6, VMTag::kDartTagId, kNoPP); | 161 __ CompareImmediate(R6, VMTag::kDartTagId, kNoPP); |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
243 // R1 : argc_tag including number of arguments and function kind. | 243 // R1 : argc_tag including number of arguments and function kind. |
244 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) { | 244 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) { |
245 const intptr_t thread_offset = NativeArguments::thread_offset(); | 245 const intptr_t thread_offset = NativeArguments::thread_offset(); |
246 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); | 246 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
247 const intptr_t argv_offset = NativeArguments::argv_offset(); | 247 const intptr_t argv_offset = NativeArguments::argv_offset(); |
248 const intptr_t retval_offset = NativeArguments::retval_offset(); | 248 const intptr_t retval_offset = NativeArguments::retval_offset(); |
249 | 249 |
250 __ EnterStubFrame(); | 250 __ EnterStubFrame(); |
251 | 251 |
252 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R28)) != 0); | 252 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R28)) != 0); |
253 __ LoadIsolate(R28, kNoPP); | 253 __ LoadIsolate(R28); |
254 | 254 |
255 // Save exit frame information to enable stack walking as we are about | 255 // Save exit frame information to enable stack walking as we are about |
256 // to transition to native code. | 256 // to transition to native code. |
257 __ StoreToOffset(FP, THR, Thread::top_exit_frame_info_offset(), kNoPP); | 257 __ StoreToOffset(FP, THR, Thread::top_exit_frame_info_offset(), kNoPP); |
258 | 258 |
259 #if defined(DEBUG) | 259 #if defined(DEBUG) |
260 { Label ok; | 260 { Label ok; |
261 // Check that we are always entering from Dart code. | 261 // Check that we are always entering from Dart code. |
262 __ LoadFromOffset(R6, R28, Isolate::vm_tag_offset(), kNoPP); | 262 __ LoadFromOffset(R6, R28, Isolate::vm_tag_offset(), kNoPP); |
263 __ CompareImmediate(R6, VMTag::kDartTagId, kNoPP); | 263 __ CompareImmediate(R6, VMTag::kDartTagId, kNoPP); |
(...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
834 // We now load the pool pointer(PP) as we are about to invoke dart code and we | 834 // We now load the pool pointer(PP) as we are about to invoke dart code and we |
835 // could potentially invoke some intrinsic functions which need the PP to be | 835 // could potentially invoke some intrinsic functions which need the PP to be |
836 // set up. | 836 // set up. |
837 __ LoadPoolPointer(PP); | 837 __ LoadPoolPointer(PP); |
838 | 838 |
839 // Set up THR, which caches the current thread in Dart code. | 839 // Set up THR, which caches the current thread in Dart code. |
840 if (THR != R3) { | 840 if (THR != R3) { |
841 __ mov(THR, R3); | 841 __ mov(THR, R3); |
842 } | 842 } |
843 // Load Isolate pointer into temporary register R5. | 843 // Load Isolate pointer into temporary register R5. |
844 __ LoadIsolate(R5, PP); | 844 __ LoadIsolate(R5); |
845 | 845 |
846 // Save the current VMTag on the stack. | 846 // Save the current VMTag on the stack. |
847 __ LoadFromOffset(R4, R5, Isolate::vm_tag_offset(), PP); | 847 __ LoadFromOffset(R4, R5, Isolate::vm_tag_offset(), PP); |
848 __ Push(R4); | 848 __ Push(R4); |
849 | 849 |
850 // Mark that the isolate is executing Dart code. | 850 // Mark that the isolate is executing Dart code. |
851 __ LoadImmediate(R6, VMTag::kDartTagId, PP); | 851 __ LoadImmediate(R6, VMTag::kDartTagId, PP); |
852 __ StoreToOffset(R6, R5, Isolate::vm_tag_offset(), PP); | 852 __ StoreToOffset(R6, R5, Isolate::vm_tag_offset(), PP); |
853 | 853 |
854 // Save top resource and top exit frame info. Use R6 as a temporary register. | 854 // Save top resource and top exit frame info. Use R6 as a temporary register. |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
891 // Call the Dart code entrypoint. | 891 // Call the Dart code entrypoint. |
892 __ blr(R0); // R4 is the arguments descriptor array. | 892 __ blr(R0); // R4 is the arguments descriptor array. |
893 __ Comment("InvokeDartCodeStub return"); | 893 __ Comment("InvokeDartCodeStub return"); |
894 | 894 |
895 // Restore constant pool pointer after return. | 895 // Restore constant pool pointer after return. |
896 __ LoadPoolPointer(PP); | 896 __ LoadPoolPointer(PP); |
897 | 897 |
898 // Get rid of arguments pushed on the stack. | 898 // Get rid of arguments pushed on the stack. |
899 __ AddImmediate(SP, FP, kExitLinkSlotFromEntryFp * kWordSize, PP); | 899 __ AddImmediate(SP, FP, kExitLinkSlotFromEntryFp * kWordSize, PP); |
900 | 900 |
901 __ LoadIsolate(R28, PP); | 901 __ LoadIsolate(R28); |
902 | 902 |
903 // Restore the saved top exit frame info and top resource back into the | 903 // Restore the saved top exit frame info and top resource back into the |
904 // Isolate structure. Uses R6 as a temporary register for this. | 904 // Isolate structure. Uses R6 as a temporary register for this. |
905 __ Pop(R6); | 905 __ Pop(R6); |
906 __ StoreToOffset(R6, THR, Thread::top_exit_frame_info_offset(), PP); | 906 __ StoreToOffset(R6, THR, Thread::top_exit_frame_info_offset(), PP); |
907 __ Pop(R6); | 907 __ Pop(R6); |
908 __ StoreToOffset(R6, THR, Thread::top_resource_offset(), PP); | 908 __ StoreToOffset(R6, THR, Thread::top_resource_offset(), PP); |
909 | 909 |
910 // Restore the current VMTag from the stack. | 910 // Restore the current VMTag from the stack. |
911 __ Pop(R4); | 911 __ Pop(R4); |
(...skipping 514 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1426 __ CompareImmediate(R6, num_args, kNoPP); | 1426 __ CompareImmediate(R6, num_args, kNoPP); |
1427 __ b(&ok, EQ); | 1427 __ b(&ok, EQ); |
1428 __ Stop("Incorrect stub for IC data"); | 1428 __ Stop("Incorrect stub for IC data"); |
1429 __ Bind(&ok); | 1429 __ Bind(&ok); |
1430 } | 1430 } |
1431 #endif // DEBUG | 1431 #endif // DEBUG |
1432 | 1432 |
1433 Label stepping, done_stepping; | 1433 Label stepping, done_stepping; |
1434 if (FLAG_support_debugger && !optimized) { | 1434 if (FLAG_support_debugger && !optimized) { |
1435 __ Comment("Check single stepping"); | 1435 __ Comment("Check single stepping"); |
1436 __ LoadIsolate(R6, kNoPP); | 1436 __ LoadIsolate(R6); |
1437 __ LoadFromOffset( | 1437 __ LoadFromOffset( |
1438 R6, R6, Isolate::single_step_offset(), kNoPP, kUnsignedByte); | 1438 R6, R6, Isolate::single_step_offset(), kNoPP, kUnsignedByte); |
1439 __ CompareRegisters(R6, ZR); | 1439 __ CompareRegisters(R6, ZR); |
1440 __ b(&stepping, NE); | 1440 __ b(&stepping, NE); |
1441 __ Bind(&done_stepping); | 1441 __ Bind(&done_stepping); |
1442 } | 1442 } |
1443 | 1443 |
1444 __ Comment("Range feedback collection"); | 1444 __ Comment("Range feedback collection"); |
1445 Label not_smi_or_overflow; | 1445 Label not_smi_or_overflow; |
1446 if (range_collection_mode == kCollectRanges) { | 1446 if (range_collection_mode == kCollectRanges) { |
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1720 __ CompareImmediate(R6, 0, kNoPP); | 1720 __ CompareImmediate(R6, 0, kNoPP); |
1721 __ b(&ok, EQ); | 1721 __ b(&ok, EQ); |
1722 __ Stop("Incorrect IC data for unoptimized static call"); | 1722 __ Stop("Incorrect IC data for unoptimized static call"); |
1723 __ Bind(&ok); | 1723 __ Bind(&ok); |
1724 } | 1724 } |
1725 #endif // DEBUG | 1725 #endif // DEBUG |
1726 | 1726 |
1727 // Check single stepping. | 1727 // Check single stepping. |
1728 Label stepping, done_stepping; | 1728 Label stepping, done_stepping; |
1729 if (FLAG_support_debugger) { | 1729 if (FLAG_support_debugger) { |
1730 __ LoadIsolate(R6, kNoPP); | 1730 __ LoadIsolate(R6); |
1731 __ LoadFromOffset( | 1731 __ LoadFromOffset( |
1732 R6, R6, Isolate::single_step_offset(), kNoPP, kUnsignedByte); | 1732 R6, R6, Isolate::single_step_offset(), kNoPP, kUnsignedByte); |
1733 __ CompareImmediate(R6, 0, kNoPP); | 1733 __ CompareImmediate(R6, 0, kNoPP); |
1734 __ b(&stepping, NE); | 1734 __ b(&stepping, NE); |
1735 __ Bind(&done_stepping); | 1735 __ Bind(&done_stepping); |
1736 } | 1736 } |
1737 | 1737 |
1738 // R5: IC data object (preserved). | 1738 // R5: IC data object (preserved). |
1739 __ LoadFieldFromOffset(R6, R5, ICData::ic_data_offset(), kNoPP); | 1739 __ LoadFieldFromOffset(R6, R5, ICData::ic_data_offset(), kNoPP); |
1740 // R6: ic_data_array with entries: target functions and count. | 1740 // R6: ic_data_array with entries: target functions and count. |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1836 __ Pop(R0); | 1836 __ Pop(R0); |
1837 __ LeaveStubFrame(); | 1837 __ LeaveStubFrame(); |
1838 __ br(R0); | 1838 __ br(R0); |
1839 } | 1839 } |
1840 | 1840 |
1841 // Called only from unoptimized code. All relevant registers have been saved. | 1841 // Called only from unoptimized code. All relevant registers have been saved. |
1842 void StubCode::GenerateDebugStepCheckStub( | 1842 void StubCode::GenerateDebugStepCheckStub( |
1843 Assembler* assembler) { | 1843 Assembler* assembler) { |
1844 // Check single stepping. | 1844 // Check single stepping. |
1845 Label stepping, done_stepping; | 1845 Label stepping, done_stepping; |
1846 __ LoadIsolate(R1, kNoPP); | 1846 __ LoadIsolate(R1); |
1847 __ LoadFromOffset( | 1847 __ LoadFromOffset( |
1848 R1, R1, Isolate::single_step_offset(), kNoPP, kUnsignedByte); | 1848 R1, R1, Isolate::single_step_offset(), kNoPP, kUnsignedByte); |
1849 __ CompareImmediate(R1, 0, kNoPP); | 1849 __ CompareImmediate(R1, 0, kNoPP); |
1850 __ b(&stepping, NE); | 1850 __ b(&stepping, NE); |
1851 __ Bind(&done_stepping); | 1851 __ Bind(&done_stepping); |
1852 | 1852 |
1853 __ ret(); | 1853 __ ret(); |
1854 | 1854 |
1855 __ Bind(&stepping); | 1855 __ Bind(&stepping); |
1856 __ EnterStubFrame(); | 1856 __ EnterStubFrame(); |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1984 // Does not return. | 1984 // Does not return. |
1985 void StubCode::GenerateJumpToExceptionHandlerStub(Assembler* assembler) { | 1985 void StubCode::GenerateJumpToExceptionHandlerStub(Assembler* assembler) { |
1986 ASSERT(kExceptionObjectReg == R0); | 1986 ASSERT(kExceptionObjectReg == R0); |
1987 ASSERT(kStackTraceObjectReg == R1); | 1987 ASSERT(kStackTraceObjectReg == R1); |
1988 __ mov(LR, R0); // Program counter. | 1988 __ mov(LR, R0); // Program counter. |
1989 __ mov(SP, R1); // Stack pointer. | 1989 __ mov(SP, R1); // Stack pointer. |
1990 __ mov(FP, R2); // Frame_pointer. | 1990 __ mov(FP, R2); // Frame_pointer. |
1991 __ mov(R0, R3); // Exception object. | 1991 __ mov(R0, R3); // Exception object. |
1992 __ mov(R1, R4); // StackTrace object. | 1992 __ mov(R1, R4); // StackTrace object. |
1993 __ mov(THR, R5); | 1993 __ mov(THR, R5); |
1994 __ LoadIsolate(R5, kNoPP); | 1994 __ LoadIsolate(R5); |
1995 // Set the tag. | 1995 // Set the tag. |
1996 __ LoadImmediate(R2, VMTag::kDartTagId, kNoPP); | 1996 __ LoadImmediate(R2, VMTag::kDartTagId, kNoPP); |
1997 __ StoreToOffset(R2, R5, Isolate::vm_tag_offset(), kNoPP); | 1997 __ StoreToOffset(R2, R5, Isolate::vm_tag_offset(), kNoPP); |
1998 // Clear top exit frame. | 1998 // Clear top exit frame. |
1999 __ StoreToOffset(ZR, THR, Thread::top_exit_frame_info_offset(), kNoPP); | 1999 __ StoreToOffset(ZR, THR, Thread::top_exit_frame_info_offset(), kNoPP); |
2000 __ ret(); // Jump to the exception handler code. | 2000 __ ret(); // Jump to the exception handler code. |
2001 } | 2001 } |
2002 | 2002 |
2003 | 2003 |
2004 // Calls to the runtime to optimize the given function. | 2004 // Calls to the runtime to optimize the given function. |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2091 // Called only from unoptimized code. All relevant registers have been saved. | 2091 // Called only from unoptimized code. All relevant registers have been saved. |
2092 // LR: return address. | 2092 // LR: return address. |
2093 // SP + 4: left operand. | 2093 // SP + 4: left operand. |
2094 // SP + 0: right operand. | 2094 // SP + 0: right operand. |
2095 // Return Zero condition flag set if equal. | 2095 // Return Zero condition flag set if equal. |
2096 void StubCode::GenerateUnoptimizedIdenticalWithNumberCheckStub( | 2096 void StubCode::GenerateUnoptimizedIdenticalWithNumberCheckStub( |
2097 Assembler* assembler) { | 2097 Assembler* assembler) { |
2098 // Check single stepping. | 2098 // Check single stepping. |
2099 Label stepping, done_stepping; | 2099 Label stepping, done_stepping; |
2100 if (FLAG_support_debugger) { | 2100 if (FLAG_support_debugger) { |
2101 __ LoadIsolate(R1, kNoPP); | 2101 __ LoadIsolate(R1); |
2102 __ LoadFromOffset( | 2102 __ LoadFromOffset( |
2103 R1, R1, Isolate::single_step_offset(), kNoPP, kUnsignedByte); | 2103 R1, R1, Isolate::single_step_offset(), kNoPP, kUnsignedByte); |
2104 __ CompareImmediate(R1, 0, kNoPP); | 2104 __ CompareImmediate(R1, 0, kNoPP); |
2105 __ b(&stepping, NE); | 2105 __ b(&stepping, NE); |
2106 __ Bind(&done_stepping); | 2106 __ Bind(&done_stepping); |
2107 } | 2107 } |
2108 | 2108 |
2109 const Register left = R1; | 2109 const Register left = R1; |
2110 const Register right = R0; | 2110 const Register right = R0; |
2111 __ LoadFromOffset(left, SP, 1 * kWordSize, kNoPP); | 2111 __ LoadFromOffset(left, SP, 1 * kWordSize, kNoPP); |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2189 // Result: | 2189 // Result: |
2190 // R1: entry point. | 2190 // R1: entry point. |
2191 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { | 2191 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { |
2192 EmitMegamorphicLookup(assembler, R0, R1, R1); | 2192 EmitMegamorphicLookup(assembler, R0, R1, R1); |
2193 __ ret(); | 2193 __ ret(); |
2194 } | 2194 } |
2195 | 2195 |
2196 } // namespace dart | 2196 } // namespace dart |
2197 | 2197 |
2198 #endif // defined TARGET_ARCH_ARM64 | 2198 #endif // defined TARGET_ARCH_ARM64 |
OLD | NEW |