1 %verify "executed" 2 /* 3 * Store an object into an array. vBB[vCC] <- vAA. 4 * 5 */ 6 /* op vAA, vBB, vCC */ 7 FETCH(a0, 1) # a0 <- CCBB 8 GET_OPA(t1) # t1 <- AA 9 and a2, a0, 255 # a2 <- BB 10 srl a3, a0, 8 # a3 <- CC 11 GET_VREG(rINST, a2) # rINST <- vBB (array object) 12 GET_VREG(a1, a3) # a1 <- vCC (requested index) 13 GET_VREG(rBIX, t1) # rBIX <- vAA 14 # null array object? 15 beqz rINST, common_errNullObject # yes, bail 16 17 LOAD_base_offArrayObject_length(a3, rINST) # a3 <- arrayObj->length 18 EAS2(rOBJ, rINST, a1) # rOBJ <- arrayObj + index*width 19 # compare unsigned index, length 20 bgeu a1, a3, common_errArrayIndex # index >= length, bail 21 /* 22 * On entry: 23 * rINST = vBB (arrayObj) 24 * rBIX = vAA (obj) 25 * rOBJ = offset into array (vBB + vCC * width) 26 */ 27 bnez rBIX, .L${opcode}_checks # yes, skip type checks 28 .L${opcode}_finish: 29 FETCH_ADVANCE_INST(2) # advance rPC, load rINST 30 GET_INST_OPCODE(t0) # extract opcode from rINST 31 sw rBIX, offArrayObject_contents(rOBJ) # vBB[vCC] <- vAA 32 GOTO_OPCODE(t0) # jump to next instruction 33 34 %break 35 .L${opcode}_checks: 36 LOAD_base_offObject_clazz(a0, rBIX) # a0 <- obj->clazz 37 LOAD_base_offObject_clazz(a1, rINST) # a1 <- arrayObj->clazz 38 JAL(dvmCanPutArrayElement) # test object type vs. array type 39 beqz v0, .L${opcode}_throw # okay ? 40 lw a2, offThread_cardTable(rSELF) 41 srl t1, rINST, GC_CARD_SHIFT 42 addu t2, a2, t1 43 sb a2, (t2) 44 b .L${opcode}_finish # yes, skip type checks 45 .L${opcode}_throw: 46 LOAD_base_offObject_clazz(a0, rBIX) # a0 <- obj->clazz 47 LOAD_base_offObject_clazz(a1, rINST) # a1 <- arrayObj->clazz 48 EXPORT_PC() 49 JAL(dvmThrowArrayStoreExceptionIncompatibleElement) 50 b common_exceptionThrown 51