   /* Copyright (C) 2008 The Android Open Source Project
    *
    * Licensed under the Apache License, Version 2.0 (the "License");
    * you may not use this file except in compliance with the License.
    * You may obtain a copy of the License at
    *
    * http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing, software
    * distributed under the License is distributed on an "AS IS" BASIS,
    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    * See the License for the specific language governing permissions and
    * limitations under the License.
    */

   /*
    * File: OP_FILLED_NEW_ARRAY.S
    *
    * Code: Constructs and fills an array with the given data. Provides
    *
    * For: float-to-int
    *
    * Description: Construct an array of the given type and size,
    *              filling it with the supplied contents. The type
    *              must be an array type. The array's contents
    *              must be single-word. The constructed instance
    *              is stored as a result in the same way that the
    *              method invocation instructions store their results,
    *              so the constructed instance must be moved to a
    *              register with a subsequent move-result-object
    *              instruction.
    *
    * Format: B|A|op CCCC G|F|E|D (35c)
    *         AA|op BBBB CCCC (3rc) (range)
    *
    * Syntax: [B=5] op {vD, vE, vF, vG, vA}, vtaboff@CCCC
    *         [B=4] op {vD, vE, vF, vG}, vtaboff@CCCC
    *         [B=3] op {vD, vE, vF}, vtaboff@CCCC
    *         [B=2] op {vD, vE}, vtaboff@CCCC
    *         [B=1] op {vD}, vtaboff@CCCC
    *
    *         op {vCCCC .. vNNNN}, meth@BBBB
    *         op {vCCCC .. vNNNN}, type@BBBB
    */

%default { "isrange":"0" }

    movl        rGLUE, %edx             # %edx<- MterpGlue pointer
    movl        offGlue_methodClassDex(%edx), %edx # %edx<- glue->methodClassDex
    movl        offDvmDex_pResClasses(%edx), %edx # %edx<- glue->methodClassDex->pResClasses
    FETCH       1, %ecx                 # %ecx<- BBBB
    EXPORT_PC
    movl (%edx, %ecx, 4), %eax # %eax<- possibly resolved class
    cmp         $$0, %eax               # %eax<- check if already resolved
    jne         .L${opcode}_continue
    jmp         .L${opcode}_break
%break

.L${opcode}_break:
    movl        $$0, -8(%esp)           # push parameter false
    movl        %ecx, -12(%esp)         # push parameter BBBB
    movl        rGLUE, %edx             # %edx<- MterpGlue pointer
    movl        offGlue_method(%edx), %edx # %edx<- glue->method
    movl        offMethod_clazz(%edx), %edx # %edx<- glue->method->clazz
    movl        %edx, -16(%esp)         # push parameter glue->method->clazz
    lea         -16(%esp), %esp
    call        dvmResolveClass         # call: (const ClassObject* referrer, u4 classIdx,
                                        #        bool fromUnverifiedConstant)
                                        # return: ClassObject*
    lea         16(%esp), %esp
    cmp         $$0, %eax               # check for null return
    je          common_exceptionThrown  # handle exception

   /*
    * On entry:
    *  %eax holds array class
    *  rINST holds BA or AA
    */

.L${opcode}_continue:
    movl        offClassObject_descriptor(%eax), %eax # %eax<- arrayClass->descriptor
    movzbl      1(%eax), %eax           # %eax<- descriptor[1]
    cmpb        $$'I', %al             # check if array of ints
    je          1f
    cmpb        $$'L', %al
    je          1f
    cmpb        $$'[', %al
    jne         .L${opcode}_notimpl     # jump to not implemented
1:
    movl        %eax, sReg0             # save type
    movl        rINST, -12(%esp)        # push parameter length
    movl        %eax, -16(%esp)         # push parameter descriptor[1]
    movl        $$ALLOC_DONT_TRACK, -8(%esp) # push parameter to allocate flags
    .if         (!$isrange)
    shrl        $$4, -12(%esp)          # parameter length is B
    .endif
    lea         -16(%esp), %esp
    call        dvmAllocPrimitiveArray  # call: (char type, size_t length, int allocFlags)
                                        # return: ArrayObject*
    lea         16(%esp), %esp
    cmp         $$0, %eax               # check for null return
    je          common_exceptionThrown  # handle exception

    FETCH       2, %edx                 # %edx<- FEDC or CCCC
    movl        rGLUE, %ecx             # %ecx<- MterpGlue pointer
    movl        %eax, offGlue_retval(%ecx) # retval<- new array
    lea         offArrayObject_contents(%eax), %eax # %eax<- newArray->contents
    subl        $$1, -12(%esp)          # length--; check for negative
    js          2f                      # if length was zero, finish

   /*
    * copy values from registers into the array
    * %eax=array, %edx=CCCC/FEDC, -12(%esp)=length (from AA or B), rINST=AA/BA
    */

    .if         $isrange
    lea         (rFP, %edx, 4), %ecx    # %ecx<- &fpp[CCCC]
1:
    movl        (%ecx), %edx            # %edx<- %ecx++
    lea         4(%ecx), %ecx           # %ecx++
    movl        %edx, (%eax)            # *contents<- vX
    lea         4(%eax), %eax           # %eax++; contents++
    subl        $$1, -12(%esp)          # length--
    jns         1b                      # or continue at 2
    .else
    cmp         $$4, -12(%esp)          # check length
    jne         1f                      # has four args
    and         $$15, rINST             # rINST<- A
    GET_VREG    rINST                   # rINST<- vA
    subl        $$1, -12(%esp)          # count--
    movl        rINST, 16(%eax)         # contents[4]<- vA
1:
    movl        %edx, %ecx              # %ecx<- %edx; ecx for temp
    andl        $$15, %ecx              # %ecx<- G/F/E/D
    GET_VREG    %ecx                    # %ecx<- vG/vF/vE/vD
    shr         $$4, %edx               # %edx<- put next reg in low 4
    subl        $$1, -12(%esp)          # count--
    movl        %ecx, (%eax)            # *contents<- vX
    lea         4(%eax), %eax           # %eax++; contents++
    jns         1b                      # or continue at 2
    .endif
2:
    cmpb        $$'I', sReg0            # check for int array
    je          3f
    movl        rGLUE, %ecx             # %ecx<- MterpGlue pointer
    movl        offGlue_retval(%ecx), %eax # Object head
    movl        offGlue_cardTable(%ecx), %ecx # card table base
    shrl        $$GC_CARD_SHIFT, %eax   # convert to card num
    movb        %cl,(%ecx, %eax)        # mark card based on object head
3:
    FINISH      3                       # jump to next instruction

   /*
    * Throw an exception to indicate this mode of filled-new-array
    * has not been implemented.
    */

.L${opcode}_notimpl:
    movl        $$.LstrInternalError, -8(%esp)
    movl        $$.LstrFilledNewArrayNotImpl, -4(%esp)
    lea         -8(%esp), %esp
    call        dvmThrowException # call: (const char* exceptionDescriptor,
                                  #        const char* msg)
                                  # return: void
    lea         8(%esp), %esp
    jmp         common_exceptionThrown

.if         (!$isrange)                 # define in one or the other, not both
.LstrFilledNewArrayNotImpl:
.asciz      "filled-new-array only implemented for 'int'"
.LstrInternalError:
.asciz  "Ljava/lang/InternalError;"
.endif
