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