Home | History | Annotate | Download | only in x86
      1 /*
      2  * Copyright (C) 2008 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  * JNI method invocation.  This is used to call a C/C++ JNI method.  The
     18  * argument list has to be pushed onto the native stack according to
     19  * local calling conventions.
     20  *
     21  * This version supports 32-bit x86
     22  */
     23 
     24 /*
     25 Function prototype:
     26 
     27 void dvmPlatformInvoke(void* pEnv, ClassObject* clazz, int argInfo, int argc,
     28     const u4* argv, const char* signature, void* func, JValue* pReturn)
     29 
     30 The method we are calling has the form:
     31 
     32   return_type func(JNIEnv* pEnv, ClassObject* clazz, ...)
     33     -or-
     34   return_type func(JNIEnv* pEnv, Object* this, ...)
     35 
     36 We receive a collection of 32-bit values which correspond to arguments from
     37 the interpreter (e.g. float occupies one, double occupies two).  It's up to
     38 us to convert these into local calling conventions.
     39 */
     40 
     41 /*
     42 x86 notes:
     43 
     44 The native code expects arguments on the stack, pushed from right to left.
     45 This matches what Dalvik is passing here.
     46 
     47 EAX, EDX and ECX are scratch.
     48 
     49 4-byte alignment is required for long long and double, so we won't pad
     50 
     51 Non-FP return types <= 4 bytes come back in EAX
     52 Non-FP return types of 8 bytes come back in EAX:EDX, with lsw in EAX.
     53 Float and double returned on top of FP stack.
     54 
     55 */
     56 
     57     .text
     58     .align  4
     59     .global dvmPlatformInvoke
     60     .type   dvmPlatformInvoke, @function
     61 
     62 /*
     63  * On entry:
     64  *  [ 8]  arg0  JNIEnv (can be left alone)
     65  *  [12]  arg1  clazz (NULL for virtual method calls, non-NULL for static)
     66  *  [16]  arg2  arg info
     67  *  [20]  arg3  argc
     68  *  [24]  arg4  argv
     69  *  [28]  arg5  short signature
     70  *  [32]  arg6  func
     71  *  [36]  arg7  pReturn
     72  *
     73  * For a virtual method call, the "this" reference is in argv[0].
     74  *
     75  * argInfo (32-bit int) layout:
     76  *   SRRRZZZZ ZZZZZZZZ AAAAAAAA AAAAAAAA
     77  *
     78  *   Z - reserved
     79  *   S - if set, argInfo hints are invalid
     80  *   R - return type enumeration (see jniInternal.h)
     81  *       VOID   -> 0
     82  *       FLOAT  -> 1
     83  *       DOUBLE -> 2
     84  *       S8     -> 3
     85  *       S4     -> 4
     86  *   A - size of the variable argument block in 32-bit words
     87  *
     88  */
     89 dvmPlatformInvoke:
     90 /* Establish the frame pointer, spill & align to 16b */
     91     pushl    %ebp
     92     movl     %esp,%ebp
     93     pushl    %edi
     94     pushl    %esi
     95     pushl    %ebx
     96     subl     $12,%esp
     97 /* For 386 ABI, argInfo hints should always be valid.  Abort if not. */
     98     movl     16(%ebp),%ebx
     99     testl    %ebx,%ebx
    100     js       dvmAbort
    101 /*
    102  * Get the size of the variable region, add two more slots for the first
    103  * two arguments and grow (preserving alignment)
    104  */
    105     movl     %ebx,%ecx
    106     leal     20(,%ecx,4),%ecx
    107     andl     $0x0003FFF0,%ecx
    108     subl     %ecx,%esp
    109 /* Handle this/class */
    110     movl     8(%ebp),%ecx
    111     movl     12(%ebp),%eax
    112     movl     24(%ebp),%esi
    113     testl    %eax,%eax
    114     jne      isClass
    115     movl     (%esi),%eax
    116     addl     $4,%esi
    117 isClass:
    118     movl     %eax,4(%esp)
    119     movl     %ecx,0(%esp)
    120 /* Now, copy the variable arguments region */
    121     movl     %ebx,%ecx
    122     andl     $0x0000FFFF,%ecx
    123     leal     8(%esp),%edi
    124     cld
    125     rep
    126     movsd
    127 /* Ready to go - call the native code */
    128     call     *32(%ebp)
    129 /* Store the result. */
    130     sarl      $28,%ebx
    131     /* Is void? */
    132     testl     %ebx,%ebx
    133     je       cleanUpAndExit
    134     movl     36(%ebp),%ecx
    135     /* Is FP? */
    136     cmpl     $2,%ebx
    137     jle      isFP
    138     cmpl     $4,%ebx  /* smaller than 32-bits? */
    139     jg       isSmall
    140 storeRetval:
    141     /* Blindly storing 64-bits won't hurt 32-bit case */
    142     movl     %eax,(%ecx)
    143     movl     %edx,4(%ecx)
    144     jmp      cleanUpAndExit
    145 isSmall:
    146     cmpl     $7,%ebx  /* S1? */
    147     jne      checkShort
    148     movsbl   %al,%eax
    149     movl     %eax,(%ecx)
    150     jmp      cleanUpAndExit
    151 checkShort:
    152     cmpl     $6,%ebx  /* U2? */
    153     jne      isSignedShort
    154     movzwl   %ax,%eax
    155     movl     %eax,(%ecx)
    156     jmp      cleanUpAndExit
    157 isSignedShort:
    158     /* Must be S2 */
    159     movswl   %ax,%eax
    160     movl     %eax,(%ecx)
    161     jmp      cleanUpAndExit
    162 isFP:
    163     /* Is Float? */
    164     cmpl    $1,%ebx
    165     je       saveFloat
    166     fstpl    (%ecx)
    167     jmp      cleanUpAndExit
    168 saveFloat:
    169     fstps    (%ecx)
    170 cleanUpAndExit:
    171     leal     -12(%ebp),%esp
    172     pop      %ebx
    173     pop      %esi
    174     pop      %edi
    175     pop      %ebp
    176     ret
    177     .size    dvmPlatformInvoke, .-dvmPlatformInvoke
    178     .section .note.GNU-stack,"",@progbits
    179