• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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: facilitates 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    * Check if argInfo is valid. Is always valid so should remove this check?
95    */
96
97    movzwl      12(%ebp), %ecx          # %ecx<- argsize in words
98    movl        12(%ebp), %ebx          # %ebx<- argInfo
99
100    shl         $2, %ecx                # %ecx<- argsize in bytes
101    subl        %ecx, %esp              # %esp<- expanded for arg region
102
103   /*
104    * Prepare for 16 byte alignment
105    */
106
107    and         $0xfffffff0, %esp
108    subl        $24, %esp
109
110
111    movl        8(%ebp), %eax           # %eax<- clazz
112    cmpl        $0, %eax                # Check virtual or static
113    movl        4(%ebp), %ecx           # %ecx<- JNIEnv
114    movl        20(%ebp), %esi          # %esi<- argV
115    jne         1f                      # Branch if static
116    movl        (%esi), %eax            # get the this pointer
117    addl        $4, %esi                # %esi<- update past this
118
1191:
120    movl        %ecx, -8(%esp)          # push JNIEnv as arg #1
121    movl        %eax, -4(%esp)          # push clazz or this as arg #2
122    lea         -8(%esp), %esp
123
124   /*
125    * Copy arguments
126    */
127
128    movzwl      %bx, %ecx               # %ecx<- %bx; argsize in words
129    lea         8(%esp), %edi           # %edi<- stack location for arguments
130    cld
131    rep         movsl                   # move %ecx arguments to 8(%esp)
132    call        *28(%ebp)
133    sarl        $28, %ebx               # %ebx<- SRRR (low 4 bits)
134    je          CallABI_EXIT            # exit call
135    cmpl        $2, %ebx
136    movl        32(%ebp), %ecx          # %ecx<- return pointer
137    je          2f                      # handle double return
138    jl          1f                      # handle float return
139
140   /*
141    *  If a native function returns a result smaller than 8-bytes
142    *  then higher bytes may contain garbage.
143    *  This code does type-checking based on size of return result.
144    *  We zero higher bytes instead of allowing the garbage to go through.
145    */
146
147    cmpl        $3,%ebx
148    je          S8
149    cmpl        $4,%ebx
150    je          S4
151    cmpl        $7,%ebx
152    je          S1
153    cmpl        $6,%ebx
154    jne         S2
155U2:
156    movzwl      %ax, %eax
157    movl        %eax, (%ecx)            # save 32-bit return
158    jmp         CallABI_EXIT            # exit call
159
160S1:
161    movsbl      %al, %eax
162    movl        %eax, (%ecx)            # save 32-bit return
163    jmp         CallABI_EXIT            # exit call
164S2:
165    movswl      %ax, %eax
166    movl        %eax, (%ecx)            # save 32-bit return
167    jmp         CallABI_EXIT            # exit call
168S4:
169    cltd
170    movl        %eax, (%ecx)            # save 32-bit return
171    jmp         CallABI_EXIT            # exit call
172S8:
173    movl        %edx, 4(%ecx)           # save 64-bit return
174    movl        %eax, (%ecx)            # save 32-bit return
175    jmp         CallABI_EXIT            # exit call
176
1772:
178    fstpl       (%ecx)                  # save double return
179    jmp         CallABI_EXIT            # exit call
1801:
181    fstps       (%ecx)                  # save float return
182
183CallABI_EXIT:
184    lea         (%ebp), %esp
185    movl        -16(%ebp), %edi         # restore %edi
186    movl        -12(%ebp), %esi         # restore %esi
187    movl        -8(%ebp), %ebx          # restore %ebx
188    movl        -4(%ebp), %ebp          # restore caller base pointer
189    ret                                 # return
190