blob: 4e797701b89a93a21e4e9ed0893f416fd7cc9e39 [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
Mathieu Chartierad2541a2013-10-25 10:05:23 -0700414 test LITERAL(0xC0000000), %ecx // test the 2 high bits.
415 jne slow_lock // slow path if either of the two high bits are set.
Ian Rogersd9c4fc92013-10-01 19:45:43 -0700416 movl %fs:THREAD_ID_OFFSET, %edx // edx := thread id
417 test %ecx, %ecx
Ian Rogersd9c4fc92013-10-01 19:45:43 -0700418 jnz already_thin // lock word contains a thin lock
419 // unlocked case - %edx holds thread id with count of 0
420 movl %eax, %ecx // remember object in case of retry
421 xor %eax, %eax // eax == 0 for comparison with lock word in cmpxchg
422 lock cmpxchg %edx, LOCK_WORD_OFFSET(%ecx)
423 jnz cmpxchg_fail // cmpxchg failed retry
424 ret
425cmpxchg_fail:
426 movl %ecx, %eax // restore eax
427 jmp retry_lock
428already_thin:
429 cmpw %ax, %dx // do we hold the lock already?
430 jne slow_lock
431 addl LITERAL(65536), %eax // increment recursion count
Mathieu Chartierad2541a2013-10-25 10:05:23 -0700432 test LITERAL(0xC0000000), %eax // overflowed if either of top two bits are set
433 jne slow_lock // count overflowed so go slow
Ian Rogersd9c4fc92013-10-01 19:45:43 -0700434 movl %eax, LOCK_WORD_OFFSET(%ecx) // update lockword, cmpxchg not necessary as we hold lock
435 ret
436slow_lock:
437 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
438 mov %esp, %edx // remember SP
439 // Outgoing argument set up
440 PUSH eax // push padding
441 PUSH edx // pass SP
442 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
443 .cfi_adjust_cfa_offset 4
444 PUSH eax // pass object
445 call artLockObjectFromCode // artLockObjectFromCode(object, Thread*, SP)
446 addl MACRO_LITERAL(16), %esp // pop arguments
447 .cfi_adjust_cfa_offset -16
448 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
449 RETURN_IF_EAX_ZERO
450END_FUNCTION art_quick_lock_object
451
452DEFINE_FUNCTION art_quick_unlock_object
453 testl %eax, %eax // null check object/eax
454 jz slow_unlock
455 movl LOCK_WORD_OFFSET(%eax), %ecx // ecx := lock word
456 movl %fs:THREAD_ID_OFFSET, %edx // edx := thread id
457 test %ecx, %ecx
458 jb slow_unlock // lock word contains a monitor
459 cmpw %cx, %dx // does the thread id match?
460 jne slow_unlock
461 cmpl LITERAL(65536), %ecx
462 jae recursive_thin_unlock
463 movl LITERAL(0), LOCK_WORD_OFFSET(%eax)
464 ret
465recursive_thin_unlock:
466 subl LITERAL(65536), %ecx
467 mov %ecx, LOCK_WORD_OFFSET(%eax)
468 ret
469slow_unlock:
470 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
471 mov %esp, %edx // remember SP
472 // Outgoing argument set up
473 PUSH eax // push padding
474 PUSH edx // pass SP
475 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
476 .cfi_adjust_cfa_offset 4
477 PUSH eax // pass object
478 call artUnlockObjectFromCode // artUnlockObjectFromCode(object, Thread*, SP)
479 addl MACRO_LITERAL(16), %esp // pop arguments
480 .cfi_adjust_cfa_offset -16
481 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
482 RETURN_IF_EAX_ZERO
483END_FUNCTION art_quick_unlock_object
484
Ian Rogers468532e2013-08-05 10:56:33 -0700485DEFINE_FUNCTION art_quick_is_assignable
Ian Rogersaeeada42013-02-13 11:28:34 -0800486 PUSH eax // alignment padding
Ian Rogersa9a82542013-10-04 11:17:26 -0700487 PUSH ecx // pass arg2 - obj->klass
488 PUSH eax // pass arg1 - checked class
489 call SYMBOL(artIsAssignableFromCode) // (Class* klass, Class* ref_klass)
Ian Rogers55bd45f2012-04-04 17:31:20 -0700490 addl LITERAL(12), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800491 .cfi_adjust_cfa_offset -12
Ian Rogers7caad772012-03-30 01:07:54 -0700492 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700493END_FUNCTION art_quick_is_assignable
Ian Rogers7caad772012-03-30 01:07:54 -0700494
Ian Rogersa9a82542013-10-04 11:17:26 -0700495DEFINE_FUNCTION art_quick_check_cast
496 PUSH eax // alignment padding
497 PUSH ecx // pass arg2 - obj->klass
498 PUSH eax // pass arg1 - checked class
499 call SYMBOL(artIsAssignableFromCode) // (Class* klass, Class* ref_klass)
500 testl %eax, %eax
501 jz 1f // jump forward if not assignable
502 addl LITERAL(12), %esp // pop arguments
503 .cfi_adjust_cfa_offset -12
504 ret
5051:
506 POP eax // pop arguments
507 POP ecx
508 addl LITERAL(4), %esp
509 .cfi_adjust_cfa_offset -12
510 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context
511 mov %esp, %edx
512 // Outgoing argument set up
513 PUSH edx // pass SP
514 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
515 .cfi_adjust_cfa_offset 4
516 PUSH ecx // pass arg2
517 PUSH eax // pass arg1
518 call SYMBOL(artThrowClassCastException) // (Class* a, Class* b, Thread*, SP)
519 int3 // unreached
520END_FUNCTION art_quick_check_cast
521
522 /*
523 * Entry from managed code for array put operations of objects where the value being stored
524 * needs to be checked for compatibility.
525 * eax = array, ecx = index, edx = value
526 */
527DEFINE_FUNCTION art_quick_aput_obj_with_null_and_bound_check
528 testl %eax, %eax
529 jnz art_quick_aput_obj_with_bound_check
530 jmp art_quick_throw_null_pointer_exception
531END_FUNCTION art_quick_aput_obj_with_null_and_bound_check
532
533DEFINE_FUNCTION art_quick_aput_obj_with_bound_check
534 movl ARRAY_LENGTH_OFFSET(%eax), %ebx
535 cmpl %ebx, %ecx
536 jb art_quick_aput_obj
537 mov %ecx, %eax
538 mov %ebx, %ecx
539 jmp art_quick_throw_array_bounds
540END_FUNCTION art_quick_aput_obj_with_bound_check
541
542DEFINE_FUNCTION art_quick_aput_obj
543 test %edx, %edx // store of null
544 jz do_aput_null
545 movl CLASS_OFFSET(%eax), %ebx
546 movl CLASS_COMPONENT_TYPE_OFFSET(%ebx), %ebx
547 cmpl CLASS_OFFSET(%edx), %ebx // value's type == array's component type - trivial assignability
548 jne check_assignability
549do_aput:
550 movl %edx, OBJECT_ARRAY_DATA_OFFSET(%eax, %ecx, 4)
551 movl %fs:THREAD_CARD_TABLE_OFFSET, %edx
552 shrl LITERAL(7), %eax
553 movb %dl, (%edx, %eax)
554 ret
555do_aput_null:
556 movl %edx, OBJECT_ARRAY_DATA_OFFSET(%eax, %ecx, 4)
557 ret
558check_assignability:
559 PUSH eax // save arguments
560 PUSH ecx
561 PUSH edx
562 subl LITERAL(8), %esp // alignment padding
563 .cfi_adjust_cfa_offset 8
564 pushl CLASS_OFFSET(%edx) // pass arg2 - type of the value to be stored
565 .cfi_adjust_cfa_offset 4
566 PUSH ebx // pass arg1 - component type of the array
567 call SYMBOL(artIsAssignableFromCode) // (Class* a, Class* b)
568 addl LITERAL(16), %esp // pop arguments
569 .cfi_adjust_cfa_offset -16
570 testl %eax, %eax
571 jz throw_array_store_exception
572 POP edx
573 POP ecx
574 POP eax
575 movl %edx, OBJECT_ARRAY_DATA_OFFSET(%eax, %ecx, 4) // do the aput
576 movl %fs:THREAD_CARD_TABLE_OFFSET, %edx
577 shrl LITERAL(7), %eax
578 movb %dl, (%edx, %eax)
579 ret
580throw_array_store_exception:
581 POP edx
582 POP ecx
583 POP eax
584 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context
585 mov %esp, %ecx
586 // Outgoing argument set up
587 PUSH ecx // pass SP
588 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
589 .cfi_adjust_cfa_offset 4
590 PUSH edx // pass arg2 - value
591 PUSH eax // pass arg1 - array
592 call SYMBOL(artThrowArrayStoreException) // (array, value, Thread*, SP)
593 int3 // unreached
594END_FUNCTION art_quick_aput_obj
595
Logan Chien8dbb7082013-01-25 20:31:17 +0800596DEFINE_FUNCTION art_quick_memcpy
Ian Rogersaeeada42013-02-13 11:28:34 -0800597 PUSH edx // pass arg3
598 PUSH ecx // pass arg2
599 PUSH eax // pass arg1
Elliott Hughesadc078a2012-04-04 11:39:05 -0700600 call SYMBOL(memcpy) // (void*, const void*, size_t)
Ian Rogers55bd45f2012-04-04 17:31:20 -0700601 addl LITERAL(12), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800602 .cfi_adjust_cfa_offset -12
Ian Rogers7caad772012-03-30 01:07:54 -0700603 ret
Ian Rogersaeeada42013-02-13 11:28:34 -0800604END_FUNCTION art_quick_memcpy
Ian Rogers7caad772012-03-30 01:07:54 -0700605
Logan Chien8dbb7082013-01-25 20:31:17 +0800606NO_ARG_DOWNCALL art_quick_test_suspend, artTestSuspendFromCode, ret
Ian Rogers7caad772012-03-30 01:07:54 -0700607
Ian Rogers468532e2013-08-05 10:56:33 -0700608DEFINE_FUNCTION art_quick_fmod
jeffhao1395b1e2012-06-13 18:05:13 -0700609 subl LITERAL(12), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800610 .cfi_adjust_cfa_offset 12
611 PUSH ebx // pass arg4 b.hi
612 PUSH edx // pass arg3 b.lo
613 PUSH ecx // pass arg2 a.hi
614 PUSH eax // pass arg1 a.lo
jeffhao1395b1e2012-06-13 18:05:13 -0700615 call SYMBOL(fmod) // (jdouble a, jdouble b)
616 fstpl (%esp) // pop return value off fp stack
617 movsd (%esp), %xmm0 // place into %xmm0
618 addl LITERAL(28), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800619 .cfi_adjust_cfa_offset -28
jeffhao292188d2012-05-17 15:45:04 -0700620 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700621END_FUNCTION art_quick_fmod
jeffhao292188d2012-05-17 15:45:04 -0700622
Ian Rogers468532e2013-08-05 10:56:33 -0700623DEFINE_FUNCTION art_quick_fmodf
Ian Rogersaeeada42013-02-13 11:28:34 -0800624 PUSH eax // alignment padding
625 PUSH ecx // pass arg2 b
626 PUSH eax // pass arg1 a
jeffhao1395b1e2012-06-13 18:05:13 -0700627 call SYMBOL(fmodf) // (jfloat a, jfloat b)
Ian Rogers1b09b092012-08-20 15:35:52 -0700628 fstps (%esp) // pop return value off fp stack
jeffhao1395b1e2012-06-13 18:05:13 -0700629 movss (%esp), %xmm0 // place into %xmm0
630 addl LITERAL(12), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800631 .cfi_adjust_cfa_offset -12
jeffhao292188d2012-05-17 15:45:04 -0700632 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700633END_FUNCTION art_quick_fmodf
jeffhao292188d2012-05-17 15:45:04 -0700634
Ian Rogers468532e2013-08-05 10:56:33 -0700635DEFINE_FUNCTION art_quick_l2d
Ian Rogers5793fea2013-02-14 13:33:34 -0800636 PUSH ecx // push arg2 a.hi
637 PUSH eax // push arg1 a.lo
638 fildll (%esp) // load as integer and push into st0
639 fstpl (%esp) // pop value off fp stack as double
jeffhao41005dd2012-05-09 17:58:52 -0700640 movsd (%esp), %xmm0 // place into %xmm0
Ian Rogers5793fea2013-02-14 13:33:34 -0800641 addl LITERAL(8), %esp // pop arguments
642 .cfi_adjust_cfa_offset -8
jeffhao41005dd2012-05-09 17:58:52 -0700643 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700644END_FUNCTION art_quick_l2d
jeffhao41005dd2012-05-09 17:58:52 -0700645
Ian Rogers468532e2013-08-05 10:56:33 -0700646DEFINE_FUNCTION art_quick_l2f
Ian Rogers5793fea2013-02-14 13:33:34 -0800647 PUSH ecx // push arg2 a.hi
648 PUSH eax // push arg1 a.lo
649 fildll (%esp) // load as integer and push into st0
650 fstps (%esp) // pop value off fp stack as a single
jeffhao41005dd2012-05-09 17:58:52 -0700651 movss (%esp), %xmm0 // place into %xmm0
Ian Rogers5793fea2013-02-14 13:33:34 -0800652 addl LITERAL(8), %esp // pop argument
653 .cfi_adjust_cfa_offset -8
jeffhao41005dd2012-05-09 17:58:52 -0700654 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700655END_FUNCTION art_quick_l2f
jeffhao41005dd2012-05-09 17:58:52 -0700656
Ian Rogers468532e2013-08-05 10:56:33 -0700657DEFINE_FUNCTION art_quick_d2l
Ian Rogersaeeada42013-02-13 11:28:34 -0800658 PUSH eax // alignment padding
659 PUSH ecx // pass arg2 a.hi
660 PUSH eax // pass arg1 a.lo
jeffhao1395b1e2012-06-13 18:05:13 -0700661 call SYMBOL(art_d2l) // (jdouble a)
jeffhao41005dd2012-05-09 17:58:52 -0700662 addl LITERAL(12), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800663 .cfi_adjust_cfa_offset -12
jeffhao41005dd2012-05-09 17:58:52 -0700664 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700665END_FUNCTION art_quick_d2l
jeffhao41005dd2012-05-09 17:58:52 -0700666
Ian Rogers468532e2013-08-05 10:56:33 -0700667DEFINE_FUNCTION art_quick_f2l
jeffhao41005dd2012-05-09 17:58:52 -0700668 subl LITERAL(8), %esp // alignment padding
Ian Rogers5793fea2013-02-14 13:33:34 -0800669 .cfi_adjust_cfa_offset 8
Ian Rogersaeeada42013-02-13 11:28:34 -0800670 PUSH eax // pass arg1 a
jeffhao1395b1e2012-06-13 18:05:13 -0700671 call SYMBOL(art_f2l) // (jfloat a)
jeffhao41005dd2012-05-09 17:58:52 -0700672 addl LITERAL(12), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800673 .cfi_adjust_cfa_offset -12
jeffhao41005dd2012-05-09 17:58:52 -0700674 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700675END_FUNCTION art_quick_f2l
jeffhao41005dd2012-05-09 17:58:52 -0700676
Ian Rogers468532e2013-08-05 10:56:33 -0700677DEFINE_FUNCTION art_quick_idivmod
jeffhao174651d2012-04-19 15:27:22 -0700678 cmpl LITERAL(0x80000000), %eax
679 je check_arg2 // special case
680args_ok:
Ian Rogers7caad772012-03-30 01:07:54 -0700681 cdq // edx:eax = sign extend eax
682 idiv %ecx // (edx,eax) = (edx:eax % ecx, edx:eax / ecx)
Ian Rogers7caad772012-03-30 01:07:54 -0700683 ret
jeffhao174651d2012-04-19 15:27:22 -0700684check_arg2:
685 cmpl LITERAL(-1), %ecx
686 jne args_ok
687 xorl %edx, %edx
688 ret // eax already holds min int
Ian Rogers468532e2013-08-05 10:56:33 -0700689END_FUNCTION art_quick_idivmod
Ian Rogers7caad772012-03-30 01:07:54 -0700690
Ian Rogers468532e2013-08-05 10:56:33 -0700691DEFINE_FUNCTION art_quick_ldiv
Ian Rogersa9a82542013-10-04 11:17:26 -0700692 subl LITERAL(12), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800693 .cfi_adjust_cfa_offset 12
694 PUSH ebx // pass arg4 b.hi
695 PUSH edx // pass arg3 b.lo
696 PUSH ecx // pass arg2 a.hi
Ian Rogersa9a82542013-10-04 11:17:26 -0700697 PUSH eax // pass arg1 a.lo
698 call SYMBOL(artLdiv) // (jlong a, jlong b)
699 addl LITERAL(28), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800700 .cfi_adjust_cfa_offset -28
Ian Rogers55bd45f2012-04-04 17:31:20 -0700701 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700702END_FUNCTION art_quick_ldiv
Ian Rogers55bd45f2012-04-04 17:31:20 -0700703
Ian Rogersa9a82542013-10-04 11:17:26 -0700704DEFINE_FUNCTION art_quick_lmod
705 subl LITERAL(12), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800706 .cfi_adjust_cfa_offset 12
707 PUSH ebx // pass arg4 b.hi
708 PUSH edx // pass arg3 b.lo
709 PUSH ecx // pass arg2 a.hi
Ian Rogersa9a82542013-10-04 11:17:26 -0700710 PUSH eax // pass arg1 a.lo
711 call SYMBOL(artLmod) // (jlong a, jlong b)
712 addl LITERAL(28), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800713 .cfi_adjust_cfa_offset -28
Ian Rogers55bd45f2012-04-04 17:31:20 -0700714 ret
Ian Rogersa9a82542013-10-04 11:17:26 -0700715END_FUNCTION art_quick_lmod
Ian Rogers55bd45f2012-04-04 17:31:20 -0700716
Ian Rogers468532e2013-08-05 10:56:33 -0700717DEFINE_FUNCTION art_quick_lmul
Ian Rogers5793fea2013-02-14 13:33:34 -0800718 imul %eax, %ebx // ebx = a.lo(eax) * b.hi(ebx)
719 imul %edx, %ecx // ecx = b.lo(edx) * a.hi(ecx)
720 mul %edx // edx:eax = a.lo(eax) * b.lo(edx)
721 add %ebx, %ecx
722 add %ecx, %edx // edx += (a.lo * b.hi) + (b.lo * a.hi)
jeffhao644d5312012-05-03 19:04:49 -0700723 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700724END_FUNCTION art_quick_lmul
jeffhao644d5312012-05-03 19:04:49 -0700725
Ian Rogers468532e2013-08-05 10:56:33 -0700726DEFINE_FUNCTION art_quick_lshl
jeffhao644d5312012-05-03 19:04:49 -0700727 // ecx:eax << edx
Ian Rogers141d6222012-04-05 12:23:06 -0700728 xchg %edx, %ecx
729 shld %cl,%eax,%edx
730 shl %cl,%eax
731 test LITERAL(32), %cl
732 jz 1f
733 mov %eax, %edx
734 xor %eax, %eax
7351:
736 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700737END_FUNCTION art_quick_lshl
Ian Rogers141d6222012-04-05 12:23:06 -0700738
Ian Rogers468532e2013-08-05 10:56:33 -0700739DEFINE_FUNCTION art_quick_lshr
jeffhao644d5312012-05-03 19:04:49 -0700740 // ecx:eax >> edx
Ian Rogers141d6222012-04-05 12:23:06 -0700741 xchg %edx, %ecx
jeffhao644d5312012-05-03 19:04:49 -0700742 shrd %cl,%edx,%eax
743 sar %cl,%edx
Ian Rogers141d6222012-04-05 12:23:06 -0700744 test LITERAL(32),%cl
745 jz 1f
jeffhao5121e0b2012-05-08 18:23:38 -0700746 mov %edx, %eax
747 sar LITERAL(31), %edx
Ian Rogers141d6222012-04-05 12:23:06 -07007481:
749 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700750END_FUNCTION art_quick_lshr
Ian Rogers141d6222012-04-05 12:23:06 -0700751
Ian Rogers468532e2013-08-05 10:56:33 -0700752DEFINE_FUNCTION art_quick_lushr
jeffhao644d5312012-05-03 19:04:49 -0700753 // ecx:eax >>> edx
Ian Rogers141d6222012-04-05 12:23:06 -0700754 xchg %edx, %ecx
jeffhao644d5312012-05-03 19:04:49 -0700755 shrd %cl,%edx,%eax
756 shr %cl,%edx
757 test LITERAL(32),%cl
Ian Rogers141d6222012-04-05 12:23:06 -0700758 jz 1f
jeffhao5121e0b2012-05-08 18:23:38 -0700759 mov %edx, %eax
760 xor %edx, %edx
Ian Rogers141d6222012-04-05 12:23:06 -07007611:
762 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700763END_FUNCTION art_quick_lushr
Ian Rogers141d6222012-04-05 12:23:06 -0700764
Ian Rogers468532e2013-08-05 10:56:33 -0700765DEFINE_FUNCTION art_quick_set32_instance
jeffhao9dbb23e2012-05-18 17:03:57 -0700766 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
767 mov %esp, %ebx // remember SP
jeffhao1ff4cd72012-05-21 11:17:48 -0700768 subl LITERAL(8), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800769 .cfi_adjust_cfa_offset 8
770 PUSH ebx // pass SP
jeffhao9dbb23e2012-05-18 17:03:57 -0700771 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800772 .cfi_adjust_cfa_offset 4
jeffhao9dbb23e2012-05-18 17:03:57 -0700773 mov 32(%ebx), %ebx // get referrer
Ian Rogersaeeada42013-02-13 11:28:34 -0800774 PUSH ebx // pass referrer
775 PUSH edx // pass new_val
776 PUSH ecx // pass object
777 PUSH eax // pass field_idx
jeffhao9dbb23e2012-05-18 17:03:57 -0700778 call SYMBOL(artSet32InstanceFromCode) // (field_idx, Object*, new_val, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700779 addl LITERAL(32), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800780 .cfi_adjust_cfa_offset -32
jeffhao9dbb23e2012-05-18 17:03:57 -0700781 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
782 RETURN_IF_EAX_ZERO // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -0700783END_FUNCTION art_quick_set32_instance
jeffhao9dbb23e2012-05-18 17:03:57 -0700784
Ian Rogers468532e2013-08-05 10:56:33 -0700785DEFINE_FUNCTION art_quick_set64_instance
Ian Rogersaeeada42013-02-13 11:28:34 -0800786 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
jeffhao1ff4cd72012-05-21 11:17:48 -0700787 subl LITERAL(8), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800788 .cfi_adjust_cfa_offset 8
789 PUSH esp // pass SP-8
jeffhao1ff4cd72012-05-21 11:17:48 -0700790 addl LITERAL(8), (%esp) // fix SP on stack by adding 8
jeffhao9dbb23e2012-05-18 17:03:57 -0700791 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800792 .cfi_adjust_cfa_offset 4
793 PUSH ebx // pass high half of new_val
794 PUSH edx // pass low half of new_val
795 PUSH ecx // pass object
796 PUSH eax // pass field_idx
jeffhao9dbb23e2012-05-18 17:03:57 -0700797 call SYMBOL(artSet64InstanceFromCode) // (field_idx, Object*, new_val, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700798 addl LITERAL(32), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800799 .cfi_adjust_cfa_offset -32
800 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
jeffhao9dbb23e2012-05-18 17:03:57 -0700801 RETURN_IF_EAX_ZERO // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -0700802END_FUNCTION art_quick_set64_instance
jeffhao9dbb23e2012-05-18 17:03:57 -0700803
Ian Rogers468532e2013-08-05 10:56:33 -0700804DEFINE_FUNCTION art_quick_set_obj_instance
Ian Rogersaeeada42013-02-13 11:28:34 -0800805 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
jeffhao9dbb23e2012-05-18 17:03:57 -0700806 mov %esp, %ebx // remember SP
jeffhao1ff4cd72012-05-21 11:17:48 -0700807 subl LITERAL(8), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800808 .cfi_adjust_cfa_offset 8
809 PUSH ebx // pass SP
jeffhao9dbb23e2012-05-18 17:03:57 -0700810 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800811 .cfi_adjust_cfa_offset 4
jeffhao9dbb23e2012-05-18 17:03:57 -0700812 mov 32(%ebx), %ebx // get referrer
Ian Rogersaeeada42013-02-13 11:28:34 -0800813 PUSH ebx // pass referrer
814 PUSH edx // pass new_val
815 PUSH ecx // pass object
816 PUSH eax // pass field_idx
jeffhao9dbb23e2012-05-18 17:03:57 -0700817 call SYMBOL(artSetObjInstanceFromCode) // (field_idx, Object*, new_val, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700818 addl LITERAL(32), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800819 .cfi_adjust_cfa_offset -32
jeffhao9dbb23e2012-05-18 17:03:57 -0700820 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
821 RETURN_IF_EAX_ZERO // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -0700822END_FUNCTION art_quick_set_obj_instance
jeffhao9dbb23e2012-05-18 17:03:57 -0700823
Ian Rogers468532e2013-08-05 10:56:33 -0700824DEFINE_FUNCTION art_quick_get32_instance
Ian Rogersaeeada42013-02-13 11:28:34 -0800825 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
jeffhao9dbb23e2012-05-18 17:03:57 -0700826 mov %esp, %ebx // remember SP
827 mov 32(%esp), %edx // get referrer
jeffhao1ff4cd72012-05-21 11:17:48 -0700828 subl LITERAL(12), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800829 .cfi_adjust_cfa_offset 12
830 PUSH ebx // pass SP
jeffhao9dbb23e2012-05-18 17:03:57 -0700831 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800832 .cfi_adjust_cfa_offset 4
833 PUSH edx // pass referrer
834 PUSH ecx // pass object
835 PUSH eax // pass field_idx
jeffhao9dbb23e2012-05-18 17:03:57 -0700836 call SYMBOL(artGet32InstanceFromCode) // (field_idx, Object*, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700837 addl LITERAL(32), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800838 .cfi_adjust_cfa_offset -32
jeffhao9dbb23e2012-05-18 17:03:57 -0700839 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
jeffhaod66a8752012-05-22 15:30:16 -0700840 RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -0700841END_FUNCTION art_quick_get32_instance
jeffhao9dbb23e2012-05-18 17:03:57 -0700842
Ian Rogers468532e2013-08-05 10:56:33 -0700843DEFINE_FUNCTION art_quick_get64_instance
jeffhao9dbb23e2012-05-18 17:03:57 -0700844 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
845 mov %esp, %ebx // remember SP
846 mov 32(%esp), %edx // get referrer
jeffhao1ff4cd72012-05-21 11:17:48 -0700847 subl LITERAL(12), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800848 .cfi_adjust_cfa_offset 12
849 PUSH ebx // pass SP
jeffhao9dbb23e2012-05-18 17:03:57 -0700850 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800851 .cfi_adjust_cfa_offset 4
852 PUSH edx // pass referrer
853 PUSH ecx // pass object
854 PUSH eax // pass field_idx
jeffhao9dbb23e2012-05-18 17:03:57 -0700855 call SYMBOL(artGet64InstanceFromCode) // (field_idx, Object*, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700856 addl LITERAL(32), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800857 .cfi_adjust_cfa_offset -32
jeffhao9dbb23e2012-05-18 17:03:57 -0700858 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
jeffhaod66a8752012-05-22 15:30:16 -0700859 RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -0700860END_FUNCTION art_quick_get64_instance
jeffhao9dbb23e2012-05-18 17:03:57 -0700861
Ian Rogers468532e2013-08-05 10:56:33 -0700862DEFINE_FUNCTION art_quick_get_obj_instance
jeffhao9dbb23e2012-05-18 17:03:57 -0700863 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
864 mov %esp, %ebx // remember SP
865 mov 32(%esp), %edx // get referrer
jeffhao1ff4cd72012-05-21 11:17:48 -0700866 subl LITERAL(12), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800867 .cfi_adjust_cfa_offset 12
868 PUSH ebx // pass SP
jeffhao9dbb23e2012-05-18 17:03:57 -0700869 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800870 .cfi_adjust_cfa_offset 4
871 PUSH edx // pass referrer
872 PUSH ecx // pass object
873 PUSH eax // pass field_idx
jeffhao9dbb23e2012-05-18 17:03:57 -0700874 call SYMBOL(artGetObjInstanceFromCode) // (field_idx, Object*, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700875 addl LITERAL(32), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800876 .cfi_adjust_cfa_offset -32
jeffhao9dbb23e2012-05-18 17:03:57 -0700877 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
jeffhaod66a8752012-05-22 15:30:16 -0700878 RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -0700879END_FUNCTION art_quick_get_obj_instance
jeffhao9dbb23e2012-05-18 17:03:57 -0700880
Ian Rogers468532e2013-08-05 10:56:33 -0700881DEFINE_FUNCTION art_quick_set32_static
jeffhao9dbb23e2012-05-18 17:03:57 -0700882 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
883 mov %esp, %ebx // remember SP
884 mov 32(%esp), %edx // get referrer
jeffhao1ff4cd72012-05-21 11:17:48 -0700885 subl LITERAL(12), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800886 .cfi_adjust_cfa_offset 12
887 PUSH ebx // pass SP
jeffhao9dbb23e2012-05-18 17:03:57 -0700888 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800889 .cfi_adjust_cfa_offset 4
890 PUSH edx // pass referrer
891 PUSH ecx // pass new_val
892 PUSH eax // pass field_idx
jeffhao9dbb23e2012-05-18 17:03:57 -0700893 call SYMBOL(artSet32StaticFromCode) // (field_idx, new_val, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700894 addl LITERAL(32), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800895 .cfi_adjust_cfa_offset -32
jeffhao9dbb23e2012-05-18 17:03:57 -0700896 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
897 RETURN_IF_EAX_ZERO // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -0700898END_FUNCTION art_quick_set32_static
jeffhao9dbb23e2012-05-18 17:03:57 -0700899
Ian Rogers468532e2013-08-05 10:56:33 -0700900DEFINE_FUNCTION art_quick_set64_static
Ian Rogersaeeada42013-02-13 11:28:34 -0800901 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
jeffhao9dbb23e2012-05-18 17:03:57 -0700902 mov %esp, %ebx // remember SP
jeffhao1ff4cd72012-05-21 11:17:48 -0700903 subl LITERAL(8), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800904 .cfi_adjust_cfa_offset 8
905 PUSH ebx // pass SP
jeffhao9dbb23e2012-05-18 17:03:57 -0700906 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800907 .cfi_adjust_cfa_offset 4
jeffhao9dbb23e2012-05-18 17:03:57 -0700908 mov 32(%ebx), %ebx // get referrer
Ian Rogersaeeada42013-02-13 11:28:34 -0800909 PUSH edx // pass high half of new_val
910 PUSH ecx // pass low half of new_val
911 PUSH ebx // pass referrer
912 PUSH eax // pass field_idx
913 call SYMBOL(artSet64StaticFromCode) // (field_idx, referrer, new_val, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700914 addl LITERAL(32), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800915 .cfi_adjust_cfa_offset -32
916 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
jeffhao9dbb23e2012-05-18 17:03:57 -0700917 RETURN_IF_EAX_ZERO // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -0700918END_FUNCTION art_quick_set64_static
jeffhao9dbb23e2012-05-18 17:03:57 -0700919
Ian Rogers468532e2013-08-05 10:56:33 -0700920DEFINE_FUNCTION art_quick_set_obj_static
Ian Rogersaeeada42013-02-13 11:28:34 -0800921 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
jeffhao9dbb23e2012-05-18 17:03:57 -0700922 mov %esp, %ebx // remember SP
923 mov 32(%esp), %edx // get referrer
jeffhao1ff4cd72012-05-21 11:17:48 -0700924 subl LITERAL(12), %esp // alignment padding
Ian Rogers62d6c772013-02-27 08:32:07 -0800925 .cfi_adjust_cfa_offset 12
Ian Rogersaeeada42013-02-13 11:28:34 -0800926 PUSH ebx // pass SP
jeffhao9dbb23e2012-05-18 17:03:57 -0700927 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800928 .cfi_adjust_cfa_offset 4
929 PUSH edx // pass referrer
930 PUSH ecx // pass new_val
931 PUSH eax // pass field_idx
932 call SYMBOL(artSetObjStaticFromCode) // (field_idx, new_val, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700933 addl LITERAL(32), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800934 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
jeffhao9dbb23e2012-05-18 17:03:57 -0700935 RETURN_IF_EAX_ZERO // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -0700936END_FUNCTION art_quick_set_obj_static
jeffhao9dbb23e2012-05-18 17:03:57 -0700937
Ian Rogers468532e2013-08-05 10:56:33 -0700938DEFINE_FUNCTION art_quick_get32_static
jeffhao9dbb23e2012-05-18 17:03:57 -0700939 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
940 mov %esp, %edx // remember SP
941 mov 32(%esp), %ecx // get referrer
Ian Rogersaeeada42013-02-13 11:28:34 -0800942 PUSH edx // pass SP
jeffhao9dbb23e2012-05-18 17:03:57 -0700943 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800944 .cfi_adjust_cfa_offset 4
945 PUSH ecx // pass referrer
946 PUSH eax // pass field_idx
jeffhao9dbb23e2012-05-18 17:03:57 -0700947 call SYMBOL(artGet32StaticFromCode) // (field_idx, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700948 addl LITERAL(16), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800949 .cfi_adjust_cfa_offset -16
jeffhao9dbb23e2012-05-18 17:03:57 -0700950 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
jeffhaod66a8752012-05-22 15:30:16 -0700951 RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -0700952END_FUNCTION art_quick_get32_static
jeffhao9dbb23e2012-05-18 17:03:57 -0700953
Ian Rogers468532e2013-08-05 10:56:33 -0700954DEFINE_FUNCTION art_quick_get64_static
Ian Rogersaeeada42013-02-13 11:28:34 -0800955 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
jeffhao9dbb23e2012-05-18 17:03:57 -0700956 mov %esp, %edx // remember SP
957 mov 32(%esp), %ecx // get referrer
Ian Rogersaeeada42013-02-13 11:28:34 -0800958 PUSH edx // pass SP
jeffhao9dbb23e2012-05-18 17:03:57 -0700959 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800960 .cfi_adjust_cfa_offset 4
961 PUSH ecx // pass referrer
962 PUSH eax // pass field_idx
jeffhao9dbb23e2012-05-18 17:03:57 -0700963 call SYMBOL(artGet64StaticFromCode) // (field_idx, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700964 addl LITERAL(16), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800965 .cfi_adjust_cfa_offset -16
jeffhao9dbb23e2012-05-18 17:03:57 -0700966 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
jeffhaod66a8752012-05-22 15:30:16 -0700967 RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -0700968END_FUNCTION art_quick_get64_static
jeffhao9dbb23e2012-05-18 17:03:57 -0700969
Ian Rogers468532e2013-08-05 10:56:33 -0700970DEFINE_FUNCTION art_quick_get_obj_static
jeffhao9dbb23e2012-05-18 17:03:57 -0700971 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
972 mov %esp, %edx // remember SP
973 mov 32(%esp), %ecx // get referrer
Ian Rogersaeeada42013-02-13 11:28:34 -0800974 PUSH edx // pass SP
jeffhao9dbb23e2012-05-18 17:03:57 -0700975 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800976 .cfi_adjust_cfa_offset 4
977 PUSH ecx // pass referrer
978 PUSH eax // pass field_idx
jeffhao9dbb23e2012-05-18 17:03:57 -0700979 call SYMBOL(artGetObjStaticFromCode) // (field_idx, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700980 addl LITERAL(16), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800981 .cfi_adjust_cfa_offset -16
jeffhao9dbb23e2012-05-18 17:03:57 -0700982 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
jeffhaod66a8752012-05-22 15:30:16 -0700983 RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -0700984END_FUNCTION art_quick_get_obj_static
jeffhaod66a8752012-05-22 15:30:16 -0700985
Logan Chien8dbb7082013-01-25 20:31:17 +0800986DEFINE_FUNCTION art_quick_proxy_invoke_handler
Ian Rogers7db619b2013-01-16 18:35:48 -0800987 SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME // save frame and Method*
Ian Rogersaeeada42013-02-13 11:28:34 -0800988 PUSH esp // pass SP
jeffhaod66a8752012-05-22 15:30:16 -0700989 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800990 .cfi_adjust_cfa_offset 4
991 PUSH ecx // pass receiver
992 PUSH eax // pass proxy method
Jeff Hao5fa60c32013-04-04 17:57:01 -0700993 call SYMBOL(artQuickProxyInvokeHandler) // (proxy method, receiver, Thread*, SP)
Ian Rogersaf6e67a2013-01-16 08:38:37 -0800994 movd %eax, %xmm0 // place return value also into floating point return value
995 movd %edx, %xmm1
996 punpckldq %xmm1, %xmm0
jeffhaod66a8752012-05-22 15:30:16 -0700997 addl LITERAL(44), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800998 .cfi_adjust_cfa_offset -44
jeffhaod66a8752012-05-22 15:30:16 -0700999 RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
Ian Rogersaeeada42013-02-13 11:28:34 -08001000END_FUNCTION art_quick_proxy_invoke_handler
jeffhao9dbb23e2012-05-18 17:03:57 -07001001
Ian Rogers468532e2013-08-05 10:56:33 -07001002DEFINE_FUNCTION art_quick_resolution_trampoline
1003 SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME
1004 PUSH esp // pass SP
1005 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
1006 .cfi_adjust_cfa_offset 4
1007 PUSH ecx // pass receiver
1008 PUSH eax // pass method
1009 call SYMBOL(artQuickResolutionTrampoline) // (Method* called, receiver, Thread*, SP)
1010 movl %eax, %edi // remember code pointer in EDI
1011 addl LITERAL(16), %esp // pop arguments
1012 test %eax, %eax // if code pointer is NULL goto deliver pending exception
1013 jz 1f
1014 POP eax // called method
1015 POP ecx // restore args
1016 POP edx
1017 POP ebx
1018 POP ebp // restore callee saves except EDI
1019 POP esi
1020 xchgl 0(%esp),%edi // restore EDI and place code pointer as only value on stack
1021 ret // tail call into method
10221:
1023 RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME
1024 DELIVER_PENDING_EXCEPTION
1025END_FUNCTION art_quick_resolution_trampoline
1026
1027DEFINE_FUNCTION art_quick_to_interpreter_bridge
Ian Rogers62d6c772013-02-27 08:32:07 -08001028 SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME // save frame
Ian Rogersaeeada42013-02-13 11:28:34 -08001029 mov %esp, %edx // remember SP
1030 PUSH eax // alignment padding
1031 PUSH edx // pass SP
Ian Rogers7db619b2013-01-16 18:35:48 -08001032 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -08001033 .cfi_adjust_cfa_offset 4
1034 PUSH eax // pass method
Ian Rogers468532e2013-08-05 10:56:33 -07001035 call SYMBOL(artQuickToInterpreterBridge) // (method, Thread*, SP)
Ian Rogers7db619b2013-01-16 18:35:48 -08001036 movd %eax, %xmm0 // place return value also into floating point return value
1037 movd %edx, %xmm1
1038 punpckldq %xmm1, %xmm0
Mathieu Chartier19841522013-10-22 11:29:00 -07001039 addl LITERAL(16), %esp // pop arguments
1040 .cfi_adjust_cfa_offset -16
1041 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
Ian Rogers7db619b2013-01-16 18:35:48 -08001042 RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -07001043END_FUNCTION art_quick_to_interpreter_bridge
Ian Rogers7db619b2013-01-16 18:35:48 -08001044
jeffhao7e4fcb82013-01-10 18:11:08 -08001045 /*
1046 * Routine that intercepts method calls and returns.
1047 */
Ian Rogers468532e2013-08-05 10:56:33 -07001048DEFINE_FUNCTION art_quick_instrumentation_entry
Ian Rogers62d6c772013-02-27 08:32:07 -08001049 SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME
1050 movl %esp, %edx // Save SP.
1051 PUSH eax // Save eax which will be clobbered by the callee-save method.
1052 subl LITERAL(8), %esp // Align stack.
1053 .cfi_adjust_cfa_offset 8
1054 pushl 40(%esp) // Pass LR.
Ian Rogersaeeada42013-02-13 11:28:34 -08001055 .cfi_adjust_cfa_offset 4
Ian Rogers62d6c772013-02-27 08:32:07 -08001056 PUSH edx // Pass SP.
1057 pushl %fs:THREAD_SELF_OFFSET // Pass Thread::Current().
Ian Rogersaeeada42013-02-13 11:28:34 -08001058 .cfi_adjust_cfa_offset 4
Ian Rogers62d6c772013-02-27 08:32:07 -08001059 PUSH ecx // Pass receiver.
1060 PUSH eax // Pass Method*.
1061 call SYMBOL(artInstrumentationMethodEntryFromCode) // (Method*, Object*, Thread*, SP, LR)
1062 addl LITERAL(28), %esp // Pop arguments upto saved Method*.
1063 movl 28(%esp), %edi // Restore edi.
1064 movl %eax, 28(%esp) // Place code* over edi, just under return pc.
Ian Rogers468532e2013-08-05 10:56:33 -07001065 movl LITERAL(SYMBOL(art_quick_instrumentation_exit)), 32(%esp)
Ian Rogers62d6c772013-02-27 08:32:07 -08001066 // Place instrumentation exit as return pc.
1067 movl (%esp), %eax // Restore eax.
1068 movl 8(%esp), %ecx // Restore ecx.
1069 movl 12(%esp), %edx // Restore edx.
1070 movl 16(%esp), %ebx // Restore ebx.
1071 movl 20(%esp), %ebp // Restore ebp.
1072 movl 24(%esp), %esi // Restore esi.
1073 addl LITERAL(28), %esp // Wind stack back upto code*.
1074 ret // Call method (and pop).
Ian Rogers468532e2013-08-05 10:56:33 -07001075END_FUNCTION art_quick_instrumentation_entry
Ian Rogers62d6c772013-02-27 08:32:07 -08001076
Ian Rogers468532e2013-08-05 10:56:33 -07001077DEFINE_FUNCTION art_quick_instrumentation_exit
Ian Rogers62d6c772013-02-27 08:32:07 -08001078 pushl LITERAL(0) // Push a fake return PC as there will be none on the stack.
1079 SETUP_REF_ONLY_CALLEE_SAVE_FRAME
1080 mov %esp, %ecx // Remember SP
1081 subl LITERAL(8), %esp // Save float return value.
1082 .cfi_adjust_cfa_offset 8
1083 movd %xmm0, (%esp)
1084 PUSH edx // Save gpr return value.
1085 PUSH eax
1086 subl LITERAL(8), %esp // Align stack
1087 movd %xmm0, (%esp)
1088 subl LITERAL(8), %esp // Pass float return value.
1089 .cfi_adjust_cfa_offset 8
1090 movd %xmm0, (%esp)
1091 PUSH edx // Pass gpr return value.
1092 PUSH eax
1093 PUSH ecx // Pass SP.
1094 pushl %fs:THREAD_SELF_OFFSET // Pass Thread::Current.
Ian Rogersaeeada42013-02-13 11:28:34 -08001095 .cfi_adjust_cfa_offset 4
Ian Rogers62d6c772013-02-27 08:32:07 -08001096 call SYMBOL(artInstrumentationMethodExitFromCode) // (Thread*, SP, gpr_result, fpr_result)
1097 mov %eax, %ecx // Move returned link register.
1098 addl LITERAL(32), %esp // Pop arguments.
1099 .cfi_adjust_cfa_offset -32
1100 movl %edx, %ebx // Move returned link register for deopt
1101 // (ebx is pretending to be our LR).
1102 POP eax // Restore gpr return value.
1103 POP edx
1104 movd (%esp), %xmm0 // Restore fpr return value.
1105 addl LITERAL(8), %esp
Ian Rogers5793fea2013-02-14 13:33:34 -08001106 .cfi_adjust_cfa_offset -8
Ian Rogers62d6c772013-02-27 08:32:07 -08001107 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
1108 addl LITERAL(4), %esp // Remove fake return pc.
1109 jmp *%ecx // Return.
Ian Rogers468532e2013-08-05 10:56:33 -07001110END_FUNCTION art_quick_instrumentation_exit
jeffhao162fd332013-01-08 16:21:01 -08001111
jeffhao7e4fcb82013-01-10 18:11:08 -08001112 /*
Ian Rogers62d6c772013-02-27 08:32:07 -08001113 * Instrumentation has requested that we deoptimize into the interpreter. The deoptimization
1114 * will long jump to the upcall with a special exception of -1.
jeffhao7e4fcb82013-01-10 18:11:08 -08001115 */
Logan Chien8dbb7082013-01-25 20:31:17 +08001116DEFINE_FUNCTION art_quick_deoptimize
Ian Rogers62d6c772013-02-27 08:32:07 -08001117 pushl %ebx // Fake that we were called.
Jeff Haoc1fcdf12013-04-11 13:34:01 -07001118 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME
Ian Rogers62d6c772013-02-27 08:32:07 -08001119 mov %esp, %ecx // Remember SP.
1120 subl LITERAL(8), %esp // Align stack.
1121 .cfi_adjust_cfa_offset 8
1122 PUSH ecx // Pass SP.
1123 pushl %fs:THREAD_SELF_OFFSET // Pass Thread::Current().
Ian Rogersaeeada42013-02-13 11:28:34 -08001124 .cfi_adjust_cfa_offset 4
Ian Rogers62d6c772013-02-27 08:32:07 -08001125 call SYMBOL(artDeoptimize) // artDeoptimize(Thread*, SP)
1126 int3 // Unreachable.
Ian Rogersaeeada42013-02-13 11:28:34 -08001127END_FUNCTION art_quick_deoptimize
jeffhao162fd332013-01-08 16:21:01 -08001128
jeffhao86e46712012-08-08 17:30:59 -07001129 /*
1130 * String's indexOf.
1131 *
1132 * On entry:
1133 * eax: string object (known non-null)
1134 * ecx: char to match (known <= 0xFFFF)
1135 * edx: Starting offset in string data
1136 */
Logan Chien8dbb7082013-01-25 20:31:17 +08001137DEFINE_FUNCTION art_quick_indexof
Ian Rogersaeeada42013-02-13 11:28:34 -08001138 PUSH edi // push callee save reg
jeffhao86e46712012-08-08 17:30:59 -07001139 mov STRING_COUNT_OFFSET(%eax), %ebx
1140 mov STRING_VALUE_OFFSET(%eax), %edi
1141 mov STRING_OFFSET_OFFSET(%eax), %eax
1142 testl %edx, %edx // check if start < 0
1143 jl clamp_min
1144clamp_done:
1145 cmpl %ebx, %edx // check if start >= count
1146 jge not_found
1147 lea STRING_DATA_OFFSET(%edi, %eax, 2), %edi // build a pointer to the start of string data
1148 mov %edi, %eax // save a copy in eax to later compute result
1149 lea (%edi, %edx, 2), %edi // build pointer to start of data to compare
1150 subl %edx, %ebx // compute iteration count
1151 /*
1152 * At this point we have:
1153 * eax: original start of string data
1154 * ecx: char to compare
1155 * ebx: length to compare
1156 * edi: start of data to test
1157 */
1158 mov %eax, %edx
1159 mov %ecx, %eax // put char to match in %eax
1160 mov %ebx, %ecx // put length to compare in %ecx
1161 repne scasw // find %ax, starting at [%edi], up to length %ecx
1162 jne not_found
1163 subl %edx, %edi
1164 sar LITERAL(1), %edi
1165 decl %edi // index = ((curr_ptr - orig_ptr) / 2) - 1
1166 mov %edi, %eax
Ian Rogersaeeada42013-02-13 11:28:34 -08001167 POP edi // pop callee save reg
jeffhao86e46712012-08-08 17:30:59 -07001168 ret
1169 .balign 16
1170not_found:
1171 mov LITERAL(-1), %eax // return -1 (not found)
Ian Rogersaeeada42013-02-13 11:28:34 -08001172 POP edi // pop callee save reg
jeffhao86e46712012-08-08 17:30:59 -07001173 ret
1174clamp_min:
1175 xor %edx, %edx // clamp start to 0
1176 jmp clamp_done
Ian Rogersaeeada42013-02-13 11:28:34 -08001177END_FUNCTION art_quick_indexof
jeffhao86e46712012-08-08 17:30:59 -07001178
1179 /*
1180 * String's compareTo.
1181 *
1182 * On entry:
1183 * eax: this string object (known non-null)
1184 * ecx: comp string object (known non-null)
1185 */
Logan Chien8dbb7082013-01-25 20:31:17 +08001186DEFINE_FUNCTION art_quick_string_compareto
Ian Rogersaeeada42013-02-13 11:28:34 -08001187 PUSH esi // push callee save reg
1188 PUSH edi // push callee save reg
jeffhao86e46712012-08-08 17:30:59 -07001189 mov STRING_COUNT_OFFSET(%eax), %edx
1190 mov STRING_COUNT_OFFSET(%ecx), %ebx
1191 mov STRING_VALUE_OFFSET(%eax), %esi
1192 mov STRING_VALUE_OFFSET(%ecx), %edi
1193 mov STRING_OFFSET_OFFSET(%eax), %eax
1194 mov STRING_OFFSET_OFFSET(%ecx), %ecx
1195 /* Build pointers to the start of string data */
1196 lea STRING_DATA_OFFSET(%esi, %eax, 2), %esi
1197 lea STRING_DATA_OFFSET(%edi, %ecx, 2), %edi
1198 /* Calculate min length and count diff */
1199 mov %edx, %ecx
1200 mov %edx, %eax
1201 subl %ebx, %eax
1202 cmovg %ebx, %ecx
1203 /*
1204 * At this point we have:
1205 * eax: value to return if first part of strings are equal
1206 * ecx: minimum among the lengths of the two strings
1207 * esi: pointer to this string data
1208 * edi: pointer to comp string data
1209 */
1210 repe cmpsw // find nonmatching chars in [%esi] and [%edi], up to length %ecx
1211 jne not_equal
Ian Rogersaeeada42013-02-13 11:28:34 -08001212 POP edi // pop callee save reg
1213 POP esi // pop callee save reg
jeffhao86e46712012-08-08 17:30:59 -07001214 ret
1215 .balign 16
1216not_equal:
Ian Rogers1b09b092012-08-20 15:35:52 -07001217 movzwl -2(%esi), %eax // get last compared char from this string
1218 movzwl -2(%edi), %ecx // get last compared char from comp string
jeffhao86e46712012-08-08 17:30:59 -07001219 subl %ecx, %eax // return the difference
Ian Rogersaeeada42013-02-13 11:28:34 -08001220 POP edi // pop callee save reg
1221 POP esi // pop callee save reg
jeffhao86e46712012-08-08 17:30:59 -07001222 ret
Ian Rogersaeeada42013-02-13 11:28:34 -08001223END_FUNCTION art_quick_string_compareto
jeffhao86e46712012-08-08 17:30:59 -07001224
Elliott Hughes787ec202012-03-29 17:14:15 -07001225 // TODO: implement these!
Logan Chien8dbb7082013-01-25 20:31:17 +08001226UNIMPLEMENTED art_quick_memcmp16