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/compiler.h" | 10 #include "vm/compiler.h" |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 // Set argv in NativeArguments: R2 already contains argv. | 166 // Set argv in NativeArguments: R2 already contains argv. |
167 | 167 |
168 ASSERT(retval_offset == 3 * kWordSize); | 168 ASSERT(retval_offset == 3 * kWordSize); |
169 __ add(R3, FP, ShifterOperand(2 * kWordSize)); // Set retval in NativeArgs. | 169 __ add(R3, FP, ShifterOperand(2 * kWordSize)); // Set retval in NativeArgs. |
170 | 170 |
171 // TODO(regis): Should we pass the structure by value as in runtime calls? | 171 // TODO(regis): Should we pass the structure by value as in runtime calls? |
172 // It would require changing Dart API for native functions. | 172 // It would require changing Dart API for native functions. |
173 // For now, space is reserved on the stack and we pass a pointer to it. | 173 // For now, space is reserved on the stack and we pass a pointer to it. |
174 __ stm(IA, SP, (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3)); | 174 __ stm(IA, SP, (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3)); |
175 __ mov(R0, ShifterOperand(SP)); // Pass the pointer to the NativeArguments. | 175 __ mov(R0, ShifterOperand(SP)); // Pass the pointer to the NativeArguments. |
| 176 __ mov(R1, ShifterOperand(R5)); // Pass the function entrypoint to call. |
| 177 |
| 178 // Call native function invocation wrapper or redirection via simulator. |
| 179 #if defined(USING_SIMULATOR) |
| 180 uword entry = reinterpret_cast<uword>(NativeEntry::NativeCallWrapper); |
| 181 entry = Simulator::RedirectExternalReference( |
| 182 entry, Simulator::kNativeCall, NativeEntry::kNumCallWrapperArguments); |
| 183 __ LoadImmediate(R2, entry); |
| 184 __ blx(R2); |
| 185 #else |
| 186 __ BranchLink(&NativeEntry::NativeCallWrapperLabel()); |
| 187 #endif |
| 188 |
| 189 // Reset exit frame information in Isolate structure. |
| 190 __ LoadImmediate(R2, 0); |
| 191 __ StoreToOffset(kWord, R2, CTX, Isolate::top_exit_frame_info_offset()); |
| 192 |
| 193 // Load Context pointer from Isolate structure into R2. |
| 194 __ LoadFromOffset(kWord, R2, CTX, Isolate::top_context_offset()); |
| 195 |
| 196 // Reset Context pointer in Isolate structure. |
| 197 __ LoadImmediate(R3, reinterpret_cast<intptr_t>(Object::null())); |
| 198 __ StoreToOffset(kWord, R3, CTX, Isolate::top_context_offset()); |
| 199 |
| 200 // Cache Context pointer into CTX while executing Dart code. |
| 201 __ mov(CTX, ShifterOperand(R2)); |
| 202 |
| 203 __ LeaveFrame((1 << FP) | (1 << LR)); |
| 204 __ Ret(); |
| 205 } |
| 206 |
| 207 |
| 208 // Input parameters: |
| 209 // LR : return address. |
| 210 // SP : address of return value. |
| 211 // R5 : address of the native function to call. |
| 212 // R2 : address of first argument in argument array. |
| 213 // R1 : argc_tag including number of arguments and function kind. |
| 214 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) { |
| 215 const intptr_t isolate_offset = NativeArguments::isolate_offset(); |
| 216 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
| 217 const intptr_t argv_offset = NativeArguments::argv_offset(); |
| 218 const intptr_t retval_offset = NativeArguments::retval_offset(); |
| 219 |
| 220 __ EnterFrame((1 << FP) | (1 << LR), 0); |
| 221 |
| 222 // Load current Isolate pointer from Context structure into R0. |
| 223 __ ldr(R0, FieldAddress(CTX, Context::isolate_offset())); |
| 224 |
| 225 // Save exit frame information to enable stack walking as we are about |
| 226 // to transition to native code. |
| 227 __ StoreToOffset(kWord, SP, R0, Isolate::top_exit_frame_info_offset()); |
| 228 |
| 229 // Save current Context pointer into Isolate structure. |
| 230 __ StoreToOffset(kWord, CTX, R0, Isolate::top_context_offset()); |
| 231 |
| 232 // Cache Isolate pointer into CTX while executing native code. |
| 233 __ mov(CTX, ShifterOperand(R0)); |
| 234 |
| 235 // Reserve space for the native arguments structure passed on the stack (the |
| 236 // outgoing pointer parameter to the native arguments structure is passed in |
| 237 // R0) and align frame before entering the C++ world. |
| 238 __ ReserveAlignedFrameSpace(sizeof(NativeArguments)); |
| 239 |
| 240 // Initialize NativeArguments structure and call native function. |
| 241 // Registers R0, R1, R2, and R3 are used. |
| 242 |
| 243 ASSERT(isolate_offset == 0 * kWordSize); |
| 244 // Set isolate in NativeArgs: R0 already contains CTX. |
| 245 |
| 246 // There are no native calls to closures, so we do not need to set the tag |
| 247 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. |
| 248 ASSERT(argc_tag_offset == 1 * kWordSize); |
| 249 // Set argc in NativeArguments: R1 already contains argc. |
| 250 |
| 251 ASSERT(argv_offset == 2 * kWordSize); |
| 252 // Set argv in NativeArguments: R2 already contains argv. |
| 253 |
| 254 ASSERT(retval_offset == 3 * kWordSize); |
| 255 __ add(R3, FP, ShifterOperand(2 * kWordSize)); // Set retval in NativeArgs. |
| 256 |
| 257 // TODO(regis): Should we pass the structure by value as in runtime calls? |
| 258 // It would require changing Dart API for native functions. |
| 259 // For now, space is reserved on the stack and we pass a pointer to it. |
| 260 __ stm(IA, SP, (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3)); |
| 261 __ mov(R0, ShifterOperand(SP)); // Pass the pointer to the NativeArguments. |
176 | 262 |
177 // Call native function or redirection via simulator. | 263 // Call native function or redirection via simulator. |
178 __ blx(R5); | 264 __ blx(R5); |
179 | 265 |
180 // Reset exit frame information in Isolate structure. | 266 // Reset exit frame information in Isolate structure. |
181 __ LoadImmediate(R2, 0); | 267 __ LoadImmediate(R2, 0); |
182 __ StoreToOffset(kWord, R2, CTX, Isolate::top_exit_frame_info_offset()); | 268 __ StoreToOffset(kWord, R2, CTX, Isolate::top_exit_frame_info_offset()); |
183 | 269 |
184 // Load Context pointer from Isolate structure into R2. | 270 // Load Context pointer from Isolate structure into R2. |
185 __ LoadFromOffset(kWord, R2, CTX, Isolate::top_context_offset()); | 271 __ LoadFromOffset(kWord, R2, CTX, Isolate::top_context_offset()); |
(...skipping 1906 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2092 __ ldr(left, Address(SP, 4 * kWordSize)); | 2178 __ ldr(left, Address(SP, 4 * kWordSize)); |
2093 __ ldr(right, Address(SP, 3 * kWordSize)); | 2179 __ ldr(right, Address(SP, 3 * kWordSize)); |
2094 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 2180 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); |
2095 __ PopList((1 << R0) | (1 << R1) | (1 << R2)); | 2181 __ PopList((1 << R0) | (1 << R1) | (1 << R2)); |
2096 __ Ret(); | 2182 __ Ret(); |
2097 } | 2183 } |
2098 | 2184 |
2099 } // namespace dart | 2185 } // namespace dart |
2100 | 2186 |
2101 #endif // defined TARGET_ARCH_ARM | 2187 #endif // defined TARGET_ARCH_ARM |
OLD | NEW |