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