OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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_ARM64) | 6 #if defined(TARGET_ARCH_ARM64) |
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 18 matching lines...) Expand all Loading... |
29 DECLARE_FLAG(bool, support_debugger); | 29 DECLARE_FLAG(bool, support_debugger); |
30 | 30 |
31 // Input parameters: | 31 // Input parameters: |
32 // LR : return address. | 32 // LR : return address. |
33 // SP : address of last argument in argument array. | 33 // SP : address of last argument in argument array. |
34 // SP + 8*R4 - 8 : address of first argument in argument array. | 34 // SP + 8*R4 - 8 : address of first argument in argument array. |
35 // SP + 8*R4 : address of return value. | 35 // SP + 8*R4 : address of return value. |
36 // R5 : address of the runtime function to call. | 36 // R5 : address of the runtime function to call. |
37 // R4 : number of arguments to the call. | 37 // R4 : number of arguments to the call. |
38 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { | 38 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { |
39 const intptr_t isolate_offset = NativeArguments::isolate_offset(); | 39 const intptr_t thread_offset = NativeArguments::thread_offset(); |
40 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); | 40 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
41 const intptr_t argv_offset = NativeArguments::argv_offset(); | 41 const intptr_t argv_offset = NativeArguments::argv_offset(); |
42 const intptr_t retval_offset = NativeArguments::retval_offset(); | 42 const intptr_t retval_offset = NativeArguments::retval_offset(); |
43 const intptr_t exitframe_last_param_slot_from_fp = 1; | 43 const intptr_t exitframe_last_param_slot_from_fp = 1; |
44 | 44 |
45 __ SetPrologueOffset(); | 45 __ SetPrologueOffset(); |
46 __ Comment("CallToRuntimeStub"); | 46 __ Comment("CallToRuntimeStub"); |
47 __ EnterFrame(0); | 47 __ EnterFrame(0); |
48 | 48 |
49 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R28)) != 0); | 49 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R28)) != 0); |
(...skipping 20 matching lines...) Expand all Loading... |
70 // Reserve space for arguments and align frame before entering C++ world. | 70 // Reserve space for arguments and align frame before entering C++ world. |
71 // NativeArguments are passed in registers. | 71 // NativeArguments are passed in registers. |
72 __ Comment("align stack"); | 72 __ Comment("align stack"); |
73 // Reserve space for arguments. | 73 // Reserve space for arguments. |
74 ASSERT(sizeof(NativeArguments) == 4 * kWordSize); | 74 ASSERT(sizeof(NativeArguments) == 4 * kWordSize); |
75 __ ReserveAlignedFrameSpace(sizeof(NativeArguments)); | 75 __ ReserveAlignedFrameSpace(sizeof(NativeArguments)); |
76 | 76 |
77 // Pass NativeArguments structure by value and call runtime. | 77 // Pass NativeArguments structure by value and call runtime. |
78 // Registers R0, R1, R2, and R3 are used. | 78 // Registers R0, R1, R2, and R3 are used. |
79 | 79 |
80 ASSERT(isolate_offset == 0 * kWordSize); | 80 ASSERT(thread_offset == 0 * kWordSize); |
81 // Set isolate in NativeArgs. | 81 // Set thread in NativeArgs. |
82 __ mov(R0, R28); | 82 __ mov(R0, THR); |
83 | 83 |
84 // There are no runtime calls to closures, so we do not need to set the tag | 84 // There are no runtime calls to closures, so we do not need to set the tag |
85 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. | 85 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. |
86 ASSERT(argc_tag_offset == 1 * kWordSize); | 86 ASSERT(argc_tag_offset == 1 * kWordSize); |
87 __ mov(R1, R4); // Set argc in NativeArguments. | 87 __ mov(R1, R4); // Set argc in NativeArguments. |
88 | 88 |
89 ASSERT(argv_offset == 2 * kWordSize); | 89 ASSERT(argv_offset == 2 * kWordSize); |
90 __ add(R2, ZR, Operand(R4, LSL, 3)); | 90 __ add(R2, ZR, Operand(R4, LSL, 3)); |
91 __ add(R2, FP, Operand(R2)); // Compute argv. | 91 __ add(R2, FP, Operand(R2)); // Compute argv. |
92 // Set argv in NativeArguments. | 92 // Set argv in NativeArguments. |
93 __ AddImmediate(R2, R2, exitframe_last_param_slot_from_fp * kWordSize, kNoPP); | 93 __ AddImmediate(R2, R2, exitframe_last_param_slot_from_fp * kWordSize, kNoPP); |
94 | 94 |
95 ASSERT(retval_offset == 3 * kWordSize); | 95 ASSERT(retval_offset == 3 * kWordSize); |
96 __ AddImmediate(R3, R2, kWordSize, kNoPP); | 96 __ AddImmediate(R3, R2, kWordSize, kNoPP); |
97 | 97 |
98 __ StoreToOffset(R0, SP, isolate_offset, kNoPP); | 98 __ StoreToOffset(R0, SP, thread_offset, kNoPP); |
99 __ StoreToOffset(R1, SP, argc_tag_offset, kNoPP); | 99 __ StoreToOffset(R1, SP, argc_tag_offset, kNoPP); |
100 __ StoreToOffset(R2, SP, argv_offset, kNoPP); | 100 __ StoreToOffset(R2, SP, argv_offset, kNoPP); |
101 __ StoreToOffset(R3, SP, retval_offset, kNoPP); | 101 __ StoreToOffset(R3, SP, retval_offset, kNoPP); |
102 __ mov(R0, SP); // Pass the pointer to the NativeArguments. | 102 __ mov(R0, SP); // Pass the pointer to the NativeArguments. |
103 | 103 |
104 // We are entering runtime code, so the C stack pointer must be restored from | 104 // We are entering runtime code, so the C stack pointer must be restored from |
105 // the stack limit to the top of the stack. We cache the stack limit address | 105 // the stack limit to the top of the stack. We cache the stack limit address |
106 // in a callee-saved register. | 106 // in a callee-saved register. |
107 __ mov(R26, CSP); | 107 __ mov(R26, CSP); |
108 __ mov(CSP, SP); | 108 __ mov(CSP, SP); |
(...skipping 23 matching lines...) Expand all Loading... |
132 } | 132 } |
133 | 133 |
134 | 134 |
135 // Input parameters: | 135 // Input parameters: |
136 // LR : return address. | 136 // LR : return address. |
137 // SP : address of return value. | 137 // SP : address of return value. |
138 // R5 : address of the native function to call. | 138 // R5 : address of the native function to call. |
139 // R2 : address of first argument in argument array. | 139 // R2 : address of first argument in argument array. |
140 // R1 : argc_tag including number of arguments and function kind. | 140 // R1 : argc_tag including number of arguments and function kind. |
141 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) { | 141 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) { |
142 const intptr_t isolate_offset = NativeArguments::isolate_offset(); | 142 const intptr_t thread_offset = NativeArguments::thread_offset(); |
143 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); | 143 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
144 const intptr_t argv_offset = NativeArguments::argv_offset(); | 144 const intptr_t argv_offset = NativeArguments::argv_offset(); |
145 const intptr_t retval_offset = NativeArguments::retval_offset(); | 145 const intptr_t retval_offset = NativeArguments::retval_offset(); |
146 | 146 |
147 __ EnterFrame(0); | 147 __ EnterFrame(0); |
148 | 148 |
149 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R28)) != 0); | 149 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R28)) != 0); |
150 __ LoadIsolate(R28, kNoPP); | 150 __ LoadIsolate(R28, kNoPP); |
151 | 151 |
152 // Save exit frame information to enable stack walking as we are about | 152 // Save exit frame information to enable stack walking as we are about |
(...skipping 15 matching lines...) Expand all Loading... |
168 __ StoreToOffset(R5, R28, Isolate::vm_tag_offset(), kNoPP); | 168 __ StoreToOffset(R5, R28, Isolate::vm_tag_offset(), kNoPP); |
169 | 169 |
170 // Reserve space for the native arguments structure passed on the stack (the | 170 // Reserve space for the native arguments structure passed on the stack (the |
171 // outgoing pointer parameter to the native arguments structure is passed in | 171 // outgoing pointer parameter to the native arguments structure is passed in |
172 // R0) and align frame before entering the C++ world. | 172 // R0) and align frame before entering the C++ world. |
173 __ ReserveAlignedFrameSpace(sizeof(NativeArguments)); | 173 __ ReserveAlignedFrameSpace(sizeof(NativeArguments)); |
174 | 174 |
175 // Initialize NativeArguments structure and call native function. | 175 // Initialize NativeArguments structure and call native function. |
176 // Registers R0, R1, R2, and R3 are used. | 176 // Registers R0, R1, R2, and R3 are used. |
177 | 177 |
178 ASSERT(isolate_offset == 0 * kWordSize); | 178 ASSERT(thread_offset == 0 * kWordSize); |
179 // Set isolate in NativeArgs. | 179 // Set thread in NativeArgs. |
180 __ mov(R0, R28); | 180 __ mov(R0, THR); |
181 | 181 |
182 // There are no native calls to closures, so we do not need to set the tag | 182 // There are no native calls to closures, so we do not need to set the tag |
183 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. | 183 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. |
184 ASSERT(argc_tag_offset == 1 * kWordSize); | 184 ASSERT(argc_tag_offset == 1 * kWordSize); |
185 // Set argc in NativeArguments: R1 already contains argc. | 185 // Set argc in NativeArguments: R1 already contains argc. |
186 | 186 |
187 ASSERT(argv_offset == 2 * kWordSize); | 187 ASSERT(argv_offset == 2 * kWordSize); |
188 // Set argv in NativeArguments: R2 already contains argv. | 188 // Set argv in NativeArguments: R2 already contains argv. |
189 | 189 |
190 // Set retval in NativeArgs. | 190 // Set retval in NativeArgs. |
191 ASSERT(retval_offset == 3 * kWordSize); | 191 ASSERT(retval_offset == 3 * kWordSize); |
192 __ AddImmediate(R3, FP, 2 * kWordSize, kNoPP); | 192 __ AddImmediate(R3, FP, 2 * kWordSize, kNoPP); |
193 | 193 |
194 // Passing the structure by value as in runtime calls would require changing | 194 // Passing the structure by value as in runtime calls would require changing |
195 // Dart API for native functions. | 195 // Dart API for native functions. |
196 // For now, space is reserved on the stack and we pass a pointer to it. | 196 // For now, space is reserved on the stack and we pass a pointer to it. |
197 __ StoreToOffset(R0, SP, isolate_offset, kNoPP); | 197 __ StoreToOffset(R0, SP, thread_offset, kNoPP); |
198 __ StoreToOffset(R1, SP, argc_tag_offset, kNoPP); | 198 __ StoreToOffset(R1, SP, argc_tag_offset, kNoPP); |
199 __ StoreToOffset(R2, SP, argv_offset, kNoPP); | 199 __ StoreToOffset(R2, SP, argv_offset, kNoPP); |
200 __ StoreToOffset(R3, SP, retval_offset, kNoPP); | 200 __ StoreToOffset(R3, SP, retval_offset, kNoPP); |
201 __ mov(R0, SP); // Pass the pointer to the NativeArguments. | 201 __ mov(R0, SP); // Pass the pointer to the NativeArguments. |
202 | 202 |
203 // We are entering runtime code, so the C stack pointer must be restored from | 203 // We are entering runtime code, so the C stack pointer must be restored from |
204 // the stack limit to the top of the stack. We cache the stack limit address | 204 // the stack limit to the top of the stack. We cache the stack limit address |
205 // in the Dart SP register, which is callee-saved in the C ABI. | 205 // in the Dart SP register, which is callee-saved in the C ABI. |
206 __ mov(R26, CSP); | 206 __ mov(R26, CSP); |
207 __ mov(CSP, SP); | 207 __ mov(CSP, SP); |
(...skipping 26 matching lines...) Expand all Loading... |
234 } | 234 } |
235 | 235 |
236 | 236 |
237 // Input parameters: | 237 // Input parameters: |
238 // LR : return address. | 238 // LR : return address. |
239 // SP : address of return value. | 239 // SP : address of return value. |
240 // R5 : address of the native function to call. | 240 // R5 : address of the native function to call. |
241 // R2 : address of first argument in argument array. | 241 // R2 : address of first argument in argument array. |
242 // R1 : argc_tag including number of arguments and function kind. | 242 // R1 : argc_tag including number of arguments and function kind. |
243 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) { | 243 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) { |
244 const intptr_t isolate_offset = NativeArguments::isolate_offset(); | 244 const intptr_t thread_offset = NativeArguments::thread_offset(); |
245 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); | 245 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
246 const intptr_t argv_offset = NativeArguments::argv_offset(); | 246 const intptr_t argv_offset = NativeArguments::argv_offset(); |
247 const intptr_t retval_offset = NativeArguments::retval_offset(); | 247 const intptr_t retval_offset = NativeArguments::retval_offset(); |
248 | 248 |
249 __ EnterFrame(0); | 249 __ EnterFrame(0); |
250 | 250 |
251 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R28)) != 0); | 251 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R28)) != 0); |
252 __ LoadIsolate(R28, kNoPP); | 252 __ LoadIsolate(R28, kNoPP); |
253 | 253 |
254 // Save exit frame information to enable stack walking as we are about | 254 // Save exit frame information to enable stack walking as we are about |
(...skipping 15 matching lines...) Expand all Loading... |
270 __ StoreToOffset(R5, R28, Isolate::vm_tag_offset(), kNoPP); | 270 __ StoreToOffset(R5, R28, Isolate::vm_tag_offset(), kNoPP); |
271 | 271 |
272 // Reserve space for the native arguments structure passed on the stack (the | 272 // Reserve space for the native arguments structure passed on the stack (the |
273 // outgoing pointer parameter to the native arguments structure is passed in | 273 // outgoing pointer parameter to the native arguments structure is passed in |
274 // R0) and align frame before entering the C++ world. | 274 // R0) and align frame before entering the C++ world. |
275 __ ReserveAlignedFrameSpace(sizeof(NativeArguments)); | 275 __ ReserveAlignedFrameSpace(sizeof(NativeArguments)); |
276 | 276 |
277 // Initialize NativeArguments structure and call native function. | 277 // Initialize NativeArguments structure and call native function. |
278 // Registers R0, R1, R2, and R3 are used. | 278 // Registers R0, R1, R2, and R3 are used. |
279 | 279 |
280 ASSERT(isolate_offset == 0 * kWordSize); | 280 ASSERT(thread_offset == 0 * kWordSize); |
281 // Set isolate in NativeArgs. | 281 // Set thread in NativeArgs. |
282 __ mov(R0, R28); | 282 __ mov(R0, THR); |
283 | 283 |
284 // There are no native calls to closures, so we do not need to set the tag | 284 // There are no native calls to closures, so we do not need to set the tag |
285 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. | 285 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. |
286 ASSERT(argc_tag_offset == 1 * kWordSize); | 286 ASSERT(argc_tag_offset == 1 * kWordSize); |
287 // Set argc in NativeArguments: R1 already contains argc. | 287 // Set argc in NativeArguments: R1 already contains argc. |
288 | 288 |
289 ASSERT(argv_offset == 2 * kWordSize); | 289 ASSERT(argv_offset == 2 * kWordSize); |
290 // Set argv in NativeArguments: R2 already contains argv. | 290 // Set argv in NativeArguments: R2 already contains argv. |
291 | 291 |
292 // Set retval in NativeArgs. | 292 // Set retval in NativeArgs. |
293 ASSERT(retval_offset == 3 * kWordSize); | 293 ASSERT(retval_offset == 3 * kWordSize); |
294 __ AddImmediate(R3, FP, 2 * kWordSize, kNoPP); | 294 __ AddImmediate(R3, FP, 2 * kWordSize, kNoPP); |
295 | 295 |
296 // Passing the structure by value as in runtime calls would require changing | 296 // Passing the structure by value as in runtime calls would require changing |
297 // Dart API for native functions. | 297 // Dart API for native functions. |
298 // For now, space is reserved on the stack and we pass a pointer to it. | 298 // For now, space is reserved on the stack and we pass a pointer to it. |
299 __ StoreToOffset(R0, SP, isolate_offset, kNoPP); | 299 __ StoreToOffset(R0, SP, thread_offset, kNoPP); |
300 __ StoreToOffset(R1, SP, argc_tag_offset, kNoPP); | 300 __ StoreToOffset(R1, SP, argc_tag_offset, kNoPP); |
301 __ StoreToOffset(R2, SP, argv_offset, kNoPP); | 301 __ StoreToOffset(R2, SP, argv_offset, kNoPP); |
302 __ StoreToOffset(R3, SP, retval_offset, kNoPP); | 302 __ StoreToOffset(R3, SP, retval_offset, kNoPP); |
303 __ mov(R0, SP); // Pass the pointer to the NativeArguments. | 303 __ mov(R0, SP); // Pass the pointer to the NativeArguments. |
304 | 304 |
305 // We are entering runtime code, so the C stack pointer must be restored from | 305 // We are entering runtime code, so the C stack pointer must be restored from |
306 // the stack limit to the top of the stack. We cache the stack limit address | 306 // the stack limit to the top of the stack. We cache the stack limit address |
307 // in the Dart SP register, which is callee-saved in the C ABI. | 307 // in the Dart SP register, which is callee-saved in the C ABI. |
308 __ mov(R26, CSP); | 308 __ mov(R26, CSP); |
309 __ mov(CSP, SP); | 309 __ mov(CSP, SP); |
(...skipping 1660 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1970 } | 1970 } |
1971 | 1971 |
1972 | 1972 |
1973 // Jump to the exception or error handler. | 1973 // Jump to the exception or error handler. |
1974 // LR: return address. | 1974 // LR: return address. |
1975 // R0: program_counter. | 1975 // R0: program_counter. |
1976 // R1: stack_pointer. | 1976 // R1: stack_pointer. |
1977 // R2: frame_pointer. | 1977 // R2: frame_pointer. |
1978 // R3: error object. | 1978 // R3: error object. |
1979 // R4: address of stacktrace object. | 1979 // R4: address of stacktrace object. |
1980 // R5: isolate. | 1980 // R5: thread. |
1981 // Does not return. | 1981 // Does not return. |
1982 void StubCode::GenerateJumpToExceptionHandlerStub(Assembler* assembler) { | 1982 void StubCode::GenerateJumpToExceptionHandlerStub(Assembler* assembler) { |
1983 ASSERT(kExceptionObjectReg == R0); | 1983 ASSERT(kExceptionObjectReg == R0); |
1984 ASSERT(kStackTraceObjectReg == R1); | 1984 ASSERT(kStackTraceObjectReg == R1); |
1985 __ mov(LR, R0); // Program counter. | 1985 __ mov(LR, R0); // Program counter. |
1986 __ mov(SP, R1); // Stack pointer. | 1986 __ mov(SP, R1); // Stack pointer. |
1987 __ mov(FP, R2); // Frame_pointer. | 1987 __ mov(FP, R2); // Frame_pointer. |
1988 __ mov(R0, R3); // Exception object. | 1988 __ mov(R0, R3); // Exception object. |
1989 __ mov(R1, R4); // StackTrace object. | 1989 __ mov(R1, R4); // StackTrace object. |
1990 // TODO(koda): Pass thread instead of isolate. | 1990 __ mov(THR, R5); |
1991 __ LoadFromOffset(THR, R5, Isolate::mutator_thread_offset(), kNoPP); | 1991 __ LoadIsolate(R5, kNoPP); |
1992 // Set the tag. | 1992 // Set the tag. |
1993 __ LoadImmediate(R2, VMTag::kDartTagId, kNoPP); | 1993 __ LoadImmediate(R2, VMTag::kDartTagId, kNoPP); |
1994 __ StoreToOffset(R2, R5, Isolate::vm_tag_offset(), kNoPP); | 1994 __ StoreToOffset(R2, R5, Isolate::vm_tag_offset(), kNoPP); |
1995 // Clear top exit frame. | 1995 // Clear top exit frame. |
1996 __ StoreToOffset(ZR, R5, Isolate::top_exit_frame_info_offset(), kNoPP); | 1996 __ StoreToOffset(ZR, R5, Isolate::top_exit_frame_info_offset(), kNoPP); |
1997 __ ret(); // Jump to the exception handler code. | 1997 __ ret(); // Jump to the exception handler code. |
1998 } | 1998 } |
1999 | 1999 |
2000 | 2000 |
2001 // Calls to the runtime to optimize the given function. | 2001 // Calls to the runtime to optimize the given function. |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2186 // Result: | 2186 // Result: |
2187 // R1: entry point. | 2187 // R1: entry point. |
2188 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { | 2188 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { |
2189 EmitMegamorphicLookup(assembler, R0, R1, R1); | 2189 EmitMegamorphicLookup(assembler, R0, R1, R1); |
2190 __ ret(); | 2190 __ ret(); |
2191 } | 2191 } |
2192 | 2192 |
2193 } // namespace dart | 2193 } // namespace dart |
2194 | 2194 |
2195 #endif // defined TARGET_ARCH_ARM64 | 2195 #endif // defined TARGET_ARCH_ARM64 |
OLD | NEW |