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    cmpb    $$'I',%cl                             # supported?
52    je      1f
53    cmpb    $$'L',%cl
54    je      1f
55    cmpb    $$'[',%cl
56    jne      .L${opcode}_notimpl                  # no, not handled yet
571:
58    .if      (!$isrange)
59    SPILL_TMP(rINST_FULL)                         # save copy, need "B" later
60    sarl    $$4,rINST_FULL
61    .endif
62    movl    rINST_FULL,OUT_ARG1(%esp)             # arg1<- A or AA (length)
63    call    dvmAllocArrayByClass                  # eax<- call(arrayClass, length, flags)
64    UNSPILL(rPC)
65    GET_GLUE(%ecx)
66    testl   %eax,%eax                             # alloc successful?
67    je      common_exceptionThrown                # no, handle exception
68    movl    %eax,offGlue_retval(%ecx)             # retval.l<- new array
69    movzwl  4(rPC),%ecx                           # ecx<- FEDC or CCCC
70    leal    offArrayObject_contents(%eax),%eax    # eax<- newArray->contents
71
72/* at this point:
73 *     eax is pointer to tgt
74 *     rINST_FULL is length
75 *     ecx is FEDC or CCCC
76 *     TMP_SPILL is BA
77 *     rPC is valid, but spilled
78 *  We now need to copy values from registers into the array
79 */
80
81    .if $isrange
82    # set up src pointer
83    SPILL(rFP)     # esi
84    SPILL(rIBASE)   # edi
85    movl    %eax,%edi         # set up dst ptr
86    leal    (rFP,%ecx,4),%esi # set up src ptr
87    movl    rINST_FULL,%ecx   # load count register
88    FETCH_INST_WORD(3)
89    rep
90    movsd
91    UNSPILL(rIBASE)
92    UNSPILL(rFP)
93    .else
94    testl  rINST_FULL,rINST_FULL
95    je     4f
96    UNSPILL_TMP(rPC)
97    andl   $$0x0f,rPC            # rPC<- 0000000A
98    sall   $$16,rPC              # rPC<- 000A0000
99    orl    %ecx,rPC              # rpc<- 000AFEDC
1003:
101    movl   $$0xf,%ecx
102    andl   rPC,%ecx           # ecx<- next reg to load
103    GET_VREG(%ecx,%ecx)
104    shrl   $$4,rPC
105    leal   4(%eax),%eax
106    movl   %ecx,-4(%eax)
107    sub    $$1,rINST_FULL
108    jne    3b
1094:
110    UNSPILL(rPC)
111    FETCH_INST_WORD(3)
112    .endif
113
114    ADVANCE_PC(3)
115    GOTO_NEXT
116
117
118    /*
119     * Throw an exception indicating that we have not implemented this
120     * mode of filled-new-array.
121     */
122.L${opcode}_notimpl:
123    movl    $$.LstrInternalError,%eax
124    movl    %eax,OUT_ARG0(%esp)
125    movl    $$.LstrFilledNewArrayNotImpl,%eax
126    movl    %eax,OUT_ARG1(%esp)
127    call    dvmThrowException
128    UNSPILL(rPC)
129    jmp     common_exceptionThrown
130
131