blob: 69738ba1a176902add7137ae68f0cae29db835b8 [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)
29 PUSH esi
30 PUSH ebp
Elliott Hughesea944212012-04-05 13:11:53 -070031 subl MACRO_LITERAL(16), %esp // Grow stack by 4 words, bottom word will hold Method*
Ian Rogersaeeada42013-02-13 11:28:34 -080032 .cfi_adjust_cfa_offset 16
Elliott Hughes787ec202012-03-29 17:14:15 -070033END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -070034
Ian Rogers7caad772012-03-30 01:07:54 -070035 /*
36 * Macro that sets up the callee save frame to conform with
37 * Runtime::CreateCalleeSaveMethod(kRefsOnly)
38 */
39MACRO0(SETUP_REF_ONLY_CALLEE_SAVE_FRAME)
Ian Rogersaeeada42013-02-13 11:28:34 -080040 PUSH edi // Save callee saves (ebx is saved/restored by the upcall)
41 PUSH esi
42 PUSH ebp
Elliott Hughesea944212012-04-05 13:11:53 -070043 subl MACRO_LITERAL(16), %esp // Grow stack by 4 words, bottom word will hold Method*
Ian Rogersaeeada42013-02-13 11:28:34 -080044 .cfi_adjust_cfa_offset 16
Ian Rogers7caad772012-03-30 01:07:54 -070045END_MACRO
46
47MACRO0(RESTORE_REF_ONLY_CALLEE_SAVE_FRAME)
Mathieu Chartier2a6c7b72013-10-16 11:16:33 -070048 addl MACRO_LITERAL(16), %esp // Unwind stack up to return address
49 POP ebp // Restore callee saves (ebx is saved/restored by the upcall)
50 POP esi
51 POP edi
Ian Rogersaeeada42013-02-13 11:28:34 -080052 .cfi_adjust_cfa_offset -28
Elliott Hughes787ec202012-03-29 17:14:15 -070053END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -070054
55 /*
56 * Macro that sets up the callee save frame to conform with
Ian Rogers7caad772012-03-30 01:07:54 -070057 * Runtime::CreateCalleeSaveMethod(kRefsAndArgs)
Ian Rogers57b86d42012-03-27 16:05:41 -070058 */
jeffhao9dbb23e2012-05-18 17:03:57 -070059MACRO0(SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME)
Ian Rogersaeeada42013-02-13 11:28:34 -080060 PUSH edi // Save callee saves
61 PUSH esi
62 PUSH ebp
63 PUSH ebx // Save args
64 PUSH edx
65 PUSH ecx
66 PUSH eax // Align stack, eax will be clobbered by Method*
Elliott Hughes787ec202012-03-29 17:14:15 -070067END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -070068
jeffhao9dbb23e2012-05-18 17:03:57 -070069MACRO0(RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME)
Elliott Hughesea944212012-04-05 13:11:53 -070070 addl MACRO_LITERAL(4), %esp // Remove padding
Ian Rogersaeeada42013-02-13 11:28:34 -080071 .cfi_adjust_cfa_offset -4
72 POP ecx // Restore args except eax
73 POP edx
74 POP ebx
75 POP ebp // Restore callee saves
76 POP esi
77 POP edi
Elliott Hughes787ec202012-03-29 17:14:15 -070078END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -070079
80 /*
81 * Macro that set calls through to artDeliverPendingExceptionFromCode, where the pending
82 * exception is Thread::Current()->exception_.
83 */
Elliott Hughes787ec202012-03-29 17:14:15 -070084MACRO0(DELIVER_PENDING_EXCEPTION)
Ian Rogers57b86d42012-03-27 16:05:41 -070085 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save callee saves for throw
86 mov %esp, %ecx
87 // Outgoing argument set up
Elliott Hughesea944212012-04-05 13:11:53 -070088 subl MACRO_LITERAL(8), %esp // Alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -080089 .cfi_adjust_cfa_offset 8
90 PUSH ecx // pass SP
Ian Rogers57b86d42012-03-27 16:05:41 -070091 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -080092 .cfi_adjust_cfa_offset 4
Mark Mendella9abe872014-01-10 05:52:01 -080093 SETUP_GOT_NOSAVE // clobbers ebx (harmless here)
94 call SYMBOL(artDeliverPendingExceptionFromCode)@PLT // artDeliverPendingExceptionFromCode(Thread*, SP)
jeffhao9dbb23e2012-05-18 17:03:57 -070095 int3 // unreached
Elliott Hughes787ec202012-03-29 17:14:15 -070096END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -070097
Elliott Hughes787ec202012-03-29 17:14:15 -070098MACRO2(NO_ARG_RUNTIME_EXCEPTION, c_name, cxx_name)
Ian Rogersaeeada42013-02-13 11:28:34 -080099 DEFINE_FUNCTION VAR(c_name, 0)
Ian Rogers57b86d42012-03-27 16:05:41 -0700100 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context
101 mov %esp, %ecx
102 // Outgoing argument set up
Elliott Hughesea944212012-04-05 13:11:53 -0700103 subl MACRO_LITERAL(8), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800104 .cfi_adjust_cfa_offset 8
105 PUSH ecx // pass SP
Ian Rogers55bd45f2012-04-04 17:31:20 -0700106 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800107 .cfi_adjust_cfa_offset 4
Mark Mendella9abe872014-01-10 05:52:01 -0800108 SETUP_GOT_NOSAVE // clobbers ebx (harmless here)
109 call VAR(cxx_name, 1)@PLT // cxx_name(Thread*, SP)
Ian Rogers57b86d42012-03-27 16:05:41 -0700110 int3 // unreached
Ian Rogersaeeada42013-02-13 11:28:34 -0800111 END_FUNCTION VAR(c_name, 0)
Elliott Hughes787ec202012-03-29 17:14:15 -0700112END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -0700113
Elliott Hughes787ec202012-03-29 17:14:15 -0700114MACRO2(ONE_ARG_RUNTIME_EXCEPTION, c_name, cxx_name)
Ian Rogersaeeada42013-02-13 11:28:34 -0800115 DEFINE_FUNCTION VAR(c_name, 0)
Ian Rogers57b86d42012-03-27 16:05:41 -0700116 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context
117 mov %esp, %ecx
118 // Outgoing argument set up
Ian Rogersaeeada42013-02-13 11:28:34 -0800119 PUSH eax // alignment padding
120 PUSH ecx // pass SP
Ian Rogers57b86d42012-03-27 16:05:41 -0700121 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800122 .cfi_adjust_cfa_offset 4
123 PUSH eax // pass arg1
Mark Mendella9abe872014-01-10 05:52:01 -0800124 SETUP_GOT_NOSAVE // clobbers ebx (harmless here)
125 call VAR(cxx_name, 1)@PLT // cxx_name(arg1, Thread*, SP)
Ian Rogers57b86d42012-03-27 16:05:41 -0700126 int3 // unreached
Ian Rogersaeeada42013-02-13 11:28:34 -0800127 END_FUNCTION VAR(c_name, 0)
Elliott Hughes787ec202012-03-29 17:14:15 -0700128END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -0700129
Elliott Hughes787ec202012-03-29 17:14:15 -0700130MACRO2(TWO_ARG_RUNTIME_EXCEPTION, c_name, cxx_name)
Ian Rogersaeeada42013-02-13 11:28:34 -0800131 DEFINE_FUNCTION VAR(c_name, 0)
Ian Rogers57b86d42012-03-27 16:05:41 -0700132 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context
133 mov %esp, %edx
134 // Outgoing argument set up
Ian Rogersaeeada42013-02-13 11:28:34 -0800135 PUSH edx // pass SP
Ian Rogers57b86d42012-03-27 16:05:41 -0700136 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800137 .cfi_adjust_cfa_offset 4
138 PUSH ecx // pass arg2
139 PUSH eax // pass arg1
Mark Mendella9abe872014-01-10 05:52:01 -0800140 SETUP_GOT_NOSAVE // clobbers ebx (harmless here)
141 call VAR(cxx_name, 1)@PLT // cxx_name(arg1, arg2, Thread*, SP)
Ian Rogers57b86d42012-03-27 16:05:41 -0700142 int3 // unreached
Ian Rogersaeeada42013-02-13 11:28:34 -0800143 END_FUNCTION VAR(c_name, 0)
Elliott Hughes787ec202012-03-29 17:14:15 -0700144END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -0700145
146 /*
147 * Called by managed code to create and deliver a NullPointerException.
148 */
Ian Rogers468532e2013-08-05 10:56:33 -0700149NO_ARG_RUNTIME_EXCEPTION art_quick_throw_null_pointer_exception, artThrowNullPointerExceptionFromCode
Ian Rogers57b86d42012-03-27 16:05:41 -0700150
151 /*
152 * Called by managed code to create and deliver an ArithmeticException.
153 */
Ian Rogers468532e2013-08-05 10:56:33 -0700154NO_ARG_RUNTIME_EXCEPTION art_quick_throw_div_zero, artThrowDivZeroFromCode
Ian Rogers57b86d42012-03-27 16:05:41 -0700155
156 /*
Ian Rogers57b86d42012-03-27 16:05:41 -0700157 * Called by managed code to create and deliver a StackOverflowError.
158 */
Ian Rogers468532e2013-08-05 10:56:33 -0700159NO_ARG_RUNTIME_EXCEPTION art_quick_throw_stack_overflow, artThrowStackOverflowFromCode
Ian Rogers57b86d42012-03-27 16:05:41 -0700160
161 /*
Elliott Hughes787ec202012-03-29 17:14:15 -0700162 * Called by managed code, saves callee saves and then calls artThrowException
163 * that will place a mock Method* at the bottom of the stack. Arg1 holds the exception.
164 */
Ian Rogers468532e2013-08-05 10:56:33 -0700165ONE_ARG_RUNTIME_EXCEPTION art_quick_deliver_exception, artDeliverExceptionFromCode
Elliott Hughes787ec202012-03-29 17:14:15 -0700166
167 /*
Ian Rogers57b86d42012-03-27 16:05:41 -0700168 * Called by managed code to create and deliver a NoSuchMethodError.
169 */
Ian Rogers468532e2013-08-05 10:56:33 -0700170ONE_ARG_RUNTIME_EXCEPTION art_quick_throw_no_such_method, artThrowNoSuchMethodFromCode
Ian Rogers57b86d42012-03-27 16:05:41 -0700171
172 /*
Elliott Hughes787ec202012-03-29 17:14:15 -0700173 * Called by managed code to create and deliver an ArrayIndexOutOfBoundsException. Arg1 holds
174 * index, arg2 holds limit.
175 */
Ian Rogers468532e2013-08-05 10:56:33 -0700176TWO_ARG_RUNTIME_EXCEPTION art_quick_throw_array_bounds, artThrowArrayBoundsFromCode
Elliott Hughes787ec202012-03-29 17:14:15 -0700177
178 /*
Ian Rogers57b86d42012-03-27 16:05:41 -0700179 * All generated callsites for interface invokes and invocation slow paths will load arguments
180 * as usual - except instead of loading arg0/r0 with the target Method*, arg0/r0 will contain
181 * the method_idx. This wrapper will save arg1-arg3, load the caller's Method*, align the
182 * stack and call the appropriate C helper.
183 * NOTE: "this" is first visible argument of the target, and so can be found in arg1/r1.
184 *
185 * The helper will attempt to locate the target and return a 64-bit result in r0/r1 consisting
186 * of the target Method* in r0 and method->code_ in r1.
187 *
188 * If unsuccessful, the helper will return NULL/NULL. There will bea pending exception in the
189 * thread and we branch to another stub to deliver it.
190 *
191 * On success this wrapper will restore arguments and *jump* to the target, leaving the lr
192 * pointing back to the original caller.
193 */
Elliott Hughes787ec202012-03-29 17:14:15 -0700194MACRO2(INVOKE_TRAMPOLINE, c_name, cxx_name)
Ian Rogersaeeada42013-02-13 11:28:34 -0800195 DEFINE_FUNCTION VAR(c_name, 0)
Ian Rogers7caad772012-03-30 01:07:54 -0700196 // Set up the callee save frame to conform with Runtime::CreateCalleeSaveMethod(kRefsAndArgs)
197 // return address
Ian Rogersaeeada42013-02-13 11:28:34 -0800198 PUSH edi
199 PUSH esi
200 PUSH ebp
Dave Allisonbbb32c22013-11-05 18:25:18 -0800201 PUSH ebx // Save args
Ian Rogersaeeada42013-02-13 11:28:34 -0800202 PUSH edx
203 PUSH ecx
Dave Allisonbbb32c22013-11-05 18:25:18 -0800204 PUSH eax // <-- callee save Method* to go here
Ian Rogers7caad772012-03-30 01:07:54 -0700205 movl %esp, %edx // remember SP
206 // Outgoing argument set up
Mark Mendella9abe872014-01-10 05:52:01 -0800207 SETUP_GOT_NOSAVE
Elliott Hughesea944212012-04-05 13:11:53 -0700208 subl MACRO_LITERAL(12), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800209 .cfi_adjust_cfa_offset 12
210 PUSH edx // pass SP
Ian Rogers7caad772012-03-30 01:07:54 -0700211 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800212 .cfi_adjust_cfa_offset 4
Ian Rogers7caad772012-03-30 01:07:54 -0700213 pushl 32(%edx) // pass caller Method*
Ian Rogersaeeada42013-02-13 11:28:34 -0800214 .cfi_adjust_cfa_offset 4
215 PUSH ecx // pass arg2
216 PUSH eax // pass arg1
Mark Mendella9abe872014-01-10 05:52:01 -0800217 call VAR(cxx_name, 1)@PLT // cxx_name(arg1, arg2, arg3, Thread*, SP)
Ian Rogers7caad772012-03-30 01:07:54 -0700218 movl %edx, %edi // save code pointer in EDI
Elliott Hughesea944212012-04-05 13:11:53 -0700219 addl MACRO_LITERAL(36), %esp // Pop arguments skip eax
Ian Rogersaeeada42013-02-13 11:28:34 -0800220 .cfi_adjust_cfa_offset -36
Dave Allisonbbb32c22013-11-05 18:25:18 -0800221 POP ecx // Restore args except eax
Ian Rogersaeeada42013-02-13 11:28:34 -0800222 POP edx
223 POP ebx
Dave Allisonbbb32c22013-11-05 18:25:18 -0800224 POP ebp // Restore callee saves
Ian Rogersaeeada42013-02-13 11:28:34 -0800225 POP esi
Ian Rogers7caad772012-03-30 01:07:54 -0700226 // Swap EDI callee save with code pointer.
227 xchgl %edi, (%esp)
228 testl %eax, %eax // Branch forward if exception pending.
229 jz 1f
230 // Tail call to intended method.
231 ret
2321:
jeffhao20b5c6c2012-05-21 14:15:18 -0700233 addl MACRO_LITERAL(4), %esp // Pop code pointer off stack
Ian Rogers5793fea2013-02-14 13:33:34 -0800234 .cfi_adjust_cfa_offset -4
Ian Rogers7caad772012-03-30 01:07:54 -0700235 DELIVER_PENDING_EXCEPTION
Ian Rogersaeeada42013-02-13 11:28:34 -0800236 END_FUNCTION VAR(c_name, 0)
Elliott Hughes787ec202012-03-29 17:14:15 -0700237END_MACRO
Ian Rogers57b86d42012-03-27 16:05:41 -0700238
Logan Chien8dbb7082013-01-25 20:31:17 +0800239INVOKE_TRAMPOLINE art_quick_invoke_interface_trampoline, artInvokeInterfaceTrampoline
240INVOKE_TRAMPOLINE art_quick_invoke_interface_trampoline_with_access_check, artInvokeInterfaceTrampolineWithAccessCheck
Ian Rogers57b86d42012-03-27 16:05:41 -0700241
Logan Chien8dbb7082013-01-25 20:31:17 +0800242INVOKE_TRAMPOLINE art_quick_invoke_static_trampoline_with_access_check, artInvokeStaticTrampolineWithAccessCheck
243INVOKE_TRAMPOLINE art_quick_invoke_direct_trampoline_with_access_check, artInvokeDirectTrampolineWithAccessCheck
244INVOKE_TRAMPOLINE art_quick_invoke_super_trampoline_with_access_check, artInvokeSuperTrampolineWithAccessCheck
245INVOKE_TRAMPOLINE art_quick_invoke_virtual_trampoline_with_access_check, artInvokeVirtualTrampolineWithAccessCheck
Ian Rogers57b86d42012-03-27 16:05:41 -0700246
Jeff Hao5d917302013-02-27 17:57:33 -0800247 /*
Jeff Hao6474d192013-03-26 14:08:09 -0700248 * Quick invocation stub.
249 * On entry:
250 * [sp] = return address
251 * [sp + 4] = method pointer
252 * [sp + 8] = argument array or NULL for no argument methods
253 * [sp + 12] = size of argument array in bytes
254 * [sp + 16] = (managed) thread pointer
255 * [sp + 20] = JValue* result
256 * [sp + 24] = result type char
Jeff Hao5d917302013-02-27 17:57:33 -0800257 */
258DEFINE_FUNCTION art_quick_invoke_stub
259 PUSH ebp // save ebp
260 PUSH ebx // save ebx
261 mov %esp, %ebp // copy value of stack pointer into base pointer
262 .cfi_def_cfa_register ebp
263 mov 20(%ebp), %ebx // get arg array size
264 addl LITERAL(28), %ebx // reserve space for return addr, method*, ebx, and ebp in frame
Jeff Hao6474d192013-03-26 14:08:09 -0700265 andl LITERAL(0xFFFFFFF0), %ebx // align frame size to 16 bytes
Jeff Hao5d917302013-02-27 17:57:33 -0800266 subl LITERAL(12), %ebx // remove space for return address, ebx, and ebp
267 subl %ebx, %esp // reserve stack space for argument array
Mark Mendella9abe872014-01-10 05:52:01 -0800268 SETUP_GOT_NOSAVE // clobbers ebx (harmless here)
Jeff Hao5d917302013-02-27 17:57:33 -0800269 lea 4(%esp), %eax // use stack pointer + method ptr as dest for memcpy
270 pushl 20(%ebp) // push size of region to memcpy
271 pushl 16(%ebp) // push arg array as source of memcpy
272 pushl %eax // push stack pointer as destination of memcpy
Mark Mendella9abe872014-01-10 05:52:01 -0800273 call SYMBOL(memcpy)@PLT // (void*, const void*, size_t)
Jeff Hao5d917302013-02-27 17:57:33 -0800274 addl LITERAL(12), %esp // pop arguments to memcpy
275 movl LITERAL(0), (%esp) // store NULL for method*
276 mov 12(%ebp), %eax // move method pointer into eax
277 mov 4(%esp), %ecx // copy arg1 into ecx
278 mov 8(%esp), %edx // copy arg2 into edx
279 mov 12(%esp), %ebx // copy arg3 into ebx
Ian Rogers225ade22013-03-18 17:45:44 -0700280 call *METHOD_CODE_OFFSET(%eax) // call the method
Jeff Hao5d917302013-02-27 17:57:33 -0800281 mov %ebp, %esp // restore stack pointer
Dave Allisonbbb32c22013-11-05 18:25:18 -0800282 .cfi_def_cfa_register esp
Jeff Hao5d917302013-02-27 17:57:33 -0800283 POP ebx // pop ebx
284 POP ebp // pop ebp
285 mov 20(%esp), %ecx // get result pointer
Jeff Hao6474d192013-03-26 14:08:09 -0700286 cmpl LITERAL(68), 24(%esp) // test if result type char == 'D'
287 je return_double_quick
288 cmpl LITERAL(70), 24(%esp) // test if result type char == 'F'
289 je return_float_quick
Jeff Hao5d917302013-02-27 17:57:33 -0800290 mov %eax, (%ecx) // store the result
291 mov %edx, 4(%ecx) // store the other half of the result
Jeff Hao6474d192013-03-26 14:08:09 -0700292 ret
293return_double_quick:
294return_float_quick:
Jeff Hao5d917302013-02-27 17:57:33 -0800295 movsd %xmm0, (%ecx) // store the floating point result
296 ret
297END_FUNCTION art_quick_invoke_stub
298
Ian Rogersd36c52e2012-04-09 16:29:25 -0700299MACRO3(NO_ARG_DOWNCALL, c_name, cxx_name, return_macro)
Ian Rogersaeeada42013-02-13 11:28:34 -0800300 DEFINE_FUNCTION VAR(c_name, 0)
Ian Rogersd36c52e2012-04-09 16:29:25 -0700301 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
302 mov %esp, %edx // remember SP
Mark Mendella9abe872014-01-10 05:52:01 -0800303 SETUP_GOT_NOSAVE // clobbers ebx (harmless here)
Ian Rogersd36c52e2012-04-09 16:29:25 -0700304 // Outgoing argument set up
305 subl MACRO_LITERAL(8), %esp // push padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800306 .cfi_adjust_cfa_offset 8
307 PUSH edx // pass SP
Ian Rogersd36c52e2012-04-09 16:29:25 -0700308 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800309 .cfi_adjust_cfa_offset 4
Mark Mendella9abe872014-01-10 05:52:01 -0800310 call VAR(cxx_name, 1)@PLT // cxx_name(Thread*, SP)
Ian Rogersd36c52e2012-04-09 16:29:25 -0700311 addl MACRO_LITERAL(16), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800312 .cfi_adjust_cfa_offset -16
Ian Rogersd36c52e2012-04-09 16:29:25 -0700313 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
Elliott Hughes754caaa2012-04-10 10:57:36 -0700314 CALL_MACRO(return_macro, 2) // return or deliver exception
Ian Rogersaeeada42013-02-13 11:28:34 -0800315 END_FUNCTION VAR(c_name, 0)
Ian Rogersd36c52e2012-04-09 16:29:25 -0700316END_MACRO
317
318MACRO3(ONE_ARG_DOWNCALL, c_name, cxx_name, return_macro)
Ian Rogersaeeada42013-02-13 11:28:34 -0800319 DEFINE_FUNCTION VAR(c_name, 0)
Ian Rogersd36c52e2012-04-09 16:29:25 -0700320 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
321 mov %esp, %edx // remember SP
Mark Mendella9abe872014-01-10 05:52:01 -0800322 SETUP_GOT_NOSAVE // clobbers EBX
Ian Rogersd36c52e2012-04-09 16:29:25 -0700323 // Outgoing argument set up
Ian Rogersaeeada42013-02-13 11:28:34 -0800324 PUSH eax // push padding
325 PUSH edx // pass SP
Ian Rogersd36c52e2012-04-09 16:29:25 -0700326 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800327 .cfi_adjust_cfa_offset 4
328 PUSH eax // pass arg1
Mark Mendella9abe872014-01-10 05:52:01 -0800329 call VAR(cxx_name, 1)@PLT // cxx_name(arg1, Thread*, SP)
Ian Rogersd36c52e2012-04-09 16:29:25 -0700330 addl MACRO_LITERAL(16), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800331 .cfi_adjust_cfa_offset -16
Ian Rogersd36c52e2012-04-09 16:29:25 -0700332 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
Elliott Hughes754caaa2012-04-10 10:57:36 -0700333 CALL_MACRO(return_macro, 2) // return or deliver exception
Ian Rogersaeeada42013-02-13 11:28:34 -0800334 END_FUNCTION VAR(c_name, 0)
Ian Rogersd36c52e2012-04-09 16:29:25 -0700335END_MACRO
336
337MACRO3(TWO_ARG_DOWNCALL, c_name, cxx_name, return_macro)
Ian Rogersaeeada42013-02-13 11:28:34 -0800338 DEFINE_FUNCTION VAR(c_name, 0)
Ian Rogers7caad772012-03-30 01:07:54 -0700339 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
340 mov %esp, %edx // remember SP
Mark Mendella9abe872014-01-10 05:52:01 -0800341 SETUP_GOT_NOSAVE // clobbers EBX
Ian Rogers7caad772012-03-30 01:07:54 -0700342 // Outgoing argument set up
Ian Rogersaeeada42013-02-13 11:28:34 -0800343 PUSH edx // pass SP
Ian Rogers7caad772012-03-30 01:07:54 -0700344 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800345 .cfi_adjust_cfa_offset 4
346 PUSH ecx // pass arg2
347 PUSH eax // pass arg1
Mark Mendella9abe872014-01-10 05:52:01 -0800348 call VAR(cxx_name, 1)@PLT // cxx_name(arg1, arg2, Thread*, SP)
Elliott Hughesea944212012-04-05 13:11:53 -0700349 addl MACRO_LITERAL(16), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800350 .cfi_adjust_cfa_offset -16
Ian Rogers7caad772012-03-30 01:07:54 -0700351 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
Elliott Hughes754caaa2012-04-10 10:57:36 -0700352 CALL_MACRO(return_macro, 2) // return or deliver exception
Ian Rogersaeeada42013-02-13 11:28:34 -0800353 END_FUNCTION VAR(c_name, 0)
Ian Rogers7caad772012-03-30 01:07:54 -0700354END_MACRO
355
Ian Rogersd36c52e2012-04-09 16:29:25 -0700356MACRO3(THREE_ARG_DOWNCALL, c_name, cxx_name, return_macro)
Ian Rogersaeeada42013-02-13 11:28:34 -0800357 DEFINE_FUNCTION VAR(c_name, 0)
Ian Rogers7caad772012-03-30 01:07:54 -0700358 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
359 mov %esp, %ebx // remember SP
360 // Outgoing argument set up
Elliott Hughesea944212012-04-05 13:11:53 -0700361 subl MACRO_LITERAL(12), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800362 .cfi_adjust_cfa_offset 12
363 PUSH ebx // pass SP
Ian Rogers7caad772012-03-30 01:07:54 -0700364 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800365 .cfi_adjust_cfa_offset 4
366 PUSH edx // pass arg3
367 PUSH ecx // pass arg2
368 PUSH eax // pass arg1
Mark Mendella9abe872014-01-10 05:52:01 -0800369 SETUP_GOT_NOSAVE // clobbers EBX
370 call VAR(cxx_name, 1)@PLT // cxx_name(arg1, arg2, arg3, Thread*, SP)
Elliott Hughesea944212012-04-05 13:11:53 -0700371 addl MACRO_LITERAL(32), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800372 .cfi_adjust_cfa_offset -32
Ian Rogers7caad772012-03-30 01:07:54 -0700373 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
Elliott Hughes754caaa2012-04-10 10:57:36 -0700374 CALL_MACRO(return_macro, 2) // return or deliver exception
Ian Rogersaeeada42013-02-13 11:28:34 -0800375 END_FUNCTION VAR(c_name, 0)
Ian Rogersd36c52e2012-04-09 16:29:25 -0700376END_MACRO
377
Mathieu Chartier590fee92013-09-13 13:46:47 -0700378MACRO0(RETURN_IF_RESULT_IS_NON_ZERO)
Ian Rogers7caad772012-03-30 01:07:54 -0700379 testl %eax, %eax // eax == 0 ?
Ian Rogersd36c52e2012-04-09 16:29:25 -0700380 jz 1f // if eax == 0 goto 1
381 ret // return
3821: // deliver exception on current thread
Ian Rogers7caad772012-03-30 01:07:54 -0700383 DELIVER_PENDING_EXCEPTION
384END_MACRO
385
Ian Rogersd36c52e2012-04-09 16:29:25 -0700386MACRO0(RETURN_IF_EAX_ZERO)
387 testl %eax, %eax // eax == 0 ?
388 jnz 1f // if eax != 0 goto 1
389 ret // return
3901: // deliver exception on current thread
Ian Rogers7caad772012-03-30 01:07:54 -0700391 DELIVER_PENDING_EXCEPTION
Ian Rogersd36c52e2012-04-09 16:29:25 -0700392END_MACRO
Ian Rogers7caad772012-03-30 01:07:54 -0700393
jeffhaod66a8752012-05-22 15:30:16 -0700394MACRO0(RETURN_OR_DELIVER_PENDING_EXCEPTION)
395 mov %fs:THREAD_EXCEPTION_OFFSET, %ebx // get exception field
396 testl %ebx, %ebx // ebx == 0 ?
397 jnz 1f // if ebx != 0 goto 1
398 ret // return
3991: // deliver exception on current thread
400 DELIVER_PENDING_EXCEPTION
401END_MACRO
402
Mathieu Chartier7410f292013-11-24 13:17:35 -0800403// Generate the allocation entrypoints for each allocator.
404GENERATE_ALL_ALLOC_ENTRYPOINTS
Ian Rogersd36c52e2012-04-09 16:29:25 -0700405
Mathieu Chartier590fee92013-09-13 13:46:47 -0700406TWO_ARG_DOWNCALL art_quick_resolve_string, artResolveStringFromCode, RETURN_IF_RESULT_IS_NON_ZERO
407TWO_ARG_DOWNCALL art_quick_initialize_static_storage, artInitializeStaticStorageFromCode, RETURN_IF_RESULT_IS_NON_ZERO
408TWO_ARG_DOWNCALL art_quick_initialize_type, artInitializeTypeFromCode, RETURN_IF_RESULT_IS_NON_ZERO
409TWO_ARG_DOWNCALL art_quick_initialize_type_and_verify_access, artInitializeTypeAndVerifyAccessFromCode, RETURN_IF_RESULT_IS_NON_ZERO
Ian Rogersd36c52e2012-04-09 16:29:25 -0700410
Ian Rogers468532e2013-08-05 10:56:33 -0700411TWO_ARG_DOWNCALL art_quick_handle_fill_data, artHandleFillArrayDataFromCode, RETURN_IF_EAX_ZERO
Ian Rogers7caad772012-03-30 01:07:54 -0700412
Ian Rogersd9c4fc92013-10-01 19:45:43 -0700413DEFINE_FUNCTION art_quick_lock_object
414 testl %eax, %eax // null check object/eax
415 jz slow_lock
416retry_lock:
417 movl LOCK_WORD_OFFSET(%eax), %ecx // ecx := lock word
Mathieu Chartierad2541a2013-10-25 10:05:23 -0700418 test LITERAL(0xC0000000), %ecx // test the 2 high bits.
419 jne slow_lock // slow path if either of the two high bits are set.
Ian Rogersd9c4fc92013-10-01 19:45:43 -0700420 movl %fs:THREAD_ID_OFFSET, %edx // edx := thread id
421 test %ecx, %ecx
Ian Rogersd9c4fc92013-10-01 19:45:43 -0700422 jnz already_thin // lock word contains a thin lock
423 // unlocked case - %edx holds thread id with count of 0
424 movl %eax, %ecx // remember object in case of retry
425 xor %eax, %eax // eax == 0 for comparison with lock word in cmpxchg
426 lock cmpxchg %edx, LOCK_WORD_OFFSET(%ecx)
427 jnz cmpxchg_fail // cmpxchg failed retry
428 ret
429cmpxchg_fail:
430 movl %ecx, %eax // restore eax
431 jmp retry_lock
432already_thin:
433 cmpw %ax, %dx // do we hold the lock already?
434 jne slow_lock
435 addl LITERAL(65536), %eax // increment recursion count
Mathieu Chartierad2541a2013-10-25 10:05:23 -0700436 test LITERAL(0xC0000000), %eax // overflowed if either of top two bits are set
437 jne slow_lock // count overflowed so go slow
Ian Rogersd9c4fc92013-10-01 19:45:43 -0700438 movl %eax, LOCK_WORD_OFFSET(%ecx) // update lockword, cmpxchg not necessary as we hold lock
439 ret
440slow_lock:
441 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
442 mov %esp, %edx // remember SP
Mark Mendella9abe872014-01-10 05:52:01 -0800443 SETUP_GOT_NOSAVE // clobbers EBX
Ian Rogersd9c4fc92013-10-01 19:45:43 -0700444 // Outgoing argument set up
445 PUSH eax // push padding
446 PUSH edx // pass SP
447 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
448 .cfi_adjust_cfa_offset 4
449 PUSH eax // pass object
Mark Mendella9abe872014-01-10 05:52:01 -0800450 call artLockObjectFromCode@PLT // artLockObjectFromCode(object, Thread*, SP)
Ian Rogersd9c4fc92013-10-01 19:45:43 -0700451 addl MACRO_LITERAL(16), %esp // pop arguments
452 .cfi_adjust_cfa_offset -16
453 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
454 RETURN_IF_EAX_ZERO
455END_FUNCTION art_quick_lock_object
456
457DEFINE_FUNCTION art_quick_unlock_object
458 testl %eax, %eax // null check object/eax
459 jz slow_unlock
460 movl LOCK_WORD_OFFSET(%eax), %ecx // ecx := lock word
461 movl %fs:THREAD_ID_OFFSET, %edx // edx := thread id
462 test %ecx, %ecx
463 jb slow_unlock // lock word contains a monitor
464 cmpw %cx, %dx // does the thread id match?
465 jne slow_unlock
466 cmpl LITERAL(65536), %ecx
467 jae recursive_thin_unlock
468 movl LITERAL(0), LOCK_WORD_OFFSET(%eax)
469 ret
470recursive_thin_unlock:
471 subl LITERAL(65536), %ecx
472 mov %ecx, LOCK_WORD_OFFSET(%eax)
473 ret
474slow_unlock:
475 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
476 mov %esp, %edx // remember SP
Mark Mendella9abe872014-01-10 05:52:01 -0800477 SETUP_GOT_NOSAVE // clobbers EBX
Ian Rogersd9c4fc92013-10-01 19:45:43 -0700478 // Outgoing argument set up
479 PUSH eax // push padding
480 PUSH edx // pass SP
481 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
482 .cfi_adjust_cfa_offset 4
483 PUSH eax // pass object
Mark Mendella9abe872014-01-10 05:52:01 -0800484 call artUnlockObjectFromCode@PLT // artUnlockObjectFromCode(object, Thread*, SP)
Ian Rogersd9c4fc92013-10-01 19:45:43 -0700485 addl MACRO_LITERAL(16), %esp // pop arguments
486 .cfi_adjust_cfa_offset -16
487 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
488 RETURN_IF_EAX_ZERO
489END_FUNCTION art_quick_unlock_object
490
Ian Rogers468532e2013-08-05 10:56:33 -0700491DEFINE_FUNCTION art_quick_is_assignable
Mark Mendella9abe872014-01-10 05:52:01 -0800492 SETUP_GOT_NOSAVE // clobbers EBX
Ian Rogersaeeada42013-02-13 11:28:34 -0800493 PUSH eax // alignment padding
Ian Rogersa9a82542013-10-04 11:17:26 -0700494 PUSH ecx // pass arg2 - obj->klass
495 PUSH eax // pass arg1 - checked class
Mark Mendella9abe872014-01-10 05:52:01 -0800496 call SYMBOL(artIsAssignableFromCode)@PLT // (Class* klass, Class* ref_klass)
Ian Rogers55bd45f2012-04-04 17:31:20 -0700497 addl LITERAL(12), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800498 .cfi_adjust_cfa_offset -12
Ian Rogers7caad772012-03-30 01:07:54 -0700499 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700500END_FUNCTION art_quick_is_assignable
Ian Rogers7caad772012-03-30 01:07:54 -0700501
Ian Rogersa9a82542013-10-04 11:17:26 -0700502DEFINE_FUNCTION art_quick_check_cast
Mark Mendella9abe872014-01-10 05:52:01 -0800503 SETUP_GOT_NOSAVE // clobbers EBX
Ian Rogersa9a82542013-10-04 11:17:26 -0700504 PUSH eax // alignment padding
505 PUSH ecx // pass arg2 - obj->klass
506 PUSH eax // pass arg1 - checked class
Mark Mendella9abe872014-01-10 05:52:01 -0800507 call SYMBOL(artIsAssignableFromCode)@PLT // (Class* klass, Class* ref_klass)
Ian Rogersa9a82542013-10-04 11:17:26 -0700508 testl %eax, %eax
509 jz 1f // jump forward if not assignable
510 addl LITERAL(12), %esp // pop arguments
511 .cfi_adjust_cfa_offset -12
512 ret
5131:
514 POP eax // pop arguments
515 POP ecx
516 addl LITERAL(4), %esp
517 .cfi_adjust_cfa_offset -12
518 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context
519 mov %esp, %edx
520 // Outgoing argument set up
521 PUSH edx // pass SP
522 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
523 .cfi_adjust_cfa_offset 4
524 PUSH ecx // pass arg2
525 PUSH eax // pass arg1
Mark Mendella9abe872014-01-10 05:52:01 -0800526 call SYMBOL(artThrowClassCastException)@PLT // (Class* a, Class* b, Thread*, SP)
Ian Rogersa9a82542013-10-04 11:17:26 -0700527 int3 // unreached
528END_FUNCTION art_quick_check_cast
529
530 /*
531 * Entry from managed code for array put operations of objects where the value being stored
532 * needs to be checked for compatibility.
533 * eax = array, ecx = index, edx = value
534 */
535DEFINE_FUNCTION art_quick_aput_obj_with_null_and_bound_check
536 testl %eax, %eax
537 jnz art_quick_aput_obj_with_bound_check
538 jmp art_quick_throw_null_pointer_exception
539END_FUNCTION art_quick_aput_obj_with_null_and_bound_check
540
541DEFINE_FUNCTION art_quick_aput_obj_with_bound_check
542 movl ARRAY_LENGTH_OFFSET(%eax), %ebx
543 cmpl %ebx, %ecx
544 jb art_quick_aput_obj
545 mov %ecx, %eax
546 mov %ebx, %ecx
547 jmp art_quick_throw_array_bounds
548END_FUNCTION art_quick_aput_obj_with_bound_check
549
550DEFINE_FUNCTION art_quick_aput_obj
551 test %edx, %edx // store of null
552 jz do_aput_null
553 movl CLASS_OFFSET(%eax), %ebx
554 movl CLASS_COMPONENT_TYPE_OFFSET(%ebx), %ebx
555 cmpl CLASS_OFFSET(%edx), %ebx // value's type == array's component type - trivial assignability
556 jne check_assignability
557do_aput:
558 movl %edx, OBJECT_ARRAY_DATA_OFFSET(%eax, %ecx, 4)
559 movl %fs:THREAD_CARD_TABLE_OFFSET, %edx
560 shrl LITERAL(7), %eax
561 movb %dl, (%edx, %eax)
562 ret
563do_aput_null:
564 movl %edx, OBJECT_ARRAY_DATA_OFFSET(%eax, %ecx, 4)
565 ret
566check_assignability:
567 PUSH eax // save arguments
568 PUSH ecx
569 PUSH edx
570 subl LITERAL(8), %esp // alignment padding
571 .cfi_adjust_cfa_offset 8
572 pushl CLASS_OFFSET(%edx) // pass arg2 - type of the value to be stored
573 .cfi_adjust_cfa_offset 4
574 PUSH ebx // pass arg1 - component type of the array
Mark Mendella9abe872014-01-10 05:52:01 -0800575 SETUP_GOT_NOSAVE // clobbers EBX
576 call SYMBOL(artIsAssignableFromCode)@PLT // (Class* a, Class* b)
Ian Rogersa9a82542013-10-04 11:17:26 -0700577 addl LITERAL(16), %esp // pop arguments
578 .cfi_adjust_cfa_offset -16
579 testl %eax, %eax
580 jz throw_array_store_exception
581 POP edx
582 POP ecx
583 POP eax
584 movl %edx, OBJECT_ARRAY_DATA_OFFSET(%eax, %ecx, 4) // do the aput
585 movl %fs:THREAD_CARD_TABLE_OFFSET, %edx
586 shrl LITERAL(7), %eax
587 movb %dl, (%edx, %eax)
588 ret
589throw_array_store_exception:
590 POP edx
591 POP ecx
592 POP eax
593 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context
594 mov %esp, %ecx
595 // Outgoing argument set up
596 PUSH ecx // pass SP
597 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
598 .cfi_adjust_cfa_offset 4
599 PUSH edx // pass arg2 - value
600 PUSH eax // pass arg1 - array
Mark Mendella9abe872014-01-10 05:52:01 -0800601 call SYMBOL(artThrowArrayStoreException)@PLT // (array, value, Thread*, SP)
Ian Rogersa9a82542013-10-04 11:17:26 -0700602 int3 // unreached
603END_FUNCTION art_quick_aput_obj
604
Logan Chien8dbb7082013-01-25 20:31:17 +0800605DEFINE_FUNCTION art_quick_memcpy
Mark Mendella9abe872014-01-10 05:52:01 -0800606 SETUP_GOT_NOSAVE // clobbers EBX
Ian Rogersaeeada42013-02-13 11:28:34 -0800607 PUSH edx // pass arg3
608 PUSH ecx // pass arg2
609 PUSH eax // pass arg1
Mark Mendella9abe872014-01-10 05:52:01 -0800610 call SYMBOL(memcpy)@PLT // (void*, const void*, size_t)
Ian Rogers55bd45f2012-04-04 17:31:20 -0700611 addl LITERAL(12), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800612 .cfi_adjust_cfa_offset -12
Ian Rogers7caad772012-03-30 01:07:54 -0700613 ret
Ian Rogersaeeada42013-02-13 11:28:34 -0800614END_FUNCTION art_quick_memcpy
Ian Rogers7caad772012-03-30 01:07:54 -0700615
Logan Chien8dbb7082013-01-25 20:31:17 +0800616NO_ARG_DOWNCALL art_quick_test_suspend, artTestSuspendFromCode, ret
Ian Rogers7caad772012-03-30 01:07:54 -0700617
Ian Rogers468532e2013-08-05 10:56:33 -0700618DEFINE_FUNCTION art_quick_fmod
jeffhao1395b1e2012-06-13 18:05:13 -0700619 subl LITERAL(12), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800620 .cfi_adjust_cfa_offset 12
621 PUSH ebx // pass arg4 b.hi
622 PUSH edx // pass arg3 b.lo
623 PUSH ecx // pass arg2 a.hi
624 PUSH eax // pass arg1 a.lo
Mark Mendella9abe872014-01-10 05:52:01 -0800625 SETUP_GOT_NOSAVE // clobbers EBX
626 call SYMBOL(fmod)@PLT // (jdouble a, jdouble b)
jeffhao1395b1e2012-06-13 18:05:13 -0700627 fstpl (%esp) // pop return value off fp stack
628 movsd (%esp), %xmm0 // place into %xmm0
629 addl LITERAL(28), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800630 .cfi_adjust_cfa_offset -28
jeffhao292188d2012-05-17 15:45:04 -0700631 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700632END_FUNCTION art_quick_fmod
jeffhao292188d2012-05-17 15:45:04 -0700633
Ian Rogers468532e2013-08-05 10:56:33 -0700634DEFINE_FUNCTION art_quick_fmodf
Ian Rogersaeeada42013-02-13 11:28:34 -0800635 PUSH eax // alignment padding
636 PUSH ecx // pass arg2 b
637 PUSH eax // pass arg1 a
Mark Mendella9abe872014-01-10 05:52:01 -0800638 SETUP_GOT_NOSAVE // clobbers EBX
639 call SYMBOL(fmodf)@PLT // (jfloat a, jfloat b)
Ian Rogers1b09b092012-08-20 15:35:52 -0700640 fstps (%esp) // pop return value off fp stack
jeffhao1395b1e2012-06-13 18:05:13 -0700641 movss (%esp), %xmm0 // place into %xmm0
642 addl LITERAL(12), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800643 .cfi_adjust_cfa_offset -12
jeffhao292188d2012-05-17 15:45:04 -0700644 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700645END_FUNCTION art_quick_fmodf
jeffhao292188d2012-05-17 15:45:04 -0700646
Ian Rogers468532e2013-08-05 10:56:33 -0700647DEFINE_FUNCTION art_quick_l2d
Ian Rogers5793fea2013-02-14 13:33:34 -0800648 PUSH ecx // push arg2 a.hi
649 PUSH eax // push arg1 a.lo
650 fildll (%esp) // load as integer and push into st0
651 fstpl (%esp) // pop value off fp stack as double
jeffhao41005dd2012-05-09 17:58:52 -0700652 movsd (%esp), %xmm0 // place into %xmm0
Ian Rogers5793fea2013-02-14 13:33:34 -0800653 addl LITERAL(8), %esp // pop arguments
654 .cfi_adjust_cfa_offset -8
jeffhao41005dd2012-05-09 17:58:52 -0700655 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700656END_FUNCTION art_quick_l2d
jeffhao41005dd2012-05-09 17:58:52 -0700657
Ian Rogers468532e2013-08-05 10:56:33 -0700658DEFINE_FUNCTION art_quick_l2f
Ian Rogers5793fea2013-02-14 13:33:34 -0800659 PUSH ecx // push arg2 a.hi
660 PUSH eax // push arg1 a.lo
661 fildll (%esp) // load as integer and push into st0
662 fstps (%esp) // pop value off fp stack as a single
jeffhao41005dd2012-05-09 17:58:52 -0700663 movss (%esp), %xmm0 // place into %xmm0
Ian Rogers5793fea2013-02-14 13:33:34 -0800664 addl LITERAL(8), %esp // pop argument
665 .cfi_adjust_cfa_offset -8
jeffhao41005dd2012-05-09 17:58:52 -0700666 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700667END_FUNCTION art_quick_l2f
jeffhao41005dd2012-05-09 17:58:52 -0700668
Ian Rogers468532e2013-08-05 10:56:33 -0700669DEFINE_FUNCTION art_quick_d2l
Ian Rogersaeeada42013-02-13 11:28:34 -0800670 PUSH eax // alignment padding
671 PUSH ecx // pass arg2 a.hi
672 PUSH eax // pass arg1 a.lo
Mark Mendella9abe872014-01-10 05:52:01 -0800673 SETUP_GOT_NOSAVE // clobbers EBX
674 call SYMBOL(art_d2l)@PLT // (jdouble a)
jeffhao41005dd2012-05-09 17:58:52 -0700675 addl LITERAL(12), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800676 .cfi_adjust_cfa_offset -12
jeffhao41005dd2012-05-09 17:58:52 -0700677 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700678END_FUNCTION art_quick_d2l
jeffhao41005dd2012-05-09 17:58:52 -0700679
Ian Rogers468532e2013-08-05 10:56:33 -0700680DEFINE_FUNCTION art_quick_f2l
jeffhao41005dd2012-05-09 17:58:52 -0700681 subl LITERAL(8), %esp // alignment padding
Ian Rogers5793fea2013-02-14 13:33:34 -0800682 .cfi_adjust_cfa_offset 8
Mark Mendella9abe872014-01-10 05:52:01 -0800683 SETUP_GOT_NOSAVE // clobbers EBX
Ian Rogersaeeada42013-02-13 11:28:34 -0800684 PUSH eax // pass arg1 a
Mark Mendella9abe872014-01-10 05:52:01 -0800685 call SYMBOL(art_f2l)@PLT // (jfloat a)
jeffhao41005dd2012-05-09 17:58:52 -0700686 addl LITERAL(12), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800687 .cfi_adjust_cfa_offset -12
jeffhao41005dd2012-05-09 17:58:52 -0700688 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700689END_FUNCTION art_quick_f2l
jeffhao41005dd2012-05-09 17:58:52 -0700690
Ian Rogers468532e2013-08-05 10:56:33 -0700691DEFINE_FUNCTION art_quick_idivmod
jeffhao174651d2012-04-19 15:27:22 -0700692 cmpl LITERAL(0x80000000), %eax
693 je check_arg2 // special case
694args_ok:
Ian Rogers7caad772012-03-30 01:07:54 -0700695 cdq // edx:eax = sign extend eax
696 idiv %ecx // (edx,eax) = (edx:eax % ecx, edx:eax / ecx)
Ian Rogers7caad772012-03-30 01:07:54 -0700697 ret
jeffhao174651d2012-04-19 15:27:22 -0700698check_arg2:
699 cmpl LITERAL(-1), %ecx
700 jne args_ok
701 xorl %edx, %edx
702 ret // eax already holds min int
Ian Rogers468532e2013-08-05 10:56:33 -0700703END_FUNCTION art_quick_idivmod
Ian Rogers7caad772012-03-30 01:07:54 -0700704
Ian Rogers468532e2013-08-05 10:56:33 -0700705DEFINE_FUNCTION art_quick_ldiv
Ian Rogersa9a82542013-10-04 11:17:26 -0700706 subl LITERAL(12), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800707 .cfi_adjust_cfa_offset 12
708 PUSH ebx // pass arg4 b.hi
709 PUSH edx // pass arg3 b.lo
710 PUSH ecx // pass arg2 a.hi
Ian Rogersa9a82542013-10-04 11:17:26 -0700711 PUSH eax // pass arg1 a.lo
Mark Mendella9abe872014-01-10 05:52:01 -0800712 SETUP_GOT_NOSAVE // clobbers EBX
713 call SYMBOL(artLdiv)@PLT // (jlong a, jlong b)
Ian Rogersa9a82542013-10-04 11:17:26 -0700714 addl LITERAL(28), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800715 .cfi_adjust_cfa_offset -28
Ian Rogers55bd45f2012-04-04 17:31:20 -0700716 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700717END_FUNCTION art_quick_ldiv
Ian Rogers55bd45f2012-04-04 17:31:20 -0700718
Ian Rogersa9a82542013-10-04 11:17:26 -0700719DEFINE_FUNCTION art_quick_lmod
720 subl LITERAL(12), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800721 .cfi_adjust_cfa_offset 12
722 PUSH ebx // pass arg4 b.hi
723 PUSH edx // pass arg3 b.lo
724 PUSH ecx // pass arg2 a.hi
Ian Rogersa9a82542013-10-04 11:17:26 -0700725 PUSH eax // pass arg1 a.lo
Mark Mendella9abe872014-01-10 05:52:01 -0800726 SETUP_GOT_NOSAVE // clobbers EBX
727 call SYMBOL(artLmod)@PLT // (jlong a, jlong b)
Ian Rogersa9a82542013-10-04 11:17:26 -0700728 addl LITERAL(28), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800729 .cfi_adjust_cfa_offset -28
Ian Rogers55bd45f2012-04-04 17:31:20 -0700730 ret
Ian Rogersa9a82542013-10-04 11:17:26 -0700731END_FUNCTION art_quick_lmod
Ian Rogers55bd45f2012-04-04 17:31:20 -0700732
Ian Rogers468532e2013-08-05 10:56:33 -0700733DEFINE_FUNCTION art_quick_lmul
Ian Rogers5793fea2013-02-14 13:33:34 -0800734 imul %eax, %ebx // ebx = a.lo(eax) * b.hi(ebx)
735 imul %edx, %ecx // ecx = b.lo(edx) * a.hi(ecx)
736 mul %edx // edx:eax = a.lo(eax) * b.lo(edx)
737 add %ebx, %ecx
738 add %ecx, %edx // edx += (a.lo * b.hi) + (b.lo * a.hi)
jeffhao644d5312012-05-03 19:04:49 -0700739 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700740END_FUNCTION art_quick_lmul
jeffhao644d5312012-05-03 19:04:49 -0700741
Ian Rogers468532e2013-08-05 10:56:33 -0700742DEFINE_FUNCTION art_quick_lshl
jeffhao644d5312012-05-03 19:04:49 -0700743 // ecx:eax << edx
Ian Rogers141d6222012-04-05 12:23:06 -0700744 xchg %edx, %ecx
745 shld %cl,%eax,%edx
746 shl %cl,%eax
747 test LITERAL(32), %cl
748 jz 1f
749 mov %eax, %edx
750 xor %eax, %eax
7511:
752 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700753END_FUNCTION art_quick_lshl
Ian Rogers141d6222012-04-05 12:23:06 -0700754
Ian Rogers468532e2013-08-05 10:56:33 -0700755DEFINE_FUNCTION art_quick_lshr
jeffhao644d5312012-05-03 19:04:49 -0700756 // ecx:eax >> edx
Ian Rogers141d6222012-04-05 12:23:06 -0700757 xchg %edx, %ecx
jeffhao644d5312012-05-03 19:04:49 -0700758 shrd %cl,%edx,%eax
759 sar %cl,%edx
Ian Rogers141d6222012-04-05 12:23:06 -0700760 test LITERAL(32),%cl
761 jz 1f
jeffhao5121e0b2012-05-08 18:23:38 -0700762 mov %edx, %eax
763 sar LITERAL(31), %edx
Ian Rogers141d6222012-04-05 12:23:06 -07007641:
765 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700766END_FUNCTION art_quick_lshr
Ian Rogers141d6222012-04-05 12:23:06 -0700767
Ian Rogers468532e2013-08-05 10:56:33 -0700768DEFINE_FUNCTION art_quick_lushr
jeffhao644d5312012-05-03 19:04:49 -0700769 // ecx:eax >>> edx
Ian Rogers141d6222012-04-05 12:23:06 -0700770 xchg %edx, %ecx
jeffhao644d5312012-05-03 19:04:49 -0700771 shrd %cl,%edx,%eax
772 shr %cl,%edx
773 test LITERAL(32),%cl
Ian Rogers141d6222012-04-05 12:23:06 -0700774 jz 1f
jeffhao5121e0b2012-05-08 18:23:38 -0700775 mov %edx, %eax
776 xor %edx, %edx
Ian Rogers141d6222012-04-05 12:23:06 -07007771:
778 ret
Ian Rogers468532e2013-08-05 10:56:33 -0700779END_FUNCTION art_quick_lushr
Ian Rogers141d6222012-04-05 12:23:06 -0700780
Ian Rogers468532e2013-08-05 10:56:33 -0700781DEFINE_FUNCTION art_quick_set32_instance
jeffhao9dbb23e2012-05-18 17:03:57 -0700782 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
783 mov %esp, %ebx // remember SP
jeffhao1ff4cd72012-05-21 11:17:48 -0700784 subl LITERAL(8), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800785 .cfi_adjust_cfa_offset 8
786 PUSH ebx // pass SP
jeffhao9dbb23e2012-05-18 17:03:57 -0700787 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800788 .cfi_adjust_cfa_offset 4
jeffhao9dbb23e2012-05-18 17:03:57 -0700789 mov 32(%ebx), %ebx // get referrer
Ian Rogersaeeada42013-02-13 11:28:34 -0800790 PUSH ebx // pass referrer
791 PUSH edx // pass new_val
792 PUSH ecx // pass object
793 PUSH eax // pass field_idx
Mark Mendella9abe872014-01-10 05:52:01 -0800794 SETUP_GOT_NOSAVE // clobbers EBX
795 call SYMBOL(artSet32InstanceFromCode)@PLT // (field_idx, Object*, new_val, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700796 addl LITERAL(32), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800797 .cfi_adjust_cfa_offset -32
jeffhao9dbb23e2012-05-18 17:03:57 -0700798 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
799 RETURN_IF_EAX_ZERO // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -0700800END_FUNCTION art_quick_set32_instance
jeffhao9dbb23e2012-05-18 17:03:57 -0700801
Ian Rogers468532e2013-08-05 10:56:33 -0700802DEFINE_FUNCTION art_quick_set64_instance
Ian Rogersaeeada42013-02-13 11:28:34 -0800803 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
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 esp // pass SP-8
jeffhao1ff4cd72012-05-21 11:17:48 -0700807 addl LITERAL(8), (%esp) // fix SP on stack by adding 8
jeffhao9dbb23e2012-05-18 17:03:57 -0700808 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800809 .cfi_adjust_cfa_offset 4
810 PUSH ebx // pass high half of new_val
811 PUSH edx // pass low half of new_val
812 PUSH ecx // pass object
813 PUSH eax // pass field_idx
Mark Mendella9abe872014-01-10 05:52:01 -0800814 SETUP_GOT_NOSAVE // clobbers EBX
815 call SYMBOL(artSet64InstanceFromCode)@PLT // (field_idx, Object*, new_val, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700816 addl LITERAL(32), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800817 .cfi_adjust_cfa_offset -32
818 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
jeffhao9dbb23e2012-05-18 17:03:57 -0700819 RETURN_IF_EAX_ZERO // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -0700820END_FUNCTION art_quick_set64_instance
jeffhao9dbb23e2012-05-18 17:03:57 -0700821
Ian Rogers468532e2013-08-05 10:56:33 -0700822DEFINE_FUNCTION art_quick_set_obj_instance
Ian Rogersaeeada42013-02-13 11:28:34 -0800823 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
jeffhao9dbb23e2012-05-18 17:03:57 -0700824 mov %esp, %ebx // remember SP
jeffhao1ff4cd72012-05-21 11:17:48 -0700825 subl LITERAL(8), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800826 .cfi_adjust_cfa_offset 8
827 PUSH ebx // pass SP
jeffhao9dbb23e2012-05-18 17:03:57 -0700828 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800829 .cfi_adjust_cfa_offset 4
jeffhao9dbb23e2012-05-18 17:03:57 -0700830 mov 32(%ebx), %ebx // get referrer
Ian Rogersaeeada42013-02-13 11:28:34 -0800831 PUSH ebx // pass referrer
832 PUSH edx // pass new_val
833 PUSH ecx // pass object
834 PUSH eax // pass field_idx
Mark Mendella9abe872014-01-10 05:52:01 -0800835 SETUP_GOT_NOSAVE // clobbers EBX
836 call SYMBOL(artSetObjInstanceFromCode)@PLT // (field_idx, Object*, new_val, 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
840 RETURN_IF_EAX_ZERO // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -0700841END_FUNCTION art_quick_set_obj_instance
jeffhao9dbb23e2012-05-18 17:03:57 -0700842
Ian Rogers468532e2013-08-05 10:56:33 -0700843DEFINE_FUNCTION art_quick_get32_instance
Ian Rogersaeeada42013-02-13 11:28:34 -0800844 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
jeffhao9dbb23e2012-05-18 17:03:57 -0700845 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
Mark Mendella9abe872014-01-10 05:52:01 -0800855 SETUP_GOT_NOSAVE // clobbers EBX
856 call SYMBOL(artGet32InstanceFromCode)@PLT // (field_idx, Object*, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700857 addl LITERAL(32), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800858 .cfi_adjust_cfa_offset -32
jeffhao9dbb23e2012-05-18 17:03:57 -0700859 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
jeffhaod66a8752012-05-22 15:30:16 -0700860 RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -0700861END_FUNCTION art_quick_get32_instance
jeffhao9dbb23e2012-05-18 17:03:57 -0700862
Ian Rogers468532e2013-08-05 10:56:33 -0700863DEFINE_FUNCTION art_quick_get64_instance
jeffhao9dbb23e2012-05-18 17:03:57 -0700864 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
865 mov %esp, %ebx // remember SP
866 mov 32(%esp), %edx // get referrer
jeffhao1ff4cd72012-05-21 11:17:48 -0700867 subl LITERAL(12), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800868 .cfi_adjust_cfa_offset 12
869 PUSH ebx // pass SP
jeffhao9dbb23e2012-05-18 17:03:57 -0700870 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800871 .cfi_adjust_cfa_offset 4
872 PUSH edx // pass referrer
873 PUSH ecx // pass object
874 PUSH eax // pass field_idx
Mark Mendella9abe872014-01-10 05:52:01 -0800875 SETUP_GOT_NOSAVE // clobbers EBX
876 call SYMBOL(artGet64InstanceFromCode)@PLT // (field_idx, Object*, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700877 addl LITERAL(32), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800878 .cfi_adjust_cfa_offset -32
jeffhao9dbb23e2012-05-18 17:03:57 -0700879 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
jeffhaod66a8752012-05-22 15:30:16 -0700880 RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -0700881END_FUNCTION art_quick_get64_instance
jeffhao9dbb23e2012-05-18 17:03:57 -0700882
Ian Rogers468532e2013-08-05 10:56:33 -0700883DEFINE_FUNCTION art_quick_get_obj_instance
jeffhao9dbb23e2012-05-18 17:03:57 -0700884 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
885 mov %esp, %ebx // remember SP
886 mov 32(%esp), %edx // get referrer
jeffhao1ff4cd72012-05-21 11:17:48 -0700887 subl LITERAL(12), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800888 .cfi_adjust_cfa_offset 12
889 PUSH ebx // pass SP
jeffhao9dbb23e2012-05-18 17:03:57 -0700890 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800891 .cfi_adjust_cfa_offset 4
892 PUSH edx // pass referrer
893 PUSH ecx // pass object
894 PUSH eax // pass field_idx
Mark Mendella9abe872014-01-10 05:52:01 -0800895 SETUP_GOT_NOSAVE // clobbers EBX
896 call SYMBOL(artGetObjInstanceFromCode)@PLT // (field_idx, Object*, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700897 addl LITERAL(32), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800898 .cfi_adjust_cfa_offset -32
jeffhao9dbb23e2012-05-18 17:03:57 -0700899 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
jeffhaod66a8752012-05-22 15:30:16 -0700900 RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -0700901END_FUNCTION art_quick_get_obj_instance
jeffhao9dbb23e2012-05-18 17:03:57 -0700902
Ian Rogers468532e2013-08-05 10:56:33 -0700903DEFINE_FUNCTION art_quick_set32_static
jeffhao9dbb23e2012-05-18 17:03:57 -0700904 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
905 mov %esp, %ebx // remember SP
906 mov 32(%esp), %edx // get referrer
jeffhao1ff4cd72012-05-21 11:17:48 -0700907 subl LITERAL(12), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800908 .cfi_adjust_cfa_offset 12
909 PUSH ebx // pass SP
jeffhao9dbb23e2012-05-18 17:03:57 -0700910 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800911 .cfi_adjust_cfa_offset 4
912 PUSH edx // pass referrer
913 PUSH ecx // pass new_val
914 PUSH eax // pass field_idx
Mark Mendella9abe872014-01-10 05:52:01 -0800915 SETUP_GOT_NOSAVE // clobbers EBX
916 call SYMBOL(artSet32StaticFromCode)@PLT // (field_idx, new_val, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700917 addl LITERAL(32), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800918 .cfi_adjust_cfa_offset -32
jeffhao9dbb23e2012-05-18 17:03:57 -0700919 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
920 RETURN_IF_EAX_ZERO // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -0700921END_FUNCTION art_quick_set32_static
jeffhao9dbb23e2012-05-18 17:03:57 -0700922
Ian Rogers468532e2013-08-05 10:56:33 -0700923DEFINE_FUNCTION art_quick_set64_static
Ian Rogersaeeada42013-02-13 11:28:34 -0800924 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
jeffhao9dbb23e2012-05-18 17:03:57 -0700925 mov %esp, %ebx // remember SP
jeffhao1ff4cd72012-05-21 11:17:48 -0700926 subl LITERAL(8), %esp // alignment padding
Ian Rogersaeeada42013-02-13 11:28:34 -0800927 .cfi_adjust_cfa_offset 8
928 PUSH ebx // pass SP
jeffhao9dbb23e2012-05-18 17:03:57 -0700929 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800930 .cfi_adjust_cfa_offset 4
jeffhao9dbb23e2012-05-18 17:03:57 -0700931 mov 32(%ebx), %ebx // get referrer
Ian Rogersaeeada42013-02-13 11:28:34 -0800932 PUSH edx // pass high half of new_val
933 PUSH ecx // pass low half of new_val
934 PUSH ebx // pass referrer
935 PUSH eax // pass field_idx
Mark Mendella9abe872014-01-10 05:52:01 -0800936 SETUP_GOT_NOSAVE // clobbers EBX
937 call SYMBOL(artSet64StaticFromCode)@PLT // (field_idx, referrer, new_val, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700938 addl LITERAL(32), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800939 .cfi_adjust_cfa_offset -32
940 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
jeffhao9dbb23e2012-05-18 17:03:57 -0700941 RETURN_IF_EAX_ZERO // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -0700942END_FUNCTION art_quick_set64_static
jeffhao9dbb23e2012-05-18 17:03:57 -0700943
Ian Rogers468532e2013-08-05 10:56:33 -0700944DEFINE_FUNCTION art_quick_set_obj_static
Ian Rogersaeeada42013-02-13 11:28:34 -0800945 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
jeffhao9dbb23e2012-05-18 17:03:57 -0700946 mov %esp, %ebx // remember SP
947 mov 32(%esp), %edx // get referrer
jeffhao1ff4cd72012-05-21 11:17:48 -0700948 subl LITERAL(12), %esp // alignment padding
Ian Rogers62d6c772013-02-27 08:32:07 -0800949 .cfi_adjust_cfa_offset 12
Ian Rogersaeeada42013-02-13 11:28:34 -0800950 PUSH ebx // pass SP
jeffhao9dbb23e2012-05-18 17:03:57 -0700951 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800952 .cfi_adjust_cfa_offset 4
953 PUSH edx // pass referrer
954 PUSH ecx // pass new_val
955 PUSH eax // pass field_idx
Mark Mendella9abe872014-01-10 05:52:01 -0800956 SETUP_GOT_NOSAVE // clobbers EBX
957 call SYMBOL(artSetObjStaticFromCode)@PLT // (field_idx, new_val, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700958 addl LITERAL(32), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800959 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
jeffhao9dbb23e2012-05-18 17:03:57 -0700960 RETURN_IF_EAX_ZERO // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -0700961END_FUNCTION art_quick_set_obj_static
jeffhao9dbb23e2012-05-18 17:03:57 -0700962
Ian Rogers468532e2013-08-05 10:56:33 -0700963DEFINE_FUNCTION art_quick_get32_static
jeffhao9dbb23e2012-05-18 17:03:57 -0700964 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
965 mov %esp, %edx // remember SP
966 mov 32(%esp), %ecx // get referrer
Ian Rogersaeeada42013-02-13 11:28:34 -0800967 PUSH edx // pass SP
jeffhao9dbb23e2012-05-18 17:03:57 -0700968 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800969 .cfi_adjust_cfa_offset 4
970 PUSH ecx // pass referrer
971 PUSH eax // pass field_idx
Mark Mendella9abe872014-01-10 05:52:01 -0800972 SETUP_GOT_NOSAVE // clobbers EBX
973 call SYMBOL(artGet32StaticFromCode)@PLT // (field_idx, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700974 addl LITERAL(16), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800975 .cfi_adjust_cfa_offset -16
jeffhao9dbb23e2012-05-18 17:03:57 -0700976 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
jeffhaod66a8752012-05-22 15:30:16 -0700977 RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -0700978END_FUNCTION art_quick_get32_static
jeffhao9dbb23e2012-05-18 17:03:57 -0700979
Ian Rogers468532e2013-08-05 10:56:33 -0700980DEFINE_FUNCTION art_quick_get64_static
Ian Rogersaeeada42013-02-13 11:28:34 -0800981 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
jeffhao9dbb23e2012-05-18 17:03:57 -0700982 mov %esp, %edx // remember SP
983 mov 32(%esp), %ecx // get referrer
Ian Rogersaeeada42013-02-13 11:28:34 -0800984 PUSH edx // pass SP
jeffhao9dbb23e2012-05-18 17:03:57 -0700985 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -0800986 .cfi_adjust_cfa_offset 4
987 PUSH ecx // pass referrer
988 PUSH eax // pass field_idx
Mark Mendella9abe872014-01-10 05:52:01 -0800989 SETUP_GOT_NOSAVE // clobbers EBX
990 call SYMBOL(artGet64StaticFromCode)@PLT // (field_idx, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -0700991 addl LITERAL(16), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -0800992 .cfi_adjust_cfa_offset -16
jeffhao9dbb23e2012-05-18 17:03:57 -0700993 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
jeffhaod66a8752012-05-22 15:30:16 -0700994 RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -0700995END_FUNCTION art_quick_get64_static
jeffhao9dbb23e2012-05-18 17:03:57 -0700996
Ian Rogers468532e2013-08-05 10:56:33 -0700997DEFINE_FUNCTION art_quick_get_obj_static
jeffhao9dbb23e2012-05-18 17:03:57 -0700998 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
999 mov %esp, %edx // remember SP
1000 mov 32(%esp), %ecx // get referrer
Ian Rogersaeeada42013-02-13 11:28:34 -08001001 PUSH edx // pass SP
jeffhao9dbb23e2012-05-18 17:03:57 -07001002 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -08001003 .cfi_adjust_cfa_offset 4
1004 PUSH ecx // pass referrer
1005 PUSH eax // pass field_idx
Mark Mendella9abe872014-01-10 05:52:01 -08001006 SETUP_GOT_NOSAVE // clobbers EBX
1007 call SYMBOL(artGetObjStaticFromCode)@PLT // (field_idx, referrer, Thread*, SP)
jeffhao1ff4cd72012-05-21 11:17:48 -07001008 addl LITERAL(16), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -08001009 .cfi_adjust_cfa_offset -16
jeffhao9dbb23e2012-05-18 17:03:57 -07001010 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
jeffhaod66a8752012-05-22 15:30:16 -07001011 RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -07001012END_FUNCTION art_quick_get_obj_static
jeffhaod66a8752012-05-22 15:30:16 -07001013
Logan Chien8dbb7082013-01-25 20:31:17 +08001014DEFINE_FUNCTION art_quick_proxy_invoke_handler
Ian Rogers7db619b2013-01-16 18:35:48 -08001015 SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME // save frame and Method*
Ian Rogersaeeada42013-02-13 11:28:34 -08001016 PUSH esp // pass SP
jeffhaod66a8752012-05-22 15:30:16 -07001017 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -08001018 .cfi_adjust_cfa_offset 4
1019 PUSH ecx // pass receiver
1020 PUSH eax // pass proxy method
Mark Mendella9abe872014-01-10 05:52:01 -08001021 SETUP_GOT_NOSAVE // clobbers EBX
1022 call SYMBOL(artQuickProxyInvokeHandler)@PLT // (proxy method, receiver, Thread*, SP)
Ian Rogersaf6e67a2013-01-16 08:38:37 -08001023 movd %eax, %xmm0 // place return value also into floating point return value
1024 movd %edx, %xmm1
1025 punpckldq %xmm1, %xmm0
jeffhaod66a8752012-05-22 15:30:16 -07001026 addl LITERAL(44), %esp // pop arguments
Ian Rogersaeeada42013-02-13 11:28:34 -08001027 .cfi_adjust_cfa_offset -44
jeffhaod66a8752012-05-22 15:30:16 -07001028 RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
Ian Rogersaeeada42013-02-13 11:28:34 -08001029END_FUNCTION art_quick_proxy_invoke_handler
jeffhao9dbb23e2012-05-18 17:03:57 -07001030
Jeff Hao88474b42013-10-23 16:24:40 -07001031 /*
1032 * Called to resolve an imt conflict. xmm0 is a hidden argument that holds the target method's
1033 * dex method index.
1034 */
1035DEFINE_FUNCTION art_quick_imt_conflict_trampoline
1036 PUSH ecx
1037 movl 8(%esp), %eax // load caller Method*
1038 movl METHOD_DEX_CACHE_METHODS_OFFSET(%eax), %eax // load dex_cache_resolved_methods
1039 movd %xmm0, %ecx // get target method index stored in xmm0
1040 movl OBJECT_ARRAY_DATA_OFFSET(%eax, %ecx, 4), %eax // load the target method
1041 POP ecx
1042 jmp art_quick_invoke_interface_trampoline
1043END_FUNCTION art_quick_imt_conflict_trampoline
1044
Ian Rogers468532e2013-08-05 10:56:33 -07001045DEFINE_FUNCTION art_quick_resolution_trampoline
1046 SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME
1047 PUSH esp // pass SP
1048 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
1049 .cfi_adjust_cfa_offset 4
1050 PUSH ecx // pass receiver
1051 PUSH eax // pass method
Mark Mendella9abe872014-01-10 05:52:01 -08001052 SETUP_GOT_NOSAVE // clobbers EBX
1053 call SYMBOL(artQuickResolutionTrampoline)@PLT // (Method* called, receiver, Thread*, SP)
Ian Rogers468532e2013-08-05 10:56:33 -07001054 movl %eax, %edi // remember code pointer in EDI
1055 addl LITERAL(16), %esp // pop arguments
1056 test %eax, %eax // if code pointer is NULL goto deliver pending exception
1057 jz 1f
1058 POP eax // called method
1059 POP ecx // restore args
1060 POP edx
1061 POP ebx
1062 POP ebp // restore callee saves except EDI
1063 POP esi
1064 xchgl 0(%esp),%edi // restore EDI and place code pointer as only value on stack
1065 ret // tail call into method
10661:
1067 RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME
1068 DELIVER_PENDING_EXCEPTION
1069END_FUNCTION art_quick_resolution_trampoline
1070
1071DEFINE_FUNCTION art_quick_to_interpreter_bridge
Ian Rogers62d6c772013-02-27 08:32:07 -08001072 SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME // save frame
Ian Rogersaeeada42013-02-13 11:28:34 -08001073 mov %esp, %edx // remember SP
1074 PUSH eax // alignment padding
1075 PUSH edx // pass SP
Ian Rogers7db619b2013-01-16 18:35:48 -08001076 pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
Ian Rogersaeeada42013-02-13 11:28:34 -08001077 .cfi_adjust_cfa_offset 4
1078 PUSH eax // pass method
Mark Mendella9abe872014-01-10 05:52:01 -08001079 SETUP_GOT_NOSAVE // clobbers EBX
1080 call SYMBOL(artQuickToInterpreterBridge)@PLT // (method, Thread*, SP)
Ian Rogers7db619b2013-01-16 18:35:48 -08001081 movd %eax, %xmm0 // place return value also into floating point return value
1082 movd %edx, %xmm1
1083 punpckldq %xmm1, %xmm0
Mathieu Chartier19841522013-10-22 11:29:00 -07001084 addl LITERAL(16), %esp // pop arguments
1085 .cfi_adjust_cfa_offset -16
1086 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
Ian Rogers7db619b2013-01-16 18:35:48 -08001087 RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
Ian Rogers468532e2013-08-05 10:56:33 -07001088END_FUNCTION art_quick_to_interpreter_bridge
Ian Rogers7db619b2013-01-16 18:35:48 -08001089
jeffhao7e4fcb82013-01-10 18:11:08 -08001090 /*
1091 * Routine that intercepts method calls and returns.
1092 */
Ian Rogers468532e2013-08-05 10:56:33 -07001093DEFINE_FUNCTION art_quick_instrumentation_entry
Ian Rogers62d6c772013-02-27 08:32:07 -08001094 SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME
1095 movl %esp, %edx // Save SP.
1096 PUSH eax // Save eax which will be clobbered by the callee-save method.
1097 subl LITERAL(8), %esp // Align stack.
1098 .cfi_adjust_cfa_offset 8
1099 pushl 40(%esp) // Pass LR.
Ian Rogersaeeada42013-02-13 11:28:34 -08001100 .cfi_adjust_cfa_offset 4
Ian Rogers62d6c772013-02-27 08:32:07 -08001101 PUSH edx // Pass SP.
1102 pushl %fs:THREAD_SELF_OFFSET // Pass Thread::Current().
Ian Rogersaeeada42013-02-13 11:28:34 -08001103 .cfi_adjust_cfa_offset 4
Ian Rogers62d6c772013-02-27 08:32:07 -08001104 PUSH ecx // Pass receiver.
1105 PUSH eax // Pass Method*.
Mark Mendella9abe872014-01-10 05:52:01 -08001106 SETUP_GOT_NOSAVE // clobbers EBX
1107 call SYMBOL(artInstrumentationMethodEntryFromCode)@PLT // (Method*, Object*, Thread*, SP, LR)
Ian Rogers62d6c772013-02-27 08:32:07 -08001108 addl LITERAL(28), %esp // Pop arguments upto saved Method*.
1109 movl 28(%esp), %edi // Restore edi.
1110 movl %eax, 28(%esp) // Place code* over edi, just under return pc.
Mark Mendella9abe872014-01-10 05:52:01 -08001111 movl LITERAL(SYMBOL(art_quick_instrumentation_exit)@PLT), 32(%esp)
Ian Rogers62d6c772013-02-27 08:32:07 -08001112 // Place instrumentation exit as return pc.
1113 movl (%esp), %eax // Restore eax.
1114 movl 8(%esp), %ecx // Restore ecx.
1115 movl 12(%esp), %edx // Restore edx.
1116 movl 16(%esp), %ebx // Restore ebx.
1117 movl 20(%esp), %ebp // Restore ebp.
1118 movl 24(%esp), %esi // Restore esi.
1119 addl LITERAL(28), %esp // Wind stack back upto code*.
1120 ret // Call method (and pop).
Ian Rogers468532e2013-08-05 10:56:33 -07001121END_FUNCTION art_quick_instrumentation_entry
Ian Rogers62d6c772013-02-27 08:32:07 -08001122
Ian Rogers468532e2013-08-05 10:56:33 -07001123DEFINE_FUNCTION art_quick_instrumentation_exit
Ian Rogers62d6c772013-02-27 08:32:07 -08001124 pushl LITERAL(0) // Push a fake return PC as there will be none on the stack.
1125 SETUP_REF_ONLY_CALLEE_SAVE_FRAME
1126 mov %esp, %ecx // Remember SP
1127 subl LITERAL(8), %esp // Save float return value.
1128 .cfi_adjust_cfa_offset 8
1129 movd %xmm0, (%esp)
1130 PUSH edx // Save gpr return value.
1131 PUSH eax
1132 subl LITERAL(8), %esp // Align stack
1133 movd %xmm0, (%esp)
1134 subl LITERAL(8), %esp // Pass float return value.
1135 .cfi_adjust_cfa_offset 8
1136 movd %xmm0, (%esp)
1137 PUSH edx // Pass gpr return value.
1138 PUSH eax
1139 PUSH ecx // Pass SP.
1140 pushl %fs:THREAD_SELF_OFFSET // Pass Thread::Current.
Ian Rogersaeeada42013-02-13 11:28:34 -08001141 .cfi_adjust_cfa_offset 4
Mark Mendella9abe872014-01-10 05:52:01 -08001142 SETUP_GOT_NOSAVE // clobbers EBX
1143 call SYMBOL(artInstrumentationMethodExitFromCode)@PLT // (Thread*, SP, gpr_result, fpr_result)
Ian Rogers62d6c772013-02-27 08:32:07 -08001144 mov %eax, %ecx // Move returned link register.
1145 addl LITERAL(32), %esp // Pop arguments.
1146 .cfi_adjust_cfa_offset -32
1147 movl %edx, %ebx // Move returned link register for deopt
1148 // (ebx is pretending to be our LR).
1149 POP eax // Restore gpr return value.
1150 POP edx
1151 movd (%esp), %xmm0 // Restore fpr return value.
1152 addl LITERAL(8), %esp
Ian Rogers5793fea2013-02-14 13:33:34 -08001153 .cfi_adjust_cfa_offset -8
Ian Rogers62d6c772013-02-27 08:32:07 -08001154 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
1155 addl LITERAL(4), %esp // Remove fake return pc.
1156 jmp *%ecx // Return.
Ian Rogers468532e2013-08-05 10:56:33 -07001157END_FUNCTION art_quick_instrumentation_exit
jeffhao162fd332013-01-08 16:21:01 -08001158
jeffhao7e4fcb82013-01-10 18:11:08 -08001159 /*
Ian Rogers62d6c772013-02-27 08:32:07 -08001160 * Instrumentation has requested that we deoptimize into the interpreter. The deoptimization
1161 * will long jump to the upcall with a special exception of -1.
jeffhao7e4fcb82013-01-10 18:11:08 -08001162 */
Logan Chien8dbb7082013-01-25 20:31:17 +08001163DEFINE_FUNCTION art_quick_deoptimize
Ian Rogers62d6c772013-02-27 08:32:07 -08001164 pushl %ebx // Fake that we were called.
Jeff Haoc1fcdf12013-04-11 13:34:01 -07001165 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME
Ian Rogers62d6c772013-02-27 08:32:07 -08001166 mov %esp, %ecx // Remember SP.
1167 subl LITERAL(8), %esp // Align stack.
1168 .cfi_adjust_cfa_offset 8
1169 PUSH ecx // Pass SP.
1170 pushl %fs:THREAD_SELF_OFFSET // Pass Thread::Current().
Ian Rogersaeeada42013-02-13 11:28:34 -08001171 .cfi_adjust_cfa_offset 4
Mark Mendella9abe872014-01-10 05:52:01 -08001172 SETUP_GOT_NOSAVE // clobbers EBX
1173 call SYMBOL(artDeoptimize)@PLT // artDeoptimize(Thread*, SP)
Ian Rogers62d6c772013-02-27 08:32:07 -08001174 int3 // Unreachable.
Ian Rogersaeeada42013-02-13 11:28:34 -08001175END_FUNCTION art_quick_deoptimize
jeffhao162fd332013-01-08 16:21:01 -08001176
jeffhao86e46712012-08-08 17:30:59 -07001177 /*
1178 * String's indexOf.
1179 *
1180 * On entry:
1181 * eax: string object (known non-null)
1182 * ecx: char to match (known <= 0xFFFF)
1183 * edx: Starting offset in string data
1184 */
Logan Chien8dbb7082013-01-25 20:31:17 +08001185DEFINE_FUNCTION art_quick_indexof
Ian Rogersaeeada42013-02-13 11:28:34 -08001186 PUSH edi // push callee save reg
jeffhao86e46712012-08-08 17:30:59 -07001187 mov STRING_COUNT_OFFSET(%eax), %ebx
1188 mov STRING_VALUE_OFFSET(%eax), %edi
1189 mov STRING_OFFSET_OFFSET(%eax), %eax
1190 testl %edx, %edx // check if start < 0
1191 jl clamp_min
1192clamp_done:
1193 cmpl %ebx, %edx // check if start >= count
1194 jge not_found
1195 lea STRING_DATA_OFFSET(%edi, %eax, 2), %edi // build a pointer to the start of string data
1196 mov %edi, %eax // save a copy in eax to later compute result
1197 lea (%edi, %edx, 2), %edi // build pointer to start of data to compare
1198 subl %edx, %ebx // compute iteration count
1199 /*
1200 * At this point we have:
1201 * eax: original start of string data
1202 * ecx: char to compare
1203 * ebx: length to compare
1204 * edi: start of data to test
1205 */
1206 mov %eax, %edx
1207 mov %ecx, %eax // put char to match in %eax
1208 mov %ebx, %ecx // put length to compare in %ecx
1209 repne scasw // find %ax, starting at [%edi], up to length %ecx
1210 jne not_found
1211 subl %edx, %edi
1212 sar LITERAL(1), %edi
1213 decl %edi // index = ((curr_ptr - orig_ptr) / 2) - 1
1214 mov %edi, %eax
Ian Rogersaeeada42013-02-13 11:28:34 -08001215 POP edi // pop callee save reg
jeffhao86e46712012-08-08 17:30:59 -07001216 ret
1217 .balign 16
1218not_found:
1219 mov LITERAL(-1), %eax // return -1 (not found)
Ian Rogersaeeada42013-02-13 11:28:34 -08001220 POP edi // pop callee save reg
jeffhao86e46712012-08-08 17:30:59 -07001221 ret
1222clamp_min:
1223 xor %edx, %edx // clamp start to 0
1224 jmp clamp_done
Ian Rogersaeeada42013-02-13 11:28:34 -08001225END_FUNCTION art_quick_indexof
jeffhao86e46712012-08-08 17:30:59 -07001226
1227 /*
1228 * String's compareTo.
1229 *
1230 * On entry:
1231 * eax: this string object (known non-null)
1232 * ecx: comp string object (known non-null)
1233 */
Logan Chien8dbb7082013-01-25 20:31:17 +08001234DEFINE_FUNCTION art_quick_string_compareto
Ian Rogersaeeada42013-02-13 11:28:34 -08001235 PUSH esi // push callee save reg
1236 PUSH edi // push callee save reg
jeffhao86e46712012-08-08 17:30:59 -07001237 mov STRING_COUNT_OFFSET(%eax), %edx
1238 mov STRING_COUNT_OFFSET(%ecx), %ebx
1239 mov STRING_VALUE_OFFSET(%eax), %esi
1240 mov STRING_VALUE_OFFSET(%ecx), %edi
1241 mov STRING_OFFSET_OFFSET(%eax), %eax
1242 mov STRING_OFFSET_OFFSET(%ecx), %ecx
1243 /* Build pointers to the start of string data */
1244 lea STRING_DATA_OFFSET(%esi, %eax, 2), %esi
1245 lea STRING_DATA_OFFSET(%edi, %ecx, 2), %edi
1246 /* Calculate min length and count diff */
1247 mov %edx, %ecx
1248 mov %edx, %eax
1249 subl %ebx, %eax
1250 cmovg %ebx, %ecx
1251 /*
1252 * At this point we have:
1253 * eax: value to return if first part of strings are equal
1254 * ecx: minimum among the lengths of the two strings
1255 * esi: pointer to this string data
1256 * edi: pointer to comp string data
1257 */
1258 repe cmpsw // find nonmatching chars in [%esi] and [%edi], up to length %ecx
1259 jne not_equal
Ian Rogersaeeada42013-02-13 11:28:34 -08001260 POP edi // pop callee save reg
1261 POP esi // pop callee save reg
jeffhao86e46712012-08-08 17:30:59 -07001262 ret
1263 .balign 16
1264not_equal:
Ian Rogers1b09b092012-08-20 15:35:52 -07001265 movzwl -2(%esi), %eax // get last compared char from this string
1266 movzwl -2(%edi), %ecx // get last compared char from comp string
jeffhao86e46712012-08-08 17:30:59 -07001267 subl %ecx, %eax // return the difference
Ian Rogersaeeada42013-02-13 11:28:34 -08001268 POP edi // pop callee save reg
1269 POP esi // pop callee save reg
jeffhao86e46712012-08-08 17:30:59 -07001270 ret
Ian Rogersaeeada42013-02-13 11:28:34 -08001271END_FUNCTION art_quick_string_compareto
jeffhao86e46712012-08-08 17:30:59 -07001272
Elliott Hughes787ec202012-03-29 17:14:15 -07001273 // TODO: implement these!
Logan Chien8dbb7082013-01-25 20:31:17 +08001274UNIMPLEMENTED art_quick_memcmp16