blob: 6a6891b33149b71be50eafed1023fd51d69ae1ba [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 Rogers7655f292013-07-29 11:07:13 -070017#include "asm_support_x86.S"
Elliott Hughes5e284222012-04-04 13:38:03 -070018
Ian Rogers57b86d42012-03-27 16:05:41 -070019 /*
20 * Macro that sets up the callee save frame to conform with
Ian Rogers7caad772012-03-30 01:07:54 -070021 * Runtime::CreateCalleeSaveMethod(kSaveAll)
Ian Rogers57b86d42012-03-27 16:05:41 -070022 */
Elliott Hughes787ec202012-03-29 17:14:15 -070023MACRO0(SETUP_SAVE_ALL_CALLEE_SAVE_FRAME)
Ian Rogersaeeada42013-02-13 11:28:34 -080024 PUSH edi // Save callee saves (ebx is saved/restored by the upcall)
25 PUSH esi
26 PUSH ebp
Elliott Hughesea944212012-04-05 13:11:53 -070027 subl MACRO_LITERAL(16), %esp // Grow stack by 4 words, bottom word will hold Method*
Ian Rogersaeeada42013-02-13 11:28:34 -080028 .cfi_adjust_cfa_offset 16
Elliott Hughes787ec202012-03-29 17:14:15 -070029END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -070030
Ian Rogers7caad772012-03-30 01:07:54 -070031 /*
32 * Macro that sets up the callee save frame to conform with
33 * Runtime::CreateCalleeSaveMethod(kRefsOnly)
34 */
35MACRO0(SETUP_REF_ONLY_CALLEE_SAVE_FRAME)
Ian Rogersaeeada42013-02-13 11:28:34 -080036 PUSH edi // Save callee saves (ebx is saved/restored by the upcall)
37 PUSH esi
38 PUSH ebp
Elliott Hughesea944212012-04-05 13:11:53 -070039 subl MACRO_LITERAL(16), %esp // Grow stack by 4 words, bottom word will hold Method*
Ian Rogersaeeada42013-02-13 11:28:34 -080040 .cfi_adjust_cfa_offset 16
Ian Rogers7caad772012-03-30 01:07:54 -070041END_MACRO
42
43MACRO0(RESTORE_REF_ONLY_CALLEE_SAVE_FRAME)
Mathieu Chartier2a6c7b72013-10-16 11:16:33 -070044 addl MACRO_LITERAL(16), %esp // Unwind stack up to return address
45 POP ebp // Restore callee saves (ebx is saved/restored by the upcall)
46 POP esi
47 POP edi
Ian Rogersaeeada42013-02-13 11:28:34 -080048 .cfi_adjust_cfa_offset -28
Elliott Hughes787ec202012-03-29 17:14:15 -070049END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -070050
51 /*
52 * Macro that sets up the callee save frame to conform with
Ian Rogers7caad772012-03-30 01:07:54 -070053 * Runtime::CreateCalleeSaveMethod(kRefsAndArgs)
Ian Rogers57b86d42012-03-27 16:05:41 -070054 */
jeffhao9dbb23e2012-05-18 17:03:57 -070055MACRO0(SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME)
Ian Rogersaeeada42013-02-13 11:28:34 -080056 PUSH edi // Save callee saves
57 PUSH esi
58 PUSH ebp
59 PUSH ebx // Save args
60 PUSH edx
61 PUSH ecx
62 PUSH eax // Align stack, eax will be clobbered by Method*
Elliott Hughes787ec202012-03-29 17:14:15 -070063END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -070064
jeffhao9dbb23e2012-05-18 17:03:57 -070065MACRO0(RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME)
Elliott Hughesea944212012-04-05 13:11:53 -070066 addl MACRO_LITERAL(4), %esp // Remove padding
Ian Rogersaeeada42013-02-13 11:28:34 -080067 .cfi_adjust_cfa_offset -4
68 POP ecx // Restore args except eax
69 POP edx
70 POP ebx
71 POP ebp // Restore callee saves
72 POP esi
73 POP edi
Elliott Hughes787ec202012-03-29 17:14:15 -070074END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -070075
76 /*
77 * Macro that set calls through to artDeliverPendingExceptionFromCode, where the pending
78 * exception is Thread::Current()->exception_.
79 */
Elliott Hughes787ec202012-03-29 17:14:15 -070080MACRO0(DELIVER_PENDING_EXCEPTION)
Ian Rogers57b86d42012-03-27 16:05:41 -070081 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save callee saves for throw
82 mov %esp, %ecx
83 // Outgoing argument set up
Elliott Hughesea944212012-04-05 13:11:53 -070084 subl MACRO_LITERAL(8), %esp // Alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -080085 .cfi_adjust_cfa_offset 8
86 PUSH ecx // pass SP
Ian Rogers57b86d42012-03-27 16:05:41 -070087 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -080088 .cfi_adjust_cfa_offset 4
jeffhao9dbb23e2012-05-18 17:03:57 -070089 call SYMBOL(artDeliverPendingExceptionFromCode) // artDeliverPendingExceptionFromCode(Thread*, SP)
90 int3 // unreached
Elliott Hughes787ec202012-03-29 17:14:15 -070091END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -070092
Elliott Hughes787ec202012-03-29 17:14:15 -070093MACRO2(NO_ARG_RUNTIME_EXCEPTION, c_name, cxx_name)
Ian Rogersaeeada42013-02-13 11:28:34 -080094 DEFINE_FUNCTION VAR(c_name, 0)
Ian Rogers57b86d42012-03-27 16:05:41 -070095 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context
96 mov %esp, %ecx
97 // Outgoing argument set up
Elliott Hughesea944212012-04-05 13:11:53 -070098 subl MACRO_LITERAL(8), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -080099 .cfi_adjust_cfa_offset 8
100 PUSH ecx // pass SP
Ian Rogers55bd45f2012-04-04 17:31:20 -0700101 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800102 .cfi_adjust_cfa_offset 4
Elliott Hughes787ec202012-03-29 17:14:15 -0700103 call VAR(cxx_name, 1) // cxx_name(Thread*, SP)
Ian Rogers57b86d42012-03-27 16:05:41 -0700104 int3 // unreached
Ian Rogersaeeada42013-02-13 11:28:34 -0800105 END_FUNCTION VAR(c_name, 0)
Elliott Hughes787ec202012-03-29 17:14:15 -0700106END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -0700107
Elliott Hughes787ec202012-03-29 17:14:15 -0700108MACRO2(ONE_ARG_RUNTIME_EXCEPTION, c_name, cxx_name)
Ian Rogersaeeada42013-02-13 11:28:34 -0800109 DEFINE_FUNCTION VAR(c_name, 0)
Ian Rogers57b86d42012-03-27 16:05:41 -0700110 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context
111 mov %esp, %ecx
112 // Outgoing argument set up
Ian Rogersaeeada42013-02-13 11:28:34 -0800113 PUSH eax // alignment padding
114 PUSH ecx // pass SP
Ian Rogers57b86d42012-03-27 16:05:41 -0700115 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800116 .cfi_adjust_cfa_offset 4
117 PUSH eax // pass arg1
Elliott Hughes787ec202012-03-29 17:14:15 -0700118 call VAR(cxx_name, 1) // cxx_name(arg1, Thread*, SP)
Ian Rogers57b86d42012-03-27 16:05:41 -0700119 int3 // unreached
Ian Rogersaeeada42013-02-13 11:28:34 -0800120 END_FUNCTION VAR(c_name, 0)
Elliott Hughes787ec202012-03-29 17:14:15 -0700121END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -0700122
Elliott Hughes787ec202012-03-29 17:14:15 -0700123MACRO2(TWO_ARG_RUNTIME_EXCEPTION, c_name, cxx_name)
Ian Rogersaeeada42013-02-13 11:28:34 -0800124 DEFINE_FUNCTION VAR(c_name, 0)
Ian Rogers57b86d42012-03-27 16:05:41 -0700125 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context
126 mov %esp, %edx
127 // Outgoing argument set up
Ian Rogersaeeada42013-02-13 11:28:34 -0800128 PUSH edx // pass SP
Ian Rogers57b86d42012-03-27 16:05:41 -0700129 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800130 .cfi_adjust_cfa_offset 4
131 PUSH ecx // pass arg2
132 PUSH eax // pass arg1
Ian Rogers7caad772012-03-30 01:07:54 -0700133 call VAR(cxx_name, 1) // cxx_name(arg1, arg2, Thread*, SP)
Ian Rogers57b86d42012-03-27 16:05:41 -0700134 int3 // unreached
Ian Rogersaeeada42013-02-13 11:28:34 -0800135 END_FUNCTION VAR(c_name, 0)
Elliott Hughes787ec202012-03-29 17:14:15 -0700136END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -0700137
138 /*
139 * Called by managed code to create and deliver a NullPointerException.
140 */
Ian Rogers468532e2013-08-05 10:56:33 -0700141NO_ARG_RUNTIME_EXCEPTION art_quick_throw_null_pointer_exception, artThrowNullPointerExceptionFromCode
Ian Rogers57b86d42012-03-27 16:05:41 -0700142
143 /*
144 * Called by managed code to create and deliver an ArithmeticException.
145 */
Ian Rogers468532e2013-08-05 10:56:33 -0700146NO_ARG_RUNTIME_EXCEPTION art_quick_throw_div_zero, artThrowDivZeroFromCode
Ian Rogers57b86d42012-03-27 16:05:41 -0700147
148 /*
Ian Rogers57b86d42012-03-27 16:05:41 -0700149 * Called by managed code to create and deliver a StackOverflowError.
150 */
Ian Rogers468532e2013-08-05 10:56:33 -0700151NO_ARG_RUNTIME_EXCEPTION art_quick_throw_stack_overflow, artThrowStackOverflowFromCode
Ian Rogers57b86d42012-03-27 16:05:41 -0700152
153 /*
Elliott Hughes787ec202012-03-29 17:14:15 -0700154 * Called by managed code, saves callee saves and then calls artThrowException
155 * that will place a mock Method* at the bottom of the stack. Arg1 holds the exception.
156 */
Ian Rogers468532e2013-08-05 10:56:33 -0700157ONE_ARG_RUNTIME_EXCEPTION art_quick_deliver_exception, artDeliverExceptionFromCode
Elliott Hughes787ec202012-03-29 17:14:15 -0700158
159 /*
Ian Rogers57b86d42012-03-27 16:05:41 -0700160 * Called by managed code to create and deliver a NoSuchMethodError.
161 */
Ian Rogers468532e2013-08-05 10:56:33 -0700162ONE_ARG_RUNTIME_EXCEPTION art_quick_throw_no_such_method, artThrowNoSuchMethodFromCode
Ian Rogers57b86d42012-03-27 16:05:41 -0700163
164 /*
Elliott Hughes787ec202012-03-29 17:14:15 -0700165 * Called by managed code to create and deliver an ArrayIndexOutOfBoundsException. Arg1 holds
166 * index, arg2 holds limit.
167 */
Ian Rogers468532e2013-08-05 10:56:33 -0700168TWO_ARG_RUNTIME_EXCEPTION art_quick_throw_array_bounds, artThrowArrayBoundsFromCode
Elliott Hughes787ec202012-03-29 17:14:15 -0700169
170 /*
Ian Rogers57b86d42012-03-27 16:05:41 -0700171 * All generated callsites for interface invokes and invocation slow paths will load arguments
172 * as usual - except instead of loading arg0/r0 with the target Method*, arg0/r0 will contain
173 * the method_idx. This wrapper will save arg1-arg3, load the caller's Method*, align the
174 * stack and call the appropriate C helper.
175 * NOTE: "this" is first visible argument of the target, and so can be found in arg1/r1.
176 *
177 * The helper will attempt to locate the target and return a 64-bit result in r0/r1 consisting
178 * of the target Method* in r0 and method->code_ in r1.
179 *
180 * If unsuccessful, the helper will return NULL/NULL. There will bea pending exception in the
181 * thread and we branch to another stub to deliver it.
182 *
183 * On success this wrapper will restore arguments and *jump* to the target, leaving the lr
184 * pointing back to the original caller.
185 */
Elliott Hughes787ec202012-03-29 17:14:15 -0700186MACRO2(INVOKE_TRAMPOLINE, c_name, cxx_name)
Ian Rogersaeeada42013-02-13 11:28:34 -0800187 DEFINE_FUNCTION VAR(c_name, 0)
Ian Rogers7caad772012-03-30 01:07:54 -0700188 // Set up the callee save frame to conform with Runtime::CreateCalleeSaveMethod(kRefsAndArgs)
189 // return address
Ian Rogersaeeada42013-02-13 11:28:34 -0800190 PUSH edi
191 PUSH esi
192 PUSH ebp
193 PUSH ebx
194 PUSH edx
195 PUSH ecx
196 PUSH eax // <-- callee save Method* to go here
Ian Rogers7caad772012-03-30 01:07:54 -0700197 movl %esp, %edx // remember SP
198 // Outgoing argument set up
Elliott Hughesea944212012-04-05 13:11:53 -0700199 subl MACRO_LITERAL(12), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800200 .cfi_adjust_cfa_offset 12
201 PUSH edx // pass SP
Ian Rogers7caad772012-03-30 01:07:54 -0700202 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800203 .cfi_adjust_cfa_offset 4
Ian Rogers7caad772012-03-30 01:07:54 -0700204 pushl 32(%edx) // pass caller Method*
Ian Rogersaeeada42013-02-13 11:28:34 -0800205 .cfi_adjust_cfa_offset 4
206 PUSH ecx // pass arg2
207 PUSH eax // pass arg1
Ian Rogers7caad772012-03-30 01:07:54 -0700208 call VAR(cxx_name, 1) // cxx_name(arg1, arg2, arg3, Thread*, SP)
209 movl %edx, %edi // save code pointer in EDI
Elliott Hughesea944212012-04-05 13:11:53 -0700210 addl MACRO_LITERAL(36), %esp // Pop arguments skip eax
Ian Rogersaeeada42013-02-13 11:28:34 -0800211 .cfi_adjust_cfa_offset -36
212 POP ecx // Restore args
213 POP edx
214 POP ebx
215 POP ebp // Restore callee saves.
216 POP esi
Ian Rogers7caad772012-03-30 01:07:54 -0700217 // Swap EDI callee save with code pointer.
218 xchgl %edi, (%esp)
219 testl %eax, %eax // Branch forward if exception pending.
220 jz 1f
221 // Tail call to intended method.
222 ret
2231:
jeffhao20b5c6c2012-05-21 14:15:18 -0700224 addl MACRO_LITERAL(4), %esp // Pop code pointer off stack
Ian Rogers5793fea2013-02-14 13:33:34 -0800225 .cfi_adjust_cfa_offset -4
Ian Rogers7caad772012-03-30 01:07:54 -0700226 DELIVER_PENDING_EXCEPTION
Ian Rogersaeeada42013-02-13 11:28:34 -0800227 END_FUNCTION VAR(c_name, 0)
Elliott Hughes787ec202012-03-29 17:14:15 -0700228END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -0700229
Logan Chien8dbb7082013-01-25 20:31:17 +0800230INVOKE_TRAMPOLINE art_quick_invoke_interface_trampoline, artInvokeInterfaceTrampoline
231INVOKE_TRAMPOLINE art_quick_invoke_interface_trampoline_with_access_check, artInvokeInterfaceTrampolineWithAccessCheck
Ian Rogers57b86d42012-03-27 16:05:41 -0700232
Logan Chien8dbb7082013-01-25 20:31:17 +0800233INVOKE_TRAMPOLINE art_quick_invoke_static_trampoline_with_access_check, artInvokeStaticTrampolineWithAccessCheck
234INVOKE_TRAMPOLINE art_quick_invoke_direct_trampoline_with_access_check, artInvokeDirectTrampolineWithAccessCheck
235INVOKE_TRAMPOLINE art_quick_invoke_super_trampoline_with_access_check, artInvokeSuperTrampolineWithAccessCheck
236INVOKE_TRAMPOLINE art_quick_invoke_virtual_trampoline_with_access_check, artInvokeVirtualTrampolineWithAccessCheck
Ian Rogers57b86d42012-03-27 16:05:41 -0700237
Jeff Hao5d917302013-02-27 17:57:33 -0800238 /*
Jeff Hao6474d192013-03-26 14:08:09 -0700239 * Quick invocation stub.
240 * On entry:
241 * [sp] = return address
242 * [sp + 4] = method pointer
243 * [sp + 8] = argument array or NULL for no argument methods
244 * [sp + 12] = size of argument array in bytes
245 * [sp + 16] = (managed) thread pointer
246 * [sp + 20] = JValue* result
247 * [sp + 24] = result type char
Jeff Hao5d917302013-02-27 17:57:33 -0800248 */
249DEFINE_FUNCTION art_quick_invoke_stub
250 PUSH ebp // save ebp
251 PUSH ebx // save ebx
252 mov %esp, %ebp // copy value of stack pointer into base pointer
253 .cfi_def_cfa_register ebp
254 mov 20(%ebp), %ebx // get arg array size
255 addl LITERAL(28), %ebx // reserve space for return addr, method*, ebx, and ebp in frame
Jeff Hao6474d192013-03-26 14:08:09 -0700256 andl LITERAL(0xFFFFFFF0), %ebx // align frame size to 16 bytes
Jeff Hao5d917302013-02-27 17:57:33 -0800257 subl LITERAL(12), %ebx // remove space for return address, ebx, and ebp
258 subl %ebx, %esp // reserve stack space for argument array
259 lea 4(%esp), %eax // use stack pointer + method ptr as dest for memcpy
260 pushl 20(%ebp) // push size of region to memcpy
261 pushl 16(%ebp) // push arg array as source of memcpy
262 pushl %eax // push stack pointer as destination of memcpy
263 call SYMBOL(memcpy) // (void*, const void*, size_t)
264 addl LITERAL(12), %esp // pop arguments to memcpy
265 movl LITERAL(0), (%esp) // store NULL for method*
266 mov 12(%ebp), %eax // move method pointer into eax
267 mov 4(%esp), %ecx // copy arg1 into ecx
268 mov 8(%esp), %edx // copy arg2 into edx
269 mov 12(%esp), %ebx // copy arg3 into ebx
Ian Rogers225ade22013-03-18 17:45:44 -0700270 call *METHOD_CODE_OFFSET(%eax) // call the method
Jeff Hao5d917302013-02-27 17:57:33 -0800271 mov %ebp, %esp // restore stack pointer
272 POP ebx // pop ebx
273 POP ebp // pop ebp
274 mov 20(%esp), %ecx // get result pointer
Jeff Hao6474d192013-03-26 14:08:09 -0700275 cmpl LITERAL(68), 24(%esp) // test if result type char == 'D'
276 je return_double_quick
277 cmpl LITERAL(70), 24(%esp) // test if result type char == 'F'
278 je return_float_quick
Jeff Hao5d917302013-02-27 17:57:33 -0800279 mov %eax, (%ecx) // store the result
280 mov %edx, 4(%ecx) // store the other half of the result
Jeff Hao6474d192013-03-26 14:08:09 -0700281 ret
282return_double_quick:
283return_float_quick:
Jeff Hao5d917302013-02-27 17:57:33 -0800284 movsd %xmm0, (%ecx) // store the floating point result
285 ret
286END_FUNCTION art_quick_invoke_stub
287
Ian Rogersd36c52e2012-04-09 16:29:25 -0700288MACRO3(NO_ARG_DOWNCALL, c_name, cxx_name, return_macro)
Ian Rogersaeeada42013-02-13 11:28:34 -0800289 DEFINE_FUNCTION VAR(c_name, 0)
Ian Rogersd36c52e2012-04-09 16:29:25 -0700290 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
291 mov %esp, %edx // remember SP
292 // Outgoing argument set up
293 subl MACRO_LITERAL(8), %esp // push padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800294 .cfi_adjust_cfa_offset 8
295 PUSH edx // pass SP
Ian Rogersd36c52e2012-04-09 16:29:25 -0700296 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800297 .cfi_adjust_cfa_offset 4
Ian Rogersd36c52e2012-04-09 16:29:25 -0700298 call VAR(cxx_name, 1) // cxx_name(Thread*, SP)
299 addl MACRO_LITERAL(16), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800300 .cfi_adjust_cfa_offset -16
Ian Rogersd36c52e2012-04-09 16:29:25 -0700301 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
Elliott Hughes754caaa2012-04-10 10:57:36 -0700302 CALL_MACRO(return_macro, 2) // return or deliver exception
Ian Rogersaeeada42013-02-13 11:28:34 -0800303 END_FUNCTION VAR(c_name, 0)
Ian Rogersd36c52e2012-04-09 16:29:25 -0700304END_MACRO
305
306MACRO3(ONE_ARG_DOWNCALL, c_name, cxx_name, return_macro)
Ian Rogersaeeada42013-02-13 11:28:34 -0800307 DEFINE_FUNCTION VAR(c_name, 0)
Ian Rogersd36c52e2012-04-09 16:29:25 -0700308 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
309 mov %esp, %edx // remember SP
310 // Outgoing argument set up
Ian Rogersaeeada42013-02-13 11:28:34 -0800311 PUSH eax // push padding
312 PUSH edx // pass SP
Ian Rogersd36c52e2012-04-09 16:29:25 -0700313 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800314 .cfi_adjust_cfa_offset 4
315 PUSH eax // pass arg1
Ian Rogersd36c52e2012-04-09 16:29:25 -0700316 call VAR(cxx_name, 1) // cxx_name(arg1, Thread*, SP)
317 addl MACRO_LITERAL(16), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800318 .cfi_adjust_cfa_offset -16
Ian Rogersd36c52e2012-04-09 16:29:25 -0700319 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
Elliott Hughes754caaa2012-04-10 10:57:36 -0700320 CALL_MACRO(return_macro, 2) // return or deliver exception
Ian Rogersaeeada42013-02-13 11:28:34 -0800321 END_FUNCTION VAR(c_name, 0)
Ian Rogersd36c52e2012-04-09 16:29:25 -0700322END_MACRO
323
324MACRO3(TWO_ARG_DOWNCALL, c_name, cxx_name, return_macro)
Ian Rogersaeeada42013-02-13 11:28:34 -0800325 DEFINE_FUNCTION VAR(c_name, 0)
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
Ian Rogersaeeada42013-02-13 11:28:34 -0800329 PUSH edx // pass SP
Ian Rogers7caad772012-03-30 01:07:54 -0700330 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800331 .cfi_adjust_cfa_offset 4
332 PUSH ecx // pass arg2
333 PUSH eax // pass arg1
Ian Rogersd36c52e2012-04-09 16:29:25 -0700334 call VAR(cxx_name, 1) // cxx_name(arg1, arg2, Thread*, SP)
Elliott Hughesea944212012-04-05 13:11:53 -0700335 addl MACRO_LITERAL(16), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800336 .cfi_adjust_cfa_offset -16
Ian Rogers7caad772012-03-30 01:07:54 -0700337 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
Elliott Hughes754caaa2012-04-10 10:57:36 -0700338 CALL_MACRO(return_macro, 2) // return or deliver exception
Ian Rogersaeeada42013-02-13 11:28:34 -0800339 END_FUNCTION VAR(c_name, 0)
Ian Rogers7caad772012-03-30 01:07:54 -0700340END_MACRO
341
Ian Rogersd36c52e2012-04-09 16:29:25 -0700342MACRO3(THREE_ARG_DOWNCALL, c_name, cxx_name, return_macro)
Ian Rogersaeeada42013-02-13 11:28:34 -0800343 DEFINE_FUNCTION VAR(c_name, 0)
Ian Rogers7caad772012-03-30 01:07:54 -0700344 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
345 mov %esp, %ebx // remember SP
346 // Outgoing argument set up
Elliott Hughesea944212012-04-05 13:11:53 -0700347 subl MACRO_LITERAL(12), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800348 .cfi_adjust_cfa_offset 12
349 PUSH ebx // pass SP
Ian Rogers7caad772012-03-30 01:07:54 -0700350 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800351 .cfi_adjust_cfa_offset 4
352 PUSH edx // pass arg3
353 PUSH ecx // pass arg2
354 PUSH eax // pass arg1
Ian Rogersd36c52e2012-04-09 16:29:25 -0700355 call VAR(cxx_name, 1) // cxx_name(arg1, arg2, arg3, Thread*, SP)
Elliott Hughesea944212012-04-05 13:11:53 -0700356 addl MACRO_LITERAL(32), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800357 .cfi_adjust_cfa_offset -32
Ian Rogers7caad772012-03-30 01:07:54 -0700358 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
Elliott Hughes754caaa2012-04-10 10:57:36 -0700359 CALL_MACRO(return_macro, 2) // return or deliver exception
Ian Rogersaeeada42013-02-13 11:28:34 -0800360 END_FUNCTION VAR(c_name, 0)
Ian Rogersd36c52e2012-04-09 16:29:25 -0700361END_MACRO
362
363MACRO0(RETURN_IF_EAX_NOT_ZERO)
Ian Rogers7caad772012-03-30 01:07:54 -0700364 testl %eax, %eax // eax == 0 ?
Ian Rogersd36c52e2012-04-09 16:29:25 -0700365 jz 1f // if eax == 0 goto 1
366 ret // return
3671: // deliver exception on current thread
Ian Rogers7caad772012-03-30 01:07:54 -0700368 DELIVER_PENDING_EXCEPTION
369END_MACRO
370
Ian Rogersd36c52e2012-04-09 16:29:25 -0700371MACRO0(RETURN_IF_EAX_ZERO)
372 testl %eax, %eax // eax == 0 ?
373 jnz 1f // if eax != 0 goto 1
374 ret // return
3751: // deliver exception on current thread
Ian Rogers7caad772012-03-30 01:07:54 -0700376 DELIVER_PENDING_EXCEPTION
Ian Rogersd36c52e2012-04-09 16:29:25 -0700377END_MACRO
Ian Rogers7caad772012-03-30 01:07:54 -0700378
jeffhaod66a8752012-05-22 15:30:16 -0700379MACRO0(RETURN_OR_DELIVER_PENDING_EXCEPTION)
380 mov %fs:THREAD_EXCEPTION_OFFSET, %ebx // get exception field
381 testl %ebx, %ebx // ebx == 0 ?
382 jnz 1f // if ebx != 0 goto 1
383 ret // return
3841: // deliver exception on current thread
385 DELIVER_PENDING_EXCEPTION
386END_MACRO
387
Ian Rogers468532e2013-08-05 10:56:33 -0700388TWO_ARG_DOWNCALL art_quick_alloc_object, artAllocObjectFromCode, RETURN_IF_EAX_NOT_ZERO
389TWO_ARG_DOWNCALL art_quick_alloc_object_with_access_check, artAllocObjectFromCodeWithAccessCheck, RETURN_IF_EAX_NOT_ZERO
390THREE_ARG_DOWNCALL art_quick_alloc_array, artAllocArrayFromCode, RETURN_IF_EAX_NOT_ZERO
391THREE_ARG_DOWNCALL art_quick_alloc_array_with_access_check, artAllocArrayFromCodeWithAccessCheck, RETURN_IF_EAX_NOT_ZERO
392THREE_ARG_DOWNCALL art_quick_check_and_alloc_array, artCheckAndAllocArrayFromCode, RETURN_IF_EAX_NOT_ZERO
393THREE_ARG_DOWNCALL art_quick_check_and_alloc_array_with_access_check, artCheckAndAllocArrayFromCodeWithAccessCheck, RETURN_IF_EAX_NOT_ZERO
Ian Rogersd36c52e2012-04-09 16:29:25 -0700394
Hiroshi Yamauchi3b4c1892013-09-12 21:33:12 -0700395TWO_ARG_DOWNCALL art_quick_alloc_object_instrumented, artAllocObjectFromCodeInstrumented, RETURN_IF_EAX_NOT_ZERO
396TWO_ARG_DOWNCALL art_quick_alloc_object_with_access_check_instrumented, artAllocObjectFromCodeWithAccessCheckInstrumented, RETURN_IF_EAX_NOT_ZERO
397THREE_ARG_DOWNCALL art_quick_alloc_array_instrumented, artAllocArrayFromCodeInstrumented, RETURN_IF_EAX_NOT_ZERO
398THREE_ARG_DOWNCALL art_quick_alloc_array_with_access_check_instrumented, artAllocArrayFromCodeWithAccessCheckInstrumented, RETURN_IF_EAX_NOT_ZERO
399THREE_ARG_DOWNCALL art_quick_check_and_alloc_array_instrumented, artCheckAndAllocArrayFromCodeInstrumented, RETURN_IF_EAX_NOT_ZERO
400THREE_ARG_DOWNCALL art_quick_check_and_alloc_array_with_access_check_instrumented, artCheckAndAllocArrayFromCodeWithAccessCheckInstrumented, RETURN_IF_EAX_NOT_ZERO
401
Ian Rogers468532e2013-08-05 10:56:33 -0700402TWO_ARG_DOWNCALL art_quick_resolve_string, artResolveStringFromCode, RETURN_IF_EAX_NOT_ZERO
403TWO_ARG_DOWNCALL art_quick_initialize_static_storage, artInitializeStaticStorageFromCode, RETURN_IF_EAX_NOT_ZERO
404TWO_ARG_DOWNCALL art_quick_initialize_type, artInitializeTypeFromCode, RETURN_IF_EAX_NOT_ZERO
405TWO_ARG_DOWNCALL art_quick_initialize_type_and_verify_access, artInitializeTypeAndVerifyAccessFromCode, RETURN_IF_EAX_NOT_ZERO
Ian Rogersd36c52e2012-04-09 16:29:25 -0700406
Ian Rogers468532e2013-08-05 10:56:33 -0700407TWO_ARG_DOWNCALL art_quick_handle_fill_data, artHandleFillArrayDataFromCode, RETURN_IF_EAX_ZERO
Ian Rogers7caad772012-03-30 01:07:54 -0700408
Ian Rogersd9c4fc92013-10-01 19:45:43 -0700409DEFINE_FUNCTION art_quick_lock_object
410 testl %eax, %eax // null check object/eax
411 jz slow_lock
412retry_lock:
413 movl LOCK_WORD_OFFSET(%eax), %ecx // ecx := lock word
414 movl %fs:THREAD_ID_OFFSET, %edx // edx := thread id
415 test %ecx, %ecx
416 jb slow_lock // lock word contains a monitor
417 jnz already_thin // lock word contains a thin lock
418 // unlocked case - %edx holds thread id with count of 0
419 movl %eax, %ecx // remember object in case of retry
420 xor %eax, %eax // eax == 0 for comparison with lock word in cmpxchg
421 lock cmpxchg %edx, LOCK_WORD_OFFSET(%ecx)
422 jnz cmpxchg_fail // cmpxchg failed retry
423 ret
424cmpxchg_fail:
425 movl %ecx, %eax // restore eax
426 jmp retry_lock
427already_thin:
428 cmpw %ax, %dx // do we hold the lock already?
429 jne slow_lock
430 addl LITERAL(65536), %eax // increment recursion count
431 jb slow_lock // count overflowed so go slow
432 movl %eax, LOCK_WORD_OFFSET(%ecx) // update lockword, cmpxchg not necessary as we hold lock
433 ret
434slow_lock:
435 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
436 mov %esp, %edx // remember SP
437 // Outgoing argument set up
438 PUSH eax // push padding
439 PUSH edx // pass SP
440 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
441 .cfi_adjust_cfa_offset 4
442 PUSH eax // pass object
443 call artLockObjectFromCode // artLockObjectFromCode(object, Thread*, SP)
444 addl MACRO_LITERAL(16), %esp // pop arguments
445 .cfi_adjust_cfa_offset -16
446 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
447 RETURN_IF_EAX_ZERO
448END_FUNCTION art_quick_lock_object
449
450DEFINE_FUNCTION art_quick_unlock_object
451 testl %eax, %eax // null check object/eax
452 jz slow_unlock
453 movl LOCK_WORD_OFFSET(%eax), %ecx // ecx := lock word
454 movl %fs:THREAD_ID_OFFSET, %edx // edx := thread id
455 test %ecx, %ecx
456 jb slow_unlock // lock word contains a monitor
457 cmpw %cx, %dx // does the thread id match?
458 jne slow_unlock
459 cmpl LITERAL(65536), %ecx
460 jae recursive_thin_unlock
461 movl LITERAL(0), LOCK_WORD_OFFSET(%eax)
462 ret
463recursive_thin_unlock:
464 subl LITERAL(65536), %ecx
465 mov %ecx, LOCK_WORD_OFFSET(%eax)
466 ret
467slow_unlock:
468 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
469 mov %esp, %edx // remember SP
470 // Outgoing argument set up
471 PUSH eax // push padding
472 PUSH edx // pass SP
473 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
474 .cfi_adjust_cfa_offset 4
475 PUSH eax // pass object
476 call artUnlockObjectFromCode // artUnlockObjectFromCode(object, Thread*, SP)
477 addl MACRO_LITERAL(16), %esp // pop arguments
478 .cfi_adjust_cfa_offset -16
479 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
480 RETURN_IF_EAX_ZERO
481END_FUNCTION art_quick_unlock_object
482
Ian Rogers468532e2013-08-05 10:56:33 -0700483DEFINE_FUNCTION art_quick_is_assignable
Ian Rogersaeeada42013-02-13 11:28:34 -0800484 PUSH eax // alignment padding
Ian Rogersa9a82542013-10-04 11:17:26 -0700485 PUSH ecx // pass arg2 - obj->klass
486 PUSH eax // pass arg1 - checked class
487 call SYMBOL(artIsAssignableFromCode) // (Class* klass, Class* ref_klass)
Ian Rogers55bd45f2012-04-04 17:31:20 -0700488 addl LITERAL(12), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800489 .cfi_adjust_cfa_offset -12
Ian Rogers7caad772012-03-30 01:07:54 -0700490 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700491END_FUNCTION art_quick_is_assignable
Ian Rogers7caad772012-03-30 01:07:54 -0700492
Ian Rogersa9a82542013-10-04 11:17:26 -0700493DEFINE_FUNCTION art_quick_check_cast
494 PUSH eax // alignment padding
495 PUSH ecx // pass arg2 - obj->klass
496 PUSH eax // pass arg1 - checked class
497 call SYMBOL(artIsAssignableFromCode) // (Class* klass, Class* ref_klass)
498 testl %eax, %eax
499 jz 1f // jump forward if not assignable
500 addl LITERAL(12), %esp // pop arguments
501 .cfi_adjust_cfa_offset -12
502 ret
5031:
504 POP eax // pop arguments
505 POP ecx
506 addl LITERAL(4), %esp
507 .cfi_adjust_cfa_offset -12
508 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context
509 mov %esp, %edx
510 // Outgoing argument set up
511 PUSH edx // pass SP
512 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
513 .cfi_adjust_cfa_offset 4
514 PUSH ecx // pass arg2
515 PUSH eax // pass arg1
516 call SYMBOL(artThrowClassCastException) // (Class* a, Class* b, Thread*, SP)
517 int3 // unreached
518END_FUNCTION art_quick_check_cast
519
520 /*
521 * Entry from managed code for array put operations of objects where the value being stored
522 * needs to be checked for compatibility.
523 * eax = array, ecx = index, edx = value
524 */
525DEFINE_FUNCTION art_quick_aput_obj_with_null_and_bound_check
526 testl %eax, %eax
527 jnz art_quick_aput_obj_with_bound_check
528 jmp art_quick_throw_null_pointer_exception
529END_FUNCTION art_quick_aput_obj_with_null_and_bound_check
530
531DEFINE_FUNCTION art_quick_aput_obj_with_bound_check
532 movl ARRAY_LENGTH_OFFSET(%eax), %ebx
533 cmpl %ebx, %ecx
534 jb art_quick_aput_obj
535 mov %ecx, %eax
536 mov %ebx, %ecx
537 jmp art_quick_throw_array_bounds
538END_FUNCTION art_quick_aput_obj_with_bound_check
539
540DEFINE_FUNCTION art_quick_aput_obj
541 test %edx, %edx // store of null
542 jz do_aput_null
543 movl CLASS_OFFSET(%eax), %ebx
544 movl CLASS_COMPONENT_TYPE_OFFSET(%ebx), %ebx
545 cmpl CLASS_OFFSET(%edx), %ebx // value's type == array's component type - trivial assignability
546 jne check_assignability
547do_aput:
548 movl %edx, OBJECT_ARRAY_DATA_OFFSET(%eax, %ecx, 4)
549 movl %fs:THREAD_CARD_TABLE_OFFSET, %edx
550 shrl LITERAL(7), %eax
551 movb %dl, (%edx, %eax)
552 ret
553do_aput_null:
554 movl %edx, OBJECT_ARRAY_DATA_OFFSET(%eax, %ecx, 4)
555 ret
556check_assignability:
557 PUSH eax // save arguments
558 PUSH ecx
559 PUSH edx
560 subl LITERAL(8), %esp // alignment padding
561 .cfi_adjust_cfa_offset 8
562 pushl CLASS_OFFSET(%edx) // pass arg2 - type of the value to be stored
563 .cfi_adjust_cfa_offset 4
564 PUSH ebx // pass arg1 - component type of the array
565 call SYMBOL(artIsAssignableFromCode) // (Class* a, Class* b)
566 addl LITERAL(16), %esp // pop arguments
567 .cfi_adjust_cfa_offset -16
568 testl %eax, %eax
569 jz throw_array_store_exception
570 POP edx
571 POP ecx
572 POP eax
573 movl %edx, OBJECT_ARRAY_DATA_OFFSET(%eax, %ecx, 4) // do the aput
574 movl %fs:THREAD_CARD_TABLE_OFFSET, %edx
575 shrl LITERAL(7), %eax
576 movb %dl, (%edx, %eax)
577 ret
578throw_array_store_exception:
579 POP edx
580 POP ecx
581 POP eax
582 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context
583 mov %esp, %ecx
584 // Outgoing argument set up
585 PUSH ecx // pass SP
586 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
587 .cfi_adjust_cfa_offset 4
588 PUSH edx // pass arg2 - value
589 PUSH eax // pass arg1 - array
590 call SYMBOL(artThrowArrayStoreException) // (array, value, Thread*, SP)
591 int3 // unreached
592END_FUNCTION art_quick_aput_obj
593
Logan Chien8dbb7082013-01-25 20:31:17 +0800594DEFINE_FUNCTION art_quick_memcpy
Ian Rogersaeeada42013-02-13 11:28:34 -0800595 PUSH edx // pass arg3
596 PUSH ecx // pass arg2
597 PUSH eax // pass arg1
Elliott Hughesadc078a2012-04-04 11:39:05 -0700598 call SYMBOL(memcpy) // (void*, const void*, size_t)
Ian Rogers55bd45f2012-04-04 17:31:20 -0700599 addl LITERAL(12), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800600 .cfi_adjust_cfa_offset -12
Ian Rogers7caad772012-03-30 01:07:54 -0700601 ret
Ian Rogersaeeada42013-02-13 11:28:34 -0800602END_FUNCTION art_quick_memcpy
Ian Rogers7caad772012-03-30 01:07:54 -0700603
Logan Chien8dbb7082013-01-25 20:31:17 +0800604NO_ARG_DOWNCALL art_quick_test_suspend, artTestSuspendFromCode, ret
Ian Rogers7caad772012-03-30 01:07:54 -0700605
Ian Rogers468532e2013-08-05 10:56:33 -0700606DEFINE_FUNCTION art_quick_fmod
jeffhao1395b1e2012-06-13 18:05:13 -0700607 subl LITERAL(12), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800608 .cfi_adjust_cfa_offset 12
609 PUSH ebx // pass arg4 b.hi
610 PUSH edx // pass arg3 b.lo
611 PUSH ecx // pass arg2 a.hi
612 PUSH eax // pass arg1 a.lo
jeffhao1395b1e2012-06-13 18:05:13 -0700613 call SYMBOL(fmod) // (jdouble a, jdouble b)
614 fstpl (%esp) // pop return value off fp stack
615 movsd (%esp), %xmm0 // place into %xmm0
616 addl LITERAL(28), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800617 .cfi_adjust_cfa_offset -28
jeffhao292188d2012-05-17 15:45:04 -0700618 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700619END_FUNCTION art_quick_fmod
jeffhao292188d2012-05-17 15:45:04 -0700620
Ian Rogers468532e2013-08-05 10:56:33 -0700621DEFINE_FUNCTION art_quick_fmodf
Ian Rogersaeeada42013-02-13 11:28:34 -0800622 PUSH eax // alignment padding
623 PUSH ecx // pass arg2 b
624 PUSH eax // pass arg1 a
jeffhao1395b1e2012-06-13 18:05:13 -0700625 call SYMBOL(fmodf) // (jfloat a, jfloat b)
Ian Rogers1b09b092012-08-20 15:35:52 -0700626 fstps (%esp) // pop return value off fp stack
jeffhao1395b1e2012-06-13 18:05:13 -0700627 movss (%esp), %xmm0 // place into %xmm0
628 addl LITERAL(12), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800629 .cfi_adjust_cfa_offset -12
jeffhao292188d2012-05-17 15:45:04 -0700630 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700631END_FUNCTION art_quick_fmodf
jeffhao292188d2012-05-17 15:45:04 -0700632
Ian Rogers468532e2013-08-05 10:56:33 -0700633DEFINE_FUNCTION art_quick_l2d
Ian Rogers5793fea2013-02-14 13:33:34 -0800634 PUSH ecx // push arg2 a.hi
635 PUSH eax // push arg1 a.lo
636 fildll (%esp) // load as integer and push into st0
637 fstpl (%esp) // pop value off fp stack as double
jeffhao41005dd2012-05-09 17:58:52 -0700638 movsd (%esp), %xmm0 // place into %xmm0
Ian Rogers5793fea2013-02-14 13:33:34 -0800639 addl LITERAL(8), %esp // pop arguments
640 .cfi_adjust_cfa_offset -8
jeffhao41005dd2012-05-09 17:58:52 -0700641 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700642END_FUNCTION art_quick_l2d
jeffhao41005dd2012-05-09 17:58:52 -0700643
Ian Rogers468532e2013-08-05 10:56:33 -0700644DEFINE_FUNCTION art_quick_l2f
Ian Rogers5793fea2013-02-14 13:33:34 -0800645 PUSH ecx // push arg2 a.hi
646 PUSH eax // push arg1 a.lo
647 fildll (%esp) // load as integer and push into st0
648 fstps (%esp) // pop value off fp stack as a single
jeffhao41005dd2012-05-09 17:58:52 -0700649 movss (%esp), %xmm0 // place into %xmm0
Ian Rogers5793fea2013-02-14 13:33:34 -0800650 addl LITERAL(8), %esp // pop argument
651 .cfi_adjust_cfa_offset -8
jeffhao41005dd2012-05-09 17:58:52 -0700652 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700653END_FUNCTION art_quick_l2f
jeffhao41005dd2012-05-09 17:58:52 -0700654
Ian Rogers468532e2013-08-05 10:56:33 -0700655DEFINE_FUNCTION art_quick_d2l
Ian Rogersaeeada42013-02-13 11:28:34 -0800656 PUSH eax // alignment padding
657 PUSH ecx // pass arg2 a.hi
658 PUSH eax // pass arg1 a.lo
jeffhao1395b1e2012-06-13 18:05:13 -0700659 call SYMBOL(art_d2l) // (jdouble a)
jeffhao41005dd2012-05-09 17:58:52 -0700660 addl LITERAL(12), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800661 .cfi_adjust_cfa_offset -12
jeffhao41005dd2012-05-09 17:58:52 -0700662 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700663END_FUNCTION art_quick_d2l
jeffhao41005dd2012-05-09 17:58:52 -0700664
Ian Rogers468532e2013-08-05 10:56:33 -0700665DEFINE_FUNCTION art_quick_f2l
jeffhao41005dd2012-05-09 17:58:52 -0700666 subl LITERAL(8), %esp // alignment padding
Ian Rogers5793fea2013-02-14 13:33:34 -0800667 .cfi_adjust_cfa_offset 8
Ian Rogersaeeada42013-02-13 11:28:34 -0800668 PUSH eax // pass arg1 a
jeffhao1395b1e2012-06-13 18:05:13 -0700669 call SYMBOL(art_f2l) // (jfloat a)
jeffhao41005dd2012-05-09 17:58:52 -0700670 addl LITERAL(12), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800671 .cfi_adjust_cfa_offset -12
jeffhao41005dd2012-05-09 17:58:52 -0700672 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700673END_FUNCTION art_quick_f2l
jeffhao41005dd2012-05-09 17:58:52 -0700674
Ian Rogers468532e2013-08-05 10:56:33 -0700675DEFINE_FUNCTION art_quick_idivmod
jeffhao174651d2012-04-19 15:27:22 -0700676 cmpl LITERAL(0x80000000), %eax
677 je check_arg2 // special case
678args_ok:
Ian Rogers7caad772012-03-30 01:07:54 -0700679 cdq // edx:eax = sign extend eax
680 idiv %ecx // (edx,eax) = (edx:eax % ecx, edx:eax / ecx)
Ian Rogers7caad772012-03-30 01:07:54 -0700681 ret
jeffhao174651d2012-04-19 15:27:22 -0700682check_arg2:
683 cmpl LITERAL(-1), %ecx
684 jne args_ok
685 xorl %edx, %edx
686 ret // eax already holds min int
Ian Rogers468532e2013-08-05 10:56:33 -0700687END_FUNCTION art_quick_idivmod
Ian Rogers7caad772012-03-30 01:07:54 -0700688
Ian Rogers468532e2013-08-05 10:56:33 -0700689DEFINE_FUNCTION art_quick_ldiv
Ian Rogersa9a82542013-10-04 11:17:26 -0700690 subl LITERAL(12), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800691 .cfi_adjust_cfa_offset 12
692 PUSH ebx // pass arg4 b.hi
693 PUSH edx // pass arg3 b.lo
694 PUSH ecx // pass arg2 a.hi
Ian Rogersa9a82542013-10-04 11:17:26 -0700695 PUSH eax // pass arg1 a.lo
696 call SYMBOL(artLdiv) // (jlong a, jlong b)
697 addl LITERAL(28), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800698 .cfi_adjust_cfa_offset -28
Ian Rogers55bd45f2012-04-04 17:31:20 -0700699 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700700END_FUNCTION art_quick_ldiv
Ian Rogers55bd45f2012-04-04 17:31:20 -0700701
Ian Rogersa9a82542013-10-04 11:17:26 -0700702DEFINE_FUNCTION art_quick_lmod
703 subl LITERAL(12), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800704 .cfi_adjust_cfa_offset 12
705 PUSH ebx // pass arg4 b.hi
706 PUSH edx // pass arg3 b.lo
707 PUSH ecx // pass arg2 a.hi
Ian Rogersa9a82542013-10-04 11:17:26 -0700708 PUSH eax // pass arg1 a.lo
709 call SYMBOL(artLmod) // (jlong a, jlong b)
710 addl LITERAL(28), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800711 .cfi_adjust_cfa_offset -28
Ian Rogers55bd45f2012-04-04 17:31:20 -0700712 ret
Ian Rogersa9a82542013-10-04 11:17:26 -0700713END_FUNCTION art_quick_lmod
Ian Rogers55bd45f2012-04-04 17:31:20 -0700714
Ian Rogers468532e2013-08-05 10:56:33 -0700715DEFINE_FUNCTION art_quick_lmul
Ian Rogers5793fea2013-02-14 13:33:34 -0800716 imul %eax, %ebx // ebx = a.lo(eax) * b.hi(ebx)
717 imul %edx, %ecx // ecx = b.lo(edx) * a.hi(ecx)
718 mul %edx // edx:eax = a.lo(eax) * b.lo(edx)
719 add %ebx, %ecx
720 add %ecx, %edx // edx += (a.lo * b.hi) + (b.lo * a.hi)
jeffhao644d5312012-05-03 19:04:49 -0700721 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700722END_FUNCTION art_quick_lmul
jeffhao644d5312012-05-03 19:04:49 -0700723
Ian Rogers468532e2013-08-05 10:56:33 -0700724DEFINE_FUNCTION art_quick_lshl
jeffhao644d5312012-05-03 19:04:49 -0700725 // ecx:eax << edx
Ian Rogers141d6222012-04-05 12:23:06 -0700726 xchg %edx, %ecx
727 shld %cl,%eax,%edx
728 shl %cl,%eax
729 test LITERAL(32), %cl
730 jz 1f
731 mov %eax, %edx
732 xor %eax, %eax
7331:
734 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700735END_FUNCTION art_quick_lshl
Ian Rogers141d6222012-04-05 12:23:06 -0700736
Ian Rogers468532e2013-08-05 10:56:33 -0700737DEFINE_FUNCTION art_quick_lshr
jeffhao644d5312012-05-03 19:04:49 -0700738 // ecx:eax >> edx
Ian Rogers141d6222012-04-05 12:23:06 -0700739 xchg %edx, %ecx
jeffhao644d5312012-05-03 19:04:49 -0700740 shrd %cl,%edx,%eax
741 sar %cl,%edx
Ian Rogers141d6222012-04-05 12:23:06 -0700742 test LITERAL(32),%cl
743 jz 1f
jeffhao5121e0b2012-05-08 18:23:38 -0700744 mov %edx, %eax
745 sar LITERAL(31), %edx
Ian Rogers141d6222012-04-05 12:23:06 -07007461:
747 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700748END_FUNCTION art_quick_lshr
Ian Rogers141d6222012-04-05 12:23:06 -0700749
Ian Rogers468532e2013-08-05 10:56:33 -0700750DEFINE_FUNCTION art_quick_lushr
jeffhao644d5312012-05-03 19:04:49 -0700751 // ecx:eax >>> edx
Ian Rogers141d6222012-04-05 12:23:06 -0700752 xchg %edx, %ecx
jeffhao644d5312012-05-03 19:04:49 -0700753 shrd %cl,%edx,%eax
754 shr %cl,%edx
755 test LITERAL(32),%cl
Ian Rogers141d6222012-04-05 12:23:06 -0700756 jz 1f
jeffhao5121e0b2012-05-08 18:23:38 -0700757 mov %edx, %eax
758 xor %edx, %edx
Ian Rogers141d6222012-04-05 12:23:06 -07007591:
760 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700761END_FUNCTION art_quick_lushr
Ian Rogers141d6222012-04-05 12:23:06 -0700762
Ian Rogers468532e2013-08-05 10:56:33 -0700763DEFINE_FUNCTION art_quick_set32_instance
jeffhao9dbb23e2012-05-18 17:03:57 -0700764 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
765 mov %esp, %ebx // remember SP
jeffhao1ff4cd72012-05-21 11:17:48 -0700766 subl LITERAL(8), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800767 .cfi_adjust_cfa_offset 8
768 PUSH ebx // pass SP
jeffhao9dbb23e2012-05-18 17:03:57 -0700769 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800770 .cfi_adjust_cfa_offset 4
jeffhao9dbb23e2012-05-18 17:03:57 -0700771 mov 32(%ebx), %ebx // get referrer
Ian Rogersaeeada42013-02-13 11:28:34 -0800772 PUSH ebx // pass referrer
773 PUSH edx // pass new_val
774 PUSH ecx // pass object
775 PUSH eax // pass field_idx
jeffhao9dbb23e2012-05-18 17:03:57 -0700776 call SYMBOL(artSet32InstanceFromCode) // (field_idx, Object*, new_val, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700777 addl LITERAL(32), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800778 .cfi_adjust_cfa_offset -32
jeffhao9dbb23e2012-05-18 17:03:57 -0700779 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
780 RETURN_IF_EAX_ZERO // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -0700781END_FUNCTION art_quick_set32_instance
jeffhao9dbb23e2012-05-18 17:03:57 -0700782
Ian Rogers468532e2013-08-05 10:56:33 -0700783DEFINE_FUNCTION art_quick_set64_instance
Ian Rogersaeeada42013-02-13 11:28:34 -0800784 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
jeffhao1ff4cd72012-05-21 11:17:48 -0700785 subl LITERAL(8), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800786 .cfi_adjust_cfa_offset 8
787 PUSH esp // pass SP-8
jeffhao1ff4cd72012-05-21 11:17:48 -0700788 addl LITERAL(8), (%esp) // fix SP on stack by adding 8
jeffhao9dbb23e2012-05-18 17:03:57 -0700789 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800790 .cfi_adjust_cfa_offset 4
791 PUSH ebx // pass high half of new_val
792 PUSH edx // pass low half of new_val
793 PUSH ecx // pass object
794 PUSH eax // pass field_idx
jeffhao9dbb23e2012-05-18 17:03:57 -0700795 call SYMBOL(artSet64InstanceFromCode) // (field_idx, Object*, new_val, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700796 addl LITERAL(32), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800797 .cfi_adjust_cfa_offset -32
798 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
jeffhao9dbb23e2012-05-18 17:03:57 -0700799 RETURN_IF_EAX_ZERO // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -0700800END_FUNCTION art_quick_set64_instance
jeffhao9dbb23e2012-05-18 17:03:57 -0700801
Ian Rogers468532e2013-08-05 10:56:33 -0700802DEFINE_FUNCTION art_quick_set_obj_instance
Ian Rogersaeeada42013-02-13 11:28:34 -0800803 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
jeffhao9dbb23e2012-05-18 17:03:57 -0700804 mov %esp, %ebx // remember SP
jeffhao1ff4cd72012-05-21 11:17:48 -0700805 subl LITERAL(8), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800806 .cfi_adjust_cfa_offset 8
807 PUSH ebx // pass SP
jeffhao9dbb23e2012-05-18 17:03:57 -0700808 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800809 .cfi_adjust_cfa_offset 4
jeffhao9dbb23e2012-05-18 17:03:57 -0700810 mov 32(%ebx), %ebx // get referrer
Ian Rogersaeeada42013-02-13 11:28:34 -0800811 PUSH ebx // pass referrer
812 PUSH edx // pass new_val
813 PUSH ecx // pass object
814 PUSH eax // pass field_idx
jeffhao9dbb23e2012-05-18 17:03:57 -0700815 call SYMBOL(artSetObjInstanceFromCode) // (field_idx, Object*, new_val, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700816 addl LITERAL(32), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800817 .cfi_adjust_cfa_offset -32
jeffhao9dbb23e2012-05-18 17:03:57 -0700818 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
819 RETURN_IF_EAX_ZERO // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -0700820END_FUNCTION art_quick_set_obj_instance
jeffhao9dbb23e2012-05-18 17:03:57 -0700821
Ian Rogers468532e2013-08-05 10:56:33 -0700822DEFINE_FUNCTION art_quick_get32_instance
Ian Rogersaeeada42013-02-13 11:28:34 -0800823 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
jeffhao9dbb23e2012-05-18 17:03:57 -0700824 mov %esp, %ebx // remember SP
825 mov 32(%esp), %edx // get referrer
jeffhao1ff4cd72012-05-21 11:17:48 -0700826 subl LITERAL(12), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800827 .cfi_adjust_cfa_offset 12
828 PUSH ebx // pass SP
jeffhao9dbb23e2012-05-18 17:03:57 -0700829 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800830 .cfi_adjust_cfa_offset 4
831 PUSH edx // pass referrer
832 PUSH ecx // pass object
833 PUSH eax // pass field_idx
jeffhao9dbb23e2012-05-18 17:03:57 -0700834 call SYMBOL(artGet32InstanceFromCode) // (field_idx, Object*, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700835 addl LITERAL(32), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800836 .cfi_adjust_cfa_offset -32
jeffhao9dbb23e2012-05-18 17:03:57 -0700837 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
jeffhaod66a8752012-05-22 15:30:16 -0700838 RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -0700839END_FUNCTION art_quick_get32_instance
jeffhao9dbb23e2012-05-18 17:03:57 -0700840
Ian Rogers468532e2013-08-05 10:56:33 -0700841DEFINE_FUNCTION art_quick_get64_instance
jeffhao9dbb23e2012-05-18 17:03:57 -0700842 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
843 mov %esp, %ebx // remember SP
844 mov 32(%esp), %edx // get referrer
jeffhao1ff4cd72012-05-21 11:17:48 -0700845 subl LITERAL(12), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800846 .cfi_adjust_cfa_offset 12
847 PUSH ebx // pass SP
jeffhao9dbb23e2012-05-18 17:03:57 -0700848 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800849 .cfi_adjust_cfa_offset 4
850 PUSH edx // pass referrer
851 PUSH ecx // pass object
852 PUSH eax // pass field_idx
jeffhao9dbb23e2012-05-18 17:03:57 -0700853 call SYMBOL(artGet64InstanceFromCode) // (field_idx, Object*, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700854 addl LITERAL(32), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800855 .cfi_adjust_cfa_offset -32
jeffhao9dbb23e2012-05-18 17:03:57 -0700856 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
jeffhaod66a8752012-05-22 15:30:16 -0700857 RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -0700858END_FUNCTION art_quick_get64_instance
jeffhao9dbb23e2012-05-18 17:03:57 -0700859
Ian Rogers468532e2013-08-05 10:56:33 -0700860DEFINE_FUNCTION art_quick_get_obj_instance
jeffhao9dbb23e2012-05-18 17:03:57 -0700861 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
862 mov %esp, %ebx // remember SP
863 mov 32(%esp), %edx // get referrer
jeffhao1ff4cd72012-05-21 11:17:48 -0700864 subl LITERAL(12), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800865 .cfi_adjust_cfa_offset 12
866 PUSH ebx // pass SP
jeffhao9dbb23e2012-05-18 17:03:57 -0700867 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800868 .cfi_adjust_cfa_offset 4
869 PUSH edx // pass referrer
870 PUSH ecx // pass object
871 PUSH eax // pass field_idx
jeffhao9dbb23e2012-05-18 17:03:57 -0700872 call SYMBOL(artGetObjInstanceFromCode) // (field_idx, Object*, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700873 addl LITERAL(32), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800874 .cfi_adjust_cfa_offset -32
jeffhao9dbb23e2012-05-18 17:03:57 -0700875 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
jeffhaod66a8752012-05-22 15:30:16 -0700876 RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -0700877END_FUNCTION art_quick_get_obj_instance
jeffhao9dbb23e2012-05-18 17:03:57 -0700878
Ian Rogers468532e2013-08-05 10:56:33 -0700879DEFINE_FUNCTION art_quick_set32_static
jeffhao9dbb23e2012-05-18 17:03:57 -0700880 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
881 mov %esp, %ebx // remember SP
882 mov 32(%esp), %edx // get referrer
jeffhao1ff4cd72012-05-21 11:17:48 -0700883 subl LITERAL(12), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800884 .cfi_adjust_cfa_offset 12
885 PUSH ebx // pass SP
jeffhao9dbb23e2012-05-18 17:03:57 -0700886 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800887 .cfi_adjust_cfa_offset 4
888 PUSH edx // pass referrer
889 PUSH ecx // pass new_val
890 PUSH eax // pass field_idx
jeffhao9dbb23e2012-05-18 17:03:57 -0700891 call SYMBOL(artSet32StaticFromCode) // (field_idx, new_val, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700892 addl LITERAL(32), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800893 .cfi_adjust_cfa_offset -32
jeffhao9dbb23e2012-05-18 17:03:57 -0700894 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
895 RETURN_IF_EAX_ZERO // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -0700896END_FUNCTION art_quick_set32_static
jeffhao9dbb23e2012-05-18 17:03:57 -0700897
Ian Rogers468532e2013-08-05 10:56:33 -0700898DEFINE_FUNCTION art_quick_set64_static
Ian Rogersaeeada42013-02-13 11:28:34 -0800899 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
jeffhao9dbb23e2012-05-18 17:03:57 -0700900 mov %esp, %ebx // remember SP
jeffhao1ff4cd72012-05-21 11:17:48 -0700901 subl LITERAL(8), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800902 .cfi_adjust_cfa_offset 8
903 PUSH ebx // pass SP
jeffhao9dbb23e2012-05-18 17:03:57 -0700904 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800905 .cfi_adjust_cfa_offset 4
jeffhao9dbb23e2012-05-18 17:03:57 -0700906 mov 32(%ebx), %ebx // get referrer
Ian Rogersaeeada42013-02-13 11:28:34 -0800907 PUSH edx // pass high half of new_val
908 PUSH ecx // pass low half of new_val
909 PUSH ebx // pass referrer
910 PUSH eax // pass field_idx
911 call SYMBOL(artSet64StaticFromCode) // (field_idx, referrer, new_val, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700912 addl LITERAL(32), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800913 .cfi_adjust_cfa_offset -32
914 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
jeffhao9dbb23e2012-05-18 17:03:57 -0700915 RETURN_IF_EAX_ZERO // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -0700916END_FUNCTION art_quick_set64_static
jeffhao9dbb23e2012-05-18 17:03:57 -0700917
Ian Rogers468532e2013-08-05 10:56:33 -0700918DEFINE_FUNCTION art_quick_set_obj_static
Ian Rogersaeeada42013-02-13 11:28:34 -0800919 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
jeffhao9dbb23e2012-05-18 17:03:57 -0700920 mov %esp, %ebx // remember SP
921 mov 32(%esp), %edx // get referrer
jeffhao1ff4cd72012-05-21 11:17:48 -0700922 subl LITERAL(12), %esp // alignment padding
Ian Rogers62d6c772013-02-27 08:32:07 -0800923 .cfi_adjust_cfa_offset 12
Ian Rogersaeeada42013-02-13 11:28:34 -0800924 PUSH ebx // pass SP
jeffhao9dbb23e2012-05-18 17:03:57 -0700925 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800926 .cfi_adjust_cfa_offset 4
927 PUSH edx // pass referrer
928 PUSH ecx // pass new_val
929 PUSH eax // pass field_idx
930 call SYMBOL(artSetObjStaticFromCode) // (field_idx, new_val, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700931 addl LITERAL(32), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800932 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
jeffhao9dbb23e2012-05-18 17:03:57 -0700933 RETURN_IF_EAX_ZERO // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -0700934END_FUNCTION art_quick_set_obj_static
jeffhao9dbb23e2012-05-18 17:03:57 -0700935
Ian Rogers468532e2013-08-05 10:56:33 -0700936DEFINE_FUNCTION art_quick_get32_static
jeffhao9dbb23e2012-05-18 17:03:57 -0700937 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
938 mov %esp, %edx // remember SP
939 mov 32(%esp), %ecx // get referrer
Ian Rogersaeeada42013-02-13 11:28:34 -0800940 PUSH edx // pass SP
jeffhao9dbb23e2012-05-18 17:03:57 -0700941 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800942 .cfi_adjust_cfa_offset 4
943 PUSH ecx // pass referrer
944 PUSH eax // pass field_idx
jeffhao9dbb23e2012-05-18 17:03:57 -0700945 call SYMBOL(artGet32StaticFromCode) // (field_idx, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700946 addl LITERAL(16), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800947 .cfi_adjust_cfa_offset -16
jeffhao9dbb23e2012-05-18 17:03:57 -0700948 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
jeffhaod66a8752012-05-22 15:30:16 -0700949 RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -0700950END_FUNCTION art_quick_get32_static
jeffhao9dbb23e2012-05-18 17:03:57 -0700951
Ian Rogers468532e2013-08-05 10:56:33 -0700952DEFINE_FUNCTION art_quick_get64_static
Ian Rogersaeeada42013-02-13 11:28:34 -0800953 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
jeffhao9dbb23e2012-05-18 17:03:57 -0700954 mov %esp, %edx // remember SP
955 mov 32(%esp), %ecx // get referrer
Ian Rogersaeeada42013-02-13 11:28:34 -0800956 PUSH edx // pass SP
jeffhao9dbb23e2012-05-18 17:03:57 -0700957 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800958 .cfi_adjust_cfa_offset 4
959 PUSH ecx // pass referrer
960 PUSH eax // pass field_idx
jeffhao9dbb23e2012-05-18 17:03:57 -0700961 call SYMBOL(artGet64StaticFromCode) // (field_idx, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700962 addl LITERAL(16), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800963 .cfi_adjust_cfa_offset -16
jeffhao9dbb23e2012-05-18 17:03:57 -0700964 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
jeffhaod66a8752012-05-22 15:30:16 -0700965 RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -0700966END_FUNCTION art_quick_get64_static
jeffhao9dbb23e2012-05-18 17:03:57 -0700967
Ian Rogers468532e2013-08-05 10:56:33 -0700968DEFINE_FUNCTION art_quick_get_obj_static
jeffhao9dbb23e2012-05-18 17:03:57 -0700969 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
970 mov %esp, %edx // remember SP
971 mov 32(%esp), %ecx // get referrer
Ian Rogersaeeada42013-02-13 11:28:34 -0800972 PUSH edx // pass SP
jeffhao9dbb23e2012-05-18 17:03:57 -0700973 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800974 .cfi_adjust_cfa_offset 4
975 PUSH ecx // pass referrer
976 PUSH eax // pass field_idx
jeffhao9dbb23e2012-05-18 17:03:57 -0700977 call SYMBOL(artGetObjStaticFromCode) // (field_idx, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700978 addl LITERAL(16), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800979 .cfi_adjust_cfa_offset -16
jeffhao9dbb23e2012-05-18 17:03:57 -0700980 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
jeffhaod66a8752012-05-22 15:30:16 -0700981 RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -0700982END_FUNCTION art_quick_get_obj_static
jeffhaod66a8752012-05-22 15:30:16 -0700983
Logan Chien8dbb7082013-01-25 20:31:17 +0800984DEFINE_FUNCTION art_quick_proxy_invoke_handler
Ian Rogers7db619b2013-01-16 18:35:48 -0800985 SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME // save frame and Method*
Ian Rogersaeeada42013-02-13 11:28:34 -0800986 PUSH esp // pass SP
jeffhaod66a8752012-05-22 15:30:16 -0700987 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800988 .cfi_adjust_cfa_offset 4
989 PUSH ecx // pass receiver
990 PUSH eax // pass proxy method
Jeff Hao5fa60c32013-04-04 17:57:01 -0700991 call SYMBOL(artQuickProxyInvokeHandler) // (proxy method, receiver, Thread*, SP)
Ian Rogersaf6e67a2013-01-16 08:38:37 -0800992 movd %eax, %xmm0 // place return value also into floating point return value
993 movd %edx, %xmm1
994 punpckldq %xmm1, %xmm0
jeffhaod66a8752012-05-22 15:30:16 -0700995 addl LITERAL(44), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800996 .cfi_adjust_cfa_offset -44
jeffhaod66a8752012-05-22 15:30:16 -0700997 RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
Ian Rogersaeeada42013-02-13 11:28:34 -0800998END_FUNCTION art_quick_proxy_invoke_handler
jeffhao9dbb23e2012-05-18 17:03:57 -0700999
Jeff Hao88474b42013-10-23 16:24:40 -07001000 /*
1001 * Called to resolve an imt conflict. xmm0 is a hidden argument that holds the target method's
1002 * dex method index.
1003 */
1004DEFINE_FUNCTION art_quick_imt_conflict_trampoline
1005 PUSH ecx
1006 movl 8(%esp), %eax // load caller Method*
1007 movl METHOD_DEX_CACHE_METHODS_OFFSET(%eax), %eax // load dex_cache_resolved_methods
1008 movd %xmm0, %ecx // get target method index stored in xmm0
1009 movl OBJECT_ARRAY_DATA_OFFSET(%eax, %ecx, 4), %eax // load the target method
1010 POP ecx
1011 jmp art_quick_invoke_interface_trampoline
1012END_FUNCTION art_quick_imt_conflict_trampoline
1013
Ian Rogers468532e2013-08-05 10:56:33 -07001014DEFINE_FUNCTION art_quick_resolution_trampoline
1015 SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME
1016 PUSH esp // pass SP
1017 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
1018 .cfi_adjust_cfa_offset 4
1019 PUSH ecx // pass receiver
1020 PUSH eax // pass method
1021 call SYMBOL(artQuickResolutionTrampoline) // (Method* called, receiver, Thread*, SP)
1022 movl %eax, %edi // remember code pointer in EDI
1023 addl LITERAL(16), %esp // pop arguments
1024 test %eax, %eax // if code pointer is NULL goto deliver pending exception
1025 jz 1f
1026 POP eax // called method
1027 POP ecx // restore args
1028 POP edx
1029 POP ebx
1030 POP ebp // restore callee saves except EDI
1031 POP esi
1032 xchgl 0(%esp),%edi // restore EDI and place code pointer as only value on stack
1033 ret // tail call into method
10341:
1035 RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME
1036 DELIVER_PENDING_EXCEPTION
1037END_FUNCTION art_quick_resolution_trampoline
1038
1039DEFINE_FUNCTION art_quick_to_interpreter_bridge
Ian Rogers62d6c772013-02-27 08:32:07 -08001040 SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME // save frame
Ian Rogersaeeada42013-02-13 11:28:34 -08001041 mov %esp, %edx // remember SP
1042 PUSH eax // alignment padding
1043 PUSH edx // pass SP
Ian Rogers7db619b2013-01-16 18:35:48 -08001044 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -08001045 .cfi_adjust_cfa_offset 4
1046 PUSH eax // pass method
Ian Rogers468532e2013-08-05 10:56:33 -07001047 call SYMBOL(artQuickToInterpreterBridge) // (method, Thread*, SP)
Ian Rogers7db619b2013-01-16 18:35:48 -08001048 movd %eax, %xmm0 // place return value also into floating point return value
1049 movd %edx, %xmm1
1050 punpckldq %xmm1, %xmm0
Mathieu Chartier19841522013-10-22 11:29:00 -07001051 addl LITERAL(16), %esp // pop arguments
1052 .cfi_adjust_cfa_offset -16
1053 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
Ian Rogers7db619b2013-01-16 18:35:48 -08001054 RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -07001055END_FUNCTION art_quick_to_interpreter_bridge
Ian Rogers7db619b2013-01-16 18:35:48 -08001056
jeffhao7e4fcb82013-01-10 18:11:08 -08001057 /*
1058 * Routine that intercepts method calls and returns.
1059 */
Ian Rogers468532e2013-08-05 10:56:33 -07001060DEFINE_FUNCTION art_quick_instrumentation_entry
Ian Rogers62d6c772013-02-27 08:32:07 -08001061 SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME
1062 movl %esp, %edx // Save SP.
1063 PUSH eax // Save eax which will be clobbered by the callee-save method.
1064 subl LITERAL(8), %esp // Align stack.
1065 .cfi_adjust_cfa_offset 8
1066 pushl 40(%esp) // Pass LR.
Ian Rogersaeeada42013-02-13 11:28:34 -08001067 .cfi_adjust_cfa_offset 4
Ian Rogers62d6c772013-02-27 08:32:07 -08001068 PUSH edx // Pass SP.
1069 pushl %fs:THREAD_SELF_OFFSET // Pass Thread::Current().
Ian Rogersaeeada42013-02-13 11:28:34 -08001070 .cfi_adjust_cfa_offset 4
Ian Rogers62d6c772013-02-27 08:32:07 -08001071 PUSH ecx // Pass receiver.
1072 PUSH eax // Pass Method*.
1073 call SYMBOL(artInstrumentationMethodEntryFromCode) // (Method*, Object*, Thread*, SP, LR)
1074 addl LITERAL(28), %esp // Pop arguments upto saved Method*.
1075 movl 28(%esp), %edi // Restore edi.
1076 movl %eax, 28(%esp) // Place code* over edi, just under return pc.
Ian Rogers468532e2013-08-05 10:56:33 -07001077 movl LITERAL(SYMBOL(art_quick_instrumentation_exit)), 32(%esp)
Ian Rogers62d6c772013-02-27 08:32:07 -08001078 // Place instrumentation exit as return pc.
1079 movl (%esp), %eax // Restore eax.
1080 movl 8(%esp), %ecx // Restore ecx.
1081 movl 12(%esp), %edx // Restore edx.
1082 movl 16(%esp), %ebx // Restore ebx.
1083 movl 20(%esp), %ebp // Restore ebp.
1084 movl 24(%esp), %esi // Restore esi.
1085 addl LITERAL(28), %esp // Wind stack back upto code*.
1086 ret // Call method (and pop).
Ian Rogers468532e2013-08-05 10:56:33 -07001087END_FUNCTION art_quick_instrumentation_entry
Ian Rogers62d6c772013-02-27 08:32:07 -08001088
Ian Rogers468532e2013-08-05 10:56:33 -07001089DEFINE_FUNCTION art_quick_instrumentation_exit
Ian Rogers62d6c772013-02-27 08:32:07 -08001090 pushl LITERAL(0) // Push a fake return PC as there will be none on the stack.
1091 SETUP_REF_ONLY_CALLEE_SAVE_FRAME
1092 mov %esp, %ecx // Remember SP
1093 subl LITERAL(8), %esp // Save float return value.
1094 .cfi_adjust_cfa_offset 8
1095 movd %xmm0, (%esp)
1096 PUSH edx // Save gpr return value.
1097 PUSH eax
1098 subl LITERAL(8), %esp // Align stack
1099 movd %xmm0, (%esp)
1100 subl LITERAL(8), %esp // Pass float return value.
1101 .cfi_adjust_cfa_offset 8
1102 movd %xmm0, (%esp)
1103 PUSH edx // Pass gpr return value.
1104 PUSH eax
1105 PUSH ecx // Pass SP.
1106 pushl %fs:THREAD_SELF_OFFSET // Pass Thread::Current.
Ian Rogersaeeada42013-02-13 11:28:34 -08001107 .cfi_adjust_cfa_offset 4
Ian Rogers62d6c772013-02-27 08:32:07 -08001108 call SYMBOL(artInstrumentationMethodExitFromCode) // (Thread*, SP, gpr_result, fpr_result)
1109 mov %eax, %ecx // Move returned link register.
1110 addl LITERAL(32), %esp // Pop arguments.
1111 .cfi_adjust_cfa_offset -32
1112 movl %edx, %ebx // Move returned link register for deopt
1113 // (ebx is pretending to be our LR).
1114 POP eax // Restore gpr return value.
1115 POP edx
1116 movd (%esp), %xmm0 // Restore fpr return value.
1117 addl LITERAL(8), %esp
Ian Rogers5793fea2013-02-14 13:33:34 -08001118 .cfi_adjust_cfa_offset -8
Ian Rogers62d6c772013-02-27 08:32:07 -08001119 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
1120 addl LITERAL(4), %esp // Remove fake return pc.
1121 jmp *%ecx // Return.
Ian Rogers468532e2013-08-05 10:56:33 -07001122END_FUNCTION art_quick_instrumentation_exit
jeffhao162fd332013-01-08 16:21:01 -08001123
jeffhao7e4fcb82013-01-10 18:11:08 -08001124 /*
Ian Rogers62d6c772013-02-27 08:32:07 -08001125 * Instrumentation has requested that we deoptimize into the interpreter. The deoptimization
1126 * will long jump to the upcall with a special exception of -1.
jeffhao7e4fcb82013-01-10 18:11:08 -08001127 */
Logan Chien8dbb7082013-01-25 20:31:17 +08001128DEFINE_FUNCTION art_quick_deoptimize
Ian Rogers62d6c772013-02-27 08:32:07 -08001129 pushl %ebx // Fake that we were called.
Jeff Haoc1fcdf12013-04-11 13:34:01 -07001130 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME
Ian Rogers62d6c772013-02-27 08:32:07 -08001131 mov %esp, %ecx // Remember SP.
1132 subl LITERAL(8), %esp // Align stack.
1133 .cfi_adjust_cfa_offset 8
1134 PUSH ecx // Pass SP.
1135 pushl %fs:THREAD_SELF_OFFSET // Pass Thread::Current().
Ian Rogersaeeada42013-02-13 11:28:34 -08001136 .cfi_adjust_cfa_offset 4
Ian Rogers62d6c772013-02-27 08:32:07 -08001137 call SYMBOL(artDeoptimize) // artDeoptimize(Thread*, SP)
1138 int3 // Unreachable.
Ian Rogersaeeada42013-02-13 11:28:34 -08001139END_FUNCTION art_quick_deoptimize
jeffhao162fd332013-01-08 16:21:01 -08001140
jeffhao86e46712012-08-08 17:30:59 -07001141 /*
1142 * String's indexOf.
1143 *
1144 * On entry:
1145 * eax: string object (known non-null)
1146 * ecx: char to match (known <= 0xFFFF)
1147 * edx: Starting offset in string data
1148 */
Logan Chien8dbb7082013-01-25 20:31:17 +08001149DEFINE_FUNCTION art_quick_indexof
Ian Rogersaeeada42013-02-13 11:28:34 -08001150 PUSH edi // push callee save reg
jeffhao86e46712012-08-08 17:30:59 -07001151 mov STRING_COUNT_OFFSET(%eax), %ebx
1152 mov STRING_VALUE_OFFSET(%eax), %edi
1153 mov STRING_OFFSET_OFFSET(%eax), %eax
1154 testl %edx, %edx // check if start < 0
1155 jl clamp_min
1156clamp_done:
1157 cmpl %ebx, %edx // check if start >= count
1158 jge not_found
1159 lea STRING_DATA_OFFSET(%edi, %eax, 2), %edi // build a pointer to the start of string data
1160 mov %edi, %eax // save a copy in eax to later compute result
1161 lea (%edi, %edx, 2), %edi // build pointer to start of data to compare
1162 subl %edx, %ebx // compute iteration count
1163 /*
1164 * At this point we have:
1165 * eax: original start of string data
1166 * ecx: char to compare
1167 * ebx: length to compare
1168 * edi: start of data to test
1169 */
1170 mov %eax, %edx
1171 mov %ecx, %eax // put char to match in %eax
1172 mov %ebx, %ecx // put length to compare in %ecx
1173 repne scasw // find %ax, starting at [%edi], up to length %ecx
1174 jne not_found
1175 subl %edx, %edi
1176 sar LITERAL(1), %edi
1177 decl %edi // index = ((curr_ptr - orig_ptr) / 2) - 1
1178 mov %edi, %eax
Ian Rogersaeeada42013-02-13 11:28:34 -08001179 POP edi // pop callee save reg
jeffhao86e46712012-08-08 17:30:59 -07001180 ret
1181 .balign 16
1182not_found:
1183 mov LITERAL(-1), %eax // return -1 (not found)
Ian Rogersaeeada42013-02-13 11:28:34 -08001184 POP edi // pop callee save reg
jeffhao86e46712012-08-08 17:30:59 -07001185 ret
1186clamp_min:
1187 xor %edx, %edx // clamp start to 0
1188 jmp clamp_done
Ian Rogersaeeada42013-02-13 11:28:34 -08001189END_FUNCTION art_quick_indexof
jeffhao86e46712012-08-08 17:30:59 -07001190
1191 /*
1192 * String's compareTo.
1193 *
1194 * On entry:
1195 * eax: this string object (known non-null)
1196 * ecx: comp string object (known non-null)
1197 */
Logan Chien8dbb7082013-01-25 20:31:17 +08001198DEFINE_FUNCTION art_quick_string_compareto
Ian Rogersaeeada42013-02-13 11:28:34 -08001199 PUSH esi // push callee save reg
1200 PUSH edi // push callee save reg
jeffhao86e46712012-08-08 17:30:59 -07001201 mov STRING_COUNT_OFFSET(%eax), %edx
1202 mov STRING_COUNT_OFFSET(%ecx), %ebx
1203 mov STRING_VALUE_OFFSET(%eax), %esi
1204 mov STRING_VALUE_OFFSET(%ecx), %edi
1205 mov STRING_OFFSET_OFFSET(%eax), %eax
1206 mov STRING_OFFSET_OFFSET(%ecx), %ecx
1207 /* Build pointers to the start of string data */
1208 lea STRING_DATA_OFFSET(%esi, %eax, 2), %esi
1209 lea STRING_DATA_OFFSET(%edi, %ecx, 2), %edi
1210 /* Calculate min length and count diff */
1211 mov %edx, %ecx
1212 mov %edx, %eax
1213 subl %ebx, %eax
1214 cmovg %ebx, %ecx
1215 /*
1216 * At this point we have:
1217 * eax: value to return if first part of strings are equal
1218 * ecx: minimum among the lengths of the two strings
1219 * esi: pointer to this string data
1220 * edi: pointer to comp string data
1221 */
1222 repe cmpsw // find nonmatching chars in [%esi] and [%edi], up to length %ecx
1223 jne not_equal
Ian Rogersaeeada42013-02-13 11:28:34 -08001224 POP edi // pop callee save reg
1225 POP esi // pop callee save reg
jeffhao86e46712012-08-08 17:30:59 -07001226 ret
1227 .balign 16
1228not_equal:
Ian Rogers1b09b092012-08-20 15:35:52 -07001229 movzwl -2(%esi), %eax // get last compared char from this string
1230 movzwl -2(%edi), %ecx // get last compared char from comp string
jeffhao86e46712012-08-08 17:30:59 -07001231 subl %ecx, %eax // return the difference
Ian Rogersaeeada42013-02-13 11:28:34 -08001232 POP edi // pop callee save reg
1233 POP esi // pop callee save reg
jeffhao86e46712012-08-08 17:30:59 -07001234 ret
Ian Rogersaeeada42013-02-13 11:28:34 -08001235END_FUNCTION art_quick_string_compareto
jeffhao86e46712012-08-08 17:30:59 -07001236
Elliott Hughes787ec202012-03-29 17:14:15 -07001237 // TODO: implement these!
Logan Chien8dbb7082013-01-25 20:31:17 +08001238UNIMPLEMENTED art_quick_memcmp16