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    lea  4(%esp), %eax            // use stack pointer + method ptr as dest for memcpy
41    pushl 20(%ebp)                // push size of region to memcpy
42    pushl 16(%ebp)                // push arg array as source of memcpy
43    pushl %eax                    // push stack pointer as destination of memcpy
44    call SYMBOL(memcpy)           // (void*, const void*, size_t)
45    addl LITERAL(12), %esp        // pop arguments to memcpy
46    mov 12(%ebp), %eax            // move method pointer into eax
47    mov %eax, (%esp)              // push method pointer onto stack
48    call *METHOD_CODE_OFFSET(%eax) // call the method
49    mov %ebp, %esp                // restore stack pointer
50    POP ebx                       // pop ebx
51    POP ebp                       // pop ebp
52    mov 20(%esp), %ecx            // get result pointer
53    cmpl LITERAL(68), 24(%esp)    // test if result type char == 'D'
54    je return_double_portable
55    cmpl LITERAL(70), 24(%esp)    // test if result type char == 'F'
56    je return_float_portable
57    mov %eax, (%ecx)              // store the result
58    mov %edx, 4(%ecx)             // store the other half of the result
59    ret
60return_double_portable:
61    fstpl (%ecx)                  // store the floating point result as double
62    ret
63return_float_portable:
64    fstps (%ecx)                  // store the floating point result as float
65    ret
66END_FUNCTION art_portable_invoke_stub
67
68DEFINE_FUNCTION art_portable_proxy_invoke_handler
69    PUSH ebp                        // Set up frame.
70    movl %esp, %ebp
71    .cfi_def_cfa_register %ebp
72    subl LITERAL(8), %esp           // Align stack
73    leal 8(%ebp), %edx              // %edx = ArtMethod** called_addr
74    movl 12(%ebp), %ecx             // %ecx = receiver
75    movl 0(%edx), %eax              // %eax = ArtMethod* called
76    pushl %edx                      // Pass called_addr.
77    pushl %fs:THREAD_SELF_OFFSET    // Pass thread.
78    pushl %ecx                      // Pass receiver.
79    pushl %eax                      // Pass called.
80    call SYMBOL(artPortableProxyInvokeHandler)  // (called, receiver, Thread*, &called)
81    leave
82    .cfi_restore %ebp
83    .cfi_def_cfa %esp, 4
84    movd %eax, %xmm0              // Place return value also into floating point return value.
85    movd %edx, %xmm1
86    punpckldq %xmm1, %xmm0
87    ret
88END_FUNCTION art_portable_proxy_invoke_handler
89
90DEFINE_FUNCTION art_portable_resolution_trampoline
91  PUSH ebp                        // Set up frame.
92  movl %esp, %ebp
93  .cfi_def_cfa_register %ebp
94  subl LITERAL(8), %esp           // Align stack
95  leal 8(%ebp), %edx              // %edx = ArtMethod** called_addr
96  movl 12(%ebp), %ecx             // %ecx = receiver
97  movl 0(%edx), %eax              // %eax = ArtMethod* called
98  pushl %edx                      // Pass called_addr.
99  pushl %fs:THREAD_SELF_OFFSET    // Pass thread.
100  pushl %ecx                      // Pass receiver.
101  pushl %eax                      // Pass called.
102  call SYMBOL(artPortableResolutionTrampoline)  // (called, receiver, Thread*, &called)
103  leave
104  .cfi_restore %ebp
105  .cfi_def_cfa %esp, 4
106  testl %eax, %eax
107  jz  resolve_fail
108  jmp * %eax
109resolve_fail:                     // Resolution failed, return with exception pending.
110  ret
111END_FUNCTION art_portable_resolution_trampoline
112
113DEFINE_FUNCTION art_portable_to_interpreter_bridge
114  PUSH ebp                        // Set up frame.
115  movl %esp, %ebp
116  .cfi_def_cfa_register %ebp
117  subl LITERAL(12), %esp          // Align stack
118  leal 8(%ebp), %edx              // %edx = ArtMethod** called_addr
119  movl 0(%edx), %eax              // %eax = ArtMethod* called
120  pushl %edx                      // Pass called_addr.
121  pushl %fs:THREAD_SELF_OFFSET    // Pass thread.
122  pushl %eax                      // Pass called.
123  call SYMBOL(artPortableToInterpreterBridge)  // (called, Thread*, &called)
124  leave
125  .cfi_restore %ebp
126  .cfi_def_cfa %esp, 4
127  ret
128END_FUNCTION art_portable_to_interpreter_bridge
129