blob: aa247a83dc0279b3363d2314fa25e0ec31a12801 [file] [log] [blame]
%default { "isrange":"0" }
%verify "executed"
%verify "unimplemented array type"
/*
* Create a new array with elements filled from registers.
*
* for: filled-new-array, filled-new-array/range
*/
/* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
/* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */
GET_GLUE(%eax)
movzbl rINST_HI,rINST_FULL # rINST_FULL<- AA or BA
movl offGlue_methodClassDex(%eax),%eax # eax<- pDvmDex
movzwl 2(rPC),%ecx # ecx<- BBBB
movl offDvmDex_pResClasses(%eax),%eax # eax<- pDvmDex->pResClasses
SPILL(rPC)
movl (%eax,%ecx,4),%eax # eax<- resolved class
EXPORT_PC()
testl %eax,%eax # already resolved?
jne .L${opcode}_continue # yes, continue
# less frequent path, so we'll redo some work
GET_GLUE(%eax)
movl $$0,OUT_ARG2(%esp) # arg2<- false
movl %ecx,OUT_ARG1(%esp) # arg1<- BBBB
movl offGlue_method(%eax),%eax # eax<- glue->method
jmp .L${opcode}_more
%break
.L${opcode}_more:
movl offMethod_clazz(%eax),%eax # eax<- method->clazz
movl %eax,OUT_ARG0(%esp) # arg0<- clazz
call dvmResolveClass # eax<- call(clazz,ref,flag)
UNSPILL(rPC)
testl %eax,%eax # null?
je common_exceptionThrown # yes, handle it
# note: fall through to .L${opcode}_continue
/*
* On entry:
* eax holds array class [r0]
* rINST_FULL holds AA or BB [r10]
* ecx is scratch
* rPC is valid, but has been spilled
*/
.L${opcode}_continue:
movl offClassObject_descriptor(%eax),%ecx # ecx<- arrayClass->descriptor
movl $$ALLOC_DONT_TRACK,OUT_ARG2(%esp) # arg2<- flags
movzbl 1(%ecx),%ecx # ecx<- descriptor[1]
movl %eax,OUT_ARG0(%esp) # arg0<- arrayClass
cmpb $$'I',%cl # supported?
je 1f
cmpb $$'L',%cl
je 1f
cmpb $$'[',%cl
jne .L${opcode}_notimpl # no, not handled yet
1:
.if (!$isrange)
SPILL_TMP(rINST_FULL) # save copy, need "B" later
sarl $$4,rINST_FULL
.endif
movl rINST_FULL,OUT_ARG1(%esp) # arg1<- A or AA (length)
call dvmAllocArrayByClass # eax<- call(arrayClass, length, flags)
UNSPILL(rPC)
GET_GLUE(%ecx)
testl %eax,%eax # alloc successful?
je common_exceptionThrown # no, handle exception
movl %eax,offGlue_retval(%ecx) # retval.l<- new array
movzwl 4(rPC),%ecx # ecx<- FEDC or CCCC
leal offArrayObject_contents(%eax),%eax # eax<- newArray->contents
/* at this point:
* eax is pointer to tgt
* rINST_FULL is length
* ecx is FEDC or CCCC
* TMP_SPILL is BA
* rPC is valid, but spilled
* We now need to copy values from registers into the array
*/
.if $isrange
# set up src pointer
SPILL(rFP) # esi
SPILL(rIBASE) # edi
movl %eax,%edi # set up dst ptr
leal (rFP,%ecx,4),%esi # set up src ptr
movl rINST_FULL,%ecx # load count register
FETCH_INST_WORD(3)
rep
movsd
UNSPILL(rIBASE)
UNSPILL(rFP)
.else
testl rINST_FULL,rINST_FULL
je 4f
UNSPILL_TMP(rPC)
andl $$0x0f,rPC # rPC<- 0000000A
sall $$16,rPC # rPC<- 000A0000
orl %ecx,rPC # rpc<- 000AFEDC
3:
movl $$0xf,%ecx
andl rPC,%ecx # ecx<- next reg to load
GET_VREG(%ecx,%ecx)
shrl $$4,rPC
leal 4(%eax),%eax
movl %ecx,-4(%eax)
sub $$1,rINST_FULL
jne 3b
4:
UNSPILL(rPC)
FETCH_INST_WORD(3)
.endif
ADVANCE_PC(3)
GOTO_NEXT
/*
* Throw an exception indicating that we have not implemented this
* mode of filled-new-array.
*/
.L${opcode}_notimpl:
movl $$.LstrInternalError,%eax
movl %eax,OUT_ARG0(%esp)
movl $$.LstrFilledNewArrayNotImpl,%eax
movl %eax,OUT_ARG1(%esp)
call dvmThrowException
UNSPILL(rPC)
jmp common_exceptionThrown