blob: 5f270f80871012cd7cdbed9c15ee840bb8b62b62 [file] [log] [blame]
/*
* 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(%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 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