| 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 10 matching lines...) Expand all Loading... |
| 21 // SP : address of last argument in argument array. | 21 // SP : address of last argument in argument array. |
| 22 // SP + 4*R4 - 4 : address of first argument in argument array. | 22 // SP + 4*R4 - 4 : address of first argument in argument array. |
| 23 // SP + 4*R4 : address of return value. | 23 // SP + 4*R4 : address of return value. |
| 24 // R5 : address of the runtime function to call. | 24 // R5 : address of the runtime function to call. |
| 25 // R4 : number of arguments to the call. | 25 // R4 : number of arguments to the call. |
| 26 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { | 26 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { |
| 27 const intptr_t isolate_offset = NativeArguments::isolate_offset(); | 27 const intptr_t isolate_offset = NativeArguments::isolate_offset(); |
| 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 |
| 31 __ EnterFrame((1 << FP) | (1 << LR), 0); | 32 __ EnterFrame((1 << FP) | (1 << LR), 0); |
| 32 | 33 |
| 33 // Load current Isolate pointer from Context structure into R0. | 34 // Load current Isolate pointer from Context structure into R0. |
| 34 __ ldr(R0, FieldAddress(CTX, Context::isolate_offset())); | 35 __ ldr(R0, FieldAddress(CTX, Context::isolate_offset())); |
| 35 | 36 |
| 36 // Save exit frame information to enable stack walking as we are about | 37 // Save exit frame information to enable stack walking as we are about |
| 37 // to transition to Dart VM C++ code. | 38 // to transition to Dart VM C++ code. |
| 38 __ StoreToOffset(kStoreWord, SP, R0, Isolate::top_exit_frame_info_offset()); | 39 __ StoreToOffset(kStoreWord, SP, R0, Isolate::top_exit_frame_info_offset()); |
| 39 | 40 |
| 40 // Save current Context pointer into Isolate structure. | 41 // Save current Context pointer into Isolate structure. |
| 41 __ StoreToOffset(kStoreWord, CTX, R0, Isolate::top_context_offset()); | 42 __ StoreToOffset(kStoreWord, CTX, R0, Isolate::top_context_offset()); |
| 42 | 43 |
| 43 // Cache Isolate pointer into CTX while executing runtime code. | 44 // Cache Isolate pointer into CTX while executing runtime code. |
| 44 __ mov(CTX, ShifterOperand(R0)); | 45 __ mov(CTX, ShifterOperand(R0)); |
| 45 | 46 |
| 46 // Reserve space for arguments and align frame before entering C++ world. | 47 // Reserve space for arguments and align frame before entering C++ world. |
| 47 // NativeArguments are passed in registers. | 48 // NativeArguments are passed in registers. |
| 48 ASSERT(sizeof(NativeArguments) == 4 * kWordSize); | 49 ASSERT(sizeof(NativeArguments) == 4 * kWordSize); |
| 49 __ ReserveAlignedFrameSpace(0); | 50 __ ReserveAlignedFrameSpace(0); |
| 50 | 51 |
| 51 // Pass NativeArguments structure by value and call runtime. | 52 // Pass NativeArguments structure by value and call runtime. |
| 52 // Registers R0, R1, R2, and R3 are used. | 53 // Registers R0, R1, R2, and R3 are used. |
| 53 | 54 |
| 54 ASSERT(isolate_offset == 0 * kWordSize); | 55 ASSERT(isolate_offset == 0 * kWordSize); |
| 55 __ mov(R0, ShifterOperand(CTX)); // Set isolate in NativeArgs. | 56 // Set isolate in NativeArgs: R0 already contains CTX. |
| 56 | 57 |
| 57 // There are no runtime calls to closures, so we do not need to set the tag | 58 // There are no runtime calls to closures, so we do not need to set the tag |
| 58 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. | 59 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. |
| 59 ASSERT(argc_tag_offset == 1 * kWordSize); | 60 ASSERT(argc_tag_offset == 1 * kWordSize); |
| 60 __ mov(R1, ShifterOperand(R4)); // Set argc in NativeArguments. | 61 __ mov(R1, ShifterOperand(R4)); // Set argc in NativeArguments. |
| 61 | 62 |
| 62 ASSERT(argv_offset == 2 * kWordSize); | 63 ASSERT(argv_offset == 2 * kWordSize); |
| 63 __ add(R2, FP, ShifterOperand(R4, LSL, 2)); // Compute argv. | 64 __ add(R2, FP, ShifterOperand(R4, LSL, 2)); // Compute argv. |
| 64 __ AddImmediate(R2, kWordSize); // Set argv in NativeArguments. | 65 __ AddImmediate(R2, kWordSize); // Set argv in NativeArguments. |
| 65 | 66 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 100 // Must preserve all registers. | 101 // Must preserve all registers. |
| 101 void StubCode::GeneratePrintStopMessageStub(Assembler* assembler) { | 102 void StubCode::GeneratePrintStopMessageStub(Assembler* assembler) { |
| 102 __ EnterCallRuntimeFrame(0); | 103 __ EnterCallRuntimeFrame(0); |
| 103 // Call the runtime leaf function. R0 already contains the parameter. | 104 // Call the runtime leaf function. R0 already contains the parameter. |
| 104 __ CallRuntime(kPrintStopMessageRuntimeEntry); | 105 __ CallRuntime(kPrintStopMessageRuntimeEntry); |
| 105 __ LeaveCallRuntimeFrame(); | 106 __ LeaveCallRuntimeFrame(); |
| 106 __ Ret(); | 107 __ Ret(); |
| 107 } | 108 } |
| 108 | 109 |
| 109 | 110 |
| 111 // Input parameters: |
| 112 // LR : return address. |
| 113 // SP : address of return value. |
| 114 // R5 : address of the native function to call. |
| 115 // R2 : address of first argument in argument array. |
| 116 // R1 : argc_tag including number of arguments and function kind. |
| 110 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) { | 117 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) { |
| 111 __ Unimplemented("CallNativeCFunction stub"); | 118 const intptr_t isolate_offset = NativeArguments::isolate_offset(); |
| 119 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
| 120 const intptr_t argv_offset = NativeArguments::argv_offset(); |
| 121 const intptr_t retval_offset = NativeArguments::retval_offset(); |
| 122 |
| 123 __ EnterFrame((1 << FP) | (1 << LR), 0); |
| 124 |
| 125 // Load current Isolate pointer from Context structure into R0. |
| 126 __ ldr(R0, FieldAddress(CTX, Context::isolate_offset())); |
| 127 |
| 128 // Save exit frame information to enable stack walking as we are about |
| 129 // to transition to native code. |
| 130 __ StoreToOffset(kStoreWord, SP, R0, Isolate::top_exit_frame_info_offset()); |
| 131 |
| 132 // Save current Context pointer into Isolate structure. |
| 133 __ StoreToOffset(kStoreWord, CTX, R0, Isolate::top_context_offset()); |
| 134 |
| 135 // Cache Isolate pointer into CTX while executing native code. |
| 136 __ mov(CTX, ShifterOperand(R0)); |
| 137 |
| 138 // Reserve space for the native arguments structure passed on the stack (the |
| 139 // outgoing pointer parameter to the native arguments structure is passed in |
| 140 // R0) and align frame before entering the C++ world. |
| 141 __ ReserveAlignedFrameSpace(sizeof(NativeArguments)); |
| 142 |
| 143 // Initialize NativeArguments structure and call native function. |
| 144 // Registers R0, R1, R2, and R3 are used. |
| 145 |
| 146 ASSERT(isolate_offset == 0 * kWordSize); |
| 147 // Set isolate in NativeArgs: R0 already contains CTX. |
| 148 |
| 149 // There are no native calls to closures, so we do not need to set the tag |
| 150 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. |
| 151 ASSERT(argc_tag_offset == 1 * kWordSize); |
| 152 // Set argc in NativeArguments: R1 already contains argc. |
| 153 |
| 154 ASSERT(argv_offset == 2 * kWordSize); |
| 155 // Set argv in NativeArguments: R2 already contains argv. |
| 156 |
| 157 ASSERT(retval_offset == 3 * kWordSize); |
| 158 __ add(R3, FP, ShifterOperand(2 * kWordSize)); // Set retval in NativeArgs. |
| 159 |
| 160 // TODO(regis): Should we pass the structure by value as in runtime calls? |
| 161 // It would require changing Dart API for native functions. |
| 162 // For now, space is reserved on the stack and we pass a pointer to it. |
| 163 __ stm(IA, SP, (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3)); |
| 164 __ mov(R0, ShifterOperand(SP)); // Pass the pointer to the NativeArguments. |
| 165 |
| 166 // Call native function or redirection via simulator. |
| 167 __ blx(R5); |
| 168 |
| 169 // Reset exit frame information in Isolate structure. |
| 170 __ LoadImmediate(R2, 0); |
| 171 __ StoreToOffset(kStoreWord, R2, CTX, Isolate::top_exit_frame_info_offset()); |
| 172 |
| 173 // Load Context pointer from Isolate structure into R2. |
| 174 __ LoadFromOffset(kLoadWord, R2, CTX, Isolate::top_context_offset()); |
| 175 |
| 176 // Reset Context pointer in Isolate structure. |
| 177 __ LoadImmediate(R3, reinterpret_cast<intptr_t>(Object::null())); |
| 178 __ StoreToOffset(kStoreWord, R3, CTX, Isolate::top_context_offset()); |
| 179 |
| 180 // Cache Context pointer into CTX while executing Dart code. |
| 181 __ mov(CTX, ShifterOperand(R2)); |
| 182 |
| 183 __ LeaveFrame((1 << FP) | (1 << LR)); |
| 184 __ Ret(); |
| 112 } | 185 } |
| 113 | 186 |
| 114 | 187 |
| 115 // Input parameters: | 188 // Input parameters: |
| 116 // R4: arguments descriptor array. | 189 // R4: arguments descriptor array. |
| 117 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { | 190 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { |
| 118 __ EnterStubFrame(); | 191 __ EnterStubFrame(); |
| 119 // Setup space on stack for return value and preserve arguments descriptor. | 192 // Setup space on stack for return value and preserve arguments descriptor. |
| 120 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); | 193 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); |
| 121 __ PushList((1 << R0) | (1 << R4)); | 194 __ PushList((1 << R0) | (1 << R4)); |
| (...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 421 } | 494 } |
| 422 | 495 |
| 423 | 496 |
| 424 void StubCode::GenerateIdenticalWithNumberCheckStub(Assembler* assembler) { | 497 void StubCode::GenerateIdenticalWithNumberCheckStub(Assembler* assembler) { |
| 425 __ Unimplemented("IdenticalWithNumberCheck stub"); | 498 __ Unimplemented("IdenticalWithNumberCheck stub"); |
| 426 } | 499 } |
| 427 | 500 |
| 428 } // namespace dart | 501 } // namespace dart |
| 429 | 502 |
| 430 #endif // defined TARGET_ARCH_ARM | 503 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |