1/* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "asm_support_x86.S" 18 19 /* 20 * Portable invocation stub. 21 * On entry: 22 * [sp] = return address 23 * [sp + 4] = method pointer 24 * [sp + 8] = argument array or NULL for no argument methods 25 * [sp + 12] = size of argument array in bytes 26 * [sp + 16] = (managed) thread pointer 27 * [sp + 20] = JValue* result 28 * [sp + 24] = result type char 29 */ 30DEFINE_FUNCTION art_portable_invoke_stub 31 PUSH ebp // save ebp 32 PUSH ebx // save ebx 33 mov %esp, %ebp // copy value of stack pointer into base pointer 34 CFI_DEF_CFA_REGISTER(ebp) 35 mov 20(%ebp), %ebx // get arg array size 36 addl LITERAL(28), %ebx // reserve space for return addr, method*, ebx, and ebp in frame 37 andl LITERAL(0xFFFFFFF0), %ebx // align frame size to 16 bytes 38 subl LITERAL(12), %ebx // remove space for return address, ebx, and ebp 39 subl %ebx, %esp // reserve stack space for argument array 40 SETUP_GOT_NOSAVE // reset ebx to GOT table 41 lea 4(%esp), %eax // use stack pointer + method ptr as dest for memcpy 42 pushl 20(%ebp) // push size of region to memcpy 43 pushl 16(%ebp) // push arg array as source of memcpy 44 pushl %eax // push stack pointer as destination of memcpy 45 call PLT_SYMBOL(memcpy) // (void*, const void*, size_t) 46 addl LITERAL(12), %esp // pop arguments to memcpy 47 mov 12(%ebp), %eax // move method pointer into eax 48 mov %eax, (%esp) // push method pointer onto stack 49 call *METHOD_PORTABLE_CODE_OFFSET_32(%eax) // call the method 50 mov %ebp, %esp // restore stack pointer 51 POP ebx // pop ebx 52 POP ebp // pop ebp 53 mov 20(%esp), %ecx // get result pointer 54 cmpl LITERAL(68), 24(%esp) // test if result type char == 'D' 55 je .Lreturn_double_portable 56 cmpl LITERAL(70), 24(%esp) // test if result type char == 'F' 57 je .Lreturn_float_portable 58 mov %eax, (%ecx) // store the result 59 mov %edx, 4(%ecx) // store the other half of the result 60 ret 61.Lreturn_double_portable: 62 fstpl (%ecx) // store the floating point result as double 63 ret 64.Lreturn_float_portable: 65 fstps (%ecx) // store the floating point result as float 66 ret 67END_FUNCTION art_portable_invoke_stub 68 69DEFINE_FUNCTION art_portable_proxy_invoke_handler 70 PUSH ebp // Set up frame. 71 movl %esp, %ebp 72 CFI_DEF_CFA_REGISTER(%ebp) 73 subl LITERAL(4), %esp // Align stack 74 SETUP_GOT // pushes ebx 75 leal 8(%ebp), %edx // %edx = ArtMethod** called_addr 76 movl 12(%ebp), %ecx // %ecx = receiver 77 movl 0(%edx), %eax // %eax = ArtMethod* called 78 pushl %edx // Pass called_addr. 79 pushl %fs:THREAD_SELF_OFFSET // Pass thread. 80 pushl %ecx // Pass receiver. 81 pushl %eax // Pass called. 82 call PLT_SYMBOL(artPortableProxyInvokeHandler) // (called, receiver, Thread*, &called) 83 UNDO_SETUP_GOT 84 leave 85 CFI_RESTORE(%ebp) 86 CFI_DEF_CFA(%esp, 4) 87 movd %eax, %xmm0 // Place return value also into floating point return value. 88 movd %edx, %xmm1 89 punpckldq %xmm1, %xmm0 90 ret 91END_FUNCTION art_portable_proxy_invoke_handler 92 93DEFINE_FUNCTION art_portable_resolution_trampoline 94 PUSH ebp // Set up frame. 95 movl %esp, %ebp 96 CFI_DEF_CFA_REGISTER(%ebp) 97 subl LITERAL(4), %esp // Align stack 98 SETUP_GOT // pushes ebx 99 leal 8(%ebp), %edx // %edx = ArtMethod** called_addr 100 movl 12(%ebp), %ecx // %ecx = receiver 101 movl 0(%edx), %eax // %eax = ArtMethod* called 102 pushl %edx // Pass called_addr. 103 pushl %fs:THREAD_SELF_OFFSET // Pass thread. 104 pushl %ecx // Pass receiver. 105 pushl %eax // Pass called. 106 call PLT_SYMBOL(artPortableResolutionTrampoline) // (called, receiver, Thread*, &called) 107 UNDO_SETUP_GOT 108 leave 109 CFI_RESTORE(%ebp) 110 CFI_DEF_CFA(%esp, 4) 111 testl %eax, %eax 112 jz .Lresolve_fail 113 jmp * %eax 114.Lresolve_fail: // Resolution failed, return with exception pending. 115 ret 116END_FUNCTION art_portable_resolution_trampoline 117 118DEFINE_FUNCTION_NO_HIDE art_portable_to_interpreter_bridge 119 PUSH ebp // Set up frame. 120 movl %esp, %ebp 121 CFI_DEF_CFA_REGISTER(%ebp) 122 subl LITERAL(8), %esp // Align stack 123 SETUP_GOT 124 leal 8(%ebp), %edx // %edx = ArtMethod** called_addr 125 movl 0(%edx), %eax // %eax = ArtMethod* called 126 pushl %edx // Pass called_addr. 127 pushl %fs:THREAD_SELF_OFFSET // Pass thread. 128 pushl %eax // Pass called. 129 call PLT_SYMBOL(artPortableToInterpreterBridge) // (called, Thread*, &called) 130 UNDO_SETUP_GOT 131 leave 132 CFI_RESTORE(%ebp) 133 CFI_DEF_CFA(%esp, 4) 134 ret 135END_FUNCTION art_portable_to_interpreter_bridge 136