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_FILLED_NEW_ARRAY.S
     18     *
     19     * Code: Constructs and fills an array with the given data. Provides
     20     *
     21     * For: float-to-int
     22     *
     23     * Description: Construct an array of the given type and size,
     24     *              filling it with the supplied contents. The type
     25     *              must be an array type. The array's contents
     26     *              must be single-word. The constructed instance
     27     *              is stored as a result in the same way that the
     28     *              method invocation instructions store their results,
     29     *              so the constructed instance must be moved to a
     30     *              register with a subsequent move-result-object
     31     *              instruction.
     32     *
     33     * Format: B|A|op CCCC G|F|E|D (35c)
     34     *         AA|op BBBB CCCC (3rc) (range)
     35     *
     36     * Syntax: [B=5] op {vD, vE, vF, vG, vA}, vtaboff@CCCC
     37     *         [B=4] op {vD, vE, vF, vG}, vtaboff@CCCC
     38     *         [B=3] op {vD, vE, vF}, vtaboff@CCCC
     39     *         [B=2] op {vD, vE}, vtaboff@CCCC
     40     *         [B=1] op {vD}, vtaboff@CCCC
     41     *
     42     *         op {vCCCC .. vNNNN}, meth@BBBB
     43     *         op {vCCCC .. vNNNN}, type@BBBB
     44     */
     45 
     46 %default { "isrange":"0" }
     47 
     48     movl        rGLUE, %edx             # %edx<- MterpGlue pointer
     49     movl        offGlue_methodClassDex(%edx), %edx # %edx<- glue->methodClassDex
     50     movl        offDvmDex_pResClasses(%edx), %edx # %edx<- glue->methodClassDex->pResClasses
     51     FETCH       1, %ecx                 # %ecx<- BBBB
     52     EXPORT_PC
     53     movl (%edx, %ecx, 4), %eax # %eax<- possibly resolved class
     54     cmp         $$0, %eax               # %eax<- check if already resolved
     55     jne         .L${opcode}_continue
     56     jmp         .L${opcode}_break
     57 %break
     58 
     59 .L${opcode}_break:
     60     movl        $$0, -8(%esp)           # push parameter false
     61     movl        %ecx, -12(%esp)         # push parameter BBBB
     62     movl        rGLUE, %edx             # %edx<- MterpGlue pointer
     63     movl        offGlue_method(%edx), %edx # %edx<- glue->method
     64     movl        offMethod_clazz(%edx), %edx # %edx<- glue->method->clazz
     65     movl        %edx, -16(%esp)         # push parameter glue->method->clazz
     66     lea         -16(%esp), %esp
     67     call        dvmResolveClass         # call: (const ClassObject* referrer, u4 classIdx,
     68                                         #        bool fromUnverifiedConstant)
     69                                         # return: ClassObject*
     70     lea         16(%esp), %esp
     71     cmp         $$0, %eax               # check for null return
     72     je          common_exceptionThrown  # handle exception
     73 
     74    /*
     75     * On entry:
     76     *  %eax holds array class
     77     *  rINST holds BA or AA
     78     */
     79 
     80 .L${opcode}_continue:
     81     movl        offClassObject_descriptor(%eax), %eax # %eax<- arrayClass->descriptor
     82     movzbl      1(%eax), %eax           # %eax<- descriptor[1]
     83     cmpb        $$'I', %al             # check if array of ints
     84     je          1f
     85     cmpb        $$'L', %al
     86     je          1f
     87     cmpb        $$'[', %al
     88     jne         .L${opcode}_notimpl     # jump to not implemented
     89 1:
     90     movl        %eax, sReg0             # save type
     91     movl        rINST, -12(%esp)        # push parameter length
     92     movl        %eax, -16(%esp)         # push parameter descriptor[1]
     93     movl        $$ALLOC_DONT_TRACK, -8(%esp) # push parameter to allocate flags
     94     .if         (!$isrange)
     95     shrl        $$4, -12(%esp)          # parameter length is B
     96     .endif
     97     lea         -16(%esp), %esp
     98     call        dvmAllocPrimitiveArray  # call: (char type, size_t length, int allocFlags)
     99                                         # return: ArrayObject*
    100     lea         16(%esp), %esp
    101     cmp         $$0, %eax               # check for null return
    102     je          common_exceptionThrown  # handle exception
    103 
    104     FETCH       2, %edx                 # %edx<- FEDC or CCCC
    105     movl        rGLUE, %ecx             # %ecx<- MterpGlue pointer
    106     movl        %eax, offGlue_retval(%ecx) # retval<- new array
    107     lea         offArrayObject_contents(%eax), %eax # %eax<- newArray->contents
    108     subl        $$1, -12(%esp)          # length--; check for negative
    109     js          2f                      # if length was zero, finish
    110 
    111    /*
    112     * copy values from registers into the array
    113     * %eax=array, %edx=CCCC/FEDC, -12(%esp)=length (from AA or B), rINST=AA/BA
    114     */
    115 
    116     .if         $isrange
    117     lea         (rFP, %edx, 4), %ecx    # %ecx<- &fpp[CCCC]
    118 1:
    119     movl        (%ecx), %edx            # %edx<- %ecx++
    120     lea         4(%ecx), %ecx           # %ecx++
    121     movl        %edx, (%eax)            # *contents<- vX
    122     lea         4(%eax), %eax           # %eax++; contents++
    123     subl        $$1, -12(%esp)          # length--
    124     jns         1b                      # or continue at 2
    125     .else
    126     cmp         $$4, -12(%esp)          # check length
    127     jne         1f                      # has four args
    128     and         $$15, rINST             # rINST<- A
    129     GET_VREG    rINST                   # rINST<- vA
    130     subl        $$1, -12(%esp)          # count--
    131     movl        rINST, 16(%eax)         # contents[4]<- vA
    132 1:
    133     movl        %edx, %ecx              # %ecx<- %edx; ecx for temp
    134     andl        $$15, %ecx              # %ecx<- G/F/E/D
    135     GET_VREG    %ecx                    # %ecx<- vG/vF/vE/vD
    136     shr         $$4, %edx               # %edx<- put next reg in low 4
    137     subl        $$1, -12(%esp)          # count--
    138     movl        %ecx, (%eax)            # *contents<- vX
    139     lea         4(%eax), %eax           # %eax++; contents++
    140     jns         1b                      # or continue at 2
    141     .endif
    142 2:
    143     cmpb        $$'I', sReg0            # check for int array
    144     je          3f
    145     movl        rGLUE, %ecx             # %ecx<- MterpGlue pointer
    146     movl        offGlue_retval(%ecx), %eax # Object head
    147     movl        offGlue_cardTable(%ecx), %ecx # card table base
    148     shrl        $$GC_CARD_SHIFT, %eax   # convert to card num
    149     movb        %cl,(%ecx, %eax)        # mark card based on object head
    150 3:
    151     FINISH      3                       # jump to next instruction
    152 
    153    /*
    154     * Throw an exception to indicate this mode of filled-new-array
    155     * has not been implemented.
    156     */
    157 
    158 .L${opcode}_notimpl:
    159     movl        $$.LstrInternalError, -8(%esp)
    160     movl        $$.LstrFilledNewArrayNotImpl, -4(%esp)
    161     lea         -8(%esp), %esp
    162     call        dvmThrowException # call: (const char* exceptionDescriptor,
    163                                   #        const char* msg)
    164                                   # return: void
    165     lea         8(%esp), %esp
    166     jmp         common_exceptionThrown
    167 
    168 .if         (!$isrange)                 # define in one or the other, not both
    169 .LstrFilledNewArrayNotImpl:
    170 .asciz      "filled-new-array only implemented for 'int'"
    171 .LstrInternalError:
    172 .asciz  "Ljava/lang/InternalError;"
    173 .endif
    174