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     .global dvmPlatformInvoke
     59     .type   dvmPlatformInvoke, @function
     60 
     61 /*
     62  * On entry:
     63  *  [ 8]  arg0  JNIEnv (can be left alone)
     64  *  [12]  arg1  clazz (NULL for virtual method calls, non-NULL for static)
     65  *  [16]  arg2  arg info
     66  *  [20]  arg3  argc
     67  *  [24]  arg4  argv
     68  *  [28]  arg5  short signature
     69  *  [32]  arg6  func
     70  *  [36]  arg7  pReturn
     71  *
     72  * For a virtual method call, the "this" reference is in argv[0].
     73  *
     74  * argInfo (32-bit int) layout:
     75  *   SRRRZZZZ ZZZZZZZZ AAAAAAAA AAAAAAAA
     76  *
     77  *   Z - reserved
     78  *   S - if set, argInfo hints are invalid
     79  *   R - return type enumeration (see jniInternal.h)
     80  *       VOID   -> 0
     81  *       FLOAT  -> 1
     82  *       DOUBLE -> 2
     83  *       S8     -> 3
     84  *       S4     -> 4
     85  *   A - size of the variable argument block in 32-bit words
     86  *
     87  */
     88 dvmPlatformInvoke:
     89 /* Establish the frame pointer, spill & align to 16b */
     90     pushl    %ebp
     91     movl     %esp,%ebp
     92     pushl    %edi
     93     pushl    %esi
     94     pushl    %ebx
     95     subl     $12,%esp
     96 /* For 386 ABI, argInfo hints should always be valid.  Abort if not. */
     97     movl     16(%ebp),%ebx
     98     testl    %ebx,%ebx
     99     js       dvmAbort
    100 /*
    101  * Get the size of the variable region, add two more slots for the first
    102  * two arguments and grow (preserving alignment)
    103  */
    104     movl     %ebx,%ecx
    105     leal     20(,%ecx,4),%ecx
    106     andl     $0x0003FFF0,%ecx
    107     subl     %ecx,%esp
    108 /* Handle this/class */
    109     movl     8(%ebp),%ecx
    110     movl     12(%ebp),%eax
    111     movl     24(%ebp),%esi
    112     testl    %eax,%eax
    113     jne      isClass
    114     movl     (%esi),%eax
    115     addl     $4,%esi
    116 isClass:
    117     movl     %eax,4(%esp)
    118     movl     %ecx,0(%esp)
    119 /* Now, copy the variable arguments region */
    120     movl     %ebx,%ecx
    121     andl     $0x0000FFFF,%ecx
    122     leal     8(%esp),%edi
    123     cld
    124     rep
    125     movsd
    126 /* Ready to go - call the native code */
    127     call     *32(%ebp)
    128 /* Store the result. */
    129     sarl      $28,%ebx
    130     /* Is void? */
    131     testl     %ebx,%ebx
    132     je       cleanUpAndExit
    133     movl     36(%ebp),%ecx
    134     /* Is FP? */
    135     cmpl     $2,%ebx
    136     jle      isFP
    137     cmpl     $4,%ebx  /* smaller than 32-bits? */
    138     jg       isSmall
    139 storeRetval:
    140     /* Blindly storing 64-bits won't hurt 32-bit case */
    141     movl     %eax,(%ecx)
    142     movl     %edx,4(%ecx)
    143     jmp      cleanUpAndExit
    144 isSmall:
    145     cmpl     $7,%ebx  /* S1? */
    146     jne      checkShort
    147     movsbl   %al,%eax
    148     movl     %eax,(%ecx)
    149     jmp      cleanUpAndExit
    150 checkShort:
    151     cmpl     $6,%ebx  /* U2? */
    152     jne      isSignedShort
    153     movzwl   %ax,%eax
    154     movl     %eax,(%ecx)
    155     jmp      cleanUpAndExit
    156 isSignedShort:
    157     /* Must be S2 */
    158     movswl   %ax,%eax
    159     movl     %eax,(%ecx)
    160     jmp      cleanUpAndExit
    161 isFP:
    162     /* Is Float? */
    163     cmpl    $1,%ebx
    164     je       saveFloat
    165     fstpl    (%ecx)
    166     jmp      cleanUpAndExit
    167 saveFloat:
    168     fstps    (%ecx)
    169 cleanUpAndExit:
    170     leal     -12(%ebp),%esp
    171     pop      %ebx
    172     pop      %esi
    173     pop      %edi
    174     pop      %ebp
    175     ret
    176     .size    dvmPlatformInvoke, .-dvmPlatformInvoke
    177     .section .note.GNU-stack,"",@progbits
    178