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     * 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