1   /* Copyright (C) 2008 The Android Open Source Project
2    *
3    * Licensed under the Apache License, Version 2.0 (the "License");
4    * you may not use this file except in compliance with the License.
5    * You may obtain a copy of the License at
6    *
7    * http://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software
10    * distributed under the License is distributed on an "AS IS" BASIS,
11    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12    * See the License for the specific language governing permissions and
13    * limitations under the License.
14    */
15
16   /*
17    * File: CallABI.S
18    *
19    * Code: facitliates call to native code C and C++ routines.
20    *
21    */
22
23   /*
24    * Function prototype:
25    *
26    * void dvmPlatformInvoke(void* pEnv, ClassObject* clazz, int argInfo, int argc,
27    * const u4* argv, const char* signature, void* func, JValue* pReturn)
28    *
29    * The method we are calling has the form:
30    *
31    * return_type func(JNIEnv* pEnv, ClassObject* clazz, ...)
32    * -or-
33    * return_type func(JNIEnv* pEnv, Object* this, ...)
34    *
35    * We receive a collection of 32-bit values which correspond to arguments from
36    * the interpreter (e.g. float occupies one, double occupies two).  It's up to
37    * us to convert these into local calling conventions.
38    */
39
40   /*
41    * On entry:
42    *   4(%sp)    JNIEnv (can be left alone)
43    *   8(%esp)   clazz (NULL for virtual method calls, non-NULL for static)
44    *   12(%esp)  arg info
45    *   16(%esp)  argc (number of 32-bit values in argv)
46    *   20(%esp)  argv
47    *   24(%esp)  short signature
48    *   28(%esp)  func
49    *   32(%esp)  pReturn
50    *
51    * For a virtual method call, the "this" reference is in argv[0].
52    *
53    * argInfo (32-bit int) layout:
54    *
55    *   SRRRHHHH HHHHHHHH HHHHHHHH HHHHHHHH
56    *
57    *   S - if set, argInfo hints are invalid
58    *   R - return type enumeration (see jniInternal.h)
59    *       VOID   -> 0
60    *       FLOAT  -> 1
61    *       DOUBLE -> 2
62    *       S8     -> 3
63    *       S4     -> 4
64    *    H - target-specific hints (see below for details)
65    *
66    * IA32 ABI JNI hint format
67    *
68    *       ZZZZ ZZZZZZZZ AAAAAAAA AAAAAAAA
69    *
70    *   Z - reserved
71    *   A - size of the variable argument block in 32-bit words
72    */
73
74    .text
75    .align  4
76    .global dvmPlatformInvoke
77    .type   dvmPlatformInvoke, %function
78
79
80dvmPlatformInvoke:
81CallABI_ENTER:
82
83   /*
84    * Save registers.
85    */
86
87    movl        %ebp, -4(%esp)
88    movl        %ebx, -8(%esp)          # save %ebx
89    movl        %esi, -12(%esp)         # save %esi
90    movl        %edi, -16(%esp)         # save %edi
91    lea         (%esp), %ebp
92
93   /*
94    * Update and align (16 bytes) stack pointer
95    */
96
97    lea         -32(%esp), %esp
98
99   /*
100    * Check if argInfo is valid. Is always valid so should remove this check?
101    */
102
103    movzwl      12(%ebp), %ecx          # %ecx<- argsize in words
104    movl        12(%ebp), %ebx          # %ebx<- argInfo
105
106    shl         $2, %ecx                # %ecx<- argsize in bytes
107    subl        %ecx, %esp              # %esp<- expanded for arg region
108
109   /*
110    * Is the alignment right?
111    */
112
113#if 1
114    test        $4, %esp
115    jnz         1f
116    subl        $4, %esp
1171:
118    test        $8, %esp
119    jnz         1f
120    subl        $8, %esp
1211:
122#endif
123
124    movl        8(%ebp), %eax           # %eax<- clazz
125    cmpl        $0, %eax                # Check virtual or static
126    movl        4(%ebp), %ecx           # %ecx<- JNIEnv
127    movl        20(%ebp), %esi          # %esi<- argV
128    jne         1f                      # Branch if static
129    movl        (%esi), %eax            # get the this pointer
130    addl        $4, %esi                # %esi<- update past this
131
1321:
133    movl        %ecx, -8(%esp)          # push JNIEnv as arg #1
134    movl        %eax, -4(%esp)          # push clazz or this as arg #2
135    lea         -8(%esp), %esp
136
137   /*
138    * Copy arguments
139    */
140
141    movzwl      %bx, %ecx               # %ecx<- %bx; argsize in words
142    lea         8(%esp), %edi           # %edi<- stack location for arguments
143    cld
144    rep         movsl                   # move %ecx arguments to 8(%esp)
145    call        *28(%ebp)
146    sarl        $28, %ebx               # %ebx<- SRRR (low 4 bits)
147    je          CallABI_EXIT            # exit call
148    cmpl        $2, %ebx
149    movl        32(%ebp), %ecx          # %ecx<- return pointer
150    je          2f                      # handle double return
151    jl          1f                      # handle float return
152    movl        %eax, (%ecx)            # save 32-bit return
153    movl        %edx, 4(%ecx)           # save 64-bit return
154    jmp         CallABI_EXIT            # exit call
155
1562:
157    fstpl       (%ecx)                  # save double return
158    jmp         CallABI_EXIT            # exit call
1591:
160    fstps       (%ecx)                  # save float return
161
162CallABI_EXIT:
163    lea         (%ebp), %esp
164    movl        -16(%ebp), %edi         # restore %edi
165    movl        -12(%ebp), %esi         # restore %esi
166    movl        -8(%ebp), %ebx          # restore %ebx
167    movl        -4(%ebp), %ebp          # restore caller base pointer
168    ret                                 # return
169