• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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    LOAD_rSELF_methodClassDex(a3)          #  a3 <- pDvmDex
12    FETCH(a1, 1)                           #  a1 <- BBBB
13    LOAD_base_offDvmDex_pResClasses(a3, a3) #  a3 <- pDvmDex->pResClasses
14    EXPORT_PC()                            #  need for resolve and alloc
15    LOAD_eas2(a0, a3, a1)                  #  a0 <- resolved class
16    GET_OPA(rOBJ)                          #  rOBJ <- AA or BA
17    # already resolved?
18    bnez      a0, .L${opcode}_continue     #  yes, continue on
19    LOAD_rSELF_method(a3)                  #  a3 <- self->method
20    li        a2, 0                        #  a2 <- false
21    LOAD_base_offMethod_clazz(a0, a3)      #  a0 <- method->clazz
22    JAL(dvmResolveClass)                   #  v0 <- call(clazz, ref)
23    move      a0, v0
24    # got null?
25    beqz      v0, common_exceptionThrown   #  yes, handle exception
26    b         .L${opcode}_continue
27%break
28
29    /*
30     * On entry:
31     *  a0 holds array class
32     *  rOBJ holds AA or BA
33     */
34.L${opcode}_continue:
35    LOAD_base_offClassObject_descriptor(a3, a0) #  a3 <- arrayClass->descriptor
36    li        a2, ALLOC_DONT_TRACK         #  a2 <- alloc flags
37    lbu       rINST, 1(a3)                 #  rINST <- descriptor[1]
38    .if $isrange
39    move      a1, rOBJ                     #  a1 <- AA (length)
40    .else
41    srl       a1, rOBJ, 4                  #  rOBJ <- B (length)
42    .endif
43    seq       t0, rINST, 'I'               #  array of ints?
44    seq       t1, rINST, 'L'               #  array of objects?
45    or        t0, t1
46    seq       t1, rINST, '['               #  array of arrays?
47    or        t0, t1
48    move      rBIX, a1                     #  save length in rBIX
49    beqz      t0, .L${opcode}_notimpl      #  no, not handled yet
50    JAL(dvmAllocArrayByClass)              #  v0 <- call(arClass, length, flags)
51    # null return?
52    beqz      v0, common_exceptionThrown   #  alloc failed, handle exception
53
54    FETCH(a1, 2)                           #  a1 <- FEDC or CCCC
55    sw        v0, offThread_retval(rSELF)  #  retval.l <- new array
56    sw        rINST, (offThread_retval+4)(rSELF) #  retval.h <- type
57    addu      a0, v0, offArrayObject_contents #  a0 <- newArray->contents
58    subu      rBIX, rBIX, 1                #  length--, check for neg
59    FETCH_ADVANCE_INST(3)                  #  advance to next instr, load rINST
60    bltz      rBIX, 2f                     #  was zero, bail
61
62    # copy values from registers into the array
63    # a0=array, a1=CCCC/FEDC, t0=length (from AA or B), rOBJ=AA/BA
64    move      t0, rBIX
65    .if $isrange
66    EAS2(a2, rFP, a1)                      #  a2 <- &fp[CCCC]
671:
68    lw        a3, 0(a2)                    #  a3 <- *a2++
69    addu      a2, 4
70    subu      t0, t0, 1                    #  count--
71    sw        a3, (a0)                     #  *contents++ = vX
72    addu      a0, 4
73    bgez      t0, 1b
74
75    # continue at 2
76    .else
77    slt       t1, t0, 4                    #  length was initially 5?
78    and       a2, rOBJ, 15                 #  a2 <- A
79    bnez      t1, 1f                       #  <= 4 args, branch
80    GET_VREG(a3, a2)                       #  a3 <- vA
81    subu      t0, t0, 1                    #  count--
82    sw        a3, 16(a0)                   #  contents[4] = vA
831:
84    and       a2, a1, 15                   #  a2 <- F/E/D/C
85    GET_VREG(a3, a2)                       #  a3 <- vF/vE/vD/vC
86    srl       a1, a1, 4                    #  a1 <- next reg in low 4
87    subu      t0, t0, 1                    #  count--
88    sw        a3, 0(a0)                    #  *contents++ = vX
89    addu      a0, a0, 4
90    bgez      t0, 1b
91    # continue at 2
92    .endif
93
942:
95    lw        a0, offThread_retval(rSELF)  #  a0 <- object
96    lw        a1, (offThread_retval+4)(rSELF) #  a1 <- type
97    seq       t1, a1, 'I'                  #  Is int array?
98    bnez      t1, 3f
99    lw        a2, offThread_cardTable(rSELF) #  a2 <- card table base
100    srl       t3, a0, GC_CARD_SHIFT
101    addu      t2, a2, t3
102    sb        a2, (t2)
1033:
104    GET_INST_OPCODE(t0)                    #  ip <- opcode from rINST
105    GOTO_OPCODE(t0)                        #  execute it
106
107
108    /*
109     * Throw an exception indicating that we have not implemented this
110     * mode of filled-new-array.
111     */
112.L${opcode}_notimpl:
113    la        a0, .LstrFilledNewArrayNotImpl
114    JAL(dvmThrowInternalError)
115    b         common_exceptionThrown
116
117    /*
118     * Ideally we'd only define this once, but depending on layout we can
119     * exceed the range of the load above.
120     */
121