| 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 |