1 /* Copyright (C) 2008 The Android Open Source Project 2 * 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 /* 17 * File: OP_FILLED_NEW_ARRAY.S 18 * 19 * Code: Constructs and fills an array with the given data. Provides 20 * 21 * For: float-to-int 22 * 23 * Description: Construct an array of the given type and size, 24 * filling it with the supplied contents. The type 25 * must be an array type. The array's contents 26 * must be single-word. The constructed instance 27 * is stored as a result in the same way that the 28 * method invocation instructions store their results, 29 * so the constructed instance must be moved to a 30 * register with a subsequent move-result-object 31 * instruction. 32 * 33 * Format: B|A|op CCCC G|F|E|D (35c) 34 * AA|op BBBB CCCC (3rc) (range) 35 * 36 * Syntax: [B=5] op {vD, vE, vF, vG, vA}, vtaboff@CCCC 37 * [B=4] op {vD, vE, vF, vG}, vtaboff@CCCC 38 * [B=3] op {vD, vE, vF}, vtaboff@CCCC 39 * [B=2] op {vD, vE}, vtaboff@CCCC 40 * [B=1] op {vD}, vtaboff@CCCC 41 * 42 * op {vCCCC .. vNNNN}, meth@BBBB 43 * op {vCCCC .. vNNNN}, type@BBBB 44 */ 45 46%default { "isrange":"0" } 47 48 movl rGLUE, %edx # %edx<- MterpGlue pointer 49 movl offGlue_methodClassDex(%edx), %edx # %edx<- glue->methodClassDex 50 movl offDvmDex_pResClasses(%edx), %edx # %edx<- glue->methodClassDex->pResClasses 51 FETCH 1, %ecx # %ecx<- BBBB 52 EXPORT_PC 53 movl (%edx, %ecx, 4), %eax # %eax<- possibly resolved class 54 cmp $$0, %eax # %eax<- check if already resolved 55 jne .L${opcode}_continue 56 jmp .L${opcode}_break 57%break 58 59.L${opcode}_break: 60 movl $$0, -8(%esp) # push parameter false 61 movl %ecx, -12(%esp) # push parameter BBBB 62 movl rGLUE, %edx # %edx<- MterpGlue pointer 63 movl offGlue_method(%edx), %edx # %edx<- glue->method 64 movl offMethod_clazz(%edx), %edx # %edx<- glue->method->clazz 65 movl %edx, -16(%esp) # push parameter glue->method->clazz 66 lea -16(%esp), %esp 67 call dvmResolveClass # call: (const ClassObject* referrer, u4 classIdx, 68 # bool fromUnverifiedConstant) 69 # return: ClassObject* 70 lea 16(%esp), %esp 71 cmp $$0, %eax # check for null return 72 je common_exceptionThrown # handle exception 73 74 /* 75 * On entry: 76 * %eax holds array class 77 * rINST holds BA or AA 78 */ 79 80.L${opcode}_continue: 81 movl offClassObject_descriptor(%eax), %eax # %eax<- arrayClass->descriptor 82 movzbl 1(%eax), %eax # %eax<- descriptor[1] 83 cmpb $$'I', %al # check if array of ints 84 je 1f 85 cmpb $$'L', %al 86 je 1f 87 cmpb $$'[', %al 88 jne .L${opcode}_notimpl # jump to not implemented 891: 90 movl %eax, sReg0 # save type 91 movl rINST, -12(%esp) # push parameter length 92 movl %eax, -16(%esp) # push parameter descriptor[1] 93 movl $$ALLOC_DONT_TRACK, -8(%esp) # push parameter to allocate flags 94 .if (!$isrange) 95 shrl $$4, -12(%esp) # parameter length is B 96 .endif 97 lea -16(%esp), %esp 98 call dvmAllocPrimitiveArray # call: (char type, size_t length, int allocFlags) 99 # return: ArrayObject* 100 lea 16(%esp), %esp 101 cmp $$0, %eax # check for null return 102 je common_exceptionThrown # handle exception 103 104 FETCH 2, %edx # %edx<- FEDC or CCCC 105 movl rGLUE, %ecx # %ecx<- MterpGlue pointer 106 movl %eax, offGlue_retval(%ecx) # retval<- new array 107 lea offArrayObject_contents(%eax), %eax # %eax<- newArray->contents 108 subl $$1, -12(%esp) # length--; check for negative 109 js 2f # if length was zero, finish 110 111 /* 112 * copy values from registers into the array 113 * %eax=array, %edx=CCCC/FEDC, -12(%esp)=length (from AA or B), rINST=AA/BA 114 */ 115 116 .if $isrange 117 lea (rFP, %edx, 4), %ecx # %ecx<- &fpp[CCCC] 1181: 119 movl (%ecx), %edx # %edx<- %ecx++ 120 lea 4(%ecx), %ecx # %ecx++ 121 movl %edx, (%eax) # *contents<- vX 122 lea 4(%eax), %eax # %eax++; contents++ 123 subl $$1, -12(%esp) # length-- 124 jns 1b # or continue at 2 125 .else 126 cmp $$4, -12(%esp) # check length 127 jne 1f # has four args 128 and $$15, rINST # rINST<- A 129 GET_VREG rINST # rINST<- vA 130 subl $$1, -12(%esp) # count-- 131 movl rINST, 16(%eax) # contents[4]<- vA 1321: 133 movl %edx, %ecx # %ecx<- %edx; ecx for temp 134 andl $$15, %ecx # %ecx<- G/F/E/D 135 GET_VREG %ecx # %ecx<- vG/vF/vE/vD 136 shr $$4, %edx # %edx<- put next reg in low 4 137 subl $$1, -12(%esp) # count-- 138 movl %ecx, (%eax) # *contents<- vX 139 lea 4(%eax), %eax # %eax++; contents++ 140 jns 1b # or continue at 2 141 .endif 1422: 143 cmpb $$'I', sReg0 # check for int array 144 je 3f 145 movl rGLUE, %ecx # %ecx<- MterpGlue pointer 146 movl offGlue_retval(%ecx), %eax # Object head 147 movl offGlue_cardTable(%ecx), %ecx # card table base 148 shrl $$GC_CARD_SHIFT, %eax # convert to card num 149 movb %cl,(%ecx, %eax) # mark card based on object head 1503: 151 FINISH 3 # jump to next instruction 152 153 /* 154 * Throw an exception to indicate this mode of filled-new-array 155 * has not been implemented. 156 */ 157 158.L${opcode}_notimpl: 159 movl $$.LstrInternalError, -8(%esp) 160 movl $$.LstrFilledNewArrayNotImpl, -4(%esp) 161 lea -8(%esp), %esp 162 call dvmThrowException # call: (const char* exceptionDescriptor, 163 # const char* msg) 164 # return: void 165 lea 8(%esp), %esp 166 jmp common_exceptionThrown 167 168.if (!$isrange) # define in one or the other, not both 169.LstrFilledNewArrayNotImpl: 170.asciz "filled-new-array only implemented for 'int'" 171.LstrInternalError: 172.asciz "Ljava/lang/InternalError;" 173.endif 174