10f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes/*
20f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * Copyright (C) 2012 The Android Open Source Project
30f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes *
40f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
50f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * you may not use this file except in compliance with the License.
60f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * You may obtain a copy of the License at
70f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes *
80f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
90f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes *
100f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * Unless required by applicable law or agreed to in writing, software
110f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
120f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * See the License for the specific language governing permissions and
140f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * limitations under the License.
150f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes */
160f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes
177655f29fabc0a12765de828914a18314382e5a35Ian Rogers#include "asm_support_x86.S"
185e284224e5525ee0a8494a73d84c8ef86e022a0aElliott Hughes
1957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    /*
2057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     * Macro that sets up the callee save frame to conform with
217caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers     * Runtime::CreateCalleeSaveMethod(kSaveAll)
2257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     */
23787ec205ee545b9c08f4fc6d3823cb43d10083afElliott HughesMACRO0(SETUP_SAVE_ALL_CALLEE_SAVE_FRAME)
24aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH edi  // Save callee saves (ebx is saved/restored by the upcall)
25aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH esi
26aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ebp
27ea94421d5b8420857680fcddaa14345bf83cea68Elliott Hughes    subl  MACRO_LITERAL(16), %esp  // Grow stack by 4 words, bottom word will hold Method*
28aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 16
29787ec205ee545b9c08f4fc6d3823cb43d10083afElliott HughesEND_MACRO
3057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers
317caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers    /*
327caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers     * Macro that sets up the callee save frame to conform with
337caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers     * Runtime::CreateCalleeSaveMethod(kRefsOnly)
347caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers     */
357caad77632ae121c9f64c488e3f8f710e2c4813dIan RogersMACRO0(SETUP_REF_ONLY_CALLEE_SAVE_FRAME)
36aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH edi  // Save callee saves (ebx is saved/restored by the upcall)
37aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH esi
38aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ebp
39ea94421d5b8420857680fcddaa14345bf83cea68Elliott Hughes    subl  MACRO_LITERAL(16), %esp  // Grow stack by 4 words, bottom word will hold Method*
40aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 16
417caad77632ae121c9f64c488e3f8f710e2c4813dIan RogersEND_MACRO
427caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers
437caad77632ae121c9f64c488e3f8f710e2c4813dIan RogersMACRO0(RESTORE_REF_ONLY_CALLEE_SAVE_FRAME)
44ea94421d5b8420857680fcddaa14345bf83cea68Elliott Hughes    addl MACRO_LITERAL(28), %esp  // Unwind stack up to return address
45aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset -28
46787ec205ee545b9c08f4fc6d3823cb43d10083afElliott HughesEND_MACRO
4757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers
4857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    /*
4957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     * Macro that sets up the callee save frame to conform with
507caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers     * Runtime::CreateCalleeSaveMethod(kRefsAndArgs)
5157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     */
529dbb23e997f84d7c6c909b246e3faca50a912336jeffhaoMACRO0(SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME)
53aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH edi  // Save callee saves
54aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH esi
55aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ebp
56aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ebx  // Save args
57aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH edx
58aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ecx
59aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH eax   // Align stack, eax will be clobbered by Method*
60787ec205ee545b9c08f4fc6d3823cb43d10083afElliott HughesEND_MACRO
6157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers
629dbb23e997f84d7c6c909b246e3faca50a912336jeffhaoMACRO0(RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME)
63ea94421d5b8420857680fcddaa14345bf83cea68Elliott Hughes    addl MACRO_LITERAL(4), %esp  // Remove padding
64aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset -4
65aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    POP ecx  // Restore args except eax
66aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    POP edx
67aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    POP ebx
68aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    POP ebp  // Restore callee saves
69aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    POP esi
70aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    POP edi
71787ec205ee545b9c08f4fc6d3823cb43d10083afElliott HughesEND_MACRO
7257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers
7357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    /*
7457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     * Macro that set calls through to artDeliverPendingExceptionFromCode, where the pending
7557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     * exception is Thread::Current()->exception_.
7657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     */
77787ec205ee545b9c08f4fc6d3823cb43d10083afElliott HughesMACRO0(DELIVER_PENDING_EXCEPTION)
7857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    SETUP_SAVE_ALL_CALLEE_SAVE_FRAME         // save callee saves for throw
7957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    mov %esp, %ecx
8057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    // Outgoing argument set up
81ea94421d5b8420857680fcddaa14345bf83cea68Elliott Hughes    subl  MACRO_LITERAL(8), %esp             // Alignment padding
82aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 8
83aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ecx                                 // pass SP
8457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    pushl %fs:THREAD_SELF_OFFSET             // pass Thread::Current()
85aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 4
869dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    call SYMBOL(artDeliverPendingExceptionFromCode)  // artDeliverPendingExceptionFromCode(Thread*, SP)
879dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    int3                                     // unreached
88787ec205ee545b9c08f4fc6d3823cb43d10083afElliott HughesEND_MACRO
8957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers
90787ec205ee545b9c08f4fc6d3823cb43d10083afElliott HughesMACRO2(NO_ARG_RUNTIME_EXCEPTION, c_name, cxx_name)
91aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    DEFINE_FUNCTION VAR(c_name, 0)
9257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    SETUP_SAVE_ALL_CALLEE_SAVE_FRAME  // save all registers as basis for long jump context
9357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    mov %esp, %ecx
9457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    // Outgoing argument set up
95ea94421d5b8420857680fcddaa14345bf83cea68Elliott Hughes    subl  MACRO_LITERAL(8), %esp  // alignment padding
96aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 8
97aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ecx                      // pass SP
9855bd45f4ea40b9a0af323f813d07f23d7a8ed397Ian Rogers    pushl %fs:THREAD_SELF_OFFSET  // pass Thread::Current()
99aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 4
100787ec205ee545b9c08f4fc6d3823cb43d10083afElliott Hughes    call VAR(cxx_name, 1)         // cxx_name(Thread*, SP)
10157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    int3                          // unreached
102aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    END_FUNCTION VAR(c_name, 0)
103787ec205ee545b9c08f4fc6d3823cb43d10083afElliott HughesEND_MACRO
10457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers
105787ec205ee545b9c08f4fc6d3823cb43d10083afElliott HughesMACRO2(ONE_ARG_RUNTIME_EXCEPTION, c_name, cxx_name)
106aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    DEFINE_FUNCTION VAR(c_name, 0)
10757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    SETUP_SAVE_ALL_CALLEE_SAVE_FRAME  // save all registers as basis for long jump context
10857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    mov %esp, %ecx
10957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    // Outgoing argument set up
110aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH eax                      // alignment padding
111aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ecx                      // pass SP
11257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    pushl %fs:THREAD_SELF_OFFSET  // pass Thread::Current()
113aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 4
114aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH eax                      // pass arg1
115787ec205ee545b9c08f4fc6d3823cb43d10083afElliott Hughes    call VAR(cxx_name, 1)         // cxx_name(arg1, Thread*, SP)
11657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    int3                          // unreached
117aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    END_FUNCTION VAR(c_name, 0)
118787ec205ee545b9c08f4fc6d3823cb43d10083afElliott HughesEND_MACRO
11957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers
120787ec205ee545b9c08f4fc6d3823cb43d10083afElliott HughesMACRO2(TWO_ARG_RUNTIME_EXCEPTION, c_name, cxx_name)
121aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    DEFINE_FUNCTION VAR(c_name, 0)
12257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    SETUP_SAVE_ALL_CALLEE_SAVE_FRAME  // save all registers as basis for long jump context
12357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    mov %esp, %edx
12457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    // Outgoing argument set up
125aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH edx                      // pass SP
12657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    pushl %fs:THREAD_SELF_OFFSET  // pass Thread::Current()
127aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 4
128aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ecx                      // pass arg2
129aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH eax                      // pass arg1
1307caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers    call VAR(cxx_name, 1)         // cxx_name(arg1, arg2, Thread*, SP)
13157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    int3                          // unreached
132aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    END_FUNCTION VAR(c_name, 0)
133787ec205ee545b9c08f4fc6d3823cb43d10083afElliott HughesEND_MACRO
13457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers
13557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    /*
13657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     * Called by managed code to create and deliver a NullPointerException.
13757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     */
138468532ea115657709bc32ee498e701a4c71762d4Ian RogersNO_ARG_RUNTIME_EXCEPTION art_quick_throw_null_pointer_exception, artThrowNullPointerExceptionFromCode
13957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers
14057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    /*
14157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     * Called by managed code to create and deliver an ArithmeticException.
14257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     */
143468532ea115657709bc32ee498e701a4c71762d4Ian RogersNO_ARG_RUNTIME_EXCEPTION art_quick_throw_div_zero, artThrowDivZeroFromCode
14457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers
14557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    /*
146787ec205ee545b9c08f4fc6d3823cb43d10083afElliott Hughes     * Called by managed code to create and deliver a StackOverflowError.
14757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     */
148468532ea115657709bc32ee498e701a4c71762d4Ian RogersNO_ARG_RUNTIME_EXCEPTION art_quick_throw_stack_overflow, artThrowStackOverflowFromCode
14957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers
15057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    /*
151787ec205ee545b9c08f4fc6d3823cb43d10083afElliott Hughes     * Called by managed code, saves callee saves and then calls artThrowException
152787ec205ee545b9c08f4fc6d3823cb43d10083afElliott Hughes     * that will place a mock Method* at the bottom of the stack. Arg1 holds the exception.
15357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     */
154468532ea115657709bc32ee498e701a4c71762d4Ian RogersONE_ARG_RUNTIME_EXCEPTION art_quick_deliver_exception, artDeliverExceptionFromCode
15557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers
15657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    /*
15757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     * Called by managed code to create and deliver a NoSuchMethodError.
15857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     */
159468532ea115657709bc32ee498e701a4c71762d4Ian RogersONE_ARG_RUNTIME_EXCEPTION art_quick_throw_no_such_method, artThrowNoSuchMethodFromCode
16057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers
16157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    /*
162787ec205ee545b9c08f4fc6d3823cb43d10083afElliott Hughes     * Called by managed code to create and deliver an ArrayIndexOutOfBoundsException. Arg1 holds
163787ec205ee545b9c08f4fc6d3823cb43d10083afElliott Hughes     * index, arg2 holds limit.
164787ec205ee545b9c08f4fc6d3823cb43d10083afElliott Hughes     */
165468532ea115657709bc32ee498e701a4c71762d4Ian RogersTWO_ARG_RUNTIME_EXCEPTION art_quick_throw_array_bounds, artThrowArrayBoundsFromCode
166787ec205ee545b9c08f4fc6d3823cb43d10083afElliott Hughes
167787ec205ee545b9c08f4fc6d3823cb43d10083afElliott Hughes    /*
16857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     * All generated callsites for interface invokes and invocation slow paths will load arguments
16957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     * as usual - except instead of loading arg0/r0 with the target Method*, arg0/r0 will contain
17057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     * the method_idx.  This wrapper will save arg1-arg3, load the caller's Method*, align the
17157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     * stack and call the appropriate C helper.
17257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     * NOTE: "this" is first visible argument of the target, and so can be found in arg1/r1.
17357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     *
17457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     * The helper will attempt to locate the target and return a 64-bit result in r0/r1 consisting
17557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     * of the target Method* in r0 and method->code_ in r1.
17657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     *
17757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     * If unsuccessful, the helper will return NULL/NULL. There will bea pending exception in the
17857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     * thread and we branch to another stub to deliver it.
17957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     *
18057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     * On success this wrapper will restore arguments and *jump* to the target, leaving the lr
18157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     * pointing back to the original caller.
18257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     */
183787ec205ee545b9c08f4fc6d3823cb43d10083afElliott HughesMACRO2(INVOKE_TRAMPOLINE, c_name, cxx_name)
184aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    DEFINE_FUNCTION VAR(c_name, 0)
1857caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers    // Set up the callee save frame to conform with Runtime::CreateCalleeSaveMethod(kRefsAndArgs)
1867caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers    // return address
187aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH edi
188aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH esi
189aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ebp
190aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ebx
191aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH edx
192aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ecx
193aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH eax   // <-- callee save Method* to go here
1947caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers    movl %esp, %edx  // remember SP
1957caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers    // Outgoing argument set up
196ea94421d5b8420857680fcddaa14345bf83cea68Elliott Hughes    subl MACRO_LITERAL(12), %esp  // alignment padding
197aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 12
198aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH edx                      // pass SP
1997caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers    pushl %fs:THREAD_SELF_OFFSET  // pass Thread::Current()
200aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 4
2017caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers    pushl 32(%edx)                // pass caller Method*
202aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 4
203aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ecx                      // pass arg2
204aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH eax                      // pass arg1
2057caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers    call VAR(cxx_name, 1)         // cxx_name(arg1, arg2, arg3, Thread*, SP)
2067caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers    movl %edx, %edi               // save code pointer in EDI
207ea94421d5b8420857680fcddaa14345bf83cea68Elliott Hughes    addl MACRO_LITERAL(36), %esp  // Pop arguments skip eax
208aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset -36
209aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    POP ecx                       // Restore args
210aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    POP edx
211aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    POP ebx
212aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    POP ebp  // Restore callee saves.
213aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    POP esi
2147caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers    // Swap EDI callee save with code pointer.
2157caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers    xchgl %edi, (%esp)
2167caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers    testl %eax, %eax              // Branch forward if exception pending.
2177caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers    jz    1f
2187caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers    // Tail call to intended method.
2197caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers    ret
2207caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers1:
22120b5c6c9d6fdd0b4192d467086a097a28d7b3a0ajeffhao    addl MACRO_LITERAL(4), %esp   // Pop code pointer off stack
2225793feaaafef40625b010429f3f79d8ee0bdfe28Ian Rogers    .cfi_adjust_cfa_offset -4
2237caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers    DELIVER_PENDING_EXCEPTION
224aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    END_FUNCTION VAR(c_name, 0)
225787ec205ee545b9c08f4fc6d3823cb43d10083afElliott HughesEND_MACRO
22657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers
2278dbb708c7dc05c786329eb5c3fff3194ab6472acLogan ChienINVOKE_TRAMPOLINE art_quick_invoke_interface_trampoline, artInvokeInterfaceTrampoline
2288dbb708c7dc05c786329eb5c3fff3194ab6472acLogan ChienINVOKE_TRAMPOLINE art_quick_invoke_interface_trampoline_with_access_check, artInvokeInterfaceTrampolineWithAccessCheck
22957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers
2308dbb708c7dc05c786329eb5c3fff3194ab6472acLogan ChienINVOKE_TRAMPOLINE art_quick_invoke_static_trampoline_with_access_check, artInvokeStaticTrampolineWithAccessCheck
2318dbb708c7dc05c786329eb5c3fff3194ab6472acLogan ChienINVOKE_TRAMPOLINE art_quick_invoke_direct_trampoline_with_access_check, artInvokeDirectTrampolineWithAccessCheck
2328dbb708c7dc05c786329eb5c3fff3194ab6472acLogan ChienINVOKE_TRAMPOLINE art_quick_invoke_super_trampoline_with_access_check, artInvokeSuperTrampolineWithAccessCheck
2338dbb708c7dc05c786329eb5c3fff3194ab6472acLogan ChienINVOKE_TRAMPOLINE art_quick_invoke_virtual_trampoline_with_access_check, artInvokeVirtualTrampolineWithAccessCheck
23457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers
2355d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    /*
2366474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao     * Quick invocation stub.
2376474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao     * On entry:
2386474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao     *   [sp] = return address
2396474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao     *   [sp + 4] = method pointer
2406474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao     *   [sp + 8] = argument array or NULL for no argument methods
2416474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao     *   [sp + 12] = size of argument array in bytes
2426474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao     *   [sp + 16] = (managed) thread pointer
2436474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao     *   [sp + 20] = JValue* result
2446474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao     *   [sp + 24] = result type char
2455d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao     */
2465d9173014c1ca09f7249a6b07629aa37778b5f8fJeff HaoDEFINE_FUNCTION art_quick_invoke_stub
2475d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    PUSH ebp                      // save ebp
2485d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    PUSH ebx                      // save ebx
2495d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    mov %esp, %ebp                // copy value of stack pointer into base pointer
2505d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    .cfi_def_cfa_register ebp
2515d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    mov 20(%ebp), %ebx            // get arg array size
2525d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    addl LITERAL(28), %ebx        // reserve space for return addr, method*, ebx, and ebp in frame
2536474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao    andl LITERAL(0xFFFFFFF0), %ebx    // align frame size to 16 bytes
2545d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    subl LITERAL(12), %ebx        // remove space for return address, ebx, and ebp
2555d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    subl %ebx, %esp               // reserve stack space for argument array
2565d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    lea  4(%esp), %eax            // use stack pointer + method ptr as dest for memcpy
2575d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    pushl 20(%ebp)                // push size of region to memcpy
2585d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    pushl 16(%ebp)                // push arg array as source of memcpy
2595d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    pushl %eax                    // push stack pointer as destination of memcpy
2605d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    call SYMBOL(memcpy)           // (void*, const void*, size_t)
2615d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    addl LITERAL(12), %esp        // pop arguments to memcpy
2625d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    movl LITERAL(0), (%esp)       // store NULL for method*
2635d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    mov 12(%ebp), %eax            // move method pointer into eax
2645d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    mov 4(%esp), %ecx             // copy arg1 into ecx
2655d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    mov 8(%esp), %edx             // copy arg2 into edx
2665d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    mov 12(%esp), %ebx            // copy arg3 into ebx
267225ade2eef559a8609879f142789a4f59aec5704Ian Rogers    call *METHOD_CODE_OFFSET(%eax) // call the method
2685d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    mov %ebp, %esp                // restore stack pointer
2695d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    POP ebx                       // pop ebx
2705d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    POP ebp                       // pop ebp
2715d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    mov 20(%esp), %ecx            // get result pointer
2726474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao    cmpl LITERAL(68), 24(%esp)    // test if result type char == 'D'
2736474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao    je return_double_quick
2746474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao    cmpl LITERAL(70), 24(%esp)    // test if result type char == 'F'
2756474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao    je return_float_quick
2765d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    mov %eax, (%ecx)              // store the result
2775d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    mov %edx, 4(%ecx)             // store the other half of the result
2786474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao    ret
2796474d190d5604898354ebf767f1944b6e3e9b445Jeff Haoreturn_double_quick:
2806474d190d5604898354ebf767f1944b6e3e9b445Jeff Haoreturn_float_quick:
2815d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    movsd %xmm0, (%ecx)           // store the floating point result
2825d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    ret
2835d9173014c1ca09f7249a6b07629aa37778b5f8fJeff HaoEND_FUNCTION art_quick_invoke_stub
2845d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao
285d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan RogersMACRO3(NO_ARG_DOWNCALL, c_name, cxx_name, return_macro)
286aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    DEFINE_FUNCTION VAR(c_name, 0)
2877caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers    SETUP_REF_ONLY_CALLEE_SAVE_FRAME  // save ref containing registers for GC
2887caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers    mov %esp, %edx                // remember SP
2897caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers    // Outgoing argument set up
290d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers    subl MACRO_LITERAL(8), %esp   // push padding
291aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 8
292aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH edx                      // pass SP
2937caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers    pushl %fs:THREAD_SELF_OFFSET  // pass Thread::Current()
294aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 4
295d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers    call VAR(cxx_name, 1)         // cxx_name(Thread*, SP)
296ea94421d5b8420857680fcddaa14345bf83cea68Elliott Hughes    addl MACRO_LITERAL(16), %esp  // pop arguments
297aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset -16
2987caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers    RESTORE_REF_ONLY_CALLEE_SAVE_FRAME  // restore frame up to return address
299754caaab12e1288b3be98417ca17c3931bb69ea8Elliott Hughes    CALL_MACRO(return_macro, 2)   // return or deliver exception
300aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    END_FUNCTION VAR(c_name, 0)
3017caad77632ae121c9f64c488e3f8f710e2c4813dIan RogersEND_MACRO
3027caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers
303d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan RogersMACRO3(ONE_ARG_DOWNCALL, c_name, cxx_name, return_macro)
304aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    DEFINE_FUNCTION VAR(c_name, 0)
3057caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers    SETUP_REF_ONLY_CALLEE_SAVE_FRAME  // save ref containing registers for GC
3067caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers    mov %esp, %edx                // remember SP
3077caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers    // Outgoing argument set up
308aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH eax                      // push padding
309aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH edx                      // pass SP
3107caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers    pushl %fs:THREAD_SELF_OFFSET  // pass Thread::Current()
311aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 4
312aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH eax                      // pass arg1
313d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers    call VAR(cxx_name, 1)         // cxx_name(arg1, Thread*, SP)
314d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers    addl MACRO_LITERAL(16), %esp  // pop arguments
315aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset -16
3167caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers    RESTORE_REF_ONLY_CALLEE_SAVE_FRAME  // restore frame up to return address
317754caaab12e1288b3be98417ca17c3931bb69ea8Elliott Hughes    CALL_MACRO(return_macro, 2)   // return or deliver exception
318aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    END_FUNCTION VAR(c_name, 0)
319d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan RogersEND_MACRO
3207caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers
321d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan RogersMACRO3(TWO_ARG_DOWNCALL, c_name, cxx_name, return_macro)
322aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    DEFINE_FUNCTION VAR(c_name, 0)
3237caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers    SETUP_REF_ONLY_CALLEE_SAVE_FRAME  // save ref containing registers for GC
3247caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers    mov %esp, %edx                // remember SP
3257caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers    // Outgoing argument set up
326aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH edx                      // pass SP
3277caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers    pushl %fs:THREAD_SELF_OFFSET  // pass Thread::Current()
328aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 4
329aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ecx                      // pass arg2
330aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH eax                      // pass arg1
331d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers    call VAR(cxx_name, 1)         // cxx_name(arg1, arg2, Thread*, SP)
332d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers    addl MACRO_LITERAL(16), %esp  // pop arguments
333aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset -16
3347caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers    RESTORE_REF_ONLY_CALLEE_SAVE_FRAME  // restore frame up to return address
335754caaab12e1288b3be98417ca17c3931bb69ea8Elliott Hughes    CALL_MACRO(return_macro, 2)   // return or deliver exception
336aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    END_FUNCTION VAR(c_name, 0)
337d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan RogersEND_MACRO
3387caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers
339d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan RogersMACRO3(THREE_ARG_DOWNCALL, c_name, cxx_name, return_macro)
340aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    DEFINE_FUNCTION VAR(c_name, 0)
3417caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers    SETUP_REF_ONLY_CALLEE_SAVE_FRAME  // save ref containing registers for GC
342d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers    mov %esp, %ebx                // remember SP
3437caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers    // Outgoing argument set up
344d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers    subl MACRO_LITERAL(12), %esp  // alignment padding
345aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 12
346aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ebx                      // pass SP
3477caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers    pushl %fs:THREAD_SELF_OFFSET  // pass Thread::Current()
348aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 4
349aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH edx                      // pass arg3
350aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ecx                      // pass arg2
351aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH eax                      // pass arg1
352d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers    call VAR(cxx_name, 1)         // cxx_name(arg1, arg2, arg3, Thread*, SP)
353d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers    addl MACRO_LITERAL(32), %esp  // pop arguments
354aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset -32
3557caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers    RESTORE_REF_ONLY_CALLEE_SAVE_FRAME  // restore frame up to return address
356754caaab12e1288b3be98417ca17c3931bb69ea8Elliott Hughes    CALL_MACRO(return_macro, 2)   // return or deliver exception
357aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    END_FUNCTION VAR(c_name, 0)
358d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan RogersEND_MACRO
359d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers
360d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan RogersMACRO0(RETURN_IF_EAX_NOT_ZERO)
361d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers    testl %eax, %eax               // eax == 0 ?
362d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers    jz  1f                         // if eax == 0 goto 1
363d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers    ret                            // return
364d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers1:                                 // deliver exception on current thread
365d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers    DELIVER_PENDING_EXCEPTION
366d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan RogersEND_MACRO
367d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers
368d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan RogersMACRO0(RETURN_IF_EAX_ZERO)
369d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers    testl %eax, %eax               // eax == 0 ?
370d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers    jnz  1f                        // if eax != 0 goto 1
371d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers    ret                            // return
372d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers1:                                 // deliver exception on current thread
3737caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers    DELIVER_PENDING_EXCEPTION
374d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan RogersEND_MACRO
375d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers
376d66a87583bebcd5f89906aeaae9f8fb104ef2ac9jeffhaoMACRO0(RETURN_OR_DELIVER_PENDING_EXCEPTION)
377d66a87583bebcd5f89906aeaae9f8fb104ef2ac9jeffhao    mov %fs:THREAD_EXCEPTION_OFFSET, %ebx // get exception field
378d66a87583bebcd5f89906aeaae9f8fb104ef2ac9jeffhao    testl %ebx, %ebx               // ebx == 0 ?
379d66a87583bebcd5f89906aeaae9f8fb104ef2ac9jeffhao    jnz 1f                         // if ebx != 0 goto 1
380d66a87583bebcd5f89906aeaae9f8fb104ef2ac9jeffhao    ret                            // return
381d66a87583bebcd5f89906aeaae9f8fb104ef2ac9jeffhao1:                                 // deliver exception on current thread
382d66a87583bebcd5f89906aeaae9f8fb104ef2ac9jeffhao    DELIVER_PENDING_EXCEPTION
383d66a87583bebcd5f89906aeaae9f8fb104ef2ac9jeffhaoEND_MACRO
384d66a87583bebcd5f89906aeaae9f8fb104ef2ac9jeffhao
385468532ea115657709bc32ee498e701a4c71762d4Ian RogersTWO_ARG_DOWNCALL art_quick_alloc_object, artAllocObjectFromCode, RETURN_IF_EAX_NOT_ZERO
386468532ea115657709bc32ee498e701a4c71762d4Ian RogersTWO_ARG_DOWNCALL art_quick_alloc_object_with_access_check, artAllocObjectFromCodeWithAccessCheck, RETURN_IF_EAX_NOT_ZERO
387468532ea115657709bc32ee498e701a4c71762d4Ian RogersTHREE_ARG_DOWNCALL art_quick_alloc_array, artAllocArrayFromCode, RETURN_IF_EAX_NOT_ZERO
388468532ea115657709bc32ee498e701a4c71762d4Ian RogersTHREE_ARG_DOWNCALL art_quick_alloc_array_with_access_check, artAllocArrayFromCodeWithAccessCheck, RETURN_IF_EAX_NOT_ZERO
389468532ea115657709bc32ee498e701a4c71762d4Ian RogersTHREE_ARG_DOWNCALL art_quick_check_and_alloc_array, artCheckAndAllocArrayFromCode, RETURN_IF_EAX_NOT_ZERO
390468532ea115657709bc32ee498e701a4c71762d4Ian RogersTHREE_ARG_DOWNCALL art_quick_check_and_alloc_array_with_access_check, artCheckAndAllocArrayFromCodeWithAccessCheck, RETURN_IF_EAX_NOT_ZERO
391d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers
392468532ea115657709bc32ee498e701a4c71762d4Ian RogersTWO_ARG_DOWNCALL art_quick_resolve_string, artResolveStringFromCode, RETURN_IF_EAX_NOT_ZERO
393468532ea115657709bc32ee498e701a4c71762d4Ian RogersTWO_ARG_DOWNCALL art_quick_initialize_static_storage, artInitializeStaticStorageFromCode, RETURN_IF_EAX_NOT_ZERO
394468532ea115657709bc32ee498e701a4c71762d4Ian RogersTWO_ARG_DOWNCALL art_quick_initialize_type, artInitializeTypeFromCode, RETURN_IF_EAX_NOT_ZERO
395468532ea115657709bc32ee498e701a4c71762d4Ian RogersTWO_ARG_DOWNCALL art_quick_initialize_type_and_verify_access, artInitializeTypeAndVerifyAccessFromCode, RETURN_IF_EAX_NOT_ZERO
396d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers
397468532ea115657709bc32ee498e701a4c71762d4Ian RogersONE_ARG_DOWNCALL art_quick_lock_object, artLockObjectFromCode, ret
398468532ea115657709bc32ee498e701a4c71762d4Ian RogersONE_ARG_DOWNCALL art_quick_unlock_object, artUnlockObjectFromCode, RETURN_IF_EAX_ZERO
399d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers
400468532ea115657709bc32ee498e701a4c71762d4Ian RogersTWO_ARG_DOWNCALL art_quick_handle_fill_data, artHandleFillArrayDataFromCode, RETURN_IF_EAX_ZERO
4017caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers
402468532ea115657709bc32ee498e701a4c71762d4Ian RogersDEFINE_FUNCTION art_quick_is_assignable
403aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH eax                     // alignment padding
404aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ecx                    // pass arg2
405aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH eax                     // pass arg1
406adc078a61329fa86bc93532f7827302b99c0b41dElliott Hughes    call SYMBOL(artIsAssignableFromCode)  // (Class* a, Class* b, Thread*, SP)
40755bd45f4ea40b9a0af323f813d07f23d7a8ed397Ian Rogers    addl LITERAL(12), %esp        // pop arguments
408aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset -12
4097caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers    ret
410468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND_FUNCTION art_quick_is_assignable
4117caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers
4128dbb708c7dc05c786329eb5c3fff3194ab6472acLogan ChienDEFINE_FUNCTION art_quick_memcpy
413aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH edx                      // pass arg3
414aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ecx                      // pass arg2
415aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH eax                      // pass arg1
416adc078a61329fa86bc93532f7827302b99c0b41dElliott Hughes    call SYMBOL(memcpy)           // (void*, const void*, size_t)
41755bd45f4ea40b9a0af323f813d07f23d7a8ed397Ian Rogers    addl LITERAL(12), %esp        // pop arguments
418aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset -12
4197caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers    ret
420aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian RogersEND_FUNCTION art_quick_memcpy
4217caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers
422468532ea115657709bc32ee498e701a4c71762d4Ian RogersTWO_ARG_DOWNCALL art_quick_check_cast, artCheckCastFromCode, RETURN_IF_EAX_ZERO
423468532ea115657709bc32ee498e701a4c71762d4Ian RogersTWO_ARG_DOWNCALL art_quick_can_put_array_element, artCanPutArrayElementFromCode, RETURN_IF_EAX_ZERO
424d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers
4258dbb708c7dc05c786329eb5c3fff3194ab6472acLogan ChienNO_ARG_DOWNCALL art_quick_test_suspend, artTestSuspendFromCode, ret
4267caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers
427468532ea115657709bc32ee498e701a4c71762d4Ian RogersDEFINE_FUNCTION art_quick_fmod
4281395b1e06c1d0ff5155b0c5d113ad3bd6f163c07jeffhao    subl LITERAL(12), %esp        // alignment padding
429aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 12
430aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ebx                      // pass arg4 b.hi
431aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH edx                      // pass arg3 b.lo
432aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ecx                      // pass arg2 a.hi
433aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH eax                      // pass arg1 a.lo
4341395b1e06c1d0ff5155b0c5d113ad3bd6f163c07jeffhao    call SYMBOL(fmod)             // (jdouble a, jdouble b)
4351395b1e06c1d0ff5155b0c5d113ad3bd6f163c07jeffhao    fstpl (%esp)                  // pop return value off fp stack
4361395b1e06c1d0ff5155b0c5d113ad3bd6f163c07jeffhao    movsd (%esp), %xmm0           // place into %xmm0
4371395b1e06c1d0ff5155b0c5d113ad3bd6f163c07jeffhao    addl LITERAL(28), %esp        // pop arguments
438aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset -28
439292188d514c9826971308a18fcc5a66261729f3bjeffhao    ret
440468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND_FUNCTION art_quick_fmod
441292188d514c9826971308a18fcc5a66261729f3bjeffhao
442468532ea115657709bc32ee498e701a4c71762d4Ian RogersDEFINE_FUNCTION art_quick_fmodf
443aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH eax                      // alignment padding
444aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ecx                      // pass arg2 b
445aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH eax                      // pass arg1 a
4461395b1e06c1d0ff5155b0c5d113ad3bd6f163c07jeffhao    call SYMBOL(fmodf)            // (jfloat a, jfloat b)
4471b09b094a85e03f6ef5f687f58bb91c433273ba1Ian Rogers    fstps (%esp)                  // pop return value off fp stack
4481395b1e06c1d0ff5155b0c5d113ad3bd6f163c07jeffhao    movss (%esp), %xmm0           // place into %xmm0
4491395b1e06c1d0ff5155b0c5d113ad3bd6f163c07jeffhao    addl LITERAL(12), %esp        // pop arguments
450aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset -12
451292188d514c9826971308a18fcc5a66261729f3bjeffhao    ret
452468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND_FUNCTION art_quick_fmodf
453292188d514c9826971308a18fcc5a66261729f3bjeffhao
454468532ea115657709bc32ee498e701a4c71762d4Ian RogersDEFINE_FUNCTION art_quick_l2d
4555793feaaafef40625b010429f3f79d8ee0bdfe28Ian Rogers    PUSH ecx                      // push arg2 a.hi
4565793feaaafef40625b010429f3f79d8ee0bdfe28Ian Rogers    PUSH eax                      // push arg1 a.lo
4575793feaaafef40625b010429f3f79d8ee0bdfe28Ian Rogers    fildll (%esp)                 // load as integer and push into st0
4585793feaaafef40625b010429f3f79d8ee0bdfe28Ian Rogers    fstpl (%esp)                  // pop value off fp stack as double
45941005ddb5576b8630a1084fbb3979ffa602c0599jeffhao    movsd (%esp), %xmm0           // place into %xmm0
4605793feaaafef40625b010429f3f79d8ee0bdfe28Ian Rogers    addl LITERAL(8), %esp         // pop arguments
4615793feaaafef40625b010429f3f79d8ee0bdfe28Ian Rogers    .cfi_adjust_cfa_offset -8
46241005ddb5576b8630a1084fbb3979ffa602c0599jeffhao    ret
463468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND_FUNCTION art_quick_l2d
46441005ddb5576b8630a1084fbb3979ffa602c0599jeffhao
465468532ea115657709bc32ee498e701a4c71762d4Ian RogersDEFINE_FUNCTION art_quick_l2f
4665793feaaafef40625b010429f3f79d8ee0bdfe28Ian Rogers    PUSH ecx                      // push arg2 a.hi
4675793feaaafef40625b010429f3f79d8ee0bdfe28Ian Rogers    PUSH eax                      // push arg1 a.lo
4685793feaaafef40625b010429f3f79d8ee0bdfe28Ian Rogers    fildll (%esp)                 // load as integer and push into st0
4695793feaaafef40625b010429f3f79d8ee0bdfe28Ian Rogers    fstps (%esp)                  // pop value off fp stack as a single
47041005ddb5576b8630a1084fbb3979ffa602c0599jeffhao    movss (%esp), %xmm0           // place into %xmm0
4715793feaaafef40625b010429f3f79d8ee0bdfe28Ian Rogers    addl LITERAL(8), %esp         // pop argument
4725793feaaafef40625b010429f3f79d8ee0bdfe28Ian Rogers    .cfi_adjust_cfa_offset -8
47341005ddb5576b8630a1084fbb3979ffa602c0599jeffhao    ret
474468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND_FUNCTION art_quick_l2f
47541005ddb5576b8630a1084fbb3979ffa602c0599jeffhao
476468532ea115657709bc32ee498e701a4c71762d4Ian RogersDEFINE_FUNCTION art_quick_d2l
477aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH eax                      // alignment padding
478aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ecx                      // pass arg2 a.hi
479aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH eax                      // pass arg1 a.lo
4801395b1e06c1d0ff5155b0c5d113ad3bd6f163c07jeffhao    call SYMBOL(art_d2l)          // (jdouble a)
48141005ddb5576b8630a1084fbb3979ffa602c0599jeffhao    addl LITERAL(12), %esp        // pop arguments
482aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset -12
48341005ddb5576b8630a1084fbb3979ffa602c0599jeffhao    ret
484468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND_FUNCTION art_quick_d2l
48541005ddb5576b8630a1084fbb3979ffa602c0599jeffhao
486468532ea115657709bc32ee498e701a4c71762d4Ian RogersDEFINE_FUNCTION art_quick_f2l
48741005ddb5576b8630a1084fbb3979ffa602c0599jeffhao    subl LITERAL(8), %esp         // alignment padding
4885793feaaafef40625b010429f3f79d8ee0bdfe28Ian Rogers    .cfi_adjust_cfa_offset 8
489aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH eax                      // pass arg1 a
4901395b1e06c1d0ff5155b0c5d113ad3bd6f163c07jeffhao    call SYMBOL(art_f2l)          // (jfloat a)
49141005ddb5576b8630a1084fbb3979ffa602c0599jeffhao    addl LITERAL(12), %esp        // pop arguments
492aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset -12
49341005ddb5576b8630a1084fbb3979ffa602c0599jeffhao    ret
494468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND_FUNCTION art_quick_f2l
49541005ddb5576b8630a1084fbb3979ffa602c0599jeffhao
496468532ea115657709bc32ee498e701a4c71762d4Ian RogersDEFINE_FUNCTION art_quick_idivmod
497174651dea03956e160a2cff0d842954823c49134jeffhao    cmpl LITERAL(0x80000000), %eax
498174651dea03956e160a2cff0d842954823c49134jeffhao    je check_arg2  // special case
499174651dea03956e160a2cff0d842954823c49134jeffhaoargs_ok:
5007caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers    cdq         // edx:eax = sign extend eax
5017caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers    idiv %ecx   // (edx,eax) = (edx:eax % ecx, edx:eax / ecx)
5027caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers    ret
503174651dea03956e160a2cff0d842954823c49134jeffhaocheck_arg2:
504174651dea03956e160a2cff0d842954823c49134jeffhao    cmpl LITERAL(-1), %ecx
505174651dea03956e160a2cff0d842954823c49134jeffhao    jne args_ok
506174651dea03956e160a2cff0d842954823c49134jeffhao    xorl %edx, %edx
507174651dea03956e160a2cff0d842954823c49134jeffhao    ret         // eax already holds min int
508468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND_FUNCTION art_quick_idivmod
5097caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers
510468532ea115657709bc32ee498e701a4c71762d4Ian RogersDEFINE_FUNCTION art_quick_ldiv
511141d62275f207bf68c55f583fb206fe586d857cfIan Rogers    subl LITERAL(12), %esp        // alignment padding
512aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 12
513aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ebx                     // pass arg4 b.hi
514aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH edx                     // pass arg3 b.lo
515aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ecx                     // pass arg2 a.hi
516aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH eax                      // pass arg1 a.lo
5171395b1e06c1d0ff5155b0c5d113ad3bd6f163c07jeffhao    call SYMBOL(artLdivFromCode)  // (jlong a, jlong b)
51855bd45f4ea40b9a0af323f813d07f23d7a8ed397Ian Rogers    addl LITERAL(28), %esp        // pop arguments
519aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset -28
52055bd45f4ea40b9a0af323f813d07f23d7a8ed397Ian Rogers    ret
521468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND_FUNCTION art_quick_ldiv
52255bd45f4ea40b9a0af323f813d07f23d7a8ed397Ian Rogers
523468532ea115657709bc32ee498e701a4c71762d4Ian RogersDEFINE_FUNCTION art_quick_ldivmod
524141d62275f207bf68c55f583fb206fe586d857cfIan Rogers    subl LITERAL(12), %esp        // alignment padding
525aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 12
526aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ebx                     // pass arg4 b.hi
527aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH edx                     // pass arg3 b.lo
528aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ecx                     // pass arg2 a.hi
529aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH eax                      // pass arg1 a.lo
5301395b1e06c1d0ff5155b0c5d113ad3bd6f163c07jeffhao    call SYMBOL(artLdivmodFromCode) // (jlong a, jlong b)
53155bd45f4ea40b9a0af323f813d07f23d7a8ed397Ian Rogers    addl LITERAL(28), %esp        // pop arguments
532aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset -28
53355bd45f4ea40b9a0af323f813d07f23d7a8ed397Ian Rogers    ret
534468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND_FUNCTION art_quick_ldivmod
53555bd45f4ea40b9a0af323f813d07f23d7a8ed397Ian Rogers
536468532ea115657709bc32ee498e701a4c71762d4Ian RogersDEFINE_FUNCTION art_quick_lmul
5375793feaaafef40625b010429f3f79d8ee0bdfe28Ian Rogers    imul %eax, %ebx              // ebx = a.lo(eax) * b.hi(ebx)
5385793feaaafef40625b010429f3f79d8ee0bdfe28Ian Rogers    imul %edx, %ecx              // ecx = b.lo(edx) * a.hi(ecx)
5395793feaaafef40625b010429f3f79d8ee0bdfe28Ian Rogers    mul  %edx                    // edx:eax = a.lo(eax) * b.lo(edx)
5405793feaaafef40625b010429f3f79d8ee0bdfe28Ian Rogers    add  %ebx, %ecx
5415793feaaafef40625b010429f3f79d8ee0bdfe28Ian Rogers    add  %ecx, %edx              // edx += (a.lo * b.hi) + (b.lo * a.hi)
542644d5310d7759f6d531a2c4220b1e2cc8f3b72d3jeffhao    ret
543468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND_FUNCTION art_quick_lmul
544644d5310d7759f6d531a2c4220b1e2cc8f3b72d3jeffhao
545468532ea115657709bc32ee498e701a4c71762d4Ian RogersDEFINE_FUNCTION art_quick_lshl
546644d5310d7759f6d531a2c4220b1e2cc8f3b72d3jeffhao    // ecx:eax << edx
547141d62275f207bf68c55f583fb206fe586d857cfIan Rogers    xchg %edx, %ecx
548141d62275f207bf68c55f583fb206fe586d857cfIan Rogers    shld %cl,%eax,%edx
549141d62275f207bf68c55f583fb206fe586d857cfIan Rogers    shl  %cl,%eax
550141d62275f207bf68c55f583fb206fe586d857cfIan Rogers    test LITERAL(32), %cl
551141d62275f207bf68c55f583fb206fe586d857cfIan Rogers    jz  1f
552141d62275f207bf68c55f583fb206fe586d857cfIan Rogers    mov %eax, %edx
553141d62275f207bf68c55f583fb206fe586d857cfIan Rogers    xor %eax, %eax
554141d62275f207bf68c55f583fb206fe586d857cfIan Rogers1:
555141d62275f207bf68c55f583fb206fe586d857cfIan Rogers    ret
556468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND_FUNCTION art_quick_lshl
557141d62275f207bf68c55f583fb206fe586d857cfIan Rogers
558468532ea115657709bc32ee498e701a4c71762d4Ian RogersDEFINE_FUNCTION art_quick_lshr
559644d5310d7759f6d531a2c4220b1e2cc8f3b72d3jeffhao    // ecx:eax >> edx
560141d62275f207bf68c55f583fb206fe586d857cfIan Rogers    xchg %edx, %ecx
561644d5310d7759f6d531a2c4220b1e2cc8f3b72d3jeffhao    shrd %cl,%edx,%eax
562644d5310d7759f6d531a2c4220b1e2cc8f3b72d3jeffhao    sar  %cl,%edx
563141d62275f207bf68c55f583fb206fe586d857cfIan Rogers    test LITERAL(32),%cl
564141d62275f207bf68c55f583fb206fe586d857cfIan Rogers    jz  1f
5655121e0b9699c8cd5e89ee323e30074b984b7b436jeffhao    mov %edx, %eax
5665121e0b9699c8cd5e89ee323e30074b984b7b436jeffhao    sar LITERAL(31), %edx
567141d62275f207bf68c55f583fb206fe586d857cfIan Rogers1:
568141d62275f207bf68c55f583fb206fe586d857cfIan Rogers    ret
569468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND_FUNCTION art_quick_lshr
570141d62275f207bf68c55f583fb206fe586d857cfIan Rogers
571468532ea115657709bc32ee498e701a4c71762d4Ian RogersDEFINE_FUNCTION art_quick_lushr
572644d5310d7759f6d531a2c4220b1e2cc8f3b72d3jeffhao    // ecx:eax >>> edx
573141d62275f207bf68c55f583fb206fe586d857cfIan Rogers    xchg %edx, %ecx
574644d5310d7759f6d531a2c4220b1e2cc8f3b72d3jeffhao    shrd %cl,%edx,%eax
575644d5310d7759f6d531a2c4220b1e2cc8f3b72d3jeffhao    shr  %cl,%edx
576644d5310d7759f6d531a2c4220b1e2cc8f3b72d3jeffhao    test LITERAL(32),%cl
577141d62275f207bf68c55f583fb206fe586d857cfIan Rogers    jz  1f
5785121e0b9699c8cd5e89ee323e30074b984b7b436jeffhao    mov %edx, %eax
5795121e0b9699c8cd5e89ee323e30074b984b7b436jeffhao    xor %edx, %edx
580141d62275f207bf68c55f583fb206fe586d857cfIan Rogers1:
581141d62275f207bf68c55f583fb206fe586d857cfIan Rogers    ret
582468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND_FUNCTION art_quick_lushr
583141d62275f207bf68c55f583fb206fe586d857cfIan Rogers
584468532ea115657709bc32ee498e701a4c71762d4Ian RogersDEFINE_FUNCTION art_quick_set32_instance
5859dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    SETUP_REF_ONLY_CALLEE_SAVE_FRAME       // save ref containing registers for GC
5869dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    mov %esp, %ebx                // remember SP
5871ff4cd7c1ec698845145edd1e9d0ba767ce45de1jeffhao    subl LITERAL(8), %esp         // alignment padding
588aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 8
589aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ebx                      // pass SP
5909dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    pushl %fs:THREAD_SELF_OFFSET  // pass Thread::Current()
591aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 4
5929dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    mov 32(%ebx), %ebx            // get referrer
593aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ebx                      // pass referrer
594aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH edx                      // pass new_val
595aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ecx                      // pass object
596aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH eax                      // pass field_idx
5979dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    call SYMBOL(artSet32InstanceFromCode)  // (field_idx, Object*, new_val, referrer, Thread*, SP)
5981ff4cd7c1ec698845145edd1e9d0ba767ce45de1jeffhao    addl LITERAL(32), %esp        // pop arguments
599aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset -32
6009dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    RESTORE_REF_ONLY_CALLEE_SAVE_FRAME     // restore frame up to return address
6019dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    RETURN_IF_EAX_ZERO            // return or deliver exception
602468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND_FUNCTION art_quick_set32_instance
6039dbb23e997f84d7c6c909b246e3faca50a912336jeffhao
604468532ea115657709bc32ee498e701a4c71762d4Ian RogersDEFINE_FUNCTION art_quick_set64_instance
605aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    SETUP_REF_ONLY_CALLEE_SAVE_FRAME  // save ref containing registers for GC
6061ff4cd7c1ec698845145edd1e9d0ba767ce45de1jeffhao    subl LITERAL(8), %esp         // alignment padding
607aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 8
608aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH esp                      // pass SP-8
6091ff4cd7c1ec698845145edd1e9d0ba767ce45de1jeffhao    addl LITERAL(8), (%esp)       // fix SP on stack by adding 8
6109dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    pushl %fs:THREAD_SELF_OFFSET  // pass Thread::Current()
611aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 4
612aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ebx                      // pass high half of new_val
613aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH edx                      // pass low half of new_val
614aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ecx                      // pass object
615aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH eax                      // pass field_idx
6169dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    call SYMBOL(artSet64InstanceFromCode)  // (field_idx, Object*, new_val, Thread*, SP)
6171ff4cd7c1ec698845145edd1e9d0ba767ce45de1jeffhao    addl LITERAL(32), %esp        // pop arguments
618aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset -32
619aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    RESTORE_REF_ONLY_CALLEE_SAVE_FRAME  // restore frame up to return address
6209dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    RETURN_IF_EAX_ZERO            // return or deliver exception
621468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND_FUNCTION art_quick_set64_instance
6229dbb23e997f84d7c6c909b246e3faca50a912336jeffhao
623468532ea115657709bc32ee498e701a4c71762d4Ian RogersDEFINE_FUNCTION art_quick_set_obj_instance
624aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    SETUP_REF_ONLY_CALLEE_SAVE_FRAME  // save ref containing registers for GC
6259dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    mov %esp, %ebx                // remember SP
6261ff4cd7c1ec698845145edd1e9d0ba767ce45de1jeffhao    subl LITERAL(8), %esp         // alignment padding
627aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 8
628aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ebx                      // pass SP
6299dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    pushl %fs:THREAD_SELF_OFFSET  // pass Thread::Current()
630aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 4
6319dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    mov 32(%ebx), %ebx            // get referrer
632aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ebx                      // pass referrer
633aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH edx                      // pass new_val
634aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ecx                      // pass object
635aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH eax                      // pass field_idx
6369dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    call SYMBOL(artSetObjInstanceFromCode) // (field_idx, Object*, new_val, referrer, Thread*, SP)
6371ff4cd7c1ec698845145edd1e9d0ba767ce45de1jeffhao    addl LITERAL(32), %esp        // pop arguments
638aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset -32
6399dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    RESTORE_REF_ONLY_CALLEE_SAVE_FRAME     // restore frame up to return address
6409dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    RETURN_IF_EAX_ZERO            // return or deliver exception
641468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND_FUNCTION art_quick_set_obj_instance
6429dbb23e997f84d7c6c909b246e3faca50a912336jeffhao
643468532ea115657709bc32ee498e701a4c71762d4Ian RogersDEFINE_FUNCTION art_quick_get32_instance
644aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    SETUP_REF_ONLY_CALLEE_SAVE_FRAME  // save ref containing registers for GC
6459dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    mov %esp, %ebx                // remember SP
6469dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    mov 32(%esp), %edx            // get referrer
6471ff4cd7c1ec698845145edd1e9d0ba767ce45de1jeffhao    subl LITERAL(12), %esp        // alignment padding
648aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 12
649aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ebx                      // pass SP
6509dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    pushl %fs:THREAD_SELF_OFFSET  // pass Thread::Current()
651aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 4
652aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH edx                      // pass referrer
653aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ecx                      // pass object
654aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH eax                      // pass field_idx
6559dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    call SYMBOL(artGet32InstanceFromCode)  // (field_idx, Object*, referrer, Thread*, SP)
6561ff4cd7c1ec698845145edd1e9d0ba767ce45de1jeffhao    addl LITERAL(32), %esp        // pop arguments
657aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset -32
6589dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    RESTORE_REF_ONLY_CALLEE_SAVE_FRAME     // restore frame up to return address
659d66a87583bebcd5f89906aeaae9f8fb104ef2ac9jeffhao    RETURN_OR_DELIVER_PENDING_EXCEPTION    // return or deliver exception
660468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND_FUNCTION art_quick_get32_instance
6619dbb23e997f84d7c6c909b246e3faca50a912336jeffhao
662468532ea115657709bc32ee498e701a4c71762d4Ian RogersDEFINE_FUNCTION art_quick_get64_instance
6639dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    SETUP_REF_ONLY_CALLEE_SAVE_FRAME       // save ref containing registers for GC
6649dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    mov %esp, %ebx                // remember SP
6659dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    mov 32(%esp), %edx            // get referrer
6661ff4cd7c1ec698845145edd1e9d0ba767ce45de1jeffhao    subl LITERAL(12), %esp        // alignment padding
667aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 12
668aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ebx                      // pass SP
6699dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    pushl %fs:THREAD_SELF_OFFSET  // pass Thread::Current()
670aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 4
671aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH edx                      // pass referrer
672aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ecx                      // pass object
673aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH eax                      // pass field_idx
6749dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    call SYMBOL(artGet64InstanceFromCode)  // (field_idx, Object*, referrer, Thread*, SP)
6751ff4cd7c1ec698845145edd1e9d0ba767ce45de1jeffhao    addl LITERAL(32), %esp        // pop arguments
676aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset -32
6779dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    RESTORE_REF_ONLY_CALLEE_SAVE_FRAME     // restore frame up to return address
678d66a87583bebcd5f89906aeaae9f8fb104ef2ac9jeffhao    RETURN_OR_DELIVER_PENDING_EXCEPTION    // return or deliver exception
679468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND_FUNCTION art_quick_get64_instance
6809dbb23e997f84d7c6c909b246e3faca50a912336jeffhao
681468532ea115657709bc32ee498e701a4c71762d4Ian RogersDEFINE_FUNCTION art_quick_get_obj_instance
6829dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    SETUP_REF_ONLY_CALLEE_SAVE_FRAME       // save ref containing registers for GC
6839dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    mov %esp, %ebx                // remember SP
6849dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    mov 32(%esp), %edx            // get referrer
6851ff4cd7c1ec698845145edd1e9d0ba767ce45de1jeffhao    subl LITERAL(12), %esp        // alignment padding
686aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 12
687aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ebx                      // pass SP
6889dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    pushl %fs:THREAD_SELF_OFFSET  // pass Thread::Current()
689aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 4
690aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH edx                      // pass referrer
691aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ecx                      // pass object
692aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH eax                      // pass field_idx
6939dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    call SYMBOL(artGetObjInstanceFromCode) // (field_idx, Object*, referrer, Thread*, SP)
6941ff4cd7c1ec698845145edd1e9d0ba767ce45de1jeffhao    addl LITERAL(32), %esp        // pop arguments
695aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset -32
6969dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    RESTORE_REF_ONLY_CALLEE_SAVE_FRAME     // restore frame up to return address
697d66a87583bebcd5f89906aeaae9f8fb104ef2ac9jeffhao    RETURN_OR_DELIVER_PENDING_EXCEPTION    // return or deliver exception
698468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND_FUNCTION art_quick_get_obj_instance
6999dbb23e997f84d7c6c909b246e3faca50a912336jeffhao
700468532ea115657709bc32ee498e701a4c71762d4Ian RogersDEFINE_FUNCTION art_quick_set32_static
7019dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    SETUP_REF_ONLY_CALLEE_SAVE_FRAME       // save ref containing registers for GC
7029dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    mov %esp, %ebx                // remember SP
7039dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    mov 32(%esp), %edx            // get referrer
7041ff4cd7c1ec698845145edd1e9d0ba767ce45de1jeffhao    subl LITERAL(12), %esp        // alignment padding
705aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 12
706aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ebx                      // pass SP
7079dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    pushl %fs:THREAD_SELF_OFFSET  // pass Thread::Current()
708aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 4
709aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH edx                      // pass referrer
710aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ecx                      // pass new_val
711aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH eax                      // pass field_idx
7129dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    call SYMBOL(artSet32StaticFromCode)    // (field_idx, new_val, referrer, Thread*, SP)
7131ff4cd7c1ec698845145edd1e9d0ba767ce45de1jeffhao    addl LITERAL(32), %esp        // pop arguments
714aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset -32
7159dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    RESTORE_REF_ONLY_CALLEE_SAVE_FRAME     // restore frame up to return address
7169dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    RETURN_IF_EAX_ZERO            // return or deliver exception
717468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND_FUNCTION art_quick_set32_static
7189dbb23e997f84d7c6c909b246e3faca50a912336jeffhao
719468532ea115657709bc32ee498e701a4c71762d4Ian RogersDEFINE_FUNCTION art_quick_set64_static
720aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    SETUP_REF_ONLY_CALLEE_SAVE_FRAME  // save ref containing registers for GC
7219dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    mov %esp, %ebx                // remember SP
7221ff4cd7c1ec698845145edd1e9d0ba767ce45de1jeffhao    subl LITERAL(8), %esp         // alignment padding
723aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 8
724aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ebx                      // pass SP
7259dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    pushl %fs:THREAD_SELF_OFFSET  // pass Thread::Current()
726aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 4
7279dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    mov 32(%ebx), %ebx            // get referrer
728aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH edx                      // pass high half of new_val
729aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ecx                      // pass low half of new_val
730aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ebx                      // pass referrer
731aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH eax                      // pass field_idx
732aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    call SYMBOL(artSet64StaticFromCode)  // (field_idx, referrer, new_val, Thread*, SP)
7331ff4cd7c1ec698845145edd1e9d0ba767ce45de1jeffhao    addl LITERAL(32), %esp        // pop arguments
734aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset -32
735aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    RESTORE_REF_ONLY_CALLEE_SAVE_FRAME  // restore frame up to return address
7369dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    RETURN_IF_EAX_ZERO            // return or deliver exception
737468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND_FUNCTION art_quick_set64_static
7389dbb23e997f84d7c6c909b246e3faca50a912336jeffhao
739468532ea115657709bc32ee498e701a4c71762d4Ian RogersDEFINE_FUNCTION art_quick_set_obj_static
740aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    SETUP_REF_ONLY_CALLEE_SAVE_FRAME  // save ref containing registers for GC
7419dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    mov %esp, %ebx                // remember SP
7429dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    mov 32(%esp), %edx            // get referrer
7431ff4cd7c1ec698845145edd1e9d0ba767ce45de1jeffhao    subl LITERAL(12), %esp        // alignment padding
74462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    .cfi_adjust_cfa_offset 12
745aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ebx                      // pass SP
7469dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    pushl %fs:THREAD_SELF_OFFSET  // pass Thread::Current()
747aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 4
748aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH edx                      // pass referrer
749aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ecx                      // pass new_val
750aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH eax                      // pass field_idx
751aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    call SYMBOL(artSetObjStaticFromCode)  // (field_idx, new_val, referrer, Thread*, SP)
7521ff4cd7c1ec698845145edd1e9d0ba767ce45de1jeffhao    addl LITERAL(32), %esp        // pop arguments
753aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    RESTORE_REF_ONLY_CALLEE_SAVE_FRAME  // restore frame up to return address
7549dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    RETURN_IF_EAX_ZERO            // return or deliver exception
755468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND_FUNCTION art_quick_set_obj_static
7569dbb23e997f84d7c6c909b246e3faca50a912336jeffhao
757468532ea115657709bc32ee498e701a4c71762d4Ian RogersDEFINE_FUNCTION art_quick_get32_static
7589dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    SETUP_REF_ONLY_CALLEE_SAVE_FRAME       // save ref containing registers for GC
7599dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    mov %esp, %edx                // remember SP
7609dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    mov 32(%esp), %ecx            // get referrer
761aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH edx                      // pass SP
7629dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    pushl %fs:THREAD_SELF_OFFSET  // pass Thread::Current()
763aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 4
764aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ecx                      // pass referrer
765aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH eax                      // pass field_idx
7669dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    call SYMBOL(artGet32StaticFromCode)    // (field_idx, referrer, Thread*, SP)
7671ff4cd7c1ec698845145edd1e9d0ba767ce45de1jeffhao    addl LITERAL(16), %esp        // pop arguments
768aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset -16
7699dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    RESTORE_REF_ONLY_CALLEE_SAVE_FRAME     // restore frame up to return address
770d66a87583bebcd5f89906aeaae9f8fb104ef2ac9jeffhao    RETURN_OR_DELIVER_PENDING_EXCEPTION    // return or deliver exception
771468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND_FUNCTION art_quick_get32_static
7729dbb23e997f84d7c6c909b246e3faca50a912336jeffhao
773468532ea115657709bc32ee498e701a4c71762d4Ian RogersDEFINE_FUNCTION art_quick_get64_static
774aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    SETUP_REF_ONLY_CALLEE_SAVE_FRAME  // save ref containing registers for GC
7759dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    mov %esp, %edx                // remember SP
7769dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    mov 32(%esp), %ecx            // get referrer
777aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH edx                      // pass SP
7789dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    pushl %fs:THREAD_SELF_OFFSET  // pass Thread::Current()
779aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 4
780aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ecx                      // pass referrer
781aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH eax                      // pass field_idx
7829dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    call SYMBOL(artGet64StaticFromCode)    // (field_idx, referrer, Thread*, SP)
7831ff4cd7c1ec698845145edd1e9d0ba767ce45de1jeffhao    addl LITERAL(16), %esp        // pop arguments
784aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset -16
7859dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    RESTORE_REF_ONLY_CALLEE_SAVE_FRAME     // restore frame up to return address
786d66a87583bebcd5f89906aeaae9f8fb104ef2ac9jeffhao    RETURN_OR_DELIVER_PENDING_EXCEPTION    // return or deliver exception
787468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND_FUNCTION art_quick_get64_static
7889dbb23e997f84d7c6c909b246e3faca50a912336jeffhao
789468532ea115657709bc32ee498e701a4c71762d4Ian RogersDEFINE_FUNCTION art_quick_get_obj_static
7909dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    SETUP_REF_ONLY_CALLEE_SAVE_FRAME       // save ref containing registers for GC
7919dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    mov %esp, %edx                // remember SP
7929dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    mov 32(%esp), %ecx            // get referrer
793aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH edx                      // pass SP
7949dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    pushl %fs:THREAD_SELF_OFFSET  // pass Thread::Current()
795aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 4
796aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ecx                      // pass referrer
797aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH eax                      // pass field_idx
7989dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    call SYMBOL(artGetObjStaticFromCode)   // (field_idx, referrer, Thread*, SP)
7991ff4cd7c1ec698845145edd1e9d0ba767ce45de1jeffhao    addl LITERAL(16), %esp        // pop arguments
800aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset -16
8019dbb23e997f84d7c6c909b246e3faca50a912336jeffhao    RESTORE_REF_ONLY_CALLEE_SAVE_FRAME     // restore frame up to return address
802d66a87583bebcd5f89906aeaae9f8fb104ef2ac9jeffhao    RETURN_OR_DELIVER_PENDING_EXCEPTION    // return or deliver exception
803468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND_FUNCTION art_quick_get_obj_static
804d66a87583bebcd5f89906aeaae9f8fb104ef2ac9jeffhao
8058dbb708c7dc05c786329eb5c3fff3194ab6472acLogan ChienDEFINE_FUNCTION art_quick_proxy_invoke_handler
8067db619bb2a4e01e8532a04b613745d4926b205d7Ian Rogers    SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME   // save frame and Method*
807aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH esp                      // pass SP
808d66a87583bebcd5f89906aeaae9f8fb104ef2ac9jeffhao    pushl %fs:THREAD_SELF_OFFSET  // pass Thread::Current()
809aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 4
810aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH ecx                      // pass receiver
811aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH eax                      // pass proxy method
8125fa60c3db4208df407113b5a69d295a9c93d53b1Jeff Hao    call SYMBOL(artQuickProxyInvokeHandler) // (proxy method, receiver, Thread*, SP)
813af6e67a4816d2593586115b89faa659225363246Ian Rogers    movd %eax, %xmm0              // place return value also into floating point return value
814af6e67a4816d2593586115b89faa659225363246Ian Rogers    movd %edx, %xmm1
815af6e67a4816d2593586115b89faa659225363246Ian Rogers    punpckldq %xmm1, %xmm0
816d66a87583bebcd5f89906aeaae9f8fb104ef2ac9jeffhao    addl LITERAL(44), %esp        // pop arguments
817aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset -44
8187db619bb2a4e01e8532a04b613745d4926b205d7Ian Rogers    RETURN_OR_DELIVER_PENDING_EXCEPTION    // return or deliver exception
819aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian RogersEND_FUNCTION art_quick_proxy_invoke_handler
8207db619bb2a4e01e8532a04b613745d4926b205d7Ian Rogers
821468532ea115657709bc32ee498e701a4c71762d4Ian RogersDEFINE_FUNCTION art_quick_resolution_trampoline
822468532ea115657709bc32ee498e701a4c71762d4Ian Rogers    SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME
823468532ea115657709bc32ee498e701a4c71762d4Ian Rogers    PUSH esp                      // pass SP
824468532ea115657709bc32ee498e701a4c71762d4Ian Rogers    pushl %fs:THREAD_SELF_OFFSET  // pass Thread::Current()
825468532ea115657709bc32ee498e701a4c71762d4Ian Rogers    .cfi_adjust_cfa_offset 4
826468532ea115657709bc32ee498e701a4c71762d4Ian Rogers    PUSH ecx                      // pass receiver
827468532ea115657709bc32ee498e701a4c71762d4Ian Rogers    PUSH eax                      // pass method
828468532ea115657709bc32ee498e701a4c71762d4Ian Rogers    call SYMBOL(artQuickResolutionTrampoline) // (Method* called, receiver, Thread*, SP)
829468532ea115657709bc32ee498e701a4c71762d4Ian Rogers    movl %eax, %edi               // remember code pointer in EDI
830468532ea115657709bc32ee498e701a4c71762d4Ian Rogers    addl LITERAL(16), %esp        // pop arguments
831468532ea115657709bc32ee498e701a4c71762d4Ian Rogers    test %eax, %eax               // if code pointer is NULL goto deliver pending exception
832468532ea115657709bc32ee498e701a4c71762d4Ian Rogers    jz 1f
833468532ea115657709bc32ee498e701a4c71762d4Ian Rogers    POP eax                       // called method
834468532ea115657709bc32ee498e701a4c71762d4Ian Rogers    POP ecx                       // restore args
835468532ea115657709bc32ee498e701a4c71762d4Ian Rogers    POP edx
836468532ea115657709bc32ee498e701a4c71762d4Ian Rogers    POP ebx
837468532ea115657709bc32ee498e701a4c71762d4Ian Rogers    POP ebp                       // restore callee saves except EDI
838468532ea115657709bc32ee498e701a4c71762d4Ian Rogers    POP esi
839468532ea115657709bc32ee498e701a4c71762d4Ian Rogers    xchgl 0(%esp),%edi            // restore EDI and place code pointer as only value on stack
840468532ea115657709bc32ee498e701a4c71762d4Ian Rogers    ret                           // tail call into method
841468532ea115657709bc32ee498e701a4c71762d4Ian Rogers1:
842468532ea115657709bc32ee498e701a4c71762d4Ian Rogers    RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME
843468532ea115657709bc32ee498e701a4c71762d4Ian Rogers    DELIVER_PENDING_EXCEPTION
844468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND_FUNCTION art_quick_resolution_trampoline
845468532ea115657709bc32ee498e701a4c71762d4Ian Rogers
846468532ea115657709bc32ee498e701a4c71762d4Ian RogersDEFINE_FUNCTION art_quick_to_interpreter_bridge
84762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME   // save frame
848aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    mov %esp, %edx                // remember SP
849aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH eax                      // alignment padding
850aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH edx                      // pass SP
8517db619bb2a4e01e8532a04b613745d4926b205d7Ian Rogers    pushl %fs:THREAD_SELF_OFFSET  // pass Thread::Current()
852aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 4
853aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH eax                      // pass  method
854468532ea115657709bc32ee498e701a4c71762d4Ian Rogers    call SYMBOL(artQuickToInterpreterBridge)  // (method, Thread*, SP)
8557db619bb2a4e01e8532a04b613745d4926b205d7Ian Rogers    movd %eax, %xmm0              // place return value also into floating point return value
8567db619bb2a4e01e8532a04b613745d4926b205d7Ian Rogers    movd %edx, %xmm1
8577db619bb2a4e01e8532a04b613745d4926b205d7Ian Rogers    punpckldq %xmm1, %xmm0
8587db619bb2a4e01e8532a04b613745d4926b205d7Ian Rogers    addl LITERAL(44), %esp        // pop arguments
859aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset -44
860d66a87583bebcd5f89906aeaae9f8fb104ef2ac9jeffhao    RETURN_OR_DELIVER_PENDING_EXCEPTION    // return or deliver exception
861468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND_FUNCTION art_quick_to_interpreter_bridge
8629dbb23e997f84d7c6c909b246e3faca50a912336jeffhao
8637e4fcb813d6c2657a5b9190a7c10168a2680bc45jeffhao    /*
8647e4fcb813d6c2657a5b9190a7c10168a2680bc45jeffhao     * Routine that intercepts method calls and returns.
8657e4fcb813d6c2657a5b9190a7c10168a2680bc45jeffhao     */
866468532ea115657709bc32ee498e701a4c71762d4Ian RogersDEFINE_FUNCTION art_quick_instrumentation_entry
86762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME
86862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    movl  %esp, %edx              // Save SP.
86962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    PUSH eax                      // Save eax which will be clobbered by the callee-save method.
87062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    subl LITERAL(8), %esp         // Align stack.
87162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    .cfi_adjust_cfa_offset 8
87262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    pushl 40(%esp)                // Pass LR.
873aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 4
87462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    PUSH edx                      // Pass SP.
87562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    pushl %fs:THREAD_SELF_OFFSET  // Pass Thread::Current().
876aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 4
87762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    PUSH ecx                      // Pass receiver.
87862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    PUSH eax                      // Pass Method*.
87962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    call  SYMBOL(artInstrumentationMethodEntryFromCode) // (Method*, Object*, Thread*, SP, LR)
88062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    addl  LITERAL(28), %esp       // Pop arguments upto saved Method*.
88162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    movl 28(%esp), %edi           // Restore edi.
88262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    movl %eax, 28(%esp)           // Place code* over edi, just under return pc.
883468532ea115657709bc32ee498e701a4c71762d4Ian Rogers    movl LITERAL(SYMBOL(art_quick_instrumentation_exit)), 32(%esp)
88462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                                  // Place instrumentation exit as return pc.
88562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    movl (%esp), %eax             // Restore eax.
88662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    movl 8(%esp), %ecx            // Restore ecx.
88762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    movl 12(%esp), %edx           // Restore edx.
88862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    movl 16(%esp), %ebx           // Restore ebx.
88962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    movl 20(%esp), %ebp           // Restore ebp.
89062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    movl 24(%esp), %esi           // Restore esi.
89162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    addl LITERAL(28), %esp        // Wind stack back upto code*.
89262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    ret                           // Call method (and pop).
893468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND_FUNCTION art_quick_instrumentation_entry
89462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
895468532ea115657709bc32ee498e701a4c71762d4Ian RogersDEFINE_FUNCTION art_quick_instrumentation_exit
89662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    pushl LITERAL(0)              // Push a fake return PC as there will be none on the stack.
89762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    SETUP_REF_ONLY_CALLEE_SAVE_FRAME
89862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    mov  %esp, %ecx               // Remember SP
89962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    subl LITERAL(8), %esp         // Save float return value.
90062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    .cfi_adjust_cfa_offset 8
90162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    movd %xmm0, (%esp)
90262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    PUSH edx                      // Save gpr return value.
90362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    PUSH eax
90462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    subl LITERAL(8), %esp         // Align stack
90562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    movd %xmm0, (%esp)
90662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    subl LITERAL(8), %esp         // Pass float return value.
90762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    .cfi_adjust_cfa_offset 8
90862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    movd %xmm0, (%esp)
90962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    PUSH edx                      // Pass gpr return value.
91062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    PUSH eax
91162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    PUSH ecx                      // Pass SP.
91262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    pushl %fs:THREAD_SELF_OFFSET  // Pass Thread::Current.
913aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 4
91462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    call  SYMBOL(artInstrumentationMethodExitFromCode)  // (Thread*, SP, gpr_result, fpr_result)
91562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    mov   %eax, %ecx              // Move returned link register.
91662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    addl LITERAL(32), %esp        // Pop arguments.
91762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    .cfi_adjust_cfa_offset -32
91862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    movl %edx, %ebx               // Move returned link register for deopt
91962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                                  // (ebx is pretending to be our LR).
92062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    POP eax                       // Restore gpr return value.
92162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    POP edx
92262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    movd (%esp), %xmm0            // Restore fpr return value.
92362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    addl LITERAL(8), %esp
9245793feaaafef40625b010429f3f79d8ee0bdfe28Ian Rogers    .cfi_adjust_cfa_offset -8
92562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
92662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    addl LITERAL(4), %esp         // Remove fake return pc.
92762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    jmp   *%ecx                   // Return.
928468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND_FUNCTION art_quick_instrumentation_exit
929162fd33474038f0de0388338ca007ecf400bb3dfjeffhao
9307e4fcb813d6c2657a5b9190a7c10168a2680bc45jeffhao    /*
93162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers     * Instrumentation has requested that we deoptimize into the interpreter. The deoptimization
93262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers     * will long jump to the upcall with a special exception of -1.
9337e4fcb813d6c2657a5b9190a7c10168a2680bc45jeffhao     */
9348dbb708c7dc05c786329eb5c3fff3194ab6472acLogan ChienDEFINE_FUNCTION art_quick_deoptimize
93562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    pushl %ebx                    // Fake that we were called.
936c1fcdf1ec5a8c5ffaf9e857ea81ac7358d1df7f5Jeff Hao    SETUP_SAVE_ALL_CALLEE_SAVE_FRAME
93762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    mov  %esp, %ecx               // Remember SP.
93862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    subl LITERAL(8), %esp         // Align stack.
93962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    .cfi_adjust_cfa_offset 8
94062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    PUSH ecx                      // Pass SP.
94162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    pushl %fs:THREAD_SELF_OFFSET  // Pass Thread::Current().
942aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    .cfi_adjust_cfa_offset 4
94362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    call SYMBOL(artDeoptimize)    // artDeoptimize(Thread*, SP)
94462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    int3                          // Unreachable.
945aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian RogersEND_FUNCTION art_quick_deoptimize
946162fd33474038f0de0388338ca007ecf400bb3dfjeffhao
94786e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    /*
94886e4671975752b112b2e8969ac6652c72c8e86c7jeffhao     * String's indexOf.
94986e4671975752b112b2e8969ac6652c72c8e86c7jeffhao     *
95086e4671975752b112b2e8969ac6652c72c8e86c7jeffhao     * On entry:
95186e4671975752b112b2e8969ac6652c72c8e86c7jeffhao     *    eax:   string object (known non-null)
95286e4671975752b112b2e8969ac6652c72c8e86c7jeffhao     *    ecx:   char to match (known <= 0xFFFF)
95386e4671975752b112b2e8969ac6652c72c8e86c7jeffhao     *    edx:   Starting offset in string data
95486e4671975752b112b2e8969ac6652c72c8e86c7jeffhao     */
9558dbb708c7dc05c786329eb5c3fff3194ab6472acLogan ChienDEFINE_FUNCTION art_quick_indexof
956aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH edi                      // push callee save reg
95786e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    mov STRING_COUNT_OFFSET(%eax), %ebx
95886e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    mov STRING_VALUE_OFFSET(%eax), %edi
95986e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    mov STRING_OFFSET_OFFSET(%eax), %eax
96086e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    testl %edx, %edx              // check if start < 0
96186e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    jl   clamp_min
96286e4671975752b112b2e8969ac6652c72c8e86c7jeffhaoclamp_done:
96386e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    cmpl %ebx, %edx               // check if start >= count
96486e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    jge  not_found
96586e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    lea  STRING_DATA_OFFSET(%edi, %eax, 2), %edi  // build a pointer to the start of string data
96686e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    mov  %edi, %eax               // save a copy in eax to later compute result
96786e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    lea  (%edi, %edx, 2), %edi    // build pointer to start of data to compare
96886e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    subl  %edx, %ebx              // compute iteration count
96986e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    /*
97086e4671975752b112b2e8969ac6652c72c8e86c7jeffhao     * At this point we have:
97186e4671975752b112b2e8969ac6652c72c8e86c7jeffhao     *   eax: original start of string data
97286e4671975752b112b2e8969ac6652c72c8e86c7jeffhao     *   ecx: char to compare
97386e4671975752b112b2e8969ac6652c72c8e86c7jeffhao     *   ebx: length to compare
97486e4671975752b112b2e8969ac6652c72c8e86c7jeffhao     *   edi: start of data to test
97586e4671975752b112b2e8969ac6652c72c8e86c7jeffhao     */
97686e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    mov  %eax, %edx
97786e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    mov  %ecx, %eax               // put char to match in %eax
97886e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    mov  %ebx, %ecx               // put length to compare in %ecx
97986e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    repne scasw                   // find %ax, starting at [%edi], up to length %ecx
98086e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    jne  not_found
98186e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    subl %edx, %edi
98286e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    sar  LITERAL(1), %edi
98386e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    decl %edi                     // index = ((curr_ptr - orig_ptr) / 2) - 1
98486e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    mov  %edi, %eax
985aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    POP edi                       // pop callee save reg
98686e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    ret
98786e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    .balign 16
98886e4671975752b112b2e8969ac6652c72c8e86c7jeffhaonot_found:
98986e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    mov  LITERAL(-1), %eax        // return -1 (not found)
990aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    POP edi                       // pop callee save reg
99186e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    ret
99286e4671975752b112b2e8969ac6652c72c8e86c7jeffhaoclamp_min:
99386e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    xor  %edx, %edx               // clamp start to 0
99486e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    jmp  clamp_done
995aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian RogersEND_FUNCTION art_quick_indexof
99686e4671975752b112b2e8969ac6652c72c8e86c7jeffhao
99786e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    /*
99886e4671975752b112b2e8969ac6652c72c8e86c7jeffhao     * String's compareTo.
99986e4671975752b112b2e8969ac6652c72c8e86c7jeffhao     *
100086e4671975752b112b2e8969ac6652c72c8e86c7jeffhao     * On entry:
100186e4671975752b112b2e8969ac6652c72c8e86c7jeffhao     *    eax:   this string object (known non-null)
100286e4671975752b112b2e8969ac6652c72c8e86c7jeffhao     *    ecx:   comp string object (known non-null)
100386e4671975752b112b2e8969ac6652c72c8e86c7jeffhao     */
10048dbb708c7dc05c786329eb5c3fff3194ab6472acLogan ChienDEFINE_FUNCTION art_quick_string_compareto
1005aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH esi                    // push callee save reg
1006aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    PUSH edi                    // push callee save reg
100786e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    mov STRING_COUNT_OFFSET(%eax), %edx
100886e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    mov STRING_COUNT_OFFSET(%ecx), %ebx
100986e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    mov STRING_VALUE_OFFSET(%eax), %esi
101086e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    mov STRING_VALUE_OFFSET(%ecx), %edi
101186e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    mov STRING_OFFSET_OFFSET(%eax), %eax
101286e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    mov STRING_OFFSET_OFFSET(%ecx), %ecx
101386e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    /* Build pointers to the start of string data */
101486e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    lea  STRING_DATA_OFFSET(%esi, %eax, 2), %esi
101586e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    lea  STRING_DATA_OFFSET(%edi, %ecx, 2), %edi
101686e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    /* Calculate min length and count diff */
101786e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    mov   %edx, %ecx
101886e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    mov   %edx, %eax
101986e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    subl  %ebx, %eax
102086e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    cmovg %ebx, %ecx
102186e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    /*
102286e4671975752b112b2e8969ac6652c72c8e86c7jeffhao     * At this point we have:
102386e4671975752b112b2e8969ac6652c72c8e86c7jeffhao     *   eax: value to return if first part of strings are equal
102486e4671975752b112b2e8969ac6652c72c8e86c7jeffhao     *   ecx: minimum among the lengths of the two strings
102586e4671975752b112b2e8969ac6652c72c8e86c7jeffhao     *   esi: pointer to this string data
102686e4671975752b112b2e8969ac6652c72c8e86c7jeffhao     *   edi: pointer to comp string data
102786e4671975752b112b2e8969ac6652c72c8e86c7jeffhao     */
102886e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    repe cmpsw                    // find nonmatching chars in [%esi] and [%edi], up to length %ecx
102986e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    jne not_equal
1030aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    POP edi                       // pop callee save reg
1031aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    POP esi                       // pop callee save reg
103286e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    ret
103386e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    .balign 16
103486e4671975752b112b2e8969ac6652c72c8e86c7jeffhaonot_equal:
10351b09b094a85e03f6ef5f687f58bb91c433273ba1Ian Rogers    movzwl  -2(%esi), %eax        // get last compared char from this string
10361b09b094a85e03f6ef5f687f58bb91c433273ba1Ian Rogers    movzwl  -2(%edi), %ecx        // get last compared char from comp string
103786e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    subl  %ecx, %eax              // return the difference
1038aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    POP edi                       // pop callee save reg
1039aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers    POP esi                       // pop callee save reg
104086e4671975752b112b2e8969ac6652c72c8e86c7jeffhao    ret
1041aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian RogersEND_FUNCTION art_quick_string_compareto
104286e4671975752b112b2e8969ac6652c72c8e86c7jeffhao
1043787ec205ee545b9c08f4fc6d3823cb43d10083afElliott Hughes    // TODO: implement these!
10448dbb708c7dc05c786329eb5c3fff3194ab6472acLogan ChienUNIMPLEMENTED art_quick_memcmp16
1045