| 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 26 matching lines...) Expand all Loading... |
| 37 // R4 : number of arguments to the call. | 37 // R4 : number of arguments to the call. |
| 38 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { | 38 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { |
| 39 const intptr_t thread_offset = NativeArguments::thread_offset(); | 39 const intptr_t thread_offset = NativeArguments::thread_offset(); |
| 40 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); | 40 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
| 41 const intptr_t argv_offset = NativeArguments::argv_offset(); | 41 const intptr_t argv_offset = NativeArguments::argv_offset(); |
| 42 const intptr_t retval_offset = NativeArguments::retval_offset(); | 42 const intptr_t retval_offset = NativeArguments::retval_offset(); |
| 43 const intptr_t exitframe_last_param_slot_from_fp = 1; | 43 const intptr_t exitframe_last_param_slot_from_fp = 1; |
| 44 | 44 |
| 45 __ SetPrologueOffset(); | 45 __ SetPrologueOffset(); |
| 46 __ Comment("CallToRuntimeStub"); | 46 __ Comment("CallToRuntimeStub"); |
| 47 __ EnterFrame(0); | 47 __ EnterStubFrame(); |
| 48 | 48 |
| 49 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R28)) != 0); | 49 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R28)) != 0); |
| 50 __ LoadIsolate(R28, kNoPP); | 50 __ LoadIsolate(R28, kNoPP); |
| 51 | 51 |
| 52 // Save exit frame information to enable stack walking as we are about | 52 // Save exit frame information to enable stack walking as we are about |
| 53 // to transition to Dart VM C++ code. | 53 // to transition to Dart VM C++ code. |
| 54 __ StoreToOffset(FP, R28, Isolate::top_exit_frame_info_offset(), kNoPP); | 54 __ StoreToOffset(FP, R28, Isolate::top_exit_frame_info_offset(), kNoPP); |
| 55 | 55 |
| 56 #if defined(DEBUG) | 56 #if defined(DEBUG) |
| 57 { Label ok; | 57 { Label ok; |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 115 __ mov(CSP, R26); | 115 __ mov(CSP, R26); |
| 116 | 116 |
| 117 // Retval is next to 1st argument. | 117 // Retval is next to 1st argument. |
| 118 // Mark that the isolate is executing Dart code. | 118 // Mark that the isolate is executing Dart code. |
| 119 __ LoadImmediate(R2, VMTag::kDartTagId, kNoPP); | 119 __ LoadImmediate(R2, VMTag::kDartTagId, kNoPP); |
| 120 __ StoreToOffset(R2, R28, Isolate::vm_tag_offset(), kNoPP); | 120 __ StoreToOffset(R2, R28, Isolate::vm_tag_offset(), kNoPP); |
| 121 | 121 |
| 122 // Reset exit frame information in Isolate structure. | 122 // Reset exit frame information in Isolate structure. |
| 123 __ StoreToOffset(ZR, R28, Isolate::top_exit_frame_info_offset(), kNoPP); | 123 __ StoreToOffset(ZR, R28, Isolate::top_exit_frame_info_offset(), kNoPP); |
| 124 | 124 |
| 125 __ LeaveFrame(); | 125 __ LeaveStubFrame(); |
| 126 __ ret(); | 126 __ ret(); |
| 127 } | 127 } |
| 128 | 128 |
| 129 | 129 |
| 130 void StubCode::GeneratePrintStopMessageStub(Assembler* assembler) { | 130 void StubCode::GeneratePrintStopMessageStub(Assembler* assembler) { |
| 131 __ Stop("GeneratePrintStopMessageStub"); | 131 __ Stop("GeneratePrintStopMessageStub"); |
| 132 } | 132 } |
| 133 | 133 |
| 134 | 134 |
| 135 // Input parameters: | 135 // Input parameters: |
| 136 // LR : return address. | 136 // LR : return address. |
| 137 // SP : address of return value. | 137 // SP : address of return value. |
| 138 // R5 : address of the native function to call. | 138 // R5 : address of the native function to call. |
| 139 // R2 : address of first argument in argument array. | 139 // R2 : address of first argument in argument array. |
| 140 // R1 : argc_tag including number of arguments and function kind. | 140 // R1 : argc_tag including number of arguments and function kind. |
| 141 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) { | 141 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) { |
| 142 const intptr_t thread_offset = NativeArguments::thread_offset(); | 142 const intptr_t thread_offset = NativeArguments::thread_offset(); |
| 143 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); | 143 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
| 144 const intptr_t argv_offset = NativeArguments::argv_offset(); | 144 const intptr_t argv_offset = NativeArguments::argv_offset(); |
| 145 const intptr_t retval_offset = NativeArguments::retval_offset(); | 145 const intptr_t retval_offset = NativeArguments::retval_offset(); |
| 146 | 146 |
| 147 __ EnterFrame(0); | 147 __ EnterStubFrame(); |
| 148 | 148 |
| 149 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R28)) != 0); | 149 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R28)) != 0); |
| 150 __ LoadIsolate(R28, kNoPP); | 150 __ LoadIsolate(R28, kNoPP); |
| 151 | 151 |
| 152 // Save exit frame information to enable stack walking as we are about | 152 // Save exit frame information to enable stack walking as we are about |
| 153 // to transition to native code. | 153 // to transition to native code. |
| 154 __ StoreToOffset(FP, R28, Isolate::top_exit_frame_info_offset(), kNoPP); | 154 __ StoreToOffset(FP, R28, Isolate::top_exit_frame_info_offset(), kNoPP); |
| 155 | 155 |
| 156 #if defined(DEBUG) | 156 #if defined(DEBUG) |
| 157 { Label ok; | 157 { Label ok; |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 222 __ mov(SP, CSP); | 222 __ mov(SP, CSP); |
| 223 __ mov(CSP, R26); | 223 __ mov(CSP, R26); |
| 224 | 224 |
| 225 // Mark that the isolate is executing Dart code. | 225 // Mark that the isolate is executing Dart code. |
| 226 __ LoadImmediate(R2, VMTag::kDartTagId, kNoPP); | 226 __ LoadImmediate(R2, VMTag::kDartTagId, kNoPP); |
| 227 __ StoreToOffset(R2, R28, Isolate::vm_tag_offset(), kNoPP); | 227 __ StoreToOffset(R2, R28, Isolate::vm_tag_offset(), kNoPP); |
| 228 | 228 |
| 229 // Reset exit frame information in Isolate structure. | 229 // Reset exit frame information in Isolate structure. |
| 230 __ StoreToOffset(ZR, R28, Isolate::top_exit_frame_info_offset(), kNoPP); | 230 __ StoreToOffset(ZR, R28, Isolate::top_exit_frame_info_offset(), kNoPP); |
| 231 | 231 |
| 232 __ LeaveFrame(); | 232 __ LeaveStubFrame(); |
| 233 __ ret(); | 233 __ ret(); |
| 234 } | 234 } |
| 235 | 235 |
| 236 | 236 |
| 237 // Input parameters: | 237 // Input parameters: |
| 238 // LR : return address. | 238 // LR : return address. |
| 239 // SP : address of return value. | 239 // SP : address of return value. |
| 240 // R5 : address of the native function to call. | 240 // R5 : address of the native function to call. |
| 241 // R2 : address of first argument in argument array. | 241 // R2 : address of first argument in argument array. |
| 242 // R1 : argc_tag including number of arguments and function kind. | 242 // R1 : argc_tag including number of arguments and function kind. |
| 243 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) { | 243 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) { |
| 244 const intptr_t thread_offset = NativeArguments::thread_offset(); | 244 const intptr_t thread_offset = NativeArguments::thread_offset(); |
| 245 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); | 245 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
| 246 const intptr_t argv_offset = NativeArguments::argv_offset(); | 246 const intptr_t argv_offset = NativeArguments::argv_offset(); |
| 247 const intptr_t retval_offset = NativeArguments::retval_offset(); | 247 const intptr_t retval_offset = NativeArguments::retval_offset(); |
| 248 | 248 |
| 249 __ EnterFrame(0); | 249 __ EnterStubFrame(); |
| 250 | 250 |
| 251 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R28)) != 0); | 251 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R28)) != 0); |
| 252 __ LoadIsolate(R28, kNoPP); | 252 __ LoadIsolate(R28, kNoPP); |
| 253 | 253 |
| 254 // Save exit frame information to enable stack walking as we are about | 254 // Save exit frame information to enable stack walking as we are about |
| 255 // to transition to native code. | 255 // to transition to native code. |
| 256 __ StoreToOffset(FP, R28, Isolate::top_exit_frame_info_offset(), kNoPP); | 256 __ StoreToOffset(FP, R28, Isolate::top_exit_frame_info_offset(), kNoPP); |
| 257 | 257 |
| 258 #if defined(DEBUG) | 258 #if defined(DEBUG) |
| 259 { Label ok; | 259 { Label ok; |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 __ mov(SP, CSP); | 315 __ mov(SP, CSP); |
| 316 __ mov(CSP, R26); | 316 __ mov(CSP, R26); |
| 317 | 317 |
| 318 // Mark that the isolate is executing Dart code. | 318 // Mark that the isolate is executing Dart code. |
| 319 __ LoadImmediate(R2, VMTag::kDartTagId, kNoPP); | 319 __ LoadImmediate(R2, VMTag::kDartTagId, kNoPP); |
| 320 __ StoreToOffset(R2, R28, Isolate::vm_tag_offset(), kNoPP); | 320 __ StoreToOffset(R2, R28, Isolate::vm_tag_offset(), kNoPP); |
| 321 | 321 |
| 322 // Reset exit frame information in Isolate structure. | 322 // Reset exit frame information in Isolate structure. |
| 323 __ StoreToOffset(ZR, R28, Isolate::top_exit_frame_info_offset(), kNoPP); | 323 __ StoreToOffset(ZR, R28, Isolate::top_exit_frame_info_offset(), kNoPP); |
| 324 | 324 |
| 325 __ LeaveFrame(); | 325 __ LeaveStubFrame(); |
| 326 __ ret(); | 326 __ ret(); |
| 327 } | 327 } |
| 328 | 328 |
| 329 | 329 |
| 330 // Input parameters: | 330 // Input parameters: |
| 331 // R4: arguments descriptor array. | 331 // R4: arguments descriptor array. |
| 332 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { | 332 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { |
| 333 // Create a stub frame as we are pushing some objects on the stack before | 333 // Create a stub frame as we are pushing some objects on the stack before |
| 334 // calling into the runtime. | 334 // calling into the runtime. |
| 335 __ EnterStubFrame(); | 335 __ EnterStubFrame(); |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 535 __ LoadFromOffset(R1, FP, kFirstLocalSlotFromFp * kWordSize, kNoPP); | 535 __ LoadFromOffset(R1, FP, kFirstLocalSlotFromFp * kWordSize, kNoPP); |
| 536 } | 536 } |
| 537 // Code above cannot cause GC. | 537 // Code above cannot cause GC. |
| 538 // There is a Dart Frame on the stack. We must restore PP and leave frame. | 538 // There is a Dart Frame on the stack. We must restore PP and leave frame. |
| 539 __ LeaveDartFrame(); | 539 __ LeaveDartFrame(); |
| 540 | 540 |
| 541 // Frame is fully rewritten at this point and it is safe to perform a GC. | 541 // Frame is fully rewritten at this point and it is safe to perform a GC. |
| 542 // Materialize any objects that were deferred by FillFrame because they | 542 // Materialize any objects that were deferred by FillFrame because they |
| 543 // require allocation. | 543 // require allocation. |
| 544 // Enter stub frame with loading PP. The caller's PP is not materialized yet. | 544 // Enter stub frame with loading PP. The caller's PP is not materialized yet. |
| 545 __ EnterStubFrame(true); | 545 __ EnterStubFrame(); |
| 546 if (preserve_result) { | 546 if (preserve_result) { |
| 547 __ Push(ZR); // Workaround for dropped stack slot during GC. | 547 __ Push(ZR); // Workaround for dropped stack slot during GC. |
| 548 __ Push(R1); // Preserve result, it will be GC-d here. | 548 __ Push(R1); // Preserve result, it will be GC-d here. |
| 549 } | 549 } |
| 550 __ Push(ZR); // Space for the result. | 550 __ Push(ZR); // Space for the result. |
| 551 __ CallRuntime(kDeoptimizeMaterializeRuntimeEntry, 0); | 551 __ CallRuntime(kDeoptimizeMaterializeRuntimeEntry, 0); |
| 552 // Result tells stub how many bytes to remove from the expression stack | 552 // Result tells stub how many bytes to remove from the expression stack |
| 553 // of the bottom-most frame. They were used as materialization arguments. | 553 // of the bottom-most frame. They were used as materialization arguments. |
| 554 __ Pop(R1); | 554 __ Pop(R1); |
| 555 __ SmiUntag(R1); | 555 __ SmiUntag(R1); |
| (...skipping 616 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1172 __ add(R0, R2, Operand(kHeapObjectTag)); | 1172 __ add(R0, R2, Operand(kHeapObjectTag)); |
| 1173 // R0: new object. | 1173 // R0: new object. |
| 1174 __ ret(); | 1174 __ ret(); |
| 1175 | 1175 |
| 1176 __ Bind(&slow_case); | 1176 __ Bind(&slow_case); |
| 1177 } | 1177 } |
| 1178 // If is_cls_parameterized: | 1178 // If is_cls_parameterized: |
| 1179 // R1: new object type arguments. | 1179 // R1: new object type arguments. |
| 1180 // Create a stub frame as we are pushing some objects on the stack before | 1180 // Create a stub frame as we are pushing some objects on the stack before |
| 1181 // calling into the runtime. | 1181 // calling into the runtime. |
| 1182 __ EnterStubFrame(true); // Uses pool pointer to pass cls to runtime. | 1182 __ EnterStubFrame(); // Uses pool pointer to pass cls to runtime. |
| 1183 // Setup space on stack for return value. | 1183 // Setup space on stack for return value. |
| 1184 __ PushObject(Object::null_object(), PP); | 1184 __ PushObject(Object::null_object(), PP); |
| 1185 __ PushObject(cls, PP); // Push class of object to be allocated. | 1185 __ PushObject(cls, PP); // Push class of object to be allocated. |
| 1186 if (is_cls_parameterized) { | 1186 if (is_cls_parameterized) { |
| 1187 // Push type arguments. | 1187 // Push type arguments. |
| 1188 __ Push(R1); | 1188 __ Push(R1); |
| 1189 } else { | 1189 } else { |
| 1190 // Push null type arguments. | 1190 // Push null type arguments. |
| 1191 __ PushObject(Object::null_object(), PP); | 1191 __ PushObject(Object::null_object(), PP); |
| 1192 } | 1192 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1204 | 1204 |
| 1205 | 1205 |
| 1206 // Called for invoking "dynamic noSuchMethod(Invocation invocation)" function | 1206 // Called for invoking "dynamic noSuchMethod(Invocation invocation)" function |
| 1207 // from the entry code of a dart function after an error in passed argument | 1207 // from the entry code of a dart function after an error in passed argument |
| 1208 // name or number is detected. | 1208 // name or number is detected. |
| 1209 // Input parameters: | 1209 // Input parameters: |
| 1210 // LR : return address. | 1210 // LR : return address. |
| 1211 // SP : address of last argument. | 1211 // SP : address of last argument. |
| 1212 // R4: arguments descriptor array. | 1212 // R4: arguments descriptor array. |
| 1213 void StubCode::GenerateCallClosureNoSuchMethodStub(Assembler* assembler) { | 1213 void StubCode::GenerateCallClosureNoSuchMethodStub(Assembler* assembler) { |
| 1214 __ EnterStubFrame(true); | 1214 __ EnterStubFrame(); |
| 1215 | 1215 |
| 1216 // Load the receiver. | 1216 // Load the receiver. |
| 1217 __ LoadFieldFromOffset(R2, R4, ArgumentsDescriptor::count_offset(), kNoPP); | 1217 __ LoadFieldFromOffset(R2, R4, ArgumentsDescriptor::count_offset(), kNoPP); |
| 1218 __ add(TMP, FP, Operand(R2, LSL, 2)); // R2 is Smi. | 1218 __ add(TMP, FP, Operand(R2, LSL, 2)); // R2 is Smi. |
| 1219 __ LoadFromOffset(R6, TMP, kParamEndSlotFromFp * kWordSize, kNoPP); | 1219 __ LoadFromOffset(R6, TMP, kParamEndSlotFromFp * kWordSize, kNoPP); |
| 1220 | 1220 |
| 1221 // Push space for the return value. | 1221 // Push space for the return value. |
| 1222 // Push the receiver. | 1222 // Push the receiver. |
| 1223 // Push arguments descriptor array. | 1223 // Push arguments descriptor array. |
| 1224 __ PushObject(Object::null_object(), PP); | 1224 __ PushObject(Object::null_object(), PP); |
| (...skipping 798 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2023 __ b(&done, NE); | 2023 __ b(&done, NE); |
| 2024 __ LoadFieldFromOffset(left, left, Mint::value_offset(), kNoPP); | 2024 __ LoadFieldFromOffset(left, left, Mint::value_offset(), kNoPP); |
| 2025 __ LoadFieldFromOffset(right, right, Mint::value_offset(), kNoPP); | 2025 __ LoadFieldFromOffset(right, right, Mint::value_offset(), kNoPP); |
| 2026 __ b(&done); | 2026 __ b(&done); |
| 2027 | 2027 |
| 2028 __ Bind(&check_bigint); | 2028 __ Bind(&check_bigint); |
| 2029 __ CompareClassId(left, kBigintCid, kNoPP); | 2029 __ CompareClassId(left, kBigintCid, kNoPP); |
| 2030 __ b(&reference_compare, NE); | 2030 __ b(&reference_compare, NE); |
| 2031 __ CompareClassId(right, kBigintCid, kNoPP); | 2031 __ CompareClassId(right, kBigintCid, kNoPP); |
| 2032 __ b(&done, NE); | 2032 __ b(&done, NE); |
| 2033 __ EnterFrame(0); | 2033 __ EnterStubFrame(); |
| 2034 __ ReserveAlignedFrameSpace(2 * kWordSize); | 2034 __ ReserveAlignedFrameSpace(2 * kWordSize); |
| 2035 __ StoreToOffset(left, SP, 0 * kWordSize, kNoPP); | 2035 __ StoreToOffset(left, SP, 0 * kWordSize, kNoPP); |
| 2036 __ StoreToOffset(right, SP, 1 * kWordSize, kNoPP); | 2036 __ StoreToOffset(right, SP, 1 * kWordSize, kNoPP); |
| 2037 __ CallRuntime(kBigintCompareRuntimeEntry, 2); | 2037 __ CallRuntime(kBigintCompareRuntimeEntry, 2); |
| 2038 // Result in R0, 0 means equal. | 2038 // Result in R0, 0 means equal. |
| 2039 __ LeaveFrame(); | 2039 __ LeaveStubFrame(); |
| 2040 __ cmp(R0, Operand(0)); | 2040 __ cmp(R0, Operand(0)); |
| 2041 __ b(&done); | 2041 __ b(&done); |
| 2042 | 2042 |
| 2043 __ Bind(&reference_compare); | 2043 __ Bind(&reference_compare); |
| 2044 __ CompareRegisters(left, right); | 2044 __ CompareRegisters(left, right); |
| 2045 __ Bind(&done); | 2045 __ Bind(&done); |
| 2046 } | 2046 } |
| 2047 | 2047 |
| 2048 | 2048 |
| 2049 // Called only from unoptimized code. All relevant registers have been saved. | 2049 // Called only from unoptimized code. All relevant registers have been saved. |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2147 // Result: | 2147 // Result: |
| 2148 // R1: entry point. | 2148 // R1: entry point. |
| 2149 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { | 2149 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { |
| 2150 EmitMegamorphicLookup(assembler, R0, R1, R1); | 2150 EmitMegamorphicLookup(assembler, R0, R1, R1); |
| 2151 __ ret(); | 2151 __ ret(); |
| 2152 } | 2152 } |
| 2153 | 2153 |
| 2154 } // namespace dart | 2154 } // namespace dart |
| 2155 | 2155 |
| 2156 #endif // defined TARGET_ARCH_ARM64 | 2156 #endif // defined TARGET_ARCH_ARM64 |
| OLD | NEW |