Home | History | Annotate | Download | only in x86
      1 %default { "isrange":"0" }
      2 %verify "executed"
      3 %verify "unimplemented array type"
      4     /*
      5      * Create a new array with elements filled from registers.
      6      *
      7      * for: filled-new-array, filled-new-array/range
      8      */
      9     /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
     10     /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */
     11     GET_GLUE(%eax)
     12     movzbl  rINST_HI,rINST_FULL               # rINST_FULL<- AA or BA
     13     movl    offGlue_methodClassDex(%eax),%eax # eax<- pDvmDex
     14     movzwl  2(rPC),%ecx                       # ecx<- BBBB
     15     movl    offDvmDex_pResClasses(%eax),%eax  # eax<- pDvmDex->pResClasses
     16     SPILL(rPC)
     17     movl    (%eax,%ecx,4),%eax                # eax<- resolved class
     18     EXPORT_PC()
     19     testl   %eax,%eax                         # already resolved?
     20     jne     .L${opcode}_continue              # yes, continue
     21     # less frequent path, so we'll redo some work
     22     GET_GLUE(%eax)
     23     movl    $$0,OUT_ARG2(%esp)                # arg2<- false
     24     movl    %ecx,OUT_ARG1(%esp)               # arg1<- BBBB
     25     movl    offGlue_method(%eax),%eax         # eax<- glue->method
     26     jmp     .L${opcode}_more
     27 %break
     28 
     29 .L${opcode}_more:
     30     movl    offMethod_clazz(%eax),%eax        # eax<- method->clazz
     31     movl    %eax,OUT_ARG0(%esp)               # arg0<- clazz
     32     call    dvmResolveClass                   # eax<- call(clazz,ref,flag)
     33     UNSPILL(rPC)
     34     testl   %eax,%eax                         # null?
     35     je      common_exceptionThrown            # yes, handle it
     36 
     37        # note: fall through to .L${opcode}_continue
     38 
     39     /*
     40      * On entry:
     41      *    eax holds array class [r0]
     42      *    rINST_FULL holds AA or BB [r10]
     43      *    ecx is scratch
     44      *    rPC is valid, but has been spilled
     45      */
     46 .L${opcode}_continue:
     47     movl    offClassObject_descriptor(%eax),%ecx  # ecx<- arrayClass->descriptor
     48     movl    $$ALLOC_DONT_TRACK,OUT_ARG2(%esp)     # arg2<- flags
     49     movzbl  1(%ecx),%ecx                          # ecx<- descriptor[1]
     50     movl    %eax,OUT_ARG0(%esp)                   # arg0<- arrayClass
     51     GET_GLUE(%eax)
     52     cmpb    $$'I',%cl                             # supported?
     53     je      1f
     54     cmpb    $$'L',%cl
     55     je      1f
     56     cmpb    $$'[',%cl
     57     jne      .L${opcode}_notimpl                  # no, not handled yet
     58 1:
     59     movl    %ecx,offGlue_retval+4(%eax)           # save type
     60     .if      (!$isrange)
     61     SPILL_TMP(rINST_FULL)                         # save copy, need "B" later
     62     sarl    $$4,rINST_FULL
     63     .endif
     64     movl    rINST_FULL,OUT_ARG1(%esp)             # arg1<- A or AA (length)
     65     call    dvmAllocArrayByClass                  # eax<- call(arrayClass, length, flags)
     66     UNSPILL(rPC)
     67     GET_GLUE(%ecx)
     68     testl   %eax,%eax                             # alloc successful?
     69     je      common_exceptionThrown                # no, handle exception
     70     movl    %eax,offGlue_retval(%ecx)             # retval.l<- new array
     71     movzwl  4(rPC),%ecx                           # ecx<- FEDC or CCCC
     72     leal    offArrayObject_contents(%eax),%eax    # eax<- newArray->contents
     73 
     74 /* at this point:
     75  *     eax is pointer to tgt
     76  *     rINST_FULL is length
     77  *     ecx is FEDC or CCCC
     78  *     TMP_SPILL is BA
     79  *     rPC is valid, but spilled
     80  *  We now need to copy values from registers into the array
     81  */
     82 
     83     .if $isrange
     84     # set up src pointer
     85     SPILL(rFP)     # esi
     86     SPILL(rIBASE)   # edi
     87     movl    %eax,%edi         # set up dst ptr
     88     leal    (rFP,%ecx,4),%esi # set up src ptr
     89     movl    rINST_FULL,%ecx   # load count register
     90     FETCH_INST_WORD(3)
     91     rep
     92     movsd
     93     GET_GLUE(%ecx)
     94     UNSPILL(rIBASE)
     95     movl    offGlue_retval+4(%ecx),%eax      # eax<- type
     96     UNSPILL(rFP)
     97     .else
     98     testl  rINST_FULL,rINST_FULL
     99     je     4f
    100     UNSPILL_TMP(rPC)
    101     andl   $$0x0f,rPC            # rPC<- 0000000A
    102     sall   $$16,rPC              # rPC<- 000A0000
    103     orl    %ecx,rPC              # rpc<- 000AFEDC
    104 3:
    105     movl   $$0xf,%ecx
    106     andl   rPC,%ecx           # ecx<- next reg to load
    107     GET_VREG(%ecx,%ecx)
    108     shrl   $$4,rPC
    109     leal   4(%eax),%eax
    110     movl   %ecx,-4(%eax)
    111     sub    $$1,rINST_FULL
    112     jne    3b
    113 4:
    114     GET_GLUE(%ecx)
    115     UNSPILL(rPC)
    116     movl    offGlue_retval+4(%ecx),%eax      # eax<- type
    117     FETCH_INST_WORD(3)
    118     .endif
    119 
    120     cmpb    $$'I',%al                        # Int array?
    121     je      5f                               # skip card mark if so
    122     movl    offGlue_retval(%ecx),%eax        # eax<- object head
    123     movl    offGlue_cardTable(%ecx),%ecx     # card table base
    124     shrl    $$GC_CARD_SHIFT,%eax             # convert to card num
    125     movb    %cl,(%ecx,%eax)                  # mark card based on object head
    126 5:
    127     ADVANCE_PC(3)
    128     GOTO_NEXT
    129 
    130 
    131     /*
    132      * Throw an exception indicating that we have not implemented this
    133      * mode of filled-new-array.
    134      */
    135 .L${opcode}_notimpl:
    136     movl    $$.LstrInternalError,%eax
    137     movl    %eax,OUT_ARG0(%esp)
    138     movl    $$.LstrFilledNewArrayNotImpl,%eax
    139     movl    %eax,OUT_ARG1(%esp)
    140     call    dvmThrowException
    141     UNSPILL(rPC)
    142     jmp     common_exceptionThrown
    143