/* * Copyright (C) 2012 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "asm_support_x86.S" /* * Portable invocation stub. * On entry: * [sp] = return address * [sp + 4] = method pointer * [sp + 8] = argument array or NULL for no argument methods * [sp + 12] = size of argument array in bytes * [sp + 16] = (managed) thread pointer * [sp + 20] = JValue* result * [sp + 24] = result type char */ DEFINE_FUNCTION art_portable_invoke_stub PUSH ebp // save ebp PUSH ebx // save ebx mov %esp, %ebp // copy value of stack pointer into base pointer CFI_DEF_CFA_REGISTER(ebp) mov 20(%ebp), %ebx // get arg array size addl LITERAL(28), %ebx // reserve space for return addr, method*, ebx, and ebp in frame andl LITERAL(0xFFFFFFF0), %ebx // align frame size to 16 bytes subl LITERAL(12), %ebx // remove space for return address, ebx, and ebp subl %ebx, %esp // reserve stack space for argument array SETUP_GOT_NOSAVE // reset ebx to GOT table lea 4(%esp), %eax // use stack pointer + method ptr as dest for memcpy pushl 20(%ebp) // push size of region to memcpy pushl 16(%ebp) // push arg array as source of memcpy pushl %eax // push stack pointer as destination of memcpy call PLT_SYMBOL(memcpy) // (void*, const void*, size_t) addl LITERAL(12), %esp // pop arguments to memcpy mov 12(%ebp), %eax // move method pointer into eax mov %eax, (%esp) // push method pointer onto stack call *METHOD_PORTABLE_CODE_OFFSET_32(%eax) // call the method mov %ebp, %esp // restore stack pointer POP ebx // pop ebx POP ebp // pop ebp mov 20(%esp), %ecx // get result pointer cmpl LITERAL(68), 24(%esp) // test if result type char == 'D' je .Lreturn_double_portable cmpl LITERAL(70), 24(%esp) // test if result type char == 'F' je .Lreturn_float_portable mov %eax, (%ecx) // store the result mov %edx, 4(%ecx) // store the other half of the result ret .Lreturn_double_portable: fstpl (%ecx) // store the floating point result as double ret .Lreturn_float_portable: fstps (%ecx) // store the floating point result as float ret END_FUNCTION art_portable_invoke_stub DEFINE_FUNCTION art_portable_proxy_invoke_handler PUSH ebp // Set up frame. movl %esp, %ebp CFI_DEF_CFA_REGISTER(%ebp) subl LITERAL(4), %esp // Align stack SETUP_GOT // pushes ebx leal 8(%ebp), %edx // %edx = ArtMethod** called_addr movl 12(%ebp), %ecx // %ecx = receiver movl 0(%edx), %eax // %eax = ArtMethod* called pushl %edx // Pass called_addr. pushl %fs:THREAD_SELF_OFFSET // Pass thread. pushl %ecx // Pass receiver. pushl %eax // Pass called. call PLT_SYMBOL(artPortableProxyInvokeHandler) // (called, receiver, Thread*, &called) UNDO_SETUP_GOT leave CFI_RESTORE(%ebp) CFI_DEF_CFA(%esp, 4) movd %eax, %xmm0 // Place return value also into floating point return value. movd %edx, %xmm1 punpckldq %xmm1, %xmm0 ret END_FUNCTION art_portable_proxy_invoke_handler DEFINE_FUNCTION art_portable_resolution_trampoline PUSH ebp // Set up frame. movl %esp, %ebp CFI_DEF_CFA_REGISTER(%ebp) subl LITERAL(4), %esp // Align stack SETUP_GOT // pushes ebx leal 8(%ebp), %edx // %edx = ArtMethod** called_addr movl 12(%ebp), %ecx // %ecx = receiver movl 0(%edx), %eax // %eax = ArtMethod* called pushl %edx // Pass called_addr. pushl %fs:THREAD_SELF_OFFSET // Pass thread. pushl %ecx // Pass receiver. pushl %eax // Pass called. call PLT_SYMBOL(artPortableResolutionTrampoline) // (called, receiver, Thread*, &called) UNDO_SETUP_GOT leave CFI_RESTORE(%ebp) CFI_DEF_CFA(%esp, 4) testl %eax, %eax jz .Lresolve_fail jmp * %eax .Lresolve_fail: // Resolution failed, return with exception pending. ret END_FUNCTION art_portable_resolution_trampoline DEFINE_FUNCTION_NO_HIDE art_portable_to_interpreter_bridge PUSH ebp // Set up frame. movl %esp, %ebp CFI_DEF_CFA_REGISTER(%ebp) subl LITERAL(8), %esp // Align stack SETUP_GOT leal 8(%ebp), %edx // %edx = ArtMethod** called_addr movl 0(%edx), %eax // %eax = ArtMethod* called pushl %edx // Pass called_addr. pushl %fs:THREAD_SELF_OFFSET // Pass thread. pushl %eax // Pass called. call PLT_SYMBOL(artPortableToInterpreterBridge) // (called, Thread*, &called) UNDO_SETUP_GOT leave CFI_RESTORE(%ebp) CFI_DEF_CFA(%esp, 4) ret END_FUNCTION art_portable_to_interpreter_bridge