blob: 91a26b8d550ec92ce7202d9e889906c9dcb1fb22 [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 */
movl rSELF,%eax
movl offThread_methodClassDex(%eax),%eax # eax<- pDvmDex
movzwl 2(rPC),%ecx # ecx<- BBBB
movl offDvmDex_pResClasses(%eax),%eax # eax<- pDvmDex->pResClasses
SPILL(rIBASE) # preserve rIBASE
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
movl rSELF,%eax
movl $$0,OUT_ARG2(%esp) # arg2<- false
movl %ecx,OUT_ARG1(%esp) # arg1<- BBBB
movl offThread_method(%eax),%eax # eax<- self->method
movl offMethod_clazz(%eax),%eax # eax<- method->clazz
movl %eax,OUT_ARG0(%esp) # arg0<- clazz
call dvmResolveClass # eax<- call(clazz,ref,flag)
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 holds AA or BB [r10]
* ecx is scratch
*/
.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
movl rSELF,%eax
cmpb $$'I',%cl # supported?
je 1f
cmpb $$'L',%cl
je 1f
cmpb $$'[',%cl
jne .L${opcode}_notimpl # no, not handled yet
1:
movl %ecx,offThread_retval+4(%eax) # save type
.if (!$isrange)
SPILL_TMP1(rINST) # save copy, need "B" later
sarl $$4,rINST
.endif
movl rINST,OUT_ARG1(%esp) # arg1<- A or AA (length)
call dvmAllocArrayByClass # eax<- call(arrayClass, length, flags)
movl rSELF,%ecx
testl %eax,%eax # alloc successful?
je common_exceptionThrown # no, handle exception
movl %eax,offThread_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 is length
* ecx is FEDC or CCCC
* TMP_SPILL1 is BA
* We now need to copy values from registers into the array
*/
.if $isrange
# set up src pointer
SPILL_TMP2(%esi)
SPILL_TMP3(%edi)
leal (rFP,%ecx,4),%esi # set up src ptr
movl %eax,%edi # set up dst ptr
movl rINST,%ecx # load count register
rep
movsd
UNSPILL_TMP2(%esi)
UNSPILL_TMP3(%edi)
movl rSELF,%ecx
movl offThread_retval+4(%ecx),%eax # eax<- type
.else
testl rINST,rINST
je 4f
UNSPILL_TMP1(rIBASE) # restore "BA"
andl $$0x0f,rIBASE # rIBASE<- 0000000A
sall $$16,rIBASE # rIBASE<- 000A0000
orl %ecx,rIBASE # rIBASE<- 000AFEDC
3:
movl $$0xf,%ecx
andl rIBASE,%ecx # ecx<- next reg to load
GET_VREG_R %ecx %ecx
shrl $$4,rIBASE
leal 4(%eax),%eax
movl %ecx,-4(%eax)
sub $$1,rINST
jne 3b
4:
movl rSELF,%ecx
movl offThread_retval+4(%ecx),%eax # eax<- type
.endif
cmpb $$'I',%al # Int array?
je 5f # skip card mark if so
movl offThread_retval(%ecx),%eax # eax<- object head
movl offThread_cardTable(%ecx),%ecx # card table base
shrl $$GC_CARD_SHIFT,%eax # convert to card num
movb %cl,(%ecx,%eax) # mark card based on object head
5:
UNSPILL(rIBASE) # restore rIBASE
FETCH_INST_OPCODE 3 %ecx
ADVANCE_PC 3
GOTO_NEXT_R %ecx
/*
* Throw an exception indicating that we have not implemented this
* mode of filled-new-array.
*/
.L${opcode}_notimpl:
movl $$.LstrInternalErrorA,%eax
movl %eax,OUT_ARG0(%esp)
movl $$.LstrFilledNewArrayNotImplA,%eax
movl %eax,OUT_ARG1(%esp)
call dvmThrowException
jmp common_exceptionThrown