17655f29fabc0a12765de828914a18314382e5a35Ian Rogers/* 27655f29fabc0a12765de828914a18314382e5a35Ian Rogers * Copyright (C) 2012 The Android Open Source Project 37655f29fabc0a12765de828914a18314382e5a35Ian Rogers * 47655f29fabc0a12765de828914a18314382e5a35Ian Rogers * Licensed under the Apache License, Version 2.0 (the "License"); 57655f29fabc0a12765de828914a18314382e5a35Ian Rogers * you may not use this file except in compliance with the License. 67655f29fabc0a12765de828914a18314382e5a35Ian Rogers * You may obtain a copy of the License at 77655f29fabc0a12765de828914a18314382e5a35Ian Rogers * 87655f29fabc0a12765de828914a18314382e5a35Ian Rogers * http://www.apache.org/licenses/LICENSE-2.0 97655f29fabc0a12765de828914a18314382e5a35Ian Rogers * 107655f29fabc0a12765de828914a18314382e5a35Ian Rogers * Unless required by applicable law or agreed to in writing, software 117655f29fabc0a12765de828914a18314382e5a35Ian Rogers * distributed under the License is distributed on an "AS IS" BASIS, 127655f29fabc0a12765de828914a18314382e5a35Ian Rogers * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137655f29fabc0a12765de828914a18314382e5a35Ian Rogers * See the License for the specific language governing permissions and 147655f29fabc0a12765de828914a18314382e5a35Ian Rogers * limitations under the License. 157655f29fabc0a12765de828914a18314382e5a35Ian Rogers */ 167655f29fabc0a12765de828914a18314382e5a35Ian Rogers 177655f29fabc0a12765de828914a18314382e5a35Ian Rogers#include "asm_support_x86.S" 187655f29fabc0a12765de828914a18314382e5a35Ian Rogers 197655f29fabc0a12765de828914a18314382e5a35Ian Rogers /* 207655f29fabc0a12765de828914a18314382e5a35Ian Rogers * Portable invocation stub. 217655f29fabc0a12765de828914a18314382e5a35Ian Rogers * On entry: 227655f29fabc0a12765de828914a18314382e5a35Ian Rogers * [sp] = return address 237655f29fabc0a12765de828914a18314382e5a35Ian Rogers * [sp + 4] = method pointer 247655f29fabc0a12765de828914a18314382e5a35Ian Rogers * [sp + 8] = argument array or NULL for no argument methods 257655f29fabc0a12765de828914a18314382e5a35Ian Rogers * [sp + 12] = size of argument array in bytes 267655f29fabc0a12765de828914a18314382e5a35Ian Rogers * [sp + 16] = (managed) thread pointer 277655f29fabc0a12765de828914a18314382e5a35Ian Rogers * [sp + 20] = JValue* result 287655f29fabc0a12765de828914a18314382e5a35Ian Rogers * [sp + 24] = result type char 297655f29fabc0a12765de828914a18314382e5a35Ian Rogers */ 307655f29fabc0a12765de828914a18314382e5a35Ian RogersDEFINE_FUNCTION art_portable_invoke_stub 317655f29fabc0a12765de828914a18314382e5a35Ian Rogers PUSH ebp // save ebp 327655f29fabc0a12765de828914a18314382e5a35Ian Rogers PUSH ebx // save ebx 337655f29fabc0a12765de828914a18314382e5a35Ian Rogers mov %esp, %ebp // copy value of stack pointer into base pointer 347655f29fabc0a12765de828914a18314382e5a35Ian Rogers .cfi_def_cfa_register ebp 357655f29fabc0a12765de828914a18314382e5a35Ian Rogers mov 20(%ebp), %ebx // get arg array size 367655f29fabc0a12765de828914a18314382e5a35Ian Rogers addl LITERAL(28), %ebx // reserve space for return addr, method*, ebx, and ebp in frame 377655f29fabc0a12765de828914a18314382e5a35Ian Rogers andl LITERAL(0xFFFFFFF0), %ebx // align frame size to 16 bytes 387655f29fabc0a12765de828914a18314382e5a35Ian Rogers subl LITERAL(12), %ebx // remove space for return address, ebx, and ebp 397655f29fabc0a12765de828914a18314382e5a35Ian Rogers subl %ebx, %esp // reserve stack space for argument array 407655f29fabc0a12765de828914a18314382e5a35Ian Rogers lea 4(%esp), %eax // use stack pointer + method ptr as dest for memcpy 417655f29fabc0a12765de828914a18314382e5a35Ian Rogers pushl 20(%ebp) // push size of region to memcpy 427655f29fabc0a12765de828914a18314382e5a35Ian Rogers pushl 16(%ebp) // push arg array as source of memcpy 437655f29fabc0a12765de828914a18314382e5a35Ian Rogers pushl %eax // push stack pointer as destination of memcpy 447655f29fabc0a12765de828914a18314382e5a35Ian Rogers call SYMBOL(memcpy) // (void*, const void*, size_t) 457655f29fabc0a12765de828914a18314382e5a35Ian Rogers addl LITERAL(12), %esp // pop arguments to memcpy 467655f29fabc0a12765de828914a18314382e5a35Ian Rogers mov 12(%ebp), %eax // move method pointer into eax 477655f29fabc0a12765de828914a18314382e5a35Ian Rogers mov %eax, (%esp) // push method pointer onto stack 487655f29fabc0a12765de828914a18314382e5a35Ian Rogers call *METHOD_CODE_OFFSET(%eax) // call the method 497655f29fabc0a12765de828914a18314382e5a35Ian Rogers mov %ebp, %esp // restore stack pointer 507655f29fabc0a12765de828914a18314382e5a35Ian Rogers POP ebx // pop ebx 517655f29fabc0a12765de828914a18314382e5a35Ian Rogers POP ebp // pop ebp 527655f29fabc0a12765de828914a18314382e5a35Ian Rogers mov 20(%esp), %ecx // get result pointer 537655f29fabc0a12765de828914a18314382e5a35Ian Rogers cmpl LITERAL(68), 24(%esp) // test if result type char == 'D' 547655f29fabc0a12765de828914a18314382e5a35Ian Rogers je return_double_portable 557655f29fabc0a12765de828914a18314382e5a35Ian Rogers cmpl LITERAL(70), 24(%esp) // test if result type char == 'F' 567655f29fabc0a12765de828914a18314382e5a35Ian Rogers je return_float_portable 577655f29fabc0a12765de828914a18314382e5a35Ian Rogers mov %eax, (%ecx) // store the result 587655f29fabc0a12765de828914a18314382e5a35Ian Rogers mov %edx, 4(%ecx) // store the other half of the result 597655f29fabc0a12765de828914a18314382e5a35Ian Rogers ret 607655f29fabc0a12765de828914a18314382e5a35Ian Rogersreturn_double_portable: 617655f29fabc0a12765de828914a18314382e5a35Ian Rogers fstpl (%ecx) // store the floating point result as double 627655f29fabc0a12765de828914a18314382e5a35Ian Rogers ret 637655f29fabc0a12765de828914a18314382e5a35Ian Rogersreturn_float_portable: 647655f29fabc0a12765de828914a18314382e5a35Ian Rogers fstps (%ecx) // store the floating point result as float 657655f29fabc0a12765de828914a18314382e5a35Ian Rogers ret 667655f29fabc0a12765de828914a18314382e5a35Ian RogersEND_FUNCTION art_portable_invoke_stub 677655f29fabc0a12765de828914a18314382e5a35Ian Rogers 687655f29fabc0a12765de828914a18314382e5a35Ian RogersDEFINE_FUNCTION art_portable_proxy_invoke_handler 6997fbbef4736845fe1ce7d1090c70eb6aaa6628ddIan Rogers PUSH ebp // Set up frame. 7097fbbef4736845fe1ce7d1090c70eb6aaa6628ddIan Rogers movl %esp, %ebp 7197fbbef4736845fe1ce7d1090c70eb6aaa6628ddIan Rogers .cfi_def_cfa_register %ebp 7297fbbef4736845fe1ce7d1090c70eb6aaa6628ddIan Rogers subl LITERAL(8), %esp // Align stack 7397fbbef4736845fe1ce7d1090c70eb6aaa6628ddIan Rogers leal 8(%ebp), %edx // %edx = ArtMethod** called_addr 7497fbbef4736845fe1ce7d1090c70eb6aaa6628ddIan Rogers movl 12(%ebp), %ecx // %ecx = receiver 7597fbbef4736845fe1ce7d1090c70eb6aaa6628ddIan Rogers movl 0(%edx), %eax // %eax = ArtMethod* called 7697fbbef4736845fe1ce7d1090c70eb6aaa6628ddIan Rogers pushl %edx // Pass called_addr. 7797fbbef4736845fe1ce7d1090c70eb6aaa6628ddIan Rogers pushl %fs:THREAD_SELF_OFFSET // Pass thread. 7897fbbef4736845fe1ce7d1090c70eb6aaa6628ddIan Rogers pushl %ecx // Pass receiver. 7997fbbef4736845fe1ce7d1090c70eb6aaa6628ddIan Rogers pushl %eax // Pass called. 8097fbbef4736845fe1ce7d1090c70eb6aaa6628ddIan Rogers call SYMBOL(artPortableProxyInvokeHandler) // (called, receiver, Thread*, &called) 8197fbbef4736845fe1ce7d1090c70eb6aaa6628ddIan Rogers leave 8297fbbef4736845fe1ce7d1090c70eb6aaa6628ddIan Rogers .cfi_restore %ebp 8397fbbef4736845fe1ce7d1090c70eb6aaa6628ddIan Rogers .cfi_def_cfa %esp, 4 8497fbbef4736845fe1ce7d1090c70eb6aaa6628ddIan Rogers movd %eax, %xmm0 // Place return value also into floating point return value. 857655f29fabc0a12765de828914a18314382e5a35Ian Rogers movd %edx, %xmm1 867655f29fabc0a12765de828914a18314382e5a35Ian Rogers punpckldq %xmm1, %xmm0 877655f29fabc0a12765de828914a18314382e5a35Ian Rogers ret 887655f29fabc0a12765de828914a18314382e5a35Ian RogersEND_FUNCTION art_portable_proxy_invoke_handler 897655f29fabc0a12765de828914a18314382e5a35Ian Rogers 90bd136a29f08486525d6abc7d0a0006ce5b4011c1Dragos SbirleaDEFINE_FUNCTION art_portable_resolution_trampoline 9197fbbef4736845fe1ce7d1090c70eb6aaa6628ddIan Rogers PUSH ebp // Set up frame. 9297fbbef4736845fe1ce7d1090c70eb6aaa6628ddIan Rogers movl %esp, %ebp 9397fbbef4736845fe1ce7d1090c70eb6aaa6628ddIan Rogers .cfi_def_cfa_register %ebp 94bd136a29f08486525d6abc7d0a0006ce5b4011c1Dragos Sbirlea subl LITERAL(8), %esp // Align stack 9597fbbef4736845fe1ce7d1090c70eb6aaa6628ddIan Rogers leal 8(%ebp), %edx // %edx = ArtMethod** called_addr 9697fbbef4736845fe1ce7d1090c70eb6aaa6628ddIan Rogers movl 12(%ebp), %ecx // %ecx = receiver 9797fbbef4736845fe1ce7d1090c70eb6aaa6628ddIan Rogers movl 0(%edx), %eax // %eax = ArtMethod* called 9897fbbef4736845fe1ce7d1090c70eb6aaa6628ddIan Rogers pushl %edx // Pass called_addr. 9997fbbef4736845fe1ce7d1090c70eb6aaa6628ddIan Rogers pushl %fs:THREAD_SELF_OFFSET // Pass thread. 10097fbbef4736845fe1ce7d1090c70eb6aaa6628ddIan Rogers pushl %ecx // Pass receiver. 10197fbbef4736845fe1ce7d1090c70eb6aaa6628ddIan Rogers pushl %eax // Pass called. 10297fbbef4736845fe1ce7d1090c70eb6aaa6628ddIan Rogers call SYMBOL(artPortableResolutionTrampoline) // (called, receiver, Thread*, &called) 103bd136a29f08486525d6abc7d0a0006ce5b4011c1Dragos Sbirlea leave 10497fbbef4736845fe1ce7d1090c70eb6aaa6628ddIan Rogers .cfi_restore %ebp 10597fbbef4736845fe1ce7d1090c70eb6aaa6628ddIan Rogers .cfi_def_cfa %esp, 4 10697fbbef4736845fe1ce7d1090c70eb6aaa6628ddIan Rogers testl %eax, %eax 10797fbbef4736845fe1ce7d1090c70eb6aaa6628ddIan Rogers jz resolve_fail 108bd136a29f08486525d6abc7d0a0006ce5b4011c1Dragos Sbirlea jmp * %eax 10997fbbef4736845fe1ce7d1090c70eb6aaa6628ddIan Rogersresolve_fail: // Resolution failed, return with exception pending. 110bd136a29f08486525d6abc7d0a0006ce5b4011c1Dragos Sbirlea ret 111bd136a29f08486525d6abc7d0a0006ce5b4011c1Dragos SbirleaEND_FUNCTION art_portable_resolution_trampoline 112bd136a29f08486525d6abc7d0a0006ce5b4011c1Dragos Sbirlea 113bd136a29f08486525d6abc7d0a0006ce5b4011c1Dragos SbirleaDEFINE_FUNCTION art_portable_to_interpreter_bridge 11497fbbef4736845fe1ce7d1090c70eb6aaa6628ddIan Rogers PUSH ebp // Set up frame. 11597fbbef4736845fe1ce7d1090c70eb6aaa6628ddIan Rogers movl %esp, %ebp 11697fbbef4736845fe1ce7d1090c70eb6aaa6628ddIan Rogers .cfi_def_cfa_register %ebp 117bd136a29f08486525d6abc7d0a0006ce5b4011c1Dragos Sbirlea subl LITERAL(12), %esp // Align stack 11897fbbef4736845fe1ce7d1090c70eb6aaa6628ddIan Rogers leal 8(%ebp), %edx // %edx = ArtMethod** called_addr 11997fbbef4736845fe1ce7d1090c70eb6aaa6628ddIan Rogers movl 0(%edx), %eax // %eax = ArtMethod* called 12097fbbef4736845fe1ce7d1090c70eb6aaa6628ddIan Rogers pushl %edx // Pass called_addr. 12197fbbef4736845fe1ce7d1090c70eb6aaa6628ddIan Rogers pushl %fs:THREAD_SELF_OFFSET // Pass thread. 12297fbbef4736845fe1ce7d1090c70eb6aaa6628ddIan Rogers pushl %eax // Pass called. 12397fbbef4736845fe1ce7d1090c70eb6aaa6628ddIan Rogers call SYMBOL(artPortableToInterpreterBridge) // (called, Thread*, &called) 124bd136a29f08486525d6abc7d0a0006ce5b4011c1Dragos Sbirlea leave 12597fbbef4736845fe1ce7d1090c70eb6aaa6628ddIan Rogers .cfi_restore %ebp 12697fbbef4736845fe1ce7d1090c70eb6aaa6628ddIan Rogers .cfi_def_cfa %esp, 4 127bd136a29f08486525d6abc7d0a0006ce5b4011c1Dragos Sbirlea ret 128984c18350e6a1d603bf31ae07f137c0a8b14e83cBrian CarlstromEND_FUNCTION art_portable_to_interpreter_bridge 129