Home | History | Annotate | Download | only in mips
      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]
     67 1:
     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
     83 1:
     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 
     94 2:
     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)
    103 3:
    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