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(%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