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 * 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 119 1: 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 155 U2: 156 movzwl %ax, %eax 157 movl %eax, (%ecx) # save 32-bit return 158 jmp CallABI_EXIT # exit call 159 160 S1: 161 movsbl %al, %eax 162 movl %eax, (%ecx) # save 32-bit return 163 jmp CallABI_EXIT # exit call 164 S2: 165 movswl %ax, %eax 166 movl %eax, (%ecx) # save 32-bit return 167 jmp CallABI_EXIT # exit call 168 S4: 169 cltd 170 movl %eax, (%ecx) # save 32-bit return 171 jmp CallABI_EXIT # exit call 172 S8: 173 movl %edx, 4(%ecx) # save 64-bit return 174 movl %eax, (%ecx) # save 32-bit return 175 jmp CallABI_EXIT # exit call 176 177 2: 178 fstpl (%ecx) # save double return 179 jmp CallABI_EXIT # exit call 180 1: 181 fstps (%ecx) # save float return 182 183 CallABI_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