diff options
Diffstat (limited to 'vm/mterp/armv5te/OP_APUT_OBJECT.S')
-rw-r--r-- | vm/mterp/armv5te/OP_APUT_OBJECT.S | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/vm/mterp/armv5te/OP_APUT_OBJECT.S b/vm/mterp/armv5te/OP_APUT_OBJECT.S new file mode 100644 index 0000000..918fcd0 --- /dev/null +++ b/vm/mterp/armv5te/OP_APUT_OBJECT.S @@ -0,0 +1,55 @@ +%verify "executed" + /* + * Store an object into an array. vBB[vCC] <- vAA. + */ + /* op vAA, vBB, vCC */ + FETCH(r0, 1) @ r0<- CCBB + mov r9, rINST, lsr #8 @ r9<- AA + and r2, r0, #255 @ r2<- BB + mov r3, r0, lsr #8 @ r3<- CC + GET_VREG(rINST, r2) @ rINST<- vBB (array object) + GET_VREG(r1, r3) @ r1<- vCC (requested index) + cmp rINST, #0 @ null array object? + GET_VREG(r9, r9) @ r9<- vAA + beq common_errNullObject @ yes, bail + ldr r3, [rINST, #offArrayObject_length] @ r3<- arrayObj->length + add r10, rINST, r1, lsl #2 @ r10<- arrayObj + index*width + cmp r1, r3 @ compare unsigned index, length + bcc .L${opcode}_finish @ we're okay, continue on + b common_errArrayIndex @ index >= length, bail + +%break + /* + * On entry: + * rINST = vBB (arrayObj) + * r9 = vAA (obj) + * r10 = offset into array (vBB + vCC * width) + */ +.L${opcode}_finish: + cmp r9, #0 @ storing null reference? + beq .L${opcode}_skip_check @ yes, skip type checks + ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz + ldr r1, [rINST, #offObject_clazz] @ r1<- arrayObj->clazz + bl dvmCanPutArrayElement @ test object type vs. array type + cmp r0, #0 @ okay? + beq .L${opcode}_throw @ no + mov r1, rINST @ r1<- arrayObj + FETCH_ADVANCE_INST(2) @ advance rPC, load rINST + ldr r2, [rSELF, #offThread_cardTable] @ get biased CT base + add r10, #offArrayObject_contents @ r0<- pointer to slot + GET_INST_OPCODE(ip) @ extract opcode from rINST + str r9, [r10] @ vBB[vCC]<- vAA + strb r2, [r2, r1, lsr #GC_CARD_SHIFT] @ mark card using object head + GOTO_OPCODE(ip) @ jump to next instruction +.L${opcode}_skip_check: + FETCH_ADVANCE_INST(2) @ advance rPC, load rINST + GET_INST_OPCODE(ip) @ extract opcode from rINST + str r9, [r10, #offArrayObject_contents] @ vBB[vCC]<- vAA + GOTO_OPCODE(ip) @ jump to next instruction +.L${opcode}_throw: + @ The types don't match. We need to throw an ArrayStoreException. + ldr r0, [r9, #offObject_clazz] + ldr r1, [rINST, #offObject_clazz] + EXPORT_PC() + bl dvmThrowArrayStoreExceptionIncompatibleElement + b common_exceptionThrown |