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 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 12 FETCH(r1, 1) @ r1<- BBBB 13 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 14 EXPORT_PC() @ need for resolve and alloc 15 ldr r0, [r3, r1, lsl #2] @ r0<- resolved class 16 mov r10, rINST, lsr #8 @ r10<- AA or BA 17 cmp r0, #0 @ already resolved? 18 bne .L${opcode}_continue @ yes, continue on 198: ldr r3, [rSELF, #offThread_method] @ r3<- self->method 20 mov r2, #0 @ r2<- false 21 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 22 bl dvmResolveClass @ r0<- call(clazz, ref) 23 cmp r0, #0 @ got null? 24 beq common_exceptionThrown @ yes, handle exception 25 b .L${opcode}_continue 26%break 27 28 /* 29 * On entry: 30 * r0 holds array class 31 * r10 holds AA or BA 32 */ 33.L${opcode}_continue: 34 ldr r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor 35 mov r2, #ALLOC_DONT_TRACK @ r2<- alloc flags 36 ldrb rINST, [r3, #1] @ rINST<- descriptor[1] 37 .if $isrange 38 mov r1, r10 @ r1<- AA (length) 39 .else 40 mov r1, r10, lsr #4 @ r1<- B (length) 41 .endif 42 cmp rINST, #'I' @ array of ints? 43 cmpne rINST, #'L' @ array of objects? 44 cmpne rINST, #'[' @ array of arrays? 45 mov r9, r1 @ save length in r9 46 bne .L${opcode}_notimpl @ no, not handled yet 47 bl dvmAllocArrayByClass @ r0<- call(arClass, length, flags) 48 cmp r0, #0 @ null return? 49 beq common_exceptionThrown @ alloc failed, handle exception 50 51 FETCH(r1, 2) @ r1<- FEDC or CCCC 52 str r0, [rSELF, #offThread_retval] @ retval.l <- new array 53 str rINST, [rSELF, #offThread_retval+4] @ retval.h <- type 54 add r0, r0, #offArrayObject_contents @ r0<- newArray->contents 55 subs r9, r9, #1 @ length--, check for neg 56 FETCH_ADVANCE_INST(3) @ advance to next instr, load rINST 57 bmi 2f @ was zero, bail 58 59 @ copy values from registers into the array 60 @ r0=array, r1=CCCC/FEDC, r9=length (from AA or B), r10=AA/BA 61 .if $isrange 62 add r2, rFP, r1, lsl #2 @ r2<- &fp[CCCC] 631: ldr r3, [r2], #4 @ r3<- *r2++ 64 subs r9, r9, #1 @ count-- 65 str r3, [r0], #4 @ *contents++ = vX 66 bpl 1b 67 @ continue at 2 68 .else 69 cmp r9, #4 @ length was initially 5? 70 and r2, r10, #15 @ r2<- A 71 bne 1f @ <= 4 args, branch 72 GET_VREG(r3, r2) @ r3<- vA 73 sub r9, r9, #1 @ count-- 74 str r3, [r0, #16] @ contents[4] = vA 751: and r2, r1, #15 @ r2<- F/E/D/C 76 GET_VREG(r3, r2) @ r3<- vF/vE/vD/vC 77 mov r1, r1, lsr #4 @ r1<- next reg in low 4 78 subs r9, r9, #1 @ count-- 79 str r3, [r0], #4 @ *contents++ = vX 80 bpl 1b 81 @ continue at 2 82 .endif 83 842: 85 ldr r0, [rSELF, #offThread_retval] @ r0<- object 86 ldr r1, [rSELF, #offThread_retval+4] @ r1<- type 87 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 88 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 89 cmp r1, #'I' @ Is int array? 90 strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head 91 GOTO_OPCODE(ip) @ execute it 92 93 /* 94 * Throw an exception indicating that we have not implemented this 95 * mode of filled-new-array. 96 */ 97.L${opcode}_notimpl: 98 ldr r0, .L_strFilledNewArrayNotImpl_${opcode} 99 bl dvmThrowInternalError 100 b common_exceptionThrown 101 102 /* 103 * Ideally we'd only define this once, but depending on layout we can 104 * exceed the range of the load above. 105 */ 106 107.L_strFilledNewArrayNotImpl_${opcode}: 108 .word .LstrFilledNewArrayNotImpl 109