| 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/assembler_macros.h" | 9 #include "vm/assembler_macros.h" |
| 10 #include "vm/code_generator.h" |
| 10 #include "vm/dart_entry.h" | 11 #include "vm/dart_entry.h" |
| 11 #include "vm/instructions.h" | 12 #include "vm/instructions.h" |
| 12 #include "vm/stack_frame.h" | 13 #include "vm/stack_frame.h" |
| 13 #include "vm/stub_code.h" | 14 #include "vm/stub_code.h" |
| 14 | 15 |
| 15 #define __ assembler-> | 16 #define __ assembler-> |
| 16 | 17 |
| 17 namespace dart { | 18 namespace dart { |
| 18 | 19 |
| 20 // Input parameters: |
| 21 // LR : return address. |
| 22 // SP : address of last argument in argument array. |
| 23 // SP + 4*R4 - 4 : address of first argument in argument array. |
| 24 // SP + 4*R4 : address of return value. |
| 25 // R5 : address of the runtime function to call. |
| 26 // R4 : number of arguments to the call. |
| 19 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { | 27 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { |
| 20 __ Unimplemented("CallToRuntime stub"); | 28 const intptr_t isolate_offset = NativeArguments::isolate_offset(); |
| 29 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
| 30 const intptr_t argv_offset = NativeArguments::argv_offset(); |
| 31 const intptr_t retval_offset = NativeArguments::retval_offset(); |
| 32 __ EnterFrame((1 << FP) | (1 << LR), 0); |
| 33 |
| 34 // Load current Isolate pointer from Context structure into R0. |
| 35 __ ldr(R0, FieldAddress(CTX, Context::isolate_offset())); |
| 36 |
| 37 // Save exit frame information to enable stack walking as we are about |
| 38 // to transition to Dart VM C++ code. |
| 39 { |
| 40 // TODO(regis): Add assembler macro for {Load,Store}BasedOffset with no |
| 41 // restriction on the offset. |
| 42 const intptr_t offset = Isolate::top_exit_frame_info_offset(); |
| 43 const int32_t offset12_hi = offset & ~kOffset12Mask; // signed |
| 44 const uint32_t offset12_lo = offset & kOffset12Mask; // unsigned |
| 45 __ AddImmediate(IP, R0, offset12_hi); |
| 46 __ str(SP, Address(IP, offset12_lo)); |
| 47 } |
| 48 |
| 49 // Save current Context pointer into Isolate structure. |
| 50 { |
| 51 // TODO(regis): Add assembler macro for {Load,Store}BasedOffset with no |
| 52 // restriction on the offset. |
| 53 const intptr_t offset = Isolate::top_context_offset(); |
| 54 const int32_t offset12_hi = offset & ~kOffset12Mask; // signed |
| 55 const uint32_t offset12_lo = offset & kOffset12Mask; // unsigned |
| 56 __ AddImmediate(IP, R0, offset12_hi); |
| 57 __ str(CTX, Address(IP, offset12_lo)); |
| 58 } |
| 59 |
| 60 // Cache Isolate pointer into CTX while executing runtime code. |
| 61 __ mov(CTX, ShifterOperand(R0)); |
| 62 |
| 63 // Reserve space for arguments and align frame before entering C++ world. |
| 64 // NativeArguments are passed in registers. |
| 65 ASSERT(sizeof(NativeArguments) == 4 * kWordSize); |
| 66 __ ReserveAlignedFrameSpace(0); |
| 67 |
| 68 // Pass NativeArguments structure by value and call runtime. |
| 69 // Registers R0, R1, R2, and R3 are used. |
| 70 |
| 71 ASSERT(isolate_offset == 0 * kWordSize); |
| 72 __ mov(R0, ShifterOperand(CTX)); // Set isolate in NativeArgs. |
| 73 |
| 74 // There are no runtime calls to closures, so we do not need to set the tag |
| 75 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. |
| 76 ASSERT(argc_tag_offset == 1 * kWordSize); |
| 77 __ mov(R1, ShifterOperand(R4)); // Set argc in NativeArguments. |
| 78 |
| 79 ASSERT(argv_offset == 2 * kWordSize); |
| 80 __ add(R2, FP, ShifterOperand(R4, LSL, 2)); // Compute argv. |
| 81 __ AddImmediate(R2, kWordSize); // Set argv in NativeArguments. |
| 82 |
| 83 ASSERT(retval_offset == 3 * kWordSize); |
| 84 __ add(R3, R2, ShifterOperand(kWordSize)); // Retval is next to 1st argument. |
| 85 |
| 86 // Call runtime or redirection via simulator. |
| 87 __ blx(R5); |
| 88 |
| 89 // Reset exit frame information in Isolate structure. |
| 90 __ LoadImmediate(R2, 0); |
| 91 { |
| 92 // TODO(regis): Add assembler macro for {Load,Store}BasedOffset with no |
| 93 // restriction on the offset. |
| 94 const intptr_t offset = Isolate::top_exit_frame_info_offset(); |
| 95 const int32_t offset12_hi = offset & ~kOffset12Mask; // signed |
| 96 const uint32_t offset12_lo = offset & kOffset12Mask; // unsigned |
| 97 __ AddImmediate(IP, CTX, offset12_hi); |
| 98 __ str(R2, Address(IP, offset12_lo)); |
| 99 } |
| 100 |
| 101 // Load Context pointer from Isolate structure into R2. |
| 102 { |
| 103 // TODO(regis): Add assembler macro for {Load,Store}BasedOffset with no |
| 104 // restriction on the offset. |
| 105 const intptr_t offset = Isolate::top_context_offset(); |
| 106 const int32_t offset12_hi = offset & ~kOffset12Mask; // signed |
| 107 const uint32_t offset12_lo = offset & kOffset12Mask; // unsigned |
| 108 __ AddImmediate(IP, CTX, offset12_hi); |
| 109 __ ldr(R2, Address(IP, offset12_lo)); |
| 110 } |
| 111 |
| 112 // Reset Context pointer in Isolate structure. |
| 113 __ LoadImmediate(R3, reinterpret_cast<intptr_t>(Object::null())); |
| 114 { |
| 115 // TODO(regis): Add assembler macro for {Load,Store}BasedOffset with no |
| 116 // restriction on the offset. |
| 117 const intptr_t offset = Isolate::top_context_offset(); |
| 118 const int32_t offset12_hi = offset & ~kOffset12Mask; // signed |
| 119 const uint32_t offset12_lo = offset & kOffset12Mask; // unsigned |
| 120 __ AddImmediate(IP, CTX, offset12_hi); |
| 121 __ str(R3, Address(IP, offset12_lo)); |
| 122 } |
| 123 |
| 124 // Cache Context pointer into CTX while executing Dart code. |
| 125 __ mov(CTX, ShifterOperand(R2)); |
| 126 |
| 127 __ LeaveFrame((1 << FP) | (1 << LR)); |
| 128 __ Ret(); |
| 21 } | 129 } |
| 22 | 130 |
| 23 | 131 |
| 24 void StubCode::GeneratePrintStopMessageStub(Assembler* assembler) { | 132 void StubCode::GeneratePrintStopMessageStub(Assembler* assembler) { |
| 25 __ Unimplemented("PrintStopMessage stub"); | 133 __ Unimplemented("PrintStopMessage stub"); |
| 26 } | 134 } |
| 27 | 135 |
| 28 | 136 |
| 29 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) { | 137 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) { |
| 30 __ Unimplemented("CallNativeCFunction stub"); | 138 __ Unimplemented("CallNativeCFunction stub"); |
| 31 } | 139 } |
| 32 | 140 |
| 33 | 141 |
| 142 // Input parameters: |
| 143 // R4: arguments descriptor array. |
| 34 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { | 144 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { |
| 35 __ Unimplemented("CallStaticFunction stub"); | 145 AssemblerMacros::EnterStubFrame(assembler); |
| 146 // Setup space on stack for return value and preserve arguments descriptor. |
| 147 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); |
| 148 __ PushList((1 << R0) | (1 << R4)); |
| 149 __ CallRuntime(kPatchStaticCallRuntimeEntry); |
| 150 // Get Code object result and restore arguments descriptor array. |
| 151 __ PopList((1 << R0) | (1 << R4)); |
| 152 // Remove the stub frame as we are about to jump to the dart function. |
| 153 AssemblerMacros::LeaveStubFrame(assembler); |
| 154 |
| 155 __ ldr(R0, FieldAddress(R0, Code::instructions_offset())); |
| 156 __ AddImmediate(R0, R0, Instructions::HeaderSize() - kHeapObjectTag); |
| 157 __ bx(R0); |
| 36 } | 158 } |
| 37 | 159 |
| 38 | 160 |
| 39 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { | 161 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { |
| 40 __ Unimplemented("FixCallersTarget stub"); | 162 __ Unimplemented("FixCallersTarget stub"); |
| 41 } | 163 } |
| 42 | 164 |
| 43 | 165 |
| 44 void StubCode::GenerateInstanceFunctionLookupStub(Assembler* assembler) { | 166 void StubCode::GenerateInstanceFunctionLookupStub(Assembler* assembler) { |
| 45 __ Unimplemented("InstanceFunctionLookup stub"); | 167 __ Unimplemented("InstanceFunctionLookup stub"); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 76 // LR : points to return address. | 198 // LR : points to return address. |
| 77 // R0 : entrypoint of the Dart function to call. | 199 // R0 : entrypoint of the Dart function to call. |
| 78 // R1 : arguments descriptor array. | 200 // R1 : arguments descriptor array. |
| 79 // R2 : arguments array. | 201 // R2 : arguments array. |
| 80 // R3 : new context containing the current isolate pointer. | 202 // R3 : new context containing the current isolate pointer. |
| 81 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { | 203 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { |
| 82 // Save frame pointer coming in. | 204 // Save frame pointer coming in. |
| 83 AssemblerMacros::EnterStubFrame(assembler); | 205 AssemblerMacros::EnterStubFrame(assembler); |
| 84 | 206 |
| 85 // Save new context and C++ ABI callee-saved registers. | 207 // Save new context and C++ ABI callee-saved registers. |
| 86 const intptr_t kNewContextOffset = -(1 + kAbiPreservedRegCount) * kWordSize; | 208 const intptr_t kNewContextOffset = |
| 87 __ PushList((1 << R3) | kAbiPreservedRegs); | 209 -(1 + kAbiPreservedCpuRegCount) * kWordSize; |
| 210 __ PushList((1 << R3) | kAbiPreservedCpuRegs); |
| 88 | 211 |
| 89 // The new Context structure contains a pointer to the current Isolate | 212 // The new Context structure contains a pointer to the current Isolate |
| 90 // structure. Cache the Context pointer in the CTX register so that it is | 213 // structure. Cache the Context pointer in the CTX register so that it is |
| 91 // available in generated code and calls to Isolate::Current() need not be | 214 // available in generated code and calls to Isolate::Current() need not be |
| 92 // done. The assumption is that this register will never be clobbered by | 215 // done. The assumption is that this register will never be clobbered by |
| 93 // compiled or runtime stub code. | 216 // compiled or runtime stub code. |
| 94 | 217 |
| 95 // Cache the new Context pointer into CTX while executing Dart code. | 218 // Cache the new Context pointer into CTX while executing Dart code. |
| 96 __ ldr(CTX, Address(R3, VMHandles::kOffsetOfRawPtrInHandle)); | 219 __ ldr(CTX, Address(R3, VMHandles::kOffsetOfRawPtrInHandle)); |
| 97 | 220 |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 185 } | 308 } |
| 186 { | 309 { |
| 187 const intptr_t offset = Isolate::top_exit_frame_info_offset(); | 310 const intptr_t offset = Isolate::top_exit_frame_info_offset(); |
| 188 const int32_t offset12_hi = offset & ~kOffset12Mask; // signed | 311 const int32_t offset12_hi = offset & ~kOffset12Mask; // signed |
| 189 const uint32_t offset12_lo = offset & kOffset12Mask; // unsigned | 312 const uint32_t offset12_lo = offset & kOffset12Mask; // unsigned |
| 190 __ AddImmediate(R7, CTX, offset12_hi); | 313 __ AddImmediate(R7, CTX, offset12_hi); |
| 191 __ str(R5, Address(R7, offset12_lo)); | 314 __ str(R5, Address(R7, offset12_lo)); |
| 192 } | 315 } |
| 193 | 316 |
| 194 // Restore C++ ABI callee-saved registers. | 317 // Restore C++ ABI callee-saved registers. |
| 195 __ PopList((1 << R3) | kAbiPreservedRegs); // Ignore restored R3. | 318 __ PopList((1 << R3) | kAbiPreservedCpuRegs); // Ignore restored R3. |
| 196 | 319 |
| 197 // Restore the frame pointer. | 320 // Restore the frame pointer. |
| 198 AssemblerMacros::LeaveStubFrame(assembler); | 321 AssemblerMacros::LeaveStubFrame(assembler); |
| 199 | 322 |
| 200 __ Ret(); | 323 __ Ret(); |
| 201 } | 324 } |
| 202 | 325 |
| 203 | 326 |
| 204 void StubCode::GenerateAllocateContextStub(Assembler* assembler) { | 327 void StubCode::GenerateAllocateContextStub(Assembler* assembler) { |
| 205 __ Unimplemented("AllocateContext stub"); | 328 __ Unimplemented("AllocateContext stub"); |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 352 } | 475 } |
| 353 | 476 |
| 354 | 477 |
| 355 void StubCode::GenerateIdenticalWithNumberCheckStub(Assembler* assembler) { | 478 void StubCode::GenerateIdenticalWithNumberCheckStub(Assembler* assembler) { |
| 356 __ Unimplemented("IdenticalWithNumberCheck stub"); | 479 __ Unimplemented("IdenticalWithNumberCheck stub"); |
| 357 } | 480 } |
| 358 | 481 |
| 359 } // namespace dart | 482 } // namespace dart |
| 360 | 483 |
| 361 #endif // defined TARGET_ARCH_ARM | 484 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |