| 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/code_generator.h" | 9 #include "vm/code_generator.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); | 28 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
| 29 const intptr_t argv_offset = NativeArguments::argv_offset(); | 29 const intptr_t argv_offset = NativeArguments::argv_offset(); |
| 30 const intptr_t retval_offset = NativeArguments::retval_offset(); | 30 const intptr_t retval_offset = NativeArguments::retval_offset(); |
| 31 __ EnterFrame((1 << FP) | (1 << LR), 0); | 31 __ EnterFrame((1 << FP) | (1 << LR), 0); |
| 32 | 32 |
| 33 // Load current Isolate pointer from Context structure into R0. | 33 // Load current Isolate pointer from Context structure into R0. |
| 34 __ ldr(R0, FieldAddress(CTX, Context::isolate_offset())); | 34 __ ldr(R0, FieldAddress(CTX, Context::isolate_offset())); |
| 35 | 35 |
| 36 // Save exit frame information to enable stack walking as we are about | 36 // Save exit frame information to enable stack walking as we are about |
| 37 // to transition to Dart VM C++ code. | 37 // to transition to Dart VM C++ code. |
| 38 { | 38 __ StoreToOffset(kStoreWord, SP, R0, Isolate::top_exit_frame_info_offset()); |
| 39 // TODO(regis): Add assembler macro for {Load,Store}BasedOffset with no | |
| 40 // restriction on the offset. | |
| 41 const intptr_t offset = Isolate::top_exit_frame_info_offset(); | |
| 42 const int32_t offset12_hi = offset & ~kOffset12Mask; // signed | |
| 43 const uint32_t offset12_lo = offset & kOffset12Mask; // unsigned | |
| 44 __ AddImmediate(IP, R0, offset12_hi); | |
| 45 __ str(SP, Address(IP, offset12_lo)); | |
| 46 } | |
| 47 | 39 |
| 48 // Save current Context pointer into Isolate structure. | 40 // Save current Context pointer into Isolate structure. |
| 49 { | 41 __ StoreToOffset(kStoreWord, CTX, R0, Isolate::top_context_offset()); |
| 50 // TODO(regis): Add assembler macro for {Load,Store}BasedOffset with no | |
| 51 // restriction on the offset. | |
| 52 const intptr_t offset = Isolate::top_context_offset(); | |
| 53 const int32_t offset12_hi = offset & ~kOffset12Mask; // signed | |
| 54 const uint32_t offset12_lo = offset & kOffset12Mask; // unsigned | |
| 55 __ AddImmediate(IP, R0, offset12_hi); | |
| 56 __ str(CTX, Address(IP, offset12_lo)); | |
| 57 } | |
| 58 | 42 |
| 59 // Cache Isolate pointer into CTX while executing runtime code. | 43 // Cache Isolate pointer into CTX while executing runtime code. |
| 60 __ mov(CTX, ShifterOperand(R0)); | 44 __ mov(CTX, ShifterOperand(R0)); |
| 61 | 45 |
| 62 // Reserve space for arguments and align frame before entering C++ world. | 46 // Reserve space for arguments and align frame before entering C++ world. |
| 63 // NativeArguments are passed in registers. | 47 // NativeArguments are passed in registers. |
| 64 ASSERT(sizeof(NativeArguments) == 4 * kWordSize); | 48 ASSERT(sizeof(NativeArguments) == 4 * kWordSize); |
| 65 __ ReserveAlignedFrameSpace(0); | 49 __ ReserveAlignedFrameSpace(0); |
| 66 | 50 |
| 67 // Pass NativeArguments structure by value and call runtime. | 51 // Pass NativeArguments structure by value and call runtime. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 80 __ AddImmediate(R2, kWordSize); // Set argv in NativeArguments. | 64 __ AddImmediate(R2, kWordSize); // Set argv in NativeArguments. |
| 81 | 65 |
| 82 ASSERT(retval_offset == 3 * kWordSize); | 66 ASSERT(retval_offset == 3 * kWordSize); |
| 83 __ add(R3, R2, ShifterOperand(kWordSize)); // Retval is next to 1st argument. | 67 __ add(R3, R2, ShifterOperand(kWordSize)); // Retval is next to 1st argument. |
| 84 | 68 |
| 85 // Call runtime or redirection via simulator. | 69 // Call runtime or redirection via simulator. |
| 86 __ blx(R5); | 70 __ blx(R5); |
| 87 | 71 |
| 88 // Reset exit frame information in Isolate structure. | 72 // Reset exit frame information in Isolate structure. |
| 89 __ LoadImmediate(R2, 0); | 73 __ LoadImmediate(R2, 0); |
| 90 { | 74 __ StoreToOffset(kStoreWord, R2, CTX, Isolate::top_exit_frame_info_offset()); |
| 91 // TODO(regis): Add assembler macro for {Load,Store}BasedOffset with no | |
| 92 // restriction on the offset. | |
| 93 const intptr_t offset = Isolate::top_exit_frame_info_offset(); | |
| 94 const int32_t offset12_hi = offset & ~kOffset12Mask; // signed | |
| 95 const uint32_t offset12_lo = offset & kOffset12Mask; // unsigned | |
| 96 __ AddImmediate(IP, CTX, offset12_hi); | |
| 97 __ str(R2, Address(IP, offset12_lo)); | |
| 98 } | |
| 99 | 75 |
| 100 // Load Context pointer from Isolate structure into R2. | 76 // Load Context pointer from Isolate structure into R2. |
| 101 { | 77 __ LoadFromOffset(kLoadWord, R2, CTX, Isolate::top_context_offset()); |
| 102 // TODO(regis): Add assembler macro for {Load,Store}BasedOffset with no | |
| 103 // restriction on the offset. | |
| 104 const intptr_t offset = Isolate::top_context_offset(); | |
| 105 const int32_t offset12_hi = offset & ~kOffset12Mask; // signed | |
| 106 const uint32_t offset12_lo = offset & kOffset12Mask; // unsigned | |
| 107 __ AddImmediate(IP, CTX, offset12_hi); | |
| 108 __ ldr(R2, Address(IP, offset12_lo)); | |
| 109 } | |
| 110 | 78 |
| 111 // Reset Context pointer in Isolate structure. | 79 // Reset Context pointer in Isolate structure. |
| 112 __ LoadImmediate(R3, reinterpret_cast<intptr_t>(Object::null())); | 80 __ LoadImmediate(R3, reinterpret_cast<intptr_t>(Object::null())); |
| 113 { | 81 __ StoreToOffset(kStoreWord, R3, CTX, Isolate::top_context_offset()); |
| 114 // TODO(regis): Add assembler macro for {Load,Store}BasedOffset with no | |
| 115 // restriction on the offset. | |
| 116 const intptr_t offset = Isolate::top_context_offset(); | |
| 117 const int32_t offset12_hi = offset & ~kOffset12Mask; // signed | |
| 118 const uint32_t offset12_lo = offset & kOffset12Mask; // unsigned | |
| 119 __ AddImmediate(IP, CTX, offset12_hi); | |
| 120 __ str(R3, Address(IP, offset12_lo)); | |
| 121 } | |
| 122 | 82 |
| 123 // Cache Context pointer into CTX while executing Dart code. | 83 // Cache Context pointer into CTX while executing Dart code. |
| 124 __ mov(CTX, ShifterOperand(R2)); | 84 __ mov(CTX, ShifterOperand(R2)); |
| 125 | 85 |
| 126 __ LeaveFrame((1 << FP) | (1 << LR)); | 86 __ LeaveFrame((1 << FP) | (1 << LR)); |
| 127 __ Ret(); | 87 __ Ret(); |
| 128 } | 88 } |
| 129 | 89 |
| 130 | 90 |
| 91 // Print the stop message. |
| 92 DEFINE_LEAF_RUNTIME_ENTRY(void, PrintStopMessage, const char* message) { |
| 93 OS::Print("Stop message: %s\n", message); |
| 94 } |
| 95 END_LEAF_RUNTIME_ENTRY |
| 96 |
| 97 |
| 98 // Input parameters: |
| 99 // R0 : stop message (const char*). |
| 100 // Must preserve all registers. |
| 131 void StubCode::GeneratePrintStopMessageStub(Assembler* assembler) { | 101 void StubCode::GeneratePrintStopMessageStub(Assembler* assembler) { |
| 132 __ Unimplemented("PrintStopMessage stub"); | 102 __ EnterCallRuntimeFrame(0); |
| 103 // Call the runtime leaf function. R0 already contains the parameter. |
| 104 __ CallRuntime(kPrintStopMessageRuntimeEntry); |
| 105 __ LeaveCallRuntimeFrame(); |
| 106 __ Ret(); |
| 133 } | 107 } |
| 134 | 108 |
| 135 | 109 |
| 136 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) { | 110 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) { |
| 137 __ Unimplemented("CallNativeCFunction stub"); | 111 __ Unimplemented("CallNativeCFunction stub"); |
| 138 } | 112 } |
| 139 | 113 |
| 140 | 114 |
| 141 // Input parameters: | 115 // Input parameters: |
| 142 // R4: arguments descriptor array. | 116 // R4: arguments descriptor array. |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 215 // compiled or runtime stub code. | 189 // compiled or runtime stub code. |
| 216 | 190 |
| 217 // Cache the new Context pointer into CTX while executing Dart code. | 191 // Cache the new Context pointer into CTX while executing Dart code. |
| 218 __ ldr(CTX, Address(R3, VMHandles::kOffsetOfRawPtrInHandle)); | 192 __ ldr(CTX, Address(R3, VMHandles::kOffsetOfRawPtrInHandle)); |
| 219 | 193 |
| 220 // Load Isolate pointer from Context structure into temporary register R8. | 194 // Load Isolate pointer from Context structure into temporary register R8. |
| 221 __ ldr(R8, FieldAddress(CTX, Context::isolate_offset())); | 195 __ ldr(R8, FieldAddress(CTX, Context::isolate_offset())); |
| 222 | 196 |
| 223 // Save the top exit frame info. Use R5 as a temporary register. | 197 // Save the top exit frame info. Use R5 as a temporary register. |
| 224 // StackFrameIterator reads the top exit frame info saved in this frame. | 198 // StackFrameIterator reads the top exit frame info saved in this frame. |
| 225 { | 199 __ LoadFromOffset(kLoadWord, R5, R8, Isolate::top_exit_frame_info_offset()); |
| 226 // TODO(regis): Add assembler macro for {Load,Store}BasedOffset with no | 200 __ LoadImmediate(R6, 0); |
| 227 // restriction on the offset. | 201 __ StoreToOffset(kStoreWord, R6, R8, Isolate::top_exit_frame_info_offset()); |
| 228 const intptr_t offset = Isolate::top_exit_frame_info_offset(); | |
| 229 const int32_t offset12_hi = offset & ~kOffset12Mask; // signed | |
| 230 const uint32_t offset12_lo = offset & kOffset12Mask; // unsigned | |
| 231 __ AddImmediate(R7, R8, offset12_hi); | |
| 232 __ ldr(R5, Address(R7, offset12_lo)); | |
| 233 __ LoadImmediate(R6, 0); | |
| 234 __ str(R6, Address(R7, offset12_lo)); | |
| 235 } | |
| 236 | 202 |
| 237 // Save the old Context pointer. Use R4 as a temporary register. | 203 // Save the old Context pointer. Use R4 as a temporary register. |
| 238 // Note that VisitObjectPointers will find this saved Context pointer during | 204 // Note that VisitObjectPointers will find this saved Context pointer during |
| 239 // GC marking, since it traverses any information between SP and | 205 // GC marking, since it traverses any information between SP and |
| 240 // FP - kExitLinkOffsetInEntryFrame. | 206 // FP - kExitLinkOffsetInEntryFrame. |
| 241 // EntryFrame::SavedContext reads the context saved in this frame. | 207 // EntryFrame::SavedContext reads the context saved in this frame. |
| 242 { | 208 __ LoadFromOffset(kLoadWord, R4, R8, Isolate::top_context_offset()); |
| 243 const intptr_t offset = Isolate::top_context_offset(); | |
| 244 const int32_t offset12_hi = offset & ~kOffset12Mask; // signed | |
| 245 const uint32_t offset12_lo = offset & kOffset12Mask; // unsigned | |
| 246 __ AddImmediate(R7, R8, offset12_hi); | |
| 247 __ ldr(R4, Address(R7, offset12_lo)); | |
| 248 } | |
| 249 | 209 |
| 250 // The constants kSavedContextOffsetInEntryFrame and | 210 // The constants kSavedContextOffsetInEntryFrame and |
| 251 // kExitLinkOffsetInEntryFrame must be kept in sync with the code below. | 211 // kExitLinkOffsetInEntryFrame must be kept in sync with the code below. |
| 252 __ PushList((1 << R4) | (1 << R5)); | 212 __ PushList((1 << R4) | (1 << R5)); |
| 253 | 213 |
| 254 // The stack pointer is restore after the call to this location. | 214 // The stack pointer is restore after the call to this location. |
| 255 const intptr_t kSavedContextOffsetInEntryFrame = -10 * kWordSize; | 215 const intptr_t kSavedContextOffsetInEntryFrame = -10 * kWordSize; |
| 256 | 216 |
| 257 // Load arguments descriptor array into R4, which is passed to Dart code. | 217 // Load arguments descriptor array into R4, which is passed to Dart code. |
| 258 __ ldr(R4, Address(R1, VMHandles::kOffsetOfRawPtrInHandle)); | 218 __ ldr(R4, Address(R1, VMHandles::kOffsetOfRawPtrInHandle)); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 291 __ AddImmediate(SP, FP, kSavedContextOffsetInEntryFrame); | 251 __ AddImmediate(SP, FP, kSavedContextOffsetInEntryFrame); |
| 292 | 252 |
| 293 // Load Isolate pointer from Context structure into CTX. Drop Context. | 253 // Load Isolate pointer from Context structure into CTX. Drop Context. |
| 294 __ ldr(CTX, FieldAddress(CTX, Context::isolate_offset())); | 254 __ ldr(CTX, FieldAddress(CTX, Context::isolate_offset())); |
| 295 | 255 |
| 296 // Restore the saved Context pointer into the Isolate structure. | 256 // Restore the saved Context pointer into the Isolate structure. |
| 297 // Uses R4 as a temporary register for this. | 257 // Uses R4 as a temporary register for this. |
| 298 // Restore the saved top exit frame info back into the Isolate structure. | 258 // Restore the saved top exit frame info back into the Isolate structure. |
| 299 // Uses R5 as a temporary register for this. | 259 // Uses R5 as a temporary register for this. |
| 300 __ PopList((1 << R4) | (1 << R5)); | 260 __ PopList((1 << R4) | (1 << R5)); |
| 301 { | 261 __ StoreToOffset(kStoreWord, R4, CTX, Isolate::top_context_offset()); |
| 302 const intptr_t offset = Isolate::top_context_offset(); | 262 __ StoreToOffset(kStoreWord, R5, CTX, Isolate::top_exit_frame_info_offset()); |
| 303 const int32_t offset12_hi = offset & ~kOffset12Mask; // signed | |
| 304 const uint32_t offset12_lo = offset & kOffset12Mask; // unsigned | |
| 305 __ AddImmediate(R7, CTX, offset12_hi); | |
| 306 __ str(R4, Address(R7, offset12_lo)); | |
| 307 } | |
| 308 { | |
| 309 const intptr_t offset = Isolate::top_exit_frame_info_offset(); | |
| 310 const int32_t offset12_hi = offset & ~kOffset12Mask; // signed | |
| 311 const uint32_t offset12_lo = offset & kOffset12Mask; // unsigned | |
| 312 __ AddImmediate(R7, CTX, offset12_hi); | |
| 313 __ str(R5, Address(R7, offset12_lo)); | |
| 314 } | |
| 315 | 263 |
| 316 // Restore C++ ABI callee-saved registers. | 264 // Restore C++ ABI callee-saved registers. |
| 317 __ PopList((1 << R3) | kAbiPreservedCpuRegs); // Ignore restored R3. | 265 __ PopList((1 << R3) | kAbiPreservedCpuRegs); // Ignore restored R3. |
| 318 | 266 |
| 319 // Restore the frame pointer and return. | 267 // Restore the frame pointer and return. |
| 320 __ LeaveStubFrame(); | 268 __ LeaveStubFrame(); |
| 321 __ Ret(); | 269 __ Ret(); |
| 322 } | 270 } |
| 323 | 271 |
| 324 | 272 |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 473 } | 421 } |
| 474 | 422 |
| 475 | 423 |
| 476 void StubCode::GenerateIdenticalWithNumberCheckStub(Assembler* assembler) { | 424 void StubCode::GenerateIdenticalWithNumberCheckStub(Assembler* assembler) { |
| 477 __ Unimplemented("IdenticalWithNumberCheck stub"); | 425 __ Unimplemented("IdenticalWithNumberCheck stub"); |
| 478 } | 426 } |
| 479 | 427 |
| 480 } // namespace dart | 428 } // namespace dart |
| 481 | 429 |
| 482 #endif // defined TARGET_ARCH_ARM | 430 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |