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     cmp         $$'I', %eax             # check if array of ints
     84     jne         .L${opcode}_notimpl     # jump to not implemented
     85     movl        rINST, -12(%esp)        # push parameter length
     86     movl        %eax, -16(%esp)         # push parameter descriptor[1]
     87     movl        $$ALLOC_DONT_TRACK, -8(%esp) # push parameter to allocate flags
     88     .if         (!$isrange)
     89     shrl        $$4, -12(%esp)          # parameter length is B
     90     .endif
     91     lea         -16(%esp), %esp
     92     call        dvmAllocPrimitiveArray  # call: (char type, size_t length, int allocFlags)
     93                                         # return: ArrayObject*
     94     lea         16(%esp), %esp
     95     cmp         $$0, %eax               # check for null return
     96     je          common_exceptionThrown  # handle exception
     97 
     98     FETCH       2, %edx                 # %edx<- FEDC or CCCC
     99     movl        rGLUE, %ecx             # %ecx<- MterpGlue pointer
    100     movl        %eax, offGlue_retval(%ecx) # retval<- new array
    101     lea         offArrayObject_contents(%eax), %eax # %eax<- newArray->contents
    102     subl        $$1, -12(%esp)          # length--; check for negative
    103     js          2f                      # if length was zero, finish
    104 
    105    /*
    106     * copy values from registers into the array
    107     * %eax=array, %edx=CCCC/FEDC, -12(%esp)=length (from AA or B), rINST=AA/BA
    108     */
    109 
    110     .if         $isrange
    111     lea         (rFP, %edx, 4), %ecx    # %ecx<- &fpp[CCCC]
    112 1:
    113     movl        (%ecx), %edx            # %edx<- %ecx++
    114     lea         4(%ecx), %ecx           # %ecx++
    115     movl        %edx, (%eax)            # *contents<- vX
    116     lea         4(%eax), %eax           # %eax++; contents++
    117     subl        $$1, -12(%esp)          # length--
    118     jns         1b                      # or continue at 2
    119     .else
    120     cmp         $$4, -12(%esp)          # check length
    121     jne         1f                      # has four args
    122     and         $$15, rINST             # rINST<- A
    123     GET_VREG    rINST                   # rINST<- vA
    124     subl        $$1, -12(%esp)          # count--
    125     movl        rINST, 16(%eax)         # contents[4]<- vA
    126 1:
    127     movl        %edx, %ecx              # %ecx<- %edx; ecx for temp
    128     andl        $$15, %ecx              # %ecx<- G/F/E/D
    129     GET_VREG    %ecx                    # %ecx<- vG/vF/vE/vD
    130     shr         $$4, %edx               # %edx<- put next reg in low 4
    131     subl        $$1, -12(%esp)          # count--
    132     movl        %ecx, (%eax)            # *contents<- vX
    133     lea         4(%eax), %eax           # %eax++; contents++
    134     jns         1b                      # or continue at 2
    135     .endif
    136 2:
    137     FINISH      3                       # jump to next instruction
    138 
    139    /*
    140     * Throw an exception to indicate this mode of filled-new-array
    141     * has not been implemented.
    142     */
    143 
    144 .L${opcode}_notimpl:
    145     movl        $$.LstrInternalError, -8(%esp)
    146     movl        $$.LstrFilledNewArrayNotImpl, -4(%esp)
    147     lea         -8(%esp), %esp
    148     call        dvmThrowException # call: (const char* exceptionDescriptor,
    149                                   #        const char* msg)
    150                                   # return: void
    151     lea         8(%esp), %esp
    152     jmp         common_exceptionThrown
    153 
    154 .if         (!$isrange)                 # define in one or the other, not both
    155 .LstrFilledNewArrayNotImpl:
    156 .asciz      "filled-new-array only implemented for 'int'"
    157 .LstrInternalError:
    158 .asciz  "Ljava/lang/InternalError;"
    159 .endif
    160