blob: f804f3ed812ffd85f3299d5e424d40d8cb9b772b [file] [log] [blame]
/* Copyright (C) 2008 The Android Open Source Project
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* See the License for the specific language governing permissions and
* limitations under the License.
* Code: Constructs and fills an array with the given data. Provides
* For: float-to-int
* Description: Construct an array of the given type and size,
* filling it with the supplied contents. The type
* must be an array type. The array's contents
* must be single-word. The constructed instance
* is stored as a result in the same way that the
* method invocation instructions store their results,
* so the constructed instance must be moved to a
* register with a subsequent move-result-object
* instruction.
* Format: B|A|op CCCC G|F|E|D (35c)
* AA|op BBBB CCCC (3rc) (range)
* Syntax: [B=5] op {vD, vE, vF, vG, vA}, vtaboff@CCCC
* [B=4] op {vD, vE, vF, vG}, vtaboff@CCCC
* [B=3] op {vD, vE, vF}, vtaboff@CCCC
* [B=2] op {vD, vE}, vtaboff@CCCC
* [B=1] op {vD}, vtaboff@CCCC
* op {vCCCC .. vNNNN}, meth@BBBB
* op {vCCCC .. vNNNN}, type@BBBB
%default { "isrange":"0" }
movl rGLUE, %edx # %edx<- MterpGlue pointer
movl offGlue_methodClassDex(%edx), %edx # %edx<- glue->methodClassDex
movl offDvmDex_pResClasses(%edx), %edx # %edx<- glue->methodClassDex->pResClasses
FETCH 1, %ecx # %ecx<- BBBB
movl (%edx, %ecx, 4), %eax # %eax<- possibly resolved class
cmp $$0, %eax # %eax<- check if already resolved
jne .L${opcode}_continue
jmp .L${opcode}_break
movl $$0, -8(%esp) # push parameter false
movl %ecx, -12(%esp) # push parameter BBBB
movl rGLUE, %edx # %edx<- MterpGlue pointer
movl offGlue_method(%edx), %edx # %edx<- glue->method
movl offMethod_clazz(%edx), %edx # %edx<- glue->method->clazz
movl %edx, -16(%esp) # push parameter glue->method->clazz
lea -16(%esp), %esp
call dvmResolveClass # call: (const ClassObject* referrer, u4 classIdx,
# bool fromUnverifiedConstant)
# return: ClassObject*
lea 16(%esp), %esp
cmp $$0, %eax # check for null return
je common_exceptionThrown # handle exception
* On entry:
* %eax holds array class
* rINST holds BA or AA
movl offClassObject_descriptor(%eax), %eax # %eax<- arrayClass->descriptor
movzbl 1(%eax), %eax # %eax<- descriptor[1]
cmpb $$'I', %al # check if array of ints
je 1f
cmpb $$'L', %al
je 1f
cmpb $$'[', %al
jne .L${opcode}_notimpl # jump to not implemented
movl %eax, sReg0 # save type
movl rINST, -12(%esp) # push parameter length
movl %eax, -16(%esp) # push parameter descriptor[1]
movl $$ALLOC_DONT_TRACK, -8(%esp) # push parameter to allocate flags
.if (!$isrange)
shrl $$4, -12(%esp) # parameter length is B
lea -16(%esp), %esp
call dvmAllocPrimitiveArray # call: (char type, size_t length, int allocFlags)
# return: ArrayObject*
lea 16(%esp), %esp
cmp $$0, %eax # check for null return
je common_exceptionThrown # handle exception
FETCH 2, %edx # %edx<- FEDC or CCCC
movl rGLUE, %ecx # %ecx<- MterpGlue pointer
movl %eax, offGlue_retval(%ecx) # retval<- new array
lea offArrayObject_contents(%eax), %eax # %eax<- newArray->contents
subl $$1, -12(%esp) # length--; check for negative
js 2f # if length was zero, finish
* copy values from registers into the array
* %eax=array, %edx=CCCC/FEDC, -12(%esp)=length (from AA or B), rINST=AA/BA
.if $isrange
lea (rFP, %edx, 4), %ecx # %ecx<- &fpp[CCCC]
movl (%ecx), %edx # %edx<- %ecx++
lea 4(%ecx), %ecx # %ecx++
movl %edx, (%eax) # *contents<- vX
lea 4(%eax), %eax # %eax++; contents++
subl $$1, -12(%esp) # length--
jns 1b # or continue at 2
cmp $$4, -12(%esp) # check length
jne 1f # has four args
and $$15, rINST # rINST<- A
subl $$1, -12(%esp) # count--
movl rINST, 16(%eax) # contents[4]<- vA
movl %edx, %ecx # %ecx<- %edx; ecx for temp
andl $$15, %ecx # %ecx<- G/F/E/D
GET_VREG %ecx # %ecx<- vG/vF/vE/vD
shr $$4, %edx # %edx<- put next reg in low 4
subl $$1, -12(%esp) # count--
movl %ecx, (%eax) # *contents<- vX
lea 4(%eax), %eax # %eax++; contents++
jns 1b # or continue at 2
cmpb $$'I', sReg0 # check for int array
je 3f
movl rGLUE, %ecx # %ecx<- MterpGlue pointer
movl offGlue_retval(%ecx), %eax # Object head
movl offGlue_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
FINISH 3 # jump to next instruction
* Throw an exception to indicate this mode of filled-new-array
* has not been implemented.
movl $$.LstrInternalError, -8(%esp)
movl $$.LstrFilledNewArrayNotImpl, -4(%esp)
lea -8(%esp), %esp
call dvmThrowException # call: (const char* exceptionDescriptor,
# const char* msg)
# return: void
lea 8(%esp), %esp
jmp common_exceptionThrown
.if (!$isrange) # define in one or the other, not both
.asciz "filled-new-array only implemented for 'int'"
.asciz "Ljava/lang/InternalError;"