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     movl    rSELF,%eax
     12     movl    offThread_methodClassDex(%eax),%eax # eax<- pDvmDex
     13     movzwl  2(rPC),%ecx                       # ecx<- BBBB
     14     movl    offDvmDex_pResClasses(%eax),%eax  # eax<- pDvmDex->pResClasses
     15     SPILL(rIBASE)                             # preserve rIBASE
     16     movl    (%eax,%ecx,4),%eax                # eax<- resolved class
     17     EXPORT_PC
     18     testl   %eax,%eax                         # already resolved?
     19     jne     .L${opcode}_continue              # yes, continue
     20     # less frequent path, so we'll redo some work
     21     movl    rSELF,%eax
     22     movl    $$0,OUT_ARG2(%esp)                # arg2<- false
     23     movl    %ecx,OUT_ARG1(%esp)               # arg1<- BBBB
     24     movl    offThread_method(%eax),%eax         # eax<- self->method
     25     movl    offMethod_clazz(%eax),%eax        # eax<- method->clazz
     26     movl    %eax,OUT_ARG0(%esp)               # arg0<- clazz
     27     call    dvmResolveClass                   # eax<- call(clazz,ref,flag)
     28     testl   %eax,%eax                         # null?
     29     je      common_exceptionThrown            # yes, handle it
     30 
     31        # note: fall through to .L${opcode}_continue
     32 
     33     /*
     34      * On entry:
     35      *    eax holds array class [r0]
     36      *    rINST holds AA or BB [r10]
     37      *    ecx is scratch
     38      */
     39 .L${opcode}_continue:
     40     movl    offClassObject_descriptor(%eax),%ecx  # ecx<- arrayClass->descriptor
     41     movl    $$ALLOC_DONT_TRACK,OUT_ARG2(%esp)     # arg2<- flags
     42     movzbl  1(%ecx),%ecx                          # ecx<- descriptor[1]
     43     movl    %eax,OUT_ARG0(%esp)                   # arg0<- arrayClass
     44     movl    rSELF,%eax
     45     cmpb    $$'I',%cl                             # supported?
     46     je      1f
     47     cmpb    $$'L',%cl
     48     je      1f
     49     cmpb    $$'[',%cl
     50     jne      .L${opcode}_notimpl                  # no, not handled yet
     51 1:
     52     movl    %ecx,offThread_retval+4(%eax)           # save type
     53     .if      (!$isrange)
     54     SPILL_TMP1(rINST)                              # save copy, need "B" later
     55     sarl    $$4,rINST
     56     .endif
     57     movl    rINST,OUT_ARG1(%esp)                  # arg1<- A or AA (length)
     58     call    dvmAllocArrayByClass     # eax<- call(arrayClass, length, flags)
     59     movl    rSELF,%ecx
     60     testl   %eax,%eax                             # alloc successful?
     61     je      common_exceptionThrown                # no, handle exception
     62     movl    %eax,offThread_retval(%ecx)             # retval.l<- new array
     63     movzwl  4(rPC),%ecx                           # ecx<- FEDC or CCCC
     64     leal    offArrayObject_contents(%eax),%eax    # eax<- newArray->contents
     65 
     66 /* at this point:
     67  *     eax is pointer to tgt
     68  *     rINST is length
     69  *     ecx is FEDC or CCCC
     70  *     TMP_SPILL1 is BA
     71  *  We now need to copy values from registers into the array
     72  */
     73 
     74     .if $isrange
     75     # set up src pointer
     76     SPILL_TMP2(%esi)
     77     SPILL_TMP3(%edi)
     78     leal    (rFP,%ecx,4),%esi # set up src ptr
     79     movl    %eax,%edi         # set up dst ptr
     80     movl    rINST,%ecx        # load count register
     81     rep
     82     movsd
     83     UNSPILL_TMP2(%esi)
     84     UNSPILL_TMP3(%edi)
     85     movl    rSELF,%ecx
     86     movl    offThread_retval+4(%ecx),%eax      # eax<- type
     87     .else
     88     testl  rINST,rINST
     89     je     4f
     90     UNSPILL_TMP1(rIBASE)      # restore "BA"
     91     andl   $$0x0f,rIBASE      # rIBASE<- 0000000A
     92     sall   $$16,rIBASE        # rIBASE<- 000A0000
     93     orl    %ecx,rIBASE        # rIBASE<- 000AFEDC
     94 3:
     95     movl   $$0xf,%ecx
     96     andl   rIBASE,%ecx        # ecx<- next reg to load
     97     GET_VREG_R %ecx %ecx
     98     shrl   $$4,rIBASE
     99     leal   4(%eax),%eax
    100     movl   %ecx,-4(%eax)
    101     sub    $$1,rINST
    102     jne    3b
    103 4:
    104     movl   rSELF,%ecx
    105     movl    offThread_retval+4(%ecx),%eax      # eax<- type
    106     .endif
    107 
    108     cmpb    $$'I',%al                        # Int array?
    109     je      5f                               # skip card mark if so
    110     movl    offThread_retval(%ecx),%eax        # eax<- object head
    111     movl    offThread_cardTable(%ecx),%ecx     # card table base
    112     shrl    $$GC_CARD_SHIFT,%eax             # convert to card num
    113     movb    %cl,(%ecx,%eax)                  # mark card based on object head
    114 5:
    115     UNSPILL(rIBASE)                          # restore rIBASE
    116     FETCH_INST_OPCODE 3 %ecx
    117     ADVANCE_PC 3
    118     GOTO_NEXT_R %ecx
    119 
    120 
    121     /*
    122      * Throw an exception indicating that we have not implemented this
    123      * mode of filled-new-array.
    124      */
    125 .L${opcode}_notimpl:
    126     movl    $$.LstrFilledNewArrayNotImplA,%eax
    127     movl    %eax,OUT_ARG0(%esp)
    128     call    dvmThrowInternalError
    129     jmp     common_exceptionThrown
    130