Authors: Andreas Krall
Reinhard Grafl
-
- Changes: Christian Thalinger
+ Christian Thalinger
Christian Ullrich
Edwin Steiner
This module generates MIPS machine code for a sequence of
intermediate code commands (ICMDs).
- $Id: codegen.c 5891 2006-11-01 20:19:44Z twisti $
+ $Id: codegen.c 5929 2006-11-06 17:13:40Z twisti $
*/
instruction *iptr;
exception_entry *ex;
u2 currentline;
+ constant_classref *cr;
+ unresolved_class *uc;
methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
unresolved_method *um;
builtintable_entry *bte;
disp = dseg_add_address(cd, &m->class->object.header);
M_ALD(REG_A0, REG_PV, disp);
}
- else {
- M_BEQZ(REG_A0, 0);
- codegen_add_nullpointerexception_ref(cd);
- }
+ else
+ emit_nullpointer_check(cd, REG_A0);
disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
M_ALD(REG_ITMP3, REG_PV, disp);
bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
if (bptr->flags >= BBREACHED) {
-
/* branch resolving */
- {
- branchref *bref;
- for (bref = bptr->branchrefs; bref != NULL; bref = bref->next) {
- gen_resolvebranch(cd->mcodebase + bref->branchpos,
- bref->branchpos,
- bptr->mpc);
- }
- }
+
+ codegen_resolve_branchrefs(cd, bptr);
/* copy interface registers to their destination */
case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
- M_BEQZ(s1, 0);
- codegen_add_nullpointerexception_ref(cd);
- M_NOP;
+ emit_nullpointer_check(cd, s1);
break;
/* constant operations ************************************************/
d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
- constant_classref *cr = iptr->sx.val.c.ref;
-
+ cr = iptr->sx.val.c.ref;
disp = dseg_add_unique_address(cd, cr);
- codegen_addpatchref(cd, PATCHER_aconst, cr, disp);
+ codegen_add_patch_ref(cd, PATCHER_aconst, cr, disp);
- if (opt_showdisassemble) {
+ if (opt_shownops) {
M_NOP; M_NOP;
}
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
- gen_div_check(s2);
+ emit_arithmetic_check(cd, s2);
M_IDIV(s1, s2);
M_MFLO(d);
M_NOP;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
- gen_div_check(s2);
+ emit_arithmetic_check(cd, s2);
M_LDIV(s1, s2);
M_MFLO(d);
M_NOP;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
- gen_div_check(s2);
+ emit_arithmetic_check(cd, s2);
M_IDIV(s1, s2);
M_MFHI(d);
M_NOP;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
- gen_div_check(s2);
+ emit_arithmetic_check(cd, s2);
M_LDIV(s1, s2);
M_MFHI(d);
M_NOP;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
- gen_nullptr_check(s1);
+ emit_nullpointer_check(cd, s1);
M_ILD(d, s1, OFFSET(java_arrayheader, size));
emit_store_dst(jd, iptr, d);
break;
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
+ emit_nullpointer_check(cd, s1);
+ emit_arrayindexoutofbounds_check(cd, s1, s2);
}
M_AADD(s2, s1, REG_ITMP3);
M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray, data[0]));
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
+ emit_nullpointer_check(cd, s1);
+ emit_arrayindexoutofbounds_check(cd, s1, s2);
}
M_AADD(s2, s1, REG_ITMP3);
M_AADD(s2, REG_ITMP3, REG_ITMP3);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
+ emit_nullpointer_check(cd, s1);
+ emit_arrayindexoutofbounds_check(cd, s1, s2);
}
M_AADD(s2, s1, REG_ITMP3);
M_AADD(s2, REG_ITMP3, REG_ITMP3);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
+ emit_nullpointer_check(cd, s1);
+ emit_arrayindexoutofbounds_check(cd, s1, s2);
}
M_ASLL_IMM(s2, 2, REG_ITMP3);
M_AADD(REG_ITMP3, s1, REG_ITMP3);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
+ emit_nullpointer_check(cd, s1);
+ emit_arrayindexoutofbounds_check(cd, s1, s2);
}
M_ASLL_IMM(s2, 3, REG_ITMP3);
M_AADD(REG_ITMP3, s1, REG_ITMP3);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
+ emit_nullpointer_check(cd, s1);
+ emit_arrayindexoutofbounds_check(cd, s1, s2);
}
M_ASLL_IMM(s2, 2, REG_ITMP3);
M_AADD(REG_ITMP3, s1, REG_ITMP3);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
+ emit_nullpointer_check(cd, s1);
+ emit_arrayindexoutofbounds_check(cd, s1, s2);
}
M_ASLL_IMM(s2, 3, REG_ITMP3);
M_AADD(REG_ITMP3, s1, REG_ITMP3);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
+ emit_nullpointer_check(cd, s1);
+ emit_arrayindexoutofbounds_check(cd, s1, s2);
}
M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
M_AADD(REG_ITMP3, s1, REG_ITMP3);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
+ emit_nullpointer_check(cd, s1);
+ emit_arrayindexoutofbounds_check(cd, s1, s2);
}
M_AADD(s2, s1, REG_ITMP1);
s3 = emit_load_s3(jd, iptr, REG_ITMP3);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
+ emit_nullpointer_check(cd, s1);
+ emit_arrayindexoutofbounds_check(cd, s1, s2);
}
M_AADD(s2, s1, REG_ITMP1);
M_AADD(s2, REG_ITMP1, REG_ITMP1);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
+ emit_nullpointer_check(cd, s1);
+ emit_arrayindexoutofbounds_check(cd, s1, s2);
}
M_ASLL_IMM(s2, 2, REG_ITMP2);
M_AADD(REG_ITMP2, s1, REG_ITMP1);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
+ emit_nullpointer_check(cd, s1);
+ emit_arrayindexoutofbounds_check(cd, s1, s2);
}
M_ASLL_IMM(s2, 3, REG_ITMP2);
M_AADD(REG_ITMP2, s1, REG_ITMP1);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
+ emit_nullpointer_check(cd, s1);
+ emit_arrayindexoutofbounds_check(cd, s1, s2);
}
M_ASLL_IMM(s2, 2, REG_ITMP2);
M_AADD(REG_ITMP2, s1, REG_ITMP1);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
+ emit_nullpointer_check(cd, s1);
+ emit_arrayindexoutofbounds_check(cd, s1, s2);
}
M_ASLL_IMM(s2, 3, REG_ITMP2);
M_AADD(REG_ITMP2, s1, REG_ITMP1);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
+ emit_nullpointer_check(cd, s1);
+ emit_arrayindexoutofbounds_check(cd, s1, s2);
}
s3 = emit_load_s3(jd, iptr, REG_ITMP3);
M_JSR(REG_RA, REG_ITMP3);
M_NOP;
- M_BEQZ(REG_RESULT, 0);
- codegen_add_arraystoreexception_ref(cd);
- M_NOP;
+/* M_BEQZ(REG_RESULT, 0); */
+/* codegen_add_arraystoreexception_ref(cd); */
+/* M_NOP; */
+ emit_arraystore_check(cd, REG_RESULT);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
+ emit_nullpointer_check(cd, s1);
+ emit_arrayindexoutofbounds_check(cd, s1, s2);
}
M_AADD(s2, s1, REG_ITMP1);
M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
+ emit_nullpointer_check(cd, s1);
+ emit_arrayindexoutofbounds_check(cd, s1, s2);
}
M_AADD(s2, s1, REG_ITMP1);
M_AADD(s2, REG_ITMP1, REG_ITMP1);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
+ emit_nullpointer_check(cd, s1);
+ emit_arrayindexoutofbounds_check(cd, s1, s2);
}
M_ASLL_IMM(s2, 2, REG_ITMP2);
M_AADD(REG_ITMP2, s1, REG_ITMP1);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
+ emit_nullpointer_check(cd, s1);
+ emit_arrayindexoutofbounds_check(cd, s1, s2);
}
M_ASLL_IMM(s2, 3, REG_ITMP2);
M_AADD(REG_ITMP2, s1, REG_ITMP1);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
+ emit_nullpointer_check(cd, s1);
+ emit_arrayindexoutofbounds_check(cd, s1, s2);
}
M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
M_AADD(REG_ITMP2, s1, REG_ITMP1);
fieldtype = uf->fieldref->parseddesc.fd->type;
disp = dseg_add_unique_address(cd, uf);
- codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
+ codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
- if (opt_showdisassemble) {
+ if (opt_shownops) {
M_NOP; M_NOP;
}
}
disp = dseg_add_address(cd, &(fi->value));
if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
- codegen_addpatchref(cd, PATCHER_clinit, fi->class, disp);
+ codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
- if (opt_showdisassemble) {
+ if (opt_shownops) {
M_NOP; M_NOP;
}
}
fieldtype = uf->fieldref->parseddesc.fd->type;
disp = dseg_add_unique_address(cd, uf);
- codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
+ codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
- if (opt_showdisassemble) {
+ if (opt_shownops) {
M_NOP; M_NOP;
}
}
disp = dseg_add_address(cd, &(fi->value));
if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
- codegen_addpatchref(cd, PATCHER_clinit, fi->class, disp);
+ codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
- if (opt_showdisassemble) {
+ if (opt_shownops) {
M_NOP; M_NOP;
}
}
fieldtype = uf->fieldref->parseddesc.fd->type;
disp = dseg_add_unique_address(cd, uf);
- codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
+ codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
- if (opt_showdisassemble) {
+ if (opt_shownops) {
M_NOP; M_NOP;
}
}
disp = dseg_add_address(cd, &(fi->value));
if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
- codegen_addpatchref(cd, PATCHER_clinit, fi->class, disp);
+ codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
- if (opt_showdisassemble) {
+ if (opt_shownops) {
M_NOP; M_NOP;
}
}
case ICMD_GETFIELD: /* ... ==> ..., value */
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
- gen_nullptr_check(s1);
+ emit_nullpointer_check(cd, s1);
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
uf = iptr->sx.s23.s3.uf;
fieldtype = uf->fieldref->parseddesc.fd->type;
disp = 0;
- codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
+ codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
- if (opt_showdisassemble) {
+ if (opt_shownops) {
M_NOP; M_NOP;
}
}
case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
- gen_nullptr_check(s1);
+ emit_nullpointer_check(cd, s1);
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
uf = iptr->sx.s23.s3.uf;
s2 = emit_load_s2(jd, iptr, REG_FTMP1);
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
- codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
+ codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
- if (opt_showdisassemble) {
+ if (opt_shownops) {
M_NOP; M_NOP;
}
}
case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
- gen_nullptr_check(s1);
+ emit_nullpointer_check(cd, s1);
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
unresolved_field *uf = iptr->sx.s23.s3.uf;
fieldtype = uf->fieldref->parseddesc.fd->type;
- codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
+ codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
- if (opt_showdisassemble) {
+ if (opt_shownops) {
M_NOP; M_NOP;
}
#ifdef ENABLE_VERIFIER
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
- codegen_addpatchref(cd, PATCHER_athrow_areturn,
- iptr->sx.s23.s2.uc, 0);
+ uc = iptr->sx.s23.s2.uc;
+
+ codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
- if (opt_showdisassemble) {
+ if (opt_shownops) {
M_NOP; M_NOP;
}
}
case ICMD_RET: /* ... ==> ... */
M_BR(0);
- codegen_addreference(cd, iptr->dst.block);
+ codegen_add_branch_ref(cd, iptr->dst.block);
M_NOP;
ALIGNCODENOP;
break;
case ICMD_JSR: /* ... ==> ... */
M_BR(0);
- codegen_addreference(cd, iptr->sx.s23.s3.jsrtarget.block);
+ codegen_add_branch_ref(cd, iptr->sx.s23.s3.jsrtarget.block);
M_NOP;
ALIGNCODENOP;
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
M_BEQZ(s1, 0);
- codegen_addreference(cd, iptr->dst.block);
+ codegen_add_branch_ref(cd, iptr->dst.block);
M_NOP;
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
M_BNEZ(s1, 0);
- codegen_addreference(cd, iptr->dst.block);
+ codegen_add_branch_ref(cd, iptr->dst.block);
M_NOP;
break;
ICONST(REG_ITMP2, iptr->sx.val.i);
M_BEQ(s1, REG_ITMP2, 0);
}
- codegen_addreference(cd, iptr->dst.block);
+ codegen_add_branch_ref(cd, iptr->dst.block);
M_NOP;
break;
}
M_BNEZ(REG_ITMP1, 0);
}
- codegen_addreference(cd, iptr->dst.block);
+ codegen_add_branch_ref(cd, iptr->dst.block);
M_NOP;
break;
M_BEQZ(REG_ITMP1, 0);
}
}
- codegen_addreference(cd, iptr->dst.block);
+ codegen_add_branch_ref(cd, iptr->dst.block);
M_NOP;
break;
ICONST(REG_ITMP2, iptr->sx.val.i);
M_BNE(s1, REG_ITMP2, 0);
}
- codegen_addreference(cd, iptr->dst.block);
+ codegen_add_branch_ref(cd, iptr->dst.block);
M_NOP;
break;
M_BNEZ(REG_ITMP1, 0);
}
}
- codegen_addreference(cd, iptr->dst.block);
+ codegen_add_branch_ref(cd, iptr->dst.block);
M_NOP;
break;
}
M_BEQZ(REG_ITMP1, 0);
}
- codegen_addreference(cd, iptr->dst.block);
+ codegen_add_branch_ref(cd, iptr->dst.block);
M_NOP;
break;
LCONST(REG_ITMP2, iptr->sx.val.l);
M_BEQ(s1, REG_ITMP2, 0);
}
- codegen_addreference(cd, iptr->dst.block);
+ codegen_add_branch_ref(cd, iptr->dst.block);
M_NOP;
break;
}
M_BNEZ(REG_ITMP1, 0);
}
- codegen_addreference(cd, iptr->dst.block);
+ codegen_add_branch_ref(cd, iptr->dst.block);
M_NOP;
break;
M_BEQZ(REG_ITMP1, 0);
}
}
- codegen_addreference(cd, iptr->dst.block);
+ codegen_add_branch_ref(cd, iptr->dst.block);
M_NOP;
break;
LCONST(REG_ITMP2, iptr->sx.val.l);
M_BNE(s1, REG_ITMP2, 0);
}
- codegen_addreference(cd, iptr->dst.block);
+ codegen_add_branch_ref(cd, iptr->dst.block);
M_NOP;
break;
M_BNEZ(REG_ITMP1, 0);
}
}
- codegen_addreference(cd, iptr->dst.block);
+ codegen_add_branch_ref(cd, iptr->dst.block);
M_NOP;
break;
}
M_BEQZ(REG_ITMP1, 0);
}
- codegen_addreference(cd, iptr->dst.block);
+ codegen_add_branch_ref(cd, iptr->dst.block);
M_NOP;
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
M_BEQ(s1, s2, 0);
- codegen_addreference(cd, iptr->dst.block);
+ codegen_add_branch_ref(cd, iptr->dst.block);
M_NOP;
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
M_BNE(s1, s2, 0);
- codegen_addreference(cd, iptr->dst.block);
+ codegen_add_branch_ref(cd, iptr->dst.block);
M_NOP;
break;
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
M_CMPLT(s1, s2, REG_ITMP1);
M_BNEZ(REG_ITMP1, 0);
- codegen_addreference(cd, iptr->dst.block);
+ codegen_add_branch_ref(cd, iptr->dst.block);
M_NOP;
break;
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
M_CMPGT(s1, s2, REG_ITMP1);
M_BNEZ(REG_ITMP1, 0);
- codegen_addreference(cd, iptr->dst.block);
+ codegen_add_branch_ref(cd, iptr->dst.block);
M_NOP;
break;
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
M_CMPGT(s1, s2, REG_ITMP1);
M_BEQZ(REG_ITMP1, 0);
- codegen_addreference(cd, iptr->dst.block);
+ codegen_add_branch_ref(cd, iptr->dst.block);
M_NOP;
break;
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
M_CMPLT(s1, s2, REG_ITMP1);
M_BEQZ(REG_ITMP1, 0);
- codegen_addreference(cd, iptr->dst.block);
+ codegen_add_branch_ref(cd, iptr->dst.block);
M_NOP;
break;
#ifdef ENABLE_VERIFIER
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
- codegen_addpatchref(cd, PATCHER_athrow_areturn,
- iptr->sx.s23.s2.uc, 0);
+ uc = iptr->sx.s23.s2.uc;
- if (opt_showdisassemble) {
+ codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
+
+ if (opt_shownops) {
M_NOP; M_NOP;
}
}
M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
M_BEQZ(REG_ITMP2, 0);
- codegen_addreference(cd, table[0].block); /* default target */
+ codegen_add_branch_ref(cd, table[0].block); /* default target */
M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1); /* delay slot*/
/* build jump table top down and use address of lowest entry */
while (--i >= 0) {
ICONST(REG_ITMP2, lookup->value);
M_BEQ(s1, REG_ITMP2, 0);
- codegen_addreference(cd, lookup->target.block);
+ codegen_add_branch_ref(cd, lookup->target.block);
M_NOP;
++lookup;
}
M_BR(0);
- codegen_addreference(cd, iptr->sx.s23.s3.lookupdefault.block);
+ codegen_add_branch_ref(cd, iptr->sx.s23.s3.lookupdefault.block);
M_NOP;
ALIGNCODENOP;
break;
break;
case ICMD_INVOKESPECIAL:
- M_BEQZ(REG_A0, 0);
+/* emit_nullpointer_check(cd, REG_A0); */
+ M_BNEZ(REG_A0, 6);
+ M_NOP;
+
+ M_LUI(REG_ITMP3, 0);
+ M_OR_IMM(REG_ITMP3, 0, REG_ITMP3);
codegen_add_nullpointerexception_ref(cd);
+ M_AADD(REG_PV, REG_ITMP3, REG_ITMP3);
+ M_JMP(REG_ITMP3);
M_NOP;
+
/* fall through */
case ICMD_INVOKESTATIC:
if (lm == NULL) {
disp = dseg_add_unique_address(cd, um);
- codegen_addpatchref(cd, PATCHER_invokestatic_special, um,
- disp);
+ codegen_add_patch_ref(cd, PATCHER_invokestatic_special, um,
+ disp);
- if (opt_showdisassemble) {
+ if (opt_shownops) {
M_NOP; M_NOP;
}
}
break;
case ICMD_INVOKEVIRTUAL:
- gen_nullptr_check(REG_A0);
+ emit_nullpointer_check(cd, REG_A0);
if (lm == NULL) {
- codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
+ codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
- if (opt_showdisassemble) {
+ if (opt_shownops) {
M_NOP; M_NOP;
}
s1 = OFFSET(vftbl_t, table[0]) +
sizeof(methodptr) * lm->vftblindex;
- M_ALD(REG_METHODPTR, REG_A0,
- OFFSET(java_objectheader, vftbl));
+ M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
M_ALD(REG_PV, REG_METHODPTR, s1);
s1 = REG_PV;
break;
case ICMD_INVOKEINTERFACE:
- gen_nullptr_check(REG_A0);
+ emit_nullpointer_check(cd, REG_A0);
if (lm == NULL) {
- codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
+ codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
- if (opt_showdisassemble) {
+ if (opt_shownops) {
M_NOP; M_NOP;
}
s2 = sizeof(methodptr) * (lm - lm->class->methods);
}
- M_ALD(REG_METHODPTR, REG_A0,
- OFFSET(java_objectheader, vftbl));
+ M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
M_ALD(REG_PV, REG_METHODPTR, s2);
s1 = REG_PV;
/* actually only used for ICMD_BUILTIN */
if (INSTRUCTION_MUST_CHECK(iptr)) {
- M_BEQZ(REG_RESULT, 0);
- codegen_add_fillinstacktrace_ref(cd);
- M_NOP;
+ emit_exception_check(cd);
}
/* store return value */
/* calculate interface checkcast code size */
- s2 = 8;
+/* s2 = 3 + 2 + 1 + 2; */
+ s2 = 3 + 7 + 1 + 7;
if (super == NULL)
- s2 += (opt_showdisassemble ? 2 : 0);
+ s2 += (opt_shownops ? 2 : 0);
/* calculate class checkcast code size */
- s3 = 10 /* 10 + (s1 == REG_ITMP1) */;
+/* s3 = 2 + 1 + 4 + 1 + 2 /\* 10 + (s1 == REG_ITMP1) *\/; */
+ s3 = 2 + 1 + 4 + 1 + 7;
if (super == NULL)
- s3 += (opt_showdisassemble ? 2 : 0);
+ s3 += (opt_shownops ? 2 : 0);
/* if class is not resolved, check which code to call */
if (super == NULL) {
- M_BEQZ(s1, 5 + (opt_showdisassemble ? 2 : 0) + s2 + 2 + s3);
+ M_BEQZ(s1, 5 + (opt_shownops ? 2 : 0) + s2 + 2 + s3);
M_NOP;
+ cr = iptr->sx.s23.s3.c.ref;
disp = dseg_add_unique_s4(cd, 0); /* super->flags */
- codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
- iptr->sx.s23.s3.c.ref,
- disp);
+ codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
+ cr, disp);
- if (opt_showdisassemble) {
+ if (opt_shownops) {
M_NOP; M_NOP;
}
if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
if (super == NULL) {
- codegen_addpatchref(cd,
- PATCHER_checkcast_instanceof_interface,
- iptr->sx.s23.s3.c.ref,
- 0);
+ cr = iptr->sx.s23.s3.c.ref;
+
+ codegen_add_patch_ref(cd, PATCHER_checkcast_interface,
+ cr, 0);
- if (opt_showdisassemble) {
+ if (opt_shownops) {
M_NOP; M_NOP;
}
}
}
M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
- M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
+ M_ILD(REG_ITMP3, REG_ITMP2,
+ OFFSET(vftbl_t, interfacetablelength));
M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
- M_BLEZ(REG_ITMP3, 0);
- codegen_add_classcastexception_ref(cd, s1);
- M_NOP;
+ emit_classcast_check(cd, ICMD_IFLE, REG_ITMP3, s1);
+
M_ALD(REG_ITMP3, REG_ITMP2,
OFFSET(vftbl_t, interfacetable[0]) -
superindex * sizeof(methodptr*));
- M_BEQZ(REG_ITMP3, 0);
- codegen_add_classcastexception_ref(cd, s1);
- M_NOP;
+ emit_classcast_check(cd, ICMD_IFEQ, REG_ITMP3, s1);
if (super == NULL) {
M_BR(1 + s3);
if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
if (super == NULL) {
+ cr = iptr->sx.s23.s3.c.ref;
disp = dseg_add_unique_address(cd, NULL);
- codegen_addpatchref(cd,
- PATCHER_checkcast_instanceof_class,
- iptr->sx.s23.s3.c.ref,
- disp);
+ codegen_add_patch_ref(cd,
+ PATCHER_checkcast_instanceof_class,
+ cr, disp);
- if (opt_showdisassemble) {
+ if (opt_shownops) {
M_NOP; M_NOP;
}
}
#endif
/* } */
M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3);
- M_BNEZ(REG_ITMP3, 0);
- codegen_add_classcastexception_ref(cd, s1);
- M_NOP;
+ emit_classcast_check(cd, ICMD_IFNE, REG_ITMP3, s1);
}
d = codegen_reg_of_dst(jd, iptr, s1);
M_INTMOVE(s1, REG_A0);
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
+ cr = iptr->sx.s23.s3.c.ref;
disp = dseg_add_unique_address(cd, NULL);
- codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast,
- iptr->sx.s23.s3.c.ref,
- disp);
+ codegen_add_patch_ref(cd, PATCHER_builtin_arraycheckcast,
+ cr, disp);
- if (opt_showdisassemble) {
+ if (opt_shownops) {
M_NOP; M_NOP;
}
}
M_NOP;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
- M_BEQZ(REG_RESULT, 0);
- codegen_add_classcastexception_ref(cd, s1);
- M_NOP;
+ emit_classcast_check(cd, ICMD_IFEQ, REG_RESULT, s1);
d = codegen_reg_of_dst(jd, iptr, s1);
}
s2 = 7;
if (super == NULL)
- s2 += (opt_showdisassemble ? 2 : 0);
+ s2 += (opt_shownops ? 2 : 0);
/* calculate class instanceof code size */
s3 = 8;
if (super == NULL)
- s3 += (opt_showdisassemble ? 2 : 0);
+ s3 += (opt_shownops ? 2 : 0);
M_CLR(d);
/* if class is not resolved, check which code to call */
if (super == NULL) {
- M_BEQZ(s1, 5 + (opt_showdisassemble ? 2 : 0) + s2 + 2 + s3);
+ M_BEQZ(s1, 5 + (opt_shownops ? 2 : 0) + s2 + 2 + s3);
M_NOP;
+ cr = iptr->sx.s23.s3.c.ref;
disp = dseg_add_unique_s4(cd, 0); /* super->flags */
- codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
- iptr->sx.s23.s3.c.ref, disp);
+ codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
+ cr, disp);
- if (opt_showdisassemble) {
+ if (opt_shownops) {
M_NOP; M_NOP;
}
if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
if (super == NULL) {
- codegen_addpatchref(cd,
- PATCHER_checkcast_instanceof_interface,
- iptr->sx.s23.s3.c.ref, 0);
+ cr = iptr->sx.s23.s3.c.ref;
+
+ codegen_add_patch_ref(cd, PATCHER_instanceof_interface,
+ cr, 0);
- if (opt_showdisassemble) {
+ if (opt_shownops) {
M_NOP; M_NOP;
}
}
}
M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
- M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
+ M_ILD(REG_ITMP3, REG_ITMP1,
+ OFFSET(vftbl_t, interfacetablelength));
M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
M_BLEZ(REG_ITMP3, 3);
M_NOP;
if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
if (super == NULL) {
+ cr = iptr->sx.s23.s3.c.ref;
disp = dseg_add_unique_address(cd, NULL);
- codegen_addpatchref(cd, PATCHER_checkcast_instanceof_class,
- iptr->sx.s23.s3.c.ref,
- disp);
+ codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_class,
+ cr, disp);
- if (opt_showdisassemble) {
+ if (opt_shownops) {
M_NOP; M_NOP;
}
}
/* is patcher function set? */
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
+ cr = iptr->sx.s23.s3.c.ref;
disp = dseg_add_unique_address(cd, NULL);
- codegen_addpatchref(cd, PATCHER_builtin_multianewarray,
- iptr->sx.s23.s3.c.ref, disp);
+ codegen_add_patch_ref(cd, PATCHER_builtin_multianewarray,
+ cr, disp);
- if (opt_showdisassemble) {
+ if (opt_shownops) {
M_NOP; M_NOP;
}
}
/* check for exception before result assignment */
- M_BEQZ(REG_RESULT, 0);
- codegen_add_fillinstacktrace_ref(cd);
- M_NOP;
+ emit_exception_check(cd);
d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
M_INTMOVE(REG_RESULT, d);
#if !defined(WITH_STATIC_CLASSPATH)
if (f == NULL) {
- codegen_addpatchref(cd, PATCHER_resolve_native, m, funcdisp);
+ codegen_add_patch_ref(cd, PATCHER_resolve_native, m, funcdisp);
- if (opt_showdisassemble) {
+ if (opt_shownops) {
M_NOP; M_NOP;
}
}
#endif
#include "vm/exceptions.h"
+#include "vm/options.h"
#include "vm/stringlocal.h" /* XXX for gen_resolvebranch */
#include "vm/jit/abi-asm.h"
#include "vm/jit/asmpart.h"
}
+/* emit_arithmetic_check *******************************************************
+
+ Emit an ArithmeticException check.
+
+*******************************************************************************/
+
+void emit_arithmetic_check(codegendata *cd, s4 reg)
+{
+#if 0
+ M_BEQZ(reg, 0);
+ codegen_add_arithmeticexception_ref(cd);
+ M_NOP;
+#else
+ M_BNEZ(reg, 6);
+ M_NOP;
+
+ M_LUI(REG_ITMP3, 0);
+ M_OR_IMM(REG_ITMP3, 0, REG_ITMP3);
+ codegen_add_arithmeticexception_ref(cd);
+ M_AADD(REG_PV, REG_ITMP3, REG_ITMP3);
+ M_JMP(REG_ITMP3);
+ M_NOP;
+#endif
+}
+
+
+/* emit_arrayindexoutofbounds_check ********************************************
+
+ Emit an ArrayIndexOutOfBoundsException check.
+
+*******************************************************************************/
+
+void emit_arrayindexoutofbounds_check(codegendata *cd, s4 s1, s4 s2)
+{
+ if (checkbounds) {
+ M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));
+ M_CMPULT(s2, REG_ITMP3, REG_ITMP3);
+
+#if 0
+ M_BEQZ(REG_ITMP3, 0);
+ codegen_add_arrayindexoutofboundsexception_ref(cd, s2);
+ M_NOP;
+#else
+ M_BNEZ(REG_ITMP3, 6);
+ M_NOP;
+
+ M_LUI(REG_ITMP3, 0);
+ M_OR_IMM(REG_ITMP3, 0, REG_ITMP3);
+ codegen_add_arrayindexoutofboundsexception_ref(cd, s2);
+ M_AADD(REG_PV, REG_ITMP3, REG_ITMP3);
+ M_JMP(REG_ITMP3);
+ M_NOP;
+#endif
+ }
+}
+
+
+/* emit_arraystore_check *******************************************************
+
+ Emit an ArrayStoreException check.
+
+*******************************************************************************/
+
+void emit_arraystore_check(codegendata *cd, s4 reg)
+{
+#if 0
+ M_BEQZ(reg, 0);
+ codegen_add_arraystoreexception_ref(cd);
+ M_NOP;
+#else
+ M_BNEZ(reg, 6);
+ M_NOP;
+
+ M_LUI(REG_ITMP3, 0);
+ M_OR_IMM(REG_ITMP3, 0, REG_ITMP3);
+ codegen_add_arraystoreexception_ref(cd);
+ M_AADD(REG_PV, REG_ITMP3, REG_ITMP3);
+ M_JMP(REG_ITMP3);
+ M_NOP;
+#endif
+}
+
+
+/* emit_classcast_check ********************************************************
+
+ Emit a ClassCastException check.
+
+*******************************************************************************/
+
+void emit_classcast_check(codegendata *cd, s4 condition, s4 reg, s4 s1)
+{
+#if 0
+ M_BNEZ(reg, 0);
+ codegen_add_classcastexception_ref(cd, s1);
+ M_NOP;
+#else
+ switch (condition) {
+ case ICMD_IFEQ:
+ M_BNEZ(reg, 6);
+ break;
+
+ case ICMD_IFNE:
+ M_BEQZ(reg, 6);
+ break;
+
+ case ICMD_IFLE:
+ M_BGTZ(reg, 6);
+ break;
+
+ default:
+ vm_abort("emit_classcast_check: condition %d not found", condition);
+ }
+
+ M_NOP;
+
+ M_LUI(REG_ITMP3, 0);
+ M_OR_IMM(REG_ITMP3, 0, REG_ITMP3);
+ codegen_add_classcastexception_ref(cd, s1);
+ M_AADD(REG_PV, REG_ITMP3, REG_ITMP3);
+ M_JMP(REG_ITMP3);
+ M_NOP;
+#endif
+}
+
+
+/* emit_nullpointer_check ******************************************************
+
+ Emit a NullPointerException check.
+
+*******************************************************************************/
+
+void emit_nullpointer_check(codegendata *cd, s4 reg)
+{
+ if (checknull) {
+#if 0
+ M_BEQZ(reg, 0);
+ codegen_add_nullpointerexception_ref(cd);
+ M_NOP;
+#else
+ M_BNEZ(reg, 6);
+ M_NOP;
+
+ M_LUI(REG_ITMP3, 0);
+ M_OR_IMM(REG_ITMP3, 0, REG_ITMP3);
+ codegen_add_nullpointerexception_ref(cd);
+ M_AADD(REG_PV, REG_ITMP3, REG_ITMP3);
+ M_JMP(REG_ITMP3);
+ M_NOP;
+#endif
+ }
+}
+
+
+/* emit_exception_check ********************************************************
+
+ Emit an Exception check.
+
+*******************************************************************************/
+
+void emit_exception_check(codegendata *cd)
+{
+#if 0
+ M_BEQZ(REG_RESULT, 0);
+ codegen_add_fillinstacktrace_ref(cd);
+ M_NOP;
+#else
+ M_BNEZ(REG_RESULT, 6);
+ M_NOP;
+
+ M_LUI(REG_ITMP3, 0);
+ M_OR_IMM(REG_ITMP3, 0, REG_ITMP3);
+ codegen_add_fillinstacktrace_ref(cd);
+ M_AADD(REG_PV, REG_ITMP3, REG_ITMP3);
+ M_JMP(REG_ITMP3);
+ M_NOP;
+#endif
+}
+
+
/* emit_exception_stubs ********************************************************
Generates the code for the exception stubs.
{
codegendata *cd;
registerdata *rd;
- exceptionref *eref;
+ exceptionref *er;
+ s4 branchmpc;
+ s4 targetmpc;
s4 targetdisp;
s4 disp;
targetdisp = 0;
- for (eref = cd->exceptionrefs; eref != NULL; eref = eref->next) {
- gen_resolvebranch(cd->mcodebase + eref->branchpos,
- eref->branchpos, cd->mcodeptr - cd->mcodebase);
+ for (er = cd->exceptionrefs; er != NULL; er = er->next) {
+ /* back-patch the branch to this exception code */
+
+ branchmpc = er->branchpos;
+ targetmpc = cd->mcodeptr - cd->mcodebase;
+
+ md_codegen_patch_branch(cd, branchmpc, targetmpc);
MCODECHECK(100);
ArrayIndexOutOfBoundsException. If so, move index register
into REG_ITMP1. */
- if (eref->reg != -1)
- M_MOV(eref->reg, REG_ITMP1);
+ if (er->reg != -1)
+ M_MOV(er->reg, REG_ITMP1);
/* calcuate exception address */
- M_LDA(REG_ITMP2_XPC, REG_PV, eref->branchpos - 4);
+ M_LDA(REG_ITMP2_XPC, REG_PV, er->branchpos - 4);
/* move function to call into REG_ITMP3 */
- disp = dseg_add_functionptr(cd, eref->function);
+ disp = dseg_add_functionptr(cd, er->function);
M_ALD(REG_ITMP3, REG_PV, disp);
if (targetdisp == 0) {
targetdisp = ((u4 *) cd->mcodeptr) - ((u4 *) cd->mcodebase);
- M_MOV(REG_PV, rd->argintregs[0]);
- M_MOV(REG_SP, rd->argintregs[1]);
+ M_MOV(REG_PV, REG_A0);
+ M_MOV(REG_SP, REG_A1);
if (jd->isleafmethod)
- M_MOV(REG_RA, rd->argintregs[2]);
+ M_MOV(REG_RA, REG_A2);
else
- M_ALD(rd->argintregs[2], REG_SP, (cd->stackframesize - 1) * 8);
+ M_ALD(REG_A2, REG_SP, (cd->stackframesize - 1) * 8);
- M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
- M_MOV(REG_ITMP1, rd->argintregs[4]);
+ M_MOV(REG_ITMP2_XPC, REG_A3);
+ M_MOV(REG_ITMP1, REG_A4);
M_ASUB_IMM(REG_SP, 2 * 8, REG_SP);
M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
void emit_patcher_stubs(jitdata *jd)
{
codegendata *cd;
- patchref *pref;
+ patchref *pr;
u4 mcode[2];
u1 *savedmcodeptr;
u1 *tmpmcodeptr;
targetdisp = 0;
- for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
+/* for (pr = list_first_unsynced(cd->patchrefs); pr != NULL; */
+/* pr = list_next_unsynced(cd->patchrefs, pr)) { */
+ for (pr = cd->patchrefs; pr != NULL; pr = pr->next) {
/* check code segment size */
MCODECHECK(100);
/* Get machine code which is patched back in later. The
call is 2 instruction words long. */
- tmpmcodeptr = (u1 *) (cd->mcodebase + pref->branchpos);
+ tmpmcodeptr = (u1 *) (cd->mcodebase + pr->branchpos);
/* We use 2 loads here as an unaligned 8-byte read on 64-bit
MIPS causes a SIGSEGV and using the same code for both
/* calculate return address and move it onto the stack */
- M_LDA(REG_ITMP3, REG_PV, pref->branchpos);
+ M_LDA(REG_ITMP3, REG_PV, pr->branchpos);
M_AST(REG_ITMP3, REG_SP, 5 * 8);
/* move pointer to java_objectheader onto stack */
/* move class/method/field reference onto stack */
- disp = dseg_add_address(cd, pref->ref);
+ disp = dseg_add_address(cd, pr->ref);
M_ALD(REG_ITMP3, REG_PV, disp);
M_AST(REG_ITMP3, REG_SP, 2 * 8);
/* move data segment displacement onto stack */
- disp = dseg_add_s4(cd, pref->disp);
+ disp = dseg_add_s4(cd, pr->disp);
M_ILD(REG_ITMP3, REG_PV, disp);
M_IST(REG_ITMP3, REG_SP, 1 * 8);
/* move patcher function pointer onto stack */
- disp = dseg_add_address(cd, pref->patcher);
+ disp = dseg_add_address(cd, pr->patcher);
M_ALD(REG_ITMP3, REG_PV, disp);
M_AST(REG_ITMP3, REG_SP, 0 * 8);