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