1*795d594fSAndroid Build Coastguard Worker%def op_check_cast(): 2*795d594fSAndroid Build Coastguard Worker% slow_path = add_slow_path(op_check_cast_slow_path) 3*795d594fSAndroid Build Coastguard Worker // Fast-path which gets the class from thread-local cache. 4*795d594fSAndroid Build Coastguard Worker% fetch_from_thread_cache("r1", miss_label="2f") 5*795d594fSAndroid Build Coastguard Worker1: 6*795d594fSAndroid Build Coastguard Worker lsr r2, rINST, #8 // r2<- A 7*795d594fSAndroid Build Coastguard Worker GET_VREG r0, r2 // r0<- vA (object) 8*795d594fSAndroid Build Coastguard Worker cmp r0, #0 9*795d594fSAndroid Build Coastguard Worker beq .L${opcode}_resume 10*795d594fSAndroid Build Coastguard Worker ldr r2, [r0, #MIRROR_OBJECT_CLASS_OFFSET] 11*795d594fSAndroid Build Coastguard Worker UNPOISON_HEAP_REF r2 12*795d594fSAndroid Build Coastguard Worker // Fast path: do a comparison without read barrier. 13*795d594fSAndroid Build Coastguard Worker cmp r1, r2 14*795d594fSAndroid Build Coastguard Worker bne ${slow_path} 15*795d594fSAndroid Build Coastguard Worker.L${opcode}_resume: 16*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 2 17*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip 18*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip 19*795d594fSAndroid Build Coastguard Worker2: 20*795d594fSAndroid Build Coastguard Worker EXPORT_PC 21*795d594fSAndroid Build Coastguard Worker mov r0, rSELF 22*795d594fSAndroid Build Coastguard Worker ldr r1, [sp] 23*795d594fSAndroid Build Coastguard Worker mov r2, rPC 24*795d594fSAndroid Build Coastguard Worker bl nterp_get_class 25*795d594fSAndroid Build Coastguard Worker mov r1, r0 26*795d594fSAndroid Build Coastguard Worker b 1b 27*795d594fSAndroid Build Coastguard Worker 28*795d594fSAndroid Build Coastguard Worker%def op_check_cast_slow_path(): 29*795d594fSAndroid Build Coastguard Worker ldr r3, [r1, #MIRROR_CLASS_ACCESS_FLAGS_OFFSET] 30*795d594fSAndroid Build Coastguard Worker tst r3, #MIRROR_CLASS_IS_INTERFACE_FLAG 31*795d594fSAndroid Build Coastguard Worker bne 2f 32*795d594fSAndroid Build Coastguard Worker ldr r3, [r1, #MIRROR_CLASS_COMPONENT_TYPE_OFFSET] 33*795d594fSAndroid Build Coastguard Worker UNPOISON_HEAP_REF r3 34*795d594fSAndroid Build Coastguard Worker cmp r3, #0 35*795d594fSAndroid Build Coastguard Worker bne 5f 36*795d594fSAndroid Build Coastguard Worker1: 37*795d594fSAndroid Build Coastguard Worker ldr r2, [r2, #MIRROR_CLASS_SUPER_CLASS_OFFSET] 38*795d594fSAndroid Build Coastguard Worker UNPOISON_HEAP_REF r2 39*795d594fSAndroid Build Coastguard Worker cmp r1, r2 40*795d594fSAndroid Build Coastguard Worker beq .L${opcode}_resume 41*795d594fSAndroid Build Coastguard Worker cmp r2, #0 42*795d594fSAndroid Build Coastguard Worker bne 1b 43*795d594fSAndroid Build Coastguard Worker2: 44*795d594fSAndroid Build Coastguard Worker TEST_IF_MARKING 4f 45*795d594fSAndroid Build Coastguard Worker3: 46*795d594fSAndroid Build Coastguard Worker EXPORT_PC 47*795d594fSAndroid Build Coastguard Worker bl art_quick_check_instance_of 48*795d594fSAndroid Build Coastguard Worker b .L${opcode}_resume 49*795d594fSAndroid Build Coastguard Worker4: 50*795d594fSAndroid Build Coastguard Worker bl art_quick_read_barrier_mark_reg01 51*795d594fSAndroid Build Coastguard Worker b 3b 52*795d594fSAndroid Build Coastguard Worker5: 53*795d594fSAndroid Build Coastguard Worker // Class in r1 is an array, r3 is the component type. 54*795d594fSAndroid Build Coastguard Worker ldr r2, [r2, #MIRROR_CLASS_COMPONENT_TYPE_OFFSET] 55*795d594fSAndroid Build Coastguard Worker UNPOISON_HEAP_REF r2 56*795d594fSAndroid Build Coastguard Worker // Check if object is an array. 57*795d594fSAndroid Build Coastguard Worker cmp r2, #0 58*795d594fSAndroid Build Coastguard Worker beq 2b 59*795d594fSAndroid Build Coastguard Worker ldr r4, [r3, #MIRROR_CLASS_SUPER_CLASS_OFFSET] 60*795d594fSAndroid Build Coastguard Worker UNPOISON_HEAP_REF r4 61*795d594fSAndroid Build Coastguard Worker cmp r4, #0 62*795d594fSAndroid Build Coastguard Worker // If the super class of the component type is not null, go slow path. 63*795d594fSAndroid Build Coastguard Worker bne 2b 64*795d594fSAndroid Build Coastguard Worker ldrh r3, [r3, #MIRROR_CLASS_OBJECT_PRIMITIVE_TYPE_OFFSET] 65*795d594fSAndroid Build Coastguard Worker // Check if the object is a primitive array. 66*795d594fSAndroid Build Coastguard Worker ldrh r2, [r2, #MIRROR_CLASS_OBJECT_PRIMITIVE_TYPE_OFFSET] 67*795d594fSAndroid Build Coastguard Worker orrs r2, r3 68*795d594fSAndroid Build Coastguard Worker beq .L${opcode}_resume 69*795d594fSAndroid Build Coastguard Worker // Go slow path for throwing the exception. 70*795d594fSAndroid Build Coastguard Worker b 2b 71*795d594fSAndroid Build Coastguard Worker 72*795d594fSAndroid Build Coastguard Worker%def op_instance_of(): 73*795d594fSAndroid Build Coastguard Worker% slow_path = add_slow_path(op_instance_of_slow_path) 74*795d594fSAndroid Build Coastguard Worker /* instance-of vA, vB, class@CCCC */ 75*795d594fSAndroid Build Coastguard Worker // Fast-path which gets the class from thread-local cache. 76*795d594fSAndroid Build Coastguard Worker% fetch_from_thread_cache("r1", miss_label="2f") 77*795d594fSAndroid Build Coastguard Worker1: 78*795d594fSAndroid Build Coastguard Worker lsr r2, rINST, #12 // r2<- B 79*795d594fSAndroid Build Coastguard Worker GET_VREG r0, r2 // r0<- vB (object) 80*795d594fSAndroid Build Coastguard Worker cmp r0, #0 81*795d594fSAndroid Build Coastguard Worker beq .L${opcode}_resume 82*795d594fSAndroid Build Coastguard Worker ldr r2, [r0, #MIRROR_OBJECT_CLASS_OFFSET] 83*795d594fSAndroid Build Coastguard Worker UNPOISON_HEAP_REF r2 84*795d594fSAndroid Build Coastguard Worker // Fast path: do a comparison without read barrier. 85*795d594fSAndroid Build Coastguard Worker cmp r1, r2 86*795d594fSAndroid Build Coastguard Worker bne ${slow_path} 87*795d594fSAndroid Build Coastguard Worker.L${opcode}_set_one: 88*795d594fSAndroid Build Coastguard Worker mov r0, #1 89*795d594fSAndroid Build Coastguard Worker.L${opcode}_resume: 90*795d594fSAndroid Build Coastguard Worker ubfx r1, rINST, #8, #4 // r1<- A 91*795d594fSAndroid Build Coastguard Worker SET_VREG r0, r1 92*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 2 93*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip 94*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip 95*795d594fSAndroid Build Coastguard Worker2: 96*795d594fSAndroid Build Coastguard Worker EXPORT_PC 97*795d594fSAndroid Build Coastguard Worker mov r0, rSELF 98*795d594fSAndroid Build Coastguard Worker ldr r1, [sp] 99*795d594fSAndroid Build Coastguard Worker mov r2, rPC 100*795d594fSAndroid Build Coastguard Worker bl nterp_get_class 101*795d594fSAndroid Build Coastguard Worker mov r1, r0 102*795d594fSAndroid Build Coastguard Worker b 1b 103*795d594fSAndroid Build Coastguard Worker 104*795d594fSAndroid Build Coastguard Worker%def op_instance_of_slow_path(): 105*795d594fSAndroid Build Coastguard Worker // Go slow path if we are marking. Checking now allows 106*795d594fSAndroid Build Coastguard Worker // not going to slow path if the super class hierarchy check fails. 107*795d594fSAndroid Build Coastguard Worker TEST_IF_MARKING 4f 108*795d594fSAndroid Build Coastguard Worker ldr r3, [r1, #MIRROR_CLASS_ACCESS_FLAGS_OFFSET] 109*795d594fSAndroid Build Coastguard Worker tst r3, #MIRROR_CLASS_IS_INTERFACE_FLAG 110*795d594fSAndroid Build Coastguard Worker bne 5f 111*795d594fSAndroid Build Coastguard Worker ldr r3, [r1, #MIRROR_CLASS_COMPONENT_TYPE_OFFSET] 112*795d594fSAndroid Build Coastguard Worker UNPOISON_HEAP_REF r3 113*795d594fSAndroid Build Coastguard Worker cmp r3, #0 114*795d594fSAndroid Build Coastguard Worker bne 3f 115*795d594fSAndroid Build Coastguard Worker1: 116*795d594fSAndroid Build Coastguard Worker ldr r2, [r2, #MIRROR_CLASS_SUPER_CLASS_OFFSET] 117*795d594fSAndroid Build Coastguard Worker UNPOISON_HEAP_REF r2 118*795d594fSAndroid Build Coastguard Worker cmp r1, r2 119*795d594fSAndroid Build Coastguard Worker beq .L${opcode}_set_one 120*795d594fSAndroid Build Coastguard Worker cmp r2, #0 121*795d594fSAndroid Build Coastguard Worker bne 1b 122*795d594fSAndroid Build Coastguard Worker2: 123*795d594fSAndroid Build Coastguard Worker mov r0, #0 124*795d594fSAndroid Build Coastguard Worker b .L${opcode}_resume 125*795d594fSAndroid Build Coastguard Worker3: 126*795d594fSAndroid Build Coastguard Worker // Class in r1 is an array, r3 is the component type. 127*795d594fSAndroid Build Coastguard Worker ldr r2, [r2, #MIRROR_CLASS_COMPONENT_TYPE_OFFSET] 128*795d594fSAndroid Build Coastguard Worker UNPOISON_HEAP_REF r2 129*795d594fSAndroid Build Coastguard Worker // Check if object is an array. 130*795d594fSAndroid Build Coastguard Worker cmp r2, #0 131*795d594fSAndroid Build Coastguard Worker beq 2b 132*795d594fSAndroid Build Coastguard Worker ldr r4, [r3, #MIRROR_CLASS_SUPER_CLASS_OFFSET] 133*795d594fSAndroid Build Coastguard Worker UNPOISON_HEAP_REF r4 134*795d594fSAndroid Build Coastguard Worker cmp r4, #0 135*795d594fSAndroid Build Coastguard Worker bne 5f 136*795d594fSAndroid Build Coastguard Worker ldrh r3, [r3, #MIRROR_CLASS_OBJECT_PRIMITIVE_TYPE_OFFSET] 137*795d594fSAndroid Build Coastguard Worker // Check if the object is a primitive array. 138*795d594fSAndroid Build Coastguard Worker ldrh r2, [r2, #MIRROR_CLASS_OBJECT_PRIMITIVE_TYPE_OFFSET] 139*795d594fSAndroid Build Coastguard Worker orr r0, r2, r3 140*795d594fSAndroid Build Coastguard Worker clz r0, r0 141*795d594fSAndroid Build Coastguard Worker lsrs r0, r0, #5 142*795d594fSAndroid Build Coastguard Worker b .L${opcode}_resume 143*795d594fSAndroid Build Coastguard Worker4: 144*795d594fSAndroid Build Coastguard Worker bl art_quick_read_barrier_mark_reg01 145*795d594fSAndroid Build Coastguard Worker5: 146*795d594fSAndroid Build Coastguard Worker EXPORT_PC 147*795d594fSAndroid Build Coastguard Worker bl artInstanceOfFromCode 148*795d594fSAndroid Build Coastguard Worker b .L${opcode}_resume 149*795d594fSAndroid Build Coastguard Worker 150*795d594fSAndroid Build Coastguard Worker%def op_iget_boolean(): 151*795d594fSAndroid Build Coastguard Worker% op_iget(load="ldrb", wide="0", is_object="0") 152*795d594fSAndroid Build Coastguard Worker 153*795d594fSAndroid Build Coastguard Worker%def op_iget_byte(): 154*795d594fSAndroid Build Coastguard Worker% op_iget(load="ldrsb", wide="0", is_object="0") 155*795d594fSAndroid Build Coastguard Worker 156*795d594fSAndroid Build Coastguard Worker%def op_iget_char(): 157*795d594fSAndroid Build Coastguard Worker% op_iget(load="ldrh", wide="0", is_object="0") 158*795d594fSAndroid Build Coastguard Worker 159*795d594fSAndroid Build Coastguard Worker%def op_iget_short(): 160*795d594fSAndroid Build Coastguard Worker% op_iget(load="ldrsh", wide="0", is_object="0") 161*795d594fSAndroid Build Coastguard Worker 162*795d594fSAndroid Build Coastguard Worker%def op_iget(load="ldr", wide="0", is_object="0"): 163*795d594fSAndroid Build Coastguard Worker% slow_path = add_slow_path(op_iget_slow_path, load, wide, is_object) 164*795d594fSAndroid Build Coastguard Worker // Fast-path which gets the field from thread-local cache. 165*795d594fSAndroid Build Coastguard Worker% fetch_from_thread_cache("r0", miss_label=slow_path) 166*795d594fSAndroid Build Coastguard Worker.L${opcode}_resume: 167*795d594fSAndroid Build Coastguard Worker lsr r2, rINST, #12 // r2<- B 168*795d594fSAndroid Build Coastguard Worker GET_VREG r3, r2 // r3<- object we're operating on 169*795d594fSAndroid Build Coastguard Worker ubfx r2, rINST, #8, #4 // r2<- A 170*795d594fSAndroid Build Coastguard Worker cmp r3, #0 171*795d594fSAndroid Build Coastguard Worker beq common_errNullObject // object was null 172*795d594fSAndroid Build Coastguard Worker .if $wide 173*795d594fSAndroid Build Coastguard Worker add r3, r3, r0 174*795d594fSAndroid Build Coastguard Worker ldrd r0, r1, [r3] 175*795d594fSAndroid Build Coastguard Worker CLEAR_SHADOW_PAIR r2, ip, lr 176*795d594fSAndroid Build Coastguard Worker VREG_INDEX_TO_ADDR r2, r2 177*795d594fSAndroid Build Coastguard Worker SET_VREG_WIDE_BY_ADDR r0, r1, r2 // fp[A] <- value 178*795d594fSAndroid Build Coastguard Worker .elseif $is_object 179*795d594fSAndroid Build Coastguard Worker $load r0, [r3, r0] 180*795d594fSAndroid Build Coastguard Worker UNPOISON_HEAP_REF r0 181*795d594fSAndroid Build Coastguard Worker TEST_IF_MARKING .L${opcode}_read_barrier 182*795d594fSAndroid Build Coastguard Worker.L${opcode}_resume_after_read_barrier: 183*795d594fSAndroid Build Coastguard Worker SET_VREG_OBJECT r0, r2 // fp[A] <- value 184*795d594fSAndroid Build Coastguard Worker .else 185*795d594fSAndroid Build Coastguard Worker $load r0, [r3, r0] 186*795d594fSAndroid Build Coastguard Worker SET_VREG r0, r2 // fp[A] <- value 187*795d594fSAndroid Build Coastguard Worker .endif 188*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 2 189*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip 190*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip 191*795d594fSAndroid Build Coastguard Worker .if $is_object 192*795d594fSAndroid Build Coastguard Worker.L${opcode}_read_barrier: 193*795d594fSAndroid Build Coastguard Worker bl art_quick_read_barrier_mark_reg00 194*795d594fSAndroid Build Coastguard Worker b .L${opcode}_resume_after_read_barrier 195*795d594fSAndroid Build Coastguard Worker .endif 196*795d594fSAndroid Build Coastguard Worker 197*795d594fSAndroid Build Coastguard Worker%def op_iget_slow_path(load, wide, is_object): 198*795d594fSAndroid Build Coastguard Worker mov r0, rSELF 199*795d594fSAndroid Build Coastguard Worker ldr r1, [sp] 200*795d594fSAndroid Build Coastguard Worker mov r2, rPC 201*795d594fSAndroid Build Coastguard Worker mov r3, #0 202*795d594fSAndroid Build Coastguard Worker EXPORT_PC 203*795d594fSAndroid Build Coastguard Worker bl nterp_get_instance_field_offset 204*795d594fSAndroid Build Coastguard Worker cmp r0, #0 205*795d594fSAndroid Build Coastguard Worker bge .L${opcode}_resume 206*795d594fSAndroid Build Coastguard Worker CLEAR_INSTANCE_VOLATILE_MARKER r0 207*795d594fSAndroid Build Coastguard Worker lsr r2, rINST, #12 // r2<- B 208*795d594fSAndroid Build Coastguard Worker GET_VREG r3, r2 // r3<- object we're operating on 209*795d594fSAndroid Build Coastguard Worker ubfx r2, rINST, #8, #4 // r2<- A 210*795d594fSAndroid Build Coastguard Worker cmp r3, #0 211*795d594fSAndroid Build Coastguard Worker beq common_errNullObject // object was null 212*795d594fSAndroid Build Coastguard Worker .if $wide 213*795d594fSAndroid Build Coastguard Worker add ip, r3, r0 214*795d594fSAndroid Build Coastguard Worker ATOMIC_LOAD64 ip, r0, r1, r3, .L${opcode}_slow_path_atomic_load 215*795d594fSAndroid Build Coastguard Worker dmb ish 216*795d594fSAndroid Build Coastguard Worker CLEAR_SHADOW_PAIR r2, ip, lr 217*795d594fSAndroid Build Coastguard Worker VREG_INDEX_TO_ADDR r2, r2 218*795d594fSAndroid Build Coastguard Worker SET_VREG_WIDE_BY_ADDR r0, r1, r2 // fp[A] <- value 219*795d594fSAndroid Build Coastguard Worker .else 220*795d594fSAndroid Build Coastguard Worker $load r0, [r3, r0] 221*795d594fSAndroid Build Coastguard Worker dmb ish 222*795d594fSAndroid Build Coastguard Worker .if $is_object 223*795d594fSAndroid Build Coastguard Worker UNPOISON_HEAP_REF r0 224*795d594fSAndroid Build Coastguard Worker TEST_IF_MARKING .L${opcode}_read_barrier 225*795d594fSAndroid Build Coastguard Worker SET_VREG_OBJECT r0, r2 // fp[A] <- value 226*795d594fSAndroid Build Coastguard Worker .else 227*795d594fSAndroid Build Coastguard Worker SET_VREG r0, r2 // fp[A] <- value 228*795d594fSAndroid Build Coastguard Worker .endif 229*795d594fSAndroid Build Coastguard Worker .endif 230*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 2 231*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip 232*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip 233*795d594fSAndroid Build Coastguard Worker 234*795d594fSAndroid Build Coastguard Worker%def op_iget_wide(): 235*795d594fSAndroid Build Coastguard Worker% op_iget(load="ldr", wide="1", is_object="0") 236*795d594fSAndroid Build Coastguard Worker 237*795d594fSAndroid Build Coastguard Worker%def op_iget_object(): 238*795d594fSAndroid Build Coastguard Worker% op_iget(load="ldr", wide="0", is_object="1") 239*795d594fSAndroid Build Coastguard Worker 240*795d594fSAndroid Build Coastguard Worker%def op_iput_boolean(): 241*795d594fSAndroid Build Coastguard Worker% op_iput(store="strb", wide="0", is_object="0") 242*795d594fSAndroid Build Coastguard Worker 243*795d594fSAndroid Build Coastguard Worker%def op_iput_byte(): 244*795d594fSAndroid Build Coastguard Worker% op_iput(store="strb", wide="0", is_object="0") 245*795d594fSAndroid Build Coastguard Worker 246*795d594fSAndroid Build Coastguard Worker%def op_iput_char(): 247*795d594fSAndroid Build Coastguard Worker% op_iput(store="strh", wide="0", is_object="0") 248*795d594fSAndroid Build Coastguard Worker 249*795d594fSAndroid Build Coastguard Worker%def op_iput_short(): 250*795d594fSAndroid Build Coastguard Worker% op_iput(store="strh", wide="0", is_object="0") 251*795d594fSAndroid Build Coastguard Worker 252*795d594fSAndroid Build Coastguard Worker%def op_iput(store="str", wide="0", is_object="0"): 253*795d594fSAndroid Build Coastguard Worker% slow_path = add_slow_path(op_iput_slow_path, store, wide, is_object) 254*795d594fSAndroid Build Coastguard Worker .if !$wide 255*795d594fSAndroid Build Coastguard Worker ubfx r4, rINST, #8, #4 // r4<- A 256*795d594fSAndroid Build Coastguard Worker GET_VREG r4, r4 // r4 <- v[A] 257*795d594fSAndroid Build Coastguard Worker .endif 258*795d594fSAndroid Build Coastguard Worker // Fast-path which gets the field from thread-local cache. 259*795d594fSAndroid Build Coastguard Worker% fetch_from_thread_cache("r0", miss_label=slow_path) 260*795d594fSAndroid Build Coastguard Worker.L${opcode}_resume: 261*795d594fSAndroid Build Coastguard Worker lsr r1, rINST, #12 // r1<- B 262*795d594fSAndroid Build Coastguard Worker GET_VREG r1, r1 // vB (object we're operating on) 263*795d594fSAndroid Build Coastguard Worker cmp r1, #0 264*795d594fSAndroid Build Coastguard Worker beq common_errNullObject 265*795d594fSAndroid Build Coastguard Worker .if $wide 266*795d594fSAndroid Build Coastguard Worker ubfx r4, rINST, #8, #4 // r4<- A 267*795d594fSAndroid Build Coastguard Worker VREG_INDEX_TO_ADDR r4, r4 268*795d594fSAndroid Build Coastguard Worker GET_VREG_WIDE_BY_ADDR r2, r3, r4 // fp[A] <- value 269*795d594fSAndroid Build Coastguard Worker add r1, r1, r0 270*795d594fSAndroid Build Coastguard Worker strd r2, r3, [r1] 271*795d594fSAndroid Build Coastguard Worker .else 272*795d594fSAndroid Build Coastguard Worker POISON_HEAP_REF_IF_OBJECT $is_object, r4 273*795d594fSAndroid Build Coastguard Worker $store r4, [r1, r0] 274*795d594fSAndroid Build Coastguard Worker WRITE_BARRIER_IF_OBJECT $is_object, r4, r1, .L${opcode}_skip_write_barrier, r0 275*795d594fSAndroid Build Coastguard Worker .endif 276*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 2 277*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip 278*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip 279*795d594fSAndroid Build Coastguard Worker 280*795d594fSAndroid Build Coastguard Worker%def op_iput_slow_path(store, wide, is_object): 281*795d594fSAndroid Build Coastguard Worker mov r0, rSELF 282*795d594fSAndroid Build Coastguard Worker ldr r1, [sp] 283*795d594fSAndroid Build Coastguard Worker mov r2, rPC 284*795d594fSAndroid Build Coastguard Worker .if $is_object 285*795d594fSAndroid Build Coastguard Worker mov r3, r4 286*795d594fSAndroid Build Coastguard Worker .else 287*795d594fSAndroid Build Coastguard Worker mov r3, #0 288*795d594fSAndroid Build Coastguard Worker .endif 289*795d594fSAndroid Build Coastguard Worker EXPORT_PC 290*795d594fSAndroid Build Coastguard Worker bl nterp_get_instance_field_offset 291*795d594fSAndroid Build Coastguard Worker .if $is_object 292*795d594fSAndroid Build Coastguard Worker // Reload the value as it may have moved. 293*795d594fSAndroid Build Coastguard Worker ubfx r4, rINST, #8, #4 // r4<- A 294*795d594fSAndroid Build Coastguard Worker GET_VREG r4, r4 // r4 <- v[A] 295*795d594fSAndroid Build Coastguard Worker .endif 296*795d594fSAndroid Build Coastguard Worker cmp r0, #0 297*795d594fSAndroid Build Coastguard Worker bge .L${opcode}_resume 298*795d594fSAndroid Build Coastguard Worker CLEAR_INSTANCE_VOLATILE_MARKER r0 299*795d594fSAndroid Build Coastguard Worker .if $wide 300*795d594fSAndroid Build Coastguard Worker lsr r4, rINST, #12 // r4<- B 301*795d594fSAndroid Build Coastguard Worker ubfx r1, rINST, #8, #4 // r1<- A 302*795d594fSAndroid Build Coastguard Worker GET_VREG r4, r4 // vB (object we're operating on) 303*795d594fSAndroid Build Coastguard Worker cmp r4, #0 304*795d594fSAndroid Build Coastguard Worker beq common_errNullObject 305*795d594fSAndroid Build Coastguard Worker VREG_INDEX_TO_ADDR r1, r1 306*795d594fSAndroid Build Coastguard Worker GET_VREG_WIDE_BY_ADDR r2, r3, r1 307*795d594fSAndroid Build Coastguard Worker add ip, r4, r0 308*795d594fSAndroid Build Coastguard Worker dmb ish 309*795d594fSAndroid Build Coastguard Worker ATOMIC_STORE64 ip, r2, r3, r0, r1, .L${opcode}_slow_path_atomic_store 310*795d594fSAndroid Build Coastguard Worker dmb ish 311*795d594fSAndroid Build Coastguard Worker .else 312*795d594fSAndroid Build Coastguard Worker lsr r1, rINST, #12 // r4<- B 313*795d594fSAndroid Build Coastguard Worker GET_VREG r1, r1 // vB (object we're operating on) 314*795d594fSAndroid Build Coastguard Worker cmp r1, #0 315*795d594fSAndroid Build Coastguard Worker beq common_errNullObject 316*795d594fSAndroid Build Coastguard Worker dmb ish 317*795d594fSAndroid Build Coastguard Worker POISON_HEAP_REF_IF_OBJECT $is_object, r4 318*795d594fSAndroid Build Coastguard Worker $store r4, [r1, r0] 319*795d594fSAndroid Build Coastguard Worker dmb ish 320*795d594fSAndroid Build Coastguard Worker WRITE_BARRIER_IF_OBJECT $is_object, r4, r1, .L${opcode}_slow_path_skip_write_barrier, r0 321*795d594fSAndroid Build Coastguard Worker .endif 322*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 2 323*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip 324*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip 325*795d594fSAndroid Build Coastguard Worker 326*795d594fSAndroid Build Coastguard Worker%def op_iput_wide(): 327*795d594fSAndroid Build Coastguard Worker% op_iput(store="str", wide="1", is_object="0") 328*795d594fSAndroid Build Coastguard Worker 329*795d594fSAndroid Build Coastguard Worker%def op_iput_object(): 330*795d594fSAndroid Build Coastguard Worker% op_iput(store="str", wide="0", is_object="1") 331*795d594fSAndroid Build Coastguard Worker 332*795d594fSAndroid Build Coastguard Worker%def op_sget_boolean(): 333*795d594fSAndroid Build Coastguard Worker% op_sget(load="ldrb", wide="0", is_object="0") 334*795d594fSAndroid Build Coastguard Worker 335*795d594fSAndroid Build Coastguard Worker%def op_sget_byte(): 336*795d594fSAndroid Build Coastguard Worker% op_sget(load="ldrsb", wide="0", is_object="0") 337*795d594fSAndroid Build Coastguard Worker 338*795d594fSAndroid Build Coastguard Worker%def op_sget_char(): 339*795d594fSAndroid Build Coastguard Worker% op_sget(load="ldrh", wide="0", is_object="0") 340*795d594fSAndroid Build Coastguard Worker 341*795d594fSAndroid Build Coastguard Worker%def op_sget_short(): 342*795d594fSAndroid Build Coastguard Worker% op_sget(load="ldrsh", wide="0", is_object="0") 343*795d594fSAndroid Build Coastguard Worker 344*795d594fSAndroid Build Coastguard Worker%def op_sget(load="ldr", wide="0", is_object="0"): 345*795d594fSAndroid Build Coastguard Worker% slow_path = add_slow_path(op_sget_slow_path, load, wide, is_object) 346*795d594fSAndroid Build Coastguard Worker // Fast-path which gets the field from thread-local cache. 347*795d594fSAndroid Build Coastguard Worker% fetch_from_thread_cache("r0", miss_label=slow_path) 348*795d594fSAndroid Build Coastguard Worker.L${opcode}_resume: 349*795d594fSAndroid Build Coastguard Worker ldr r1, [r0, #ART_FIELD_OFFSET_OFFSET] 350*795d594fSAndroid Build Coastguard Worker lsr r2, rINST, #8 // r2 <- A 351*795d594fSAndroid Build Coastguard Worker ldr r0, [r0, #ART_FIELD_DECLARING_CLASS_OFFSET] 352*795d594fSAndroid Build Coastguard Worker TEST_IF_MARKING .L${opcode}_read_barrier 353*795d594fSAndroid Build Coastguard Worker.L${opcode}_resume_after_read_barrier: 354*795d594fSAndroid Build Coastguard Worker .if $wide 355*795d594fSAndroid Build Coastguard Worker add r0, r0, r1 356*795d594fSAndroid Build Coastguard Worker ldrd r0, r1, [r0] 357*795d594fSAndroid Build Coastguard Worker CLEAR_SHADOW_PAIR r2, ip, lr 358*795d594fSAndroid Build Coastguard Worker VREG_INDEX_TO_ADDR r2, r2 359*795d594fSAndroid Build Coastguard Worker SET_VREG_WIDE_BY_ADDR r0, r1, r2 // fp[A] <- value 360*795d594fSAndroid Build Coastguard Worker .elseif $is_object 361*795d594fSAndroid Build Coastguard Worker $load r0, [r0, r1] 362*795d594fSAndroid Build Coastguard Worker UNPOISON_HEAP_REF r0 363*795d594fSAndroid Build Coastguard Worker // No need to check the marking register, we know it's not set here. 364*795d594fSAndroid Build Coastguard Worker.L${opcode}_after_reference_load: 365*795d594fSAndroid Build Coastguard Worker SET_VREG_OBJECT r0, r2 // fp[A] <- value 366*795d594fSAndroid Build Coastguard Worker .else 367*795d594fSAndroid Build Coastguard Worker $load r0, [r0, r1] 368*795d594fSAndroid Build Coastguard Worker SET_VREG r0, r2 // fp[A] <- value 369*795d594fSAndroid Build Coastguard Worker .endif 370*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 2 371*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip 372*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip 373*795d594fSAndroid Build Coastguard Worker.L${opcode}_read_barrier: 374*795d594fSAndroid Build Coastguard Worker bl art_quick_read_barrier_mark_reg00 375*795d594fSAndroid Build Coastguard Worker .if $is_object 376*795d594fSAndroid Build Coastguard Worker ldr r0, [r0, r1] 377*795d594fSAndroid Build Coastguard Worker UNPOISON_HEAP_REF r0 378*795d594fSAndroid Build Coastguard Worker.L${opcode}_mark_after_load: 379*795d594fSAndroid Build Coastguard Worker // Here, we know the marking register is set. 380*795d594fSAndroid Build Coastguard Worker bl art_quick_read_barrier_mark_reg00 381*795d594fSAndroid Build Coastguard Worker b .L${opcode}_after_reference_load 382*795d594fSAndroid Build Coastguard Worker .else 383*795d594fSAndroid Build Coastguard Worker b .L${opcode}_resume_after_read_barrier 384*795d594fSAndroid Build Coastguard Worker .endif 385*795d594fSAndroid Build Coastguard Worker 386*795d594fSAndroid Build Coastguard Worker%def op_sget_slow_path(load="ldr", wide="0", is_object="0"): 387*795d594fSAndroid Build Coastguard Worker mov r0, rSELF 388*795d594fSAndroid Build Coastguard Worker ldr r1, [sp] 389*795d594fSAndroid Build Coastguard Worker mov r2, rPC 390*795d594fSAndroid Build Coastguard Worker mov r3, #0 391*795d594fSAndroid Build Coastguard Worker EXPORT_PC 392*795d594fSAndroid Build Coastguard Worker bl nterp_get_static_field 393*795d594fSAndroid Build Coastguard Worker tst r0, #1 394*795d594fSAndroid Build Coastguard Worker beq .L${opcode}_resume 395*795d594fSAndroid Build Coastguard Worker CLEAR_STATIC_VOLATILE_MARKER r0 396*795d594fSAndroid Build Coastguard Worker ldr r1, [r0, #ART_FIELD_OFFSET_OFFSET] 397*795d594fSAndroid Build Coastguard Worker lsr r2, rINST, #8 // r2 <- A 398*795d594fSAndroid Build Coastguard Worker ldr r0, [r0, #ART_FIELD_DECLARING_CLASS_OFFSET] 399*795d594fSAndroid Build Coastguard Worker TEST_IF_MARKING .L${opcode}_slow_path_read_barrier 400*795d594fSAndroid Build Coastguard Worker.L${opcode}_slow_path_resume_after_read_barrier: 401*795d594fSAndroid Build Coastguard Worker .if $wide 402*795d594fSAndroid Build Coastguard Worker add ip, r0, r1 403*795d594fSAndroid Build Coastguard Worker ATOMIC_LOAD64 ip, r0, r1, r3, .L${opcode}_slow_path_atomic_load 404*795d594fSAndroid Build Coastguard Worker dmb ish 405*795d594fSAndroid Build Coastguard Worker CLEAR_SHADOW_PAIR r2, ip, lr 406*795d594fSAndroid Build Coastguard Worker VREG_INDEX_TO_ADDR r2, r2 407*795d594fSAndroid Build Coastguard Worker SET_VREG_WIDE_BY_ADDR r0, r1, r2 // fp[A] <- value 408*795d594fSAndroid Build Coastguard Worker .else 409*795d594fSAndroid Build Coastguard Worker $load r0, [r0, r1] 410*795d594fSAndroid Build Coastguard Worker dmb ish 411*795d594fSAndroid Build Coastguard Worker .if $is_object 412*795d594fSAndroid Build Coastguard Worker UNPOISON_HEAP_REF r0 413*795d594fSAndroid Build Coastguard Worker TEST_IF_MARKING .L${opcode}_mark_after_load 414*795d594fSAndroid Build Coastguard Worker SET_VREG_OBJECT r0, r2 // fp[A] <- value 415*795d594fSAndroid Build Coastguard Worker .else 416*795d594fSAndroid Build Coastguard Worker SET_VREG r0, r2 // fp[A] <- value 417*795d594fSAndroid Build Coastguard Worker .endif 418*795d594fSAndroid Build Coastguard Worker .endif 419*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 2 420*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip 421*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip 422*795d594fSAndroid Build Coastguard Worker.L${opcode}_slow_path_read_barrier: 423*795d594fSAndroid Build Coastguard Worker bl art_quick_read_barrier_mark_reg00 424*795d594fSAndroid Build Coastguard Worker b .L${opcode}_slow_path_resume_after_read_barrier 425*795d594fSAndroid Build Coastguard Worker 426*795d594fSAndroid Build Coastguard Worker%def op_sget_wide(): 427*795d594fSAndroid Build Coastguard Worker% op_sget(load="ldr", wide="1", is_object="0") 428*795d594fSAndroid Build Coastguard Worker 429*795d594fSAndroid Build Coastguard Worker%def op_sget_object(): 430*795d594fSAndroid Build Coastguard Worker% op_sget(load="ldr", wide="0", is_object="1") 431*795d594fSAndroid Build Coastguard Worker 432*795d594fSAndroid Build Coastguard Worker%def op_sput_boolean(): 433*795d594fSAndroid Build Coastguard Worker% op_sput(store="strb", wide="0", is_object="0") 434*795d594fSAndroid Build Coastguard Worker 435*795d594fSAndroid Build Coastguard Worker%def op_sput_byte(): 436*795d594fSAndroid Build Coastguard Worker% op_sput(store="strb", wide="0", is_object="0") 437*795d594fSAndroid Build Coastguard Worker 438*795d594fSAndroid Build Coastguard Worker%def op_sput_char(): 439*795d594fSAndroid Build Coastguard Worker% op_sput(store="strh", wide="0", is_object="0") 440*795d594fSAndroid Build Coastguard Worker 441*795d594fSAndroid Build Coastguard Worker%def op_sput_short(): 442*795d594fSAndroid Build Coastguard Worker% op_sput(store="strh", wide="0", is_object="0") 443*795d594fSAndroid Build Coastguard Worker 444*795d594fSAndroid Build Coastguard Worker%def op_sput(store="str", wide="0", is_object="0"): 445*795d594fSAndroid Build Coastguard Worker% slow_path = add_slow_path(op_sput_slow_path, store, wide, is_object) 446*795d594fSAndroid Build Coastguard Worker .if !$wide 447*795d594fSAndroid Build Coastguard Worker lsr r4, rINST, #8 // r4 <- A 448*795d594fSAndroid Build Coastguard Worker GET_VREG r4, r4 // r4 <- v[A] 449*795d594fSAndroid Build Coastguard Worker .endif 450*795d594fSAndroid Build Coastguard Worker // Fast-path which gets the field from thread-local cache. 451*795d594fSAndroid Build Coastguard Worker% fetch_from_thread_cache("r0", miss_label=slow_path) 452*795d594fSAndroid Build Coastguard Worker.L${opcode}_resume: 453*795d594fSAndroid Build Coastguard Worker ldr r1, [r0, #ART_FIELD_OFFSET_OFFSET] 454*795d594fSAndroid Build Coastguard Worker ldr r0, [r0, #ART_FIELD_DECLARING_CLASS_OFFSET] 455*795d594fSAndroid Build Coastguard Worker TEST_IF_MARKING .L${opcode}_read_barrier 456*795d594fSAndroid Build Coastguard Worker.L${opcode}_resume_after_read_barrier: 457*795d594fSAndroid Build Coastguard Worker .if $wide 458*795d594fSAndroid Build Coastguard Worker lsr r2, rINST, #8 // r2 <- A 459*795d594fSAndroid Build Coastguard Worker VREG_INDEX_TO_ADDR r2, r2 460*795d594fSAndroid Build Coastguard Worker GET_VREG_WIDE_BY_ADDR r2, r3, r2 // fp[A] <- value 461*795d594fSAndroid Build Coastguard Worker add r0, r0, r1 462*795d594fSAndroid Build Coastguard Worker strd r2, r3, [r0] 463*795d594fSAndroid Build Coastguard Worker .else 464*795d594fSAndroid Build Coastguard Worker POISON_HEAP_REF_IF_OBJECT $is_object, r4 465*795d594fSAndroid Build Coastguard Worker $store r4, [r0, r1] 466*795d594fSAndroid Build Coastguard Worker WRITE_BARRIER_IF_OBJECT $is_object, r4, r0, .L${opcode}_skip_write_barrier, r1 467*795d594fSAndroid Build Coastguard Worker .endif 468*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 2 469*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip 470*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip 471*795d594fSAndroid Build Coastguard Worker.L${opcode}_read_barrier: 472*795d594fSAndroid Build Coastguard Worker bl art_quick_read_barrier_mark_reg00 473*795d594fSAndroid Build Coastguard Worker b .L${opcode}_resume_after_read_barrier 474*795d594fSAndroid Build Coastguard Worker 475*795d594fSAndroid Build Coastguard Worker%def op_sput_slow_path(store, wide, is_object): 476*795d594fSAndroid Build Coastguard Worker mov r0, rSELF 477*795d594fSAndroid Build Coastguard Worker ldr r1, [sp] 478*795d594fSAndroid Build Coastguard Worker mov r2, rPC 479*795d594fSAndroid Build Coastguard Worker .if $is_object 480*795d594fSAndroid Build Coastguard Worker mov r3, r4 481*795d594fSAndroid Build Coastguard Worker .else 482*795d594fSAndroid Build Coastguard Worker mov r3, #0 483*795d594fSAndroid Build Coastguard Worker .endif 484*795d594fSAndroid Build Coastguard Worker EXPORT_PC 485*795d594fSAndroid Build Coastguard Worker bl nterp_get_static_field 486*795d594fSAndroid Build Coastguard Worker .if $is_object 487*795d594fSAndroid Build Coastguard Worker // Reload the value as it may have moved. 488*795d594fSAndroid Build Coastguard Worker lsr r4, rINST, #8 // r4 <- A 489*795d594fSAndroid Build Coastguard Worker GET_VREG r4, r4 // r4 <- v[A] 490*795d594fSAndroid Build Coastguard Worker .endif 491*795d594fSAndroid Build Coastguard Worker tst r0, #1 492*795d594fSAndroid Build Coastguard Worker beq .L${opcode}_resume 493*795d594fSAndroid Build Coastguard Worker CLEAR_STATIC_VOLATILE_MARKER r0 494*795d594fSAndroid Build Coastguard Worker ldr r1, [r0, #ART_FIELD_OFFSET_OFFSET] 495*795d594fSAndroid Build Coastguard Worker ldr r0, [r0, #ART_FIELD_DECLARING_CLASS_OFFSET] 496*795d594fSAndroid Build Coastguard Worker TEST_IF_MARKING .L${opcode}_slow_path_read_barrier 497*795d594fSAndroid Build Coastguard Worker.L${opcode}_slow_path_resume_after_read_barrier: 498*795d594fSAndroid Build Coastguard Worker .if $wide 499*795d594fSAndroid Build Coastguard Worker lsr r2, rINST, #8 // r2 <- A 500*795d594fSAndroid Build Coastguard Worker VREG_INDEX_TO_ADDR r2, r2 501*795d594fSAndroid Build Coastguard Worker GET_VREG_WIDE_BY_ADDR r2, r3, r2 502*795d594fSAndroid Build Coastguard Worker add ip, r0, r1 503*795d594fSAndroid Build Coastguard Worker dmb ish 504*795d594fSAndroid Build Coastguard Worker ATOMIC_STORE64 ip, r2, r3, r0, r1, .L${opcode}_slow_path_atomic_store 505*795d594fSAndroid Build Coastguard Worker dmb ish 506*795d594fSAndroid Build Coastguard Worker .else 507*795d594fSAndroid Build Coastguard Worker dmb ish 508*795d594fSAndroid Build Coastguard Worker POISON_HEAP_REF_IF_OBJECT $is_object r4 509*795d594fSAndroid Build Coastguard Worker $store r4, [r0, r1] 510*795d594fSAndroid Build Coastguard Worker dmb ish 511*795d594fSAndroid Build Coastguard Worker WRITE_BARRIER_IF_OBJECT $is_object, r4, r0, .L${opcode}_slow_path_skip_write_barrier, r1 512*795d594fSAndroid Build Coastguard Worker .endif 513*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 2 514*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip 515*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip 516*795d594fSAndroid Build Coastguard Worker.L${opcode}_slow_path_read_barrier: 517*795d594fSAndroid Build Coastguard Worker bl art_quick_read_barrier_mark_reg00 518*795d594fSAndroid Build Coastguard Worker b .L${opcode}_slow_path_resume_after_read_barrier 519*795d594fSAndroid Build Coastguard Worker 520*795d594fSAndroid Build Coastguard Worker%def op_sput_wide(): 521*795d594fSAndroid Build Coastguard Worker% op_sput(store="str", wide="1", is_object="0") 522*795d594fSAndroid Build Coastguard Worker 523*795d594fSAndroid Build Coastguard Worker%def op_sput_object(): 524*795d594fSAndroid Build Coastguard Worker% op_sput(store="str", wide="0", is_object="1") 525*795d594fSAndroid Build Coastguard Worker 526*795d594fSAndroid Build Coastguard Worker%def op_new_instance(): 527*795d594fSAndroid Build Coastguard Worker // The routine is too big to fit in a handler, so jump to it. 528*795d594fSAndroid Build Coastguard Worker EXPORT_PC 529*795d594fSAndroid Build Coastguard Worker // Fast-path which gets the class from thread-local cache. 530*795d594fSAndroid Build Coastguard Worker% fetch_from_thread_cache("r0", miss_label="2f") 531*795d594fSAndroid Build Coastguard Worker TEST_IF_MARKING 3f 532*795d594fSAndroid Build Coastguard Worker4: 533*795d594fSAndroid Build Coastguard Worker ldr lr, [rSELF, #THREAD_ALLOC_OBJECT_ENTRYPOINT_OFFSET] 534*795d594fSAndroid Build Coastguard Worker blx lr 535*795d594fSAndroid Build Coastguard Worker dmb ishst // need fence for making object's class visible 536*795d594fSAndroid Build Coastguard Worker1: 537*795d594fSAndroid Build Coastguard Worker lsr r1, rINST, #8 // r1 <- A 538*795d594fSAndroid Build Coastguard Worker SET_VREG_OBJECT r0, r1 // fp[A] <- value 539*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 2 540*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip 541*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip 542*795d594fSAndroid Build Coastguard Worker2: 543*795d594fSAndroid Build Coastguard Worker mov r0, rSELF 544*795d594fSAndroid Build Coastguard Worker ldr r1, [sp] 545*795d594fSAndroid Build Coastguard Worker mov r2, rPC 546*795d594fSAndroid Build Coastguard Worker bl nterp_allocate_object 547*795d594fSAndroid Build Coastguard Worker b 1b 548*795d594fSAndroid Build Coastguard Worker3: 549*795d594fSAndroid Build Coastguard Worker bl art_quick_read_barrier_mark_reg00 550*795d594fSAndroid Build Coastguard Worker b 4b 551