blob: 4f3d3349b519bdc5a270eb390d6f91615f4452ad [file] [log] [blame]
Elliott Hughes0f3c5532012-03-30 14:51:51 -07001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Ian Rogers57b86d42012-03-27 16:05:41 -070017#include "asm_support.h"
18
19#if defined(__APPLE__)
Elliott Hughes787ec202012-03-29 17:14:15 -070020 // Mac OS' as(1) doesn't let you name macro parameters.
21 #define MACRO0(macro_name) .macro macro_name
22 #define MACRO1(macro_name, macro_arg1) .macro macro_name
23 #define MACRO2(macro_name, macro_arg1, macro_args2) .macro macro_name
24 #define END_MACRO .endmacro
25
26 // Mac OS' as(1) uses $0, $1, and so on for macro arguments, and function names
27 // are mangled with an extra underscore prefix. The use of $x for arguments
28 // mean that literals need to be represented with $$x in macros.
Elliott Hughes20a7a072012-04-04 12:54:00 -070029 #define SYMBOL(name) _ ## name
Elliott Hughesadc078a2012-04-04 11:39:05 -070030 #define VAR(name,index) SYMBOL($index)
Elliott Hughesea944212012-04-05 13:11:53 -070031 #define LITERAL(value) $value
32 #define MACRO_LITERAL(value) $$value
Elliott Hughes787ec202012-03-29 17:14:15 -070033#else
34 // Regular gas(1) lets you name macro parameters.
35 #define MACRO0(macro_name) .macro macro_name
36 #define MACRO1(macro_name, macro_arg1) .macro macro_name macro_arg1
37 #define MACRO2(macro_name, macro_arg1, macro_arg2) .macro macro_name macro_arg1, macro_arg2
38 #define END_MACRO .endm
39
40 // Regular gas(1) uses \argument_name for macro arguments.
41 // We need to turn on alternate macro syntax so we can use & instead or the preprocessor
42 // will screw us by inserting a space between the \ and the name. Even in this mode there's
43 // no special meaning to $, so literals are still just $x.
44 .altmacro
Elliott Hughesadc078a2012-04-04 11:39:05 -070045 #define SYMBOL(name) name
Elliott Hughes787ec202012-03-29 17:14:15 -070046 #define VAR(name,index) name&
47 #define LITERAL(value) $value
Elliott Hughesea944212012-04-05 13:11:53 -070048 #define MACRO_LITERAL(value) $value
Ian Rogers57b86d42012-03-27 16:05:41 -070049#endif
50
Ian Rogers57b86d42012-03-27 16:05:41 -070051 /* Cache alignment for function entry */
Elliott Hughes787ec202012-03-29 17:14:15 -070052MACRO0(ALIGN_FUNCTION_ENTRY)
Ian Rogers57b86d42012-03-27 16:05:41 -070053 .balign 16
Elliott Hughes787ec202012-03-29 17:14:15 -070054END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -070055
Elliott Hughes5e284222012-04-04 13:38:03 -070056MACRO1(DEFINE_FUNCTION,c_name)
57 .globl VAR(c_name, 0)
58 ALIGN_FUNCTION_ENTRY
59VAR(c_name, 0):
60END_MACRO
61
Ian Rogers57b86d42012-03-27 16:05:41 -070062 /*
63 * Macro that sets up the callee save frame to conform with
Ian Rogers7caad772012-03-30 01:07:54 -070064 * Runtime::CreateCalleeSaveMethod(kSaveAll)
Ian Rogers57b86d42012-03-27 16:05:41 -070065 */
Elliott Hughes787ec202012-03-29 17:14:15 -070066MACRO0(SETUP_SAVE_ALL_CALLEE_SAVE_FRAME)
Ian Rogers57b86d42012-03-27 16:05:41 -070067 pushl %edi // Save callee saves (ebx is saved/restored by the upcall)
68 pushl %esi
69 pushl %ebp
Elliott Hughesea944212012-04-05 13:11:53 -070070 subl MACRO_LITERAL(16), %esp // Grow stack by 4 words, bottom word will hold Method*
Elliott Hughes787ec202012-03-29 17:14:15 -070071END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -070072
Ian Rogers7caad772012-03-30 01:07:54 -070073 /*
74 * Macro that sets up the callee save frame to conform with
75 * Runtime::CreateCalleeSaveMethod(kRefsOnly)
76 */
77MACRO0(SETUP_REF_ONLY_CALLEE_SAVE_FRAME)
78 pushl %edi // Save callee saves (ebx is saved/restored by the upcall)
79 pushl %esi
80 pushl %ebp
Elliott Hughesea944212012-04-05 13:11:53 -070081 subl MACRO_LITERAL(16), %esp // Grow stack by 4 words, bottom word will hold Method*
Ian Rogers7caad772012-03-30 01:07:54 -070082END_MACRO
83
84MACRO0(RESTORE_REF_ONLY_CALLEE_SAVE_FRAME)
Elliott Hughesea944212012-04-05 13:11:53 -070085 addl MACRO_LITERAL(28), %esp // Unwind stack up to return address
Elliott Hughes787ec202012-03-29 17:14:15 -070086END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -070087
88 /*
89 * Macro that sets up the callee save frame to conform with
Ian Rogers7caad772012-03-30 01:07:54 -070090 * Runtime::CreateCalleeSaveMethod(kRefsAndArgs)
Ian Rogers57b86d42012-03-27 16:05:41 -070091 */
Elliott Hughes787ec202012-03-29 17:14:15 -070092MACRO0(SETUP_REF_AND_ARG_CALLEE_SAVE_FRAME)
Ian Rogers57b86d42012-03-27 16:05:41 -070093 pushl %edi // Save callee saves
94 pushl %esi
95 pushl %ebp
96 pushl %ebx // Save args
97 pushl %edx
98 pushl %ecx
99 pushl %eax // Align stack, eax will be clobbered by Method*
Elliott Hughes787ec202012-03-29 17:14:15 -0700100END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -0700101
Elliott Hughes787ec202012-03-29 17:14:15 -0700102MACRO0(RESTORE_REF_AND_ARG_CALLEE_SAVE_FRAME)
Elliott Hughesea944212012-04-05 13:11:53 -0700103 addl MACRO_LITERAL(4), %esp // Remove padding
Ian Rogers7caad772012-03-30 01:07:54 -0700104 popl %ecx // Restore args except eax
105 popl %edx
106 popl %ebx
Ian Rogers57b86d42012-03-27 16:05:41 -0700107 popl %ebp // Restore callee saves
108 popl %esi
109 popl %edi
Elliott Hughes787ec202012-03-29 17:14:15 -0700110END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -0700111
112 /*
113 * Macro that set calls through to artDeliverPendingExceptionFromCode, where the pending
114 * exception is Thread::Current()->exception_.
115 */
Elliott Hughes787ec202012-03-29 17:14:15 -0700116MACRO0(DELIVER_PENDING_EXCEPTION)
Ian Rogers57b86d42012-03-27 16:05:41 -0700117 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save callee saves for throw
118 mov %esp, %ecx
119 // Outgoing argument set up
Elliott Hughesea944212012-04-05 13:11:53 -0700120 subl MACRO_LITERAL(8), %esp // Alignment padding
Ian Rogers57b86d42012-03-27 16:05:41 -0700121 pushl %ecx // pass SP
122 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Elliott Hughesadc078a2012-04-04 11:39:05 -0700123 call SYMBOL(artDeliverPendingExceptionFromCode) // artDeliverExceptionFromCode(Thread*, SP)
Ian Rogers57b86d42012-03-27 16:05:41 -0700124 int3
Elliott Hughes787ec202012-03-29 17:14:15 -0700125END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -0700126
Elliott Hughes787ec202012-03-29 17:14:15 -0700127MACRO2(NO_ARG_RUNTIME_EXCEPTION, c_name, cxx_name)
128 .globl VAR(c_name, 0)
Ian Rogers57b86d42012-03-27 16:05:41 -0700129 ALIGN_FUNCTION_ENTRY
Elliott Hughes787ec202012-03-29 17:14:15 -0700130VAR(c_name, 0):
Ian Rogers57b86d42012-03-27 16:05:41 -0700131 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context
132 mov %esp, %ecx
133 // Outgoing argument set up
Elliott Hughesea944212012-04-05 13:11:53 -0700134 subl MACRO_LITERAL(8), %esp // alignment padding
Ian Rogers57b86d42012-03-27 16:05:41 -0700135 pushl %ecx // pass SP
Ian Rogers55bd45f2012-04-04 17:31:20 -0700136 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Elliott Hughes787ec202012-03-29 17:14:15 -0700137 call VAR(cxx_name, 1) // cxx_name(Thread*, SP)
Ian Rogers57b86d42012-03-27 16:05:41 -0700138 int3 // unreached
Elliott Hughes787ec202012-03-29 17:14:15 -0700139END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -0700140
Elliott Hughes787ec202012-03-29 17:14:15 -0700141MACRO2(ONE_ARG_RUNTIME_EXCEPTION, c_name, cxx_name)
142 .globl VAR(c_name, 0)
Ian Rogers57b86d42012-03-27 16:05:41 -0700143 ALIGN_FUNCTION_ENTRY
Elliott Hughes787ec202012-03-29 17:14:15 -0700144VAR(c_name, 0):
Ian Rogers57b86d42012-03-27 16:05:41 -0700145 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context
146 mov %esp, %ecx
147 // Outgoing argument set up
Ian Rogers55bd45f2012-04-04 17:31:20 -0700148 pushl %eax // alignment padding
Ian Rogers57b86d42012-03-27 16:05:41 -0700149 pushl %ecx // pass SP
150 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
151 pushl %eax // pass arg1
Elliott Hughes787ec202012-03-29 17:14:15 -0700152 call VAR(cxx_name, 1) // cxx_name(arg1, Thread*, SP)
Ian Rogers57b86d42012-03-27 16:05:41 -0700153 int3 // unreached
Elliott Hughes787ec202012-03-29 17:14:15 -0700154END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -0700155
Elliott Hughes787ec202012-03-29 17:14:15 -0700156MACRO2(TWO_ARG_RUNTIME_EXCEPTION, c_name, cxx_name)
157 .globl VAR(c_name, 0)
Ian Rogers57b86d42012-03-27 16:05:41 -0700158 ALIGN_FUNCTION_ENTRY
Elliott Hughes787ec202012-03-29 17:14:15 -0700159VAR(c_name, 0):
Ian Rogers57b86d42012-03-27 16:05:41 -0700160 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context
161 mov %esp, %edx
162 // Outgoing argument set up
163 pushl %edx // pass SP
164 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogers57b86d42012-03-27 16:05:41 -0700165 pushl %ecx // pass arg2
Ian Rogers7caad772012-03-30 01:07:54 -0700166 pushl %eax // pass arg1
167 call VAR(cxx_name, 1) // cxx_name(arg1, arg2, Thread*, SP)
Ian Rogers57b86d42012-03-27 16:05:41 -0700168 int3 // unreached
Elliott Hughes787ec202012-03-29 17:14:15 -0700169END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -0700170
171 /*
172 * Called by managed code to create and deliver a NullPointerException.
173 */
174NO_ARG_RUNTIME_EXCEPTION art_throw_null_pointer_exception_from_code, artThrowNullPointerExceptionFromCode
175
176 /*
177 * Called by managed code to create and deliver an ArithmeticException.
178 */
179NO_ARG_RUNTIME_EXCEPTION art_throw_div_zero_from_code, artThrowDivZeroFromCode
180
181 /*
Ian Rogers57b86d42012-03-27 16:05:41 -0700182 * Called by managed code to create and deliver a StackOverflowError.
183 */
184NO_ARG_RUNTIME_EXCEPTION art_throw_stack_overflow_from_code, artThrowStackOverflowFromCode
185
186 /*
Elliott Hughes787ec202012-03-29 17:14:15 -0700187 * Called by managed code, saves callee saves and then calls artThrowException
188 * that will place a mock Method* at the bottom of the stack. Arg1 holds the exception.
189 */
190ONE_ARG_RUNTIME_EXCEPTION art_deliver_exception_from_code, artDeliverExceptionFromCode
191
192 /*
Ian Rogers57b86d42012-03-27 16:05:41 -0700193 * Called by managed code to create and deliver a NoSuchMethodError.
194 */
195ONE_ARG_RUNTIME_EXCEPTION art_throw_no_such_method_from_code, artThrowNoSuchMethodFromCode
196
197 /*
Elliott Hughes787ec202012-03-29 17:14:15 -0700198 * Called by managed code to create and deliver an ArrayIndexOutOfBoundsException. Arg1 holds
199 * index, arg2 holds limit.
200 */
201TWO_ARG_RUNTIME_EXCEPTION art_throw_array_bounds_from_code, artThrowArrayBoundsFromCode
202
203 /*
Ian Rogers57b86d42012-03-27 16:05:41 -0700204 * Called by managed code to create and deliver verification errors. Arg1 is kind, arg2 is ref.
205 */
206TWO_ARG_RUNTIME_EXCEPTION art_throw_verification_error_from_code, artThrowVerificationErrorFromCode
207
208 /*
209 * All generated callsites for interface invokes and invocation slow paths will load arguments
210 * as usual - except instead of loading arg0/r0 with the target Method*, arg0/r0 will contain
211 * the method_idx. This wrapper will save arg1-arg3, load the caller's Method*, align the
212 * stack and call the appropriate C helper.
213 * NOTE: "this" is first visible argument of the target, and so can be found in arg1/r1.
214 *
215 * The helper will attempt to locate the target and return a 64-bit result in r0/r1 consisting
216 * of the target Method* in r0 and method->code_ in r1.
217 *
218 * If unsuccessful, the helper will return NULL/NULL. There will bea pending exception in the
219 * thread and we branch to another stub to deliver it.
220 *
221 * On success this wrapper will restore arguments and *jump* to the target, leaving the lr
222 * pointing back to the original caller.
223 */
Elliott Hughes787ec202012-03-29 17:14:15 -0700224MACRO2(INVOKE_TRAMPOLINE, c_name, cxx_name)
225 .globl VAR(c_name, 0)
Ian Rogers57b86d42012-03-27 16:05:41 -0700226 ALIGN_FUNCTION_ENTRY
Elliott Hughes787ec202012-03-29 17:14:15 -0700227VAR(c_name, 0):
Ian Rogers7caad772012-03-30 01:07:54 -0700228 // Set up the callee save frame to conform with Runtime::CreateCalleeSaveMethod(kRefsAndArgs)
229 // return address
230 pushl %edi
231 pushl %esi
232 pushl %ebp
233 pushl %ebx
234 pushl %edx
235 pushl %ecx
236 pushl %eax // <-- callee save Method* to go here
237 movl %esp, %edx // remember SP
238 // Outgoing argument set up
Elliott Hughesea944212012-04-05 13:11:53 -0700239 subl MACRO_LITERAL(12), %esp // alignment padding
Ian Rogers7caad772012-03-30 01:07:54 -0700240 pushl %edx // pass SP
241 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
242 pushl 32(%edx) // pass caller Method*
243 pushl %ecx // pass arg2
244 pushl %eax // pass arg1
245 call VAR(cxx_name, 1) // cxx_name(arg1, arg2, arg3, Thread*, SP)
246 movl %edx, %edi // save code pointer in EDI
Elliott Hughesea944212012-04-05 13:11:53 -0700247 addl MACRO_LITERAL(36), %esp // Pop arguments skip eax
Ian Rogers7caad772012-03-30 01:07:54 -0700248 popl %ecx // Restore args
249 popl %edx
250 popl %ebx
251 popl %ebp // Restore callee saves.
252 popl %esi
253 // Swap EDI callee save with code pointer.
254 xchgl %edi, (%esp)
255 testl %eax, %eax // Branch forward if exception pending.
256 jz 1f
257 // Tail call to intended method.
258 ret
2591:
260 DELIVER_PENDING_EXCEPTION
Elliott Hughes787ec202012-03-29 17:14:15 -0700261END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -0700262
263INVOKE_TRAMPOLINE art_invoke_interface_trampoline, artInvokeInterfaceTrampoline
264INVOKE_TRAMPOLINE art_invoke_interface_trampoline_with_access_check, artInvokeInterfaceTrampolineWithAccessCheck
265
266INVOKE_TRAMPOLINE art_invoke_static_trampoline_with_access_check, artInvokeStaticTrampolineWithAccessCheck
267INVOKE_TRAMPOLINE art_invoke_direct_trampoline_with_access_check, artInvokeDirectTrampolineWithAccessCheck
268INVOKE_TRAMPOLINE art_invoke_super_trampoline_with_access_check, artInvokeSuperTrampolineWithAccessCheck
269INVOKE_TRAMPOLINE art_invoke_virtual_trampoline_with_access_check, artInvokeVirtualTrampolineWithAccessCheck
270
Ian Rogers7caad772012-03-30 01:07:54 -0700271MACRO2(TWO_ARG_ALLOC, c_name, cxx_name)
272 .globl VAR(c_name, 0)
273 ALIGN_FUNCTION_ENTRY
274VAR(c_name, 0):
275 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
276 mov %esp, %edx // remember SP
277 // Outgoing argument set up
278 pushl %edx // pass SP
279 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
280 pushl %ecx // pass arg2
281 pushl %eax // pass arg1
282 call VAR(cxx_name, 1) // cxx_name(arg1, arg2, arg3, Thread*, SP)
Elliott Hughesea944212012-04-05 13:11:53 -0700283 addl MACRO_LITERAL(16), %esp // pop arguments
Ian Rogers7caad772012-03-30 01:07:54 -0700284 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
Elliott Hughesea944212012-04-05 13:11:53 -0700285 testl %eax, %eax // eax == 0 ?
Ian Rogers7caad772012-03-30 01:07:54 -0700286 jz 1f
287 ret
2881:
289 DELIVER_PENDING_EXCEPTION
290END_MACRO
291
292MACRO2(THREE_ARG_ALLOC, c_name, cxx_name)
293 .globl VAR(c_name, 0)
294 ALIGN_FUNCTION_ENTRY
295VAR(c_name, 0):
296 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
297 mov %esp, %ebx // remember SP
298 // Outgoing argument set up
Elliott Hughesea944212012-04-05 13:11:53 -0700299 subl MACRO_LITERAL(12), %esp // alignment padding
Ian Rogers7caad772012-03-30 01:07:54 -0700300 pushl %ebx // pass SP
301 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
302 pushl %edx // pass arg3
303 pushl %ecx // pass arg2
304 pushl %eax // pass arg1
305 call VAR(cxx_name, 1) // cxx_name(arg1, arg2, Thread*, SP)
Elliott Hughesea944212012-04-05 13:11:53 -0700306 addl MACRO_LITERAL(32), %esp // pop arguments
Ian Rogers7caad772012-03-30 01:07:54 -0700307 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
308 testl %eax, %eax // eax == 0 ?
309 jz 1f
310 ret
3111:
312 DELIVER_PENDING_EXCEPTION
313END_MACRO
314
315TWO_ARG_ALLOC art_alloc_object_from_code, artAllocObjectFromCode
316TWO_ARG_ALLOC art_alloc_object_from_code_with_access_check, artAllocObjectFromCodeWithAccessCheck
317THREE_ARG_ALLOC art_alloc_array_from_code, artAllocArrayFromCode
318THREE_ARG_ALLOC art_alloc_array_from_code_with_access_check, artAllocArrayFromCodeWithAccessCheck
319THREE_ARG_ALLOC art_check_and_alloc_array_from_code, artCheckAndAllocArrayFromCode
320THREE_ARG_ALLOC art_check_and_alloc_array_from_code_with_access_check, artCheckAndAllocArrayFromCodeWithAccessCheck
321
322TWO_ARG_ALLOC art_resolve_string_from_code, artResolveStringFromCode
323TWO_ARG_ALLOC art_initialize_static_storage_from_code, artInitializeStaticStorageFromCode
324
Elliott Hughes5e284222012-04-04 13:38:03 -0700325DEFINE_FUNCTION art_lock_object_from_code
Ian Rogers7caad772012-03-30 01:07:54 -0700326 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
327 mov %esp, %edx // remember SP
328 // Outgoing argument set up
329 pushl %eax // alignment padding
330 pushl %edx // pass SP
331 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
332 pushl %eax // pass arg1
Elliott Hughesadc078a2012-04-04 11:39:05 -0700333 call SYMBOL(artLockObjectFromCode) // (Object*, Thread*, SP)
Ian Rogers55bd45f2012-04-04 17:31:20 -0700334 addl LITERAL(16), %esp // pop arguments
Ian Rogers7caad772012-03-30 01:07:54 -0700335 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
336 ret
337
Elliott Hughes5e284222012-04-04 13:38:03 -0700338DEFINE_FUNCTION art_unlock_object_from_code
Ian Rogers7caad772012-03-30 01:07:54 -0700339 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
340 mov %esp, %edx // remember SP
341 // Outgoing argument set up
342 pushl %eax // alignment padding
343 pushl %edx // pass SP
344 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
345 pushl %eax // pass arg1
Elliott Hughesadc078a2012-04-04 11:39:05 -0700346 call SYMBOL(artUnlockObjectFromCode) // (Object*, Thread*, SP)
Ian Rogers55bd45f2012-04-04 17:31:20 -0700347 addl LITERAL(16), %esp // pop arguments
Ian Rogers7caad772012-03-30 01:07:54 -0700348 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
Elliott Hughes5e284222012-04-04 13:38:03 -0700349 testl %eax, %eax // eax == 0 ?
Ian Rogers7caad772012-03-30 01:07:54 -0700350 jnz 1f
351 ret
3521:
353 DELIVER_PENDING_EXCEPTION
354
Elliott Hughes5e284222012-04-04 13:38:03 -0700355DEFINE_FUNCTION art_handle_fill_data_from_code
Ian Rogers7caad772012-03-30 01:07:54 -0700356 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
357 mov %esp, %edx // remember SP
358 // Outgoing argument set up
359 pushl %edx // pass SP
360 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
361 pushl %ecx // pass arg2
362 pushl %eax // pass arg1
Elliott Hughesadc078a2012-04-04 11:39:05 -0700363 call SYMBOL(artHandleFillArrayDataFromCode) // (Array* array, const uint16_t* table, Thread*, SP)
Ian Rogers55bd45f2012-04-04 17:31:20 -0700364 addl LITERAL(16), %esp // pop arguments
Ian Rogers7caad772012-03-30 01:07:54 -0700365 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
Ian Rogers55bd45f2012-04-04 17:31:20 -0700366 testl %eax, %eax // eax == 0 ?
Ian Rogers7caad772012-03-30 01:07:54 -0700367 jnz 1f
368 ret
3691:
370 DELIVER_PENDING_EXCEPTION
371
Elliott Hughes5e284222012-04-04 13:38:03 -0700372DEFINE_FUNCTION art_is_assignable_from_code
Ian Rogers7caad772012-03-30 01:07:54 -0700373 pushl %eax // alignment padding
374 pushl %ecx // pass arg2
375 pushl %eax // pass arg1
Elliott Hughesadc078a2012-04-04 11:39:05 -0700376 call SYMBOL(artIsAssignableFromCode) // (Class* a, Class* b, Thread*, SP)
Ian Rogers55bd45f2012-04-04 17:31:20 -0700377 addl LITERAL(12), %esp // pop arguments
Ian Rogers7caad772012-03-30 01:07:54 -0700378 ret
379
Elliott Hughes5e284222012-04-04 13:38:03 -0700380DEFINE_FUNCTION art_memcpy
Ian Rogers7caad772012-03-30 01:07:54 -0700381 pushl %edx // pass arg3
382 pushl %ecx // pass arg2
383 pushl %eax // pass arg1
Elliott Hughesadc078a2012-04-04 11:39:05 -0700384 call SYMBOL(memcpy) // (void*, const void*, size_t)
Ian Rogers55bd45f2012-04-04 17:31:20 -0700385 addl LITERAL(12), %esp // pop arguments
Ian Rogers7caad772012-03-30 01:07:54 -0700386 ret
387
Elliott Hughes5e284222012-04-04 13:38:03 -0700388DEFINE_FUNCTION art_check_cast_from_code
Ian Rogers7caad772012-03-30 01:07:54 -0700389 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
390 mov %esp, %edx // remember SP
391 // Outgoing argument set up
392 pushl %edx // pass SP
393 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
394 pushl %ecx // pass arg2
395 pushl %eax // pass arg1
Elliott Hughes5e284222012-04-04 13:38:03 -0700396 call SYMBOL(artCheckCastFromCode) // (Class* a, Class* b, Thread*, SP)
Ian Rogers55bd45f2012-04-04 17:31:20 -0700397 addl LITERAL(16), %esp // pop arguments
Ian Rogers7caad772012-03-30 01:07:54 -0700398 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
Elliott Hughes5e284222012-04-04 13:38:03 -0700399 testl %eax, %eax // eax == 0 ?
Ian Rogers7caad772012-03-30 01:07:54 -0700400 jnz 1f
401 ret
4021:
403 DELIVER_PENDING_EXCEPTION
404
Elliott Hughes5e284222012-04-04 13:38:03 -0700405DEFINE_FUNCTION art_idiv_from_code
Ian Rogers7caad772012-03-30 01:07:54 -0700406 cdq // edx:eax = sign extend eax
407 idiv %ecx // (edx,eax) = (edx:eax % ecx, edx:eax / ecx)
408 ret
409
Elliott Hughes5e284222012-04-04 13:38:03 -0700410DEFINE_FUNCTION art_idivmod_from_code
Ian Rogers7caad772012-03-30 01:07:54 -0700411 cdq // edx:eax = sign extend eax
412 idiv %ecx // (edx,eax) = (edx:eax % ecx, edx:eax / ecx)
413 movl %eax, %edx
414 ret
415
Ian Rogers55bd45f2012-04-04 17:31:20 -0700416DEFINE_FUNCTION art_ldiv_from_code
Ian Rogers141d6222012-04-05 12:23:06 -0700417 subl LITERAL(12), %esp // alignment padding
Ian Rogers55bd45f2012-04-04 17:31:20 -0700418 pushl %ebx // pass arg4
419 pushl %edx // pass arg3
420 pushl %ecx // pass arg2
421 pushl %eax // pass arg1
422 call SYMBOL(artLdivFromCode) // (jlong a, jlong b, Thread*, SP)
423 addl LITERAL(28), %esp // pop arguments
424 ret
425
426DEFINE_FUNCTION art_ldivmod_from_code
Ian Rogers141d6222012-04-05 12:23:06 -0700427 subl LITERAL(12), %esp // alignment padding
Ian Rogers55bd45f2012-04-04 17:31:20 -0700428 pushl %ebx // pass arg4
429 pushl %edx // pass arg3
430 pushl %ecx // pass arg2
431 pushl %eax // pass arg1
432 call SYMBOL(artLdivmodFromCode) // (jlong a, jlong b, Thread*, SP)
433 addl LITERAL(28), %esp // pop arguments
434 ret
435
Ian Rogers141d6222012-04-05 12:23:06 -0700436DEFINE_FUNCTION art_lshl_from_code
437 // eax:ecx << edx
438 xchg %edx, %ecx
439 shld %cl,%eax,%edx
440 shl %cl,%eax
441 test LITERAL(32), %cl
442 jz 1f
443 mov %eax, %edx
444 xor %eax, %eax
4451:
446 ret
447
448DEFINE_FUNCTION art_lshr_from_code
449 // eax:ecx >> edx
450 xchg %edx, %ecx
451 shrd %cl,%eax,%edx
452 sar %cl,%eax
453 test LITERAL(32),%cl
454 jz 1f
455 mov %edx, %eax
456 sar LITERAL(31), %edx
4571:
458 ret
459
460DEFINE_FUNCTION art_lushr_from_code
461 // eax:ecx >>> edx
462 xchg %edx, %ecx
463 shrd %cl,%eax,%edx
464 shr %cl,%eax
465 test $0x20,%cl
466 jz 1f
467 mov %edx, %eax
468 xor %edx, %edx
4691:
470 ret
471
Elliott Hughes5e284222012-04-04 13:38:03 -0700472DEFINE_FUNCTION art_can_put_array_element_from_code
Ian Rogers7caad772012-03-30 01:07:54 -0700473 test %eax, %eax // Null is trivially storable
474 jz 1f
475 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
476 mov %esp, %edx // remember SP
477 // Outgoing argument set up
478 pushl %edx // pass SP
479 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
480 pushl %ecx // pass arg2
481 pushl %eax // pass arg1
Elliott Hughesadc078a2012-04-04 11:39:05 -0700482 call SYMBOL(artCanPutArrayElementFromCode) // (Object* element, Class* array_class, Thread*, SP)
Ian Rogers55bd45f2012-04-04 17:31:20 -0700483 addl LITERAL(16), %esp // pop arguments
Ian Rogers7caad772012-03-30 01:07:54 -0700484 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
Elliott Hughes5e284222012-04-04 13:38:03 -0700485 testl %eax, %eax // eax == 0 ?
Ian Rogers7caad772012-03-30 01:07:54 -0700486 jnz 2f
4871:
488 ret
4892:
490 DELIVER_PENDING_EXCEPTION
491
Elliott Hughes787ec202012-03-29 17:14:15 -0700492MACRO1(UNIMPLEMENTED,name)
493 .globl VAR(name, 0)
494 ALIGN_FUNCTION_ENTRY
495VAR(name, 0):
Ian Rogers57b86d42012-03-27 16:05:41 -0700496 int3
Elliott Hughes787ec202012-03-29 17:14:15 -0700497END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -0700498
Elliott Hughes787ec202012-03-29 17:14:15 -0700499 // TODO: implement these!
500UNIMPLEMENTED art_proxy_invoke_handler
501UNIMPLEMENTED art_update_debugger
502UNIMPLEMENTED art_test_suspend
Elliott Hughes787ec202012-03-29 17:14:15 -0700503UNIMPLEMENTED art_initialize_type_and_verify_access_from_code
504UNIMPLEMENTED art_initialize_type_from_code
Elliott Hughes787ec202012-03-29 17:14:15 -0700505UNIMPLEMENTED art_set32_instance_from_code
506UNIMPLEMENTED art_set64_instance_from_code
507UNIMPLEMENTED art_set_obj_instance_from_code
508UNIMPLEMENTED art_get32_instance_from_code
509UNIMPLEMENTED art_get64_instance_from_code
510UNIMPLEMENTED art_get_obj_instance_from_code
511UNIMPLEMENTED art_set32_static_from_code
512UNIMPLEMENTED art_set64_static_from_code
513UNIMPLEMENTED art_set_obj_static_from_code
514UNIMPLEMENTED art_get32_static_from_code
515UNIMPLEMENTED art_get64_static_from_code
516UNIMPLEMENTED art_get_obj_static_from_code
Elliott Hughes787ec202012-03-29 17:14:15 -0700517UNIMPLEMENTED art_indexof
Ian Rogers7caad772012-03-30 01:07:54 -0700518UNIMPLEMENTED art_memcmp16
Elliott Hughes787ec202012-03-29 17:14:15 -0700519UNIMPLEMENTED art_string_compareto