xref: /aosp_15_r20/art/runtime/arch/x86/quick_entrypoints_x86.S (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker/*
2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2012 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker *
4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker *
8*795d594fSAndroid Build Coastguard Worker *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker *
10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker */
16*795d594fSAndroid Build Coastguard Worker
17*795d594fSAndroid Build Coastguard Worker#include "asm_support_x86.S"
18*795d594fSAndroid Build Coastguard Worker#include "interpreter/cfi_asm_support.h"
19*795d594fSAndroid Build Coastguard Worker
20*795d594fSAndroid Build Coastguard Worker#include "arch/quick_alloc_entrypoints.S"
21*795d594fSAndroid Build Coastguard Worker#include "arch/quick_field_entrypoints.S"
22*795d594fSAndroid Build Coastguard Worker
23*795d594fSAndroid Build Coastguard Worker// For x86, the CFA is esp+4, the address above the pushed return address on the stack.
24*795d594fSAndroid Build Coastguard Worker
25*795d594fSAndroid Build Coastguard Worker    /*
26*795d594fSAndroid Build Coastguard Worker     * Macro that sets up the callee save frame to conform with
27*795d594fSAndroid Build Coastguard Worker     * Runtime::CreateCalleeSaveMethod(kSaveRefsOnly)
28*795d594fSAndroid Build Coastguard Worker     * and preserves the value of temp_reg at entry.
29*795d594fSAndroid Build Coastguard Worker     */
30*795d594fSAndroid Build Coastguard WorkerMACRO1(SETUP_SAVE_REFS_ONLY_FRAME_PRESERVE_TEMP_REG, temp_reg)
31*795d594fSAndroid Build Coastguard Worker    PUSH edi  // Save callee saves (ebx is saved/restored by the upcall)
32*795d594fSAndroid Build Coastguard Worker    PUSH esi
33*795d594fSAndroid Build Coastguard Worker    PUSH ebp
34*795d594fSAndroid Build Coastguard Worker    PUSH RAW_VAR(temp_reg)  // Save temp_reg
35*795d594fSAndroid Build Coastguard Worker    INCREASE_FRAME 8             // Grow stack by 2 words.
36*795d594fSAndroid Build Coastguard Worker
37*795d594fSAndroid Build Coastguard Worker    LOAD_RUNTIME_INSTANCE \temp_reg
38*795d594fSAndroid Build Coastguard Worker    // Push save all callee-save method.
39*795d594fSAndroid Build Coastguard Worker    pushl RUNTIME_SAVE_REFS_ONLY_METHOD_OFFSET(REG_VAR(temp_reg))
40*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
41*795d594fSAndroid Build Coastguard Worker    // Store esp as the top quick frame.
42*795d594fSAndroid Build Coastguard Worker    movl %esp, %fs:THREAD_TOP_QUICK_FRAME_OFFSET
43*795d594fSAndroid Build Coastguard Worker    // Restore temp_reg.
44*795d594fSAndroid Build Coastguard Worker    movl 12(%esp), REG_VAR(temp_reg)
45*795d594fSAndroid Build Coastguard Worker    CFI_RESTORE(RAW_VAR(temp_reg))
46*795d594fSAndroid Build Coastguard Worker
47*795d594fSAndroid Build Coastguard Worker    // Ugly compile-time check, but we only have the preprocessor.
48*795d594fSAndroid Build Coastguard Worker    // Last +4: implicit return address pushed on stack when caller made call.
49*795d594fSAndroid Build Coastguard Worker#if (FRAME_SIZE_SAVE_REFS_ONLY != 3*4 + 16 + 4)
50*795d594fSAndroid Build Coastguard Worker#error "FRAME_SIZE_SAVE_REFS_ONLY(X86) size not as expected."
51*795d594fSAndroid Build Coastguard Worker#endif
52*795d594fSAndroid Build Coastguard WorkerEND_MACRO
53*795d594fSAndroid Build Coastguard Worker
54*795d594fSAndroid Build Coastguard Worker    /*
55*795d594fSAndroid Build Coastguard Worker     * Macro that sets up the callee save frame to conform with
56*795d594fSAndroid Build Coastguard Worker     * Runtime::CreateCalleeSaveMethod(kSaveRefsAndArgs)
57*795d594fSAndroid Build Coastguard Worker     */
58*795d594fSAndroid Build Coastguard WorkerMACRO1(SETUP_SAVE_REFS_AND_ARGS_FRAME, temp_reg)
59*795d594fSAndroid Build Coastguard Worker    SETUP_SAVE_REFS_AND_ARGS_FRAME_REGISTERS_ONLY
60*795d594fSAndroid Build Coastguard Worker
61*795d594fSAndroid Build Coastguard Worker    LOAD_RUNTIME_INSTANCE \temp_reg
62*795d594fSAndroid Build Coastguard Worker    // Push save all callee-save method.
63*795d594fSAndroid Build Coastguard Worker    pushl RUNTIME_SAVE_REFS_AND_ARGS_METHOD_OFFSET(REG_VAR(temp_reg))
64*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
65*795d594fSAndroid Build Coastguard Worker    // Store esp as the stop quick frame.
66*795d594fSAndroid Build Coastguard Worker    movl %esp, %fs:THREAD_TOP_QUICK_FRAME_OFFSET
67*795d594fSAndroid Build Coastguard WorkerEND_MACRO
68*795d594fSAndroid Build Coastguard Worker
69*795d594fSAndroid Build Coastguard Worker    /*
70*795d594fSAndroid Build Coastguard Worker     * Macro that sets up the callee save frame to conform with
71*795d594fSAndroid Build Coastguard Worker     * Runtime::CreateCalleeSaveMethod(kSaveRefsAndArgs) where the method is passed in EAX.
72*795d594fSAndroid Build Coastguard Worker     */
73*795d594fSAndroid Build Coastguard WorkerMACRO0(SETUP_SAVE_REFS_AND_ARGS_FRAME_WITH_METHOD_IN_EAX)
74*795d594fSAndroid Build Coastguard Worker    SETUP_SAVE_REFS_AND_ARGS_FRAME_REGISTERS_ONLY
75*795d594fSAndroid Build Coastguard Worker
76*795d594fSAndroid Build Coastguard Worker    pushl %eax  // Store the ArtMethod reference at the bottom of the stack.
77*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
78*795d594fSAndroid Build Coastguard Worker    // Store esp as the stop quick frame.
79*795d594fSAndroid Build Coastguard Worker    movl %esp, %fs:THREAD_TOP_QUICK_FRAME_OFFSET
80*795d594fSAndroid Build Coastguard WorkerEND_MACRO
81*795d594fSAndroid Build Coastguard Worker
82*795d594fSAndroid Build Coastguard Worker// Restore register and jump to routine
83*795d594fSAndroid Build Coastguard Worker// Inputs:  EDI contains pointer to code.
84*795d594fSAndroid Build Coastguard Worker// Notes: Need to pop EAX too (restores Method*)
85*795d594fSAndroid Build Coastguard WorkerMACRO0(RESTORE_SAVE_REFS_AND_ARGS_FRAME_AND_JUMP)
86*795d594fSAndroid Build Coastguard Worker    POP eax  // Restore Method*
87*795d594fSAndroid Build Coastguard Worker
88*795d594fSAndroid Build Coastguard Worker    // Restore FPRs.
89*795d594fSAndroid Build Coastguard Worker    movsd 0(%esp), %xmm0
90*795d594fSAndroid Build Coastguard Worker    movsd 8(%esp), %xmm1
91*795d594fSAndroid Build Coastguard Worker    movsd 16(%esp), %xmm2
92*795d594fSAndroid Build Coastguard Worker    movsd 24(%esp), %xmm3
93*795d594fSAndroid Build Coastguard Worker
94*795d594fSAndroid Build Coastguard Worker    DECREASE_FRAME 32             // Remove FPRs.
95*795d594fSAndroid Build Coastguard Worker
96*795d594fSAndroid Build Coastguard Worker    POP ecx  // Restore args except eax
97*795d594fSAndroid Build Coastguard Worker    POP edx
98*795d594fSAndroid Build Coastguard Worker    POP ebx
99*795d594fSAndroid Build Coastguard Worker    POP ebp  // Restore callee saves
100*795d594fSAndroid Build Coastguard Worker    POP esi
101*795d594fSAndroid Build Coastguard Worker    xchgl 0(%esp),%edi // restore EDI and place code pointer as only value on stack
102*795d594fSAndroid Build Coastguard Worker    ret
103*795d594fSAndroid Build Coastguard WorkerEND_MACRO
104*795d594fSAndroid Build Coastguard Worker
105*795d594fSAndroid Build Coastguard Worker    /*
106*795d594fSAndroid Build Coastguard Worker     * Macro that sets up the callee save frame to conform with
107*795d594fSAndroid Build Coastguard Worker     * Runtime::CreateCalleeSaveMethod(kSaveEverything)
108*795d594fSAndroid Build Coastguard Worker     * when EDI and ESI are already saved.
109*795d594fSAndroid Build Coastguard Worker     */
110*795d594fSAndroid Build Coastguard WorkerMACRO2(SETUP_SAVE_EVERYTHING_FRAME_EDI_ESI_SAVED, temp_reg, runtime_method_offset = RUNTIME_SAVE_EVERYTHING_METHOD_OFFSET)
111*795d594fSAndroid Build Coastguard Worker    // Save core registers from highest to lowest to agree with core spills bitmap.
112*795d594fSAndroid Build Coastguard Worker    // EDI and ESI, or at least placeholders for them, are already on the stack.
113*795d594fSAndroid Build Coastguard Worker    PUSH ebp
114*795d594fSAndroid Build Coastguard Worker    PUSH ebx
115*795d594fSAndroid Build Coastguard Worker    PUSH edx
116*795d594fSAndroid Build Coastguard Worker    PUSH ecx
117*795d594fSAndroid Build Coastguard Worker    PUSH eax
118*795d594fSAndroid Build Coastguard Worker    // Create space for FPR registers and stack alignment padding.
119*795d594fSAndroid Build Coastguard Worker    INCREASE_FRAME 12 + 8 * 8
120*795d594fSAndroid Build Coastguard Worker    // Save FPRs.
121*795d594fSAndroid Build Coastguard Worker    movsd %xmm0, 12(%esp)
122*795d594fSAndroid Build Coastguard Worker    movsd %xmm1, 20(%esp)
123*795d594fSAndroid Build Coastguard Worker    movsd %xmm2, 28(%esp)
124*795d594fSAndroid Build Coastguard Worker    movsd %xmm3, 36(%esp)
125*795d594fSAndroid Build Coastguard Worker    movsd %xmm4, 44(%esp)
126*795d594fSAndroid Build Coastguard Worker    movsd %xmm5, 52(%esp)
127*795d594fSAndroid Build Coastguard Worker    movsd %xmm6, 60(%esp)
128*795d594fSAndroid Build Coastguard Worker    movsd %xmm7, 68(%esp)
129*795d594fSAndroid Build Coastguard Worker
130*795d594fSAndroid Build Coastguard Worker    LOAD_RUNTIME_INSTANCE \temp_reg
131*795d594fSAndroid Build Coastguard Worker    // Push save everything callee-save method.
132*795d594fSAndroid Build Coastguard Worker    pushl \runtime_method_offset(REG_VAR(temp_reg))
133*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
134*795d594fSAndroid Build Coastguard Worker    // Store esp as the stop quick frame.
135*795d594fSAndroid Build Coastguard Worker    movl %esp, %fs:THREAD_TOP_QUICK_FRAME_OFFSET
136*795d594fSAndroid Build Coastguard Worker
137*795d594fSAndroid Build Coastguard Worker    // Ugly compile-time check, but we only have the preprocessor.
138*795d594fSAndroid Build Coastguard Worker    // Last +4: implicit return address pushed on stack when caller made call.
139*795d594fSAndroid Build Coastguard Worker#if (FRAME_SIZE_SAVE_EVERYTHING != 7*4 + 8*8 + 12 + 4 + 4)
140*795d594fSAndroid Build Coastguard Worker#error "FRAME_SIZE_SAVE_EVERYTHING(X86) size not as expected."
141*795d594fSAndroid Build Coastguard Worker#endif
142*795d594fSAndroid Build Coastguard WorkerEND_MACRO
143*795d594fSAndroid Build Coastguard Worker
144*795d594fSAndroid Build Coastguard Worker    /*
145*795d594fSAndroid Build Coastguard Worker     * Macro that sets up the callee save frame to conform with
146*795d594fSAndroid Build Coastguard Worker     * Runtime::CreateCalleeSaveMethod(kSaveEverything)
147*795d594fSAndroid Build Coastguard Worker     * when EDI is already saved.
148*795d594fSAndroid Build Coastguard Worker     */
149*795d594fSAndroid Build Coastguard WorkerMACRO2(SETUP_SAVE_EVERYTHING_FRAME_EDI_SAVED, temp_reg, runtime_method_offset = RUNTIME_SAVE_EVERYTHING_METHOD_OFFSET)
150*795d594fSAndroid Build Coastguard Worker    // Save core registers from highest to lowest to agree with core spills bitmap.
151*795d594fSAndroid Build Coastguard Worker    // EDI, or at least a placeholder for it, is already on the stack.
152*795d594fSAndroid Build Coastguard Worker    PUSH esi
153*795d594fSAndroid Build Coastguard Worker    SETUP_SAVE_EVERYTHING_FRAME_EDI_ESI_SAVED RAW_VAR(temp_reg), \runtime_method_offset
154*795d594fSAndroid Build Coastguard WorkerEND_MACRO
155*795d594fSAndroid Build Coastguard Worker
156*795d594fSAndroid Build Coastguard Worker    /*
157*795d594fSAndroid Build Coastguard Worker     * Macro that sets up the callee save frame to conform with
158*795d594fSAndroid Build Coastguard Worker     * Runtime::CreateCalleeSaveMethod(kSaveEverything)
159*795d594fSAndroid Build Coastguard Worker     */
160*795d594fSAndroid Build Coastguard WorkerMACRO2(SETUP_SAVE_EVERYTHING_FRAME, temp_reg, runtime_method_offset = RUNTIME_SAVE_EVERYTHING_METHOD_OFFSET)
161*795d594fSAndroid Build Coastguard Worker    PUSH edi
162*795d594fSAndroid Build Coastguard Worker    SETUP_SAVE_EVERYTHING_FRAME_EDI_SAVED RAW_VAR(temp_reg), \runtime_method_offset
163*795d594fSAndroid Build Coastguard WorkerEND_MACRO
164*795d594fSAndroid Build Coastguard Worker
165*795d594fSAndroid Build Coastguard WorkerMACRO0(RESTORE_SAVE_EVERYTHING_FRAME_FRPS)
166*795d594fSAndroid Build Coastguard Worker    // Restore FPRs. Method and padding is still on the stack.
167*795d594fSAndroid Build Coastguard Worker    movsd 16(%esp), %xmm0
168*795d594fSAndroid Build Coastguard Worker    movsd 24(%esp), %xmm1
169*795d594fSAndroid Build Coastguard Worker    movsd 32(%esp), %xmm2
170*795d594fSAndroid Build Coastguard Worker    movsd 40(%esp), %xmm3
171*795d594fSAndroid Build Coastguard Worker    movsd 48(%esp), %xmm4
172*795d594fSAndroid Build Coastguard Worker    movsd 56(%esp), %xmm5
173*795d594fSAndroid Build Coastguard Worker    movsd 64(%esp), %xmm6
174*795d594fSAndroid Build Coastguard Worker    movsd 72(%esp), %xmm7
175*795d594fSAndroid Build Coastguard WorkerEND_MACRO
176*795d594fSAndroid Build Coastguard Worker
177*795d594fSAndroid Build Coastguard WorkerMACRO0(RESTORE_SAVE_EVERYTHING_FRAME_GPRS_EXCEPT_EAX)
178*795d594fSAndroid Build Coastguard Worker    // Restore core registers (except eax).
179*795d594fSAndroid Build Coastguard Worker    POP ecx
180*795d594fSAndroid Build Coastguard Worker    POP edx
181*795d594fSAndroid Build Coastguard Worker    POP ebx
182*795d594fSAndroid Build Coastguard Worker    POP ebp
183*795d594fSAndroid Build Coastguard Worker    POP esi
184*795d594fSAndroid Build Coastguard Worker    POP edi
185*795d594fSAndroid Build Coastguard WorkerEND_MACRO
186*795d594fSAndroid Build Coastguard Worker
187*795d594fSAndroid Build Coastguard WorkerMACRO0(RESTORE_SAVE_EVERYTHING_FRAME)
188*795d594fSAndroid Build Coastguard Worker    RESTORE_SAVE_EVERYTHING_FRAME_FRPS
189*795d594fSAndroid Build Coastguard Worker
190*795d594fSAndroid Build Coastguard Worker    // Remove save everything callee save method, stack alignment padding and FPRs.
191*795d594fSAndroid Build Coastguard Worker    DECREASE_FRAME 16 + 8 * 8
192*795d594fSAndroid Build Coastguard Worker
193*795d594fSAndroid Build Coastguard Worker    POP eax
194*795d594fSAndroid Build Coastguard Worker    RESTORE_SAVE_EVERYTHING_FRAME_GPRS_EXCEPT_EAX
195*795d594fSAndroid Build Coastguard WorkerEND_MACRO
196*795d594fSAndroid Build Coastguard Worker
197*795d594fSAndroid Build Coastguard WorkerMACRO0(RESTORE_SAVE_EVERYTHING_FRAME_KEEP_EAX)
198*795d594fSAndroid Build Coastguard Worker    RESTORE_SAVE_EVERYTHING_FRAME_FRPS
199*795d594fSAndroid Build Coastguard Worker
200*795d594fSAndroid Build Coastguard Worker    // Remove save everything callee save method, stack alignment padding and FPRs, skip EAX.
201*795d594fSAndroid Build Coastguard Worker    DECREASE_FRAME 16 + 8 * 8 + 4
202*795d594fSAndroid Build Coastguard Worker
203*795d594fSAndroid Build Coastguard Worker    RESTORE_SAVE_EVERYTHING_FRAME_GPRS_EXCEPT_EAX
204*795d594fSAndroid Build Coastguard WorkerEND_MACRO
205*795d594fSAndroid Build Coastguard Worker
206*795d594fSAndroid Build Coastguard WorkerMACRO2(NO_ARG_RUNTIME_EXCEPTION, c_name, cxx_name)
207*795d594fSAndroid Build Coastguard Worker    DEFINE_FUNCTION VAR(c_name)
208*795d594fSAndroid Build Coastguard Worker    SETUP_SAVE_ALL_CALLEE_SAVES_FRAME ebx      // save all registers as basis for long jump context
209*795d594fSAndroid Build Coastguard Worker    // Outgoing argument set up
210*795d594fSAndroid Build Coastguard Worker    INCREASE_FRAME 12                          // alignment padding
211*795d594fSAndroid Build Coastguard Worker    pushl %fs:THREAD_SELF_OFFSET               // pass Thread::Current()
212*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
213*795d594fSAndroid Build Coastguard Worker    call CALLVAR(cxx_name)                     // cxx_name(Thread*)
214*795d594fSAndroid Build Coastguard Worker    call SYMBOL(art_quick_do_long_jump)
215*795d594fSAndroid Build Coastguard Worker    UNREACHABLE
216*795d594fSAndroid Build Coastguard Worker    END_FUNCTION VAR(c_name)
217*795d594fSAndroid Build Coastguard WorkerEND_MACRO
218*795d594fSAndroid Build Coastguard Worker
219*795d594fSAndroid Build Coastguard WorkerMACRO2(NO_ARG_RUNTIME_EXCEPTION_SAVE_EVERYTHING, c_name, cxx_name)
220*795d594fSAndroid Build Coastguard Worker    DEFINE_FUNCTION VAR(c_name)
221*795d594fSAndroid Build Coastguard Worker    SETUP_SAVE_EVERYTHING_FRAME ebx            // save all registers as basis for long jump context
222*795d594fSAndroid Build Coastguard Worker    // Outgoing argument set up
223*795d594fSAndroid Build Coastguard Worker    INCREASE_FRAME 12                          // alignment padding
224*795d594fSAndroid Build Coastguard Worker    pushl %fs:THREAD_SELF_OFFSET               // pass Thread::Current()
225*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
226*795d594fSAndroid Build Coastguard Worker    call CALLVAR(cxx_name)                     // cxx_name(Thread*)
227*795d594fSAndroid Build Coastguard Worker    call SYMBOL(art_quick_do_long_jump)
228*795d594fSAndroid Build Coastguard Worker    UNREACHABLE
229*795d594fSAndroid Build Coastguard Worker    END_FUNCTION VAR(c_name)
230*795d594fSAndroid Build Coastguard WorkerEND_MACRO
231*795d594fSAndroid Build Coastguard Worker
232*795d594fSAndroid Build Coastguard WorkerMACRO2(ONE_ARG_RUNTIME_EXCEPTION, c_name, cxx_name)
233*795d594fSAndroid Build Coastguard Worker    DEFINE_FUNCTION VAR(c_name)
234*795d594fSAndroid Build Coastguard Worker    SETUP_SAVE_ALL_CALLEE_SAVES_FRAME ebx      // save all registers as basis for long jump context
235*795d594fSAndroid Build Coastguard Worker    // Outgoing argument set up
236*795d594fSAndroid Build Coastguard Worker    INCREASE_FRAME 8                           // alignment padding
237*795d594fSAndroid Build Coastguard Worker    pushl %fs:THREAD_SELF_OFFSET               // pass Thread::Current()
238*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
239*795d594fSAndroid Build Coastguard Worker    PUSH eax                                   // pass arg1
240*795d594fSAndroid Build Coastguard Worker    call CALLVAR(cxx_name)                     // cxx_name(arg1, Thread*)
241*795d594fSAndroid Build Coastguard Worker    call SYMBOL(art_quick_do_long_jump)
242*795d594fSAndroid Build Coastguard Worker    UNREACHABLE
243*795d594fSAndroid Build Coastguard Worker    END_FUNCTION VAR(c_name)
244*795d594fSAndroid Build Coastguard WorkerEND_MACRO
245*795d594fSAndroid Build Coastguard Worker
246*795d594fSAndroid Build Coastguard WorkerMACRO2(TWO_ARG_RUNTIME_EXCEPTION_SAVE_EVERYTHING, c_name, cxx_name)
247*795d594fSAndroid Build Coastguard Worker    DEFINE_FUNCTION VAR(c_name)
248*795d594fSAndroid Build Coastguard Worker    SETUP_SAVE_EVERYTHING_FRAME ebx            // save all registers as basis for long jump context
249*795d594fSAndroid Build Coastguard Worker    // Outgoing argument set up
250*795d594fSAndroid Build Coastguard Worker    PUSH eax                                   // alignment padding
251*795d594fSAndroid Build Coastguard Worker    pushl %fs:THREAD_SELF_OFFSET               // pass Thread::Current()
252*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
253*795d594fSAndroid Build Coastguard Worker    PUSH ecx                                   // pass arg2
254*795d594fSAndroid Build Coastguard Worker    PUSH eax                                   // pass arg1
255*795d594fSAndroid Build Coastguard Worker    call CALLVAR(cxx_name)                     // cxx_name(arg1, arg2, Thread*)
256*795d594fSAndroid Build Coastguard Worker    call SYMBOL(art_quick_do_long_jump)
257*795d594fSAndroid Build Coastguard Worker    UNREACHABLE
258*795d594fSAndroid Build Coastguard Worker    END_FUNCTION VAR(c_name)
259*795d594fSAndroid Build Coastguard WorkerEND_MACRO
260*795d594fSAndroid Build Coastguard Worker
261*795d594fSAndroid Build Coastguard Worker    /*
262*795d594fSAndroid Build Coastguard Worker     * Called by managed code to create and deliver a NullPointerException.
263*795d594fSAndroid Build Coastguard Worker     */
264*795d594fSAndroid Build Coastguard WorkerNO_ARG_RUNTIME_EXCEPTION_SAVE_EVERYTHING art_quick_throw_null_pointer_exception, artThrowNullPointerExceptionFromCode
265*795d594fSAndroid Build Coastguard Worker
266*795d594fSAndroid Build Coastguard Worker    /*
267*795d594fSAndroid Build Coastguard Worker     * Call installed by a signal handler to create and deliver a NullPointerException.
268*795d594fSAndroid Build Coastguard Worker     */
269*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION_CUSTOM_CFA art_quick_throw_null_pointer_exception_from_signal, 2 * __SIZEOF_POINTER__
270*795d594fSAndroid Build Coastguard Worker    // Fault address and return address were saved by the fault handler.
271*795d594fSAndroid Build Coastguard Worker    // Save all registers as basis for long jump context; EDI will replace fault address later.
272*795d594fSAndroid Build Coastguard Worker    SETUP_SAVE_EVERYTHING_FRAME_EDI_SAVED ebx
273*795d594fSAndroid Build Coastguard Worker    // Retrieve fault address and save EDI.
274*795d594fSAndroid Build Coastguard Worker    movl (FRAME_SIZE_SAVE_EVERYTHING - 2 * __SIZEOF_POINTER__)(%esp), %eax
275*795d594fSAndroid Build Coastguard Worker    movl %edi, (FRAME_SIZE_SAVE_EVERYTHING - 2 * __SIZEOF_POINTER__)(%esp)
276*795d594fSAndroid Build Coastguard Worker    CFI_REL_OFFSET(%edi, (FRAME_SIZE_SAVE_EVERYTHING - 2 * __SIZEOF_POINTER__))
277*795d594fSAndroid Build Coastguard Worker    // Outgoing argument set up
278*795d594fSAndroid Build Coastguard Worker    INCREASE_FRAME 8                                      // alignment padding
279*795d594fSAndroid Build Coastguard Worker    pushl %fs:THREAD_SELF_OFFSET                          // pass Thread::Current()
280*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
281*795d594fSAndroid Build Coastguard Worker    PUSH eax                                              // pass arg1
282*795d594fSAndroid Build Coastguard Worker    call SYMBOL(artThrowNullPointerExceptionFromSignal)   // (addr, self)
283*795d594fSAndroid Build Coastguard Worker    call SYMBOL(art_quick_do_long_jump)
284*795d594fSAndroid Build Coastguard Worker    UNREACHABLE
285*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION art_quick_throw_null_pointer_exception_from_signal
286*795d594fSAndroid Build Coastguard Worker
287*795d594fSAndroid Build Coastguard Worker    /*
288*795d594fSAndroid Build Coastguard Worker     * Called by managed code to create and deliver an ArithmeticException.
289*795d594fSAndroid Build Coastguard Worker     */
290*795d594fSAndroid Build Coastguard WorkerNO_ARG_RUNTIME_EXCEPTION_SAVE_EVERYTHING art_quick_throw_div_zero, artThrowDivZeroFromCode
291*795d594fSAndroid Build Coastguard Worker
292*795d594fSAndroid Build Coastguard Worker    /*
293*795d594fSAndroid Build Coastguard Worker     * Called by managed code to create and deliver a StackOverflowError.
294*795d594fSAndroid Build Coastguard Worker     */
295*795d594fSAndroid Build Coastguard WorkerNO_ARG_RUNTIME_EXCEPTION art_quick_throw_stack_overflow, artThrowStackOverflowFromCode
296*795d594fSAndroid Build Coastguard Worker
297*795d594fSAndroid Build Coastguard Worker    /*
298*795d594fSAndroid Build Coastguard Worker     * Called by managed code, saves callee saves and then calls artThrowException
299*795d594fSAndroid Build Coastguard Worker     * that will place a mock Method* at the bottom of the stack. Arg1 holds the exception.
300*795d594fSAndroid Build Coastguard Worker     */
301*795d594fSAndroid Build Coastguard WorkerONE_ARG_RUNTIME_EXCEPTION art_quick_deliver_exception, artDeliverExceptionFromCode
302*795d594fSAndroid Build Coastguard Worker
303*795d594fSAndroid Build Coastguard Worker    /*
304*795d594fSAndroid Build Coastguard Worker     * Called by managed code to create and deliver an ArrayIndexOutOfBoundsException. Arg1 holds
305*795d594fSAndroid Build Coastguard Worker     * index, arg2 holds limit.
306*795d594fSAndroid Build Coastguard Worker     */
307*795d594fSAndroid Build Coastguard WorkerTWO_ARG_RUNTIME_EXCEPTION_SAVE_EVERYTHING art_quick_throw_array_bounds, artThrowArrayBoundsFromCode
308*795d594fSAndroid Build Coastguard Worker
309*795d594fSAndroid Build Coastguard Worker    /*
310*795d594fSAndroid Build Coastguard Worker     * Called by managed code to create and deliver a StringIndexOutOfBoundsException
311*795d594fSAndroid Build Coastguard Worker     * as if thrown from a call to String.charAt(). Arg1 holds index, arg2 holds limit.
312*795d594fSAndroid Build Coastguard Worker     */
313*795d594fSAndroid Build Coastguard WorkerTWO_ARG_RUNTIME_EXCEPTION_SAVE_EVERYTHING art_quick_throw_string_bounds, artThrowStringBoundsFromCode
314*795d594fSAndroid Build Coastguard Worker
315*795d594fSAndroid Build Coastguard Worker    /*
316*795d594fSAndroid Build Coastguard Worker     * All generated callsites for interface invokes and invocation slow paths will load arguments
317*795d594fSAndroid Build Coastguard Worker     * as usual - except instead of loading arg0/r0 with the target Method*, arg0/r0 will contain
318*795d594fSAndroid Build Coastguard Worker     * the method_idx.  This wrapper will save arg1-arg3 and call the appropriate C helper.
319*795d594fSAndroid Build Coastguard Worker     * NOTE: "this" is first visible argument of the target, and so can be found in arg1/r1.
320*795d594fSAndroid Build Coastguard Worker     *
321*795d594fSAndroid Build Coastguard Worker     * The helper will attempt to locate the target and return a 64-bit result in r0/r1 consisting
322*795d594fSAndroid Build Coastguard Worker     * of the target Method* in r0 and method->code_ in r1.
323*795d594fSAndroid Build Coastguard Worker     *
324*795d594fSAndroid Build Coastguard Worker     * If unsuccessful, the helper will return null/null and there will be a pending exception in the
325*795d594fSAndroid Build Coastguard Worker     * thread and we branch to another stub to deliver it.
326*795d594fSAndroid Build Coastguard Worker     *
327*795d594fSAndroid Build Coastguard Worker     * On success this wrapper will restore arguments and *jump* to the target, leaving the lr
328*795d594fSAndroid Build Coastguard Worker     * pointing back to the original caller.
329*795d594fSAndroid Build Coastguard Worker     */
330*795d594fSAndroid Build Coastguard WorkerMACRO1(INVOKE_TRAMPOLINE_BODY, cxx_name)
331*795d594fSAndroid Build Coastguard Worker    SETUP_SAVE_REFS_AND_ARGS_FRAME ebx
332*795d594fSAndroid Build Coastguard Worker    movl %esp, %edx  // remember SP
333*795d594fSAndroid Build Coastguard Worker
334*795d594fSAndroid Build Coastguard Worker    // Outgoing argument set up
335*795d594fSAndroid Build Coastguard Worker    PUSH edx                      // pass SP
336*795d594fSAndroid Build Coastguard Worker    pushl %fs:THREAD_SELF_OFFSET  // pass Thread::Current()
337*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
338*795d594fSAndroid Build Coastguard Worker    PUSH ecx                      // pass arg2
339*795d594fSAndroid Build Coastguard Worker    PUSH eax                      // pass arg1
340*795d594fSAndroid Build Coastguard Worker    call CALLVAR(cxx_name)        // cxx_name(arg1, arg2, Thread*, SP)
341*795d594fSAndroid Build Coastguard Worker    movl %edx, %edi               // save code pointer in EDI
342*795d594fSAndroid Build Coastguard Worker    DECREASE_FRAME 20             // Pop arguments skip eax
343*795d594fSAndroid Build Coastguard Worker
344*795d594fSAndroid Build Coastguard Worker    // Restore FPRs.
345*795d594fSAndroid Build Coastguard Worker    movsd 0(%esp), %xmm0
346*795d594fSAndroid Build Coastguard Worker    movsd 8(%esp), %xmm1
347*795d594fSAndroid Build Coastguard Worker    movsd 16(%esp), %xmm2
348*795d594fSAndroid Build Coastguard Worker    movsd 24(%esp), %xmm3
349*795d594fSAndroid Build Coastguard Worker
350*795d594fSAndroid Build Coastguard Worker    // Remove space for FPR args.
351*795d594fSAndroid Build Coastguard Worker    DECREASE_FRAME 4 * 8
352*795d594fSAndroid Build Coastguard Worker
353*795d594fSAndroid Build Coastguard Worker    POP ecx  // Restore args except eax
354*795d594fSAndroid Build Coastguard Worker    POP edx
355*795d594fSAndroid Build Coastguard Worker    POP ebx
356*795d594fSAndroid Build Coastguard Worker    POP ebp  // Restore callee saves
357*795d594fSAndroid Build Coastguard Worker    POP esi
358*795d594fSAndroid Build Coastguard Worker    // Swap EDI callee save with code pointer.
359*795d594fSAndroid Build Coastguard Worker    xchgl %edi, (%esp)
360*795d594fSAndroid Build Coastguard Worker    testl %eax, %eax              // Branch forward if exception pending.
361*795d594fSAndroid Build Coastguard Worker    jz    1f
362*795d594fSAndroid Build Coastguard Worker    // Tail call to intended method.
363*795d594fSAndroid Build Coastguard Worker    ret
364*795d594fSAndroid Build Coastguard Worker1:
365*795d594fSAndroid Build Coastguard Worker    DECREASE_FRAME 4              // Pop code pointer off stack
366*795d594fSAndroid Build Coastguard Worker    DELIVER_PENDING_EXCEPTION
367*795d594fSAndroid Build Coastguard WorkerEND_MACRO
368*795d594fSAndroid Build Coastguard WorkerMACRO2(INVOKE_TRAMPOLINE, c_name, cxx_name)
369*795d594fSAndroid Build Coastguard Worker    DEFINE_FUNCTION VAR(c_name)
370*795d594fSAndroid Build Coastguard Worker    INVOKE_TRAMPOLINE_BODY RAW_VAR(cxx_name)
371*795d594fSAndroid Build Coastguard Worker    END_FUNCTION VAR(c_name)
372*795d594fSAndroid Build Coastguard WorkerEND_MACRO
373*795d594fSAndroid Build Coastguard Worker
374*795d594fSAndroid Build Coastguard WorkerINVOKE_TRAMPOLINE art_quick_invoke_interface_trampoline_with_access_check, artInvokeInterfaceTrampolineWithAccessCheck
375*795d594fSAndroid Build Coastguard Worker
376*795d594fSAndroid Build Coastguard WorkerINVOKE_TRAMPOLINE art_quick_invoke_static_trampoline_with_access_check, artInvokeStaticTrampolineWithAccessCheck
377*795d594fSAndroid Build Coastguard WorkerINVOKE_TRAMPOLINE art_quick_invoke_direct_trampoline_with_access_check, artInvokeDirectTrampolineWithAccessCheck
378*795d594fSAndroid Build Coastguard WorkerINVOKE_TRAMPOLINE art_quick_invoke_super_trampoline_with_access_check, artInvokeSuperTrampolineWithAccessCheck
379*795d594fSAndroid Build Coastguard WorkerINVOKE_TRAMPOLINE art_quick_invoke_virtual_trampoline_with_access_check, artInvokeVirtualTrampolineWithAccessCheck
380*795d594fSAndroid Build Coastguard Worker
381*795d594fSAndroid Build Coastguard Worker    /*
382*795d594fSAndroid Build Coastguard Worker     * Helper for quick invocation stub to set up XMM registers.
383*795d594fSAndroid Build Coastguard Worker     * Increments shorty and arg_array and clobbers temp_char.
384*795d594fSAndroid Build Coastguard Worker     * Branches to finished if it encounters the end of the shorty.
385*795d594fSAndroid Build Coastguard Worker     */
386*795d594fSAndroid Build Coastguard WorkerMACRO5(LOOP_OVER_SHORTY_LOADING_XMMS, xmm_reg, shorty, arg_array, temp_char, finished)
387*795d594fSAndroid Build Coastguard Worker1: // LOOP
388*795d594fSAndroid Build Coastguard Worker    movb (REG_VAR(shorty)), REG_VAR(temp_char)     // temp_char := *shorty
389*795d594fSAndroid Build Coastguard Worker    addl MACRO_LITERAL(1), REG_VAR(shorty)         // shorty++
390*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(0), REG_VAR(temp_char)      // if (temp_char == '\0')
391*795d594fSAndroid Build Coastguard Worker    je VAR(finished)                               //   goto finished
392*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(68), REG_VAR(temp_char)     // if (temp_char == 'D')
393*795d594fSAndroid Build Coastguard Worker    je 2f                                          //   goto FOUND_DOUBLE
394*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(70), REG_VAR(temp_char)     // if (temp_char == 'F')
395*795d594fSAndroid Build Coastguard Worker    je 3f                                          //   goto FOUND_FLOAT
396*795d594fSAndroid Build Coastguard Worker    addl MACRO_LITERAL(4), REG_VAR(arg_array)      // arg_array++
397*795d594fSAndroid Build Coastguard Worker    //  Handle extra space in arg array taken by a long.
398*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(74), REG_VAR(temp_char)     // if (temp_char != 'J')
399*795d594fSAndroid Build Coastguard Worker    jne 1b                                         //   goto LOOP
400*795d594fSAndroid Build Coastguard Worker    addl MACRO_LITERAL(4), REG_VAR(arg_array)      // arg_array++
401*795d594fSAndroid Build Coastguard Worker    jmp 1b                                         // goto LOOP
402*795d594fSAndroid Build Coastguard Worker2:  // FOUND_DOUBLE
403*795d594fSAndroid Build Coastguard Worker    movsd (REG_VAR(arg_array)), REG_VAR(xmm_reg)
404*795d594fSAndroid Build Coastguard Worker    addl MACRO_LITERAL(8), REG_VAR(arg_array)      // arg_array+=2
405*795d594fSAndroid Build Coastguard Worker    jmp 4f
406*795d594fSAndroid Build Coastguard Worker3:  // FOUND_FLOAT
407*795d594fSAndroid Build Coastguard Worker    movss (REG_VAR(arg_array)), REG_VAR(xmm_reg)
408*795d594fSAndroid Build Coastguard Worker    addl MACRO_LITERAL(4), REG_VAR(arg_array)      // arg_array++
409*795d594fSAndroid Build Coastguard Worker4:
410*795d594fSAndroid Build Coastguard WorkerEND_MACRO
411*795d594fSAndroid Build Coastguard Worker
412*795d594fSAndroid Build Coastguard Worker    /*
413*795d594fSAndroid Build Coastguard Worker     * Helper for quick invocation stub to set up GPR registers.
414*795d594fSAndroid Build Coastguard Worker     * Increments shorty and arg_array, and returns the current short character in
415*795d594fSAndroid Build Coastguard Worker     * temp_char. Branches to finished if it encounters the end of the shorty.
416*795d594fSAndroid Build Coastguard Worker     */
417*795d594fSAndroid Build Coastguard WorkerMACRO4(SKIP_OVER_FLOATS, shorty, arg_array, temp_char, finished)
418*795d594fSAndroid Build Coastguard Worker1: // LOOP:
419*795d594fSAndroid Build Coastguard Worker    movb (REG_VAR(shorty)), REG_VAR(temp_char)     // temp_char := *shorty
420*795d594fSAndroid Build Coastguard Worker    addl MACRO_LITERAL(1), REG_VAR(shorty)         // shorty++
421*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(0), REG_VAR(temp_char)      // if (temp_char == '\0')
422*795d594fSAndroid Build Coastguard Worker    je VAR(finished)                               //   goto finished
423*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(70), REG_VAR(temp_char)     // if (temp_char == 'F')
424*795d594fSAndroid Build Coastguard Worker    je 3f                                          //   goto SKIP_FLOAT
425*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(68), REG_VAR(temp_char)     // if (temp_char == 'D')
426*795d594fSAndroid Build Coastguard Worker    je 4f                                          //   goto SKIP_DOUBLE
427*795d594fSAndroid Build Coastguard Worker    jmp 5f                                         // goto end
428*795d594fSAndroid Build Coastguard Worker3:  // SKIP_FLOAT
429*795d594fSAndroid Build Coastguard Worker    addl MACRO_LITERAL(4), REG_VAR(arg_array)      // arg_array++
430*795d594fSAndroid Build Coastguard Worker    jmp 1b                                         // goto LOOP
431*795d594fSAndroid Build Coastguard Worker4:  // SKIP_DOUBLE
432*795d594fSAndroid Build Coastguard Worker    addl MACRO_LITERAL(8), REG_VAR(arg_array)      // arg_array+=2
433*795d594fSAndroid Build Coastguard Worker    jmp 1b                                         // goto LOOP
434*795d594fSAndroid Build Coastguard Worker5:
435*795d594fSAndroid Build Coastguard WorkerEND_MACRO
436*795d594fSAndroid Build Coastguard Worker
437*795d594fSAndroid Build Coastguard Worker  /*
438*795d594fSAndroid Build Coastguard Worker     * Quick invocation stub (non-static).
439*795d594fSAndroid Build Coastguard Worker     * On entry:
440*795d594fSAndroid Build Coastguard Worker     *   [sp] = return address
441*795d594fSAndroid Build Coastguard Worker     *   [sp + 4] = method pointer
442*795d594fSAndroid Build Coastguard Worker     *   [sp + 8] = argument array or null for no argument methods
443*795d594fSAndroid Build Coastguard Worker     *   [sp + 12] = size of argument array in bytes
444*795d594fSAndroid Build Coastguard Worker     *   [sp + 16] = (managed) thread pointer
445*795d594fSAndroid Build Coastguard Worker     *   [sp + 20] = JValue* result
446*795d594fSAndroid Build Coastguard Worker     *   [sp + 24] = shorty
447*795d594fSAndroid Build Coastguard Worker     */
448*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION art_quick_invoke_stub
449*795d594fSAndroid Build Coastguard Worker    // Save the non-volatiles.
450*795d594fSAndroid Build Coastguard Worker    PUSH ebp                      // save ebp
451*795d594fSAndroid Build Coastguard Worker    PUSH ebx                      // save ebx
452*795d594fSAndroid Build Coastguard Worker    PUSH esi                      // save esi
453*795d594fSAndroid Build Coastguard Worker    PUSH edi                      // save edi
454*795d594fSAndroid Build Coastguard Worker    // Set up argument XMM registers.
455*795d594fSAndroid Build Coastguard Worker    mov 24+16(%esp), %esi         // ESI := shorty + 1  ; ie skip return arg character.
456*795d594fSAndroid Build Coastguard Worker    addl LITERAL(1), %esi
457*795d594fSAndroid Build Coastguard Worker    mov 8+16(%esp), %edi          // EDI := arg_array + 4 ; ie skip this pointer.
458*795d594fSAndroid Build Coastguard Worker    addl LITERAL(4), %edi
459*795d594fSAndroid Build Coastguard Worker    // Clobbers ESI, EDI, EAX.
460*795d594fSAndroid Build Coastguard Worker    LOOP_OVER_SHORTY_LOADING_XMMS xmm0, esi, edi, al, .Lxmm_setup_finished
461*795d594fSAndroid Build Coastguard Worker    LOOP_OVER_SHORTY_LOADING_XMMS xmm1, esi, edi, al, .Lxmm_setup_finished
462*795d594fSAndroid Build Coastguard Worker    LOOP_OVER_SHORTY_LOADING_XMMS xmm2, esi, edi, al, .Lxmm_setup_finished
463*795d594fSAndroid Build Coastguard Worker    LOOP_OVER_SHORTY_LOADING_XMMS xmm3, esi, edi, al, .Lxmm_setup_finished
464*795d594fSAndroid Build Coastguard Worker    .balign 16
465*795d594fSAndroid Build Coastguard Worker.Lxmm_setup_finished:
466*795d594fSAndroid Build Coastguard Worker    mov %esp, %ebp                // copy value of stack pointer into base pointer
467*795d594fSAndroid Build Coastguard Worker    CFI_DEF_CFA_REGISTER(ebp)
468*795d594fSAndroid Build Coastguard Worker    mov 28(%ebp), %ebx            // get arg array size
469*795d594fSAndroid Build Coastguard Worker    // reserve space for return addr, method*, ebx, ebp, esi, and edi in frame
470*795d594fSAndroid Build Coastguard Worker    addl LITERAL(36), %ebx
471*795d594fSAndroid Build Coastguard Worker    // align frame size to 16 bytes
472*795d594fSAndroid Build Coastguard Worker    andl LITERAL(0xFFFFFFF0), %ebx
473*795d594fSAndroid Build Coastguard Worker    subl LITERAL(20), %ebx        // remove space for return address, ebx, ebp, esi and edi
474*795d594fSAndroid Build Coastguard Worker    subl %ebx, %esp               // reserve stack space for argument array
475*795d594fSAndroid Build Coastguard Worker
476*795d594fSAndroid Build Coastguard Worker    movl LITERAL(0), (%esp)       // store null for method*
477*795d594fSAndroid Build Coastguard Worker
478*795d594fSAndroid Build Coastguard Worker    // Copy arg array into stack.
479*795d594fSAndroid Build Coastguard Worker    movl 28(%ebp), %ecx           // ECX = size of args
480*795d594fSAndroid Build Coastguard Worker    movl 24(%ebp), %esi           // ESI = argument array
481*795d594fSAndroid Build Coastguard Worker    leal 4(%esp), %edi            // EDI = just after Method* in stack arguments
482*795d594fSAndroid Build Coastguard Worker    rep movsb                     // while (ecx--) { *edi++ = *esi++ }
483*795d594fSAndroid Build Coastguard Worker
484*795d594fSAndroid Build Coastguard Worker    mov 40(%ebp), %esi            // ESI := shorty + 1  ; ie skip return arg character.
485*795d594fSAndroid Build Coastguard Worker    addl LITERAL(1), %esi
486*795d594fSAndroid Build Coastguard Worker    mov 24(%ebp), %edi            // EDI := arg_array
487*795d594fSAndroid Build Coastguard Worker    mov 0(%edi), %ecx             // ECX := this pointer
488*795d594fSAndroid Build Coastguard Worker    addl LITERAL(4), %edi         // EDI := arg_array + 4 ; ie skip this pointer.
489*795d594fSAndroid Build Coastguard Worker
490*795d594fSAndroid Build Coastguard Worker    // Enumerate the possible cases for loading GPRS.
491*795d594fSAndroid Build Coastguard Worker    // edx (and maybe ebx):
492*795d594fSAndroid Build Coastguard Worker    SKIP_OVER_FLOATS esi, edi, al, .Lgpr_setup_finished
493*795d594fSAndroid Build Coastguard Worker    cmpb LITERAL(74), %al         // if (al == 'J') goto FOUND_LONG
494*795d594fSAndroid Build Coastguard Worker    je .LfirstLong
495*795d594fSAndroid Build Coastguard Worker    // Must be an integer value.
496*795d594fSAndroid Build Coastguard Worker    movl (%edi), %edx
497*795d594fSAndroid Build Coastguard Worker    addl LITERAL(4), %edi         // arg_array++
498*795d594fSAndroid Build Coastguard Worker
499*795d594fSAndroid Build Coastguard Worker    // Now check ebx
500*795d594fSAndroid Build Coastguard Worker    SKIP_OVER_FLOATS esi, edi, al, .Lgpr_setup_finished
501*795d594fSAndroid Build Coastguard Worker    // Must be first word of a long, or an integer. First word of long doesn't
502*795d594fSAndroid Build Coastguard Worker    // go into EBX, but can be loaded there anyways, as it is harmless.
503*795d594fSAndroid Build Coastguard Worker    movl (%edi), %ebx
504*795d594fSAndroid Build Coastguard Worker    jmp .Lgpr_setup_finished
505*795d594fSAndroid Build Coastguard Worker.LfirstLong:
506*795d594fSAndroid Build Coastguard Worker    movl (%edi), %edx
507*795d594fSAndroid Build Coastguard Worker    movl 4(%edi), %ebx
508*795d594fSAndroid Build Coastguard Worker    // Nothing left to load.
509*795d594fSAndroid Build Coastguard Worker.Lgpr_setup_finished:
510*795d594fSAndroid Build Coastguard Worker    mov 20(%ebp), %eax            // move method pointer into eax
511*795d594fSAndroid Build Coastguard Worker    call *ART_METHOD_QUICK_CODE_OFFSET_32(%eax) // call the method
512*795d594fSAndroid Build Coastguard Worker    mov %ebp, %esp                // restore stack pointer
513*795d594fSAndroid Build Coastguard Worker    CFI_DEF_CFA_REGISTER(esp)
514*795d594fSAndroid Build Coastguard Worker    POP edi                       // pop edi
515*795d594fSAndroid Build Coastguard Worker    POP esi                       // pop esi
516*795d594fSAndroid Build Coastguard Worker    POP ebx                       // pop ebx
517*795d594fSAndroid Build Coastguard Worker    POP ebp                       // pop ebp
518*795d594fSAndroid Build Coastguard Worker    mov 20(%esp), %ecx            // get result pointer
519*795d594fSAndroid Build Coastguard Worker    mov %eax, (%ecx)              // store the result assuming its a long, int or Object*
520*795d594fSAndroid Build Coastguard Worker    mov %edx, 4(%ecx)             // store the other half of the result
521*795d594fSAndroid Build Coastguard Worker    mov 24(%esp), %edx            // get the shorty
522*795d594fSAndroid Build Coastguard Worker    cmpb LITERAL(68), (%edx)      // test if result type char == 'D'
523*795d594fSAndroid Build Coastguard Worker    je .Lreturn_double_quick
524*795d594fSAndroid Build Coastguard Worker    cmpb LITERAL(70), (%edx)      // test if result type char == 'F'
525*795d594fSAndroid Build Coastguard Worker    je .Lreturn_float_quick
526*795d594fSAndroid Build Coastguard Worker    ret
527*795d594fSAndroid Build Coastguard Worker.Lreturn_double_quick:
528*795d594fSAndroid Build Coastguard Worker    movsd %xmm0, (%ecx)           // store the floating point result
529*795d594fSAndroid Build Coastguard Worker    ret
530*795d594fSAndroid Build Coastguard Worker.Lreturn_float_quick:
531*795d594fSAndroid Build Coastguard Worker    movss %xmm0, (%ecx)           // store the floating point result
532*795d594fSAndroid Build Coastguard Worker    ret
533*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION art_quick_invoke_stub
534*795d594fSAndroid Build Coastguard Worker
535*795d594fSAndroid Build Coastguard Worker  /*
536*795d594fSAndroid Build Coastguard Worker     * Quick invocation stub (static).
537*795d594fSAndroid Build Coastguard Worker     * On entry:
538*795d594fSAndroid Build Coastguard Worker     *   [sp] = return address
539*795d594fSAndroid Build Coastguard Worker     *   [sp + 4] = method pointer
540*795d594fSAndroid Build Coastguard Worker     *   [sp + 8] = argument array or null for no argument methods
541*795d594fSAndroid Build Coastguard Worker     *   [sp + 12] = size of argument array in bytes
542*795d594fSAndroid Build Coastguard Worker     *   [sp + 16] = (managed) thread pointer
543*795d594fSAndroid Build Coastguard Worker     *   [sp + 20] = JValue* result
544*795d594fSAndroid Build Coastguard Worker     *   [sp + 24] = shorty
545*795d594fSAndroid Build Coastguard Worker     */
546*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION art_quick_invoke_static_stub
547*795d594fSAndroid Build Coastguard Worker    // Save the non-volatiles.
548*795d594fSAndroid Build Coastguard Worker    PUSH ebp                      // save ebp
549*795d594fSAndroid Build Coastguard Worker    PUSH ebx                      // save ebx
550*795d594fSAndroid Build Coastguard Worker    PUSH esi                      // save esi
551*795d594fSAndroid Build Coastguard Worker    PUSH edi                      // save edi
552*795d594fSAndroid Build Coastguard Worker    // Set up argument XMM registers.
553*795d594fSAndroid Build Coastguard Worker    mov 24+16(%esp), %esi         // ESI := shorty + 1  ; ie skip return arg character.
554*795d594fSAndroid Build Coastguard Worker    addl LITERAL(1), %esi
555*795d594fSAndroid Build Coastguard Worker    mov 8+16(%esp), %edi          // EDI := arg_array
556*795d594fSAndroid Build Coastguard Worker    // Clobbers ESI, EDI, EAX.
557*795d594fSAndroid Build Coastguard Worker    LOOP_OVER_SHORTY_LOADING_XMMS xmm0, esi, edi, al, .Lxmm_setup_finished2
558*795d594fSAndroid Build Coastguard Worker    LOOP_OVER_SHORTY_LOADING_XMMS xmm1, esi, edi, al, .Lxmm_setup_finished2
559*795d594fSAndroid Build Coastguard Worker    LOOP_OVER_SHORTY_LOADING_XMMS xmm2, esi, edi, al, .Lxmm_setup_finished2
560*795d594fSAndroid Build Coastguard Worker    LOOP_OVER_SHORTY_LOADING_XMMS xmm3, esi, edi, al, .Lxmm_setup_finished2
561*795d594fSAndroid Build Coastguard Worker    .balign 16
562*795d594fSAndroid Build Coastguard Worker.Lxmm_setup_finished2:
563*795d594fSAndroid Build Coastguard Worker    mov %esp, %ebp                // copy value of stack pointer into base pointer
564*795d594fSAndroid Build Coastguard Worker    CFI_DEF_CFA_REGISTER(ebp)
565*795d594fSAndroid Build Coastguard Worker    mov 28(%ebp), %ebx            // get arg array size
566*795d594fSAndroid Build Coastguard Worker    // reserve space for return addr, method*, ebx, ebp, esi, and edi in frame
567*795d594fSAndroid Build Coastguard Worker    addl LITERAL(36), %ebx
568*795d594fSAndroid Build Coastguard Worker    // align frame size to 16 bytes
569*795d594fSAndroid Build Coastguard Worker    andl LITERAL(0xFFFFFFF0), %ebx
570*795d594fSAndroid Build Coastguard Worker    subl LITERAL(20), %ebx        // remove space for return address, ebx, ebp, esi and edi
571*795d594fSAndroid Build Coastguard Worker    subl %ebx, %esp               // reserve stack space for argument array
572*795d594fSAndroid Build Coastguard Worker
573*795d594fSAndroid Build Coastguard Worker    movl LITERAL(0), (%esp)       // store null for method*
574*795d594fSAndroid Build Coastguard Worker
575*795d594fSAndroid Build Coastguard Worker    // Copy arg array into stack.
576*795d594fSAndroid Build Coastguard Worker    movl 28(%ebp), %ecx           // ECX = size of args
577*795d594fSAndroid Build Coastguard Worker    movl 24(%ebp), %esi           // ESI = argument array
578*795d594fSAndroid Build Coastguard Worker    leal 4(%esp), %edi            // EDI = just after Method* in stack arguments
579*795d594fSAndroid Build Coastguard Worker    rep movsb                     // while (ecx--) { *edi++ = *esi++ }
580*795d594fSAndroid Build Coastguard Worker
581*795d594fSAndroid Build Coastguard Worker    mov 40(%ebp), %esi            // ESI := shorty + 1  ; ie skip return arg character.
582*795d594fSAndroid Build Coastguard Worker    addl LITERAL(1), %esi
583*795d594fSAndroid Build Coastguard Worker    mov 24(%ebp), %edi            // EDI := arg_array
584*795d594fSAndroid Build Coastguard Worker
585*795d594fSAndroid Build Coastguard Worker    // Enumerate the possible cases for loading GPRS.
586*795d594fSAndroid Build Coastguard Worker    // ecx (and maybe edx)
587*795d594fSAndroid Build Coastguard Worker    SKIP_OVER_FLOATS esi, edi, al, .Lgpr_setup_finished2
588*795d594fSAndroid Build Coastguard Worker    cmpb LITERAL(74), %al         // if (al == 'J') goto FOUND_LONG
589*795d594fSAndroid Build Coastguard Worker    je .LfirstLong2
590*795d594fSAndroid Build Coastguard Worker    // Must be an integer value.  Load into ECX.
591*795d594fSAndroid Build Coastguard Worker    movl (%edi), %ecx
592*795d594fSAndroid Build Coastguard Worker    addl LITERAL(4), %edi         // arg_array++
593*795d594fSAndroid Build Coastguard Worker
594*795d594fSAndroid Build Coastguard Worker    // Now check edx (and maybe ebx).
595*795d594fSAndroid Build Coastguard Worker    SKIP_OVER_FLOATS esi, edi, al, .Lgpr_setup_finished2
596*795d594fSAndroid Build Coastguard Worker    cmpb LITERAL(74), %al         // if (al == 'J') goto FOUND_LONG
597*795d594fSAndroid Build Coastguard Worker    je .LSecondLong2
598*795d594fSAndroid Build Coastguard Worker    // Must be an integer.  Load into EDX.
599*795d594fSAndroid Build Coastguard Worker    movl (%edi), %edx
600*795d594fSAndroid Build Coastguard Worker    addl LITERAL(4), %edi         // arg_array++
601*795d594fSAndroid Build Coastguard Worker
602*795d594fSAndroid Build Coastguard Worker    // Is there anything for ebx?
603*795d594fSAndroid Build Coastguard Worker    SKIP_OVER_FLOATS esi, edi, al, .Lgpr_setup_finished2
604*795d594fSAndroid Build Coastguard Worker    // Must be first word of a long, or an integer. First word of long doesn't
605*795d594fSAndroid Build Coastguard Worker    // go into EBX, but can be loaded there anyways, as it is harmless.
606*795d594fSAndroid Build Coastguard Worker    movl (%edi), %ebx
607*795d594fSAndroid Build Coastguard Worker    jmp .Lgpr_setup_finished2
608*795d594fSAndroid Build Coastguard Worker.LSecondLong2:
609*795d594fSAndroid Build Coastguard Worker    // EDX:EBX is long.  That is all.
610*795d594fSAndroid Build Coastguard Worker    movl (%edi), %edx
611*795d594fSAndroid Build Coastguard Worker    movl 4(%edi), %ebx
612*795d594fSAndroid Build Coastguard Worker    jmp .Lgpr_setup_finished2
613*795d594fSAndroid Build Coastguard Worker.LfirstLong2:
614*795d594fSAndroid Build Coastguard Worker    // ECX:EDX is a long
615*795d594fSAndroid Build Coastguard Worker    movl (%edi), %ecx
616*795d594fSAndroid Build Coastguard Worker    movl 4(%edi), %edx
617*795d594fSAndroid Build Coastguard Worker    addl LITERAL(8), %edi         // arg_array += 2
618*795d594fSAndroid Build Coastguard Worker
619*795d594fSAndroid Build Coastguard Worker    // Anything for EBX?
620*795d594fSAndroid Build Coastguard Worker    SKIP_OVER_FLOATS esi, edi, al, .Lgpr_setup_finished2
621*795d594fSAndroid Build Coastguard Worker    // Must be first word of a long, or an integer. First word of long doesn't
622*795d594fSAndroid Build Coastguard Worker    // go into EBX, but can be loaded there anyways, as it is harmless.
623*795d594fSAndroid Build Coastguard Worker    movl (%edi), %ebx
624*795d594fSAndroid Build Coastguard Worker    jmp .Lgpr_setup_finished2
625*795d594fSAndroid Build Coastguard Worker    // Nothing left to load.
626*795d594fSAndroid Build Coastguard Worker.Lgpr_setup_finished2:
627*795d594fSAndroid Build Coastguard Worker    mov 20(%ebp), %eax            // move method pointer into eax
628*795d594fSAndroid Build Coastguard Worker    call *ART_METHOD_QUICK_CODE_OFFSET_32(%eax) // call the method
629*795d594fSAndroid Build Coastguard Worker    mov %ebp, %esp                // restore stack pointer
630*795d594fSAndroid Build Coastguard Worker    CFI_DEF_CFA_REGISTER(esp)
631*795d594fSAndroid Build Coastguard Worker    POP edi                       // pop edi
632*795d594fSAndroid Build Coastguard Worker    POP esi                       // pop esi
633*795d594fSAndroid Build Coastguard Worker    POP ebx                       // pop ebx
634*795d594fSAndroid Build Coastguard Worker    POP ebp                       // pop ebp
635*795d594fSAndroid Build Coastguard Worker    mov 20(%esp), %ecx            // get result pointer
636*795d594fSAndroid Build Coastguard Worker    mov %eax, (%ecx)              // store the result assuming its a long, int or Object*
637*795d594fSAndroid Build Coastguard Worker    mov %edx, 4(%ecx)             // store the other half of the result
638*795d594fSAndroid Build Coastguard Worker    mov 24(%esp), %edx            // get the shorty
639*795d594fSAndroid Build Coastguard Worker    cmpb LITERAL(68), (%edx)      // test if result type char == 'D'
640*795d594fSAndroid Build Coastguard Worker    je .Lreturn_double_quick2
641*795d594fSAndroid Build Coastguard Worker    cmpb LITERAL(70), (%edx)      // test if result type char == 'F'
642*795d594fSAndroid Build Coastguard Worker    je .Lreturn_float_quick2
643*795d594fSAndroid Build Coastguard Worker    ret
644*795d594fSAndroid Build Coastguard Worker.Lreturn_double_quick2:
645*795d594fSAndroid Build Coastguard Worker    movsd %xmm0, (%ecx)           // store the floating point result
646*795d594fSAndroid Build Coastguard Worker    ret
647*795d594fSAndroid Build Coastguard Worker.Lreturn_float_quick2:
648*795d594fSAndroid Build Coastguard Worker    movss %xmm0, (%ecx)           // store the floating point result
649*795d594fSAndroid Build Coastguard Worker    ret
650*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION art_quick_invoke_static_stub
651*795d594fSAndroid Build Coastguard Worker
652*795d594fSAndroid Build Coastguard Worker    /*
653*795d594fSAndroid Build Coastguard Worker     * Long jump stub.
654*795d594fSAndroid Build Coastguard Worker     * Custom calling convention: On entry EAX is the long jump context. This is expected to
655*795d594fSAndroid Build Coastguard Worker     * be returned from a previous entrypoint call which threw an exception or deoptimized.
656*795d594fSAndroid Build Coastguard Worker     */
657*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION art_quick_do_long_jump
658*795d594fSAndroid Build Coastguard Worker#if defined(__APPLE__)
659*795d594fSAndroid Build Coastguard Worker    int3
660*795d594fSAndroid Build Coastguard Worker    int3
661*795d594fSAndroid Build Coastguard Worker#else
662*795d594fSAndroid Build Coastguard Worker    // Reserve space for the gprs + fprs; add 16-byte stack alignment padding for call.
663*795d594fSAndroid Build Coastguard Worker    // (Note that the return address plus 3 args below shall take exactly 16 bytes.)
664*795d594fSAndroid Build Coastguard Worker    INCREASE_FRAME (X86_LONG_JUMP_CONTEXT_SIZE + 15) & ~15
665*795d594fSAndroid Build Coastguard Worker
666*795d594fSAndroid Build Coastguard Worker    lea 0(%esp), %esi                               // GPRS
667*795d594fSAndroid Build Coastguard Worker    lea X86_LONG_JUMP_GPRS_SIZE(%esp), %edx         // FPRS
668*795d594fSAndroid Build Coastguard Worker
669*795d594fSAndroid Build Coastguard Worker    PUSH_ARG edx
670*795d594fSAndroid Build Coastguard Worker    PUSH_ARG esi
671*795d594fSAndroid Build Coastguard Worker    PUSH_ARG eax
672*795d594fSAndroid Build Coastguard Worker    call SYMBOL(artContextCopyForLongJump)          // Context* context,
673*795d594fSAndroid Build Coastguard Worker                                                    // uintptr_t* gprs,
674*795d594fSAndroid Build Coastguard Worker                                                    // uintptr_t* fprs
675*795d594fSAndroid Build Coastguard Worker
676*795d594fSAndroid Build Coastguard Worker    DECREASE_FRAME 8                                // Remove the context and GPRS arguments.
677*795d594fSAndroid Build Coastguard Worker    POP_ARG edx                                     // Restore FPRS, make ESP point to GPRS.
678*795d594fSAndroid Build Coastguard Worker
679*795d594fSAndroid Build Coastguard Worker    // Address base of FPRs.
680*795d594fSAndroid Build Coastguard Worker    movsd 0(%edx), %xmm0     // Load up XMM0-XMM7.
681*795d594fSAndroid Build Coastguard Worker    movsd 8(%edx), %xmm1
682*795d594fSAndroid Build Coastguard Worker    movsd 16(%edx), %xmm2
683*795d594fSAndroid Build Coastguard Worker    movsd 24(%edx), %xmm3
684*795d594fSAndroid Build Coastguard Worker    movsd 32(%edx), %xmm4
685*795d594fSAndroid Build Coastguard Worker    movsd 40(%edx), %xmm5
686*795d594fSAndroid Build Coastguard Worker    movsd 48(%edx), %xmm6
687*795d594fSAndroid Build Coastguard Worker    movsd 56(%edx), %xmm7
688*795d594fSAndroid Build Coastguard Worker    popal            // Load all registers except ESP and EIP with values in gprs.
689*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(-(X86_LONG_JUMP_GPRS_SIZE - /*ESP*/ 4))
690*795d594fSAndroid Build Coastguard Worker
691*795d594fSAndroid Build Coastguard Worker    POP_ARG esp      // Load stack pointer.
692*795d594fSAndroid Build Coastguard Worker    CFI_DEF_CFA(esp, 4)
693*795d594fSAndroid Build Coastguard Worker    ret              // From higher in the stack pop EIP.
694*795d594fSAndroid Build Coastguard Worker#endif
695*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION art_quick_do_long_jump
696*795d594fSAndroid Build Coastguard Worker
697*795d594fSAndroid Build Coastguard WorkerMACRO3(ONE_ARG_DOWNCALL, c_name, cxx_name, return_macro)
698*795d594fSAndroid Build Coastguard Worker    DEFINE_FUNCTION VAR(c_name)
699*795d594fSAndroid Build Coastguard Worker    SETUP_SAVE_REFS_ONLY_FRAME ebx               // save ref containing registers for GC
700*795d594fSAndroid Build Coastguard Worker    // Outgoing argument set up
701*795d594fSAndroid Build Coastguard Worker    INCREASE_FRAME 8                             // push padding
702*795d594fSAndroid Build Coastguard Worker    pushl %fs:THREAD_SELF_OFFSET                 // pass Thread::Current()
703*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
704*795d594fSAndroid Build Coastguard Worker    PUSH eax                                     // pass arg1
705*795d594fSAndroid Build Coastguard Worker    call CALLVAR(cxx_name)                       // cxx_name(arg1, Thread*)
706*795d594fSAndroid Build Coastguard Worker    DECREASE_FRAME 16                            // pop arguments
707*795d594fSAndroid Build Coastguard Worker    RESTORE_SAVE_REFS_ONLY_FRAME                 // restore frame up to return address
708*795d594fSAndroid Build Coastguard Worker    CALL_MACRO(return_macro)                     // return or deliver exception
709*795d594fSAndroid Build Coastguard Worker    END_FUNCTION VAR(c_name)
710*795d594fSAndroid Build Coastguard WorkerEND_MACRO
711*795d594fSAndroid Build Coastguard Worker
712*795d594fSAndroid Build Coastguard WorkerMACRO3(TWO_ARG_DOWNCALL, c_name, cxx_name, return_macro)
713*795d594fSAndroid Build Coastguard Worker    DEFINE_FUNCTION VAR(c_name)
714*795d594fSAndroid Build Coastguard Worker    SETUP_SAVE_REFS_ONLY_FRAME ebx               // save ref containing registers for GC
715*795d594fSAndroid Build Coastguard Worker    // Outgoing argument set up
716*795d594fSAndroid Build Coastguard Worker    PUSH eax                                     // push padding
717*795d594fSAndroid Build Coastguard Worker    pushl %fs:THREAD_SELF_OFFSET                 // pass Thread::Current()
718*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
719*795d594fSAndroid Build Coastguard Worker    PUSH ecx                                     // pass arg2
720*795d594fSAndroid Build Coastguard Worker    PUSH eax                                     // pass arg1
721*795d594fSAndroid Build Coastguard Worker    call CALLVAR(cxx_name)                       // cxx_name(arg1, arg2, Thread*)
722*795d594fSAndroid Build Coastguard Worker    DECREASE_FRAME 16                            // pop arguments
723*795d594fSAndroid Build Coastguard Worker    RESTORE_SAVE_REFS_ONLY_FRAME                 // restore frame up to return address
724*795d594fSAndroid Build Coastguard Worker    CALL_MACRO(return_macro)                     // return or deliver exception
725*795d594fSAndroid Build Coastguard Worker    END_FUNCTION VAR(c_name)
726*795d594fSAndroid Build Coastguard WorkerEND_MACRO
727*795d594fSAndroid Build Coastguard Worker
728*795d594fSAndroid Build Coastguard WorkerMACRO3(THREE_ARG_DOWNCALL, c_name, cxx_name, return_macro)
729*795d594fSAndroid Build Coastguard Worker    DEFINE_FUNCTION VAR(c_name)
730*795d594fSAndroid Build Coastguard Worker    SETUP_SAVE_REFS_ONLY_FRAME ebx               // save ref containing registers for GC
731*795d594fSAndroid Build Coastguard Worker    // Outgoing argument set up
732*795d594fSAndroid Build Coastguard Worker    pushl %fs:THREAD_SELF_OFFSET                 // pass Thread::Current()
733*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
734*795d594fSAndroid Build Coastguard Worker    PUSH edx                                     // pass arg3
735*795d594fSAndroid Build Coastguard Worker    PUSH ecx                                     // pass arg2
736*795d594fSAndroid Build Coastguard Worker    PUSH eax                                     // pass arg1
737*795d594fSAndroid Build Coastguard Worker    call CALLVAR(cxx_name)                       // cxx_name(arg1, arg2, arg3, Thread*)
738*795d594fSAndroid Build Coastguard Worker    DECREASE_FRAME 16                            // pop arguments
739*795d594fSAndroid Build Coastguard Worker    RESTORE_SAVE_REFS_ONLY_FRAME                 // restore frame up to return address
740*795d594fSAndroid Build Coastguard Worker    CALL_MACRO(return_macro)                     // return or deliver exception
741*795d594fSAndroid Build Coastguard Worker    END_FUNCTION VAR(c_name)
742*795d594fSAndroid Build Coastguard WorkerEND_MACRO
743*795d594fSAndroid Build Coastguard Worker
744*795d594fSAndroid Build Coastguard WorkerMACRO3(FOUR_ARG_DOWNCALL, c_name, cxx_name, return_macro)
745*795d594fSAndroid Build Coastguard Worker    DEFINE_FUNCTION VAR(c_name)
746*795d594fSAndroid Build Coastguard Worker    SETUP_SAVE_REFS_ONLY_FRAME_PRESERVE_TEMP_REG ebx  // save ref containing registers for GC
747*795d594fSAndroid Build Coastguard Worker
748*795d594fSAndroid Build Coastguard Worker    // Outgoing argument set up
749*795d594fSAndroid Build Coastguard Worker    INCREASE_FRAME 12                            // alignment padding
750*795d594fSAndroid Build Coastguard Worker    pushl %fs:THREAD_SELF_OFFSET                 // pass Thread::Current()
751*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
752*795d594fSAndroid Build Coastguard Worker    PUSH ebx                                     // pass arg4
753*795d594fSAndroid Build Coastguard Worker    PUSH edx                                     // pass arg3
754*795d594fSAndroid Build Coastguard Worker    PUSH ecx                                     // pass arg2
755*795d594fSAndroid Build Coastguard Worker    PUSH eax                                     // pass arg1
756*795d594fSAndroid Build Coastguard Worker    call CALLVAR(cxx_name)                       // cxx_name(arg1, arg2, arg3, arg4, Thread*)
757*795d594fSAndroid Build Coastguard Worker    DECREASE_FRAME 32                            // pop arguments
758*795d594fSAndroid Build Coastguard Worker    RESTORE_SAVE_REFS_ONLY_FRAME                 // restore frame up to return address
759*795d594fSAndroid Build Coastguard Worker    CALL_MACRO(return_macro)                     // return or deliver exception
760*795d594fSAndroid Build Coastguard Worker    END_FUNCTION VAR(c_name)
761*795d594fSAndroid Build Coastguard WorkerEND_MACRO
762*795d594fSAndroid Build Coastguard Worker
763*795d594fSAndroid Build Coastguard Worker    /*
764*795d594fSAndroid Build Coastguard Worker     * Macro for resolution and initialization of indexed DEX file
765*795d594fSAndroid Build Coastguard Worker     * constants such as classes and strings.
766*795d594fSAndroid Build Coastguard Worker     */
767*795d594fSAndroid Build Coastguard WorkerMACRO3(ONE_ARG_SAVE_EVERYTHING_DOWNCALL, c_name, cxx_name, runtime_method_offset = RUNTIME_SAVE_EVERYTHING_METHOD_OFFSET)
768*795d594fSAndroid Build Coastguard Worker    DEFINE_FUNCTION VAR(c_name)
769*795d594fSAndroid Build Coastguard Worker    SETUP_SAVE_EVERYTHING_FRAME ebx, \runtime_method_offset  // save ref containing registers for GC
770*795d594fSAndroid Build Coastguard Worker    // Outgoing argument set up
771*795d594fSAndroid Build Coastguard Worker    INCREASE_FRAME 8                                  // push padding
772*795d594fSAndroid Build Coastguard Worker    pushl %fs:THREAD_SELF_OFFSET                      // pass Thread::Current()
773*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
774*795d594fSAndroid Build Coastguard Worker    PUSH eax                                          // pass the index of the constant as arg1
775*795d594fSAndroid Build Coastguard Worker    call CALLVAR(cxx_name)                            // cxx_name(arg1, Thread*)
776*795d594fSAndroid Build Coastguard Worker    DECREASE_FRAME 16                                 // pop arguments
777*795d594fSAndroid Build Coastguard Worker    testl %eax, %eax                                  // If result is null deliver pending exception
778*795d594fSAndroid Build Coastguard Worker    jz 1f
779*795d594fSAndroid Build Coastguard Worker    DEOPT_OR_RESTORE_SAVE_EVERYTHING_FRAME_AND_RETURN_EAX ebx,  /* is_ref= */1  // Check for deopt
780*795d594fSAndroid Build Coastguard Worker1:
781*795d594fSAndroid Build Coastguard Worker    DELIVER_PENDING_EXCEPTION_FRAME_READY
782*795d594fSAndroid Build Coastguard Worker    END_FUNCTION VAR(c_name)
783*795d594fSAndroid Build Coastguard WorkerEND_MACRO
784*795d594fSAndroid Build Coastguard Worker
785*795d594fSAndroid Build Coastguard WorkerMACRO2(ONE_ARG_SAVE_EVERYTHING_DOWNCALL_FOR_CLINIT, c_name, cxx_name)
786*795d594fSAndroid Build Coastguard Worker    ONE_ARG_SAVE_EVERYTHING_DOWNCALL \c_name, \cxx_name, RUNTIME_SAVE_EVERYTHING_FOR_CLINIT_METHOD_OFFSET
787*795d594fSAndroid Build Coastguard WorkerEND_MACRO
788*795d594fSAndroid Build Coastguard Worker
789*795d594fSAndroid Build Coastguard WorkerMACRO0(RETURN_OR_DEOPT_IF_RESULT_IS_NON_NULL_OR_DELIVER)
790*795d594fSAndroid Build Coastguard Worker    CFI_REMEMBER_STATE
791*795d594fSAndroid Build Coastguard Worker    testl %eax, %eax                  // eax == 0 ?
792*795d594fSAndroid Build Coastguard Worker    jz  1f                            // if eax == 0 goto 1
793*795d594fSAndroid Build Coastguard Worker    DEOPT_OR_RETURN ebx, /*is_ref=*/1 // check if deopt is required
794*795d594fSAndroid Build Coastguard Worker1:                                    // deliver exception on current thread
795*795d594fSAndroid Build Coastguard Worker    CFI_RESTORE_STATE_AND_DEF_CFA esp, 4
796*795d594fSAndroid Build Coastguard Worker    DELIVER_PENDING_EXCEPTION
797*795d594fSAndroid Build Coastguard WorkerEND_MACRO
798*795d594fSAndroid Build Coastguard Worker
799*795d594fSAndroid Build Coastguard WorkerMACRO1(RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION, is_ref = 0)
800*795d594fSAndroid Build Coastguard Worker    CFI_REMEMBER_STATE
801*795d594fSAndroid Build Coastguard Worker    cmpl MACRO_LITERAL(0),%fs:THREAD_EXCEPTION_OFFSET // exception field == 0 ?
802*795d594fSAndroid Build Coastguard Worker    jne 1f                                            // if exception field != 0 goto 1
803*795d594fSAndroid Build Coastguard Worker    DEOPT_OR_RETURN ebx, \is_ref                      // check if deopt is required
804*795d594fSAndroid Build Coastguard Worker1:                                                    // deliver exception on current thread
805*795d594fSAndroid Build Coastguard Worker    CFI_RESTORE_STATE_AND_DEF_CFA esp, 4
806*795d594fSAndroid Build Coastguard Worker    DELIVER_PENDING_EXCEPTION
807*795d594fSAndroid Build Coastguard WorkerEND_MACRO
808*795d594fSAndroid Build Coastguard Worker
809*795d594fSAndroid Build Coastguard WorkerMACRO0(RETURN_REF_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION)
810*795d594fSAndroid Build Coastguard Worker    RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION /*is_ref=*/1
811*795d594fSAndroid Build Coastguard WorkerEND_MACRO
812*795d594fSAndroid Build Coastguard Worker
813*795d594fSAndroid Build Coastguard WorkerMACRO2(DEOPT_OR_RETURN, temp, is_ref = 0)
814*795d594fSAndroid Build Coastguard Worker  cmpl LITERAL(0), %fs:THREAD_DEOPT_CHECK_REQUIRED_OFFSET
815*795d594fSAndroid Build Coastguard Worker  jne 2f
816*795d594fSAndroid Build Coastguard Worker  ret
817*795d594fSAndroid Build Coastguard Worker2:
818*795d594fSAndroid Build Coastguard Worker  SETUP_SAVE_EVERYTHING_FRAME \temp
819*795d594fSAndroid Build Coastguard Worker  INCREASE_FRAME 4                  // alignment padding
820*795d594fSAndroid Build Coastguard Worker  pushl MACRO_LITERAL(\is_ref)      // is_ref
821*795d594fSAndroid Build Coastguard Worker  CFI_ADJUST_CFA_OFFSET(4)
822*795d594fSAndroid Build Coastguard Worker  PUSH_ARG eax                      // result
823*795d594fSAndroid Build Coastguard Worker  pushl %fs:THREAD_SELF_OFFSET      // Pass Thread::Current
824*795d594fSAndroid Build Coastguard Worker  CFI_ADJUST_CFA_OFFSET(4)
825*795d594fSAndroid Build Coastguard Worker  call SYMBOL(artDeoptimizeIfNeeded)
826*795d594fSAndroid Build Coastguard Worker  DECREASE_FRAME(16)                // pop arguments
827*795d594fSAndroid Build Coastguard Worker
828*795d594fSAndroid Build Coastguard Worker  CFI_REMEMBER_STATE
829*795d594fSAndroid Build Coastguard Worker  testl %eax, %eax
830*795d594fSAndroid Build Coastguard Worker  jnz 3f
831*795d594fSAndroid Build Coastguard Worker
832*795d594fSAndroid Build Coastguard Worker  RESTORE_SAVE_EVERYTHING_FRAME
833*795d594fSAndroid Build Coastguard Worker  ret
834*795d594fSAndroid Build Coastguard Worker
835*795d594fSAndroid Build Coastguard Worker3:
836*795d594fSAndroid Build Coastguard Worker  // Deoptimize
837*795d594fSAndroid Build Coastguard Worker  CFI_RESTORE_STATE_AND_DEF_CFA esp, FRAME_SIZE_SAVE_EVERYTHING
838*795d594fSAndroid Build Coastguard Worker  call SYMBOL(art_quick_do_long_jump)
839*795d594fSAndroid Build Coastguard Worker  UNREACHABLE
840*795d594fSAndroid Build Coastguard WorkerEND_MACRO
841*795d594fSAndroid Build Coastguard Worker
842*795d594fSAndroid Build Coastguard WorkerMACRO2(DEOPT_OR_RESTORE_SAVE_EVERYTHING_FRAME_AND_RETURN_EAX, temp, is_ref = 0)
843*795d594fSAndroid Build Coastguard Worker  cmpl LITERAL(0), %fs:THREAD_DEOPT_CHECK_REQUIRED_OFFSET
844*795d594fSAndroid Build Coastguard Worker  CFI_REMEMBER_STATE
845*795d594fSAndroid Build Coastguard Worker  jne 2f
846*795d594fSAndroid Build Coastguard Worker  RESTORE_SAVE_EVERYTHING_FRAME_KEEP_EAX
847*795d594fSAndroid Build Coastguard Worker  ret
848*795d594fSAndroid Build Coastguard Worker2:
849*795d594fSAndroid Build Coastguard Worker  CFI_RESTORE_STATE_AND_DEF_CFA esp, FRAME_SIZE_SAVE_EVERYTHING
850*795d594fSAndroid Build Coastguard Worker  movl %eax, SAVE_EVERYTHING_FRAME_EAX_OFFSET(%esp) // update eax in the frame
851*795d594fSAndroid Build Coastguard Worker  INCREASE_FRAME 4                                  // alignment padding
852*795d594fSAndroid Build Coastguard Worker  pushl MACRO_LITERAL(\is_ref)                      // is_ref
853*795d594fSAndroid Build Coastguard Worker  CFI_ADJUST_CFA_OFFSET(4)
854*795d594fSAndroid Build Coastguard Worker  PUSH_ARG eax                                      // result
855*795d594fSAndroid Build Coastguard Worker  pushl %fs:THREAD_SELF_OFFSET                      // Pass Thread::Current
856*795d594fSAndroid Build Coastguard Worker  CFI_ADJUST_CFA_OFFSET(4)
857*795d594fSAndroid Build Coastguard Worker  call SYMBOL(artDeoptimizeIfNeeded)
858*795d594fSAndroid Build Coastguard Worker  DECREASE_FRAME(16)                                // pop arguments
859*795d594fSAndroid Build Coastguard Worker
860*795d594fSAndroid Build Coastguard Worker  CFI_REMEMBER_STATE
861*795d594fSAndroid Build Coastguard Worker  testl %eax, %eax
862*795d594fSAndroid Build Coastguard Worker  jnz 3f
863*795d594fSAndroid Build Coastguard Worker
864*795d594fSAndroid Build Coastguard Worker  RESTORE_SAVE_EVERYTHING_FRAME
865*795d594fSAndroid Build Coastguard Worker  ret
866*795d594fSAndroid Build Coastguard Worker
867*795d594fSAndroid Build Coastguard Worker3:
868*795d594fSAndroid Build Coastguard Worker  // Deoptimize
869*795d594fSAndroid Build Coastguard Worker  CFI_RESTORE_STATE_AND_DEF_CFA esp, FRAME_SIZE_SAVE_EVERYTHING
870*795d594fSAndroid Build Coastguard Worker  call SYMBOL(art_quick_do_long_jump)
871*795d594fSAndroid Build Coastguard Worker  UNREACHABLE
872*795d594fSAndroid Build Coastguard WorkerEND_MACRO
873*795d594fSAndroid Build Coastguard Worker
874*795d594fSAndroid Build Coastguard Worker
875*795d594fSAndroid Build Coastguard WorkerMACRO0(RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER)
876*795d594fSAndroid Build Coastguard Worker    CFI_REMEMBER_STATE
877*795d594fSAndroid Build Coastguard Worker    testl %eax, %eax               // eax == 0 ?
878*795d594fSAndroid Build Coastguard Worker    jnz  1f                        // if eax != 0 goto 1
879*795d594fSAndroid Build Coastguard Worker    DEOPT_OR_RETURN ebx            // check if deopt is needed
880*795d594fSAndroid Build Coastguard Worker1:                                 // deliver exception on current thread
881*795d594fSAndroid Build Coastguard Worker    CFI_RESTORE_STATE_AND_DEF_CFA esp, 4
882*795d594fSAndroid Build Coastguard Worker    DELIVER_PENDING_EXCEPTION
883*795d594fSAndroid Build Coastguard WorkerEND_MACRO
884*795d594fSAndroid Build Coastguard Worker
885*795d594fSAndroid Build Coastguard Worker// Generate the allocation entrypoints for each allocator.
886*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_ENTRYPOINTS_FOR_NON_TLAB_ALLOCATORS
887*795d594fSAndroid Build Coastguard Worker
888*795d594fSAndroid Build Coastguard Worker// Comment out allocators that have x86 specific asm.
889*795d594fSAndroid Build Coastguard Worker// Region TLAB:
890*795d594fSAndroid Build Coastguard Worker// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_region_tlab, RegionTLAB)
891*795d594fSAndroid Build Coastguard Worker// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_region_tlab, RegionTLAB)
892*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_region_tlab, RegionTLAB)
893*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_OBJECT(_region_tlab, RegionTLAB)
894*795d594fSAndroid Build Coastguard Worker// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_region_tlab, RegionTLAB)
895*795d594fSAndroid Build Coastguard Worker// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED8(_region_tlab, RegionTLAB)
896*795d594fSAndroid Build Coastguard Worker// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED16(_region_tlab, RegionTLAB)
897*795d594fSAndroid Build Coastguard Worker// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED32(_region_tlab, RegionTLAB)
898*795d594fSAndroid Build Coastguard Worker// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED64(_region_tlab, RegionTLAB)
899*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_FROM_BYTES(_region_tlab, RegionTLAB)
900*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_FROM_CHARS(_region_tlab, RegionTLAB)
901*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_FROM_STRING(_region_tlab, RegionTLAB)
902*795d594fSAndroid Build Coastguard Worker// Normal TLAB:
903*795d594fSAndroid Build Coastguard Worker// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_tlab, TLAB)
904*795d594fSAndroid Build Coastguard Worker// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_tlab, TLAB)
905*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_tlab, TLAB)
906*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_OBJECT(_tlab, TLAB)
907*795d594fSAndroid Build Coastguard Worker// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_tlab, TLAB)
908*795d594fSAndroid Build Coastguard Worker// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED8(_tlab, TLAB)
909*795d594fSAndroid Build Coastguard Worker// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED16(_tlab, TLAB)
910*795d594fSAndroid Build Coastguard Worker// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED32(_tlab, TLAB)
911*795d594fSAndroid Build Coastguard Worker// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED64(_tlab, TLAB)
912*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_FROM_BYTES(_tlab, TLAB)
913*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_FROM_CHARS(_tlab, TLAB)
914*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_FROM_STRING(_tlab, TLAB)
915*795d594fSAndroid Build Coastguard Worker
916*795d594fSAndroid Build Coastguard Worker// A hand-written override for GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_rosalloc, RosAlloc).
917*795d594fSAndroid Build Coastguard WorkerMACRO2(ART_QUICK_ALLOC_OBJECT_ROSALLOC, c_name, cxx_name)
918*795d594fSAndroid Build Coastguard Worker    DEFINE_FUNCTION VAR(c_name)
919*795d594fSAndroid Build Coastguard Worker    // Fast path rosalloc allocation.
920*795d594fSAndroid Build Coastguard Worker    // eax: type/return value
921*795d594fSAndroid Build Coastguard Worker    // ecx, ebx, edx: free
922*795d594fSAndroid Build Coastguard Worker    movl %fs:THREAD_SELF_OFFSET, %ebx                   // ebx = thread
923*795d594fSAndroid Build Coastguard Worker                                                        // Check if the thread local allocation
924*795d594fSAndroid Build Coastguard Worker                                                        // stack has room
925*795d594fSAndroid Build Coastguard Worker    movl THREAD_LOCAL_ALLOC_STACK_TOP_OFFSET(%ebx), %ecx
926*795d594fSAndroid Build Coastguard Worker    cmpl THREAD_LOCAL_ALLOC_STACK_END_OFFSET(%ebx), %ecx
927*795d594fSAndroid Build Coastguard Worker    jae  .Lslow_path\c_name
928*795d594fSAndroid Build Coastguard Worker
929*795d594fSAndroid Build Coastguard Worker    movl MIRROR_CLASS_OBJECT_SIZE_ALLOC_FAST_PATH_OFFSET(%eax), %ecx  // Load the object size (ecx)
930*795d594fSAndroid Build Coastguard Worker                                                        // Check if the size is for a thread
931*795d594fSAndroid Build Coastguard Worker                                                        // local allocation. Also does the
932*795d594fSAndroid Build Coastguard Worker                                                        // finalizable and initialization check.
933*795d594fSAndroid Build Coastguard Worker    cmpl LITERAL(ROSALLOC_MAX_THREAD_LOCAL_BRACKET_SIZE), %ecx
934*795d594fSAndroid Build Coastguard Worker    ja   .Lslow_path\c_name
935*795d594fSAndroid Build Coastguard Worker    shrl LITERAL(ROSALLOC_BRACKET_QUANTUM_SIZE_SHIFT), %ecx // Calculate the rosalloc bracket index
936*795d594fSAndroid Build Coastguard Worker                                                            // from object size.
937*795d594fSAndroid Build Coastguard Worker                                                        // Load thread local rosalloc run (ebx)
938*795d594fSAndroid Build Coastguard Worker                                                        // Subtract __SIZEOF_POINTER__ to subtract
939*795d594fSAndroid Build Coastguard Worker                                                        // one from edi as there is no 0 byte run
940*795d594fSAndroid Build Coastguard Worker                                                        // and the size is already aligned.
941*795d594fSAndroid Build Coastguard Worker    movl (THREAD_ROSALLOC_RUNS_OFFSET - __SIZEOF_POINTER__)(%ebx, %ecx, __SIZEOF_POINTER__), %ebx
942*795d594fSAndroid Build Coastguard Worker                                                        // Load free_list head (edi),
943*795d594fSAndroid Build Coastguard Worker                                                        // this will be the return value.
944*795d594fSAndroid Build Coastguard Worker    movl (ROSALLOC_RUN_FREE_LIST_OFFSET + ROSALLOC_RUN_FREE_LIST_HEAD_OFFSET)(%ebx), %ecx
945*795d594fSAndroid Build Coastguard Worker    jecxz   .Lslow_path\c_name
946*795d594fSAndroid Build Coastguard Worker                                                        // Point of no slow path. Won't go to
947*795d594fSAndroid Build Coastguard Worker                                                        // the slow path from here on.
948*795d594fSAndroid Build Coastguard Worker                                                        // Load the next pointer of the head
949*795d594fSAndroid Build Coastguard Worker                                                        // and update head of free list with
950*795d594fSAndroid Build Coastguard Worker                                                        // next pointer
951*795d594fSAndroid Build Coastguard Worker    movl ROSALLOC_SLOT_NEXT_OFFSET(%ecx), %edx
952*795d594fSAndroid Build Coastguard Worker    movl %edx, (ROSALLOC_RUN_FREE_LIST_OFFSET + ROSALLOC_RUN_FREE_LIST_HEAD_OFFSET)(%ebx)
953*795d594fSAndroid Build Coastguard Worker                                                        // Decrement size of free list by 1
954*795d594fSAndroid Build Coastguard Worker    decl (ROSALLOC_RUN_FREE_LIST_OFFSET + ROSALLOC_RUN_FREE_LIST_SIZE_OFFSET)(%ebx)
955*795d594fSAndroid Build Coastguard Worker                                                        // Store the class pointer in the
956*795d594fSAndroid Build Coastguard Worker                                                        // header. This also overwrites the
957*795d594fSAndroid Build Coastguard Worker                                                        // next pointer. The offsets are
958*795d594fSAndroid Build Coastguard Worker                                                        // asserted to match.
959*795d594fSAndroid Build Coastguard Worker#if ROSALLOC_SLOT_NEXT_OFFSET != MIRROR_OBJECT_CLASS_OFFSET
960*795d594fSAndroid Build Coastguard Worker#error "Class pointer needs to overwrite next pointer."
961*795d594fSAndroid Build Coastguard Worker#endif
962*795d594fSAndroid Build Coastguard Worker    POISON_HEAP_REF eax
963*795d594fSAndroid Build Coastguard Worker    movl %eax, MIRROR_OBJECT_CLASS_OFFSET(%ecx)
964*795d594fSAndroid Build Coastguard Worker    movl %fs:THREAD_SELF_OFFSET, %ebx                   // ebx = thread
965*795d594fSAndroid Build Coastguard Worker                                                        // Push the new object onto the thread
966*795d594fSAndroid Build Coastguard Worker                                                        // local allocation stack and
967*795d594fSAndroid Build Coastguard Worker                                                        // increment the thread local
968*795d594fSAndroid Build Coastguard Worker                                                        // allocation stack top.
969*795d594fSAndroid Build Coastguard Worker    movl THREAD_LOCAL_ALLOC_STACK_TOP_OFFSET(%ebx), %eax
970*795d594fSAndroid Build Coastguard Worker    movl %ecx, (%eax)
971*795d594fSAndroid Build Coastguard Worker    addl LITERAL(COMPRESSED_REFERENCE_SIZE), %eax
972*795d594fSAndroid Build Coastguard Worker    movl %eax, THREAD_LOCAL_ALLOC_STACK_TOP_OFFSET(%ebx)
973*795d594fSAndroid Build Coastguard Worker                                                        // No fence needed for x86.
974*795d594fSAndroid Build Coastguard Worker    movl %ecx, %eax                                     // Move object to return register
975*795d594fSAndroid Build Coastguard Worker    ret
976*795d594fSAndroid Build Coastguard Worker.Lslow_path\c_name:
977*795d594fSAndroid Build Coastguard Worker    SETUP_SAVE_REFS_ONLY_FRAME ebx              // save ref containing registers for GC
978*795d594fSAndroid Build Coastguard Worker    // Outgoing argument set up
979*795d594fSAndroid Build Coastguard Worker    INCREASE_FRAME(8)                           // alignment padding
980*795d594fSAndroid Build Coastguard Worker    pushl %fs:THREAD_SELF_OFFSET  // pass Thread::Current()
981*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
982*795d594fSAndroid Build Coastguard Worker    PUSH eax
983*795d594fSAndroid Build Coastguard Worker    call SYMBOL(artAllocObjectFromCodeResolvedRosAlloc)  // cxx_name(arg0, Thread*)
984*795d594fSAndroid Build Coastguard Worker    addl LITERAL(16), %esp                       // pop arguments
985*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(-16)
986*795d594fSAndroid Build Coastguard Worker    RESTORE_SAVE_REFS_ONLY_FRAME                 // restore frame up to return address
987*795d594fSAndroid Build Coastguard Worker    RETURN_OR_DEOPT_IF_RESULT_IS_NON_NULL_OR_DELIVER      // return or deliver exception
988*795d594fSAndroid Build Coastguard Worker    END_FUNCTION VAR(c_name)
989*795d594fSAndroid Build Coastguard WorkerEND_MACRO
990*795d594fSAndroid Build Coastguard Worker
991*795d594fSAndroid Build Coastguard WorkerART_QUICK_ALLOC_OBJECT_ROSALLOC art_quick_alloc_object_resolved_rosalloc, artAllocObjectFromCodeResolvedRosAlloc
992*795d594fSAndroid Build Coastguard WorkerART_QUICK_ALLOC_OBJECT_ROSALLOC art_quick_alloc_object_initialized_rosalloc, artAllocObjectFromCodeInitializedRosAlloc
993*795d594fSAndroid Build Coastguard Worker
994*795d594fSAndroid Build Coastguard Worker// The common fast path code for art_quick_alloc_object_resolved/initialized_tlab
995*795d594fSAndroid Build Coastguard Worker// and art_quick_alloc_object_resolved/initialized_region_tlab.
996*795d594fSAndroid Build Coastguard Worker//
997*795d594fSAndroid Build Coastguard Worker// EAX: type/return_value
998*795d594fSAndroid Build Coastguard WorkerMACRO1(ALLOC_OBJECT_RESOLVED_TLAB_FAST_PATH, slowPathLabel)
999*795d594fSAndroid Build Coastguard Worker    movl %fs:THREAD_SELF_OFFSET, %ebx                   // ebx = thread
1000*795d594fSAndroid Build Coastguard Worker    movl THREAD_LOCAL_END_OFFSET(%ebx), %edi            // Load thread_local_end.
1001*795d594fSAndroid Build Coastguard Worker    subl THREAD_LOCAL_POS_OFFSET(%ebx), %edi            // Compute the remaining buffer size.
1002*795d594fSAndroid Build Coastguard Worker    movl MIRROR_CLASS_OBJECT_SIZE_ALLOC_FAST_PATH_OFFSET(%eax), %ecx  // Load the object size.
1003*795d594fSAndroid Build Coastguard Worker    cmpl %edi, %ecx                                     // Check if it fits.
1004*795d594fSAndroid Build Coastguard Worker    ja   VAR(slowPathLabel)
1005*795d594fSAndroid Build Coastguard Worker    movl THREAD_LOCAL_POS_OFFSET(%ebx), %edx            // Load thread_local_pos
1006*795d594fSAndroid Build Coastguard Worker                                                        // as allocated object.
1007*795d594fSAndroid Build Coastguard Worker    addl %edx, %ecx                                     // Add the object size.
1008*795d594fSAndroid Build Coastguard Worker    movl %ecx, THREAD_LOCAL_POS_OFFSET(%ebx)            // Update thread_local_pos.
1009*795d594fSAndroid Build Coastguard Worker                                                        // Store the class pointer in the header.
1010*795d594fSAndroid Build Coastguard Worker                                                        // No fence needed for x86.
1011*795d594fSAndroid Build Coastguard Worker    POISON_HEAP_REF eax
1012*795d594fSAndroid Build Coastguard Worker    movl %eax, MIRROR_OBJECT_CLASS_OFFSET(%edx)
1013*795d594fSAndroid Build Coastguard Worker    movl %edx, %eax
1014*795d594fSAndroid Build Coastguard Worker    POP edi
1015*795d594fSAndroid Build Coastguard Worker    ret                                                 // Fast path succeeded.
1016*795d594fSAndroid Build Coastguard WorkerEND_MACRO
1017*795d594fSAndroid Build Coastguard Worker
1018*795d594fSAndroid Build Coastguard Worker// The common slow path code for art_quick_alloc_object_resolved/initialized_tlab
1019*795d594fSAndroid Build Coastguard Worker// and art_quick_alloc_object_resolved/initialized_region_tlab.
1020*795d594fSAndroid Build Coastguard WorkerMACRO1(ALLOC_OBJECT_RESOLVED_TLAB_SLOW_PATH, cxx_name)
1021*795d594fSAndroid Build Coastguard Worker    POP edi
1022*795d594fSAndroid Build Coastguard Worker    SETUP_SAVE_REFS_ONLY_FRAME ebx                      // save ref containing registers for GC
1023*795d594fSAndroid Build Coastguard Worker    // Outgoing argument set up
1024*795d594fSAndroid Build Coastguard Worker    subl LITERAL(8), %esp                               // alignment padding
1025*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(8)
1026*795d594fSAndroid Build Coastguard Worker    pushl %fs:THREAD_SELF_OFFSET                        // pass Thread::Current()
1027*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
1028*795d594fSAndroid Build Coastguard Worker    PUSH eax
1029*795d594fSAndroid Build Coastguard Worker    call CALLVAR(cxx_name)                              // cxx_name(arg0, Thread*)
1030*795d594fSAndroid Build Coastguard Worker    addl LITERAL(16), %esp
1031*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(-16)
1032*795d594fSAndroid Build Coastguard Worker    RESTORE_SAVE_REFS_ONLY_FRAME                        // restore frame up to return address
1033*795d594fSAndroid Build Coastguard Worker    RETURN_OR_DEOPT_IF_RESULT_IS_NON_NULL_OR_DELIVER    // return or deliver exception
1034*795d594fSAndroid Build Coastguard WorkerEND_MACRO
1035*795d594fSAndroid Build Coastguard Worker
1036*795d594fSAndroid Build Coastguard WorkerMACRO2(ART_QUICK_ALLOC_OBJECT_TLAB, c_name, cxx_name)
1037*795d594fSAndroid Build Coastguard Worker    DEFINE_FUNCTION VAR(c_name)
1038*795d594fSAndroid Build Coastguard Worker    // Fast path tlab allocation.
1039*795d594fSAndroid Build Coastguard Worker    // EAX: type
1040*795d594fSAndroid Build Coastguard Worker    // EBX, ECX, EDX: free.
1041*795d594fSAndroid Build Coastguard Worker    PUSH edi
1042*795d594fSAndroid Build Coastguard Worker    CFI_REMEMBER_STATE
1043*795d594fSAndroid Build Coastguard Worker    ALLOC_OBJECT_RESOLVED_TLAB_FAST_PATH .Lslow_path\c_name
1044*795d594fSAndroid Build Coastguard Worker.Lslow_path\c_name:
1045*795d594fSAndroid Build Coastguard Worker    CFI_RESTORE_STATE_AND_DEF_CFA esp, 8
1046*795d594fSAndroid Build Coastguard Worker    ALLOC_OBJECT_RESOLVED_TLAB_SLOW_PATH RAW_VAR(cxx_name)
1047*795d594fSAndroid Build Coastguard Worker    END_FUNCTION VAR(c_name)
1048*795d594fSAndroid Build Coastguard WorkerEND_MACRO
1049*795d594fSAndroid Build Coastguard Worker
1050*795d594fSAndroid Build Coastguard WorkerART_QUICK_ALLOC_OBJECT_TLAB art_quick_alloc_object_resolved_tlab, artAllocObjectFromCodeResolvedTLAB
1051*795d594fSAndroid Build Coastguard WorkerART_QUICK_ALLOC_OBJECT_TLAB art_quick_alloc_object_initialized_tlab, artAllocObjectFromCodeInitializedTLAB
1052*795d594fSAndroid Build Coastguard WorkerART_QUICK_ALLOC_OBJECT_TLAB art_quick_alloc_object_resolved_region_tlab, artAllocObjectFromCodeResolvedRegionTLAB
1053*795d594fSAndroid Build Coastguard WorkerART_QUICK_ALLOC_OBJECT_TLAB art_quick_alloc_object_initialized_region_tlab, artAllocObjectFromCodeInitializedRegionTLAB
1054*795d594fSAndroid Build Coastguard Worker
1055*795d594fSAndroid Build Coastguard Worker// The fast path code for art_quick_alloc_array_region_tlab.
1056*795d594fSAndroid Build Coastguard Worker// Inputs: EAX: the class, ECX: int32_t component_count, EDX: total_size
1057*795d594fSAndroid Build Coastguard Worker// Free temp: EBX
1058*795d594fSAndroid Build Coastguard Worker// Output: EAX: return value.
1059*795d594fSAndroid Build Coastguard WorkerMACRO1(ALLOC_ARRAY_TLAB_FAST_PATH_RESOLVED_WITH_SIZE, slowPathLabel)
1060*795d594fSAndroid Build Coastguard Worker    mov %fs:THREAD_SELF_OFFSET, %ebx                          // ebx = thread
1061*795d594fSAndroid Build Coastguard Worker    // Mask out the unaligned part to make sure we are 8 byte aligned.
1062*795d594fSAndroid Build Coastguard Worker    andl LITERAL(OBJECT_ALIGNMENT_MASK_TOGGLED), %edx
1063*795d594fSAndroid Build Coastguard Worker    movl THREAD_LOCAL_END_OFFSET(%ebx), %edi
1064*795d594fSAndroid Build Coastguard Worker    subl THREAD_LOCAL_POS_OFFSET(%ebx), %edi
1065*795d594fSAndroid Build Coastguard Worker    cmpl %edi, %edx                                           // Check if it fits.
1066*795d594fSAndroid Build Coastguard Worker    ja   RAW_VAR(slowPathLabel)
1067*795d594fSAndroid Build Coastguard Worker    movl THREAD_LOCAL_POS_OFFSET(%ebx), %edi
1068*795d594fSAndroid Build Coastguard Worker    addl %edi, %edx                                            // Add the object size.
1069*795d594fSAndroid Build Coastguard Worker    movl %edx, THREAD_LOCAL_POS_OFFSET(%ebx)                   // Update thread_local_pos_
1070*795d594fSAndroid Build Coastguard Worker                                                               // Store the class pointer in the
1071*795d594fSAndroid Build Coastguard Worker                                                               // header.
1072*795d594fSAndroid Build Coastguard Worker                                                               // No fence needed for x86.
1073*795d594fSAndroid Build Coastguard Worker    POISON_HEAP_REF eax
1074*795d594fSAndroid Build Coastguard Worker    movl %eax, MIRROR_OBJECT_CLASS_OFFSET(%edi)
1075*795d594fSAndroid Build Coastguard Worker    movl %ecx, MIRROR_ARRAY_LENGTH_OFFSET(%edi)
1076*795d594fSAndroid Build Coastguard Worker    movl %edi, %eax
1077*795d594fSAndroid Build Coastguard Worker    POP edi
1078*795d594fSAndroid Build Coastguard Worker    ret                                                        // Fast path succeeded.
1079*795d594fSAndroid Build Coastguard WorkerEND_MACRO
1080*795d594fSAndroid Build Coastguard Worker
1081*795d594fSAndroid Build Coastguard WorkerMACRO1(COMPUTE_ARRAY_SIZE_UNKNOWN, slow_path)
1082*795d594fSAndroid Build Coastguard Worker    // Possibly a large object, go slow.
1083*795d594fSAndroid Build Coastguard Worker    // Also does negative array size check.
1084*795d594fSAndroid Build Coastguard Worker    cmpl LITERAL((MIN_LARGE_OBJECT_THRESHOLD - MIRROR_WIDE_ARRAY_DATA_OFFSET) / 8), %ecx
1085*795d594fSAndroid Build Coastguard Worker    jae RAW_VAR(slow_path)
1086*795d594fSAndroid Build Coastguard Worker    PUSH ecx
1087*795d594fSAndroid Build Coastguard Worker    movl %ecx, %edx
1088*795d594fSAndroid Build Coastguard Worker    movl MIRROR_CLASS_COMPONENT_TYPE_OFFSET(%eax), %ecx        // Load component type.
1089*795d594fSAndroid Build Coastguard Worker    UNPOISON_HEAP_REF ecx
1090*795d594fSAndroid Build Coastguard Worker    movl MIRROR_CLASS_OBJECT_PRIMITIVE_TYPE_OFFSET(%ecx), %ecx // Load primitive type.
1091*795d594fSAndroid Build Coastguard Worker    shr MACRO_LITERAL(PRIMITIVE_TYPE_SIZE_SHIFT_SHIFT), %ecx        // Get component size shift.
1092*795d594fSAndroid Build Coastguard Worker    sall %cl, %edx                                              // Calculate array count shifted.
1093*795d594fSAndroid Build Coastguard Worker    // Add array header + alignment rounding.
1094*795d594fSAndroid Build Coastguard Worker    add MACRO_LITERAL(MIRROR_INT_ARRAY_DATA_OFFSET + OBJECT_ALIGNMENT_MASK), %edx
1095*795d594fSAndroid Build Coastguard Worker    // Add 4 extra bytes if we are doing a long array.
1096*795d594fSAndroid Build Coastguard Worker    add MACRO_LITERAL(1), %ecx
1097*795d594fSAndroid Build Coastguard Worker    and MACRO_LITERAL(4), %ecx
1098*795d594fSAndroid Build Coastguard Worker#if MIRROR_WIDE_ARRAY_DATA_OFFSET != MIRROR_INT_ARRAY_DATA_OFFSET + 4
1099*795d594fSAndroid Build Coastguard Worker#error Long array data offset must be 4 greater than int array data offset.
1100*795d594fSAndroid Build Coastguard Worker#endif
1101*795d594fSAndroid Build Coastguard Worker    addl %ecx, %edx
1102*795d594fSAndroid Build Coastguard Worker    POP ecx
1103*795d594fSAndroid Build Coastguard WorkerEND_MACRO
1104*795d594fSAndroid Build Coastguard Worker
1105*795d594fSAndroid Build Coastguard WorkerMACRO1(COMPUTE_ARRAY_SIZE_8, slow_path)
1106*795d594fSAndroid Build Coastguard Worker    // EAX: mirror::Class* klass, ECX: int32_t component_count
1107*795d594fSAndroid Build Coastguard Worker    // Possibly a large object, go slow.
1108*795d594fSAndroid Build Coastguard Worker    // Also does negative array size check.
1109*795d594fSAndroid Build Coastguard Worker    cmpl LITERAL(MIN_LARGE_OBJECT_THRESHOLD - MIRROR_INT_ARRAY_DATA_OFFSET), %ecx
1110*795d594fSAndroid Build Coastguard Worker    jae RAW_VAR(slow_path)
1111*795d594fSAndroid Build Coastguard Worker    // Add array header + alignment rounding.
1112*795d594fSAndroid Build Coastguard Worker    leal (MIRROR_INT_ARRAY_DATA_OFFSET + OBJECT_ALIGNMENT_MASK)(%ecx), %edx
1113*795d594fSAndroid Build Coastguard WorkerEND_MACRO
1114*795d594fSAndroid Build Coastguard Worker
1115*795d594fSAndroid Build Coastguard WorkerMACRO1(COMPUTE_ARRAY_SIZE_16, slow_path)
1116*795d594fSAndroid Build Coastguard Worker    // EAX: mirror::Class* klass, ECX: int32_t component_count
1117*795d594fSAndroid Build Coastguard Worker    // Possibly a large object, go slow.
1118*795d594fSAndroid Build Coastguard Worker    // Also does negative array size check.
1119*795d594fSAndroid Build Coastguard Worker    cmpl LITERAL((MIN_LARGE_OBJECT_THRESHOLD - MIRROR_INT_ARRAY_DATA_OFFSET) / 2), %ecx
1120*795d594fSAndroid Build Coastguard Worker    jae RAW_VAR(slow_path)
1121*795d594fSAndroid Build Coastguard Worker    // Add array header + alignment rounding.
1122*795d594fSAndroid Build Coastguard Worker    leal ((MIRROR_INT_ARRAY_DATA_OFFSET + OBJECT_ALIGNMENT_MASK) / 2)(%ecx), %edx
1123*795d594fSAndroid Build Coastguard Worker    sall MACRO_LITERAL(1), %edx
1124*795d594fSAndroid Build Coastguard WorkerEND_MACRO
1125*795d594fSAndroid Build Coastguard Worker
1126*795d594fSAndroid Build Coastguard WorkerMACRO1(COMPUTE_ARRAY_SIZE_32, slow_path)
1127*795d594fSAndroid Build Coastguard Worker    // EAX: mirror::Class* klass, ECX: int32_t component_count
1128*795d594fSAndroid Build Coastguard Worker    // Possibly a large object, go slow.
1129*795d594fSAndroid Build Coastguard Worker    // Also does negative array size check.
1130*795d594fSAndroid Build Coastguard Worker    cmpl LITERAL((MIN_LARGE_OBJECT_THRESHOLD - MIRROR_INT_ARRAY_DATA_OFFSET) / 4), %ecx
1131*795d594fSAndroid Build Coastguard Worker    jae RAW_VAR(slow_path)
1132*795d594fSAndroid Build Coastguard Worker    // Add array header + alignment rounding.
1133*795d594fSAndroid Build Coastguard Worker    leal ((MIRROR_INT_ARRAY_DATA_OFFSET + OBJECT_ALIGNMENT_MASK) / 4)(%ecx), %edx
1134*795d594fSAndroid Build Coastguard Worker    sall MACRO_LITERAL(2), %edx
1135*795d594fSAndroid Build Coastguard WorkerEND_MACRO
1136*795d594fSAndroid Build Coastguard Worker
1137*795d594fSAndroid Build Coastguard WorkerMACRO1(COMPUTE_ARRAY_SIZE_64, slow_path)
1138*795d594fSAndroid Build Coastguard Worker    // EAX: mirror::Class* klass, ECX: int32_t component_count
1139*795d594fSAndroid Build Coastguard Worker    // Possibly a large object, go slow.
1140*795d594fSAndroid Build Coastguard Worker    // Also does negative array size check.
1141*795d594fSAndroid Build Coastguard Worker    cmpl LITERAL((MIN_LARGE_OBJECT_THRESHOLD - MIRROR_WIDE_ARRAY_DATA_OFFSET) / 8), %ecx
1142*795d594fSAndroid Build Coastguard Worker    jae RAW_VAR(slow_path)
1143*795d594fSAndroid Build Coastguard Worker    // Add array header + alignment rounding.
1144*795d594fSAndroid Build Coastguard Worker    leal ((MIRROR_WIDE_ARRAY_DATA_OFFSET + OBJECT_ALIGNMENT_MASK) / 8)(%ecx), %edx
1145*795d594fSAndroid Build Coastguard Worker    sall MACRO_LITERAL(3), %edx
1146*795d594fSAndroid Build Coastguard WorkerEND_MACRO
1147*795d594fSAndroid Build Coastguard Worker
1148*795d594fSAndroid Build Coastguard WorkerMACRO3(GENERATE_ALLOC_ARRAY_TLAB, c_entrypoint, cxx_name, size_setup)
1149*795d594fSAndroid Build Coastguard Worker    DEFINE_FUNCTION VAR(c_entrypoint)
1150*795d594fSAndroid Build Coastguard Worker    // EAX: mirror::Class* klass, ECX: int32_t component_count
1151*795d594fSAndroid Build Coastguard Worker    PUSH edi
1152*795d594fSAndroid Build Coastguard Worker    CALL_MACRO(size_setup) .Lslow_path\c_entrypoint
1153*795d594fSAndroid Build Coastguard Worker    CFI_REMEMBER_STATE
1154*795d594fSAndroid Build Coastguard Worker    ALLOC_ARRAY_TLAB_FAST_PATH_RESOLVED_WITH_SIZE .Lslow_path\c_entrypoint
1155*795d594fSAndroid Build Coastguard Worker.Lslow_path\c_entrypoint:
1156*795d594fSAndroid Build Coastguard Worker    CFI_RESTORE_STATE_AND_DEF_CFA esp, 8
1157*795d594fSAndroid Build Coastguard Worker    POP edi
1158*795d594fSAndroid Build Coastguard Worker    SETUP_SAVE_REFS_ONLY_FRAME ebx                      // save ref containing registers for GC
1159*795d594fSAndroid Build Coastguard Worker    // Outgoing argument set up
1160*795d594fSAndroid Build Coastguard Worker    PUSH eax                                            // alignment padding
1161*795d594fSAndroid Build Coastguard Worker    pushl %fs:THREAD_SELF_OFFSET                        // pass Thread::Current()
1162*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
1163*795d594fSAndroid Build Coastguard Worker    PUSH ecx
1164*795d594fSAndroid Build Coastguard Worker    PUSH eax
1165*795d594fSAndroid Build Coastguard Worker    call CALLVAR(cxx_name)                              // cxx_name(arg0, arg1, Thread*)
1166*795d594fSAndroid Build Coastguard Worker    addl LITERAL(16), %esp                              // pop arguments
1167*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(-16)
1168*795d594fSAndroid Build Coastguard Worker    RESTORE_SAVE_REFS_ONLY_FRAME                        // restore frame up to return address
1169*795d594fSAndroid Build Coastguard Worker    RETURN_OR_DEOPT_IF_RESULT_IS_NON_NULL_OR_DELIVER    // return or deliver exception
1170*795d594fSAndroid Build Coastguard Worker    END_FUNCTION VAR(c_entrypoint)
1171*795d594fSAndroid Build Coastguard WorkerEND_MACRO
1172*795d594fSAndroid Build Coastguard Worker
1173*795d594fSAndroid Build Coastguard Worker
1174*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved_region_tlab, artAllocArrayFromCodeResolvedRegionTLAB, COMPUTE_ARRAY_SIZE_UNKNOWN
1175*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved8_region_tlab, artAllocArrayFromCodeResolvedRegionTLAB, COMPUTE_ARRAY_SIZE_8
1176*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved16_region_tlab, artAllocArrayFromCodeResolvedRegionTLAB, COMPUTE_ARRAY_SIZE_16
1177*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved32_region_tlab, artAllocArrayFromCodeResolvedRegionTLAB, COMPUTE_ARRAY_SIZE_32
1178*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved64_region_tlab, artAllocArrayFromCodeResolvedRegionTLAB, COMPUTE_ARRAY_SIZE_64
1179*795d594fSAndroid Build Coastguard Worker
1180*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved_tlab, artAllocArrayFromCodeResolvedTLAB, COMPUTE_ARRAY_SIZE_UNKNOWN
1181*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved8_tlab, artAllocArrayFromCodeResolvedTLAB, COMPUTE_ARRAY_SIZE_8
1182*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved16_tlab, artAllocArrayFromCodeResolvedTLAB, COMPUTE_ARRAY_SIZE_16
1183*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved32_tlab, artAllocArrayFromCodeResolvedTLAB, COMPUTE_ARRAY_SIZE_32
1184*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved64_tlab, artAllocArrayFromCodeResolvedTLAB, COMPUTE_ARRAY_SIZE_64
1185*795d594fSAndroid Build Coastguard Worker
1186*795d594fSAndroid Build Coastguard WorkerONE_ARG_SAVE_EVERYTHING_DOWNCALL_FOR_CLINIT art_quick_initialize_static_storage, artInitializeStaticStorageFromCode
1187*795d594fSAndroid Build Coastguard WorkerONE_ARG_SAVE_EVERYTHING_DOWNCALL_FOR_CLINIT art_quick_resolve_type, artResolveTypeFromCode
1188*795d594fSAndroid Build Coastguard WorkerONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_resolve_type_and_verify_access, artResolveTypeAndVerifyAccessFromCode
1189*795d594fSAndroid Build Coastguard WorkerONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_resolve_method_handle, artResolveMethodHandleFromCode
1190*795d594fSAndroid Build Coastguard WorkerONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_resolve_method_type, artResolveMethodTypeFromCode
1191*795d594fSAndroid Build Coastguard WorkerONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_resolve_string, artResolveStringFromCode
1192*795d594fSAndroid Build Coastguard Worker
1193*795d594fSAndroid Build Coastguard WorkerTWO_ARG_DOWNCALL art_quick_handle_fill_data, \
1194*795d594fSAndroid Build Coastguard Worker                 artHandleFillArrayDataFromCode, \
1195*795d594fSAndroid Build Coastguard Worker                 RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER
1196*795d594fSAndroid Build Coastguard Worker
1197*795d594fSAndroid Build Coastguard Worker    /*
1198*795d594fSAndroid Build Coastguard Worker     * Entry from managed code that tries to lock the object in a fast path and
1199*795d594fSAndroid Build Coastguard Worker     * calls `artLockObjectFromCode()` for the difficult cases, may block for GC.
1200*795d594fSAndroid Build Coastguard Worker     * EAX holds the possibly null object to lock.
1201*795d594fSAndroid Build Coastguard Worker     */
1202*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION art_quick_lock_object
1203*795d594fSAndroid Build Coastguard Worker    testl %eax, %eax
1204*795d594fSAndroid Build Coastguard Worker    jz   SYMBOL(art_quick_lock_object_no_inline)
1205*795d594fSAndroid Build Coastguard Worker    movl %eax, %ecx                       // Move obj to a different register.
1206*795d594fSAndroid Build Coastguard Worker    LOCK_OBJECT_FAST_PATH ecx, edx, /*saved_eax*/ none, .Llock_object_slow
1207*795d594fSAndroid Build Coastguard Worker.Llock_object_slow:
1208*795d594fSAndroid Build Coastguard Worker    movl %ecx, %eax                       // Move obj back to EAX.
1209*795d594fSAndroid Build Coastguard Worker    jmp  SYMBOL(art_quick_lock_object_no_inline)
1210*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION art_quick_lock_object
1211*795d594fSAndroid Build Coastguard Worker
1212*795d594fSAndroid Build Coastguard Worker    /*
1213*795d594fSAndroid Build Coastguard Worker     * Entry from managed code that calls `artLockObjectFromCode()`, may block for GC.
1214*795d594fSAndroid Build Coastguard Worker     * EAX holds the possibly null object to lock.
1215*795d594fSAndroid Build Coastguard Worker     */
1216*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION art_quick_lock_object_no_inline
1217*795d594fSAndroid Build Coastguard Worker    // This is also the slow path for art_quick_lock_object.
1218*795d594fSAndroid Build Coastguard Worker    SETUP_SAVE_REFS_ONLY_FRAME ebx        // save ref containing registers for GC
1219*795d594fSAndroid Build Coastguard Worker    // Outgoing argument set up
1220*795d594fSAndroid Build Coastguard Worker    INCREASE_FRAME 8                      // alignment padding
1221*795d594fSAndroid Build Coastguard Worker    pushl %fs:THREAD_SELF_OFFSET          // pass Thread::Current()
1222*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
1223*795d594fSAndroid Build Coastguard Worker    PUSH_ARG eax                          // pass object
1224*795d594fSAndroid Build Coastguard Worker    call SYMBOL(artLockObjectFromCode)    // artLockObjectFromCode(object, Thread*)
1225*795d594fSAndroid Build Coastguard Worker    DECREASE_FRAME 16                     // pop arguments
1226*795d594fSAndroid Build Coastguard Worker    RESTORE_SAVE_REFS_ONLY_FRAME          // restore frame up to return address
1227*795d594fSAndroid Build Coastguard Worker    RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER
1228*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION art_quick_lock_object_no_inline
1229*795d594fSAndroid Build Coastguard Worker
1230*795d594fSAndroid Build Coastguard Worker    /*
1231*795d594fSAndroid Build Coastguard Worker     * Entry from managed code that tries to unlock the object in a fast path and calls
1232*795d594fSAndroid Build Coastguard Worker     * `artUnlockObjectFromCode()` for the difficult cases and delivers exception on failure.
1233*795d594fSAndroid Build Coastguard Worker     * EAX holds the possibly null object to unlock.
1234*795d594fSAndroid Build Coastguard Worker     */
1235*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION art_quick_unlock_object
1236*795d594fSAndroid Build Coastguard Worker    testl %eax, %eax
1237*795d594fSAndroid Build Coastguard Worker    jz   SYMBOL(art_quick_unlock_object_no_inline)
1238*795d594fSAndroid Build Coastguard Worker    movl %eax, %ecx                       // Move obj to a different register.
1239*795d594fSAndroid Build Coastguard Worker    UNLOCK_OBJECT_FAST_PATH ecx, edx, /*saved_eax*/ none, .Lunlock_object_slow
1240*795d594fSAndroid Build Coastguard Worker.Lunlock_object_slow:
1241*795d594fSAndroid Build Coastguard Worker    movl %ecx, %eax                       // Move obj back to EAX.
1242*795d594fSAndroid Build Coastguard Worker    jmp  SYMBOL(art_quick_unlock_object_no_inline)
1243*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION art_quick_unlock_object
1244*795d594fSAndroid Build Coastguard Worker
1245*795d594fSAndroid Build Coastguard Worker    /*
1246*795d594fSAndroid Build Coastguard Worker     * Entry from managed code that calls `artUnlockObjectFromCode()`
1247*795d594fSAndroid Build Coastguard Worker     * and delivers exception on failure.
1248*795d594fSAndroid Build Coastguard Worker     * EAX holds the possibly null object to unlock.
1249*795d594fSAndroid Build Coastguard Worker     */
1250*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION art_quick_unlock_object_no_inline
1251*795d594fSAndroid Build Coastguard Worker    // This is also the slow path for art_quick_unlock_object.
1252*795d594fSAndroid Build Coastguard Worker    SETUP_SAVE_REFS_ONLY_FRAME ebx        // save ref containing registers for GC
1253*795d594fSAndroid Build Coastguard Worker    // Outgoing argument set up
1254*795d594fSAndroid Build Coastguard Worker    INCREASE_FRAME 8                      // alignment padding
1255*795d594fSAndroid Build Coastguard Worker    pushl %fs:THREAD_SELF_OFFSET          // pass Thread::Current()
1256*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
1257*795d594fSAndroid Build Coastguard Worker    PUSH_ARG eax                          // pass object
1258*795d594fSAndroid Build Coastguard Worker    call SYMBOL(artUnlockObjectFromCode)  // artUnlockObjectFromCode(object, Thread*)
1259*795d594fSAndroid Build Coastguard Worker    DECREASE_FRAME 16                     // pop arguments
1260*795d594fSAndroid Build Coastguard Worker    RESTORE_SAVE_REFS_ONLY_FRAME          // restore frame up to return address
1261*795d594fSAndroid Build Coastguard Worker    RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER
1262*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION art_quick_unlock_object_no_inline
1263*795d594fSAndroid Build Coastguard Worker
1264*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION art_quick_instance_of
1265*795d594fSAndroid Build Coastguard Worker    PUSH eax                              // alignment padding
1266*795d594fSAndroid Build Coastguard Worker    PUSH ecx                              // pass arg2 - obj->klass
1267*795d594fSAndroid Build Coastguard Worker    PUSH eax                              // pass arg1 - checked class
1268*795d594fSAndroid Build Coastguard Worker    call SYMBOL(artInstanceOfFromCode)    // (Object* obj, Class* ref_klass)
1269*795d594fSAndroid Build Coastguard Worker    addl LITERAL(12), %esp                // pop arguments
1270*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(-12)
1271*795d594fSAndroid Build Coastguard Worker    ret
1272*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION art_quick_instance_of
1273*795d594fSAndroid Build Coastguard Worker
1274*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION art_quick_check_instance_of
1275*795d594fSAndroid Build Coastguard Worker    // Type check using the bit string passes null as the target class. In that case just throw.
1276*795d594fSAndroid Build Coastguard Worker    testl %ecx, %ecx
1277*795d594fSAndroid Build Coastguard Worker    jz .Lthrow_class_cast_exception_for_bitstring_check
1278*795d594fSAndroid Build Coastguard Worker
1279*795d594fSAndroid Build Coastguard Worker    PUSH eax                              // alignment padding
1280*795d594fSAndroid Build Coastguard Worker    PUSH ecx                              // pass arg2 - checked class
1281*795d594fSAndroid Build Coastguard Worker    PUSH eax                              // pass arg1 - obj
1282*795d594fSAndroid Build Coastguard Worker    call SYMBOL(artInstanceOfFromCode)    // (Object* obj, Class* ref_klass)
1283*795d594fSAndroid Build Coastguard Worker    testl %eax, %eax
1284*795d594fSAndroid Build Coastguard Worker    jz .Lthrow_class_cast_exception       // jump forward if not assignable
1285*795d594fSAndroid Build Coastguard Worker    addl LITERAL(12), %esp                // pop arguments
1286*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(-12)
1287*795d594fSAndroid Build Coastguard Worker    ret
1288*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(12)             // Reset unwind info so following code unwinds.
1289*795d594fSAndroid Build Coastguard Worker
1290*795d594fSAndroid Build Coastguard Worker.Lthrow_class_cast_exception:
1291*795d594fSAndroid Build Coastguard Worker    POP eax                               // pop arguments
1292*795d594fSAndroid Build Coastguard Worker    POP ecx
1293*795d594fSAndroid Build Coastguard Worker    addl LITERAL(4), %esp
1294*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(-4)
1295*795d594fSAndroid Build Coastguard Worker
1296*795d594fSAndroid Build Coastguard Worker.Lthrow_class_cast_exception_for_bitstring_check:
1297*795d594fSAndroid Build Coastguard Worker    SETUP_SAVE_ALL_CALLEE_SAVES_FRAME ebx // save all registers as basis for long jump context
1298*795d594fSAndroid Build Coastguard Worker    // Outgoing argument set up
1299*795d594fSAndroid Build Coastguard Worker    PUSH eax                              // alignment padding
1300*795d594fSAndroid Build Coastguard Worker    pushl %fs:THREAD_SELF_OFFSET          // pass Thread::Current()
1301*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
1302*795d594fSAndroid Build Coastguard Worker    PUSH ecx                              // pass arg2
1303*795d594fSAndroid Build Coastguard Worker    PUSH eax                              // pass arg1
1304*795d594fSAndroid Build Coastguard Worker    call SYMBOL(artThrowClassCastExceptionForObject)  // (Object* src, Class* dest, Thread*)
1305*795d594fSAndroid Build Coastguard Worker    call SYMBOL(art_quick_do_long_jump)
1306*795d594fSAndroid Build Coastguard Worker    UNREACHABLE
1307*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION art_quick_check_instance_of
1308*795d594fSAndroid Build Coastguard Worker
1309*795d594fSAndroid Build Coastguard Worker// Restore reg's value if reg is not the same as exclude_reg, otherwise just adjust stack.
1310*795d594fSAndroid Build Coastguard WorkerMACRO2(POP_REG_NE, reg, exclude_reg)
1311*795d594fSAndroid Build Coastguard Worker    .ifc RAW_VAR(reg), RAW_VAR(exclude_reg)
1312*795d594fSAndroid Build Coastguard Worker      DECREASE_FRAME 4
1313*795d594fSAndroid Build Coastguard Worker    .else
1314*795d594fSAndroid Build Coastguard Worker      POP RAW_VAR(reg)
1315*795d594fSAndroid Build Coastguard Worker    .endif
1316*795d594fSAndroid Build Coastguard WorkerEND_MACRO
1317*795d594fSAndroid Build Coastguard Worker
1318*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION art_quick_aput_obj
1319*795d594fSAndroid Build Coastguard Worker    test %edx, %edx              // store of null
1320*795d594fSAndroid Build Coastguard Worker    jz .Laput_obj_null
1321*795d594fSAndroid Build Coastguard Worker    movl MIRROR_OBJECT_CLASS_OFFSET(%eax), %ebx
1322*795d594fSAndroid Build Coastguard Worker    UNPOISON_HEAP_REF ebx
1323*795d594fSAndroid Build Coastguard Worker#ifdef USE_READ_BARRIER
1324*795d594fSAndroid Build Coastguard Worker    cmpl LITERAL(0), %fs:THREAD_IS_GC_MARKING_OFFSET
1325*795d594fSAndroid Build Coastguard Worker    CFI_REMEMBER_STATE
1326*795d594fSAndroid Build Coastguard Worker    jnz .Laput_obj_gc_marking
1327*795d594fSAndroid Build Coastguard Worker#endif  // USE_READ_BARRIER
1328*795d594fSAndroid Build Coastguard Worker    movl MIRROR_CLASS_COMPONENT_TYPE_OFFSET(%ebx), %ebx
1329*795d594fSAndroid Build Coastguard Worker    cmpl MIRROR_OBJECT_CLASS_OFFSET(%edx), %ebx  // Both poisoned if heap poisoning is enabled.
1330*795d594fSAndroid Build Coastguard Worker    jne .Laput_obj_check_assignability
1331*795d594fSAndroid Build Coastguard Worker.Laput_obj_store:
1332*795d594fSAndroid Build Coastguard Worker    POISON_HEAP_REF edx
1333*795d594fSAndroid Build Coastguard Worker    movl %edx, MIRROR_OBJECT_ARRAY_DATA_OFFSET(%eax, %ecx, 4)
1334*795d594fSAndroid Build Coastguard Worker    movl %fs:THREAD_CARD_TABLE_OFFSET, %edx
1335*795d594fSAndroid Build Coastguard Worker    shrl LITERAL(CARD_TABLE_CARD_SHIFT), %eax
1336*795d594fSAndroid Build Coastguard Worker    movb %dl, (%edx, %eax)
1337*795d594fSAndroid Build Coastguard Worker    ret
1338*795d594fSAndroid Build Coastguard Worker
1339*795d594fSAndroid Build Coastguard Worker.Laput_obj_null:
1340*795d594fSAndroid Build Coastguard Worker    movl %edx, MIRROR_OBJECT_ARRAY_DATA_OFFSET(%eax, %ecx, 4)
1341*795d594fSAndroid Build Coastguard Worker    ret
1342*795d594fSAndroid Build Coastguard Worker
1343*795d594fSAndroid Build Coastguard Worker.Laput_obj_check_assignability:
1344*795d594fSAndroid Build Coastguard Worker    UNPOISON_HEAP_REF ebx         // Unpoison array component type if poisoning is enabled.
1345*795d594fSAndroid Build Coastguard Worker    PUSH_ARG eax                  // Save `art_quick_aput_obj()` arguments.
1346*795d594fSAndroid Build Coastguard Worker    PUSH_ARG ecx
1347*795d594fSAndroid Build Coastguard Worker    PUSH_ARG edx
1348*795d594fSAndroid Build Coastguard Worker    INCREASE_FRAME 8              // Alignment padding.
1349*795d594fSAndroid Build Coastguard Worker    // Pass arg2 - type of the value to be stored.
1350*795d594fSAndroid Build Coastguard Worker#if defined(USE_HEAP_POISONING)
1351*795d594fSAndroid Build Coastguard Worker    movl MIRROR_OBJECT_CLASS_OFFSET(%edx), %eax
1352*795d594fSAndroid Build Coastguard Worker    UNPOISON_HEAP_REF eax
1353*795d594fSAndroid Build Coastguard Worker    PUSH_ARG eax
1354*795d594fSAndroid Build Coastguard Worker#else
1355*795d594fSAndroid Build Coastguard Worker    pushl MIRROR_OBJECT_CLASS_OFFSET(%edx)
1356*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
1357*795d594fSAndroid Build Coastguard Worker#endif
1358*795d594fSAndroid Build Coastguard Worker.Laput_obj_check_assignability_call:
1359*795d594fSAndroid Build Coastguard Worker    PUSH_ARG ebx                  // Pass arg1 - component type of the array.
1360*795d594fSAndroid Build Coastguard Worker    call SYMBOL(artIsAssignableFromCode)  // (Class* a, Class* b)
1361*795d594fSAndroid Build Coastguard Worker    DECREASE_FRAME 16             // Pop `artIsAssignableFromCode()` arguments
1362*795d594fSAndroid Build Coastguard Worker    testl %eax, %eax
1363*795d594fSAndroid Build Coastguard Worker    POP_ARG edx                   // Pop `art_quick_aput_obj()` arguments; flags unaffected.
1364*795d594fSAndroid Build Coastguard Worker    POP_ARG ecx
1365*795d594fSAndroid Build Coastguard Worker    POP_ARG eax
1366*795d594fSAndroid Build Coastguard Worker    jz   .Lthrow_array_store_exception
1367*795d594fSAndroid Build Coastguard Worker    POISON_HEAP_REF edx
1368*795d594fSAndroid Build Coastguard Worker    movl %edx, MIRROR_OBJECT_ARRAY_DATA_OFFSET(%eax, %ecx, 4)  // Do the aput.
1369*795d594fSAndroid Build Coastguard Worker    movl %fs:THREAD_CARD_TABLE_OFFSET, %edx
1370*795d594fSAndroid Build Coastguard Worker    shrl LITERAL(CARD_TABLE_CARD_SHIFT), %eax
1371*795d594fSAndroid Build Coastguard Worker    movb %dl, (%edx, %eax)
1372*795d594fSAndroid Build Coastguard Worker    ret
1373*795d594fSAndroid Build Coastguard Worker
1374*795d594fSAndroid Build Coastguard Worker.Lthrow_array_store_exception:
1375*795d594fSAndroid Build Coastguard Worker    SETUP_SAVE_ALL_CALLEE_SAVES_FRAME ebx // Save all registers as basis for long jump context.
1376*795d594fSAndroid Build Coastguard Worker    // Outgoing argument set up.
1377*795d594fSAndroid Build Coastguard Worker    PUSH_ARG eax                  // Alignment padding.
1378*795d594fSAndroid Build Coastguard Worker    PUSH_ARG fs:THREAD_SELF_OFFSET  // Pass Thread::Current()
1379*795d594fSAndroid Build Coastguard Worker    PUSH_ARG edx                  // Pass arg2 - value.
1380*795d594fSAndroid Build Coastguard Worker    PUSH_ARG eax                  // Pass arg1 - array.
1381*795d594fSAndroid Build Coastguard Worker    call SYMBOL(artThrowArrayStoreException) // (array, value, Thread*)
1382*795d594fSAndroid Build Coastguard Worker    call SYMBOL(art_quick_do_long_jump)
1383*795d594fSAndroid Build Coastguard Worker    UNREACHABLE
1384*795d594fSAndroid Build Coastguard Worker
1385*795d594fSAndroid Build Coastguard Worker#ifdef USE_READ_BARRIER
1386*795d594fSAndroid Build Coastguard Worker.Laput_obj_gc_marking:
1387*795d594fSAndroid Build Coastguard Worker    CFI_RESTORE_STATE_AND_DEF_CFA esp, 4
1388*795d594fSAndroid Build Coastguard Worker    PUSH_ARG eax                  // Save `art_quick_aput_obj()` arguments.
1389*795d594fSAndroid Build Coastguard Worker    PUSH_ARG ecx                  // We need to align stack for `art_quick_read_barrier_mark_regNN`
1390*795d594fSAndroid Build Coastguard Worker    PUSH_ARG edx                  // and use a register (EAX) as a temporary for the object class.
1391*795d594fSAndroid Build Coastguard Worker    call SYMBOL(art_quick_read_barrier_mark_reg03)  // Mark EBX.
1392*795d594fSAndroid Build Coastguard Worker    movl MIRROR_CLASS_COMPONENT_TYPE_OFFSET(%ebx), %ebx
1393*795d594fSAndroid Build Coastguard Worker    UNPOISON_HEAP_REF ebx
1394*795d594fSAndroid Build Coastguard Worker    call SYMBOL(art_quick_read_barrier_mark_reg03)  // Mark EBX.
1395*795d594fSAndroid Build Coastguard Worker    movl MIRROR_OBJECT_CLASS_OFFSET(%edx), %eax
1396*795d594fSAndroid Build Coastguard Worker    UNPOISON_HEAP_REF eax
1397*795d594fSAndroid Build Coastguard Worker    call SYMBOL(art_quick_read_barrier_mark_reg00)  // Mark EAX.
1398*795d594fSAndroid Build Coastguard Worker    cmpl %eax, %ebx
1399*795d594fSAndroid Build Coastguard Worker    CFI_REMEMBER_STATE
1400*795d594fSAndroid Build Coastguard Worker    jne .Laput_obj_check_assignability_gc_marking
1401*795d594fSAndroid Build Coastguard Worker    POP_ARG edx                   // Restore `art_quick_aput_obj()` arguments.
1402*795d594fSAndroid Build Coastguard Worker    POP_ARG ecx
1403*795d594fSAndroid Build Coastguard Worker    POP_ARG eax
1404*795d594fSAndroid Build Coastguard Worker    jmp .Laput_obj_store
1405*795d594fSAndroid Build Coastguard Worker
1406*795d594fSAndroid Build Coastguard Worker.Laput_obj_check_assignability_gc_marking:
1407*795d594fSAndroid Build Coastguard Worker    CFI_RESTORE_STATE_AND_DEF_CFA esp, 16
1408*795d594fSAndroid Build Coastguard Worker    // Prepare arguments in line with `.Laput_obj_check_assignability_call` and jump there.
1409*795d594fSAndroid Build Coastguard Worker    // (EAX, ECX and EDX were already saved in the right stack slots.)
1410*795d594fSAndroid Build Coastguard Worker    INCREASE_FRAME 8              // Alignment padding.
1411*795d594fSAndroid Build Coastguard Worker    PUSH_ARG eax                  // Pass arg2 - type of the value to be stored.
1412*795d594fSAndroid Build Coastguard Worker    // The arg1 shall be pushed at `.Laput_obj_check_assignability_call`.
1413*795d594fSAndroid Build Coastguard Worker    jmp .Laput_obj_check_assignability_call
1414*795d594fSAndroid Build Coastguard Worker#endif  // USE_READ_BARRIER
1415*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION art_quick_aput_obj
1416*795d594fSAndroid Build Coastguard Worker
1417*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION art_quick_memcpy
1418*795d594fSAndroid Build Coastguard Worker    PUSH edx                      // pass arg3
1419*795d594fSAndroid Build Coastguard Worker    PUSH ecx                      // pass arg2
1420*795d594fSAndroid Build Coastguard Worker    PUSH eax                      // pass arg1
1421*795d594fSAndroid Build Coastguard Worker    // PLT call requires EBX initialized to the $_GLOBAL_OFFSET_TABLE_.
1422*795d594fSAndroid Build Coastguard Worker    SETUP_PC_REL_BASE_0 ebx
1423*795d594fSAndroid Build Coastguard Worker1:
1424*795d594fSAndroid Build Coastguard Worker    addl $_GLOBAL_OFFSET_TABLE_ + (1b - 0b), %ebx
1425*795d594fSAndroid Build Coastguard Worker    call PLT_SYMBOL(memcpy)       // (void*, const void*, size_t)
1426*795d594fSAndroid Build Coastguard Worker    addl LITERAL(12), %esp        // pop arguments
1427*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(-12)
1428*795d594fSAndroid Build Coastguard Worker    ret
1429*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION art_quick_memcpy
1430*795d594fSAndroid Build Coastguard Worker
1431*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION art_quick_test_suspend
1432*795d594fSAndroid Build Coastguard Worker    SETUP_SAVE_EVERYTHING_FRAME ebx, RUNTIME_SAVE_EVERYTHING_FOR_SUSPEND_CHECK_METHOD_OFFSET  // save everything for GC
1433*795d594fSAndroid Build Coastguard Worker    // Outgoing argument set up
1434*795d594fSAndroid Build Coastguard Worker    INCREASE_FRAME 12                                 // push padding
1435*795d594fSAndroid Build Coastguard Worker    pushl %fs:THREAD_SELF_OFFSET                      // pass Thread::Current()
1436*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
1437*795d594fSAndroid Build Coastguard Worker    call SYMBOL(artTestSuspendFromCode)               // (Thread*)
1438*795d594fSAndroid Build Coastguard Worker    DECREASE_FRAME 16                                 // pop arguments
1439*795d594fSAndroid Build Coastguard Worker
1440*795d594fSAndroid Build Coastguard Worker    CFI_REMEMBER_STATE
1441*795d594fSAndroid Build Coastguard Worker    testl %eax, %eax
1442*795d594fSAndroid Build Coastguard Worker    jnz .Ltest_suspend_deoptimize
1443*795d594fSAndroid Build Coastguard Worker
1444*795d594fSAndroid Build Coastguard Worker    RESTORE_SAVE_EVERYTHING_FRAME                     // restore frame up to return address
1445*795d594fSAndroid Build Coastguard Worker    ret                                               // return
1446*795d594fSAndroid Build Coastguard Worker
1447*795d594fSAndroid Build Coastguard Worker.Ltest_suspend_deoptimize:
1448*795d594fSAndroid Build Coastguard Worker    // Deoptimize
1449*795d594fSAndroid Build Coastguard Worker    CFI_RESTORE_STATE_AND_DEF_CFA esp, FRAME_SIZE_SAVE_EVERYTHING
1450*795d594fSAndroid Build Coastguard Worker    call SYMBOL(art_quick_do_long_jump)
1451*795d594fSAndroid Build Coastguard Worker    UNREACHABLE
1452*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION art_quick_test_suspend
1453*795d594fSAndroid Build Coastguard Worker
1454*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION art_quick_d2l
1455*795d594fSAndroid Build Coastguard Worker    subl LITERAL(12), %esp        // alignment padding, room for argument
1456*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(12)
1457*795d594fSAndroid Build Coastguard Worker    movsd %xmm0, 0(%esp)          // arg a
1458*795d594fSAndroid Build Coastguard Worker    call SYMBOL(art_d2l)          // (jdouble a)
1459*795d594fSAndroid Build Coastguard Worker    addl LITERAL(12), %esp        // pop arguments
1460*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(-12)
1461*795d594fSAndroid Build Coastguard Worker    ret
1462*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION art_quick_d2l
1463*795d594fSAndroid Build Coastguard Worker
1464*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION art_quick_f2l
1465*795d594fSAndroid Build Coastguard Worker    subl LITERAL(12), %esp        // alignment padding
1466*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(12)
1467*795d594fSAndroid Build Coastguard Worker    movss %xmm0, 0(%esp)          // arg a
1468*795d594fSAndroid Build Coastguard Worker    call SYMBOL(art_f2l)          // (jfloat a)
1469*795d594fSAndroid Build Coastguard Worker    addl LITERAL(12), %esp        // pop arguments
1470*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(-12)
1471*795d594fSAndroid Build Coastguard Worker    ret
1472*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION art_quick_f2l
1473*795d594fSAndroid Build Coastguard Worker
1474*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION art_quick_ldiv
1475*795d594fSAndroid Build Coastguard Worker    subl LITERAL(12), %esp        // alignment padding
1476*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(12)
1477*795d594fSAndroid Build Coastguard Worker    PUSH ebx                      // pass arg4 b.hi
1478*795d594fSAndroid Build Coastguard Worker    PUSH edx                      // pass arg3 b.lo
1479*795d594fSAndroid Build Coastguard Worker    PUSH ecx                      // pass arg2 a.hi
1480*795d594fSAndroid Build Coastguard Worker    PUSH eax                      // pass arg1 a.lo
1481*795d594fSAndroid Build Coastguard Worker    call SYMBOL(artLdiv)          // (jlong a, jlong b)
1482*795d594fSAndroid Build Coastguard Worker    addl LITERAL(28), %esp        // pop arguments
1483*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(-28)
1484*795d594fSAndroid Build Coastguard Worker    ret
1485*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION art_quick_ldiv
1486*795d594fSAndroid Build Coastguard Worker
1487*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION art_quick_lmod
1488*795d594fSAndroid Build Coastguard Worker    subl LITERAL(12), %esp        // alignment padding
1489*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(12)
1490*795d594fSAndroid Build Coastguard Worker    PUSH ebx                      // pass arg4 b.hi
1491*795d594fSAndroid Build Coastguard Worker    PUSH edx                      // pass arg3 b.lo
1492*795d594fSAndroid Build Coastguard Worker    PUSH ecx                      // pass arg2 a.hi
1493*795d594fSAndroid Build Coastguard Worker    PUSH eax                      // pass arg1 a.lo
1494*795d594fSAndroid Build Coastguard Worker    call SYMBOL(artLmod)          // (jlong a, jlong b)
1495*795d594fSAndroid Build Coastguard Worker    addl LITERAL(28), %esp        // pop arguments
1496*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(-28)
1497*795d594fSAndroid Build Coastguard Worker    ret
1498*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION art_quick_lmod
1499*795d594fSAndroid Build Coastguard Worker
1500*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION art_quick_lmul
1501*795d594fSAndroid Build Coastguard Worker    imul %eax, %ebx               // ebx = a.lo(eax) * b.hi(ebx)
1502*795d594fSAndroid Build Coastguard Worker    imul %edx, %ecx               // ecx = b.lo(edx) * a.hi(ecx)
1503*795d594fSAndroid Build Coastguard Worker    mul  %edx                     // edx:eax = a.lo(eax) * b.lo(edx)
1504*795d594fSAndroid Build Coastguard Worker    add  %ebx, %ecx
1505*795d594fSAndroid Build Coastguard Worker    add  %ecx, %edx               // edx += (a.lo * b.hi) + (b.lo * a.hi)
1506*795d594fSAndroid Build Coastguard Worker    ret
1507*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION art_quick_lmul
1508*795d594fSAndroid Build Coastguard Worker
1509*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION art_quick_lshl
1510*795d594fSAndroid Build Coastguard Worker    // ecx:eax << edx
1511*795d594fSAndroid Build Coastguard Worker    xchg %edx, %ecx
1512*795d594fSAndroid Build Coastguard Worker    shld %cl,%eax,%edx
1513*795d594fSAndroid Build Coastguard Worker    shl  %cl,%eax
1514*795d594fSAndroid Build Coastguard Worker    test LITERAL(32), %cl
1515*795d594fSAndroid Build Coastguard Worker    jz  1f
1516*795d594fSAndroid Build Coastguard Worker    mov %eax, %edx
1517*795d594fSAndroid Build Coastguard Worker    xor %eax, %eax
1518*795d594fSAndroid Build Coastguard Worker1:
1519*795d594fSAndroid Build Coastguard Worker    ret
1520*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION art_quick_lshl
1521*795d594fSAndroid Build Coastguard Worker
1522*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION art_quick_lshr
1523*795d594fSAndroid Build Coastguard Worker    // ecx:eax >> edx
1524*795d594fSAndroid Build Coastguard Worker    xchg %edx, %ecx
1525*795d594fSAndroid Build Coastguard Worker    shrd %cl,%edx,%eax
1526*795d594fSAndroid Build Coastguard Worker    sar  %cl,%edx
1527*795d594fSAndroid Build Coastguard Worker    test LITERAL(32),%cl
1528*795d594fSAndroid Build Coastguard Worker    jz  1f
1529*795d594fSAndroid Build Coastguard Worker    mov %edx, %eax
1530*795d594fSAndroid Build Coastguard Worker    sar LITERAL(31), %edx
1531*795d594fSAndroid Build Coastguard Worker1:
1532*795d594fSAndroid Build Coastguard Worker    ret
1533*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION art_quick_lshr
1534*795d594fSAndroid Build Coastguard Worker
1535*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION art_quick_lushr
1536*795d594fSAndroid Build Coastguard Worker    // ecx:eax >>> edx
1537*795d594fSAndroid Build Coastguard Worker    xchg %edx, %ecx
1538*795d594fSAndroid Build Coastguard Worker    shrd %cl,%edx,%eax
1539*795d594fSAndroid Build Coastguard Worker    shr  %cl,%edx
1540*795d594fSAndroid Build Coastguard Worker    test LITERAL(32),%cl
1541*795d594fSAndroid Build Coastguard Worker    jz  1f
1542*795d594fSAndroid Build Coastguard Worker    mov %edx, %eax
1543*795d594fSAndroid Build Coastguard Worker    xor %edx, %edx
1544*795d594fSAndroid Build Coastguard Worker1:
1545*795d594fSAndroid Build Coastguard Worker    ret
1546*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION art_quick_lushr
1547*795d594fSAndroid Build Coastguard Worker
1548*795d594fSAndroid Build Coastguard WorkerGENERATE_STATIC_FIELD_GETTERS
1549*795d594fSAndroid Build Coastguard Worker
1550*795d594fSAndroid Build Coastguard WorkerGENERATE_INSTANCE_FIELD_GETTERS
1551*795d594fSAndroid Build Coastguard Worker
1552*795d594fSAndroid Build Coastguard WorkerGENERATE_STATIC_FIELD_SETTERS /*emit64=*/0
1553*795d594fSAndroid Build Coastguard Worker
1554*795d594fSAndroid Build Coastguard WorkerTHREE_ARG_DOWNCALL art_quick_set64_static, \
1555*795d594fSAndroid Build Coastguard Worker                   artSet64StaticFromCompiledCode, \
1556*795d594fSAndroid Build Coastguard Worker                   RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER
1557*795d594fSAndroid Build Coastguard Worker
1558*795d594fSAndroid Build Coastguard WorkerGENERATE_INSTANCE_FIELD_SETTERS /*emit64=*/0
1559*795d594fSAndroid Build Coastguard Worker
1560*795d594fSAndroid Build Coastguard Worker// Call artSet64InstanceFromCode with 4 word size arguments.
1561*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION art_quick_set64_instance
1562*795d594fSAndroid Build Coastguard Worker    movd %ebx, %xmm0
1563*795d594fSAndroid Build Coastguard Worker    SETUP_SAVE_REFS_ONLY_FRAME ebx  // save ref containing registers for GC
1564*795d594fSAndroid Build Coastguard Worker    movd %xmm0, %ebx
1565*795d594fSAndroid Build Coastguard Worker    // Outgoing argument set up
1566*795d594fSAndroid Build Coastguard Worker    subl LITERAL(12), %esp         // alignment padding
1567*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(12)
1568*795d594fSAndroid Build Coastguard Worker    pushl %fs:THREAD_SELF_OFFSET  // pass Thread::Current()
1569*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
1570*795d594fSAndroid Build Coastguard Worker    PUSH ebx                      // pass high half of new_val
1571*795d594fSAndroid Build Coastguard Worker    PUSH edx                      // pass low half of new_val
1572*795d594fSAndroid Build Coastguard Worker    PUSH ecx                      // pass object
1573*795d594fSAndroid Build Coastguard Worker    PUSH eax                      // pass field_idx
1574*795d594fSAndroid Build Coastguard Worker    call SYMBOL(artSet64InstanceFromCompiledCode)  // (field_idx, Object*, new_val, Thread*)
1575*795d594fSAndroid Build Coastguard Worker    addl LITERAL(32), %esp        // pop arguments
1576*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(-32)
1577*795d594fSAndroid Build Coastguard Worker    RESTORE_SAVE_REFS_ONLY_FRAME  // restore frame up to return address
1578*795d594fSAndroid Build Coastguard Worker    RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER  // return or deliver exception
1579*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION art_quick_set64_instance
1580*795d594fSAndroid Build Coastguard Worker
1581*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION art_quick_proxy_invoke_handler
1582*795d594fSAndroid Build Coastguard Worker    SETUP_SAVE_REFS_AND_ARGS_FRAME_WITH_METHOD_IN_EAX
1583*795d594fSAndroid Build Coastguard Worker    PUSH esp                      // pass SP
1584*795d594fSAndroid Build Coastguard Worker    pushl %fs:THREAD_SELF_OFFSET  // pass Thread::Current()
1585*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
1586*795d594fSAndroid Build Coastguard Worker    PUSH ecx                      // pass receiver
1587*795d594fSAndroid Build Coastguard Worker    PUSH eax                      // pass proxy method
1588*795d594fSAndroid Build Coastguard Worker    call SYMBOL(artQuickProxyInvokeHandler) // (proxy method, receiver, Thread*, SP)
1589*795d594fSAndroid Build Coastguard Worker    movd %eax, %xmm0              // place return value also into floating point return value
1590*795d594fSAndroid Build Coastguard Worker    movd %edx, %xmm1
1591*795d594fSAndroid Build Coastguard Worker    punpckldq %xmm1, %xmm0
1592*795d594fSAndroid Build Coastguard Worker    addl LITERAL(16 + FRAME_SIZE_SAVE_REFS_AND_ARGS - FRAME_SIZE_SAVE_REFS_ONLY), %esp
1593*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(-(16 + FRAME_SIZE_SAVE_REFS_AND_ARGS - FRAME_SIZE_SAVE_REFS_ONLY))
1594*795d594fSAndroid Build Coastguard Worker    RESTORE_SAVE_REFS_ONLY_FRAME
1595*795d594fSAndroid Build Coastguard Worker    RETURN_OR_DELIVER_PENDING_EXCEPTION    // return or deliver exception
1596*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION art_quick_proxy_invoke_handler
1597*795d594fSAndroid Build Coastguard Worker
1598*795d594fSAndroid Build Coastguard Worker    /*
1599*795d594fSAndroid Build Coastguard Worker     * Called to resolve an imt conflict.
1600*795d594fSAndroid Build Coastguard Worker     * eax is the conflict ArtMethod.
1601*795d594fSAndroid Build Coastguard Worker     * xmm7 is a hidden argument that holds the target interface method.
1602*795d594fSAndroid Build Coastguard Worker     *
1603*795d594fSAndroid Build Coastguard Worker     * Note that this stub writes to eax.
1604*795d594fSAndroid Build Coastguard Worker     * Because of lack of free registers, it also saves and restores esi.
1605*795d594fSAndroid Build Coastguard Worker     */
1606*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION art_quick_imt_conflict_trampoline
1607*795d594fSAndroid Build Coastguard Worker    PUSH ESI
1608*795d594fSAndroid Build Coastguard Worker    movd %xmm7, %esi            // Get target method index stored in xmm7, remember it in ESI.
1609*795d594fSAndroid Build Coastguard Worker    movl ART_METHOD_JNI_OFFSET_32(%eax), %eax  // Load ImtConflictTable.
1610*795d594fSAndroid Build Coastguard Worker.Limt_table_iterate:
1611*795d594fSAndroid Build Coastguard Worker    cmpl %esi, 0(%eax)
1612*795d594fSAndroid Build Coastguard Worker    CFI_REMEMBER_STATE
1613*795d594fSAndroid Build Coastguard Worker    jne .Limt_table_next_entry
1614*795d594fSAndroid Build Coastguard Worker    // We successfully hit an entry in the table. Load the target method
1615*795d594fSAndroid Build Coastguard Worker    // and jump to it.
1616*795d594fSAndroid Build Coastguard Worker    movl __SIZEOF_POINTER__(%eax), %eax
1617*795d594fSAndroid Build Coastguard Worker    POP ESI
1618*795d594fSAndroid Build Coastguard Worker    jmp *ART_METHOD_QUICK_CODE_OFFSET_32(%eax)
1619*795d594fSAndroid Build Coastguard Worker.Limt_table_next_entry:
1620*795d594fSAndroid Build Coastguard Worker    CFI_RESTORE_STATE_AND_DEF_CFA esp, 8
1621*795d594fSAndroid Build Coastguard Worker    // If the entry is null, the interface method is not in the ImtConflictTable.
1622*795d594fSAndroid Build Coastguard Worker    cmpl LITERAL(0), 0(%eax)
1623*795d594fSAndroid Build Coastguard Worker    jz .Lconflict_trampoline
1624*795d594fSAndroid Build Coastguard Worker    // Iterate over the entries of the ImtConflictTable.
1625*795d594fSAndroid Build Coastguard Worker    addl LITERAL(2 * __SIZEOF_POINTER__), %eax
1626*795d594fSAndroid Build Coastguard Worker    jmp .Limt_table_iterate
1627*795d594fSAndroid Build Coastguard Worker.Lconflict_trampoline:
1628*795d594fSAndroid Build Coastguard Worker    // Call the runtime stub to populate the ImtConflictTable and jump to the
1629*795d594fSAndroid Build Coastguard Worker    // resolved method.
1630*795d594fSAndroid Build Coastguard Worker    // Pass the interface method in first argument.
1631*795d594fSAndroid Build Coastguard Worker    movl %esi, %eax
1632*795d594fSAndroid Build Coastguard Worker    POP ESI
1633*795d594fSAndroid Build Coastguard Worker    INVOKE_TRAMPOLINE_BODY artInvokeInterfaceTrampoline
1634*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION art_quick_imt_conflict_trampoline
1635*795d594fSAndroid Build Coastguard Worker
1636*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION art_quick_resolution_trampoline
1637*795d594fSAndroid Build Coastguard Worker    SETUP_SAVE_REFS_AND_ARGS_FRAME ebx
1638*795d594fSAndroid Build Coastguard Worker    movl %esp, %edi
1639*795d594fSAndroid Build Coastguard Worker    PUSH EDI                      // pass SP. do not just PUSH ESP; that messes up unwinding
1640*795d594fSAndroid Build Coastguard Worker    pushl %fs:THREAD_SELF_OFFSET  // pass Thread::Current()
1641*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
1642*795d594fSAndroid Build Coastguard Worker    PUSH ecx                      // pass receiver
1643*795d594fSAndroid Build Coastguard Worker    PUSH eax                      // pass method
1644*795d594fSAndroid Build Coastguard Worker    call SYMBOL(artQuickResolutionTrampoline) // (Method* called, receiver, Thread*, SP)
1645*795d594fSAndroid Build Coastguard Worker    movl %eax, %edi               // remember code pointer in EDI
1646*795d594fSAndroid Build Coastguard Worker    addl LITERAL(16), %esp        // pop arguments
1647*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(-16)
1648*795d594fSAndroid Build Coastguard Worker    test %eax, %eax               // if code pointer is null goto deliver the OOME.
1649*795d594fSAndroid Build Coastguard Worker    CFI_REMEMBER_STATE
1650*795d594fSAndroid Build Coastguard Worker    jz 1f
1651*795d594fSAndroid Build Coastguard Worker    RESTORE_SAVE_REFS_AND_ARGS_FRAME_AND_JUMP
1652*795d594fSAndroid Build Coastguard Worker1:
1653*795d594fSAndroid Build Coastguard Worker    CFI_RESTORE_STATE_AND_DEF_CFA esp, 64
1654*795d594fSAndroid Build Coastguard Worker    RESTORE_SAVE_REFS_AND_ARGS_FRAME
1655*795d594fSAndroid Build Coastguard Worker    DELIVER_PENDING_EXCEPTION
1656*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION art_quick_resolution_trampoline
1657*795d594fSAndroid Build Coastguard Worker
1658*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION art_quick_generic_jni_trampoline
1659*795d594fSAndroid Build Coastguard Worker    SETUP_SAVE_REFS_AND_ARGS_FRAME_WITH_METHOD_IN_EAX
1660*795d594fSAndroid Build Coastguard Worker    movl %esp, %ebp               // save SP at callee-save frame
1661*795d594fSAndroid Build Coastguard Worker    CFI_DEF_CFA_REGISTER(ebp)
1662*795d594fSAndroid Build Coastguard Worker    subl LITERAL(GENERIC_JNI_TRAMPOLINE_RESERVED_AREA), %esp
1663*795d594fSAndroid Build Coastguard Worker    // prepare for artQuickGenericJniTrampoline call
1664*795d594fSAndroid Build Coastguard Worker    // (Thread*, managed_sp, reserved_area)
1665*795d594fSAndroid Build Coastguard Worker    //   (esp)    4(esp)        8(esp)  <= C calling convention
1666*795d594fSAndroid Build Coastguard Worker    //  fs:...      ebp           esp   <= where they are
1667*795d594fSAndroid Build Coastguard Worker
1668*795d594fSAndroid Build Coastguard Worker    movl %esp, %eax
1669*795d594fSAndroid Build Coastguard Worker    subl LITERAL(4), %esp         // Padding for 16B alignment.
1670*795d594fSAndroid Build Coastguard Worker    pushl %eax                    // Pass reserved area.
1671*795d594fSAndroid Build Coastguard Worker    pushl %ebp                    // Pass managed frame SP.
1672*795d594fSAndroid Build Coastguard Worker    pushl %fs:THREAD_SELF_OFFSET  // Pass Thread::Current().
1673*795d594fSAndroid Build Coastguard Worker    call SYMBOL(artQuickGenericJniTrampoline)  // (Thread*, sp)
1674*795d594fSAndroid Build Coastguard Worker
1675*795d594fSAndroid Build Coastguard Worker    // The C call will have registered the complete save-frame on success.
1676*795d594fSAndroid Build Coastguard Worker    // The result of the call is:
1677*795d594fSAndroid Build Coastguard Worker    //     eax: pointer to native code, 0 on error.
1678*795d594fSAndroid Build Coastguard Worker    //     The bottom of the reserved area contains values for arg registers,
1679*795d594fSAndroid Build Coastguard Worker    //     hidden arg register and SP for out args for the call.
1680*795d594fSAndroid Build Coastguard Worker
1681*795d594fSAndroid Build Coastguard Worker    // Check for error (class init check or locking for synchronized native method can throw).
1682*795d594fSAndroid Build Coastguard Worker    test %eax, %eax
1683*795d594fSAndroid Build Coastguard Worker    jz .Lexception_in_native
1684*795d594fSAndroid Build Coastguard Worker
1685*795d594fSAndroid Build Coastguard Worker    // On x86 there are no registers passed, so no native call args to pop here.
1686*795d594fSAndroid Build Coastguard Worker
1687*795d594fSAndroid Build Coastguard Worker    // Save code pointer in EDX.
1688*795d594fSAndroid Build Coastguard Worker    movl %eax, %edx
1689*795d594fSAndroid Build Coastguard Worker    // Load hidden arg (EAX) for @CriticalNative.
1690*795d594fSAndroid Build Coastguard Worker    movl 16(%esp), %eax
1691*795d594fSAndroid Build Coastguard Worker    // Load SP for out args, releasing unneeded reserved area.
1692*795d594fSAndroid Build Coastguard Worker    movl 20(%esp), %esp
1693*795d594fSAndroid Build Coastguard Worker
1694*795d594fSAndroid Build Coastguard Worker    // Native call.
1695*795d594fSAndroid Build Coastguard Worker    call *%edx
1696*795d594fSAndroid Build Coastguard Worker
1697*795d594fSAndroid Build Coastguard Worker    // result sign extension is handled in C code
1698*795d594fSAndroid Build Coastguard Worker    // prepare for artQuickGenericJniEndTrampoline call
1699*795d594fSAndroid Build Coastguard Worker    // (Thread*, result, result_f)
1700*795d594fSAndroid Build Coastguard Worker    //  (esp)    4(esp)  12(esp)    <= C calling convention
1701*795d594fSAndroid Build Coastguard Worker    //  fs:...  eax:edx   fp0      <= where they are
1702*795d594fSAndroid Build Coastguard Worker
1703*795d594fSAndroid Build Coastguard Worker    subl LITERAL(20), %esp        // Padding & pass float result.
1704*795d594fSAndroid Build Coastguard Worker    fstpl (%esp)
1705*795d594fSAndroid Build Coastguard Worker    pushl %edx                    // Pass int result.
1706*795d594fSAndroid Build Coastguard Worker    pushl %eax
1707*795d594fSAndroid Build Coastguard Worker    pushl %fs:THREAD_SELF_OFFSET  // Pass Thread::Current().
1708*795d594fSAndroid Build Coastguard Worker    call SYMBOL(artQuickGenericJniEndTrampoline)
1709*795d594fSAndroid Build Coastguard Worker
1710*795d594fSAndroid Build Coastguard Worker    // Pending exceptions possible.
1711*795d594fSAndroid Build Coastguard Worker    mov %fs:THREAD_EXCEPTION_OFFSET, %ebx
1712*795d594fSAndroid Build Coastguard Worker    testl %ebx, %ebx
1713*795d594fSAndroid Build Coastguard Worker    jnz .Lexception_in_native
1714*795d594fSAndroid Build Coastguard Worker
1715*795d594fSAndroid Build Coastguard Worker    // Tear down the alloca.
1716*795d594fSAndroid Build Coastguard Worker    movl %ebp, %esp
1717*795d594fSAndroid Build Coastguard Worker
1718*795d594fSAndroid Build Coastguard Worker    // Quick expects the return value to be in xmm0.
1719*795d594fSAndroid Build Coastguard Worker    movd %eax, %xmm0
1720*795d594fSAndroid Build Coastguard Worker    movd %edx, %xmm1
1721*795d594fSAndroid Build Coastguard Worker    punpckldq %xmm1, %xmm0
1722*795d594fSAndroid Build Coastguard Worker
1723*795d594fSAndroid Build Coastguard Worker    LOAD_RUNTIME_INSTANCE ebx
1724*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(0), RUN_EXIT_HOOKS_OFFSET_FROM_RUNTIME_INSTANCE(%ebx)
1725*795d594fSAndroid Build Coastguard Worker    CFI_REMEMBER_STATE
1726*795d594fSAndroid Build Coastguard Worker    jne .Lcall_method_exit_hook
1727*795d594fSAndroid Build Coastguard Worker.Lcall_method_exit_hook_done:
1728*795d594fSAndroid Build Coastguard Worker
1729*795d594fSAndroid Build Coastguard Worker    // Tear down the callee-save frame.
1730*795d594fSAndroid Build Coastguard Worker    CFI_DEF_CFA_REGISTER(esp)
1731*795d594fSAndroid Build Coastguard Worker    // Remove space for the method, FPR and GPR args
1732*795d594fSAndroid Build Coastguard Worker    DECREASE_FRAME 4 + 4 * 8 + 3*4
1733*795d594fSAndroid Build Coastguard Worker    // Restore callee saves and return.
1734*795d594fSAndroid Build Coastguard Worker    POP ebp
1735*795d594fSAndroid Build Coastguard Worker    POP esi
1736*795d594fSAndroid Build Coastguard Worker    POP edi
1737*795d594fSAndroid Build Coastguard Worker    ret
1738*795d594fSAndroid Build Coastguard Worker
1739*795d594fSAndroid Build Coastguard Worker.Lcall_method_exit_hook:
1740*795d594fSAndroid Build Coastguard Worker    CFI_RESTORE_STATE_AND_DEF_CFA ebp, 64
1741*795d594fSAndroid Build Coastguard Worker    movl LITERAL(FRAME_SIZE_SAVE_REFS_AND_ARGS), %ebx
1742*795d594fSAndroid Build Coastguard Worker    call art_quick_method_exit_hook
1743*795d594fSAndroid Build Coastguard Worker    jmp .Lcall_method_exit_hook_done
1744*795d594fSAndroid Build Coastguard Worker
1745*795d594fSAndroid Build Coastguard Worker.Lexception_in_native:
1746*795d594fSAndroid Build Coastguard Worker    pushl %fs:THREAD_TOP_QUICK_FRAME_OFFSET
1747*795d594fSAndroid Build Coastguard Worker    addl LITERAL(-1), (%esp)  // Remove the GenericJNI tag.
1748*795d594fSAndroid Build Coastguard Worker    movl (%esp), %esp
1749*795d594fSAndroid Build Coastguard Worker    call art_deliver_pending_exception
1750*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION art_quick_generic_jni_trampoline
1751*795d594fSAndroid Build Coastguard Worker
1752*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION art_deliver_pending_exception
1753*795d594fSAndroid Build Coastguard Worker    // This will create a new save-all frame, required by the runtime.
1754*795d594fSAndroid Build Coastguard Worker    DELIVER_PENDING_EXCEPTION
1755*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION art_deliver_pending_exception
1756*795d594fSAndroid Build Coastguard Worker
1757*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION art_quick_to_interpreter_bridge
1758*795d594fSAndroid Build Coastguard Worker    SETUP_SAVE_REFS_AND_ARGS_FRAME ebx  // save frame
1759*795d594fSAndroid Build Coastguard Worker    mov %esp, %edx                // remember SP
1760*795d594fSAndroid Build Coastguard Worker    PUSH eax                      // alignment padding
1761*795d594fSAndroid Build Coastguard Worker    PUSH edx                      // pass SP
1762*795d594fSAndroid Build Coastguard Worker    pushl %fs:THREAD_SELF_OFFSET  // pass Thread::Current()
1763*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
1764*795d594fSAndroid Build Coastguard Worker    PUSH eax                      // pass  method
1765*795d594fSAndroid Build Coastguard Worker    call SYMBOL(artQuickToInterpreterBridge)  // (method, Thread*, SP)
1766*795d594fSAndroid Build Coastguard Worker    addl LITERAL(16), %esp        // pop arguments
1767*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(-16)
1768*795d594fSAndroid Build Coastguard Worker
1769*795d594fSAndroid Build Coastguard Worker    // Return eax:edx in xmm0 also.
1770*795d594fSAndroid Build Coastguard Worker    movd %eax, %xmm0
1771*795d594fSAndroid Build Coastguard Worker    movd %edx, %xmm1
1772*795d594fSAndroid Build Coastguard Worker    punpckldq %xmm1, %xmm0
1773*795d594fSAndroid Build Coastguard Worker
1774*795d594fSAndroid Build Coastguard Worker    addl LITERAL(48), %esp        // Remove FPRs and EAX, ECX, EDX, EBX.
1775*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(-48)
1776*795d594fSAndroid Build Coastguard Worker
1777*795d594fSAndroid Build Coastguard Worker    POP ebp                       // Restore callee saves
1778*795d594fSAndroid Build Coastguard Worker    POP esi
1779*795d594fSAndroid Build Coastguard Worker    POP edi
1780*795d594fSAndroid Build Coastguard Worker
1781*795d594fSAndroid Build Coastguard Worker    RETURN_OR_DELIVER_PENDING_EXCEPTION    // return or deliver exception
1782*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION art_quick_to_interpreter_bridge
1783*795d594fSAndroid Build Coastguard Worker
1784*795d594fSAndroid Build Coastguard Worker    /*
1785*795d594fSAndroid Build Coastguard Worker     * Called by managed code, saves callee saves and then calls artInvokeObsoleteMethod
1786*795d594fSAndroid Build Coastguard Worker     */
1787*795d594fSAndroid Build Coastguard WorkerONE_ARG_RUNTIME_EXCEPTION art_invoke_obsolete_method_stub, artInvokeObsoleteMethod
1788*795d594fSAndroid Build Coastguard Worker
1789*795d594fSAndroid Build Coastguard Worker    /*
1790*795d594fSAndroid Build Coastguard Worker     * Compiled code has requested that we deoptimize into the interpreter. The deoptimization
1791*795d594fSAndroid Build Coastguard Worker     * will long jump to the interpreter bridge.
1792*795d594fSAndroid Build Coastguard Worker     */
1793*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION art_quick_deoptimize_from_compiled_code
1794*795d594fSAndroid Build Coastguard Worker    SETUP_SAVE_EVERYTHING_FRAME ebx
1795*795d594fSAndroid Build Coastguard Worker    subl LITERAL(8), %esp                       // Align stack.
1796*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(8)
1797*795d594fSAndroid Build Coastguard Worker    pushl %fs:THREAD_SELF_OFFSET                // Pass Thread::Current().
1798*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
1799*795d594fSAndroid Build Coastguard Worker    PUSH eax
1800*795d594fSAndroid Build Coastguard Worker    call SYMBOL(artDeoptimizeFromCompiledCode)  // (DeoptimizationKind, Thread*)
1801*795d594fSAndroid Build Coastguard Worker    call SYMBOL(art_quick_do_long_jump)
1802*795d594fSAndroid Build Coastguard Worker    UNREACHABLE
1803*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION art_quick_deoptimize_from_compiled_code
1804*795d594fSAndroid Build Coastguard Worker
1805*795d594fSAndroid Build Coastguard Worker    /*
1806*795d594fSAndroid Build Coastguard Worker     * String's compareTo.
1807*795d594fSAndroid Build Coastguard Worker     *
1808*795d594fSAndroid Build Coastguard Worker     * On entry:
1809*795d594fSAndroid Build Coastguard Worker     *    eax:   this string object (known non-null)
1810*795d594fSAndroid Build Coastguard Worker     *    ecx:   comp string object (known non-null)
1811*795d594fSAndroid Build Coastguard Worker     */
1812*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION art_quick_string_compareto
1813*795d594fSAndroid Build Coastguard Worker    PUSH esi                      // push callee save reg
1814*795d594fSAndroid Build Coastguard Worker    PUSH edi                      // push callee save reg
1815*795d594fSAndroid Build Coastguard Worker    mov MIRROR_STRING_COUNT_OFFSET(%eax), %edx
1816*795d594fSAndroid Build Coastguard Worker    mov MIRROR_STRING_COUNT_OFFSET(%ecx), %ebx
1817*795d594fSAndroid Build Coastguard Worker    lea MIRROR_STRING_VALUE_OFFSET(%eax), %esi
1818*795d594fSAndroid Build Coastguard Worker    lea MIRROR_STRING_VALUE_OFFSET(%ecx), %edi
1819*795d594fSAndroid Build Coastguard Worker#if (STRING_COMPRESSION_FEATURE)
1820*795d594fSAndroid Build Coastguard Worker    /* Differ cases */
1821*795d594fSAndroid Build Coastguard Worker    shrl    LITERAL(1), %edx
1822*795d594fSAndroid Build Coastguard Worker    jnc     .Lstring_compareto_this_is_compressed
1823*795d594fSAndroid Build Coastguard Worker    shrl    LITERAL(1), %ebx
1824*795d594fSAndroid Build Coastguard Worker    jnc     .Lstring_compareto_that_is_compressed
1825*795d594fSAndroid Build Coastguard Worker    jmp     .Lstring_compareto_both_not_compressed
1826*795d594fSAndroid Build Coastguard Worker.Lstring_compareto_this_is_compressed:
1827*795d594fSAndroid Build Coastguard Worker    shrl    LITERAL(1), %ebx
1828*795d594fSAndroid Build Coastguard Worker    jnc     .Lstring_compareto_both_compressed
1829*795d594fSAndroid Build Coastguard Worker    /* If (this->IsCompressed() && that->IsCompressed() == false) */
1830*795d594fSAndroid Build Coastguard Worker    mov     %edx, %eax
1831*795d594fSAndroid Build Coastguard Worker    subl    %ebx, %eax
1832*795d594fSAndroid Build Coastguard Worker    mov     %edx, %ecx
1833*795d594fSAndroid Build Coastguard Worker    cmovg   %ebx, %ecx
1834*795d594fSAndroid Build Coastguard Worker    /* Going into loop to compare each character */
1835*795d594fSAndroid Build Coastguard Worker    jecxz   .Lstring_compareto_keep_length            // check loop counter (if 0, don't compare)
1836*795d594fSAndroid Build Coastguard Worker.Lstring_compareto_loop_comparison_this_compressed:
1837*795d594fSAndroid Build Coastguard Worker    movzbl  (%esi), %edx                              // move *(this_cur_char) byte to long
1838*795d594fSAndroid Build Coastguard Worker    movzwl  (%edi), %ebx                              // move *(that_cur_char) word to long
1839*795d594fSAndroid Build Coastguard Worker    addl    LITERAL(1), %esi                          // ++this_cur_char (8-bit)
1840*795d594fSAndroid Build Coastguard Worker    addl    LITERAL(2), %edi                          // ++that_cur_char (16-bit)
1841*795d594fSAndroid Build Coastguard Worker    subl    %ebx, %edx
1842*795d594fSAndroid Build Coastguard Worker    loope   .Lstring_compareto_loop_comparison_this_compressed
1843*795d594fSAndroid Build Coastguard Worker    cmovne  %edx, %eax                        // return eax = *(this_cur_char) - *(that_cur_char)
1844*795d594fSAndroid Build Coastguard Worker    jmp     .Lstring_compareto_return
1845*795d594fSAndroid Build Coastguard Worker.Lstring_compareto_that_is_compressed:
1846*795d594fSAndroid Build Coastguard Worker    mov     %edx, %eax
1847*795d594fSAndroid Build Coastguard Worker    subl    %ebx, %eax
1848*795d594fSAndroid Build Coastguard Worker    mov     %edx, %ecx
1849*795d594fSAndroid Build Coastguard Worker    cmovg   %ebx, %ecx
1850*795d594fSAndroid Build Coastguard Worker    /* If (this->IsCompressed() == false && that->IsCompressed()) */
1851*795d594fSAndroid Build Coastguard Worker    jecxz   .Lstring_compareto_keep_length            // check loop counter, if 0, don't compare
1852*795d594fSAndroid Build Coastguard Worker.Lstring_compareto_loop_comparison_that_compressed:
1853*795d594fSAndroid Build Coastguard Worker    movzwl  (%esi), %edx                              // move *(this_cur_char) word to long
1854*795d594fSAndroid Build Coastguard Worker    movzbl  (%edi), %ebx                              // move *(that_cur_char) byte to long
1855*795d594fSAndroid Build Coastguard Worker    addl    LITERAL(2), %esi                          // ++this_cur_char (16-bit)
1856*795d594fSAndroid Build Coastguard Worker    addl    LITERAL(1), %edi                          // ++that_cur_char (8-bit)
1857*795d594fSAndroid Build Coastguard Worker    subl    %ebx, %edx
1858*795d594fSAndroid Build Coastguard Worker    loope   .Lstring_compareto_loop_comparison_that_compressed
1859*795d594fSAndroid Build Coastguard Worker    cmovne  %edx, %eax
1860*795d594fSAndroid Build Coastguard Worker    jmp     .Lstring_compareto_return         // return eax = *(this_cur_char) - *(that_cur_char)
1861*795d594fSAndroid Build Coastguard Worker.Lstring_compareto_both_compressed:
1862*795d594fSAndroid Build Coastguard Worker    /* Calculate min length and count diff */
1863*795d594fSAndroid Build Coastguard Worker    mov     %edx, %ecx
1864*795d594fSAndroid Build Coastguard Worker    mov     %edx, %eax
1865*795d594fSAndroid Build Coastguard Worker    subl    %ebx, %eax
1866*795d594fSAndroid Build Coastguard Worker    cmovg   %ebx, %ecx
1867*795d594fSAndroid Build Coastguard Worker    jecxz   .Lstring_compareto_keep_length
1868*795d594fSAndroid Build Coastguard Worker    repe    cmpsb
1869*795d594fSAndroid Build Coastguard Worker    je      .Lstring_compareto_keep_length
1870*795d594fSAndroid Build Coastguard Worker    movzbl  -1(%esi), %eax        // get last compared char from this string (8-bit)
1871*795d594fSAndroid Build Coastguard Worker    movzbl  -1(%edi), %ecx        // get last compared char from comp string (8-bit)
1872*795d594fSAndroid Build Coastguard Worker    jmp     .Lstring_compareto_count_difference
1873*795d594fSAndroid Build Coastguard Worker#endif // STRING_COMPRESSION_FEATURE
1874*795d594fSAndroid Build Coastguard Worker.Lstring_compareto_both_not_compressed:
1875*795d594fSAndroid Build Coastguard Worker    /* Calculate min length and count diff */
1876*795d594fSAndroid Build Coastguard Worker    mov     %edx, %ecx
1877*795d594fSAndroid Build Coastguard Worker    mov     %edx, %eax
1878*795d594fSAndroid Build Coastguard Worker    subl    %ebx, %eax
1879*795d594fSAndroid Build Coastguard Worker    cmovg   %ebx, %ecx
1880*795d594fSAndroid Build Coastguard Worker    /*
1881*795d594fSAndroid Build Coastguard Worker     * At this point we have:
1882*795d594fSAndroid Build Coastguard Worker     *   eax: value to return if first part of strings are equal
1883*795d594fSAndroid Build Coastguard Worker     *   ecx: minimum among the lengths of the two strings
1884*795d594fSAndroid Build Coastguard Worker     *   esi: pointer to this string data
1885*795d594fSAndroid Build Coastguard Worker     *   edi: pointer to comp string data
1886*795d594fSAndroid Build Coastguard Worker     */
1887*795d594fSAndroid Build Coastguard Worker    jecxz .Lstring_compareto_keep_length
1888*795d594fSAndroid Build Coastguard Worker    repe  cmpsw                   // find nonmatching chars in [%esi] and [%edi], up to length %ecx
1889*795d594fSAndroid Build Coastguard Worker    je    .Lstring_compareto_keep_length
1890*795d594fSAndroid Build Coastguard Worker    movzwl  -2(%esi), %eax        // get last compared char from this string (16-bit)
1891*795d594fSAndroid Build Coastguard Worker    movzwl  -2(%edi), %ecx        // get last compared char from comp string (16-bit)
1892*795d594fSAndroid Build Coastguard Worker.Lstring_compareto_count_difference:
1893*795d594fSAndroid Build Coastguard Worker    subl    %ecx, %eax
1894*795d594fSAndroid Build Coastguard Worker.Lstring_compareto_keep_length:
1895*795d594fSAndroid Build Coastguard Worker.Lstring_compareto_return:
1896*795d594fSAndroid Build Coastguard Worker    POP edi                       // pop callee save reg
1897*795d594fSAndroid Build Coastguard Worker    POP esi                       // pop callee save reg
1898*795d594fSAndroid Build Coastguard Worker    ret
1899*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION art_quick_string_compareto
1900*795d594fSAndroid Build Coastguard Worker
1901*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION art_quick_string_builder_append
1902*795d594fSAndroid Build Coastguard Worker    SETUP_SAVE_REFS_ONLY_FRAME ebx            // save ref containing registers for GC
1903*795d594fSAndroid Build Coastguard Worker    // Outgoing argument set up
1904*795d594fSAndroid Build Coastguard Worker    leal FRAME_SIZE_SAVE_REFS_ONLY + __SIZEOF_POINTER__(%esp), %edi  // prepare args
1905*795d594fSAndroid Build Coastguard Worker    push %eax                                         // push padding
1906*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
1907*795d594fSAndroid Build Coastguard Worker    pushl %fs:THREAD_SELF_OFFSET                      // pass Thread::Current()
1908*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
1909*795d594fSAndroid Build Coastguard Worker    push %edi                                         // pass args
1910*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
1911*795d594fSAndroid Build Coastguard Worker    push %eax                                         // pass format
1912*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
1913*795d594fSAndroid Build Coastguard Worker    call SYMBOL(artStringBuilderAppend)               // (uint32_t, const unit32_t*, Thread*)
1914*795d594fSAndroid Build Coastguard Worker    DECREASE_FRAME 16                                 // pop arguments
1915*795d594fSAndroid Build Coastguard Worker    RESTORE_SAVE_REFS_ONLY_FRAME                      // restore frame up to return address
1916*795d594fSAndroid Build Coastguard Worker    RETURN_OR_DEOPT_IF_RESULT_IS_NON_NULL_OR_DELIVER  // return or deliver exception
1917*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION art_quick_string_builder_append
1918*795d594fSAndroid Build Coastguard Worker
1919*795d594fSAndroid Build Coastguard Worker// Create a function `name` calling the ReadBarrier::Mark routine,
1920*795d594fSAndroid Build Coastguard Worker// getting its argument and returning its result through register
1921*795d594fSAndroid Build Coastguard Worker// `reg`, saving and restoring all caller-save registers.
1922*795d594fSAndroid Build Coastguard Worker//
1923*795d594fSAndroid Build Coastguard Worker// The generated function follows a non-standard runtime calling convention:
1924*795d594fSAndroid Build Coastguard Worker// - register `reg` (which may differ from EAX) is used to pass the (sole) argument,
1925*795d594fSAndroid Build Coastguard Worker// - register `reg` (which may differ from EAX) is used to return the result,
1926*795d594fSAndroid Build Coastguard Worker// - all other registers are callee-save (the values they hold are preserved).
1927*795d594fSAndroid Build Coastguard WorkerMACRO2(READ_BARRIER_MARK_REG, name, reg)
1928*795d594fSAndroid Build Coastguard Worker    DEFINE_FUNCTION VAR(name)
1929*795d594fSAndroid Build Coastguard Worker    // Null check so that we can load the lock word.
1930*795d594fSAndroid Build Coastguard Worker    test REG_VAR(reg), REG_VAR(reg)
1931*795d594fSAndroid Build Coastguard Worker    jz .Lret_rb_\name
1932*795d594fSAndroid Build Coastguard Worker.Lnot_null_\name:
1933*795d594fSAndroid Build Coastguard Worker    // Check the mark bit, if it is 1 return.
1934*795d594fSAndroid Build Coastguard Worker    testl LITERAL(LOCK_WORD_MARK_BIT_MASK_SHIFTED), MIRROR_OBJECT_LOCK_WORD_OFFSET(REG_VAR(reg))
1935*795d594fSAndroid Build Coastguard Worker    jz .Lslow_rb_\name
1936*795d594fSAndroid Build Coastguard Worker    ret
1937*795d594fSAndroid Build Coastguard Worker.Lslow_rb_\name:
1938*795d594fSAndroid Build Coastguard Worker    PUSH eax
1939*795d594fSAndroid Build Coastguard Worker    mov MIRROR_OBJECT_LOCK_WORD_OFFSET(REG_VAR(reg)), %eax
1940*795d594fSAndroid Build Coastguard Worker    add LITERAL(LOCK_WORD_STATE_FORWARDING_ADDRESS_OVERFLOW), %eax
1941*795d594fSAndroid Build Coastguard Worker    // Jump if overflow, the only case where it overflows should be the forwarding address one.
1942*795d594fSAndroid Build Coastguard Worker    // Taken ~25% of the time.
1943*795d594fSAndroid Build Coastguard Worker    CFI_REMEMBER_STATE
1944*795d594fSAndroid Build Coastguard Worker    jnae .Lret_forwarding_address\name
1945*795d594fSAndroid Build Coastguard Worker
1946*795d594fSAndroid Build Coastguard Worker    // Save all potentially live caller-save core registers.
1947*795d594fSAndroid Build Coastguard Worker    mov 0(%esp), %eax
1948*795d594fSAndroid Build Coastguard Worker    PUSH ecx
1949*795d594fSAndroid Build Coastguard Worker    PUSH edx
1950*795d594fSAndroid Build Coastguard Worker    PUSH ebx
1951*795d594fSAndroid Build Coastguard Worker    // 8-byte align the stack to improve (8-byte) XMM register saving and restoring.
1952*795d594fSAndroid Build Coastguard Worker    // and create space for caller-save floating-point registers.
1953*795d594fSAndroid Build Coastguard Worker    INCREASE_FRAME 4 + 8 * 8
1954*795d594fSAndroid Build Coastguard Worker    // Save all potentially live caller-save floating-point registers.
1955*795d594fSAndroid Build Coastguard Worker    movsd %xmm0, 0(%esp)
1956*795d594fSAndroid Build Coastguard Worker    movsd %xmm1, 8(%esp)
1957*795d594fSAndroid Build Coastguard Worker    movsd %xmm2, 16(%esp)
1958*795d594fSAndroid Build Coastguard Worker    movsd %xmm3, 24(%esp)
1959*795d594fSAndroid Build Coastguard Worker    movsd %xmm4, 32(%esp)
1960*795d594fSAndroid Build Coastguard Worker    movsd %xmm5, 40(%esp)
1961*795d594fSAndroid Build Coastguard Worker    movsd %xmm6, 48(%esp)
1962*795d594fSAndroid Build Coastguard Worker    movsd %xmm7, 56(%esp)
1963*795d594fSAndroid Build Coastguard Worker
1964*795d594fSAndroid Build Coastguard Worker    subl LITERAL(4), %esp            // alignment padding
1965*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
1966*795d594fSAndroid Build Coastguard Worker    PUSH RAW_VAR(reg)                // pass arg1 - obj from `reg`
1967*795d594fSAndroid Build Coastguard Worker    call SYMBOL(artReadBarrierMark)  // artReadBarrierMark(obj)
1968*795d594fSAndroid Build Coastguard Worker    .ifnc RAW_VAR(reg), eax
1969*795d594fSAndroid Build Coastguard Worker      movl %eax, REG_VAR(reg)        // return result into `reg`
1970*795d594fSAndroid Build Coastguard Worker    .endif
1971*795d594fSAndroid Build Coastguard Worker    addl LITERAL(8), %esp            // pop argument and remove padding
1972*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(-8)
1973*795d594fSAndroid Build Coastguard Worker
1974*795d594fSAndroid Build Coastguard Worker    // Restore floating-point registers.
1975*795d594fSAndroid Build Coastguard Worker    movsd 0(%esp), %xmm0
1976*795d594fSAndroid Build Coastguard Worker    movsd 8(%esp), %xmm1
1977*795d594fSAndroid Build Coastguard Worker    movsd 16(%esp), %xmm2
1978*795d594fSAndroid Build Coastguard Worker    movsd 24(%esp), %xmm3
1979*795d594fSAndroid Build Coastguard Worker    movsd 32(%esp), %xmm4
1980*795d594fSAndroid Build Coastguard Worker    movsd 40(%esp), %xmm5
1981*795d594fSAndroid Build Coastguard Worker    movsd 48(%esp), %xmm6
1982*795d594fSAndroid Build Coastguard Worker    movsd 56(%esp), %xmm7
1983*795d594fSAndroid Build Coastguard Worker    // Remove floating-point registers and padding.
1984*795d594fSAndroid Build Coastguard Worker    DECREASE_FRAME 8 * 8 + 4
1985*795d594fSAndroid Build Coastguard Worker    // Restore core regs, except `reg`, as it is used to return the
1986*795d594fSAndroid Build Coastguard Worker    // result of this function (simply remove it from the stack instead).
1987*795d594fSAndroid Build Coastguard Worker    POP_REG_NE ebx, RAW_VAR(reg)
1988*795d594fSAndroid Build Coastguard Worker    POP_REG_NE edx, RAW_VAR(reg)
1989*795d594fSAndroid Build Coastguard Worker    POP_REG_NE ecx, RAW_VAR(reg)
1990*795d594fSAndroid Build Coastguard Worker    POP_REG_NE eax, RAW_VAR(reg)
1991*795d594fSAndroid Build Coastguard Worker.Lret_rb_\name:
1992*795d594fSAndroid Build Coastguard Worker    ret
1993*795d594fSAndroid Build Coastguard Worker.Lret_forwarding_address\name:
1994*795d594fSAndroid Build Coastguard Worker    CFI_RESTORE_STATE_AND_DEF_CFA esp, 8
1995*795d594fSAndroid Build Coastguard Worker    // The overflow cleared the top bits.
1996*795d594fSAndroid Build Coastguard Worker    sall LITERAL(LOCK_WORD_STATE_FORWARDING_ADDRESS_SHIFT), %eax
1997*795d594fSAndroid Build Coastguard Worker    mov %eax, REG_VAR(reg)
1998*795d594fSAndroid Build Coastguard Worker    POP_REG_NE eax, RAW_VAR(reg)
1999*795d594fSAndroid Build Coastguard Worker    ret
2000*795d594fSAndroid Build Coastguard Worker    END_FUNCTION VAR(name)
2001*795d594fSAndroid Build Coastguard WorkerEND_MACRO
2002*795d594fSAndroid Build Coastguard Worker
2003*795d594fSAndroid Build Coastguard WorkerREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg00, eax
2004*795d594fSAndroid Build Coastguard WorkerREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg01, ecx
2005*795d594fSAndroid Build Coastguard WorkerREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg02, edx
2006*795d594fSAndroid Build Coastguard WorkerREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg03, ebx
2007*795d594fSAndroid Build Coastguard WorkerREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg05, ebp
2008*795d594fSAndroid Build Coastguard Worker// Note: There is no art_quick_read_barrier_mark_reg04, as register 4 (ESP)
2009*795d594fSAndroid Build Coastguard Worker// cannot be used to pass arguments.
2010*795d594fSAndroid Build Coastguard WorkerREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg06, esi
2011*795d594fSAndroid Build Coastguard WorkerREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg07, edi
2012*795d594fSAndroid Build Coastguard Worker
2013*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION art_quick_read_barrier_slow
2014*795d594fSAndroid Build Coastguard Worker    PUSH edx                         // pass arg3 - offset
2015*795d594fSAndroid Build Coastguard Worker    PUSH ecx                         // pass arg2 - obj
2016*795d594fSAndroid Build Coastguard Worker    PUSH eax                         // pass arg1 - ref
2017*795d594fSAndroid Build Coastguard Worker    call SYMBOL(artReadBarrierSlow)  // artReadBarrierSlow(ref, obj, offset)
2018*795d594fSAndroid Build Coastguard Worker    addl LITERAL(12), %esp           // pop arguments
2019*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(-12)
2020*795d594fSAndroid Build Coastguard Worker    ret
2021*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION art_quick_read_barrier_slow
2022*795d594fSAndroid Build Coastguard Worker
2023*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION art_quick_read_barrier_for_root_slow
2024*795d594fSAndroid Build Coastguard Worker    subl LITERAL(8), %esp                   // alignment padding
2025*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(8)
2026*795d594fSAndroid Build Coastguard Worker    PUSH eax                                // pass arg1 - root
2027*795d594fSAndroid Build Coastguard Worker    call SYMBOL(artReadBarrierForRootSlow)  // artReadBarrierForRootSlow(root)
2028*795d594fSAndroid Build Coastguard Worker    addl LITERAL(12), %esp                  // pop argument and remove padding
2029*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(-12)
2030*795d594fSAndroid Build Coastguard Worker    ret
2031*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION art_quick_read_barrier_for_root_slow
2032*795d594fSAndroid Build Coastguard Worker
2033*795d594fSAndroid Build Coastguard Worker  /*
2034*795d594fSAndroid Build Coastguard Worker     * On stack replacement stub.
2035*795d594fSAndroid Build Coastguard Worker     * On entry:
2036*795d594fSAndroid Build Coastguard Worker     *   [sp] = return address
2037*795d594fSAndroid Build Coastguard Worker     *   [sp + 4] = stack to copy
2038*795d594fSAndroid Build Coastguard Worker     *   [sp + 8] = size of stack
2039*795d594fSAndroid Build Coastguard Worker     *   [sp + 12] = pc to call
2040*795d594fSAndroid Build Coastguard Worker     *   [sp + 16] = JValue* result
2041*795d594fSAndroid Build Coastguard Worker     *   [sp + 20] = shorty
2042*795d594fSAndroid Build Coastguard Worker     *   [sp + 24] = thread
2043*795d594fSAndroid Build Coastguard Worker     */
2044*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION art_quick_osr_stub
2045*795d594fSAndroid Build Coastguard Worker    // Save native callee saves.
2046*795d594fSAndroid Build Coastguard Worker    PUSH ebp
2047*795d594fSAndroid Build Coastguard Worker    PUSH ebx
2048*795d594fSAndroid Build Coastguard Worker    PUSH esi
2049*795d594fSAndroid Build Coastguard Worker    PUSH edi
2050*795d594fSAndroid Build Coastguard Worker    SAVE_SIZE=20                   // 4 registers and the return address
2051*795d594fSAndroid Build Coastguard Worker    mov 4+16(%esp), %esi           // ESI = argument array
2052*795d594fSAndroid Build Coastguard Worker    mov 8+16(%esp), %ecx           // ECX = size of args
2053*795d594fSAndroid Build Coastguard Worker    mov 12+16(%esp), %ebx          // EBX = pc to call
2054*795d594fSAndroid Build Coastguard Worker    mov %esp, %ebp                 // Save stack pointer
2055*795d594fSAndroid Build Coastguard Worker    CFI_DEF_CFA(ebp, SAVE_SIZE)    // CFA = ebp + SAVE_SIZE
2056*795d594fSAndroid Build Coastguard Worker    CFI_REMEMBER_STATE
2057*795d594fSAndroid Build Coastguard Worker    andl LITERAL(0xFFFFFFF0), %esp // Align stack
2058*795d594fSAndroid Build Coastguard Worker    pushl %ebp                     // Save old stack pointer
2059*795d594fSAndroid Build Coastguard Worker    subl LITERAL(12), %esp         // Align stack
2060*795d594fSAndroid Build Coastguard Worker    movl LITERAL(0), (%esp)        // Store null for ArtMethod* slot
2061*795d594fSAndroid Build Coastguard Worker    // ebp isn't properly spilled in the osr method, so we need use DWARF expression.
2062*795d594fSAndroid Build Coastguard Worker    // NB: the CFI must be before the call since this is the address gdb will lookup.
2063*795d594fSAndroid Build Coastguard Worker    // NB: gdb expects that cfa_expression returns the CFA value (not address to it).
2064*795d594fSAndroid Build Coastguard Worker    CFI_ESCAPE(                    /* cfa = [sp + 12] + SAVE_SIZE */ \
2065*795d594fSAndroid Build Coastguard Worker      0x0f, 6,                     /* DW_CFA_def_cfa_expression(len) */ \
2066*795d594fSAndroid Build Coastguard Worker      0x92, 4, 12,                 /* DW_OP_bregx(reg,offset) */ \
2067*795d594fSAndroid Build Coastguard Worker      0x06,                        /* DW_OP_deref */ \
2068*795d594fSAndroid Build Coastguard Worker      0x23, SAVE_SIZE)             /* DW_OP_plus_uconst(val) */
2069*795d594fSAndroid Build Coastguard Worker    call .Losr_entry
2070*795d594fSAndroid Build Coastguard Worker    mov 12(%esp), %esp             // Restore stack pointer.
2071*795d594fSAndroid Build Coastguard Worker    CFI_DEF_CFA(esp, SAVE_SIZE)    // CFA = esp + SAVE_SIZE
2072*795d594fSAndroid Build Coastguard Worker
2073*795d594fSAndroid Build Coastguard Worker    // Restore callee saves.
2074*795d594fSAndroid Build Coastguard Worker    POP edi
2075*795d594fSAndroid Build Coastguard Worker    POP esi
2076*795d594fSAndroid Build Coastguard Worker    POP ebx
2077*795d594fSAndroid Build Coastguard Worker    POP ebp
2078*795d594fSAndroid Build Coastguard Worker    mov 16(%esp), %ecx            // Get JValue result
2079*795d594fSAndroid Build Coastguard Worker    mov %eax, (%ecx)              // Store the result.
2080*795d594fSAndroid Build Coastguard Worker    mov %edx, 4(%ecx)             // Store the other half of the result.
2081*795d594fSAndroid Build Coastguard Worker    ret
2082*795d594fSAndroid Build Coastguard Worker.Losr_entry:
2083*795d594fSAndroid Build Coastguard Worker    CFI_RESTORE_STATE_AND_DEF_CFA ebp, SAVE_SIZE   // CFA = ebp + SAVE_SIZE
2084*795d594fSAndroid Build Coastguard Worker    subl LITERAL(4), %ecx         // Given stack size contains pushed frame pointer, substract it.
2085*795d594fSAndroid Build Coastguard Worker    subl %ecx, %esp
2086*795d594fSAndroid Build Coastguard Worker    mov %esp, %edi                // EDI = beginning of stack
2087*795d594fSAndroid Build Coastguard Worker    rep movsb                     // while (ecx--) { *edi++ = *esi++ }
2088*795d594fSAndroid Build Coastguard Worker    jmp *%ebx
2089*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION art_quick_osr_stub
2090*795d594fSAndroid Build Coastguard Worker
2091*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION art_quick_invoke_polymorphic
2092*795d594fSAndroid Build Coastguard Worker                                                   // On entry: EAX := unused, ECX := receiver
2093*795d594fSAndroid Build Coastguard Worker    SETUP_SAVE_REFS_AND_ARGS_FRAME ebx             // Save frame.
2094*795d594fSAndroid Build Coastguard Worker    mov %esp, %edx                                 // Remember SP
2095*795d594fSAndroid Build Coastguard Worker    sub LITERAL(4), %esp                           // Alignment padding
2096*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
2097*795d594fSAndroid Build Coastguard Worker    push %edx                                      // Push SP
2098*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
2099*795d594fSAndroid Build Coastguard Worker    pushl %fs:THREAD_SELF_OFFSET                   // Push Thread::Current()
2100*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
2101*795d594fSAndroid Build Coastguard Worker    push %ecx                                      // Push receiver (method handle)
2102*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
2103*795d594fSAndroid Build Coastguard Worker    call SYMBOL(artInvokePolymorphic)              // invoke with (receiver, thread, SP)
2104*795d594fSAndroid Build Coastguard Worker    addl LITERAL(16), %esp                         // Pop arguments.
2105*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(-16)
2106*795d594fSAndroid Build Coastguard Worker    mov %eax, 4(%esp)                              // Result is in EAX:EDX. Copy to saved FP state.
2107*795d594fSAndroid Build Coastguard Worker    mov %edx, 8(%esp)
2108*795d594fSAndroid Build Coastguard Worker    mov %edx, 40(%esp)                             // Copy EDX to saved context
2109*795d594fSAndroid Build Coastguard Worker    RESTORE_SAVE_REFS_AND_ARGS_FRAME
2110*795d594fSAndroid Build Coastguard Worker    RETURN_OR_DELIVER_PENDING_EXCEPTION
2111*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION art_quick_invoke_polymorphic
2112*795d594fSAndroid Build Coastguard Worker
2113*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION art_quick_invoke_custom
2114*795d594fSAndroid Build Coastguard Worker    SETUP_SAVE_REFS_AND_ARGS_FRAME ebx             // Save frame.
2115*795d594fSAndroid Build Coastguard Worker                                                   // EAX := call_site_index
2116*795d594fSAndroid Build Coastguard Worker    mov %esp, %ecx                                 // Remember SP.
2117*795d594fSAndroid Build Coastguard Worker    subl LITERAL(4), %esp                          // Alignment padding.
2118*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
2119*795d594fSAndroid Build Coastguard Worker    push %ecx                                      // pass SP
2120*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
2121*795d594fSAndroid Build Coastguard Worker    pushl %fs:THREAD_SELF_OFFSET                   // pass Thread::Current()
2122*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
2123*795d594fSAndroid Build Coastguard Worker    push %eax                                      // pass call_site_index
2124*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
2125*795d594fSAndroid Build Coastguard Worker    call SYMBOL(artInvokeCustom)                   // artInvokeCustom(call_site_index, Thread*, SP)
2126*795d594fSAndroid Build Coastguard Worker    addl LITERAL(16), %esp                         // Pop arguments.
2127*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(-16)
2128*795d594fSAndroid Build Coastguard Worker    mov %eax, 4(%esp)                              // Result is in EAX:EDX. Copy to saved FP state.
2129*795d594fSAndroid Build Coastguard Worker    mov %edx, 8(%esp)
2130*795d594fSAndroid Build Coastguard Worker    mov %edx, 40(%esp)                             // Copy EDX to saved context
2131*795d594fSAndroid Build Coastguard Worker    RESTORE_SAVE_REFS_AND_ARGS_FRAME
2132*795d594fSAndroid Build Coastguard Worker    RETURN_OR_DELIVER_PENDING_EXCEPTION
2133*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION art_quick_invoke_custom
2134*795d594fSAndroid Build Coastguard Worker
2135*795d594fSAndroid Build Coastguard Worker// On entry: eax is the class, ebp is the inline cache.
2136*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION art_quick_update_inline_cache
2137*795d594fSAndroid Build Coastguard Worker#if (INLINE_CACHE_SIZE != 5)
2138*795d594fSAndroid Build Coastguard Worker#error "INLINE_CACHE_SIZE not as expected."
2139*795d594fSAndroid Build Coastguard Worker#endif
2140*795d594fSAndroid Build Coastguard Worker    // Don't update the cache if we are marking.
2141*795d594fSAndroid Build Coastguard Worker    cmpl LITERAL(0), %fs:THREAD_IS_GC_MARKING_OFFSET
2142*795d594fSAndroid Build Coastguard Worker    jnz .Lret
2143*795d594fSAndroid Build Coastguard Worker    PUSH ecx
2144*795d594fSAndroid Build Coastguard Worker    movl %eax, %ecx // eax will be used for cmpxchg
2145*795d594fSAndroid Build Coastguard Worker.Lentry1:
2146*795d594fSAndroid Build Coastguard Worker    movl INLINE_CACHE_CLASSES_OFFSET(%ebp), %eax
2147*795d594fSAndroid Build Coastguard Worker    cmpl %ecx, %eax
2148*795d594fSAndroid Build Coastguard Worker    je .Ldone
2149*795d594fSAndroid Build Coastguard Worker    testl %eax, %eax
2150*795d594fSAndroid Build Coastguard Worker    jnz .Lentry2
2151*795d594fSAndroid Build Coastguard Worker    lock cmpxchg %ecx, INLINE_CACHE_CLASSES_OFFSET(%ebp)
2152*795d594fSAndroid Build Coastguard Worker    jz .Ldone
2153*795d594fSAndroid Build Coastguard Worker    jmp .Lentry1
2154*795d594fSAndroid Build Coastguard Worker.Lentry2:
2155*795d594fSAndroid Build Coastguard Worker    movl (INLINE_CACHE_CLASSES_OFFSET+4)(%ebp), %eax
2156*795d594fSAndroid Build Coastguard Worker    cmpl %ecx, %eax
2157*795d594fSAndroid Build Coastguard Worker    je .Ldone
2158*795d594fSAndroid Build Coastguard Worker    testl %eax, %eax
2159*795d594fSAndroid Build Coastguard Worker    jnz .Lentry3
2160*795d594fSAndroid Build Coastguard Worker    lock cmpxchg %ecx, (INLINE_CACHE_CLASSES_OFFSET+4)(%ebp)
2161*795d594fSAndroid Build Coastguard Worker    jz .Ldone
2162*795d594fSAndroid Build Coastguard Worker    jmp .Lentry2
2163*795d594fSAndroid Build Coastguard Worker.Lentry3:
2164*795d594fSAndroid Build Coastguard Worker    movl (INLINE_CACHE_CLASSES_OFFSET+8)(%ebp), %eax
2165*795d594fSAndroid Build Coastguard Worker    cmpl %ecx, %eax
2166*795d594fSAndroid Build Coastguard Worker    je .Ldone
2167*795d594fSAndroid Build Coastguard Worker    testl %eax, %eax
2168*795d594fSAndroid Build Coastguard Worker    jnz .Lentry4
2169*795d594fSAndroid Build Coastguard Worker    lock cmpxchg %ecx, (INLINE_CACHE_CLASSES_OFFSET+8)(%ebp)
2170*795d594fSAndroid Build Coastguard Worker    jz .Ldone
2171*795d594fSAndroid Build Coastguard Worker    jmp .Lentry3
2172*795d594fSAndroid Build Coastguard Worker.Lentry4:
2173*795d594fSAndroid Build Coastguard Worker    movl (INLINE_CACHE_CLASSES_OFFSET+12)(%ebp), %eax
2174*795d594fSAndroid Build Coastguard Worker    cmpl %ecx, %eax
2175*795d594fSAndroid Build Coastguard Worker    je .Ldone
2176*795d594fSAndroid Build Coastguard Worker    testl %eax, %eax
2177*795d594fSAndroid Build Coastguard Worker    jnz .Lentry5
2178*795d594fSAndroid Build Coastguard Worker    lock cmpxchg %ecx, (INLINE_CACHE_CLASSES_OFFSET+12)(%ebp)
2179*795d594fSAndroid Build Coastguard Worker    jz .Ldone
2180*795d594fSAndroid Build Coastguard Worker    jmp .Lentry4
2181*795d594fSAndroid Build Coastguard Worker.Lentry5:
2182*795d594fSAndroid Build Coastguard Worker    // Unconditionally store, the cache is megamorphic.
2183*795d594fSAndroid Build Coastguard Worker    movl %ecx, (INLINE_CACHE_CLASSES_OFFSET+16)(%ebp)
2184*795d594fSAndroid Build Coastguard Worker.Ldone:
2185*795d594fSAndroid Build Coastguard Worker    // Restore registers
2186*795d594fSAndroid Build Coastguard Worker    movl %ecx, %eax
2187*795d594fSAndroid Build Coastguard Worker    POP ecx
2188*795d594fSAndroid Build Coastguard Worker.Lret:
2189*795d594fSAndroid Build Coastguard Worker    ret
2190*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION art_quick_update_inline_cache
2191*795d594fSAndroid Build Coastguard Worker
2192*795d594fSAndroid Build Coastguard Worker    // TODO: implement these!
2193*795d594fSAndroid Build Coastguard WorkerUNIMPLEMENTED art_quick_memcmp16
2194*795d594fSAndroid Build Coastguard Worker
2195*795d594fSAndroid Build Coastguard Worker// On entry, the method is at the bottom of the stack.
2196*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION art_quick_compile_optimized
2197*795d594fSAndroid Build Coastguard Worker    SETUP_SAVE_EVERYTHING_FRAME ebx
2198*795d594fSAndroid Build Coastguard Worker    mov FRAME_SIZE_SAVE_EVERYTHING(%esp), %eax // Fetch ArtMethod
2199*795d594fSAndroid Build Coastguard Worker    sub LITERAL(8), %esp   		       // Alignment padding
2200*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(8)
2201*795d594fSAndroid Build Coastguard Worker    pushl %fs:THREAD_SELF_OFFSET               // pass Thread::Current()
2202*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
2203*795d594fSAndroid Build Coastguard Worker    pushl %eax
2204*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
2205*795d594fSAndroid Build Coastguard Worker    call SYMBOL(artCompileOptimized)           // (ArtMethod*, Thread*)
2206*795d594fSAndroid Build Coastguard Worker    addl LITERAL(16), %esp                     // Pop arguments.
2207*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(-16)
2208*795d594fSAndroid Build Coastguard Worker    RESTORE_SAVE_EVERYTHING_FRAME
2209*795d594fSAndroid Build Coastguard Worker    ret
2210*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION art_quick_compile_optimized
2211*795d594fSAndroid Build Coastguard Worker
2212*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION art_quick_method_entry_hook
2213*795d594fSAndroid Build Coastguard Worker    SETUP_SAVE_EVERYTHING_FRAME edx
2214*795d594fSAndroid Build Coastguard Worker    mov FRAME_SIZE_SAVE_EVERYTHING(%esp), %eax // Fetch ArtMethod
2215*795d594fSAndroid Build Coastguard Worker    mov %esp, %edx  // Store esp before pushing anything on stack.
2216*795d594fSAndroid Build Coastguard Worker    subl LITERAL(4), %esp
2217*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
2218*795d594fSAndroid Build Coastguard Worker
2219*795d594fSAndroid Build Coastguard Worker    push %edx                       // Pass SP
2220*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
2221*795d594fSAndroid Build Coastguard Worker    pushl %fs:THREAD_SELF_OFFSET    // Pass Thread::Current().
2222*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
2223*795d594fSAndroid Build Coastguard Worker    pushl %eax                      // Pass Method*.
2224*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
2225*795d594fSAndroid Build Coastguard Worker
2226*795d594fSAndroid Build Coastguard Worker    call SYMBOL(artMethodEntryHook) // (Method*, Thread*, SP)
2227*795d594fSAndroid Build Coastguard Worker
2228*795d594fSAndroid Build Coastguard Worker    addl LITERAL(16), %esp          // Pop arguments.
2229*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(-16)
2230*795d594fSAndroid Build Coastguard Worker
2231*795d594fSAndroid Build Coastguard Worker    CFI_REMEMBER_STATE
2232*795d594fSAndroid Build Coastguard Worker    testl %eax, %eax
2233*795d594fSAndroid Build Coastguard Worker    jnz .Lentryhook_deopt
2234*795d594fSAndroid Build Coastguard Worker
2235*795d594fSAndroid Build Coastguard Worker    // Normal return.
2236*795d594fSAndroid Build Coastguard Worker    RESTORE_SAVE_EVERYTHING_FRAME
2237*795d594fSAndroid Build Coastguard Worker    ret
2238*795d594fSAndroid Build Coastguard Worker
2239*795d594fSAndroid Build Coastguard Worker.Lentryhook_deopt:
2240*795d594fSAndroid Build Coastguard Worker    // Deoptimize.
2241*795d594fSAndroid Build Coastguard Worker    CFI_RESTORE_STATE_AND_DEF_CFA esp, FRAME_SIZE_SAVE_EVERYTHING
2242*795d594fSAndroid Build Coastguard Worker    call SYMBOL(art_quick_do_long_jump)
2243*795d594fSAndroid Build Coastguard Worker    UNREACHABLE
2244*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION art_quick_method_entry_hook
2245*795d594fSAndroid Build Coastguard Worker
2246*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION art_quick_method_exit_hook
2247*795d594fSAndroid Build Coastguard Worker    PUSH edi
2248*795d594fSAndroid Build Coastguard Worker    SETUP_SAVE_EVERYTHING_FRAME_EDI_SAVED edi
2249*795d594fSAndroid Build Coastguard Worker
2250*795d594fSAndroid Build Coastguard Worker    leal FRAME_SIZE_SAVE_EVERYTHING(%esp), %edi // Remember ArtMethod**
2251*795d594fSAndroid Build Coastguard Worker    subl LITERAL(4), %esp                       // Align stack.
2252*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
2253*795d594fSAndroid Build Coastguard Worker
2254*795d594fSAndroid Build Coastguard Worker    PUSH_ARG edx                   // Save gpr return value. edx and eax need to be together
2255*795d594fSAndroid Build Coastguard Worker                                   // which isn't the case in kSaveEverything frame.
2256*795d594fSAndroid Build Coastguard Worker    PUSH_ARG eax
2257*795d594fSAndroid Build Coastguard Worker    movl %esp, %edx                // Get pointer to gpr_result
2258*795d594fSAndroid Build Coastguard Worker    leal 28(%esp), %eax            // Get pointer to fpr_result, in kSaveEverything frame
2259*795d594fSAndroid Build Coastguard Worker    PUSH_ARG ebx                   // push frame_size
2260*795d594fSAndroid Build Coastguard Worker    PUSH_ARG eax                   // Pass fpr_result
2261*795d594fSAndroid Build Coastguard Worker    PUSH_ARG edx                   // Pass gpr_result
2262*795d594fSAndroid Build Coastguard Worker    PUSH_ARG edi                   // Pass ArtMethod**
2263*795d594fSAndroid Build Coastguard Worker    pushl %fs:THREAD_SELF_OFFSET   // Pass Thread::Current.
2264*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(4)
2265*795d594fSAndroid Build Coastguard Worker    call SYMBOL(artMethodExitHook) // (Thread*, ArtMethod**, gpr_result*, fpr_result*,
2266*795d594fSAndroid Build Coastguard Worker                                   // frame_size)
2267*795d594fSAndroid Build Coastguard Worker
2268*795d594fSAndroid Build Coastguard Worker    // Keep gpr_result in case the return result was changed.
2269*795d594fSAndroid Build Coastguard Worker    movl 20(%esp), %ecx
2270*795d594fSAndroid Build Coastguard Worker
2271*795d594fSAndroid Build Coastguard Worker    addl LITERAL(32), %esp         // Pop arguments and gpr_result.
2272*795d594fSAndroid Build Coastguard Worker    CFI_ADJUST_CFA_OFFSET(-32)
2273*795d594fSAndroid Build Coastguard Worker
2274*795d594fSAndroid Build Coastguard Worker    CFI_REMEMBER_STATE
2275*795d594fSAndroid Build Coastguard Worker    testl %eax, %eax
2276*795d594fSAndroid Build Coastguard Worker    jnz .Lexithook_deopt_or_exception
2277*795d594fSAndroid Build Coastguard Worker
2278*795d594fSAndroid Build Coastguard Worker    // Return result could have been changed if it's a reference.
2279*795d594fSAndroid Build Coastguard Worker    movl %ecx, (80)(%esp)
2280*795d594fSAndroid Build Coastguard Worker
2281*795d594fSAndroid Build Coastguard Worker    // Normal return.
2282*795d594fSAndroid Build Coastguard Worker    RESTORE_SAVE_EVERYTHING_FRAME
2283*795d594fSAndroid Build Coastguard Worker    ret
2284*795d594fSAndroid Build Coastguard Worker
2285*795d594fSAndroid Build Coastguard Worker.Lexithook_deopt_or_exception:
2286*795d594fSAndroid Build Coastguard Worker    // Deoptimize or exception thrown.
2287*795d594fSAndroid Build Coastguard Worker    CFI_RESTORE_STATE_AND_DEF_CFA esp, FRAME_SIZE_SAVE_EVERYTHING
2288*795d594fSAndroid Build Coastguard Worker    call SYMBOL(art_quick_do_long_jump)
2289*795d594fSAndroid Build Coastguard Worker    UNREACHABLE
2290*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION art_quick_method_exit_hook
2291