blob: 96794713cfa790489d9603e5cce6d3366d4cc3ef [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
Mathieu Chartier7410f292013-11-24 13:17:35 -080019#include "arch/quick_alloc_entrypoints.S"
20
Dave Allisonbbb32c22013-11-05 18:25:18 -080021// For x86, the CFA is esp+4, the address above the pushed return address on the stack.
22
Ian Rogers57b86d42012-03-27 16:05:41 -070023 /*
24 * Macro that sets up the callee save frame to conform with
Ian Rogers7caad772012-03-30 01:07:54 -070025 * Runtime::CreateCalleeSaveMethod(kSaveAll)
Ian Rogers57b86d42012-03-27 16:05:41 -070026 */
Elliott Hughes787ec202012-03-29 17:14:15 -070027MACRO0(SETUP_SAVE_ALL_CALLEE_SAVE_FRAME)
Ian Rogersaeeada42013-02-13 11:28:34 -080028 PUSH edi // Save callee saves (ebx is saved/restored by the upcall)
Dave Allisonbbb32c22013-11-05 18:25:18 -080029 .cfi_rel_offset edi, -8
Ian Rogersaeeada42013-02-13 11:28:34 -080030 PUSH esi
Dave Allisonbbb32c22013-11-05 18:25:18 -080031 .cfi_rel_offset esi, -12
Ian Rogersaeeada42013-02-13 11:28:34 -080032 PUSH ebp
Dave Allisonbbb32c22013-11-05 18:25:18 -080033 .cfi_rel_offset ebp, -16
Elliott Hughesea944212012-04-05 13:11:53 -070034 subl MACRO_LITERAL(16), %esp // Grow stack by 4 words, bottom word will hold Method*
Ian Rogersaeeada42013-02-13 11:28:34 -080035 .cfi_adjust_cfa_offset 16
Elliott Hughes787ec202012-03-29 17:14:15 -070036END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -070037
Ian Rogers7caad772012-03-30 01:07:54 -070038 /*
39 * Macro that sets up the callee save frame to conform with
40 * Runtime::CreateCalleeSaveMethod(kRefsOnly)
41 */
42MACRO0(SETUP_REF_ONLY_CALLEE_SAVE_FRAME)
Ian Rogersaeeada42013-02-13 11:28:34 -080043 PUSH edi // Save callee saves (ebx is saved/restored by the upcall)
Dave Allisonbbb32c22013-11-05 18:25:18 -080044 .cfi_rel_offset edi, -8
Ian Rogersaeeada42013-02-13 11:28:34 -080045 PUSH esi
Dave Allisonbbb32c22013-11-05 18:25:18 -080046 .cfi_rel_offset esi, -12
Ian Rogersaeeada42013-02-13 11:28:34 -080047 PUSH ebp
Dave Allisonbbb32c22013-11-05 18:25:18 -080048 .cfi_rel_offset ebp, -16
Elliott Hughesea944212012-04-05 13:11:53 -070049 subl MACRO_LITERAL(16), %esp // Grow stack by 4 words, bottom word will hold Method*
Ian Rogersaeeada42013-02-13 11:28:34 -080050 .cfi_adjust_cfa_offset 16
Ian Rogers7caad772012-03-30 01:07:54 -070051END_MACRO
52
53MACRO0(RESTORE_REF_ONLY_CALLEE_SAVE_FRAME)
Mathieu Chartier2a6c7b72013-10-16 11:16:33 -070054 addl MACRO_LITERAL(16), %esp // Unwind stack up to return address
55 POP ebp // Restore callee saves (ebx is saved/restored by the upcall)
Dave Allisonbbb32c22013-11-05 18:25:18 -080056 .cfi_restore ebp
Mathieu Chartier2a6c7b72013-10-16 11:16:33 -070057 POP esi
Dave Allisonbbb32c22013-11-05 18:25:18 -080058 .cfi_restore esi
Mathieu Chartier2a6c7b72013-10-16 11:16:33 -070059 POP edi
Dave Allisonbbb32c22013-11-05 18:25:18 -080060 .cfi_restore edi
Ian Rogersaeeada42013-02-13 11:28:34 -080061 .cfi_adjust_cfa_offset -28
Elliott Hughes787ec202012-03-29 17:14:15 -070062END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -070063
64 /*
65 * Macro that sets up the callee save frame to conform with
Ian Rogers7caad772012-03-30 01:07:54 -070066 * Runtime::CreateCalleeSaveMethod(kRefsAndArgs)
Ian Rogers57b86d42012-03-27 16:05:41 -070067 */
jeffhao9dbb23e2012-05-18 17:03:57 -070068MACRO0(SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME)
Ian Rogersaeeada42013-02-13 11:28:34 -080069 PUSH edi // Save callee saves
Dave Allisonbbb32c22013-11-05 18:25:18 -080070 .cfi_rel_offset edi, -8
Ian Rogersaeeada42013-02-13 11:28:34 -080071 PUSH esi
Dave Allisonbbb32c22013-11-05 18:25:18 -080072 .cfi_rel_offset esi, -12
Ian Rogersaeeada42013-02-13 11:28:34 -080073 PUSH ebp
Dave Allisonbbb32c22013-11-05 18:25:18 -080074 .cfi_rel_offset ebp, -16
Ian Rogersaeeada42013-02-13 11:28:34 -080075 PUSH ebx // Save args
Dave Allisonbbb32c22013-11-05 18:25:18 -080076 .cfi_rel_offset ebx, -20
Ian Rogersaeeada42013-02-13 11:28:34 -080077 PUSH edx
Dave Allisonbbb32c22013-11-05 18:25:18 -080078 .cfi_rel_offset edx, -24
Ian Rogersaeeada42013-02-13 11:28:34 -080079 PUSH ecx
Dave Allisonbbb32c22013-11-05 18:25:18 -080080 .cfi_rel_offset ecx, -28
Ian Rogersaeeada42013-02-13 11:28:34 -080081 PUSH eax // Align stack, eax will be clobbered by Method*
Dave Allisonbbb32c22013-11-05 18:25:18 -080082 .cfi_rel_offset eax, -28
Elliott Hughes787ec202012-03-29 17:14:15 -070083END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -070084
jeffhao9dbb23e2012-05-18 17:03:57 -070085MACRO0(RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME)
Elliott Hughesea944212012-04-05 13:11:53 -070086 addl MACRO_LITERAL(4), %esp // Remove padding
Ian Rogersaeeada42013-02-13 11:28:34 -080087 .cfi_adjust_cfa_offset -4
88 POP ecx // Restore args except eax
Dave Allisonbbb32c22013-11-05 18:25:18 -080089 .cfi_restore ecx
Ian Rogersaeeada42013-02-13 11:28:34 -080090 POP edx
Dave Allisonbbb32c22013-11-05 18:25:18 -080091 .cfi_restore edx
Ian Rogersaeeada42013-02-13 11:28:34 -080092 POP ebx
Dave Allisonbbb32c22013-11-05 18:25:18 -080093 .cfi_restore ebx
Ian Rogersaeeada42013-02-13 11:28:34 -080094 POP ebp // Restore callee saves
Dave Allisonbbb32c22013-11-05 18:25:18 -080095 .cfi_restore ebp
Ian Rogersaeeada42013-02-13 11:28:34 -080096 POP esi
Dave Allisonbbb32c22013-11-05 18:25:18 -080097 .cfi_restore esi
Ian Rogersaeeada42013-02-13 11:28:34 -080098 POP edi
Dave Allisonbbb32c22013-11-05 18:25:18 -080099 .cfi_restore edi
Elliott Hughes787ec202012-03-29 17:14:15 -0700100END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -0700101
102 /*
103 * Macro that set calls through to artDeliverPendingExceptionFromCode, where the pending
104 * exception is Thread::Current()->exception_.
105 */
Elliott Hughes787ec202012-03-29 17:14:15 -0700106MACRO0(DELIVER_PENDING_EXCEPTION)
Ian Rogers57b86d42012-03-27 16:05:41 -0700107 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save callee saves for throw
108 mov %esp, %ecx
109 // Outgoing argument set up
Elliott Hughesea944212012-04-05 13:11:53 -0700110 subl MACRO_LITERAL(8), %esp // Alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800111 .cfi_adjust_cfa_offset 8
112 PUSH ecx // pass SP
Ian Rogers57b86d42012-03-27 16:05:41 -0700113 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800114 .cfi_adjust_cfa_offset 4
jeffhao9dbb23e2012-05-18 17:03:57 -0700115 call SYMBOL(artDeliverPendingExceptionFromCode) // artDeliverPendingExceptionFromCode(Thread*, SP)
116 int3 // unreached
Elliott Hughes787ec202012-03-29 17:14:15 -0700117END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -0700118
Elliott Hughes787ec202012-03-29 17:14:15 -0700119MACRO2(NO_ARG_RUNTIME_EXCEPTION, c_name, cxx_name)
Ian Rogersaeeada42013-02-13 11:28:34 -0800120 DEFINE_FUNCTION VAR(c_name, 0)
Ian Rogers57b86d42012-03-27 16:05:41 -0700121 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context
122 mov %esp, %ecx
123 // Outgoing argument set up
Elliott Hughesea944212012-04-05 13:11:53 -0700124 subl MACRO_LITERAL(8), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800125 .cfi_adjust_cfa_offset 8
126 PUSH ecx // pass SP
Ian Rogers55bd45f2012-04-04 17:31:20 -0700127 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800128 .cfi_adjust_cfa_offset 4
Elliott Hughes787ec202012-03-29 17:14:15 -0700129 call VAR(cxx_name, 1) // cxx_name(Thread*, SP)
Ian Rogers57b86d42012-03-27 16:05:41 -0700130 int3 // unreached
Ian Rogersaeeada42013-02-13 11:28:34 -0800131 END_FUNCTION VAR(c_name, 0)
Elliott Hughes787ec202012-03-29 17:14:15 -0700132END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -0700133
Elliott Hughes787ec202012-03-29 17:14:15 -0700134MACRO2(ONE_ARG_RUNTIME_EXCEPTION, c_name, cxx_name)
Ian Rogersaeeada42013-02-13 11:28:34 -0800135 DEFINE_FUNCTION VAR(c_name, 0)
Ian Rogers57b86d42012-03-27 16:05:41 -0700136 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context
137 mov %esp, %ecx
138 // Outgoing argument set up
Ian Rogersaeeada42013-02-13 11:28:34 -0800139 PUSH eax // alignment padding
140 PUSH ecx // pass SP
Ian Rogers57b86d42012-03-27 16:05:41 -0700141 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800142 .cfi_adjust_cfa_offset 4
143 PUSH eax // pass arg1
Elliott Hughes787ec202012-03-29 17:14:15 -0700144 call VAR(cxx_name, 1) // cxx_name(arg1, Thread*, SP)
Ian Rogers57b86d42012-03-27 16:05:41 -0700145 int3 // unreached
Ian Rogersaeeada42013-02-13 11:28:34 -0800146 END_FUNCTION VAR(c_name, 0)
Elliott Hughes787ec202012-03-29 17:14:15 -0700147END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -0700148
Elliott Hughes787ec202012-03-29 17:14:15 -0700149MACRO2(TWO_ARG_RUNTIME_EXCEPTION, c_name, cxx_name)
Ian Rogersaeeada42013-02-13 11:28:34 -0800150 DEFINE_FUNCTION VAR(c_name, 0)
Ian Rogers57b86d42012-03-27 16:05:41 -0700151 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context
152 mov %esp, %edx
153 // Outgoing argument set up
Ian Rogersaeeada42013-02-13 11:28:34 -0800154 PUSH edx // pass SP
Ian Rogers57b86d42012-03-27 16:05:41 -0700155 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800156 .cfi_adjust_cfa_offset 4
157 PUSH ecx // pass arg2
158 PUSH eax // pass arg1
Ian Rogers7caad772012-03-30 01:07:54 -0700159 call VAR(cxx_name, 1) // cxx_name(arg1, arg2, Thread*, SP)
Ian Rogers57b86d42012-03-27 16:05:41 -0700160 int3 // unreached
Ian Rogersaeeada42013-02-13 11:28:34 -0800161 END_FUNCTION VAR(c_name, 0)
Elliott Hughes787ec202012-03-29 17:14:15 -0700162END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -0700163
164 /*
165 * Called by managed code to create and deliver a NullPointerException.
166 */
Ian Rogers468532e2013-08-05 10:56:33 -0700167NO_ARG_RUNTIME_EXCEPTION art_quick_throw_null_pointer_exception, artThrowNullPointerExceptionFromCode
Ian Rogers57b86d42012-03-27 16:05:41 -0700168
169 /*
170 * Called by managed code to create and deliver an ArithmeticException.
171 */
Ian Rogers468532e2013-08-05 10:56:33 -0700172NO_ARG_RUNTIME_EXCEPTION art_quick_throw_div_zero, artThrowDivZeroFromCode
Ian Rogers57b86d42012-03-27 16:05:41 -0700173
174 /*
Ian Rogers57b86d42012-03-27 16:05:41 -0700175 * Called by managed code to create and deliver a StackOverflowError.
176 */
Ian Rogers468532e2013-08-05 10:56:33 -0700177NO_ARG_RUNTIME_EXCEPTION art_quick_throw_stack_overflow, artThrowStackOverflowFromCode
Ian Rogers57b86d42012-03-27 16:05:41 -0700178
179 /*
Elliott Hughes787ec202012-03-29 17:14:15 -0700180 * Called by managed code, saves callee saves and then calls artThrowException
181 * that will place a mock Method* at the bottom of the stack. Arg1 holds the exception.
182 */
Ian Rogers468532e2013-08-05 10:56:33 -0700183ONE_ARG_RUNTIME_EXCEPTION art_quick_deliver_exception, artDeliverExceptionFromCode
Elliott Hughes787ec202012-03-29 17:14:15 -0700184
185 /*
Ian Rogers57b86d42012-03-27 16:05:41 -0700186 * Called by managed code to create and deliver a NoSuchMethodError.
187 */
Ian Rogers468532e2013-08-05 10:56:33 -0700188ONE_ARG_RUNTIME_EXCEPTION art_quick_throw_no_such_method, artThrowNoSuchMethodFromCode
Ian Rogers57b86d42012-03-27 16:05:41 -0700189
190 /*
Elliott Hughes787ec202012-03-29 17:14:15 -0700191 * Called by managed code to create and deliver an ArrayIndexOutOfBoundsException. Arg1 holds
192 * index, arg2 holds limit.
193 */
Ian Rogers468532e2013-08-05 10:56:33 -0700194TWO_ARG_RUNTIME_EXCEPTION art_quick_throw_array_bounds, artThrowArrayBoundsFromCode
Elliott Hughes787ec202012-03-29 17:14:15 -0700195
196 /*
Ian Rogers57b86d42012-03-27 16:05:41 -0700197 * All generated callsites for interface invokes and invocation slow paths will load arguments
198 * as usual - except instead of loading arg0/r0 with the target Method*, arg0/r0 will contain
199 * the method_idx. This wrapper will save arg1-arg3, load the caller's Method*, align the
200 * stack and call the appropriate C helper.
201 * NOTE: "this" is first visible argument of the target, and so can be found in arg1/r1.
202 *
203 * The helper will attempt to locate the target and return a 64-bit result in r0/r1 consisting
204 * of the target Method* in r0 and method->code_ in r1.
205 *
206 * If unsuccessful, the helper will return NULL/NULL. There will bea pending exception in the
207 * thread and we branch to another stub to deliver it.
208 *
209 * On success this wrapper will restore arguments and *jump* to the target, leaving the lr
210 * pointing back to the original caller.
211 */
Elliott Hughes787ec202012-03-29 17:14:15 -0700212MACRO2(INVOKE_TRAMPOLINE, c_name, cxx_name)
Ian Rogersaeeada42013-02-13 11:28:34 -0800213 DEFINE_FUNCTION VAR(c_name, 0)
Ian Rogers7caad772012-03-30 01:07:54 -0700214 // Set up the callee save frame to conform with Runtime::CreateCalleeSaveMethod(kRefsAndArgs)
215 // return address
Ian Rogersaeeada42013-02-13 11:28:34 -0800216 PUSH edi
Dave Allisonbbb32c22013-11-05 18:25:18 -0800217 .cfi_rel_offset edi, -8
Ian Rogersaeeada42013-02-13 11:28:34 -0800218 PUSH esi
Dave Allisonbbb32c22013-11-05 18:25:18 -0800219 .cfi_rel_offset esi, -12
Ian Rogersaeeada42013-02-13 11:28:34 -0800220 PUSH ebp
Dave Allisonbbb32c22013-11-05 18:25:18 -0800221 .cfi_rel_offset ebp, -16
222 PUSH ebx // Save args
223 .cfi_rel_offset ebx, -20
Ian Rogersaeeada42013-02-13 11:28:34 -0800224 PUSH edx
Dave Allisonbbb32c22013-11-05 18:25:18 -0800225 .cfi_rel_offset edx, -24
Ian Rogersaeeada42013-02-13 11:28:34 -0800226 PUSH ecx
Dave Allisonbbb32c22013-11-05 18:25:18 -0800227 .cfi_rel_offset ecx, -28
228 PUSH eax // <-- callee save Method* to go here
229 .cfi_rel_offset eax, -32
Ian Rogers7caad772012-03-30 01:07:54 -0700230 movl %esp, %edx // remember SP
231 // Outgoing argument set up
Elliott Hughesea944212012-04-05 13:11:53 -0700232 subl MACRO_LITERAL(12), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800233 .cfi_adjust_cfa_offset 12
234 PUSH edx // pass SP
Ian Rogers7caad772012-03-30 01:07:54 -0700235 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800236 .cfi_adjust_cfa_offset 4
Ian Rogers7caad772012-03-30 01:07:54 -0700237 pushl 32(%edx) // pass caller Method*
Ian Rogersaeeada42013-02-13 11:28:34 -0800238 .cfi_adjust_cfa_offset 4
239 PUSH ecx // pass arg2
240 PUSH eax // pass arg1
Ian Rogers7caad772012-03-30 01:07:54 -0700241 call VAR(cxx_name, 1) // cxx_name(arg1, arg2, arg3, Thread*, SP)
242 movl %edx, %edi // save code pointer in EDI
Elliott Hughesea944212012-04-05 13:11:53 -0700243 addl MACRO_LITERAL(36), %esp // Pop arguments skip eax
Ian Rogersaeeada42013-02-13 11:28:34 -0800244 .cfi_adjust_cfa_offset -36
Dave Allisonbbb32c22013-11-05 18:25:18 -0800245 POP ecx // Restore args except eax
246 .cfi_restore ecx
Ian Rogersaeeada42013-02-13 11:28:34 -0800247 POP edx
Dave Allisonbbb32c22013-11-05 18:25:18 -0800248 .cfi_restore edx
Ian Rogersaeeada42013-02-13 11:28:34 -0800249 POP ebx
Dave Allisonbbb32c22013-11-05 18:25:18 -0800250 .cfi_restore ebx
251 POP ebp // Restore callee saves
252 .cfi_restore ebp
Ian Rogersaeeada42013-02-13 11:28:34 -0800253 POP esi
Dave Allisonbbb32c22013-11-05 18:25:18 -0800254 .cfi_restore esi
Ian Rogers7caad772012-03-30 01:07:54 -0700255 // Swap EDI callee save with code pointer.
256 xchgl %edi, (%esp)
257 testl %eax, %eax // Branch forward if exception pending.
258 jz 1f
259 // Tail call to intended method.
260 ret
2611:
jeffhao20b5c6c2012-05-21 14:15:18 -0700262 addl MACRO_LITERAL(4), %esp // Pop code pointer off stack
Ian Rogers5793fea2013-02-14 13:33:34 -0800263 .cfi_adjust_cfa_offset -4
Ian Rogers7caad772012-03-30 01:07:54 -0700264 DELIVER_PENDING_EXCEPTION
Ian Rogersaeeada42013-02-13 11:28:34 -0800265 END_FUNCTION VAR(c_name, 0)
Elliott Hughes787ec202012-03-29 17:14:15 -0700266END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -0700267
Logan Chien8dbb7082013-01-25 20:31:17 +0800268INVOKE_TRAMPOLINE art_quick_invoke_interface_trampoline, artInvokeInterfaceTrampoline
269INVOKE_TRAMPOLINE art_quick_invoke_interface_trampoline_with_access_check, artInvokeInterfaceTrampolineWithAccessCheck
Ian Rogers57b86d42012-03-27 16:05:41 -0700270
Logan Chien8dbb7082013-01-25 20:31:17 +0800271INVOKE_TRAMPOLINE art_quick_invoke_static_trampoline_with_access_check, artInvokeStaticTrampolineWithAccessCheck
272INVOKE_TRAMPOLINE art_quick_invoke_direct_trampoline_with_access_check, artInvokeDirectTrampolineWithAccessCheck
273INVOKE_TRAMPOLINE art_quick_invoke_super_trampoline_with_access_check, artInvokeSuperTrampolineWithAccessCheck
274INVOKE_TRAMPOLINE art_quick_invoke_virtual_trampoline_with_access_check, artInvokeVirtualTrampolineWithAccessCheck
Ian Rogers57b86d42012-03-27 16:05:41 -0700275
Jeff Hao5d917302013-02-27 17:57:33 -0800276 /*
Jeff Hao6474d192013-03-26 14:08:09 -0700277 * Quick invocation stub.
278 * On entry:
279 * [sp] = return address
280 * [sp + 4] = method pointer
281 * [sp + 8] = argument array or NULL for no argument methods
282 * [sp + 12] = size of argument array in bytes
283 * [sp + 16] = (managed) thread pointer
284 * [sp + 20] = JValue* result
285 * [sp + 24] = result type char
Jeff Hao5d917302013-02-27 17:57:33 -0800286 */
287DEFINE_FUNCTION art_quick_invoke_stub
288 PUSH ebp // save ebp
Dave Allisonbbb32c22013-11-05 18:25:18 -0800289 .cfi_rel_offset ebp, -8
Jeff Hao5d917302013-02-27 17:57:33 -0800290 PUSH ebx // save ebx
Dave Allisonbbb32c22013-11-05 18:25:18 -0800291 .cfi_rel_offset ebx, -12
Jeff Hao5d917302013-02-27 17:57:33 -0800292 mov %esp, %ebp // copy value of stack pointer into base pointer
293 .cfi_def_cfa_register ebp
294 mov 20(%ebp), %ebx // get arg array size
295 addl LITERAL(28), %ebx // reserve space for return addr, method*, ebx, and ebp in frame
Jeff Hao6474d192013-03-26 14:08:09 -0700296 andl LITERAL(0xFFFFFFF0), %ebx // align frame size to 16 bytes
Jeff Hao5d917302013-02-27 17:57:33 -0800297 subl LITERAL(12), %ebx // remove space for return address, ebx, and ebp
298 subl %ebx, %esp // reserve stack space for argument array
299 lea 4(%esp), %eax // use stack pointer + method ptr as dest for memcpy
300 pushl 20(%ebp) // push size of region to memcpy
301 pushl 16(%ebp) // push arg array as source of memcpy
302 pushl %eax // push stack pointer as destination of memcpy
303 call SYMBOL(memcpy) // (void*, const void*, size_t)
304 addl LITERAL(12), %esp // pop arguments to memcpy
305 movl LITERAL(0), (%esp) // store NULL for method*
306 mov 12(%ebp), %eax // move method pointer into eax
307 mov 4(%esp), %ecx // copy arg1 into ecx
308 mov 8(%esp), %edx // copy arg2 into edx
309 mov 12(%esp), %ebx // copy arg3 into ebx
Ian Rogers225ade22013-03-18 17:45:44 -0700310 call *METHOD_CODE_OFFSET(%eax) // call the method
Jeff Hao5d917302013-02-27 17:57:33 -0800311 mov %ebp, %esp // restore stack pointer
Dave Allisonbbb32c22013-11-05 18:25:18 -0800312 .cfi_def_cfa_register esp
Jeff Hao5d917302013-02-27 17:57:33 -0800313 POP ebx // pop ebx
Dave Allisonbbb32c22013-11-05 18:25:18 -0800314 .cfi_restore ebx
Jeff Hao5d917302013-02-27 17:57:33 -0800315 POP ebp // pop ebp
Dave Allisonbbb32c22013-11-05 18:25:18 -0800316 .cfi_restore ebp
Jeff Hao5d917302013-02-27 17:57:33 -0800317 mov 20(%esp), %ecx // get result pointer
Jeff Hao6474d192013-03-26 14:08:09 -0700318 cmpl LITERAL(68), 24(%esp) // test if result type char == 'D'
319 je return_double_quick
320 cmpl LITERAL(70), 24(%esp) // test if result type char == 'F'
321 je return_float_quick
Jeff Hao5d917302013-02-27 17:57:33 -0800322 mov %eax, (%ecx) // store the result
323 mov %edx, 4(%ecx) // store the other half of the result
Jeff Hao6474d192013-03-26 14:08:09 -0700324 ret
325return_double_quick:
326return_float_quick:
Jeff Hao5d917302013-02-27 17:57:33 -0800327 movsd %xmm0, (%ecx) // store the floating point result
328 ret
329END_FUNCTION art_quick_invoke_stub
330
Ian Rogersd36c52e2012-04-09 16:29:25 -0700331MACRO3(NO_ARG_DOWNCALL, c_name, cxx_name, return_macro)
Ian Rogersaeeada42013-02-13 11:28:34 -0800332 DEFINE_FUNCTION VAR(c_name, 0)
Ian Rogersd36c52e2012-04-09 16:29:25 -0700333 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
334 mov %esp, %edx // remember SP
335 // Outgoing argument set up
336 subl MACRO_LITERAL(8), %esp // push padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800337 .cfi_adjust_cfa_offset 8
338 PUSH edx // pass SP
Ian Rogersd36c52e2012-04-09 16:29:25 -0700339 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800340 .cfi_adjust_cfa_offset 4
Ian Rogersd36c52e2012-04-09 16:29:25 -0700341 call VAR(cxx_name, 1) // cxx_name(Thread*, SP)
342 addl MACRO_LITERAL(16), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800343 .cfi_adjust_cfa_offset -16
Ian Rogersd36c52e2012-04-09 16:29:25 -0700344 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
Elliott Hughes754caaa2012-04-10 10:57:36 -0700345 CALL_MACRO(return_macro, 2) // return or deliver exception
Ian Rogersaeeada42013-02-13 11:28:34 -0800346 END_FUNCTION VAR(c_name, 0)
Ian Rogersd36c52e2012-04-09 16:29:25 -0700347END_MACRO
348
349MACRO3(ONE_ARG_DOWNCALL, c_name, cxx_name, return_macro)
Ian Rogersaeeada42013-02-13 11:28:34 -0800350 DEFINE_FUNCTION VAR(c_name, 0)
Ian Rogersd36c52e2012-04-09 16:29:25 -0700351 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
352 mov %esp, %edx // remember SP
353 // Outgoing argument set up
Ian Rogersaeeada42013-02-13 11:28:34 -0800354 PUSH eax // push padding
355 PUSH edx // pass SP
Ian Rogersd36c52e2012-04-09 16:29:25 -0700356 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800357 .cfi_adjust_cfa_offset 4
358 PUSH eax // pass arg1
Ian Rogersd36c52e2012-04-09 16:29:25 -0700359 call VAR(cxx_name, 1) // cxx_name(arg1, Thread*, SP)
360 addl MACRO_LITERAL(16), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800361 .cfi_adjust_cfa_offset -16
Ian Rogersd36c52e2012-04-09 16:29:25 -0700362 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
Elliott Hughes754caaa2012-04-10 10:57:36 -0700363 CALL_MACRO(return_macro, 2) // return or deliver exception
Ian Rogersaeeada42013-02-13 11:28:34 -0800364 END_FUNCTION VAR(c_name, 0)
Ian Rogersd36c52e2012-04-09 16:29:25 -0700365END_MACRO
366
367MACRO3(TWO_ARG_DOWNCALL, c_name, cxx_name, return_macro)
Ian Rogersaeeada42013-02-13 11:28:34 -0800368 DEFINE_FUNCTION VAR(c_name, 0)
Ian Rogers7caad772012-03-30 01:07:54 -0700369 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
370 mov %esp, %edx // remember SP
371 // Outgoing argument set up
Ian Rogersaeeada42013-02-13 11:28:34 -0800372 PUSH edx // pass SP
Ian Rogers7caad772012-03-30 01:07:54 -0700373 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800374 .cfi_adjust_cfa_offset 4
375 PUSH ecx // pass arg2
376 PUSH eax // pass arg1
Ian Rogersd36c52e2012-04-09 16:29:25 -0700377 call VAR(cxx_name, 1) // cxx_name(arg1, arg2, Thread*, SP)
Elliott Hughesea944212012-04-05 13:11:53 -0700378 addl MACRO_LITERAL(16), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800379 .cfi_adjust_cfa_offset -16
Ian Rogers7caad772012-03-30 01:07:54 -0700380 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
Elliott Hughes754caaa2012-04-10 10:57:36 -0700381 CALL_MACRO(return_macro, 2) // return or deliver exception
Ian Rogersaeeada42013-02-13 11:28:34 -0800382 END_FUNCTION VAR(c_name, 0)
Ian Rogers7caad772012-03-30 01:07:54 -0700383END_MACRO
384
Ian Rogersd36c52e2012-04-09 16:29:25 -0700385MACRO3(THREE_ARG_DOWNCALL, c_name, cxx_name, return_macro)
Ian Rogersaeeada42013-02-13 11:28:34 -0800386 DEFINE_FUNCTION VAR(c_name, 0)
Ian Rogers7caad772012-03-30 01:07:54 -0700387 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
388 mov %esp, %ebx // remember SP
389 // Outgoing argument set up
Elliott Hughesea944212012-04-05 13:11:53 -0700390 subl MACRO_LITERAL(12), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800391 .cfi_adjust_cfa_offset 12
392 PUSH ebx // pass SP
Ian Rogers7caad772012-03-30 01:07:54 -0700393 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800394 .cfi_adjust_cfa_offset 4
395 PUSH edx // pass arg3
396 PUSH ecx // pass arg2
397 PUSH eax // pass arg1
Ian Rogersd36c52e2012-04-09 16:29:25 -0700398 call VAR(cxx_name, 1) // cxx_name(arg1, arg2, arg3, Thread*, SP)
Elliott Hughesea944212012-04-05 13:11:53 -0700399 addl MACRO_LITERAL(32), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800400 .cfi_adjust_cfa_offset -32
Ian Rogers7caad772012-03-30 01:07:54 -0700401 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
Elliott Hughes754caaa2012-04-10 10:57:36 -0700402 CALL_MACRO(return_macro, 2) // return or deliver exception
Ian Rogersaeeada42013-02-13 11:28:34 -0800403 END_FUNCTION VAR(c_name, 0)
Ian Rogersd36c52e2012-04-09 16:29:25 -0700404END_MACRO
405
Mathieu Chartier590fee92013-09-13 13:46:47 -0700406MACRO0(RETURN_IF_RESULT_IS_NON_ZERO)
Ian Rogers7caad772012-03-30 01:07:54 -0700407 testl %eax, %eax // eax == 0 ?
Ian Rogersd36c52e2012-04-09 16:29:25 -0700408 jz 1f // if eax == 0 goto 1
409 ret // return
4101: // deliver exception on current thread
Ian Rogers7caad772012-03-30 01:07:54 -0700411 DELIVER_PENDING_EXCEPTION
412END_MACRO
413
Ian Rogersd36c52e2012-04-09 16:29:25 -0700414MACRO0(RETURN_IF_EAX_ZERO)
415 testl %eax, %eax // eax == 0 ?
416 jnz 1f // if eax != 0 goto 1
417 ret // return
4181: // deliver exception on current thread
Ian Rogers7caad772012-03-30 01:07:54 -0700419 DELIVER_PENDING_EXCEPTION
Ian Rogersd36c52e2012-04-09 16:29:25 -0700420END_MACRO
Ian Rogers7caad772012-03-30 01:07:54 -0700421
jeffhaod66a8752012-05-22 15:30:16 -0700422MACRO0(RETURN_OR_DELIVER_PENDING_EXCEPTION)
423 mov %fs:THREAD_EXCEPTION_OFFSET, %ebx // get exception field
424 testl %ebx, %ebx // ebx == 0 ?
425 jnz 1f // if ebx != 0 goto 1
426 ret // return
4271: // deliver exception on current thread
428 DELIVER_PENDING_EXCEPTION
429END_MACRO
430
Mathieu Chartier7410f292013-11-24 13:17:35 -0800431// Generate the allocation entrypoints for each allocator.
432GENERATE_ALL_ALLOC_ENTRYPOINTS
Ian Rogersd36c52e2012-04-09 16:29:25 -0700433
Mathieu Chartier590fee92013-09-13 13:46:47 -0700434TWO_ARG_DOWNCALL art_quick_resolve_string, artResolveStringFromCode, RETURN_IF_RESULT_IS_NON_ZERO
435TWO_ARG_DOWNCALL art_quick_initialize_static_storage, artInitializeStaticStorageFromCode, RETURN_IF_RESULT_IS_NON_ZERO
436TWO_ARG_DOWNCALL art_quick_initialize_type, artInitializeTypeFromCode, RETURN_IF_RESULT_IS_NON_ZERO
437TWO_ARG_DOWNCALL art_quick_initialize_type_and_verify_access, artInitializeTypeAndVerifyAccessFromCode, RETURN_IF_RESULT_IS_NON_ZERO
Ian Rogersd36c52e2012-04-09 16:29:25 -0700438
Ian Rogers468532e2013-08-05 10:56:33 -0700439TWO_ARG_DOWNCALL art_quick_handle_fill_data, artHandleFillArrayDataFromCode, RETURN_IF_EAX_ZERO
Ian Rogers7caad772012-03-30 01:07:54 -0700440
Ian Rogersd9c4fc92013-10-01 19:45:43 -0700441DEFINE_FUNCTION art_quick_lock_object
442 testl %eax, %eax // null check object/eax
443 jz slow_lock
444retry_lock:
445 movl LOCK_WORD_OFFSET(%eax), %ecx // ecx := lock word
Mathieu Chartierad2541a2013-10-25 10:05:23 -0700446 test LITERAL(0xC0000000), %ecx // test the 2 high bits.
447 jne slow_lock // slow path if either of the two high bits are set.
Ian Rogersd9c4fc92013-10-01 19:45:43 -0700448 movl %fs:THREAD_ID_OFFSET, %edx // edx := thread id
449 test %ecx, %ecx
Ian Rogersd9c4fc92013-10-01 19:45:43 -0700450 jnz already_thin // lock word contains a thin lock
451 // unlocked case - %edx holds thread id with count of 0
452 movl %eax, %ecx // remember object in case of retry
453 xor %eax, %eax // eax == 0 for comparison with lock word in cmpxchg
454 lock cmpxchg %edx, LOCK_WORD_OFFSET(%ecx)
455 jnz cmpxchg_fail // cmpxchg failed retry
456 ret
457cmpxchg_fail:
458 movl %ecx, %eax // restore eax
459 jmp retry_lock
460already_thin:
461 cmpw %ax, %dx // do we hold the lock already?
462 jne slow_lock
463 addl LITERAL(65536), %eax // increment recursion count
Mathieu Chartierad2541a2013-10-25 10:05:23 -0700464 test LITERAL(0xC0000000), %eax // overflowed if either of top two bits are set
465 jne slow_lock // count overflowed so go slow
Ian Rogersd9c4fc92013-10-01 19:45:43 -0700466 movl %eax, LOCK_WORD_OFFSET(%ecx) // update lockword, cmpxchg not necessary as we hold lock
467 ret
468slow_lock:
469 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
470 mov %esp, %edx // remember SP
471 // Outgoing argument set up
472 PUSH eax // push padding
473 PUSH edx // pass SP
474 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
475 .cfi_adjust_cfa_offset 4
476 PUSH eax // pass object
477 call artLockObjectFromCode // artLockObjectFromCode(object, Thread*, SP)
478 addl MACRO_LITERAL(16), %esp // pop arguments
479 .cfi_adjust_cfa_offset -16
480 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
481 RETURN_IF_EAX_ZERO
482END_FUNCTION art_quick_lock_object
483
484DEFINE_FUNCTION art_quick_unlock_object
485 testl %eax, %eax // null check object/eax
486 jz slow_unlock
487 movl LOCK_WORD_OFFSET(%eax), %ecx // ecx := lock word
488 movl %fs:THREAD_ID_OFFSET, %edx // edx := thread id
489 test %ecx, %ecx
490 jb slow_unlock // lock word contains a monitor
491 cmpw %cx, %dx // does the thread id match?
492 jne slow_unlock
493 cmpl LITERAL(65536), %ecx
494 jae recursive_thin_unlock
495 movl LITERAL(0), LOCK_WORD_OFFSET(%eax)
496 ret
497recursive_thin_unlock:
498 subl LITERAL(65536), %ecx
499 mov %ecx, LOCK_WORD_OFFSET(%eax)
500 ret
501slow_unlock:
502 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
503 mov %esp, %edx // remember SP
504 // Outgoing argument set up
505 PUSH eax // push padding
506 PUSH edx // pass SP
507 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
508 .cfi_adjust_cfa_offset 4
509 PUSH eax // pass object
510 call artUnlockObjectFromCode // artUnlockObjectFromCode(object, Thread*, SP)
511 addl MACRO_LITERAL(16), %esp // pop arguments
512 .cfi_adjust_cfa_offset -16
513 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
514 RETURN_IF_EAX_ZERO
515END_FUNCTION art_quick_unlock_object
516
Ian Rogers468532e2013-08-05 10:56:33 -0700517DEFINE_FUNCTION art_quick_is_assignable
Ian Rogersaeeada42013-02-13 11:28:34 -0800518 PUSH eax // alignment padding
Ian Rogersa9a82542013-10-04 11:17:26 -0700519 PUSH ecx // pass arg2 - obj->klass
520 PUSH eax // pass arg1 - checked class
521 call SYMBOL(artIsAssignableFromCode) // (Class* klass, Class* ref_klass)
Ian Rogers55bd45f2012-04-04 17:31:20 -0700522 addl LITERAL(12), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800523 .cfi_adjust_cfa_offset -12
Ian Rogers7caad772012-03-30 01:07:54 -0700524 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700525END_FUNCTION art_quick_is_assignable
Ian Rogers7caad772012-03-30 01:07:54 -0700526
Ian Rogersa9a82542013-10-04 11:17:26 -0700527DEFINE_FUNCTION art_quick_check_cast
528 PUSH eax // alignment padding
529 PUSH ecx // pass arg2 - obj->klass
Dave Allisonbbb32c22013-11-05 18:25:18 -0800530 .cfi_rel_offset ecx, -12
Ian Rogersa9a82542013-10-04 11:17:26 -0700531 PUSH eax // pass arg1 - checked class
Dave Allisonbbb32c22013-11-05 18:25:18 -0800532 .cfi_rel_offset eax, -16
Ian Rogersa9a82542013-10-04 11:17:26 -0700533 call SYMBOL(artIsAssignableFromCode) // (Class* klass, Class* ref_klass)
534 testl %eax, %eax
535 jz 1f // jump forward if not assignable
536 addl LITERAL(12), %esp // pop arguments
537 .cfi_adjust_cfa_offset -12
538 ret
5391:
540 POP eax // pop arguments
Dave Allisonbbb32c22013-11-05 18:25:18 -0800541 .cfi_restore eax
Ian Rogersa9a82542013-10-04 11:17:26 -0700542 POP ecx
Dave Allisonbbb32c22013-11-05 18:25:18 -0800543 .cfi_restore ecx
Ian Rogersa9a82542013-10-04 11:17:26 -0700544 addl LITERAL(4), %esp
545 .cfi_adjust_cfa_offset -12
546 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context
547 mov %esp, %edx
548 // Outgoing argument set up
549 PUSH edx // pass SP
550 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
551 .cfi_adjust_cfa_offset 4
552 PUSH ecx // pass arg2
553 PUSH eax // pass arg1
554 call SYMBOL(artThrowClassCastException) // (Class* a, Class* b, Thread*, SP)
555 int3 // unreached
556END_FUNCTION art_quick_check_cast
557
558 /*
559 * Entry from managed code for array put operations of objects where the value being stored
560 * needs to be checked for compatibility.
561 * eax = array, ecx = index, edx = value
562 */
563DEFINE_FUNCTION art_quick_aput_obj_with_null_and_bound_check
564 testl %eax, %eax
565 jnz art_quick_aput_obj_with_bound_check
566 jmp art_quick_throw_null_pointer_exception
567END_FUNCTION art_quick_aput_obj_with_null_and_bound_check
568
569DEFINE_FUNCTION art_quick_aput_obj_with_bound_check
570 movl ARRAY_LENGTH_OFFSET(%eax), %ebx
571 cmpl %ebx, %ecx
572 jb art_quick_aput_obj
573 mov %ecx, %eax
574 mov %ebx, %ecx
575 jmp art_quick_throw_array_bounds
576END_FUNCTION art_quick_aput_obj_with_bound_check
577
578DEFINE_FUNCTION art_quick_aput_obj
579 test %edx, %edx // store of null
580 jz do_aput_null
581 movl CLASS_OFFSET(%eax), %ebx
582 movl CLASS_COMPONENT_TYPE_OFFSET(%ebx), %ebx
583 cmpl CLASS_OFFSET(%edx), %ebx // value's type == array's component type - trivial assignability
584 jne check_assignability
585do_aput:
586 movl %edx, OBJECT_ARRAY_DATA_OFFSET(%eax, %ecx, 4)
587 movl %fs:THREAD_CARD_TABLE_OFFSET, %edx
588 shrl LITERAL(7), %eax
589 movb %dl, (%edx, %eax)
590 ret
591do_aput_null:
592 movl %edx, OBJECT_ARRAY_DATA_OFFSET(%eax, %ecx, 4)
593 ret
594check_assignability:
595 PUSH eax // save arguments
596 PUSH ecx
597 PUSH edx
598 subl LITERAL(8), %esp // alignment padding
599 .cfi_adjust_cfa_offset 8
600 pushl CLASS_OFFSET(%edx) // pass arg2 - type of the value to be stored
601 .cfi_adjust_cfa_offset 4
602 PUSH ebx // pass arg1 - component type of the array
603 call SYMBOL(artIsAssignableFromCode) // (Class* a, Class* b)
604 addl LITERAL(16), %esp // pop arguments
605 .cfi_adjust_cfa_offset -16
606 testl %eax, %eax
607 jz throw_array_store_exception
608 POP edx
609 POP ecx
610 POP eax
611 movl %edx, OBJECT_ARRAY_DATA_OFFSET(%eax, %ecx, 4) // do the aput
612 movl %fs:THREAD_CARD_TABLE_OFFSET, %edx
613 shrl LITERAL(7), %eax
614 movb %dl, (%edx, %eax)
615 ret
616throw_array_store_exception:
617 POP edx
618 POP ecx
619 POP eax
620 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context
621 mov %esp, %ecx
622 // Outgoing argument set up
623 PUSH ecx // pass SP
624 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
625 .cfi_adjust_cfa_offset 4
626 PUSH edx // pass arg2 - value
627 PUSH eax // pass arg1 - array
628 call SYMBOL(artThrowArrayStoreException) // (array, value, Thread*, SP)
629 int3 // unreached
630END_FUNCTION art_quick_aput_obj
631
Logan Chien8dbb7082013-01-25 20:31:17 +0800632DEFINE_FUNCTION art_quick_memcpy
Ian Rogersaeeada42013-02-13 11:28:34 -0800633 PUSH edx // pass arg3
634 PUSH ecx // pass arg2
635 PUSH eax // pass arg1
Elliott Hughesadc078a2012-04-04 11:39:05 -0700636 call SYMBOL(memcpy) // (void*, const void*, size_t)
Ian Rogers55bd45f2012-04-04 17:31:20 -0700637 addl LITERAL(12), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800638 .cfi_adjust_cfa_offset -12
Ian Rogers7caad772012-03-30 01:07:54 -0700639 ret
Ian Rogersaeeada42013-02-13 11:28:34 -0800640END_FUNCTION art_quick_memcpy
Ian Rogers7caad772012-03-30 01:07:54 -0700641
Logan Chien8dbb7082013-01-25 20:31:17 +0800642NO_ARG_DOWNCALL art_quick_test_suspend, artTestSuspendFromCode, ret
Ian Rogers7caad772012-03-30 01:07:54 -0700643
Ian Rogers468532e2013-08-05 10:56:33 -0700644DEFINE_FUNCTION art_quick_fmod
jeffhao1395b1e2012-06-13 18:05:13 -0700645 subl LITERAL(12), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800646 .cfi_adjust_cfa_offset 12
647 PUSH ebx // pass arg4 b.hi
648 PUSH edx // pass arg3 b.lo
649 PUSH ecx // pass arg2 a.hi
650 PUSH eax // pass arg1 a.lo
jeffhao1395b1e2012-06-13 18:05:13 -0700651 call SYMBOL(fmod) // (jdouble a, jdouble b)
652 fstpl (%esp) // pop return value off fp stack
653 movsd (%esp), %xmm0 // place into %xmm0
654 addl LITERAL(28), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800655 .cfi_adjust_cfa_offset -28
jeffhao292188d2012-05-17 15:45:04 -0700656 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700657END_FUNCTION art_quick_fmod
jeffhao292188d2012-05-17 15:45:04 -0700658
Ian Rogers468532e2013-08-05 10:56:33 -0700659DEFINE_FUNCTION art_quick_fmodf
Ian Rogersaeeada42013-02-13 11:28:34 -0800660 PUSH eax // alignment padding
661 PUSH ecx // pass arg2 b
662 PUSH eax // pass arg1 a
jeffhao1395b1e2012-06-13 18:05:13 -0700663 call SYMBOL(fmodf) // (jfloat a, jfloat b)
Ian Rogers1b09b092012-08-20 15:35:52 -0700664 fstps (%esp) // pop return value off fp stack
jeffhao1395b1e2012-06-13 18:05:13 -0700665 movss (%esp), %xmm0 // place into %xmm0
666 addl LITERAL(12), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800667 .cfi_adjust_cfa_offset -12
jeffhao292188d2012-05-17 15:45:04 -0700668 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700669END_FUNCTION art_quick_fmodf
jeffhao292188d2012-05-17 15:45:04 -0700670
Ian Rogers468532e2013-08-05 10:56:33 -0700671DEFINE_FUNCTION art_quick_l2d
Ian Rogers5793fea2013-02-14 13:33:34 -0800672 PUSH ecx // push arg2 a.hi
673 PUSH eax // push arg1 a.lo
674 fildll (%esp) // load as integer and push into st0
675 fstpl (%esp) // pop value off fp stack as double
jeffhao41005dd2012-05-09 17:58:52 -0700676 movsd (%esp), %xmm0 // place into %xmm0
Ian Rogers5793fea2013-02-14 13:33:34 -0800677 addl LITERAL(8), %esp // pop arguments
678 .cfi_adjust_cfa_offset -8
jeffhao41005dd2012-05-09 17:58:52 -0700679 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700680END_FUNCTION art_quick_l2d
jeffhao41005dd2012-05-09 17:58:52 -0700681
Ian Rogers468532e2013-08-05 10:56:33 -0700682DEFINE_FUNCTION art_quick_l2f
Ian Rogers5793fea2013-02-14 13:33:34 -0800683 PUSH ecx // push arg2 a.hi
684 PUSH eax // push arg1 a.lo
685 fildll (%esp) // load as integer and push into st0
686 fstps (%esp) // pop value off fp stack as a single
jeffhao41005dd2012-05-09 17:58:52 -0700687 movss (%esp), %xmm0 // place into %xmm0
Ian Rogers5793fea2013-02-14 13:33:34 -0800688 addl LITERAL(8), %esp // pop argument
689 .cfi_adjust_cfa_offset -8
jeffhao41005dd2012-05-09 17:58:52 -0700690 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700691END_FUNCTION art_quick_l2f
jeffhao41005dd2012-05-09 17:58:52 -0700692
Ian Rogers468532e2013-08-05 10:56:33 -0700693DEFINE_FUNCTION art_quick_d2l
Ian Rogersaeeada42013-02-13 11:28:34 -0800694 PUSH eax // alignment padding
695 PUSH ecx // pass arg2 a.hi
696 PUSH eax // pass arg1 a.lo
jeffhao1395b1e2012-06-13 18:05:13 -0700697 call SYMBOL(art_d2l) // (jdouble a)
jeffhao41005dd2012-05-09 17:58:52 -0700698 addl LITERAL(12), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800699 .cfi_adjust_cfa_offset -12
jeffhao41005dd2012-05-09 17:58:52 -0700700 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700701END_FUNCTION art_quick_d2l
jeffhao41005dd2012-05-09 17:58:52 -0700702
Ian Rogers468532e2013-08-05 10:56:33 -0700703DEFINE_FUNCTION art_quick_f2l
jeffhao41005dd2012-05-09 17:58:52 -0700704 subl LITERAL(8), %esp // alignment padding
Ian Rogers5793fea2013-02-14 13:33:34 -0800705 .cfi_adjust_cfa_offset 8
Ian Rogersaeeada42013-02-13 11:28:34 -0800706 PUSH eax // pass arg1 a
jeffhao1395b1e2012-06-13 18:05:13 -0700707 call SYMBOL(art_f2l) // (jfloat a)
jeffhao41005dd2012-05-09 17:58:52 -0700708 addl LITERAL(12), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800709 .cfi_adjust_cfa_offset -12
jeffhao41005dd2012-05-09 17:58:52 -0700710 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700711END_FUNCTION art_quick_f2l
jeffhao41005dd2012-05-09 17:58:52 -0700712
Ian Rogers468532e2013-08-05 10:56:33 -0700713DEFINE_FUNCTION art_quick_idivmod
jeffhao174651d2012-04-19 15:27:22 -0700714 cmpl LITERAL(0x80000000), %eax
715 je check_arg2 // special case
716args_ok:
Ian Rogers7caad772012-03-30 01:07:54 -0700717 cdq // edx:eax = sign extend eax
718 idiv %ecx // (edx,eax) = (edx:eax % ecx, edx:eax / ecx)
Ian Rogers7caad772012-03-30 01:07:54 -0700719 ret
jeffhao174651d2012-04-19 15:27:22 -0700720check_arg2:
721 cmpl LITERAL(-1), %ecx
722 jne args_ok
723 xorl %edx, %edx
724 ret // eax already holds min int
Ian Rogers468532e2013-08-05 10:56:33 -0700725END_FUNCTION art_quick_idivmod
Ian Rogers7caad772012-03-30 01:07:54 -0700726
Ian Rogers468532e2013-08-05 10:56:33 -0700727DEFINE_FUNCTION art_quick_ldiv
Ian Rogersa9a82542013-10-04 11:17:26 -0700728 subl LITERAL(12), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800729 .cfi_adjust_cfa_offset 12
730 PUSH ebx // pass arg4 b.hi
731 PUSH edx // pass arg3 b.lo
732 PUSH ecx // pass arg2 a.hi
Ian Rogersa9a82542013-10-04 11:17:26 -0700733 PUSH eax // pass arg1 a.lo
734 call SYMBOL(artLdiv) // (jlong a, jlong b)
735 addl LITERAL(28), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800736 .cfi_adjust_cfa_offset -28
Ian Rogers55bd45f2012-04-04 17:31:20 -0700737 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700738END_FUNCTION art_quick_ldiv
Ian Rogers55bd45f2012-04-04 17:31:20 -0700739
Ian Rogersa9a82542013-10-04 11:17:26 -0700740DEFINE_FUNCTION art_quick_lmod
741 subl LITERAL(12), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800742 .cfi_adjust_cfa_offset 12
743 PUSH ebx // pass arg4 b.hi
744 PUSH edx // pass arg3 b.lo
745 PUSH ecx // pass arg2 a.hi
Ian Rogersa9a82542013-10-04 11:17:26 -0700746 PUSH eax // pass arg1 a.lo
747 call SYMBOL(artLmod) // (jlong a, jlong b)
748 addl LITERAL(28), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800749 .cfi_adjust_cfa_offset -28
Ian Rogers55bd45f2012-04-04 17:31:20 -0700750 ret
Ian Rogersa9a82542013-10-04 11:17:26 -0700751END_FUNCTION art_quick_lmod
Ian Rogers55bd45f2012-04-04 17:31:20 -0700752
Ian Rogers468532e2013-08-05 10:56:33 -0700753DEFINE_FUNCTION art_quick_lmul
Ian Rogers5793fea2013-02-14 13:33:34 -0800754 imul %eax, %ebx // ebx = a.lo(eax) * b.hi(ebx)
755 imul %edx, %ecx // ecx = b.lo(edx) * a.hi(ecx)
756 mul %edx // edx:eax = a.lo(eax) * b.lo(edx)
757 add %ebx, %ecx
758 add %ecx, %edx // edx += (a.lo * b.hi) + (b.lo * a.hi)
jeffhao644d5312012-05-03 19:04:49 -0700759 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700760END_FUNCTION art_quick_lmul
jeffhao644d5312012-05-03 19:04:49 -0700761
Ian Rogers468532e2013-08-05 10:56:33 -0700762DEFINE_FUNCTION art_quick_lshl
jeffhao644d5312012-05-03 19:04:49 -0700763 // ecx:eax << edx
Ian Rogers141d6222012-04-05 12:23:06 -0700764 xchg %edx, %ecx
765 shld %cl,%eax,%edx
766 shl %cl,%eax
767 test LITERAL(32), %cl
768 jz 1f
769 mov %eax, %edx
770 xor %eax, %eax
7711:
772 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700773END_FUNCTION art_quick_lshl
Ian Rogers141d6222012-04-05 12:23:06 -0700774
Ian Rogers468532e2013-08-05 10:56:33 -0700775DEFINE_FUNCTION art_quick_lshr
jeffhao644d5312012-05-03 19:04:49 -0700776 // ecx:eax >> edx
Ian Rogers141d6222012-04-05 12:23:06 -0700777 xchg %edx, %ecx
jeffhao644d5312012-05-03 19:04:49 -0700778 shrd %cl,%edx,%eax
779 sar %cl,%edx
Ian Rogers141d6222012-04-05 12:23:06 -0700780 test LITERAL(32),%cl
781 jz 1f
jeffhao5121e0b2012-05-08 18:23:38 -0700782 mov %edx, %eax
783 sar LITERAL(31), %edx
Ian Rogers141d6222012-04-05 12:23:06 -07007841:
785 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700786END_FUNCTION art_quick_lshr
Ian Rogers141d6222012-04-05 12:23:06 -0700787
Ian Rogers468532e2013-08-05 10:56:33 -0700788DEFINE_FUNCTION art_quick_lushr
jeffhao644d5312012-05-03 19:04:49 -0700789 // ecx:eax >>> edx
Ian Rogers141d6222012-04-05 12:23:06 -0700790 xchg %edx, %ecx
jeffhao644d5312012-05-03 19:04:49 -0700791 shrd %cl,%edx,%eax
792 shr %cl,%edx
793 test LITERAL(32),%cl
Ian Rogers141d6222012-04-05 12:23:06 -0700794 jz 1f
jeffhao5121e0b2012-05-08 18:23:38 -0700795 mov %edx, %eax
796 xor %edx, %edx
Ian Rogers141d6222012-04-05 12:23:06 -07007971:
798 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700799END_FUNCTION art_quick_lushr
Ian Rogers141d6222012-04-05 12:23:06 -0700800
Ian Rogers468532e2013-08-05 10:56:33 -0700801DEFINE_FUNCTION art_quick_set32_instance
jeffhao9dbb23e2012-05-18 17:03:57 -0700802 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
803 mov %esp, %ebx // remember SP
jeffhao1ff4cd72012-05-21 11:17:48 -0700804 subl LITERAL(8), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800805 .cfi_adjust_cfa_offset 8
806 PUSH ebx // pass SP
jeffhao9dbb23e2012-05-18 17:03:57 -0700807 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800808 .cfi_adjust_cfa_offset 4
jeffhao9dbb23e2012-05-18 17:03:57 -0700809 mov 32(%ebx), %ebx // get referrer
Ian Rogersaeeada42013-02-13 11:28:34 -0800810 PUSH ebx // pass referrer
811 PUSH edx // pass new_val
812 PUSH ecx // pass object
813 PUSH eax // pass field_idx
jeffhao9dbb23e2012-05-18 17:03:57 -0700814 call SYMBOL(artSet32InstanceFromCode) // (field_idx, Object*, new_val, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700815 addl LITERAL(32), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800816 .cfi_adjust_cfa_offset -32
jeffhao9dbb23e2012-05-18 17:03:57 -0700817 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
818 RETURN_IF_EAX_ZERO // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -0700819END_FUNCTION art_quick_set32_instance
jeffhao9dbb23e2012-05-18 17:03:57 -0700820
Ian Rogers468532e2013-08-05 10:56:33 -0700821DEFINE_FUNCTION art_quick_set64_instance
Ian Rogersaeeada42013-02-13 11:28:34 -0800822 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
jeffhao1ff4cd72012-05-21 11:17:48 -0700823 subl LITERAL(8), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800824 .cfi_adjust_cfa_offset 8
825 PUSH esp // pass SP-8
jeffhao1ff4cd72012-05-21 11:17:48 -0700826 addl LITERAL(8), (%esp) // fix SP on stack by adding 8
jeffhao9dbb23e2012-05-18 17:03:57 -0700827 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800828 .cfi_adjust_cfa_offset 4
829 PUSH ebx // pass high half of new_val
830 PUSH edx // pass low half of new_val
831 PUSH ecx // pass object
832 PUSH eax // pass field_idx
jeffhao9dbb23e2012-05-18 17:03:57 -0700833 call SYMBOL(artSet64InstanceFromCode) // (field_idx, Object*, new_val, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700834 addl LITERAL(32), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800835 .cfi_adjust_cfa_offset -32
836 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
jeffhao9dbb23e2012-05-18 17:03:57 -0700837 RETURN_IF_EAX_ZERO // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -0700838END_FUNCTION art_quick_set64_instance
jeffhao9dbb23e2012-05-18 17:03:57 -0700839
Ian Rogers468532e2013-08-05 10:56:33 -0700840DEFINE_FUNCTION art_quick_set_obj_instance
Ian Rogersaeeada42013-02-13 11:28:34 -0800841 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
jeffhao9dbb23e2012-05-18 17:03:57 -0700842 mov %esp, %ebx // remember SP
jeffhao1ff4cd72012-05-21 11:17:48 -0700843 subl LITERAL(8), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800844 .cfi_adjust_cfa_offset 8
845 PUSH ebx // pass SP
jeffhao9dbb23e2012-05-18 17:03:57 -0700846 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800847 .cfi_adjust_cfa_offset 4
jeffhao9dbb23e2012-05-18 17:03:57 -0700848 mov 32(%ebx), %ebx // get referrer
Ian Rogersaeeada42013-02-13 11:28:34 -0800849 PUSH ebx // pass referrer
850 PUSH edx // pass new_val
851 PUSH ecx // pass object
852 PUSH eax // pass field_idx
jeffhao9dbb23e2012-05-18 17:03:57 -0700853 call SYMBOL(artSetObjInstanceFromCode) // (field_idx, Object*, new_val, 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
857 RETURN_IF_EAX_ZERO // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -0700858END_FUNCTION art_quick_set_obj_instance
jeffhao9dbb23e2012-05-18 17:03:57 -0700859
Ian Rogers468532e2013-08-05 10:56:33 -0700860DEFINE_FUNCTION art_quick_get32_instance
Ian Rogersaeeada42013-02-13 11:28:34 -0800861 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
jeffhao9dbb23e2012-05-18 17:03:57 -0700862 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(artGet32InstanceFromCode) // (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_get32_instance
jeffhao9dbb23e2012-05-18 17:03:57 -0700878
Ian Rogers468532e2013-08-05 10:56:33 -0700879DEFINE_FUNCTION art_quick_get64_instance
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 object
890 PUSH eax // pass field_idx
jeffhao9dbb23e2012-05-18 17:03:57 -0700891 call SYMBOL(artGet64InstanceFromCode) // (field_idx, Object*, 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
jeffhaod66a8752012-05-22 15:30:16 -0700895 RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -0700896END_FUNCTION art_quick_get64_instance
jeffhao9dbb23e2012-05-18 17:03:57 -0700897
Ian Rogers468532e2013-08-05 10:56:33 -0700898DEFINE_FUNCTION art_quick_get_obj_instance
jeffhao9dbb23e2012-05-18 17:03:57 -0700899 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
900 mov %esp, %ebx // remember SP
901 mov 32(%esp), %edx // get referrer
jeffhao1ff4cd72012-05-21 11:17:48 -0700902 subl LITERAL(12), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800903 .cfi_adjust_cfa_offset 12
904 PUSH ebx // pass SP
jeffhao9dbb23e2012-05-18 17:03:57 -0700905 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800906 .cfi_adjust_cfa_offset 4
907 PUSH edx // pass referrer
908 PUSH ecx // pass object
909 PUSH eax // pass field_idx
jeffhao9dbb23e2012-05-18 17:03:57 -0700910 call SYMBOL(artGetObjInstanceFromCode) // (field_idx, Object*, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700911 addl LITERAL(32), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800912 .cfi_adjust_cfa_offset -32
jeffhao9dbb23e2012-05-18 17:03:57 -0700913 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
jeffhaod66a8752012-05-22 15:30:16 -0700914 RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -0700915END_FUNCTION art_quick_get_obj_instance
jeffhao9dbb23e2012-05-18 17:03:57 -0700916
Ian Rogers468532e2013-08-05 10:56:33 -0700917DEFINE_FUNCTION art_quick_set32_static
jeffhao9dbb23e2012-05-18 17:03:57 -0700918 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
919 mov %esp, %ebx // remember SP
920 mov 32(%esp), %edx // get referrer
jeffhao1ff4cd72012-05-21 11:17:48 -0700921 subl LITERAL(12), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800922 .cfi_adjust_cfa_offset 12
923 PUSH ebx // pass SP
jeffhao9dbb23e2012-05-18 17:03:57 -0700924 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800925 .cfi_adjust_cfa_offset 4
926 PUSH edx // pass referrer
927 PUSH ecx // pass new_val
928 PUSH eax // pass field_idx
jeffhao9dbb23e2012-05-18 17:03:57 -0700929 call SYMBOL(artSet32StaticFromCode) // (field_idx, new_val, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700930 addl LITERAL(32), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800931 .cfi_adjust_cfa_offset -32
jeffhao9dbb23e2012-05-18 17:03:57 -0700932 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
933 RETURN_IF_EAX_ZERO // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -0700934END_FUNCTION art_quick_set32_static
jeffhao9dbb23e2012-05-18 17:03:57 -0700935
Ian Rogers468532e2013-08-05 10:56:33 -0700936DEFINE_FUNCTION art_quick_set64_static
Ian Rogersaeeada42013-02-13 11:28:34 -0800937 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
jeffhao9dbb23e2012-05-18 17:03:57 -0700938 mov %esp, %ebx // remember SP
jeffhao1ff4cd72012-05-21 11:17:48 -0700939 subl LITERAL(8), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800940 .cfi_adjust_cfa_offset 8
941 PUSH ebx // pass SP
jeffhao9dbb23e2012-05-18 17:03:57 -0700942 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800943 .cfi_adjust_cfa_offset 4
jeffhao9dbb23e2012-05-18 17:03:57 -0700944 mov 32(%ebx), %ebx // get referrer
Ian Rogersaeeada42013-02-13 11:28:34 -0800945 PUSH edx // pass high half of new_val
946 PUSH ecx // pass low half of new_val
947 PUSH ebx // pass referrer
948 PUSH eax // pass field_idx
949 call SYMBOL(artSet64StaticFromCode) // (field_idx, referrer, new_val, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700950 addl LITERAL(32), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800951 .cfi_adjust_cfa_offset -32
952 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
jeffhao9dbb23e2012-05-18 17:03:57 -0700953 RETURN_IF_EAX_ZERO // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -0700954END_FUNCTION art_quick_set64_static
jeffhao9dbb23e2012-05-18 17:03:57 -0700955
Ian Rogers468532e2013-08-05 10:56:33 -0700956DEFINE_FUNCTION art_quick_set_obj_static
Ian Rogersaeeada42013-02-13 11:28:34 -0800957 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
jeffhao9dbb23e2012-05-18 17:03:57 -0700958 mov %esp, %ebx // remember SP
959 mov 32(%esp), %edx // get referrer
jeffhao1ff4cd72012-05-21 11:17:48 -0700960 subl LITERAL(12), %esp // alignment padding
Ian Rogers62d6c772013-02-27 08:32:07 -0800961 .cfi_adjust_cfa_offset 12
Ian Rogersaeeada42013-02-13 11:28:34 -0800962 PUSH ebx // pass SP
jeffhao9dbb23e2012-05-18 17:03:57 -0700963 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800964 .cfi_adjust_cfa_offset 4
965 PUSH edx // pass referrer
966 PUSH ecx // pass new_val
967 PUSH eax // pass field_idx
968 call SYMBOL(artSetObjStaticFromCode) // (field_idx, new_val, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700969 addl LITERAL(32), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800970 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
jeffhao9dbb23e2012-05-18 17:03:57 -0700971 RETURN_IF_EAX_ZERO // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -0700972END_FUNCTION art_quick_set_obj_static
jeffhao9dbb23e2012-05-18 17:03:57 -0700973
Ian Rogers468532e2013-08-05 10:56:33 -0700974DEFINE_FUNCTION art_quick_get32_static
jeffhao9dbb23e2012-05-18 17:03:57 -0700975 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
976 mov %esp, %edx // remember SP
977 mov 32(%esp), %ecx // get referrer
Ian Rogersaeeada42013-02-13 11:28:34 -0800978 PUSH edx // pass SP
jeffhao9dbb23e2012-05-18 17:03:57 -0700979 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800980 .cfi_adjust_cfa_offset 4
981 PUSH ecx // pass referrer
982 PUSH eax // pass field_idx
jeffhao9dbb23e2012-05-18 17:03:57 -0700983 call SYMBOL(artGet32StaticFromCode) // (field_idx, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700984 addl LITERAL(16), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800985 .cfi_adjust_cfa_offset -16
jeffhao9dbb23e2012-05-18 17:03:57 -0700986 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
jeffhaod66a8752012-05-22 15:30:16 -0700987 RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -0700988END_FUNCTION art_quick_get32_static
jeffhao9dbb23e2012-05-18 17:03:57 -0700989
Ian Rogers468532e2013-08-05 10:56:33 -0700990DEFINE_FUNCTION art_quick_get64_static
Ian Rogersaeeada42013-02-13 11:28:34 -0800991 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
jeffhao9dbb23e2012-05-18 17:03:57 -0700992 mov %esp, %edx // remember SP
993 mov 32(%esp), %ecx // get referrer
Ian Rogersaeeada42013-02-13 11:28:34 -0800994 PUSH edx // pass SP
jeffhao9dbb23e2012-05-18 17:03:57 -0700995 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800996 .cfi_adjust_cfa_offset 4
997 PUSH ecx // pass referrer
998 PUSH eax // pass field_idx
jeffhao9dbb23e2012-05-18 17:03:57 -0700999 call SYMBOL(artGet64StaticFromCode) // (field_idx, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -07001000 addl LITERAL(16), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -08001001 .cfi_adjust_cfa_offset -16
jeffhao9dbb23e2012-05-18 17:03:57 -07001002 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
jeffhaod66a8752012-05-22 15:30:16 -07001003 RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -07001004END_FUNCTION art_quick_get64_static
jeffhao9dbb23e2012-05-18 17:03:57 -07001005
Ian Rogers468532e2013-08-05 10:56:33 -07001006DEFINE_FUNCTION art_quick_get_obj_static
jeffhao9dbb23e2012-05-18 17:03:57 -07001007 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
1008 mov %esp, %edx // remember SP
1009 mov 32(%esp), %ecx // get referrer
Ian Rogersaeeada42013-02-13 11:28:34 -08001010 PUSH edx // pass SP
jeffhao9dbb23e2012-05-18 17:03:57 -07001011 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -08001012 .cfi_adjust_cfa_offset 4
1013 PUSH ecx // pass referrer
1014 PUSH eax // pass field_idx
jeffhao9dbb23e2012-05-18 17:03:57 -07001015 call SYMBOL(artGetObjStaticFromCode) // (field_idx, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -07001016 addl LITERAL(16), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -08001017 .cfi_adjust_cfa_offset -16
jeffhao9dbb23e2012-05-18 17:03:57 -07001018 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
jeffhaod66a8752012-05-22 15:30:16 -07001019 RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -07001020END_FUNCTION art_quick_get_obj_static
jeffhaod66a8752012-05-22 15:30:16 -07001021
Logan Chien8dbb7082013-01-25 20:31:17 +08001022DEFINE_FUNCTION art_quick_proxy_invoke_handler
Ian Rogers7db619b2013-01-16 18:35:48 -08001023 SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME // save frame and Method*
Ian Rogersaeeada42013-02-13 11:28:34 -08001024 PUSH esp // pass SP
jeffhaod66a8752012-05-22 15:30:16 -07001025 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -08001026 .cfi_adjust_cfa_offset 4
1027 PUSH ecx // pass receiver
1028 PUSH eax // pass proxy method
Jeff Hao5fa60c32013-04-04 17:57:01 -07001029 call SYMBOL(artQuickProxyInvokeHandler) // (proxy method, receiver, Thread*, SP)
Ian Rogersaf6e67a2013-01-16 08:38:37 -08001030 movd %eax, %xmm0 // place return value also into floating point return value
1031 movd %edx, %xmm1
1032 punpckldq %xmm1, %xmm0
jeffhaod66a8752012-05-22 15:30:16 -07001033 addl LITERAL(44), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -08001034 .cfi_adjust_cfa_offset -44
jeffhaod66a8752012-05-22 15:30:16 -07001035 RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
Ian Rogersaeeada42013-02-13 11:28:34 -08001036END_FUNCTION art_quick_proxy_invoke_handler
jeffhao9dbb23e2012-05-18 17:03:57 -07001037
Jeff Hao88474b42013-10-23 16:24:40 -07001038 /*
1039 * Called to resolve an imt conflict. xmm0 is a hidden argument that holds the target method's
1040 * dex method index.
1041 */
1042DEFINE_FUNCTION art_quick_imt_conflict_trampoline
1043 PUSH ecx
1044 movl 8(%esp), %eax // load caller Method*
1045 movl METHOD_DEX_CACHE_METHODS_OFFSET(%eax), %eax // load dex_cache_resolved_methods
1046 movd %xmm0, %ecx // get target method index stored in xmm0
1047 movl OBJECT_ARRAY_DATA_OFFSET(%eax, %ecx, 4), %eax // load the target method
1048 POP ecx
1049 jmp art_quick_invoke_interface_trampoline
1050END_FUNCTION art_quick_imt_conflict_trampoline
1051
Ian Rogers468532e2013-08-05 10:56:33 -07001052DEFINE_FUNCTION art_quick_resolution_trampoline
1053 SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME
1054 PUSH esp // pass SP
1055 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
1056 .cfi_adjust_cfa_offset 4
1057 PUSH ecx // pass receiver
1058 PUSH eax // pass method
1059 call SYMBOL(artQuickResolutionTrampoline) // (Method* called, receiver, Thread*, SP)
1060 movl %eax, %edi // remember code pointer in EDI
1061 addl LITERAL(16), %esp // pop arguments
1062 test %eax, %eax // if code pointer is NULL goto deliver pending exception
1063 jz 1f
1064 POP eax // called method
1065 POP ecx // restore args
1066 POP edx
1067 POP ebx
1068 POP ebp // restore callee saves except EDI
1069 POP esi
1070 xchgl 0(%esp),%edi // restore EDI and place code pointer as only value on stack
1071 ret // tail call into method
10721:
1073 RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME
1074 DELIVER_PENDING_EXCEPTION
1075END_FUNCTION art_quick_resolution_trampoline
1076
1077DEFINE_FUNCTION art_quick_to_interpreter_bridge
Ian Rogers62d6c772013-02-27 08:32:07 -08001078 SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME // save frame
Ian Rogersaeeada42013-02-13 11:28:34 -08001079 mov %esp, %edx // remember SP
1080 PUSH eax // alignment padding
1081 PUSH edx // pass SP
Ian Rogers7db619b2013-01-16 18:35:48 -08001082 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -08001083 .cfi_adjust_cfa_offset 4
1084 PUSH eax // pass method
Ian Rogers468532e2013-08-05 10:56:33 -07001085 call SYMBOL(artQuickToInterpreterBridge) // (method, Thread*, SP)
Ian Rogers7db619b2013-01-16 18:35:48 -08001086 movd %eax, %xmm0 // place return value also into floating point return value
1087 movd %edx, %xmm1
1088 punpckldq %xmm1, %xmm0
Mathieu Chartier19841522013-10-22 11:29:00 -07001089 addl LITERAL(16), %esp // pop arguments
1090 .cfi_adjust_cfa_offset -16
1091 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
Ian Rogers7db619b2013-01-16 18:35:48 -08001092 RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -07001093END_FUNCTION art_quick_to_interpreter_bridge
Ian Rogers7db619b2013-01-16 18:35:48 -08001094
jeffhao7e4fcb82013-01-10 18:11:08 -08001095 /*
1096 * Routine that intercepts method calls and returns.
1097 */
Ian Rogers468532e2013-08-05 10:56:33 -07001098DEFINE_FUNCTION art_quick_instrumentation_entry
Ian Rogers62d6c772013-02-27 08:32:07 -08001099 SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME
1100 movl %esp, %edx // Save SP.
1101 PUSH eax // Save eax which will be clobbered by the callee-save method.
1102 subl LITERAL(8), %esp // Align stack.
1103 .cfi_adjust_cfa_offset 8
1104 pushl 40(%esp) // Pass LR.
Ian Rogersaeeada42013-02-13 11:28:34 -08001105 .cfi_adjust_cfa_offset 4
Ian Rogers62d6c772013-02-27 08:32:07 -08001106 PUSH edx // Pass SP.
1107 pushl %fs:THREAD_SELF_OFFSET // Pass Thread::Current().
Ian Rogersaeeada42013-02-13 11:28:34 -08001108 .cfi_adjust_cfa_offset 4
Ian Rogers62d6c772013-02-27 08:32:07 -08001109 PUSH ecx // Pass receiver.
1110 PUSH eax // Pass Method*.
1111 call SYMBOL(artInstrumentationMethodEntryFromCode) // (Method*, Object*, Thread*, SP, LR)
1112 addl LITERAL(28), %esp // Pop arguments upto saved Method*.
1113 movl 28(%esp), %edi // Restore edi.
1114 movl %eax, 28(%esp) // Place code* over edi, just under return pc.
Ian Rogers468532e2013-08-05 10:56:33 -07001115 movl LITERAL(SYMBOL(art_quick_instrumentation_exit)), 32(%esp)
Ian Rogers62d6c772013-02-27 08:32:07 -08001116 // Place instrumentation exit as return pc.
1117 movl (%esp), %eax // Restore eax.
1118 movl 8(%esp), %ecx // Restore ecx.
1119 movl 12(%esp), %edx // Restore edx.
1120 movl 16(%esp), %ebx // Restore ebx.
1121 movl 20(%esp), %ebp // Restore ebp.
1122 movl 24(%esp), %esi // Restore esi.
1123 addl LITERAL(28), %esp // Wind stack back upto code*.
1124 ret // Call method (and pop).
Ian Rogers468532e2013-08-05 10:56:33 -07001125END_FUNCTION art_quick_instrumentation_entry
Ian Rogers62d6c772013-02-27 08:32:07 -08001126
Ian Rogers468532e2013-08-05 10:56:33 -07001127DEFINE_FUNCTION art_quick_instrumentation_exit
Ian Rogers62d6c772013-02-27 08:32:07 -08001128 pushl LITERAL(0) // Push a fake return PC as there will be none on the stack.
1129 SETUP_REF_ONLY_CALLEE_SAVE_FRAME
1130 mov %esp, %ecx // Remember SP
1131 subl LITERAL(8), %esp // Save float return value.
1132 .cfi_adjust_cfa_offset 8
1133 movd %xmm0, (%esp)
1134 PUSH edx // Save gpr return value.
1135 PUSH eax
1136 subl LITERAL(8), %esp // Align stack
1137 movd %xmm0, (%esp)
1138 subl LITERAL(8), %esp // Pass float return value.
1139 .cfi_adjust_cfa_offset 8
1140 movd %xmm0, (%esp)
1141 PUSH edx // Pass gpr return value.
1142 PUSH eax
1143 PUSH ecx // Pass SP.
1144 pushl %fs:THREAD_SELF_OFFSET // Pass Thread::Current.
Ian Rogersaeeada42013-02-13 11:28:34 -08001145 .cfi_adjust_cfa_offset 4
Ian Rogers62d6c772013-02-27 08:32:07 -08001146 call SYMBOL(artInstrumentationMethodExitFromCode) // (Thread*, SP, gpr_result, fpr_result)
1147 mov %eax, %ecx // Move returned link register.
1148 addl LITERAL(32), %esp // Pop arguments.
1149 .cfi_adjust_cfa_offset -32
1150 movl %edx, %ebx // Move returned link register for deopt
1151 // (ebx is pretending to be our LR).
1152 POP eax // Restore gpr return value.
1153 POP edx
1154 movd (%esp), %xmm0 // Restore fpr return value.
1155 addl LITERAL(8), %esp
Ian Rogers5793fea2013-02-14 13:33:34 -08001156 .cfi_adjust_cfa_offset -8
Ian Rogers62d6c772013-02-27 08:32:07 -08001157 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
1158 addl LITERAL(4), %esp // Remove fake return pc.
1159 jmp *%ecx // Return.
Ian Rogers468532e2013-08-05 10:56:33 -07001160END_FUNCTION art_quick_instrumentation_exit
jeffhao162fd332013-01-08 16:21:01 -08001161
jeffhao7e4fcb82013-01-10 18:11:08 -08001162 /*
Ian Rogers62d6c772013-02-27 08:32:07 -08001163 * Instrumentation has requested that we deoptimize into the interpreter. The deoptimization
1164 * will long jump to the upcall with a special exception of -1.
jeffhao7e4fcb82013-01-10 18:11:08 -08001165 */
Logan Chien8dbb7082013-01-25 20:31:17 +08001166DEFINE_FUNCTION art_quick_deoptimize
Ian Rogers62d6c772013-02-27 08:32:07 -08001167 pushl %ebx // Fake that we were called.
Jeff Haoc1fcdf12013-04-11 13:34:01 -07001168 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME
Ian Rogers62d6c772013-02-27 08:32:07 -08001169 mov %esp, %ecx // Remember SP.
1170 subl LITERAL(8), %esp // Align stack.
1171 .cfi_adjust_cfa_offset 8
1172 PUSH ecx // Pass SP.
1173 pushl %fs:THREAD_SELF_OFFSET // Pass Thread::Current().
Ian Rogersaeeada42013-02-13 11:28:34 -08001174 .cfi_adjust_cfa_offset 4
Ian Rogers62d6c772013-02-27 08:32:07 -08001175 call SYMBOL(artDeoptimize) // artDeoptimize(Thread*, SP)
1176 int3 // Unreachable.
Ian Rogersaeeada42013-02-13 11:28:34 -08001177END_FUNCTION art_quick_deoptimize
jeffhao162fd332013-01-08 16:21:01 -08001178
jeffhao86e46712012-08-08 17:30:59 -07001179 /*
1180 * String's indexOf.
1181 *
1182 * On entry:
1183 * eax: string object (known non-null)
1184 * ecx: char to match (known <= 0xFFFF)
1185 * edx: Starting offset in string data
1186 */
Logan Chien8dbb7082013-01-25 20:31:17 +08001187DEFINE_FUNCTION art_quick_indexof
Ian Rogersaeeada42013-02-13 11:28:34 -08001188 PUSH edi // push callee save reg
jeffhao86e46712012-08-08 17:30:59 -07001189 mov STRING_COUNT_OFFSET(%eax), %ebx
1190 mov STRING_VALUE_OFFSET(%eax), %edi
1191 mov STRING_OFFSET_OFFSET(%eax), %eax
1192 testl %edx, %edx // check if start < 0
1193 jl clamp_min
1194clamp_done:
1195 cmpl %ebx, %edx // check if start >= count
1196 jge not_found
1197 lea STRING_DATA_OFFSET(%edi, %eax, 2), %edi // build a pointer to the start of string data
1198 mov %edi, %eax // save a copy in eax to later compute result
1199 lea (%edi, %edx, 2), %edi // build pointer to start of data to compare
1200 subl %edx, %ebx // compute iteration count
1201 /*
1202 * At this point we have:
1203 * eax: original start of string data
1204 * ecx: char to compare
1205 * ebx: length to compare
1206 * edi: start of data to test
1207 */
1208 mov %eax, %edx
1209 mov %ecx, %eax // put char to match in %eax
1210 mov %ebx, %ecx // put length to compare in %ecx
1211 repne scasw // find %ax, starting at [%edi], up to length %ecx
1212 jne not_found
1213 subl %edx, %edi
1214 sar LITERAL(1), %edi
1215 decl %edi // index = ((curr_ptr - orig_ptr) / 2) - 1
1216 mov %edi, %eax
Ian Rogersaeeada42013-02-13 11:28:34 -08001217 POP edi // pop callee save reg
jeffhao86e46712012-08-08 17:30:59 -07001218 ret
1219 .balign 16
1220not_found:
1221 mov LITERAL(-1), %eax // return -1 (not found)
Ian Rogersaeeada42013-02-13 11:28:34 -08001222 POP edi // pop callee save reg
jeffhao86e46712012-08-08 17:30:59 -07001223 ret
1224clamp_min:
1225 xor %edx, %edx // clamp start to 0
1226 jmp clamp_done
Ian Rogersaeeada42013-02-13 11:28:34 -08001227END_FUNCTION art_quick_indexof
jeffhao86e46712012-08-08 17:30:59 -07001228
1229 /*
1230 * String's compareTo.
1231 *
1232 * On entry:
1233 * eax: this string object (known non-null)
1234 * ecx: comp string object (known non-null)
1235 */
Logan Chien8dbb7082013-01-25 20:31:17 +08001236DEFINE_FUNCTION art_quick_string_compareto
Ian Rogersaeeada42013-02-13 11:28:34 -08001237 PUSH esi // push callee save reg
1238 PUSH edi // push callee save reg
jeffhao86e46712012-08-08 17:30:59 -07001239 mov STRING_COUNT_OFFSET(%eax), %edx
1240 mov STRING_COUNT_OFFSET(%ecx), %ebx
1241 mov STRING_VALUE_OFFSET(%eax), %esi
1242 mov STRING_VALUE_OFFSET(%ecx), %edi
1243 mov STRING_OFFSET_OFFSET(%eax), %eax
1244 mov STRING_OFFSET_OFFSET(%ecx), %ecx
1245 /* Build pointers to the start of string data */
1246 lea STRING_DATA_OFFSET(%esi, %eax, 2), %esi
1247 lea STRING_DATA_OFFSET(%edi, %ecx, 2), %edi
1248 /* Calculate min length and count diff */
1249 mov %edx, %ecx
1250 mov %edx, %eax
1251 subl %ebx, %eax
1252 cmovg %ebx, %ecx
1253 /*
1254 * At this point we have:
1255 * eax: value to return if first part of strings are equal
1256 * ecx: minimum among the lengths of the two strings
1257 * esi: pointer to this string data
1258 * edi: pointer to comp string data
1259 */
1260 repe cmpsw // find nonmatching chars in [%esi] and [%edi], up to length %ecx
1261 jne not_equal
Ian Rogersaeeada42013-02-13 11:28:34 -08001262 POP edi // pop callee save reg
1263 POP esi // pop callee save reg
jeffhao86e46712012-08-08 17:30:59 -07001264 ret
1265 .balign 16
1266not_equal:
Ian Rogers1b09b092012-08-20 15:35:52 -07001267 movzwl -2(%esi), %eax // get last compared char from this string
1268 movzwl -2(%edi), %ecx // get last compared char from comp string
jeffhao86e46712012-08-08 17:30:59 -07001269 subl %ecx, %eax // return the difference
Ian Rogersaeeada42013-02-13 11:28:34 -08001270 POP edi // pop callee save reg
1271 POP esi // pop callee save reg
jeffhao86e46712012-08-08 17:30:59 -07001272 ret
Ian Rogersaeeada42013-02-13 11:28:34 -08001273END_FUNCTION art_quick_string_compareto
jeffhao86e46712012-08-08 17:30:59 -07001274
Elliott Hughes787ec202012-03-29 17:14:15 -07001275 // TODO: implement these!
Logan Chien8dbb7082013-01-25 20:31:17 +08001276UNIMPLEMENTED art_quick_memcmp16