| 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 21 matching lines...) Expand all Loading... |
| 32 // SP : address of last argument in argument array. | 32 // SP : address of last argument in argument array. |
| 33 // SP + 4*R4 - 4 : address of first argument in argument array. | 33 // SP + 4*R4 - 4 : address of first argument in argument array. |
| 34 // SP + 4*R4 : address of return value. | 34 // SP + 4*R4 : address of return value. |
| 35 // R5 : address of the runtime function to call. | 35 // R5 : address of the runtime function to call. |
| 36 // R4 : number of arguments to the call. | 36 // R4 : number of arguments to the call. |
| 37 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { | 37 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { |
| 38 const intptr_t isolate_offset = NativeArguments::isolate_offset(); | 38 const intptr_t isolate_offset = NativeArguments::isolate_offset(); |
| 39 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); | 39 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
| 40 const intptr_t argv_offset = NativeArguments::argv_offset(); | 40 const intptr_t argv_offset = NativeArguments::argv_offset(); |
| 41 const intptr_t retval_offset = NativeArguments::retval_offset(); | 41 const intptr_t retval_offset = NativeArguments::retval_offset(); |
| 42 const intptr_t exitframe_last_param_slot_from_fp = 1; | 42 const intptr_t exitframe_last_param_slot_from_fp = 2; |
| 43 | 43 |
| 44 __ mov(IP, ShifterOperand(0)); |
| 45 __ Push(IP); // Push 0 for the PC marker. |
| 44 __ EnterFrame((1 << FP) | (1 << LR), 0); | 46 __ EnterFrame((1 << FP) | (1 << LR), 0); |
| 45 | 47 |
| 46 // Load current Isolate pointer from Context structure into R0. | 48 // Load current Isolate pointer from Context structure into R0. |
| 47 __ ldr(R0, FieldAddress(CTX, Context::isolate_offset())); | 49 __ ldr(R0, FieldAddress(CTX, Context::isolate_offset())); |
| 48 | 50 |
| 49 // Save exit frame information to enable stack walking as we are about | 51 // Save exit frame information to enable stack walking as we are about |
| 50 // to transition to Dart VM C++ code. | 52 // to transition to Dart VM C++ code. |
| 51 __ StoreToOffset(kWord, SP, R0, Isolate::top_exit_frame_info_offset()); | 53 __ StoreToOffset(kWord, SP, R0, Isolate::top_exit_frame_info_offset()); |
| 52 | 54 |
| 53 // Save current Context pointer into Isolate structure. | 55 // Save current Context pointer into Isolate structure. |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 __ LoadFromOffset(kWord, R2, CTX, Isolate::top_context_offset()); | 93 __ LoadFromOffset(kWord, R2, CTX, Isolate::top_context_offset()); |
| 92 | 94 |
| 93 // Reset Context pointer in Isolate structure. | 95 // Reset Context pointer in Isolate structure. |
| 94 __ LoadImmediate(R3, reinterpret_cast<intptr_t>(Object::null())); | 96 __ LoadImmediate(R3, reinterpret_cast<intptr_t>(Object::null())); |
| 95 __ StoreToOffset(kWord, R3, CTX, Isolate::top_context_offset()); | 97 __ StoreToOffset(kWord, R3, CTX, Isolate::top_context_offset()); |
| 96 | 98 |
| 97 // Cache Context pointer into CTX while executing Dart code. | 99 // Cache Context pointer into CTX while executing Dart code. |
| 98 __ mov(CTX, ShifterOperand(R2)); | 100 __ mov(CTX, ShifterOperand(R2)); |
| 99 | 101 |
| 100 __ LeaveFrame((1 << FP) | (1 << LR)); | 102 __ LeaveFrame((1 << FP) | (1 << LR)); |
| 103 // Adjust SP for the empty PC marker. |
| 104 __ AddImmediate(SP, kWordSize); |
| 101 __ Ret(); | 105 __ Ret(); |
| 102 } | 106 } |
| 103 | 107 |
| 104 | 108 |
| 105 // Print the stop message. | 109 // Print the stop message. |
| 106 DEFINE_LEAF_RUNTIME_ENTRY(void, PrintStopMessage, 1, const char* message) { | 110 DEFINE_LEAF_RUNTIME_ENTRY(void, PrintStopMessage, 1, const char* message) { |
| 107 OS::Print("Stop message: %s\n", message); | 111 OS::Print("Stop message: %s\n", message); |
| 108 } | 112 } |
| 109 END_LEAF_RUNTIME_ENTRY | 113 END_LEAF_RUNTIME_ENTRY |
| 110 | 114 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 126 // SP : address of return value. | 130 // SP : address of return value. |
| 127 // R5 : address of the native function to call. | 131 // R5 : address of the native function to call. |
| 128 // R2 : address of first argument in argument array. | 132 // R2 : address of first argument in argument array. |
| 129 // R1 : argc_tag including number of arguments and function kind. | 133 // R1 : argc_tag including number of arguments and function kind. |
| 130 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) { | 134 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) { |
| 131 const intptr_t isolate_offset = NativeArguments::isolate_offset(); | 135 const intptr_t isolate_offset = NativeArguments::isolate_offset(); |
| 132 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); | 136 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
| 133 const intptr_t argv_offset = NativeArguments::argv_offset(); | 137 const intptr_t argv_offset = NativeArguments::argv_offset(); |
| 134 const intptr_t retval_offset = NativeArguments::retval_offset(); | 138 const intptr_t retval_offset = NativeArguments::retval_offset(); |
| 135 | 139 |
| 140 __ mov(IP, ShifterOperand(0)); |
| 141 __ Push(IP); // Push 0 for the PC marker. |
| 136 __ EnterFrame((1 << FP) | (1 << LR), 0); | 142 __ EnterFrame((1 << FP) | (1 << LR), 0); |
| 137 | 143 |
| 138 // Load current Isolate pointer from Context structure into R0. | 144 // Load current Isolate pointer from Context structure into R0. |
| 139 __ ldr(R0, FieldAddress(CTX, Context::isolate_offset())); | 145 __ ldr(R0, FieldAddress(CTX, Context::isolate_offset())); |
| 140 | 146 |
| 141 // Save exit frame information to enable stack walking as we are about | 147 // Save exit frame information to enable stack walking as we are about |
| 142 // to transition to native code. | 148 // to transition to native code. |
| 143 __ StoreToOffset(kWord, SP, R0, Isolate::top_exit_frame_info_offset()); | 149 __ StoreToOffset(kWord, SP, R0, Isolate::top_exit_frame_info_offset()); |
| 144 | 150 |
| 145 // Save current Context pointer into Isolate structure. | 151 // Save current Context pointer into Isolate structure. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 161 | 167 |
| 162 // There are no native calls to closures, so we do not need to set the tag | 168 // There are no native calls to closures, so we do not need to set the tag |
| 163 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. | 169 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. |
| 164 ASSERT(argc_tag_offset == 1 * kWordSize); | 170 ASSERT(argc_tag_offset == 1 * kWordSize); |
| 165 // Set argc in NativeArguments: R1 already contains argc. | 171 // Set argc in NativeArguments: R1 already contains argc. |
| 166 | 172 |
| 167 ASSERT(argv_offset == 2 * kWordSize); | 173 ASSERT(argv_offset == 2 * kWordSize); |
| 168 // Set argv in NativeArguments: R2 already contains argv. | 174 // Set argv in NativeArguments: R2 already contains argv. |
| 169 | 175 |
| 170 ASSERT(retval_offset == 3 * kWordSize); | 176 ASSERT(retval_offset == 3 * kWordSize); |
| 171 __ add(R3, FP, ShifterOperand(2 * kWordSize)); // Set retval in NativeArgs. | 177 __ add(R3, FP, ShifterOperand(3 * kWordSize)); // Set retval in NativeArgs. |
| 172 | 178 |
| 173 // TODO(regis): Should we pass the structure by value as in runtime calls? | 179 // TODO(regis): Should we pass the structure by value as in runtime calls? |
| 174 // It would require changing Dart API for native functions. | 180 // It would require changing Dart API for native functions. |
| 175 // For now, space is reserved on the stack and we pass a pointer to it. | 181 // For now, space is reserved on the stack and we pass a pointer to it. |
| 176 __ stm(IA, SP, (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3)); | 182 __ stm(IA, SP, (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3)); |
| 177 __ mov(R0, ShifterOperand(SP)); // Pass the pointer to the NativeArguments. | 183 __ mov(R0, ShifterOperand(SP)); // Pass the pointer to the NativeArguments. |
| 178 __ mov(R1, ShifterOperand(R5)); // Pass the function entrypoint to call. | 184 __ mov(R1, ShifterOperand(R5)); // Pass the function entrypoint to call. |
| 179 | 185 |
| 180 // Call native function invocation wrapper or redirection via simulator. | 186 // Call native function invocation wrapper or redirection via simulator. |
| 181 #if defined(USING_SIMULATOR) | 187 #if defined(USING_SIMULATOR) |
| (...skipping 14 matching lines...) Expand all Loading... |
| 196 __ LoadFromOffset(kWord, R2, CTX, Isolate::top_context_offset()); | 202 __ LoadFromOffset(kWord, R2, CTX, Isolate::top_context_offset()); |
| 197 | 203 |
| 198 // Reset Context pointer in Isolate structure. | 204 // Reset Context pointer in Isolate structure. |
| 199 __ LoadImmediate(R3, reinterpret_cast<intptr_t>(Object::null())); | 205 __ LoadImmediate(R3, reinterpret_cast<intptr_t>(Object::null())); |
| 200 __ StoreToOffset(kWord, R3, CTX, Isolate::top_context_offset()); | 206 __ StoreToOffset(kWord, R3, CTX, Isolate::top_context_offset()); |
| 201 | 207 |
| 202 // Cache Context pointer into CTX while executing Dart code. | 208 // Cache Context pointer into CTX while executing Dart code. |
| 203 __ mov(CTX, ShifterOperand(R2)); | 209 __ mov(CTX, ShifterOperand(R2)); |
| 204 | 210 |
| 205 __ LeaveFrame((1 << FP) | (1 << LR)); | 211 __ LeaveFrame((1 << FP) | (1 << LR)); |
| 212 // Adjust SP for the empty PC marker. |
| 213 __ AddImmediate(SP, kWordSize); |
| 206 __ Ret(); | 214 __ Ret(); |
| 207 } | 215 } |
| 208 | 216 |
| 209 | 217 |
| 210 // Input parameters: | 218 // Input parameters: |
| 211 // LR : return address. | 219 // LR : return address. |
| 212 // SP : address of return value. | 220 // SP : address of return value. |
| 213 // R5 : address of the native function to call. | 221 // R5 : address of the native function to call. |
| 214 // R2 : address of first argument in argument array. | 222 // R2 : address of first argument in argument array. |
| 215 // R1 : argc_tag including number of arguments and function kind. | 223 // R1 : argc_tag including number of arguments and function kind. |
| 216 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) { | 224 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) { |
| 217 const intptr_t isolate_offset = NativeArguments::isolate_offset(); | 225 const intptr_t isolate_offset = NativeArguments::isolate_offset(); |
| 218 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); | 226 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
| 219 const intptr_t argv_offset = NativeArguments::argv_offset(); | 227 const intptr_t argv_offset = NativeArguments::argv_offset(); |
| 220 const intptr_t retval_offset = NativeArguments::retval_offset(); | 228 const intptr_t retval_offset = NativeArguments::retval_offset(); |
| 221 | 229 |
| 230 __ mov(IP, ShifterOperand(0)); |
| 231 __ Push(IP); // Push 0 for the PC marker. |
| 222 __ EnterFrame((1 << FP) | (1 << LR), 0); | 232 __ EnterFrame((1 << FP) | (1 << LR), 0); |
| 223 | 233 |
| 224 // Load current Isolate pointer from Context structure into R0. | 234 // Load current Isolate pointer from Context structure into R0. |
| 225 __ ldr(R0, FieldAddress(CTX, Context::isolate_offset())); | 235 __ ldr(R0, FieldAddress(CTX, Context::isolate_offset())); |
| 226 | 236 |
| 227 // Save exit frame information to enable stack walking as we are about | 237 // Save exit frame information to enable stack walking as we are about |
| 228 // to transition to native code. | 238 // to transition to native code. |
| 229 __ StoreToOffset(kWord, SP, R0, Isolate::top_exit_frame_info_offset()); | 239 __ StoreToOffset(kWord, SP, R0, Isolate::top_exit_frame_info_offset()); |
| 230 | 240 |
| 231 // Save current Context pointer into Isolate structure. | 241 // Save current Context pointer into Isolate structure. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 247 | 257 |
| 248 // There are no native calls to closures, so we do not need to set the tag | 258 // There are no native calls to closures, so we do not need to set the tag |
| 249 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. | 259 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. |
| 250 ASSERT(argc_tag_offset == 1 * kWordSize); | 260 ASSERT(argc_tag_offset == 1 * kWordSize); |
| 251 // Set argc in NativeArguments: R1 already contains argc. | 261 // Set argc in NativeArguments: R1 already contains argc. |
| 252 | 262 |
| 253 ASSERT(argv_offset == 2 * kWordSize); | 263 ASSERT(argv_offset == 2 * kWordSize); |
| 254 // Set argv in NativeArguments: R2 already contains argv. | 264 // Set argv in NativeArguments: R2 already contains argv. |
| 255 | 265 |
| 256 ASSERT(retval_offset == 3 * kWordSize); | 266 ASSERT(retval_offset == 3 * kWordSize); |
| 257 __ add(R3, FP, ShifterOperand(2 * kWordSize)); // Set retval in NativeArgs. | 267 __ add(R3, FP, ShifterOperand(3 * kWordSize)); // Set retval in NativeArgs. |
| 258 | 268 |
| 259 // TODO(regis): Should we pass the structure by value as in runtime calls? | 269 // TODO(regis): Should we pass the structure by value as in runtime calls? |
| 260 // It would require changing Dart API for native functions. | 270 // It would require changing Dart API for native functions. |
| 261 // For now, space is reserved on the stack and we pass a pointer to it. | 271 // For now, space is reserved on the stack and we pass a pointer to it. |
| 262 __ stm(IA, SP, (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3)); | 272 __ stm(IA, SP, (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3)); |
| 263 __ mov(R0, ShifterOperand(SP)); // Pass the pointer to the NativeArguments. | 273 __ mov(R0, ShifterOperand(SP)); // Pass the pointer to the NativeArguments. |
| 264 | 274 |
| 265 // Call native function or redirection via simulator. | 275 // Call native function or redirection via simulator. |
| 266 __ blx(R5); | 276 __ blx(R5); |
| 267 | 277 |
| 268 // Reset exit frame information in Isolate structure. | 278 // Reset exit frame information in Isolate structure. |
| 269 __ LoadImmediate(R2, 0); | 279 __ LoadImmediate(R2, 0); |
| 270 __ StoreToOffset(kWord, R2, CTX, Isolate::top_exit_frame_info_offset()); | 280 __ StoreToOffset(kWord, R2, CTX, Isolate::top_exit_frame_info_offset()); |
| 271 | 281 |
| 272 // Load Context pointer from Isolate structure into R2. | 282 // Load Context pointer from Isolate structure into R2. |
| 273 __ LoadFromOffset(kWord, R2, CTX, Isolate::top_context_offset()); | 283 __ LoadFromOffset(kWord, R2, CTX, Isolate::top_context_offset()); |
| 274 | 284 |
| 275 // Reset Context pointer in Isolate structure. | 285 // Reset Context pointer in Isolate structure. |
| 276 __ LoadImmediate(R3, reinterpret_cast<intptr_t>(Object::null())); | 286 __ LoadImmediate(R3, reinterpret_cast<intptr_t>(Object::null())); |
| 277 __ StoreToOffset(kWord, R3, CTX, Isolate::top_context_offset()); | 287 __ StoreToOffset(kWord, R3, CTX, Isolate::top_context_offset()); |
| 278 | 288 |
| 279 // Cache Context pointer into CTX while executing Dart code. | 289 // Cache Context pointer into CTX while executing Dart code. |
| 280 __ mov(CTX, ShifterOperand(R2)); | 290 __ mov(CTX, ShifterOperand(R2)); |
| 281 | 291 |
| 282 __ LeaveFrame((1 << FP) | (1 << LR)); | 292 __ LeaveFrame((1 << FP) | (1 << LR)); |
| 293 // Adjust SP for the empty PC marker. |
| 294 __ AddImmediate(SP, kWordSize); |
| 283 __ Ret(); | 295 __ Ret(); |
| 284 } | 296 } |
| 285 | 297 |
| 286 | 298 |
| 287 // Input parameters: | 299 // Input parameters: |
| 288 // R4: arguments descriptor array. | 300 // R4: arguments descriptor array. |
| 289 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { | 301 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { |
| 290 // Create a stub frame as we are pushing some objects on the stack before | 302 // Create a stub frame as we are pushing some objects on the stack before |
| 291 // calling into the runtime. | 303 // calling into the runtime. |
| 292 __ EnterStubFrame(); | 304 __ EnterStubFrame(); |
| (...skipping 1849 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2142 const Register right = R0; | 2154 const Register right = R0; |
| 2143 __ ldr(left, Address(SP, 1 * kWordSize)); | 2155 __ ldr(left, Address(SP, 1 * kWordSize)); |
| 2144 __ ldr(right, Address(SP, 0 * kWordSize)); | 2156 __ ldr(right, Address(SP, 0 * kWordSize)); |
| 2145 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 2157 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); |
| 2146 __ Ret(); | 2158 __ Ret(); |
| 2147 } | 2159 } |
| 2148 | 2160 |
| 2149 } // namespace dart | 2161 } // namespace dart |
| 2150 | 2162 |
| 2151 #endif // defined TARGET_ARCH_ARM | 2163 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |