Home | History | Annotate | Download | only in x86-atom
      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