blob: 44a8fb6c47f9238db6b8154a1d57f6742ee20299 [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
Ian Rogersd36c52e2012-04-09 16:29:25 -070024 #define MACRO3(macro_name, macro_arg1, macro_args2, macro_args3) .macro macro_name
Elliott Hughes787ec202012-03-29 17:14:15 -070025 #define END_MACRO .endmacro
26
27 // Mac OS' as(1) uses $0, $1, and so on for macro arguments, and function names
28 // are mangled with an extra underscore prefix. The use of $x for arguments
29 // mean that literals need to be represented with $$x in macros.
Elliott Hughes20a7a072012-04-04 12:54:00 -070030 #define SYMBOL(name) _ ## name
Elliott Hughesadc078a2012-04-04 11:39:05 -070031 #define VAR(name,index) SYMBOL($index)
Elliott Hughes754caaa2012-04-10 10:57:36 -070032 #define CALL_MACRO(name,index) $index
Elliott Hughesea944212012-04-05 13:11:53 -070033 #define LITERAL(value) $value
34 #define MACRO_LITERAL(value) $$value
Elliott Hughes787ec202012-03-29 17:14:15 -070035#else
36 // Regular gas(1) lets you name macro parameters.
37 #define MACRO0(macro_name) .macro macro_name
38 #define MACRO1(macro_name, macro_arg1) .macro macro_name macro_arg1
39 #define MACRO2(macro_name, macro_arg1, macro_arg2) .macro macro_name macro_arg1, macro_arg2
Ian Rogersd36c52e2012-04-09 16:29:25 -070040 #define MACRO3(macro_name, macro_arg1, macro_arg2, macro_arg3) .macro macro_name macro_arg1, macro_arg2, macro_arg3
Elliott Hughes787ec202012-03-29 17:14:15 -070041 #define END_MACRO .endm
42
43 // Regular gas(1) uses \argument_name for macro arguments.
44 // We need to turn on alternate macro syntax so we can use & instead or the preprocessor
45 // will screw us by inserting a space between the \ and the name. Even in this mode there's
46 // no special meaning to $, so literals are still just $x.
47 .altmacro
Elliott Hughesadc078a2012-04-04 11:39:05 -070048 #define SYMBOL(name) name
Elliott Hughes787ec202012-03-29 17:14:15 -070049 #define VAR(name,index) name&
Elliott Hughes754caaa2012-04-10 10:57:36 -070050 #define CALL_MACRO(name,index) name&
Elliott Hughes787ec202012-03-29 17:14:15 -070051 #define LITERAL(value) $value
Elliott Hughesea944212012-04-05 13:11:53 -070052 #define MACRO_LITERAL(value) $value
Ian Rogers57b86d42012-03-27 16:05:41 -070053#endif
54
Ian Rogers57b86d42012-03-27 16:05:41 -070055 /* Cache alignment for function entry */
Elliott Hughes787ec202012-03-29 17:14:15 -070056MACRO0(ALIGN_FUNCTION_ENTRY)
Ian Rogers57b86d42012-03-27 16:05:41 -070057 .balign 16
Elliott Hughes787ec202012-03-29 17:14:15 -070058END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -070059
Elliott Hughes5e284222012-04-04 13:38:03 -070060MACRO1(DEFINE_FUNCTION,c_name)
61 .globl VAR(c_name, 0)
62 ALIGN_FUNCTION_ENTRY
63VAR(c_name, 0):
64END_MACRO
65
Ian Rogers57b86d42012-03-27 16:05:41 -070066 /*
67 * Macro that sets up the callee save frame to conform with
Ian Rogers7caad772012-03-30 01:07:54 -070068 * Runtime::CreateCalleeSaveMethod(kSaveAll)
Ian Rogers57b86d42012-03-27 16:05:41 -070069 */
Elliott Hughes787ec202012-03-29 17:14:15 -070070MACRO0(SETUP_SAVE_ALL_CALLEE_SAVE_FRAME)
Ian Rogers57b86d42012-03-27 16:05:41 -070071 pushl %edi // Save callee saves (ebx is saved/restored by the upcall)
72 pushl %esi
73 pushl %ebp
Elliott Hughesea944212012-04-05 13:11:53 -070074 subl MACRO_LITERAL(16), %esp // Grow stack by 4 words, bottom word will hold Method*
Elliott Hughes787ec202012-03-29 17:14:15 -070075END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -070076
Ian Rogers7caad772012-03-30 01:07:54 -070077 /*
78 * Macro that sets up the callee save frame to conform with
79 * Runtime::CreateCalleeSaveMethod(kRefsOnly)
80 */
81MACRO0(SETUP_REF_ONLY_CALLEE_SAVE_FRAME)
82 pushl %edi // Save callee saves (ebx is saved/restored by the upcall)
83 pushl %esi
84 pushl %ebp
Elliott Hughesea944212012-04-05 13:11:53 -070085 subl MACRO_LITERAL(16), %esp // Grow stack by 4 words, bottom word will hold Method*
Ian Rogers7caad772012-03-30 01:07:54 -070086END_MACRO
87
88MACRO0(RESTORE_REF_ONLY_CALLEE_SAVE_FRAME)
Elliott Hughesea944212012-04-05 13:11:53 -070089 addl MACRO_LITERAL(28), %esp // Unwind stack up to return address
Elliott Hughes787ec202012-03-29 17:14:15 -070090END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -070091
92 /*
93 * Macro that sets up the callee save frame to conform with
Ian Rogers7caad772012-03-30 01:07:54 -070094 * Runtime::CreateCalleeSaveMethod(kRefsAndArgs)
Ian Rogers57b86d42012-03-27 16:05:41 -070095 */
jeffhao9dbb23e2012-05-18 17:03:57 -070096MACRO0(SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME)
Ian Rogers57b86d42012-03-27 16:05:41 -070097 pushl %edi // Save callee saves
98 pushl %esi
99 pushl %ebp
100 pushl %ebx // Save args
101 pushl %edx
102 pushl %ecx
103 pushl %eax // Align stack, eax will be clobbered by Method*
Elliott Hughes787ec202012-03-29 17:14:15 -0700104END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -0700105
jeffhao9dbb23e2012-05-18 17:03:57 -0700106MACRO0(RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME)
Elliott Hughesea944212012-04-05 13:11:53 -0700107 addl MACRO_LITERAL(4), %esp // Remove padding
Ian Rogers7caad772012-03-30 01:07:54 -0700108 popl %ecx // Restore args except eax
109 popl %edx
110 popl %ebx
Ian Rogers57b86d42012-03-27 16:05:41 -0700111 popl %ebp // Restore callee saves
112 popl %esi
113 popl %edi
Elliott Hughes787ec202012-03-29 17:14:15 -0700114END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -0700115
116 /*
117 * Macro that set calls through to artDeliverPendingExceptionFromCode, where the pending
118 * exception is Thread::Current()->exception_.
119 */
Elliott Hughes787ec202012-03-29 17:14:15 -0700120MACRO0(DELIVER_PENDING_EXCEPTION)
Ian Rogers57b86d42012-03-27 16:05:41 -0700121 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save callee saves for throw
122 mov %esp, %ecx
123 // Outgoing argument set up
Elliott Hughesea944212012-04-05 13:11:53 -0700124 subl MACRO_LITERAL(8), %esp // Alignment padding
Ian Rogers57b86d42012-03-27 16:05:41 -0700125 pushl %ecx // pass SP
126 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
jeffhao9dbb23e2012-05-18 17:03:57 -0700127 call SYMBOL(artDeliverPendingExceptionFromCode) // artDeliverPendingExceptionFromCode(Thread*, SP)
128 int3 // unreached
Elliott Hughes787ec202012-03-29 17:14:15 -0700129END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -0700130
Elliott Hughes787ec202012-03-29 17:14:15 -0700131MACRO2(NO_ARG_RUNTIME_EXCEPTION, c_name, cxx_name)
132 .globl VAR(c_name, 0)
Ian Rogers57b86d42012-03-27 16:05:41 -0700133 ALIGN_FUNCTION_ENTRY
Elliott Hughes787ec202012-03-29 17:14:15 -0700134VAR(c_name, 0):
Ian Rogers57b86d42012-03-27 16:05:41 -0700135 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context
136 mov %esp, %ecx
137 // Outgoing argument set up
Elliott Hughesea944212012-04-05 13:11:53 -0700138 subl MACRO_LITERAL(8), %esp // alignment padding
Ian Rogers57b86d42012-03-27 16:05:41 -0700139 pushl %ecx // pass SP
Ian Rogers55bd45f2012-04-04 17:31:20 -0700140 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Elliott Hughes787ec202012-03-29 17:14:15 -0700141 call VAR(cxx_name, 1) // cxx_name(Thread*, SP)
Ian Rogers57b86d42012-03-27 16:05:41 -0700142 int3 // unreached
Elliott Hughes787ec202012-03-29 17:14:15 -0700143END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -0700144
Elliott Hughes787ec202012-03-29 17:14:15 -0700145MACRO2(ONE_ARG_RUNTIME_EXCEPTION, c_name, cxx_name)
146 .globl VAR(c_name, 0)
Ian Rogers57b86d42012-03-27 16:05:41 -0700147 ALIGN_FUNCTION_ENTRY
Elliott Hughes787ec202012-03-29 17:14:15 -0700148VAR(c_name, 0):
Ian Rogers57b86d42012-03-27 16:05:41 -0700149 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context
150 mov %esp, %ecx
151 // Outgoing argument set up
Ian Rogers55bd45f2012-04-04 17:31:20 -0700152 pushl %eax // alignment padding
Ian Rogers57b86d42012-03-27 16:05:41 -0700153 pushl %ecx // pass SP
154 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
155 pushl %eax // pass arg1
Elliott Hughes787ec202012-03-29 17:14:15 -0700156 call VAR(cxx_name, 1) // cxx_name(arg1, Thread*, SP)
Ian Rogers57b86d42012-03-27 16:05:41 -0700157 int3 // unreached
Elliott Hughes787ec202012-03-29 17:14:15 -0700158END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -0700159
Elliott Hughes787ec202012-03-29 17:14:15 -0700160MACRO2(TWO_ARG_RUNTIME_EXCEPTION, c_name, cxx_name)
161 .globl VAR(c_name, 0)
Ian Rogers57b86d42012-03-27 16:05:41 -0700162 ALIGN_FUNCTION_ENTRY
Elliott Hughes787ec202012-03-29 17:14:15 -0700163VAR(c_name, 0):
Ian Rogers57b86d42012-03-27 16:05:41 -0700164 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context
165 mov %esp, %edx
166 // Outgoing argument set up
167 pushl %edx // pass SP
168 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogers57b86d42012-03-27 16:05:41 -0700169 pushl %ecx // pass arg2
Ian Rogers7caad772012-03-30 01:07:54 -0700170 pushl %eax // pass arg1
171 call VAR(cxx_name, 1) // cxx_name(arg1, arg2, Thread*, SP)
Ian Rogers57b86d42012-03-27 16:05:41 -0700172 int3 // unreached
Elliott Hughes787ec202012-03-29 17:14:15 -0700173END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -0700174
175 /*
176 * Called by managed code to create and deliver a NullPointerException.
177 */
Logan Chien8dbb7082013-01-25 20:31:17 +0800178NO_ARG_RUNTIME_EXCEPTION art_quick_throw_null_pointer_exception_from_code, artThrowNullPointerExceptionFromCode
Ian Rogers57b86d42012-03-27 16:05:41 -0700179
180 /*
181 * Called by managed code to create and deliver an ArithmeticException.
182 */
Logan Chien8dbb7082013-01-25 20:31:17 +0800183NO_ARG_RUNTIME_EXCEPTION art_quick_throw_div_zero_from_code, artThrowDivZeroFromCode
Ian Rogers57b86d42012-03-27 16:05:41 -0700184
185 /*
Ian Rogers57b86d42012-03-27 16:05:41 -0700186 * Called by managed code to create and deliver a StackOverflowError.
187 */
Logan Chien8dbb7082013-01-25 20:31:17 +0800188NO_ARG_RUNTIME_EXCEPTION art_quick_throw_stack_overflow_from_code, artThrowStackOverflowFromCode
Ian Rogers57b86d42012-03-27 16:05:41 -0700189
190 /*
Elliott Hughes787ec202012-03-29 17:14:15 -0700191 * Called by managed code, saves callee saves and then calls artThrowException
192 * that will place a mock Method* at the bottom of the stack. Arg1 holds the exception.
193 */
Logan Chien8dbb7082013-01-25 20:31:17 +0800194ONE_ARG_RUNTIME_EXCEPTION art_quick_deliver_exception_from_code, artDeliverExceptionFromCode
Elliott Hughes787ec202012-03-29 17:14:15 -0700195
196 /*
Ian Rogers57b86d42012-03-27 16:05:41 -0700197 * Called by managed code to create and deliver a NoSuchMethodError.
198 */
Logan Chien8dbb7082013-01-25 20:31:17 +0800199ONE_ARG_RUNTIME_EXCEPTION art_quick_throw_no_such_method_from_code, artThrowNoSuchMethodFromCode
Ian Rogers57b86d42012-03-27 16:05:41 -0700200
201 /*
Elliott Hughes787ec202012-03-29 17:14:15 -0700202 * Called by managed code to create and deliver an ArrayIndexOutOfBoundsException. Arg1 holds
203 * index, arg2 holds limit.
204 */
Logan Chien8dbb7082013-01-25 20:31:17 +0800205TWO_ARG_RUNTIME_EXCEPTION art_quick_throw_array_bounds_from_code, artThrowArrayBoundsFromCode
Elliott Hughes787ec202012-03-29 17:14:15 -0700206
207 /*
Ian Rogers57b86d42012-03-27 16:05:41 -0700208 * All generated callsites for interface invokes and invocation slow paths will load arguments
209 * as usual - except instead of loading arg0/r0 with the target Method*, arg0/r0 will contain
210 * the method_idx. This wrapper will save arg1-arg3, load the caller's Method*, align the
211 * stack and call the appropriate C helper.
212 * NOTE: "this" is first visible argument of the target, and so can be found in arg1/r1.
213 *
214 * The helper will attempt to locate the target and return a 64-bit result in r0/r1 consisting
215 * of the target Method* in r0 and method->code_ in r1.
216 *
217 * If unsuccessful, the helper will return NULL/NULL. There will bea pending exception in the
218 * thread and we branch to another stub to deliver it.
219 *
220 * On success this wrapper will restore arguments and *jump* to the target, leaving the lr
221 * pointing back to the original caller.
222 */
Elliott Hughes787ec202012-03-29 17:14:15 -0700223MACRO2(INVOKE_TRAMPOLINE, c_name, cxx_name)
224 .globl VAR(c_name, 0)
Ian Rogers57b86d42012-03-27 16:05:41 -0700225 ALIGN_FUNCTION_ENTRY
Elliott Hughes787ec202012-03-29 17:14:15 -0700226VAR(c_name, 0):
Ian Rogers7caad772012-03-30 01:07:54 -0700227 // Set up the callee save frame to conform with Runtime::CreateCalleeSaveMethod(kRefsAndArgs)
228 // return address
229 pushl %edi
230 pushl %esi
231 pushl %ebp
232 pushl %ebx
233 pushl %edx
234 pushl %ecx
235 pushl %eax // <-- callee save Method* to go here
236 movl %esp, %edx // remember SP
237 // Outgoing argument set up
Elliott Hughesea944212012-04-05 13:11:53 -0700238 subl MACRO_LITERAL(12), %esp // alignment padding
Ian Rogers7caad772012-03-30 01:07:54 -0700239 pushl %edx // pass SP
240 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
241 pushl 32(%edx) // pass caller Method*
242 pushl %ecx // pass arg2
243 pushl %eax // pass arg1
244 call VAR(cxx_name, 1) // cxx_name(arg1, arg2, arg3, Thread*, SP)
245 movl %edx, %edi // save code pointer in EDI
Elliott Hughesea944212012-04-05 13:11:53 -0700246 addl MACRO_LITERAL(36), %esp // Pop arguments skip eax
Ian Rogers7caad772012-03-30 01:07:54 -0700247 popl %ecx // Restore args
248 popl %edx
249 popl %ebx
250 popl %ebp // Restore callee saves.
251 popl %esi
252 // Swap EDI callee save with code pointer.
253 xchgl %edi, (%esp)
254 testl %eax, %eax // Branch forward if exception pending.
255 jz 1f
256 // Tail call to intended method.
257 ret
2581:
jeffhao20b5c6c2012-05-21 14:15:18 -0700259 addl MACRO_LITERAL(4), %esp // Pop code pointer off stack
Ian Rogers7caad772012-03-30 01:07:54 -0700260 DELIVER_PENDING_EXCEPTION
Elliott Hughes787ec202012-03-29 17:14:15 -0700261END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -0700262
Logan Chien8dbb7082013-01-25 20:31:17 +0800263INVOKE_TRAMPOLINE art_quick_invoke_interface_trampoline, artInvokeInterfaceTrampoline
264INVOKE_TRAMPOLINE art_quick_invoke_interface_trampoline_with_access_check, artInvokeInterfaceTrampolineWithAccessCheck
Ian Rogers57b86d42012-03-27 16:05:41 -0700265
Logan Chien8dbb7082013-01-25 20:31:17 +0800266INVOKE_TRAMPOLINE art_quick_invoke_static_trampoline_with_access_check, artInvokeStaticTrampolineWithAccessCheck
267INVOKE_TRAMPOLINE art_quick_invoke_direct_trampoline_with_access_check, artInvokeDirectTrampolineWithAccessCheck
268INVOKE_TRAMPOLINE art_quick_invoke_super_trampoline_with_access_check, artInvokeSuperTrampolineWithAccessCheck
269INVOKE_TRAMPOLINE art_quick_invoke_virtual_trampoline_with_access_check, artInvokeVirtualTrampolineWithAccessCheck
Ian Rogers57b86d42012-03-27 16:05:41 -0700270
Ian Rogersd36c52e2012-04-09 16:29:25 -0700271MACRO3(NO_ARG_DOWNCALL, c_name, cxx_name, return_macro)
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 subl MACRO_LITERAL(8), %esp // push padding
279 pushl %edx // pass SP
280 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
281 call VAR(cxx_name, 1) // cxx_name(Thread*, SP)
282 addl MACRO_LITERAL(16), %esp // pop arguments
283 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
Elliott Hughes754caaa2012-04-10 10:57:36 -0700284 CALL_MACRO(return_macro, 2) // return or deliver exception
Ian Rogersd36c52e2012-04-09 16:29:25 -0700285END_MACRO
286
287MACRO3(ONE_ARG_DOWNCALL, c_name, cxx_name, return_macro)
288 .globl VAR(c_name, 0)
289 ALIGN_FUNCTION_ENTRY
290VAR(c_name, 0):
291 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
292 mov %esp, %edx // remember SP
293 // Outgoing argument set up
294 pushl %eax // push padding
295 pushl %edx // pass SP
296 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
297 pushl %eax // pass arg1
298 call VAR(cxx_name, 1) // cxx_name(arg1, Thread*, SP)
299 addl MACRO_LITERAL(16), %esp // pop arguments
300 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
Elliott Hughes754caaa2012-04-10 10:57:36 -0700301 CALL_MACRO(return_macro, 2) // return or deliver exception
Ian Rogersd36c52e2012-04-09 16:29:25 -0700302END_MACRO
303
304MACRO3(TWO_ARG_DOWNCALL, c_name, cxx_name, return_macro)
Ian Rogers7caad772012-03-30 01:07:54 -0700305 .globl VAR(c_name, 0)
306 ALIGN_FUNCTION_ENTRY
307VAR(c_name, 0):
308 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
309 mov %esp, %edx // remember SP
310 // Outgoing argument set up
311 pushl %edx // pass SP
312 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
313 pushl %ecx // pass arg2
314 pushl %eax // pass arg1
Ian Rogersd36c52e2012-04-09 16:29:25 -0700315 call VAR(cxx_name, 1) // cxx_name(arg1, arg2, Thread*, SP)
Elliott Hughesea944212012-04-05 13:11:53 -0700316 addl MACRO_LITERAL(16), %esp // pop arguments
Ian Rogers7caad772012-03-30 01:07:54 -0700317 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
Elliott Hughes754caaa2012-04-10 10:57:36 -0700318 CALL_MACRO(return_macro, 2) // return or deliver exception
Ian Rogers7caad772012-03-30 01:07:54 -0700319END_MACRO
320
Ian Rogersd36c52e2012-04-09 16:29:25 -0700321MACRO3(THREE_ARG_DOWNCALL, c_name, cxx_name, return_macro)
Ian Rogers7caad772012-03-30 01:07:54 -0700322 .globl VAR(c_name, 0)
323 ALIGN_FUNCTION_ENTRY
324VAR(c_name, 0):
325 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
326 mov %esp, %ebx // remember SP
327 // Outgoing argument set up
Elliott Hughesea944212012-04-05 13:11:53 -0700328 subl MACRO_LITERAL(12), %esp // alignment padding
Ian Rogers7caad772012-03-30 01:07:54 -0700329 pushl %ebx // pass SP
330 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
331 pushl %edx // pass arg3
332 pushl %ecx // pass arg2
333 pushl %eax // pass arg1
Ian Rogersd36c52e2012-04-09 16:29:25 -0700334 call VAR(cxx_name, 1) // cxx_name(arg1, arg2, arg3, Thread*, SP)
Elliott Hughesea944212012-04-05 13:11:53 -0700335 addl MACRO_LITERAL(32), %esp // pop arguments
Ian Rogers7caad772012-03-30 01:07:54 -0700336 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
Elliott Hughes754caaa2012-04-10 10:57:36 -0700337 CALL_MACRO(return_macro, 2) // return or deliver exception
Ian Rogersd36c52e2012-04-09 16:29:25 -0700338END_MACRO
339
340MACRO0(RETURN_IF_EAX_NOT_ZERO)
Ian Rogers7caad772012-03-30 01:07:54 -0700341 testl %eax, %eax // eax == 0 ?
Ian Rogersd36c52e2012-04-09 16:29:25 -0700342 jz 1f // if eax == 0 goto 1
343 ret // return
3441: // deliver exception on current thread
Ian Rogers7caad772012-03-30 01:07:54 -0700345 DELIVER_PENDING_EXCEPTION
346END_MACRO
347
Ian Rogersd36c52e2012-04-09 16:29:25 -0700348MACRO0(RETURN_IF_EAX_ZERO)
349 testl %eax, %eax // eax == 0 ?
350 jnz 1f // if eax != 0 goto 1
351 ret // return
3521: // deliver exception on current thread
Ian Rogers7caad772012-03-30 01:07:54 -0700353 DELIVER_PENDING_EXCEPTION
Ian Rogersd36c52e2012-04-09 16:29:25 -0700354END_MACRO
Ian Rogers7caad772012-03-30 01:07:54 -0700355
jeffhaod66a8752012-05-22 15:30:16 -0700356MACRO0(RETURN_OR_DELIVER_PENDING_EXCEPTION)
357 mov %fs:THREAD_EXCEPTION_OFFSET, %ebx // get exception field
358 testl %ebx, %ebx // ebx == 0 ?
359 jnz 1f // if ebx != 0 goto 1
360 ret // return
3611: // deliver exception on current thread
362 DELIVER_PENDING_EXCEPTION
363END_MACRO
364
Logan Chien8dbb7082013-01-25 20:31:17 +0800365TWO_ARG_DOWNCALL art_quick_alloc_object_from_code, artAllocObjectFromCode, RETURN_IF_EAX_NOT_ZERO
366TWO_ARG_DOWNCALL art_quick_alloc_object_from_code_with_access_check, artAllocObjectFromCodeWithAccessCheck, RETURN_IF_EAX_NOT_ZERO
367THREE_ARG_DOWNCALL art_quick_alloc_array_from_code, artAllocArrayFromCode, RETURN_IF_EAX_NOT_ZERO
368THREE_ARG_DOWNCALL art_quick_alloc_array_from_code_with_access_check, artAllocArrayFromCodeWithAccessCheck, RETURN_IF_EAX_NOT_ZERO
369THREE_ARG_DOWNCALL art_quick_check_and_alloc_array_from_code, artCheckAndAllocArrayFromCode, RETURN_IF_EAX_NOT_ZERO
370THREE_ARG_DOWNCALL art_quick_check_and_alloc_array_from_code_with_access_check, artCheckAndAllocArrayFromCodeWithAccessCheck, RETURN_IF_EAX_NOT_ZERO
Ian Rogersd36c52e2012-04-09 16:29:25 -0700371
Logan Chien8dbb7082013-01-25 20:31:17 +0800372TWO_ARG_DOWNCALL art_quick_resolve_string_from_code, artResolveStringFromCode, RETURN_IF_EAX_NOT_ZERO
373TWO_ARG_DOWNCALL art_quick_initialize_static_storage_from_code, artInitializeStaticStorageFromCode, RETURN_IF_EAX_NOT_ZERO
374TWO_ARG_DOWNCALL art_quick_initialize_type_from_code, artInitializeTypeFromCode, RETURN_IF_EAX_NOT_ZERO
375TWO_ARG_DOWNCALL art_quick_initialize_type_and_verify_access_from_code, artInitializeTypeAndVerifyAccessFromCode, RETURN_IF_EAX_NOT_ZERO
Ian Rogersd36c52e2012-04-09 16:29:25 -0700376
jeffhao7e4fcb82013-01-10 18:11:08 -0800377 /*
378 * On entry, eax and ecx must be preserved, edx is dex PC
379 */
Logan Chien8dbb7082013-01-25 20:31:17 +0800380DEFINE_FUNCTION art_quick_update_debugger
jeffhao7e4fcb82013-01-10 18:11:08 -0800381 mov %eax, %ebx // stash away eax so that it's saved as if it were an argument
jeffhao162fd332013-01-08 16:21:01 -0800382 SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME
jeffhao7e4fcb82013-01-10 18:11:08 -0800383 subl LITERAL(4), %esp // alignment padding
jeffhao162fd332013-01-08 16:21:01 -0800384 pushl %esp // pass arg2 (sp)
385 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
386 pushl %edx // pass arg0 (dex pc)
387 call SYMBOL(artUpdateDebuggerFromCode) // artUpdateDebuggerFromCode(int32_t, Thread*, Method**)
jeffhao7e4fcb82013-01-10 18:11:08 -0800388 addl LITERAL(16), %esp // pop arguments
jeffhao162fd332013-01-08 16:21:01 -0800389 RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME
jeffhao7e4fcb82013-01-10 18:11:08 -0800390 mov %ebx, %eax // restore original eax
jeffhao162fd332013-01-08 16:21:01 -0800391 ret
392
Logan Chien8dbb7082013-01-25 20:31:17 +0800393ONE_ARG_DOWNCALL art_quick_lock_object_from_code, artLockObjectFromCode, ret
394ONE_ARG_DOWNCALL art_quick_unlock_object_from_code, artUnlockObjectFromCode, RETURN_IF_EAX_ZERO
Ian Rogersd36c52e2012-04-09 16:29:25 -0700395
Logan Chien8dbb7082013-01-25 20:31:17 +0800396TWO_ARG_DOWNCALL art_quick_handle_fill_data_from_code, artHandleFillArrayDataFromCode, RETURN_IF_EAX_ZERO
Ian Rogers7caad772012-03-30 01:07:54 -0700397
Logan Chien8dbb7082013-01-25 20:31:17 +0800398DEFINE_FUNCTION art_quick_is_assignable_from_code
Ian Rogers7caad772012-03-30 01:07:54 -0700399 pushl %eax // alignment padding
400 pushl %ecx // pass arg2
401 pushl %eax // pass arg1
Elliott Hughesadc078a2012-04-04 11:39:05 -0700402 call SYMBOL(artIsAssignableFromCode) // (Class* a, Class* b, Thread*, SP)
Ian Rogers55bd45f2012-04-04 17:31:20 -0700403 addl LITERAL(12), %esp // pop arguments
Ian Rogers7caad772012-03-30 01:07:54 -0700404 ret
405
Logan Chien8dbb7082013-01-25 20:31:17 +0800406DEFINE_FUNCTION art_quick_memcpy
Ian Rogers7caad772012-03-30 01:07:54 -0700407 pushl %edx // pass arg3
408 pushl %ecx // pass arg2
409 pushl %eax // pass arg1
Elliott Hughesadc078a2012-04-04 11:39:05 -0700410 call SYMBOL(memcpy) // (void*, const void*, size_t)
Ian Rogers55bd45f2012-04-04 17:31:20 -0700411 addl LITERAL(12), %esp // pop arguments
Ian Rogers7caad772012-03-30 01:07:54 -0700412 ret
413
Logan Chien8dbb7082013-01-25 20:31:17 +0800414TWO_ARG_DOWNCALL art_quick_check_cast_from_code, artCheckCastFromCode, RETURN_IF_EAX_ZERO
415TWO_ARG_DOWNCALL art_quick_can_put_array_element_from_code, artCanPutArrayElementFromCode, RETURN_IF_EAX_ZERO
Ian Rogersd36c52e2012-04-09 16:29:25 -0700416
Logan Chien8dbb7082013-01-25 20:31:17 +0800417NO_ARG_DOWNCALL art_quick_test_suspend, artTestSuspendFromCode, ret
Ian Rogers7caad772012-03-30 01:07:54 -0700418
Logan Chien8dbb7082013-01-25 20:31:17 +0800419DEFINE_FUNCTION art_quick_fmod_from_code
jeffhao1395b1e2012-06-13 18:05:13 -0700420 subl LITERAL(12), %esp // alignment padding
421 pushl %ebx // pass arg4 b.hi
422 pushl %edx // pass arg3 b.lo
423 pushl %ecx // pass arg2 a.hi
424 pushl %eax // pass arg1 a.lo
425 call SYMBOL(fmod) // (jdouble a, jdouble b)
426 fstpl (%esp) // pop return value off fp stack
427 movsd (%esp), %xmm0 // place into %xmm0
428 addl LITERAL(28), %esp // pop arguments
jeffhao292188d2012-05-17 15:45:04 -0700429 ret
430
Logan Chien8dbb7082013-01-25 20:31:17 +0800431DEFINE_FUNCTION art_quick_fmodf_from_code
jeffhao1395b1e2012-06-13 18:05:13 -0700432 pushl %eax // alignment padding
433 pushl %ecx // pass arg2 b
434 pushl %eax // pass arg1 a
435 call SYMBOL(fmodf) // (jfloat a, jfloat b)
Ian Rogers1b09b092012-08-20 15:35:52 -0700436 fstps (%esp) // pop return value off fp stack
jeffhao1395b1e2012-06-13 18:05:13 -0700437 movss (%esp), %xmm0 // place into %xmm0
438 addl LITERAL(12), %esp // pop arguments
jeffhao292188d2012-05-17 15:45:04 -0700439 ret
440
Logan Chien8dbb7082013-01-25 20:31:17 +0800441DEFINE_FUNCTION art_quick_l2d_from_code
jeffhao41005dd2012-05-09 17:58:52 -0700442 pushl %eax // alignment padding
jeffhao1395b1e2012-06-13 18:05:13 -0700443 pushl %ecx // pass arg2 a.hi
444 pushl %eax // pass arg1 a.lo
445 call SYMBOL(art_l2d) // (jlong a)
jeffhao292188d2012-05-17 15:45:04 -0700446 fstpl (%esp) // pop return value off fp stack
jeffhao41005dd2012-05-09 17:58:52 -0700447 movsd (%esp), %xmm0 // place into %xmm0
448 addl LITERAL(12), %esp // pop arguments
449 ret
450
Logan Chien8dbb7082013-01-25 20:31:17 +0800451DEFINE_FUNCTION art_quick_l2f_from_code
jeffhao41005dd2012-05-09 17:58:52 -0700452 pushl %eax // alignment padding
jeffhao1395b1e2012-06-13 18:05:13 -0700453 pushl %ecx // pass arg2 a.hi
454 pushl %eax // pass arg1 a.lo
455 call SYMBOL(art_l2f) // (jlong a)
Ian Rogers1b09b092012-08-20 15:35:52 -0700456 fstps (%esp) // pop return value off fp stack
jeffhao41005dd2012-05-09 17:58:52 -0700457 movss (%esp), %xmm0 // place into %xmm0
458 addl LITERAL(12), %esp // pop arguments
459 ret
460
Logan Chien8dbb7082013-01-25 20:31:17 +0800461DEFINE_FUNCTION art_quick_d2l_from_code
jeffhao41005dd2012-05-09 17:58:52 -0700462 pushl %eax // alignment padding
jeffhao1395b1e2012-06-13 18:05:13 -0700463 pushl %ecx // pass arg2 a.hi
464 pushl %eax // pass arg1 a.lo
465 call SYMBOL(art_d2l) // (jdouble a)
jeffhao41005dd2012-05-09 17:58:52 -0700466 addl LITERAL(12), %esp // pop arguments
467 ret
468
Logan Chien8dbb7082013-01-25 20:31:17 +0800469DEFINE_FUNCTION art_quick_f2l_from_code
jeffhao41005dd2012-05-09 17:58:52 -0700470 subl LITERAL(8), %esp // alignment padding
jeffhao1395b1e2012-06-13 18:05:13 -0700471 pushl %eax // pass arg1 a
472 call SYMBOL(art_f2l) // (jfloat a)
jeffhao41005dd2012-05-09 17:58:52 -0700473 addl LITERAL(12), %esp // pop arguments
474 ret
475
Logan Chien8dbb7082013-01-25 20:31:17 +0800476DEFINE_FUNCTION art_quick_idivmod_from_code
jeffhao174651d2012-04-19 15:27:22 -0700477 cmpl LITERAL(0x80000000), %eax
478 je check_arg2 // special case
479args_ok:
Ian Rogers7caad772012-03-30 01:07:54 -0700480 cdq // edx:eax = sign extend eax
481 idiv %ecx // (edx,eax) = (edx:eax % ecx, edx:eax / ecx)
Ian Rogers7caad772012-03-30 01:07:54 -0700482 ret
jeffhao174651d2012-04-19 15:27:22 -0700483check_arg2:
484 cmpl LITERAL(-1), %ecx
485 jne args_ok
486 xorl %edx, %edx
487 ret // eax already holds min int
Ian Rogers7caad772012-03-30 01:07:54 -0700488
Logan Chien8dbb7082013-01-25 20:31:17 +0800489DEFINE_FUNCTION art_quick_ldiv_from_code
Ian Rogers141d6222012-04-05 12:23:06 -0700490 subl LITERAL(12), %esp // alignment padding
jeffhao1395b1e2012-06-13 18:05:13 -0700491 pushl %ebx // pass arg4 b.hi
492 pushl %edx // pass arg3 b.lo
493 pushl %ecx // pass arg2 a.hi
494 pushl %eax // pass arg1 a.lo
495 call SYMBOL(artLdivFromCode) // (jlong a, jlong b)
Ian Rogers55bd45f2012-04-04 17:31:20 -0700496 addl LITERAL(28), %esp // pop arguments
497 ret
498
Logan Chien8dbb7082013-01-25 20:31:17 +0800499DEFINE_FUNCTION art_quick_ldivmod_from_code
Ian Rogers141d6222012-04-05 12:23:06 -0700500 subl LITERAL(12), %esp // alignment padding
jeffhao1395b1e2012-06-13 18:05:13 -0700501 pushl %ebx // pass arg4 b.hi
502 pushl %edx // pass arg3 b.lo
503 pushl %ecx // pass arg2 a.hi
504 pushl %eax // pass arg1 a.lo
505 call SYMBOL(artLdivmodFromCode) // (jlong a, jlong b)
Ian Rogers55bd45f2012-04-04 17:31:20 -0700506 addl LITERAL(28), %esp // pop arguments
507 ret
508
Logan Chien8dbb7082013-01-25 20:31:17 +0800509DEFINE_FUNCTION art_quick_lmul_from_code
jeffhao644d5312012-05-03 19:04:49 -0700510 subl LITERAL(12), %esp // alignment padding
jeffhao1395b1e2012-06-13 18:05:13 -0700511 pushl %ebx // pass arg4 b.hi
512 pushl %edx // pass arg3 b.lo
513 pushl %ecx // pass arg2 a.hi
514 pushl %eax // pass arg1 a.lo
515 call SYMBOL(artLmulFromCode) // (jlong a, jlong b)
jeffhao644d5312012-05-03 19:04:49 -0700516 addl LITERAL(28), %esp // pop arguments
517 ret
518
Logan Chien8dbb7082013-01-25 20:31:17 +0800519DEFINE_FUNCTION art_quick_lshl_from_code
jeffhao644d5312012-05-03 19:04:49 -0700520 // ecx:eax << edx
Ian Rogers141d6222012-04-05 12:23:06 -0700521 xchg %edx, %ecx
522 shld %cl,%eax,%edx
523 shl %cl,%eax
524 test LITERAL(32), %cl
525 jz 1f
526 mov %eax, %edx
527 xor %eax, %eax
5281:
529 ret
530
Logan Chien8dbb7082013-01-25 20:31:17 +0800531DEFINE_FUNCTION art_quick_lshr_from_code
jeffhao644d5312012-05-03 19:04:49 -0700532 // ecx:eax >> edx
Ian Rogers141d6222012-04-05 12:23:06 -0700533 xchg %edx, %ecx
jeffhao644d5312012-05-03 19:04:49 -0700534 shrd %cl,%edx,%eax
535 sar %cl,%edx
Ian Rogers141d6222012-04-05 12:23:06 -0700536 test LITERAL(32),%cl
537 jz 1f
jeffhao5121e0b2012-05-08 18:23:38 -0700538 mov %edx, %eax
539 sar LITERAL(31), %edx
Ian Rogers141d6222012-04-05 12:23:06 -07005401:
541 ret
542
Logan Chien8dbb7082013-01-25 20:31:17 +0800543DEFINE_FUNCTION art_quick_lushr_from_code
jeffhao644d5312012-05-03 19:04:49 -0700544 // ecx:eax >>> edx
Ian Rogers141d6222012-04-05 12:23:06 -0700545 xchg %edx, %ecx
jeffhao644d5312012-05-03 19:04:49 -0700546 shrd %cl,%edx,%eax
547 shr %cl,%edx
548 test LITERAL(32),%cl
Ian Rogers141d6222012-04-05 12:23:06 -0700549 jz 1f
jeffhao5121e0b2012-05-08 18:23:38 -0700550 mov %edx, %eax
551 xor %edx, %edx
Ian Rogers141d6222012-04-05 12:23:06 -07005521:
553 ret
554
Logan Chien8dbb7082013-01-25 20:31:17 +0800555DEFINE_FUNCTION art_quick_set32_instance_from_code
jeffhao9dbb23e2012-05-18 17:03:57 -0700556 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
557 mov %esp, %ebx // remember SP
jeffhao1ff4cd72012-05-21 11:17:48 -0700558 subl LITERAL(8), %esp // alignment padding
jeffhao9dbb23e2012-05-18 17:03:57 -0700559 pushl %ebx // pass SP
560 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
561 mov 32(%ebx), %ebx // get referrer
562 pushl %ebx // pass referrer
563 pushl %edx // pass new_val
564 pushl %ecx // pass object
565 pushl %eax // pass field_idx
566 call SYMBOL(artSet32InstanceFromCode) // (field_idx, Object*, new_val, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700567 addl LITERAL(32), %esp // pop arguments
jeffhao9dbb23e2012-05-18 17:03:57 -0700568 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
569 RETURN_IF_EAX_ZERO // return or deliver exception
570
Logan Chien8dbb7082013-01-25 20:31:17 +0800571DEFINE_FUNCTION art_quick_set64_instance_from_code
jeffhao9dbb23e2012-05-18 17:03:57 -0700572 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
jeffhao1ff4cd72012-05-21 11:17:48 -0700573 subl LITERAL(8), %esp // alignment padding
jeffhao9dbb23e2012-05-18 17:03:57 -0700574 pushl %esp // pass SP-8
jeffhao1ff4cd72012-05-21 11:17:48 -0700575 addl LITERAL(8), (%esp) // fix SP on stack by adding 8
jeffhao9dbb23e2012-05-18 17:03:57 -0700576 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
577 pushl %ebx // pass high half of new_val
578 pushl %edx // pass low half of new_val
579 pushl %ecx // pass object
580 pushl %eax // pass field_idx
581 call SYMBOL(artSet64InstanceFromCode) // (field_idx, Object*, new_val, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700582 addl LITERAL(32), %esp // pop arguments
jeffhao9dbb23e2012-05-18 17:03:57 -0700583 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
584 RETURN_IF_EAX_ZERO // return or deliver exception
585
Logan Chien8dbb7082013-01-25 20:31:17 +0800586DEFINE_FUNCTION art_quick_set_obj_instance_from_code
jeffhao9dbb23e2012-05-18 17:03:57 -0700587 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
588 mov %esp, %ebx // remember SP
jeffhao1ff4cd72012-05-21 11:17:48 -0700589 subl LITERAL(8), %esp // alignment padding
jeffhao9dbb23e2012-05-18 17:03:57 -0700590 pushl %ebx // pass SP
591 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
592 mov 32(%ebx), %ebx // get referrer
593 pushl %ebx // pass referrer
594 pushl %edx // pass new_val
595 pushl %ecx // pass object
596 pushl %eax // pass field_idx
597 call SYMBOL(artSetObjInstanceFromCode) // (field_idx, Object*, new_val, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700598 addl LITERAL(32), %esp // pop arguments
jeffhao9dbb23e2012-05-18 17:03:57 -0700599 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
600 RETURN_IF_EAX_ZERO // return or deliver exception
601
Logan Chien8dbb7082013-01-25 20:31:17 +0800602DEFINE_FUNCTION art_quick_get32_instance_from_code
jeffhao9dbb23e2012-05-18 17:03:57 -0700603 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
604 mov %esp, %ebx // remember SP
605 mov 32(%esp), %edx // get referrer
jeffhao1ff4cd72012-05-21 11:17:48 -0700606 subl LITERAL(12), %esp // alignment padding
jeffhao9dbb23e2012-05-18 17:03:57 -0700607 pushl %ebx // pass SP
608 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
609 pushl %edx // pass referrer
610 pushl %ecx // pass object
611 pushl %eax // pass field_idx
612 call SYMBOL(artGet32InstanceFromCode) // (field_idx, Object*, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700613 addl LITERAL(32), %esp // pop arguments
jeffhao9dbb23e2012-05-18 17:03:57 -0700614 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
jeffhaod66a8752012-05-22 15:30:16 -0700615 RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
jeffhao9dbb23e2012-05-18 17:03:57 -0700616
Logan Chien8dbb7082013-01-25 20:31:17 +0800617DEFINE_FUNCTION art_quick_get64_instance_from_code
jeffhao9dbb23e2012-05-18 17:03:57 -0700618 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
619 mov %esp, %ebx // remember SP
620 mov 32(%esp), %edx // get referrer
jeffhao1ff4cd72012-05-21 11:17:48 -0700621 subl LITERAL(12), %esp // alignment padding
jeffhao9dbb23e2012-05-18 17:03:57 -0700622 pushl %ebx // pass SP
623 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
624 pushl %edx // pass referrer
625 pushl %ecx // pass object
626 pushl %eax // pass field_idx
627 call SYMBOL(artGet64InstanceFromCode) // (field_idx, Object*, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700628 addl LITERAL(32), %esp // pop arguments
jeffhao9dbb23e2012-05-18 17:03:57 -0700629 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
jeffhaod66a8752012-05-22 15:30:16 -0700630 RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
jeffhao9dbb23e2012-05-18 17:03:57 -0700631
Logan Chien8dbb7082013-01-25 20:31:17 +0800632DEFINE_FUNCTION art_quick_get_obj_instance_from_code
jeffhao9dbb23e2012-05-18 17:03:57 -0700633 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
634 mov %esp, %ebx // remember SP
635 mov 32(%esp), %edx // get referrer
jeffhao1ff4cd72012-05-21 11:17:48 -0700636 subl LITERAL(12), %esp // alignment padding
jeffhao9dbb23e2012-05-18 17:03:57 -0700637 pushl %ebx // pass SP
638 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
639 pushl %edx // pass referrer
640 pushl %ecx // pass object
641 pushl %eax // pass field_idx
642 call SYMBOL(artGetObjInstanceFromCode) // (field_idx, Object*, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700643 addl LITERAL(32), %esp // pop arguments
jeffhao9dbb23e2012-05-18 17:03:57 -0700644 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
jeffhaod66a8752012-05-22 15:30:16 -0700645 RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
jeffhao9dbb23e2012-05-18 17:03:57 -0700646
Logan Chien8dbb7082013-01-25 20:31:17 +0800647DEFINE_FUNCTION art_quick_set32_static_from_code
jeffhao9dbb23e2012-05-18 17:03:57 -0700648 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
649 mov %esp, %ebx // remember SP
650 mov 32(%esp), %edx // get referrer
jeffhao1ff4cd72012-05-21 11:17:48 -0700651 subl LITERAL(12), %esp // alignment padding
jeffhao9dbb23e2012-05-18 17:03:57 -0700652 pushl %ebx // pass SP
653 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
654 pushl %edx // pass referrer
655 pushl %ecx // pass new_val
656 pushl %eax // pass field_idx
657 call SYMBOL(artSet32StaticFromCode) // (field_idx, new_val, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700658 addl LITERAL(32), %esp // pop arguments
jeffhao9dbb23e2012-05-18 17:03:57 -0700659 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
660 RETURN_IF_EAX_ZERO // return or deliver exception
661
Logan Chien8dbb7082013-01-25 20:31:17 +0800662DEFINE_FUNCTION art_quick_set64_static_from_code
jeffhao9dbb23e2012-05-18 17:03:57 -0700663 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
664 mov %esp, %ebx // remember SP
jeffhao1ff4cd72012-05-21 11:17:48 -0700665 subl LITERAL(8), %esp // alignment padding
jeffhao9dbb23e2012-05-18 17:03:57 -0700666 pushl %ebx // pass SP
667 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
668 mov 32(%ebx), %ebx // get referrer
669 pushl %edx // pass high half of new_val
670 pushl %ecx // pass low half of new_val
671 pushl %ebx // pass referrer
672 pushl %eax // pass field_idx
673 call SYMBOL(artSet64StaticFromCode) // (field_idx, referrer, new_val, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700674 addl LITERAL(32), %esp // pop arguments
jeffhao9dbb23e2012-05-18 17:03:57 -0700675 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
676 RETURN_IF_EAX_ZERO // return or deliver exception
677
Logan Chien8dbb7082013-01-25 20:31:17 +0800678DEFINE_FUNCTION art_quick_set_obj_static_from_code
jeffhao9dbb23e2012-05-18 17:03:57 -0700679 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
680 mov %esp, %ebx // remember SP
681 mov 32(%esp), %edx // get referrer
jeffhao1ff4cd72012-05-21 11:17:48 -0700682 subl LITERAL(12), %esp // alignment padding
jeffhao9dbb23e2012-05-18 17:03:57 -0700683 pushl %ebx // pass SP
684 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
685 pushl %edx // pass referrer
686 pushl %ecx // pass new_val
687 pushl %eax // pass field_idx
688 call SYMBOL(artSetObjStaticFromCode) // (field_idx, new_val, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700689 addl LITERAL(32), %esp // pop arguments
jeffhao9dbb23e2012-05-18 17:03:57 -0700690 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
691 RETURN_IF_EAX_ZERO // return or deliver exception
692
Logan Chien8dbb7082013-01-25 20:31:17 +0800693DEFINE_FUNCTION art_quick_get32_static_from_code
jeffhao9dbb23e2012-05-18 17:03:57 -0700694 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
695 mov %esp, %edx // remember SP
696 mov 32(%esp), %ecx // get referrer
697 pushl %edx // pass SP
698 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
699 pushl %ecx // pass referrer
700 pushl %eax // pass field_idx
701 call SYMBOL(artGet32StaticFromCode) // (field_idx, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700702 addl LITERAL(16), %esp // pop arguments
jeffhao9dbb23e2012-05-18 17:03:57 -0700703 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
jeffhaod66a8752012-05-22 15:30:16 -0700704 RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
jeffhao9dbb23e2012-05-18 17:03:57 -0700705
Logan Chien8dbb7082013-01-25 20:31:17 +0800706DEFINE_FUNCTION art_quick_get64_static_from_code
jeffhao9dbb23e2012-05-18 17:03:57 -0700707 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
708 mov %esp, %edx // remember SP
709 mov 32(%esp), %ecx // get referrer
710 pushl %edx // pass SP
711 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
712 pushl %ecx // pass referrer
713 pushl %eax // pass field_idx
714 call SYMBOL(artGet64StaticFromCode) // (field_idx, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700715 addl LITERAL(16), %esp // pop arguments
jeffhao9dbb23e2012-05-18 17:03:57 -0700716 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
jeffhaod66a8752012-05-22 15:30:16 -0700717 RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
jeffhao9dbb23e2012-05-18 17:03:57 -0700718
Logan Chien8dbb7082013-01-25 20:31:17 +0800719DEFINE_FUNCTION art_quick_get_obj_static_from_code
jeffhao9dbb23e2012-05-18 17:03:57 -0700720 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
721 mov %esp, %edx // remember SP
722 mov 32(%esp), %ecx // get referrer
723 pushl %edx // pass SP
724 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
725 pushl %ecx // pass referrer
726 pushl %eax // pass field_idx
727 call SYMBOL(artGetObjStaticFromCode) // (field_idx, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700728 addl LITERAL(16), %esp // pop arguments
jeffhao9dbb23e2012-05-18 17:03:57 -0700729 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
jeffhaod66a8752012-05-22 15:30:16 -0700730 RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
731
Logan Chien8dbb7082013-01-25 20:31:17 +0800732DEFINE_FUNCTION art_quick_proxy_invoke_handler
Ian Rogers7db619b2013-01-16 18:35:48 -0800733 SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME // save frame and Method*
Ian Rogersaf6e67a2013-01-16 08:38:37 -0800734 pushl %esp // pass SP
jeffhaod66a8752012-05-22 15:30:16 -0700735 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
736 pushl %ecx // pass receiver
737 pushl %eax // pass proxy method
Ian Rogersaf6e67a2013-01-16 08:38:37 -0800738 call SYMBOL(artProxyInvokeHandler) // (proxy method, receiver, Thread*, SP)
739 movd %eax, %xmm0 // place return value also into floating point return value
740 movd %edx, %xmm1
741 punpckldq %xmm1, %xmm0
jeffhaod66a8752012-05-22 15:30:16 -0700742 addl LITERAL(44), %esp // pop arguments
743 RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
jeffhao9dbb23e2012-05-18 17:03:57 -0700744
Logan Chien8dbb7082013-01-25 20:31:17 +0800745DEFINE_FUNCTION art_quick_interpreter_entry
Ian Rogers7db619b2013-01-16 18:35:48 -0800746 SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME // save frame and Method*
747 pushl %eax // alignment padding
748 pushl %esp // pass SP
749 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
750 pushl %eax // pass method
751 call SYMBOL(artInterpreterEntry) // (method, Thread*, SP)
752 movd %eax, %xmm0 // place return value also into floating point return value
753 movd %edx, %xmm1
754 punpckldq %xmm1, %xmm0
755 addl LITERAL(44), %esp // pop arguments
756 RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
757
jeffhao7e4fcb82013-01-10 18:11:08 -0800758 /*
759 * Routine that intercepts method calls and returns.
760 */
Logan Chien8dbb7082013-01-25 20:31:17 +0800761DEFINE_FUNCTION art_quick_instrumentation_entry_from_code
jeffhao7e4fcb82013-01-10 18:11:08 -0800762 xchgl %eax, (%esp) // place LR in eax, save eax
763 pushl %ecx // save ecx
764 pushl %edx // save edx
765 pushl %ebx // save ebx
766 lea 16(%esp), %edx // remember bottom of caller's frame
767 pushl %eax // pass LR
768 pushl %edx // pass SP
769 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
770 pushl 24(%esp) // pass Method*
771 call SYMBOL(artInstrumentationMethodEntryFromCode) // (Method*, Thread*, SP, LR)
772 addl LITERAL(16), %esp // pop arguments
773 popl %ebx // restore ebx
774 popl %edx // restore edx
775 movl (%esp), %ecx // restore ecx (without popping)
776 movl %eax, (%esp) // place method's code pointer on stack
777 movl 4(%esp), %eax // restore eax (without popping)
Logan Chien8dbb7082013-01-25 20:31:17 +0800778 movl LITERAL(SYMBOL(art_quick_instrumentation_exit_from_code)), 4(%esp)
jeffhao7e4fcb82013-01-10 18:11:08 -0800779 // place instrumentation exit as return pc
780 ret // call method (and pop)
Logan Chien8dbb7082013-01-25 20:31:17 +0800781DEFINE_FUNCTION art_quick_instrumentation_exit_from_code
jeffhao7e4fcb82013-01-10 18:11:08 -0800782 mov %esp, %ecx // remember bottom of caller's frame
783 pushl %edx // save return value
784 pushl %eax // save other half of return value
785 pushl %ecx // pass SP
786 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current
787 call SYMBOL(artInstrumentationMethodExitFromCode) // (Thread*, SP)
788 mov %eax, %ecx // move returned link register
789 // TODO: Set link register for deopt
790 addl LITERAL(8), %esp // pop arguments
791 popl %eax // restore return value
792 popl %edx // restore other half of return value
793 jmp *%ecx // return
jeffhao162fd332013-01-08 16:21:01 -0800794
jeffhao7e4fcb82013-01-10 18:11:08 -0800795 /*
796 * The thread's enter interpreter flag is set and so we should transition to the interpreter
797 * rather than allow execution to continue in the frame below. There may be live results in
798 * registers depending on how complete the operation is when we safepoint - for example, a
799 * set operation may have completed while a get operation needs writing back into the vregs.
800 */
Logan Chien8dbb7082013-01-25 20:31:17 +0800801DEFINE_FUNCTION art_quick_deoptimize
jeffhao7e4fcb82013-01-10 18:11:08 -0800802 SETUP_REF_ONLY_CALLEE_SAVE_FRAME
803 pushl %esp // pass SP
804 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
805 pushl %edx // push half of return value
806 pushl %eax // push other half of return value
807 call SYMBOL(artDeoptimize) // artDeoptimize(return value, Thread*, SP)
808 // Returns caller method's frame size.
809 addl LITERAL(16), %esp // pop arguments
810 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
811 testl %eax, %eax // Was the caller an upcall?
812 jz 1f // Return if caller was upcall.
813 lea (%esp, %eax), %edx // edx == bottom of caller's frame.
814 mov %edx, %esp // Remove frame.
815 SETUP_REF_ONLY_CALLEE_SAVE_FRAME
816 call SYMBOL(artEnterInterpreterFromDeoptimize) // Enter interpreter, callee-save ends stack fragment.
817 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
8181:
819 ret // Return to caller.
jeffhao162fd332013-01-08 16:21:01 -0800820
jeffhao86e46712012-08-08 17:30:59 -0700821 /*
822 * String's indexOf.
823 *
824 * On entry:
825 * eax: string object (known non-null)
826 * ecx: char to match (known <= 0xFFFF)
827 * edx: Starting offset in string data
828 */
Logan Chien8dbb7082013-01-25 20:31:17 +0800829DEFINE_FUNCTION art_quick_indexof
jeffhao86e46712012-08-08 17:30:59 -0700830 pushl %edi // push callee save reg
831 mov STRING_COUNT_OFFSET(%eax), %ebx
832 mov STRING_VALUE_OFFSET(%eax), %edi
833 mov STRING_OFFSET_OFFSET(%eax), %eax
834 testl %edx, %edx // check if start < 0
835 jl clamp_min
836clamp_done:
837 cmpl %ebx, %edx // check if start >= count
838 jge not_found
839 lea STRING_DATA_OFFSET(%edi, %eax, 2), %edi // build a pointer to the start of string data
840 mov %edi, %eax // save a copy in eax to later compute result
841 lea (%edi, %edx, 2), %edi // build pointer to start of data to compare
842 subl %edx, %ebx // compute iteration count
843 /*
844 * At this point we have:
845 * eax: original start of string data
846 * ecx: char to compare
847 * ebx: length to compare
848 * edi: start of data to test
849 */
850 mov %eax, %edx
851 mov %ecx, %eax // put char to match in %eax
852 mov %ebx, %ecx // put length to compare in %ecx
853 repne scasw // find %ax, starting at [%edi], up to length %ecx
854 jne not_found
855 subl %edx, %edi
856 sar LITERAL(1), %edi
857 decl %edi // index = ((curr_ptr - orig_ptr) / 2) - 1
858 mov %edi, %eax
859 popl %edi // pop callee save reg
860 ret
861 .balign 16
862not_found:
863 mov LITERAL(-1), %eax // return -1 (not found)
864 popl %edi // pop callee save reg
865 ret
866clamp_min:
867 xor %edx, %edx // clamp start to 0
868 jmp clamp_done
869
870 /*
871 * String's compareTo.
872 *
873 * On entry:
874 * eax: this string object (known non-null)
875 * ecx: comp string object (known non-null)
876 */
Logan Chien8dbb7082013-01-25 20:31:17 +0800877DEFINE_FUNCTION art_quick_string_compareto
jeffhao86e46712012-08-08 17:30:59 -0700878 pushl %esi // push callee save reg
879 pushl %edi // push callee save reg
880 mov STRING_COUNT_OFFSET(%eax), %edx
881 mov STRING_COUNT_OFFSET(%ecx), %ebx
882 mov STRING_VALUE_OFFSET(%eax), %esi
883 mov STRING_VALUE_OFFSET(%ecx), %edi
884 mov STRING_OFFSET_OFFSET(%eax), %eax
885 mov STRING_OFFSET_OFFSET(%ecx), %ecx
886 /* Build pointers to the start of string data */
887 lea STRING_DATA_OFFSET(%esi, %eax, 2), %esi
888 lea STRING_DATA_OFFSET(%edi, %ecx, 2), %edi
889 /* Calculate min length and count diff */
890 mov %edx, %ecx
891 mov %edx, %eax
892 subl %ebx, %eax
893 cmovg %ebx, %ecx
894 /*
895 * At this point we have:
896 * eax: value to return if first part of strings are equal
897 * ecx: minimum among the lengths of the two strings
898 * esi: pointer to this string data
899 * edi: pointer to comp string data
900 */
901 repe cmpsw // find nonmatching chars in [%esi] and [%edi], up to length %ecx
902 jne not_equal
903 popl %edi // pop callee save reg
904 popl %esi // pop callee save reg
905 ret
906 .balign 16
907not_equal:
Ian Rogers1b09b092012-08-20 15:35:52 -0700908 movzwl -2(%esi), %eax // get last compared char from this string
909 movzwl -2(%edi), %ecx // get last compared char from comp string
jeffhao86e46712012-08-08 17:30:59 -0700910 subl %ecx, %eax // return the difference
911 popl %edi // pop callee save reg
912 popl %esi // pop callee save reg
913 ret
914
Elliott Hughes787ec202012-03-29 17:14:15 -0700915MACRO1(UNIMPLEMENTED,name)
916 .globl VAR(name, 0)
917 ALIGN_FUNCTION_ENTRY
918VAR(name, 0):
Ian Rogers57b86d42012-03-27 16:05:41 -0700919 int3
Elliott Hughes787ec202012-03-29 17:14:15 -0700920END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -0700921
Elliott Hughes787ec202012-03-29 17:14:15 -0700922 // TODO: implement these!
Logan Chien8dbb7082013-01-25 20:31:17 +0800923UNIMPLEMENTED art_quick_memcmp16