%def field(helper=""): TODO %def op_check_cast(): /* * Check to see if a cast from one class to another is allowed. */ /* check-cast vAA, class@BBBB */ EXPORT_PC() FETCH(a0, 1) # a0 <- BBBB GET_OPA(a1) # a1 <- AA EAS2(a1, rFP, a1) # a1 <- &object lw a2, OFF_FP_METHOD(rFP) # a2 <- method move a3, rSELF # a3 <- self JAL(MterpCheckCast) # v0 <- CheckCast(index, &obj, method, self) PREFETCH_INST(2) bnez v0, MterpPossibleException ADVANCE(2) GET_INST_OPCODE(t0) # extract opcode from rINST GOTO_OPCODE(t0) # jump to next instruction %def op_iget(is_object="0", helper="MterpIGetU32"): % field(helper=helper) %def op_iget_boolean(): % op_iget(helper="MterpIGetU8") %def op_iget_boolean_quick(): % op_iget_quick(load="lbu") %def op_iget_byte(): % op_iget(helper="MterpIGetI8") %def op_iget_byte_quick(): % op_iget_quick(load="lb") %def op_iget_char(): % op_iget(helper="MterpIGetU16") %def op_iget_char_quick(): % op_iget_quick(load="lhu") %def op_iget_object(): % op_iget(is_object="1", helper="MterpIGetObj") %def op_iget_object_quick(): /* For: iget-object-quick */ /* op vA, vB, offset@CCCC */ GET_OPB(a2) # a2 <- B FETCH(a1, 1) # a1 <- field byte offset EXPORT_PC() GET_VREG(a0, a2) # a0 <- object we're operating on JAL(artIGetObjectFromMterp) # v0 <- GetObj(obj, offset) lw a3, THREAD_EXCEPTION_OFFSET(rSELF) GET_OPA4(a2) # a2<- A+ PREFETCH_INST(2) # load rINST bnez a3, MterpPossibleException # bail out ADVANCE(2) # advance rPC GET_INST_OPCODE(t0) # extract opcode from rINST SET_VREG_OBJECT_GOTO(v0, a2, t0) # fp[A] <- v0 %def op_iget_quick(load="lw"): /* For: iget-quick, iget-boolean-quick, iget-byte-quick, iget-char-quick, iget-short-quick */ /* op vA, vB, offset@CCCC */ GET_OPB(a2) # a2 <- B GET_VREG(a3, a2) # a3 <- object we're operating on FETCH(a1, 1) # a1 <- field byte offset GET_OPA4(a2) # a2 <- A(+) # check object for null beqz a3, common_errNullObject # object was null addu t0, a3, a1 $load a0, 0(t0) # a0 <- obj.field (8/16/32 bits) FETCH_ADVANCE_INST(2) # advance rPC, load rINST GET_INST_OPCODE(t0) # extract opcode from rINST SET_VREG_GOTO(a0, a2, t0) # fp[A] <- a0 %def op_iget_short(): % op_iget(helper="MterpIGetI16") %def op_iget_short_quick(): % op_iget_quick(load="lh") %def op_iget_wide(): % op_iget(helper="MterpIGetU64") %def op_iget_wide_quick(): /* iget-wide-quick vA, vB, offset@CCCC */ GET_OPB(a2) # a2 <- B GET_VREG(a3, a2) # a3 <- object we're operating on FETCH(a1, 1) # a1 <- field byte offset GET_OPA4(a2) # a2 <- A(+) # check object for null beqz a3, common_errNullObject # object was null addu t0, a3, a1 # t0 <- a3 + a1 LOAD64(a0, a1, t0) # a0 <- obj.field (64 bits, aligned) FETCH_ADVANCE_INST(2) # advance rPC, load rINST GET_INST_OPCODE(t0) # extract opcode from rINST SET_VREG64_GOTO(a0, a1, a2, t0) # fp[A] <- a0/a1 %def op_instance_of(): /* * Check to see if an object reference is an instance of a class. * * Most common situation is a non-null object, being compared against * an already-resolved class. */ /* instance-of vA, vB, class@CCCC */ EXPORT_PC() FETCH(a0, 1) # a0 <- CCCC GET_OPB(a1) # a1 <- B EAS2(a1, rFP, a1) # a1 <- &object lw a2, OFF_FP_METHOD(rFP) # a2 <- method move a3, rSELF # a3 <- self GET_OPA4(rOBJ) # rOBJ <- A+ JAL(MterpInstanceOf) # v0 <- Mterp(index, &obj, method, self) lw a1, THREAD_EXCEPTION_OFFSET(rSELF) PREFETCH_INST(2) # load rINST bnez a1, MterpException ADVANCE(2) # advance rPC GET_INST_OPCODE(t0) # extract opcode from rINST SET_VREG_GOTO(v0, rOBJ, t0) # vA <- v0 %def op_iput(is_object="0", helper="MterpIPutU32"): % field(helper=helper) %def op_iput_boolean(): % op_iput(helper="MterpIPutU8") %def op_iput_boolean_quick(): % op_iput_quick(store="sb") %def op_iput_byte(): % op_iput(helper="MterpIPutI8") %def op_iput_byte_quick(): % op_iput_quick(store="sb") %def op_iput_char(): % op_iput(helper="MterpIPutU16") %def op_iput_char_quick(): % op_iput_quick(store="sh") %def op_iput_object(): % op_iput(is_object="1", helper="MterpIPutObj") %def op_iput_object_quick(): /* For: iput-object-quick */ /* op vA, vB, offset@CCCC */ EXPORT_PC() addu a0, rFP, OFF_FP_SHADOWFRAME move a1, rPC move a2, rINST JAL(MterpIputObjectQuick) beqz v0, MterpException FETCH_ADVANCE_INST(2) # advance rPC, load rINST GET_INST_OPCODE(t0) # extract opcode from rINST GOTO_OPCODE(t0) # jump to next instruction %def op_iput_quick(store="sw"): /* For: iput-quick, iput-object-quick */ /* op vA, vB, offset@CCCC */ GET_OPB(a2) # a2 <- B GET_VREG(a3, a2) # a3 <- fp[B], the object pointer FETCH(a1, 1) # a1 <- field byte offset GET_OPA4(a2) # a2 <- A(+) beqz a3, common_errNullObject # object was null GET_VREG(a0, a2) # a0 <- fp[A] FETCH_ADVANCE_INST(2) # advance rPC, load rINST addu t0, a3, a1 GET_INST_OPCODE(t1) # extract opcode from rINST GET_OPCODE_TARGET(t1) $store a0, 0(t0) # obj.field (8/16/32 bits) <- a0 JR(t1) # jump to next instruction %def op_iput_short(): % op_iput(helper="MterpIPutI16") %def op_iput_short_quick(): % op_iput_quick(store="sh") %def op_iput_wide(): % op_iput(helper="MterpIPutU64") %def op_iput_wide_quick(): /* iput-wide-quick vA, vB, offset@CCCC */ GET_OPA4(a0) # a0 <- A(+) GET_OPB(a1) # a1 <- B GET_VREG(a2, a1) # a2 <- fp[B], the object pointer # check object for null beqz a2, common_errNullObject # object was null EAS2(a3, rFP, a0) # a3 <- &fp[A] LOAD64(a0, a1, a3) # a0/a1 <- fp[A] FETCH(a3, 1) # a3 <- field byte offset FETCH_ADVANCE_INST(2) # advance rPC, load rINST addu a2, a2, a3 # obj.field (64 bits, aligned) <- a0/a1 GET_INST_OPCODE(t0) # extract opcode from rINST GET_OPCODE_TARGET(t0) STORE64(a0, a1, a2) # obj.field (64 bits, aligned) <- a0/a1 JR(t0) # jump to next instruction %def op_new_instance(): /* * Create a new instance of a class. */ /* new-instance vAA, class@BBBB */ EXPORT_PC() addu a0, rFP, OFF_FP_SHADOWFRAME move a1, rSELF move a2, rINST JAL(MterpNewInstance) beqz v0, MterpPossibleException FETCH_ADVANCE_INST(2) # advance rPC, load rINST GET_INST_OPCODE(t0) # extract opcode from rINST GOTO_OPCODE(t0) # jump to next instruction %def op_sget(is_object="0", helper="MterpSGetU32"): % field(helper=helper) %def op_sget_boolean(): % op_sget(helper="MterpSGetU8") %def op_sget_byte(): % op_sget(helper="MterpSGetI8") %def op_sget_char(): % op_sget(helper="MterpSGetU16") %def op_sget_object(): % op_sget(is_object="1", helper="MterpSGetObj") %def op_sget_short(): % op_sget(helper="MterpSGetI16") %def op_sget_wide(): % op_sget(helper="MterpSGetU64") %def op_sput(is_object="0", helper="MterpSPutU32"): % field(helper=helper) %def op_sput_boolean(): % op_sput(helper="MterpSPutU8") %def op_sput_byte(): % op_sput(helper="MterpSPutI8") %def op_sput_char(): % op_sput(helper="MterpSPutU16") %def op_sput_object(): % op_sput(is_object="1", helper="MterpSPutObj") %def op_sput_short(): % op_sput(helper="MterpSPutI16") %def op_sput_wide(): % op_sput(helper="MterpSPutU64")