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 80 dvmPlatformInvoke: 81 CallABI_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 117 1: 118 test $8, %esp 119 jnz 1f 120 subl $8, %esp 121 1: 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 132 1: 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 153 /* 154 * If a native function returns a result smaller than 8-bytes 155 * then higher bytes may contain garbage. 156 * This code does type-checking based on size of return result. 157 * We zero higher bytes instead of allowing the garbage to go through. 158 */ 159 160 cmpl $3,%ebx 161 je S8 162 cmpl $4,%ebx 163 je S4 164 cmpl $7,%ebx 165 je S1 166 cmpl $6,%ebx 167 jne S2 168 U2: 169 movzwl %ax, %eax 170 movl %eax, (%ecx) # save 32-bit return 171 jmp CallABI_EXIT # exit call 172 173 S1: 174 movsbl %al, %eax 175 movl %eax, (%ecx) # save 32-bit return 176 jmp CallABI_EXIT # exit call 177 S2: 178 movswl %ax, %eax 179 movl %eax, (%ecx) # save 32-bit return 180 jmp CallABI_EXIT # exit call 181 S4: 182 cltd 183 movl %eax, (%ecx) # save 32-bit return 184 jmp CallABI_EXIT # exit call 185 S8: 186 movl %edx, 4(%ecx) # save 64-bit return 187 movl %eax, (%ecx) # save 32-bit return 188 jmp CallABI_EXIT # exit call 189 190 2: 191 fstpl (%ecx) # save double return 192 jmp CallABI_EXIT # exit call 193 1: 194 fstps (%ecx) # save float return 195 196 CallABI_EXIT: 197 lea (%ebp), %esp 198 movl -16(%ebp), %edi # restore %edi 199 movl -12(%ebp), %esi # restore %esi 200 movl -8(%ebp), %ebx # restore %ebx 201 movl -4(%ebp), %ebp # restore caller base pointer 202 ret # return 203