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