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 cmp $$'I', %eax # check if array of ints 84 jne .L${opcode}_notimpl # jump to not implemented 85 movl rINST, -12(%esp) # push parameter length 86 movl %eax, -16(%esp) # push parameter descriptor[1] 87 movl $$ALLOC_DONT_TRACK, -8(%esp) # push parameter to allocate flags 88 .if (!$isrange) 89 shrl $$4, -12(%esp) # parameter length is B 90 .endif 91 lea -16(%esp), %esp 92 call dvmAllocPrimitiveArray # call: (char type, size_t length, int allocFlags) 93 # return: ArrayObject* 94 lea 16(%esp), %esp 95 cmp $$0, %eax # check for null return 96 je common_exceptionThrown # handle exception 97 98 FETCH 2, %edx # %edx<- FEDC or CCCC 99 movl rGLUE, %ecx # %ecx<- MterpGlue pointer 100 movl %eax, offGlue_retval(%ecx) # retval<- new array 101 lea offArrayObject_contents(%eax), %eax # %eax<- newArray->contents 102 subl $$1, -12(%esp) # length--; check for negative 103 js 2f # if length was zero, finish 104 105 /* 106 * copy values from registers into the array 107 * %eax=array, %edx=CCCC/FEDC, -12(%esp)=length (from AA or B), rINST=AA/BA 108 */ 109 110 .if $isrange 111 lea (rFP, %edx, 4), %ecx # %ecx<- &fpp[CCCC] 112 1: 113 movl (%ecx), %edx # %edx<- %ecx++ 114 lea 4(%ecx), %ecx # %ecx++ 115 movl %edx, (%eax) # *contents<- vX 116 lea 4(%eax), %eax # %eax++; contents++ 117 subl $$1, -12(%esp) # length-- 118 jns 1b # or continue at 2 119 .else 120 cmp $$4, -12(%esp) # check length 121 jne 1f # has four args 122 and $$15, rINST # rINST<- A 123 GET_VREG rINST # rINST<- vA 124 subl $$1, -12(%esp) # count-- 125 movl rINST, 16(%eax) # contents[4]<- vA 126 1: 127 movl %edx, %ecx # %ecx<- %edx; ecx for temp 128 andl $$15, %ecx # %ecx<- G/F/E/D 129 GET_VREG %ecx # %ecx<- vG/vF/vE/vD 130 shr $$4, %edx # %edx<- put next reg in low 4 131 subl $$1, -12(%esp) # count-- 132 movl %ecx, (%eax) # *contents<- vX 133 lea 4(%eax), %eax # %eax++; contents++ 134 jns 1b # or continue at 2 135 .endif 136 2: 137 FINISH 3 # jump to next instruction 138 139 /* 140 * Throw an exception to indicate this mode of filled-new-array 141 * has not been implemented. 142 */ 143 144 .L${opcode}_notimpl: 145 movl $$.LstrInternalError, -8(%esp) 146 movl $$.LstrFilledNewArrayNotImpl, -4(%esp) 147 lea -8(%esp), %esp 148 call dvmThrowException # call: (const char* exceptionDescriptor, 149 # const char* msg) 150 # return: void 151 lea 8(%esp), %esp 152 jmp common_exceptionThrown 153 154 .if (!$isrange) # define in one or the other, not both 155 .LstrFilledNewArrayNotImpl: 156 .asciz "filled-new-array only implemented for 'int'" 157 .LstrInternalError: 158 .asciz "Ljava/lang/InternalError;" 159 .endif 160