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