1%def op_aget(load="ldr", shift="2", data_offset="MIRROR_INT_ARRAY_DATA_OFFSET", wide="0", is_object="0"): 2/* 3 * Array get. vAA <- vBB[vCC]. 4 * 5 * for: aget, aget-boolean, aget-byte, aget-char, aget-short, aget-wide, aget-object 6 * 7 */ 8 FETCH_B w2, 1, 0 // w2<- BB 9 lsr w9, wINST, #8 // w9<- AA 10 FETCH_B w3, 1, 1 // w3<- CC 11 GET_VREG w0, w2 // w0<- vBB (array object) 12 GET_VREG w1, w3 // w1<- vCC (requested index) 13 cbz x0, common_errNullObject // bail if null array object. 14 ldr w3, [x0, #MIRROR_ARRAY_LENGTH_OFFSET] // w3<- arrayObj->length 15 add x0, x0, w1, uxtw #$shift // w0<- arrayObj + index*width 16 cmp w1, w3 // compare unsigned index, length 17 bcs common_errArrayIndex // index >= length, bail 18 FETCH_ADVANCE_INST 2 // advance rPC, load rINST 19 GET_INST_OPCODE x10 // extract opcode from wINST 20 .if $wide 21 ldr x2, [x0, #$data_offset] // x2<- vBB[vCC] 22 SET_VREG_WIDE x2, w9 23 GOTO_OPCODE x10 // jump to next instruction 24 .elseif $is_object 25 $load w2, [x0, #$data_offset] // w2<- vBB[vCC] 26 UNPOISON_HEAP_REF w2 27 TEST_IF_MARKING 2f 281: 29 SET_VREG_OBJECT w2, w9 // vAA<- w2 30 GOTO_OPCODE x10 // jump to next instruction 312: 32 bl art_quick_read_barrier_mark_reg02 33 b 1b 34 .else 35 $load w2, [x0, #$data_offset] // w2<- vBB[vCC] 36 SET_VREG w2, w9 // vAA<- w2 37 GOTO_OPCODE x10 // jump to next instruction 38 .endif 39 40%def op_aget_boolean(): 41% op_aget(load="ldrb", shift="0", data_offset="MIRROR_BOOLEAN_ARRAY_DATA_OFFSET", is_object="0") 42 43%def op_aget_byte(): 44% op_aget(load="ldrsb", shift="0", data_offset="MIRROR_BYTE_ARRAY_DATA_OFFSET", is_object="0") 45 46%def op_aget_char(): 47% op_aget(load="ldrh", shift="1", data_offset="MIRROR_CHAR_ARRAY_DATA_OFFSET", is_object="0") 48 49%def op_aget_object(): 50% op_aget(load="ldr", shift="2", data_offset="MIRROR_OBJECT_ARRAY_DATA_OFFSET", is_object="1") 51 52%def op_aget_short(): 53% op_aget(load="ldrsh", shift="1", data_offset="MIRROR_SHORT_ARRAY_DATA_OFFSET", is_object="0") 54 55%def op_aget_wide(): 56% op_aget(load="ldr", shift="3", data_offset="MIRROR_WIDE_ARRAY_DATA_OFFSET", wide="1", is_object="0") 57 58%def op_aput(store="str", shift="2", data_offset="MIRROR_INT_ARRAY_DATA_OFFSET", wide="0", is_object="0"): 59/* 60 * Array put. vBB[vCC] <- vAA. 61 * 62 * for: aput, aput-boolean, aput-byte, aput-char, aput-short, aput-wide, aput-object 63 * 64 */ 65 FETCH_B w2, 1, 0 // w2<- BB 66 lsr w9, wINST, #8 // w9<- AA 67 FETCH_B w3, 1, 1 // w3<- CC 68 GET_VREG w0, w2 // w0<- vBB (array object) 69 GET_VREG w1, w3 // w1<- vCC (requested index) 70 cbz w0, common_errNullObject // bail if null 71 ldr w3, [x0, #MIRROR_ARRAY_LENGTH_OFFSET] // w3<- arrayObj->length 72 .if !$is_object 73 add x0, x0, w1, uxtw #$shift // w0<- arrayObj + index*width 74 .endif 75 cmp w1, w3 // compare unsigned index, length 76 bcs common_errArrayIndex // index >= length, bail 77 .if $is_object 78 EXPORT_PC // Export PC before overwriting it. 79 .endif 80 FETCH_ADVANCE_INST 2 // advance rPC, load rINST 81 .if $wide 82 GET_VREG_WIDE x2, w9 // x2<- vAA 83 .else 84 GET_VREG w2, w9 // w2<- vAA 85 .endif 86 .if $wide 87 $store x2, [x0, #$data_offset] // vBB[vCC]<- x2 88 .elseif $is_object 89 bl art_quick_aput_obj 90 .else 91 $store w2, [x0, #$data_offset] // vBB[vCC]<- w2 92 .endif 93 GET_INST_OPCODE ip // extract opcode from rINST 94 GOTO_OPCODE ip // jump to next instruction 95 96%def op_aput_boolean(): 97% op_aput(store="strb", shift="0", data_offset="MIRROR_BOOLEAN_ARRAY_DATA_OFFSET", wide="0", is_object="0") 98 99%def op_aput_byte(): 100% op_aput(store="strb", shift="0", data_offset="MIRROR_BYTE_ARRAY_DATA_OFFSET", wide="0", is_object="0") 101 102%def op_aput_char(): 103% op_aput(store="strh", shift="1", data_offset="MIRROR_CHAR_ARRAY_DATA_OFFSET", wide="0", is_object="0") 104 105%def op_aput_short(): 106% op_aput(store="strh", shift="1", data_offset="MIRROR_SHORT_ARRAY_DATA_OFFSET", wide="0", is_object="0") 107 108%def op_aput_wide(): 109% op_aput(store="str", shift="3", data_offset="MIRROR_WIDE_ARRAY_DATA_OFFSET", wide="1", is_object="0") 110 111%def op_aput_object(): 112% op_aput(store="str", shift="2", data_offset="MIRROR_INT_ARRAY_DATA_OFFSET", wide="0", is_object="1") 113 114%def op_array_length(): 115 /* 116 * Return the length of an array. 117 */ 118 lsr w1, wINST, #12 // w1<- B 119 ubfx w2, wINST, #8, #4 // w2<- A 120 GET_VREG w0, w1 // w0<- vB (object ref) 121 cbz w0, common_errNullObject // bail if null 122 FETCH_ADVANCE_INST 1 // advance rPC, load rINST 123 ldr w3, [x0, #MIRROR_ARRAY_LENGTH_OFFSET] // w3<- array length 124 GET_INST_OPCODE ip // extract opcode from rINST 125 SET_VREG w3, w2 // vB<- length 126 GOTO_OPCODE ip // jump to next instruction 127 128%def op_fill_array_data(): 129 /* fill-array-data vAA, +BBBBBBBB */ 130 EXPORT_PC 131 FETCH w0, 1 // x0<- 000000000000bbbb (lo) 132 FETCH_S x1, 2 // x1<- ssssssssssssBBBB (hi) 133 lsr w3, wINST, #8 // w3<- AA 134 orr x0, x0, x1, lsl #16 // x0<- ssssssssBBBBbbbb 135 GET_VREG w1, w3 // w1<- vAA (array object) 136 add x0, xPC, x0, lsl #1 // x0<- PC + ssssssssBBBBbbbb*2 (array data off.) 137 bl art_quick_handle_fill_data 138 FETCH_ADVANCE_INST 3 // advance rPC, load rINST 139 GET_INST_OPCODE ip // extract opcode from rINST 140 GOTO_OPCODE ip // jump to next instruction 141 142%def op_filled_new_array(helper="nterp_filled_new_array"): 143/* 144 * Create a new array with elements filled from registers. 145 * 146 * for: filled-new-array, filled-new-array/range 147 */ 148 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 149 /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */ 150 EXPORT_PC 151 mov x0, xSELF 152 ldr x1, [sp] 153 mov x2, xFP 154 mov x3, xPC 155 bl $helper 156 FETCH_ADVANCE_INST 3 // advance rPC, load rINST 157 GET_INST_OPCODE ip // extract opcode from rINST 158 GOTO_OPCODE ip // jump to next instruction 159 160%def op_filled_new_array_range(): 161% op_filled_new_array(helper="nterp_filled_new_array_range") 162 163%def op_new_array(): 164 /* new-array vA, vB, class@CCCC */ 165 EXPORT_PC 166 // Fast-path which gets the class from thread-local cache. 167% fetch_from_thread_cache("x0", miss_label="2f") 168 TEST_IF_MARKING 3f 1691: 170 lsr w1, wINST, #12 // w1<- B 171 GET_VREG w1, w1 // w1<- vB (array length) 172 ldr lr, [xSELF, #THREAD_ALLOC_ARRAY_ENTRYPOINT_OFFSET] 173 blr lr 174 dmb ishst // need fence for making array's class visible 175 ubfx w1, wINST, #8, #4 // w1<- A 176 SET_VREG_OBJECT w0, w1 177 FETCH_ADVANCE_INST 2 178 GET_INST_OPCODE ip 179 GOTO_OPCODE ip 1802: 181 mov x0, xSELF 182 ldr x1, [sp, 0] 183 mov x2, xPC 184 bl nterp_get_class 185 b 1b 1863: 187 bl art_quick_read_barrier_mark_reg00 188 b 1b 189