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: OP_INSTANCE_OF.S
     18     *
     19     * Code: Checks if object is instance of a class. Uses no substitutions.
     20     *
     21     * For: instance-of
     22     *
     23     * Description: Store in the given destination register 1 if the indicated
     24     *              reference is an instance of the given type, or 0 if not.
     25     *              The type must be a reference type (not a primitive type).
     26     *
     27     * Format: B|A|op CCCC (22c)
     28     *
     29     * Syntax: op vA, vB, type@CCCC
     30     *         op vA, vB, field@CCCC
     31     */
     32 
     33     movl        rINST, %edx             # %edx<- BA
     34     shr         $$4, %edx               # %edx<- B
     35     GET_VREG    %edx                    # %edx<- vB
     36     cmp         $$0, %edx               # check for null object
     37     je          .L${opcode}_store       # null object
     38     jmp         .L${opcode}_break
     39 %break
     40 
     41 .L${opcode}_break:
     42     movl        rGLUE, %ecx             # %ecx<- pMterpGlue
     43     movl        offGlue_methodClassDex(%ecx), %ecx # %ecx<- pDvmDex
     44     FETCH       1, %eax                 # %eax<- CCCC
     45     movl        offDvmDex_pResClasses(%ecx), %ecx # %ecx<- pDvmDex->pResClasses
     46     movl        (%ecx, %eax, 4), %ecx   # %ecx<- resolved class
     47     movl        offObject_clazz(%edx), %edx # %edx<- obj->clazz
     48     cmp         $$0, %ecx               # check if already resovled
     49     je          .L${opcode}_resolve     # not resolved before, so resolve now
     50 
     51 .L${opcode}_resolved:
     52     cmp         %ecx, %edx              # check if same class
     53     je          .L${opcode}_trivial     # yes, finish
     54     jmp         .L${opcode}_fullcheck   # no, do full check
     55 
     56    /*
     57     * The trivial test failed, we need to perform a full check.
     58     * %edx holds obj->clazz
     59     * %ecx holds class resolved from BBBB
     60     */
     61 
     62 .L${opcode}_fullcheck:
     63     movl        %edx, -8(%esp)          # push parameter obj->clazz
     64     movl        %ecx, -4(%esp)          # push parameter resolved class
     65     lea         -8(%esp), %esp
     66     call        dvmInstanceofNonTrivial # perform full check
     67                                         # call: (ClassObject* instance, ClassObject* clazz)
     68                                         # return: int
     69     andl        $$15, rINST             # rINST<- A
     70     FFETCH_ADV  2, %edx                 # %edx<- next instruction hi; fetch, advance
     71     lea         8(%esp), %esp
     72     SET_VREG    %eax, rINST             # vA<- r0
     73     FGETOP_JMP  2, %edx                 # jump to next instruction; getop, jmp
     74 
     75    /*
     76     * %edx holds boolean result
     77     */
     78 
     79 .L${opcode}_store:
     80     FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
     81     andl        $$15, rINST             # rINST<- A
     82     SET_VREG    %edx, rINST             # vA<- r0
     83     FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
     84 
     85    /*
     86     * Trivial test succeeded, save and bail.
     87     */
     88 
     89 .L${opcode}_trivial:
     90     FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
     91     andl        $$15, rINST             # rINST<- A
     92     SET_VREG    $$1, rINST              # vA<- r0
     93     FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
     94 
     95    /*
     96     * Resolution required.  This is the least-likely path.
     97     * %eax holds BBBB
     98     */
     99 
    100 .L${opcode}_resolve:
    101 
    102     movl        rGLUE, %ecx             # %ecx<- pMterpGlue
    103     EXPORT_PC
    104     movl        offGlue_method(%ecx), %ecx # %ecx<- glue->method
    105     movl        offMethod_clazz(%ecx), %ecx # %ecx<- glue->method->clazz
    106     movl        %ecx, -12(%esp)         # push parameter glue->method->clazz
    107     movl        %eax, -8(%esp)          # push parameter CCCC; type index
    108     movl        $$1, -4(%esp)           # push parameter true
    109     lea         -12(%esp), %esp
    110     call        dvmResolveClass         # call: (const ClassObject* referrer, u4 classIdx,
    111                                         #        bool fromUnverifiedConstant)
    112                                         # return: ClassObject*
    113     lea         12(%esp), %esp
    114     cmp         $$0, %eax               # check for null
    115     je          common_exceptionThrown  # handle exception
    116     movl        rINST, %edx             # %edx<- BA+
    117     shr         $$4, %edx               # %edx<- B
    118     movl        %eax, %ecx              # need class in %ecx
    119     GET_VREG    %edx                    # %edx<- vB
    120     movl        offObject_clazz(%edx), %edx # %edx<- obj->clazz
    121     jmp         .L${opcode}_resolved    # clazz resolved, continue
    122