Changes: Joseph Wenninger
Christian Ullrich
- $Id: codegen.c 3567 2005-11-04 16:33:20Z twisti $
+ $Id: codegen.c 3949 2005-12-20 20:39:09Z edwin $
*/
#include "vm/global.h"
#include "vm/loader.h"
#include "vm/stringlocal.h"
-#include "vm/tables.h"
#include "vm/utf8.h"
#include "vm/jit/asmpart.h"
#include "vm/jit/jit.h"
*******************************************************************************/
-void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
+bool codegen(methodinfo *m, codegendata *cd, registerdata *rd)
{
s4 len, s1, s2, s3, d, off;
ptrint a;
/* REG_RES Register usage: see lsra.inc icmd_uses_tmp */
/* EAX: NO ECX: NO EDX: NO */
+
d = reg_of_var(rd, iptr->dst, REG_ITMP1);
if (iptr->dst->flags & INMEMORY) {
- i386_mov_imm_membase(cd, iptr->val.i, REG_SP, iptr->dst->regoff * 4);
+ M_IST_IMM(iptr->val.i, REG_SP, iptr->dst->regoff * 4);
} else {
if (iptr->val.i == 0) {
- i386_alu_reg_reg(cd, ALU_XOR, d, d);
+ M_CLR(d);
} else {
- i386_mov_imm_reg(cd, iptr->val.i, d);
+ M_MOV_IMM(iptr->val.i, d);
}
}
break;
/* REG_RES Register usage: see lsra.inc icmd_uses_tmp */
/* EAX: NO ECX: NO EDX: NO */
+
d = reg_of_var(rd, iptr->dst, REG_ITMP1);
if (iptr->dst->flags & INMEMORY) {
- i386_mov_imm_membase(cd, iptr->val.l, REG_SP, iptr->dst->regoff * 4);
- i386_mov_imm_membase(cd, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 4 + 4);
+ M_IST_IMM(iptr->val.l, REG_SP, iptr->dst->regoff * 4);
+ M_IST_IMM(iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 4 + 4);
} else {
log_text("LCONST: longs have to be in memory");
case ICMD_FCONST: /* ... ==> ..., constant */
/* op1 = 0, val.f = constant */
+
/* REG_RES Register usage: see lsra.inc icmd_uses_tmp */
/* EAX: YES ECX: NO EDX: NO */
case ICMD_DCONST: /* ... ==> ..., constant */
/* op1 = 0, val.d = constant */
+
/* REG_RES Register usage: see lsra.inc icmd_uses_tmp */
/* EAX: YES ECX: NO EDX: NO */
case ICMD_ACONST: /* ... ==> ..., constant */
/* op1 = 0, val.a = constant */
+
/* REG_RES Register usage: see lsra.inc icmd_uses_tmp */
/* EAX: YES ECX: NO EDX: NO */
d = reg_of_var(rd, iptr->dst, REG_ITMP1);
- if (iptr->dst->flags & INMEMORY) {
- i386_mov_imm_membase(cd, (s4) iptr->val.a, REG_SP, iptr->dst->regoff * 4);
+
+ if ((iptr->target != NULL) && (iptr->val.a == NULL)) {
+ codegen_addpatchref(cd, cd->mcodeptr,
+ PATCHER_aconst,
+ (unresolved_class *) iptr->target, 0);
+
+ if (opt_showdisassemble) {
+ M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
+ }
+
+ M_MOV_IMM((ptrint) iptr->val.a, d);
+ store_reg_to_var_int(iptr->dst, d);
} else {
- if ((s4) iptr->val.a == 0) {
- i386_alu_reg_reg(cd, ALU_XOR, d, d);
+ if (iptr->dst->flags & INMEMORY) {
+ M_AST_IMM((ptrint) iptr->val.a, REG_SP, iptr->dst->regoff * 4);
} else {
- i386_mov_imm_reg(cd, (s4) iptr->val.a, d);
+ if ((ptrint) iptr->val.a == 0) {
+ M_CLR(d);
+ } else {
+ M_MOV_IMM((ptrint) iptr->val.a, d);
+ }
}
}
break;
M_COPY(src->prev, iptr->dst->prev);
M_COPY(src->prev->prev, iptr->dst->prev->prev);
M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
- M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev);
+ M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev);
break;
case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
break;
case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
+
/* REG_RES Register usage: see icmd_uses_reg_res.inc */
/* EAX: S|YES ECX: S|YES EDX: S|YES OUTPUT: REG_NULL */
var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
var_to_reg_int(s2, src->prev, REG_ITMP2);
-/* if (iptr->op1 == 0) { */
+ if (iptr->op1 == 0) {
gen_nullptr_check(s1);
gen_bound_check;
-/* } */
+ }
var_to_reg_int(s3, src, REG_ITMP3);
- bte = iptr->val.a;
-
M_AST(s1, REG_SP, 0 * 4);
M_AST(s3, REG_SP, 1 * 4);
- M_MOV_IMM((ptrint) bte->fp, REG_ITMP1);
+ M_MOV_IMM((ptrint) BUILTIN_canstore, REG_ITMP1);
M_CALL(REG_ITMP1);
M_TEST(REG_RESULT);
M_BEQ(0);
} else {
fieldinfo *fi = iptr->val.a;
- if (!fi->class->initialized) {
+ if (!(fi->class->state & CLASS_INITIALIZED)) {
codegen_addpatchref(cd, cd->mcodeptr,
PATCHER_clinit, fi->class, 0);
} else {
fieldinfo *fi = iptr->val.a;
- if (!fi->class->initialized) {
+ if (!(fi->class->state & CLASS_INITIALIZED)) {
codegen_addpatchref(cd, cd->mcodeptr,
PATCHER_clinit, fi->class, 0);
} else {
fieldinfo *fi = iptr[1].val.a;
- if (!fi->class->initialized) {
+ if (!(fi->class->state & CLASS_INITIALIZED)) {
codegen_addpatchref(cd, cd->mcodeptr,
PATCHER_clinit, fi->class, 0);
var_to_reg_int(s1, src, REG_ITMP1);
M_INTMOVE(s1, REG_ITMP1_XPTR);
+#ifdef ENABLE_VERIFIER
if (iptr->val.a) {
codegen_addpatchref(cd, cd->mcodeptr,
PATCHER_athrow_areturn,
M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
}
}
+#endif /* ENABLE_VERIFIER */
M_CALL_IMM(0); /* passing exception pc */
M_POP(REG_ITMP2_XPC);
var_to_reg_int(s1, src, REG_RESULT);
M_INTMOVE(s1, REG_RESULT);
+#ifdef ENABLE_VERIFIER
if (iptr->val.a) {
codegen_addpatchref(cd, cd->mcodeptr,
PATCHER_athrow_areturn,
M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
}
}
+#endif /* ENABLE_VERIFIER */
goto nowperformreturn;
case ICMD_FRETURN: /* ..., retvalue ==> ... */
break;
case ICMD_FRETURN:
- i386_fsts_membase(cd, REG_SP, rd->memuse * 4);
+ i386_fstps_membase(cd, REG_SP, rd->memuse * 4);
break;
case ICMD_DRETURN:
- i386_fstl_membase(cd, REG_SP, rd->memuse * 4);
+ i386_fstpl_membase(cd, REG_SP, rd->memuse * 4);
break;
}
M_AST(REG_ITMP2, REG_SP, 0);
- i386_mov_imm_reg(cd, (ptrint) BUILTIN_monitorexit, REG_ITMP1);
- i386_call_reg(cd, REG_ITMP1);
+ M_MOV_IMM((ptrint) BUILTIN_monitorexit, REG_ITMP1);
+ M_CALL(REG_ITMP1);
/* and now restore the proper return value */
switch (iptr->opc) {
case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
case ICMD_INVOKEINTERFACE:
+
/* REG_RES Register usage: see icmd_uses_reg_res.inc */
- /* EAX: S|YES ECX: YES EDX: YES OUTPUT: EAX*/
+ /* EAX: S|YES ECX: YES EDX: YES OUTPUT: EAX */
lm = iptr->val.a;
- if (lm)
- md = lm->parseddesc;
- else {
+ if (lm == NULL) {
unresolved_method *um = iptr->target;
md = um->methodref->parseddesc.md;
+ } else {
+ md = lm->parseddesc;
}
gen_method:
switch (iptr->opc) {
case ICMD_BUILTIN:
- if (iptr->target) {
- codegen_addpatchref(cd, cd->mcodeptr, bte->fp,
- iptr->target, 0);
-
- if (opt_showdisassemble) {
- M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
- }
-
- a = 0;
-
- } else {
- a = (ptrint) bte->fp;
- }
-
+ a = (ptrint) bte->fp;
d = md->returntype.type;
M_MOV_IMM(a, REG_ITMP1);
/* fall through */
case ICMD_INVOKESTATIC:
- if (!lm) {
+ if (lm == NULL) {
unresolved_method *um = iptr->target;
codegen_addpatchref(cd, cd->mcodeptr,
break;
case ICMD_INVOKEVIRTUAL:
- i386_mov_membase_reg(cd, REG_SP, 0, REG_ITMP1);
+ M_ALD(REG_ITMP1, REG_SP, 0 * 4);
gen_nullptr_check(REG_ITMP1);
- if (!lm) {
+ if (lm == NULL) {
unresolved_method *um = iptr->target;
codegen_addpatchref(cd, cd->mcodeptr,
M_ALD(REG_ITMP1, REG_SP, 0 * 4);
gen_nullptr_check(REG_ITMP1);
- if (!lm) {
+ if (lm == NULL) {
unresolved_method *um = iptr->target;
codegen_addpatchref(cd, cd->mcodeptr,
case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
- /* REG_RES Register usage: see icmd_uses_reg_res.inc */
- /* EAX: YES ECX: I|YES EDX: I|YES OUTPUT: REG_NULL*/
-
/* op1: 0 == array, 1 == class */
/* val.a: (classinfo*) superclass */
+ /* REG_RES Register usage: see icmd_uses_reg_res.inc */
+ /* EAX: YES ECX: I|YES EDX: I|YES OUTPUT: REG_NULL */
+
/* superclass is an interface:
*
* OK if ((sub == NULL) ||
* super->vftbl->diffval));
*/
- {
- classinfo *super;
- vftbl_t *supervftbl;
- s4 superindex;
+ if (iptr->op1 == 1) {
+ /* object type cast-check */
- super = (classinfo *) iptr->val.a;
+ classinfo *super;
+ vftbl_t *supervftbl;
+ s4 superindex;
- if (!super) {
- superindex = 0;
- supervftbl = NULL;
+ super = (classinfo *) iptr->val.a;
- } else {
- superindex = super->index;
- supervftbl = super->vftbl;
- }
+ if (!super) {
+ superindex = 0;
+ supervftbl = NULL;
+
+ } else {
+ superindex = super->index;
+ supervftbl = super->vftbl;
+ }
#if defined(USE_THREADS) && defined(NATIVE_THREADS)
- codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
+ codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
#endif
- var_to_reg_int(s1, src, REG_ITMP1);
+ var_to_reg_int(s1, src, REG_ITMP1);
- /* calculate interface checkcast code size */
+ /* calculate interface checkcast code size */
- s2 = 2; /* mov_membase_reg */
- CALCOFFSETBYTES(s2, s1, OFFSET(java_objectheader, vftbl));
+ s2 = 2; /* mov_membase_reg */
+ CALCOFFSETBYTES(s2, s1, OFFSET(java_objectheader, vftbl));
- s2 += (2 + 4 /* mov_membase32_reg */ + 2 + 4 /* sub imm32 */ +
- 2 /* test */ + 6 /* jcc */ + 2 + 4 /* mov_membase32_reg */ +
- 2 /* test */ + 6 /* jcc */);
+ s2 += (2 + 4 /* mov_membase32_reg */ + 2 + 4 /* sub imm32 */ +
+ 2 /* test */ + 6 /* jcc */ + 2 + 4 /* mov_membase32_reg */ +
+ 2 /* test */ + 6 /* jcc */);
- if (!super)
- s2 += (opt_showdisassemble ? 5 : 0);
+ if (!super)
+ s2 += (opt_showdisassemble ? 5 : 0);
- /* calculate class checkcast code size */
+ /* calculate class checkcast code size */
- s3 = 2; /* mov_membase_reg */
- CALCOFFSETBYTES(s3, s1, OFFSET(java_objectheader, vftbl));
+ s3 = 2; /* mov_membase_reg */
+ CALCOFFSETBYTES(s3, s1, OFFSET(java_objectheader, vftbl));
- s3 += 5 /* mov_imm_reg */ + 2 + 4 /* mov_membase32_reg */;
+ s3 += 5 /* mov_imm_reg */ + 2 + 4 /* mov_membase32_reg */;
#if 0
- if (s1 != REG_ITMP1) {
- a += 2;
- CALCOFFSETBYTES(a, REG_ITMP3, OFFSET(vftbl_t, baseval));
+ if (s1 != REG_ITMP1) {
+ a += 2;
+ CALCOFFSETBYTES(a, REG_ITMP3, OFFSET(vftbl_t, baseval));
- a += 2;
- CALCOFFSETBYTES(a, REG_ITMP3, OFFSET(vftbl_t, diffval));
+ a += 2;
+ CALCOFFSETBYTES(a, REG_ITMP3, OFFSET(vftbl_t, diffval));
- a += 2;
+ a += 2;
- } else
+ } else
#endif
- {
- s3 += (2 + 4 /* mov_membase32_reg */ + 2 /* sub */ +
- 5 /* mov_imm_reg */ + 2 /* mov_membase_reg */);
- CALCOFFSETBYTES(s3, REG_ITMP3, OFFSET(vftbl_t, diffval));
- }
-
- s3 += 2 /* cmp */ + 6 /* jcc */;
-
- if (!super)
- s3 += (opt_showdisassemble ? 5 : 0);
-
- /* if class is not resolved, check which code to call */
-
- if (!super) {
- i386_test_reg_reg(cd, s1, s1);
- i386_jcc(cd, I386_CC_Z, 5 + (opt_showdisassemble ? 5 : 0) + 6 + 6 + s2 + 5 + s3);
-
- codegen_addpatchref(cd, cd->mcodeptr,
- PATCHER_checkcast_instanceof_flags,
- (constant_classref *) iptr->target, 0);
+ {
+ s3 += (2 + 4 /* mov_membase32_reg */ + 2 /* sub */ +
+ 5 /* mov_imm_reg */ + 2 /* mov_membase_reg */);
+ CALCOFFSETBYTES(s3, REG_ITMP3, OFFSET(vftbl_t, diffval));
+ }
- if (opt_showdisassemble) {
- M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
- }
+ s3 += 2 /* cmp */ + 6 /* jcc */;
- i386_mov_imm_reg(cd, 0, REG_ITMP2); /* super->flags */
- i386_alu_imm_reg(cd, ALU_AND, ACC_INTERFACE, REG_ITMP2);
- i386_jcc(cd, I386_CC_Z, s2 + 5);
- }
+ if (!super)
+ s3 += (opt_showdisassemble ? 5 : 0);
- /* interface checkcast code */
+ /* if class is not resolved, check which code to call */
- if (!super || (super->flags & ACC_INTERFACE)) {
- if (super) {
+ if (!super) {
i386_test_reg_reg(cd, s1, s1);
- i386_jcc(cd, I386_CC_Z, s2);
- }
+ i386_jcc(cd, I386_CC_Z, 5 + (opt_showdisassemble ? 5 : 0) + 6 + 6 + s2 + 5 + s3);
- i386_mov_membase_reg(cd, s1,
- OFFSET(java_objectheader, vftbl),
- REG_ITMP2);
-
- if (!super) {
codegen_addpatchref(cd, cd->mcodeptr,
- PATCHER_checkcast_instanceof_interface,
+ PATCHER_checkcast_instanceof_flags,
(constant_classref *) iptr->target, 0);
if (opt_showdisassemble) {
M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
}
+
+ i386_mov_imm_reg(cd, 0, REG_ITMP2); /* super->flags */
+ i386_alu_imm_reg(cd, ALU_AND, ACC_INTERFACE, REG_ITMP2);
+ i386_jcc(cd, I386_CC_Z, s2 + 5);
}
- i386_mov_membase32_reg(cd, REG_ITMP2,
- OFFSET(vftbl_t, interfacetablelength),
- REG_ITMP3);
- i386_alu_imm32_reg(cd, ALU_SUB, superindex, REG_ITMP3);
- i386_test_reg_reg(cd, REG_ITMP3, REG_ITMP3);
- i386_jcc(cd, I386_CC_LE, 0);
- codegen_addxcastrefs(cd, cd->mcodeptr);
- i386_mov_membase32_reg(cd, REG_ITMP2,
- OFFSET(vftbl_t, interfacetable[0]) -
- superindex * sizeof(methodptr*),
- REG_ITMP3);
- i386_test_reg_reg(cd, REG_ITMP3, REG_ITMP3);
- i386_jcc(cd, I386_CC_E, 0);
- codegen_addxcastrefs(cd, cd->mcodeptr);
+ /* interface checkcast code */
- if (!super)
- i386_jmp_imm(cd, s3);
- }
+ if (!super || (super->flags & ACC_INTERFACE)) {
+ if (super) {
+ i386_test_reg_reg(cd, s1, s1);
+ i386_jcc(cd, I386_CC_Z, s2);
+ }
- /* class checkcast code */
+ i386_mov_membase_reg(cd, s1,
+ OFFSET(java_objectheader, vftbl),
+ REG_ITMP2);
- if (!super || !(super->flags & ACC_INTERFACE)) {
- if (super) {
- i386_test_reg_reg(cd, s1, s1);
- i386_jcc(cd, I386_CC_Z, s3);
+ if (!super) {
+ codegen_addpatchref(cd, cd->mcodeptr,
+ PATCHER_checkcast_instanceof_interface,
+ (constant_classref *) iptr->target, 0);
+
+ if (opt_showdisassemble) {
+ M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
+ }
+ }
+
+ i386_mov_membase32_reg(cd, REG_ITMP2,
+ OFFSET(vftbl_t, interfacetablelength),
+ REG_ITMP3);
+ i386_alu_imm32_reg(cd, ALU_SUB, superindex, REG_ITMP3);
+ i386_test_reg_reg(cd, REG_ITMP3, REG_ITMP3);
+ i386_jcc(cd, I386_CC_LE, 0);
+ codegen_addxcastrefs(cd, cd->mcodeptr);
+ i386_mov_membase32_reg(cd, REG_ITMP2,
+ OFFSET(vftbl_t, interfacetable[0]) -
+ superindex * sizeof(methodptr*),
+ REG_ITMP3);
+ i386_test_reg_reg(cd, REG_ITMP3, REG_ITMP3);
+ i386_jcc(cd, I386_CC_E, 0);
+ codegen_addxcastrefs(cd, cd->mcodeptr);
+
+ if (!super)
+ i386_jmp_imm(cd, s3);
}
- i386_mov_membase_reg(cd, s1,
- OFFSET(java_objectheader, vftbl),
- REG_ITMP2);
+ /* class checkcast code */
- if (!super) {
- codegen_addpatchref(cd, cd->mcodeptr,
- PATCHER_checkcast_class,
- (constant_classref *) iptr->target, 0);
+ if (!super || !(super->flags & ACC_INTERFACE)) {
+ if (super) {
+ i386_test_reg_reg(cd, s1, s1);
+ i386_jcc(cd, I386_CC_Z, s3);
+ }
- if (opt_showdisassemble) {
- M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
+ i386_mov_membase_reg(cd, s1,
+ OFFSET(java_objectheader, vftbl),
+ REG_ITMP2);
+
+ if (!super) {
+ codegen_addpatchref(cd, cd->mcodeptr,
+ PATCHER_checkcast_class,
+ (constant_classref *) iptr->target, 0);
+
+ if (opt_showdisassemble) {
+ M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
+ }
}
- }
- i386_mov_imm_reg(cd, (ptrint) supervftbl, REG_ITMP3);
+ i386_mov_imm_reg(cd, (ptrint) supervftbl, REG_ITMP3);
#if defined(USE_THREADS) && defined(NATIVE_THREADS)
- codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
+ codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
#endif
- i386_mov_membase32_reg(cd, REG_ITMP2,
- OFFSET(vftbl_t, baseval),
- REG_ITMP2);
-
-/* if (s1 != REG_ITMP1) { */
-/* i386_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, baseval), REG_ITMP1); */
-/* i386_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, diffval), REG_ITMP3); */
-/* #if defined(USE_THREADS) && defined(NATIVE_THREADS) */
-/* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
-/* #endif */
-/* i386_alu_reg_reg(cd, ALU_SUB, REG_ITMP1, REG_ITMP2); */
-
-/* } else { */
- i386_mov_membase32_reg(cd, REG_ITMP3,
- OFFSET(vftbl_t, baseval),
- REG_ITMP3);
- i386_alu_reg_reg(cd, ALU_SUB, REG_ITMP3, REG_ITMP2);
- i386_mov_imm_reg(cd, (ptrint) supervftbl, REG_ITMP3);
- i386_mov_membase_reg(cd, REG_ITMP3,
- OFFSET(vftbl_t, diffval),
- REG_ITMP3);
+ i386_mov_membase32_reg(cd, REG_ITMP2,
+ OFFSET(vftbl_t, baseval),
+ REG_ITMP2);
+
+ /* if (s1 != REG_ITMP1) { */
+ /* i386_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, baseval), REG_ITMP1); */
+ /* i386_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, diffval), REG_ITMP3); */
+ /* #if defined(USE_THREADS) && defined(NATIVE_THREADS) */
+ /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
+ /* #endif */
+ /* i386_alu_reg_reg(cd, ALU_SUB, REG_ITMP1, REG_ITMP2); */
+
+ /* } else { */
+ i386_mov_membase32_reg(cd, REG_ITMP3,
+ OFFSET(vftbl_t, baseval),
+ REG_ITMP3);
+ i386_alu_reg_reg(cd, ALU_SUB, REG_ITMP3, REG_ITMP2);
+ i386_mov_imm_reg(cd, (ptrint) supervftbl, REG_ITMP3);
+ i386_mov_membase_reg(cd, REG_ITMP3,
+ OFFSET(vftbl_t, diffval),
+ REG_ITMP3);
#if defined(USE_THREADS) && defined(NATIVE_THREADS)
- codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
+ codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
#endif
-/* } */
+ /* } */
- i386_alu_reg_reg(cd, ALU_CMP, REG_ITMP3, REG_ITMP2);
- i386_jcc(cd, I386_CC_A, 0); /* (u) REG_ITMP2 > (u) REG_ITMP3 -> jump */
- codegen_addxcastrefs(cd, cd->mcodeptr);
- }
- d = reg_of_var(rd, iptr->dst, REG_ITMP3);
- M_INTMOVE(s1, d);
- store_reg_to_var_int(iptr->dst, d);
- }
- break;
-
- case ICMD_ARRAYCHECKCAST: /* ..., objectref ==> ..., objectref */
- /* op1: 1... resolved, 0... not resolved */
+ i386_alu_reg_reg(cd, ALU_CMP, REG_ITMP3, REG_ITMP2);
+ i386_jcc(cd, I386_CC_A, 0); /* (u) REG_ITMP2 > (u) REG_ITMP3 -> jump */
+ codegen_addxcastrefs(cd, cd->mcodeptr);
+ }
+ d = reg_of_var(rd, iptr->dst, REG_ITMP3);
- var_to_reg_int(s1, src, REG_ITMP1);
- M_AST(s1, REG_SP, 0 * 4);
+ } else {
+ /* array type cast-check */
- bte = iptr->val.a;
+ var_to_reg_int(s1, src, REG_ITMP1);
+ M_AST(s1, REG_SP, 0 * 4);
- if (!iptr->op1) {
- codegen_addpatchref(cd, cd->mcodeptr, bte->fp, iptr->target, 0);
+ if (iptr->val.a == NULL) {
+ codegen_addpatchref(cd, cd->mcodeptr,
+ PATCHER_builtin_arraycheckcast,
+ iptr->target, 0);
- if (opt_showdisassemble) {
- M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
+ if (opt_showdisassemble) {
+ M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
+ }
}
- a = 0;
+ M_AST_IMM((ptrint) iptr->val.a, REG_SP, 1 * 4);
+ M_MOV_IMM((ptrint) BUILTIN_arraycheckcast, REG_ITMP3);
+ M_CALL(REG_ITMP3);
+ M_TEST(REG_RESULT);
+ M_BEQ(0);
+ codegen_addxcastrefs(cd, cd->mcodeptr);
- } else {
- a = (ptrint) bte->fp;
+ var_to_reg_int(s1, src, REG_ITMP1);
+ d = reg_of_var(rd, iptr->dst, s1);
}
-
- M_AST_IMM((ptrint) iptr->target, REG_SP, 1 * 4);
- M_MOV_IMM((ptrint) a, REG_ITMP3);
- M_CALL(REG_ITMP3);
- M_TEST(REG_RESULT);
- M_BEQ(0);
- codegen_addxcastrefs(cd, cd->mcodeptr);
-
- var_to_reg_int(s1, src, REG_ITMP1);
- d = reg_of_var(rd, iptr->dst, s1);
M_INTMOVE(s1, d);
store_reg_to_var_int(iptr->dst, d);
break;
break;
default:
- throw_cacao_exception_exit(string_java_lang_InternalError,
- "Unknown ICMD %d", iptr->opc);
+ *exceptionptr =
+ new_internalerror("Unknown ICMD %d", iptr->opc);
+ return false;
} /* switch */
} /* for instruction */
xcodeptr = NULL;
for (bref = cd->xdivrefs; bref != NULL; bref = bref->next) {
- if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
- gen_resolvebranch(cd->mcodebase + bref->branchpos,
- bref->branchpos,
- xcodeptr - cd->mcodebase - (5 + 6));
- continue;
- }
-
gen_resolvebranch(cd->mcodebase + bref->branchpos,
bref->branchpos,
cd->mcodeptr - cd->mcodebase);
- MCODECHECK(100);
+ MCODECHECK(512);
- M_MOV_IMM(0, REG_ITMP2_XPC); /* 5 bytes */
+ M_MOV_IMM(0, REG_ITMP2_XPC);
dseg_adddata(cd, cd->mcodeptr);
- M_AADD_IMM32(bref->branchpos - 6, REG_ITMP2_XPC); /* 6 bytes */
+ M_AADD_IMM32(bref->branchpos - 6, REG_ITMP2_XPC);
if (xcodeptr != NULL) {
M_JMP_IMM((xcodeptr - cd->mcodeptr) - 5);
bref->branchpos,
cd->mcodeptr - cd->mcodebase);
- MCODECHECK(100);
+ MCODECHECK(512);
/* move index register into REG_ITMP1 */
- M_INTMOVE(bref->reg, REG_ITMP1); /* 2 bytes */
+ M_INTMOVE(bref->reg, REG_ITMP1);
- M_MOV_IMM(0, REG_ITMP2_XPC); /* 5 bytes */
+ M_MOV_IMM(0, REG_ITMP2_XPC);
dseg_adddata(cd, cd->mcodeptr);
- M_AADD_IMM32(bref->branchpos - 6, REG_ITMP2_XPC); /* 6 bytes */
+ M_AADD_IMM32(bref->branchpos - 6, REG_ITMP2_XPC);
if (xcodeptr != NULL) {
M_JMP_IMM((xcodeptr - cd->mcodeptr) - 5);
xcodeptr = NULL;
for (bref = cd->xstorerefs; bref != NULL; bref = bref->next) {
- if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
- gen_resolvebranch(cd->mcodebase + bref->branchpos,
- bref->branchpos,
- xcodeptr - cd->mcodebase - (5 + 6));
- continue;
- }
-
gen_resolvebranch(cd->mcodebase + bref->branchpos,
bref->branchpos,
cd->mcodeptr - cd->mcodebase);
- MCODECHECK(100);
+ MCODECHECK(512);
- M_MOV_IMM(0, REG_ITMP2_XPC); /* 5 bytes */
+ M_MOV_IMM(0, REG_ITMP2_XPC);
dseg_adddata(cd, cd->mcodeptr);
- M_AADD_IMM32(bref->branchpos - 6, REG_ITMP2_XPC); /* 6 bytes */
+ M_AADD_IMM32(bref->branchpos - 6, REG_ITMP2_XPC);
if (xcodeptr != NULL) {
M_JMP_IMM((xcodeptr - cd->mcodeptr) - 5);
xcodeptr = NULL;
for (bref = cd->xcastrefs; bref != NULL; bref = bref->next) {
- if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
- gen_resolvebranch(cd->mcodebase + bref->branchpos,
- bref->branchpos,
- xcodeptr - cd->mcodebase - (5 + 6));
- continue;
- }
-
gen_resolvebranch(cd->mcodebase + bref->branchpos,
bref->branchpos,
cd->mcodeptr - cd->mcodebase);
- MCODECHECK(100);
+ MCODECHECK(512);
- M_MOV_IMM(0, REG_ITMP2_XPC); /* 5 bytes */
+ M_MOV_IMM(0, REG_ITMP2_XPC);
dseg_adddata(cd, cd->mcodeptr);
- M_AADD_IMM32(bref->branchpos - 6, REG_ITMP2_XPC); /* 6 bytes */
+ M_AADD_IMM32(bref->branchpos - 6, REG_ITMP2_XPC);
if (xcodeptr != NULL) {
M_JMP_IMM((xcodeptr - cd->mcodeptr) - 5);
xcodeptr = NULL;
for (bref = cd->xnullrefs; bref != NULL; bref = bref->next) {
- if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
- gen_resolvebranch(cd->mcodebase + bref->branchpos,
- bref->branchpos,
- xcodeptr - cd->mcodebase - (5 + 6));
- continue;
- }
-
gen_resolvebranch(cd->mcodebase + bref->branchpos,
bref->branchpos,
cd->mcodeptr - cd->mcodebase);
- MCODECHECK(100);
+ MCODECHECK(512);
- M_MOV_IMM(0, REG_ITMP2_XPC); /* 5 bytes */
+ M_MOV_IMM(0, REG_ITMP2_XPC);
dseg_adddata(cd, cd->mcodeptr);
- M_AADD_IMM32(bref->branchpos - 6, REG_ITMP2_XPC); /* 6 bytes */
+ M_AADD_IMM32(bref->branchpos - 6, REG_ITMP2_XPC);
if (xcodeptr != NULL) {
M_JMP_IMM((xcodeptr - cd->mcodeptr) - 5);
xcodeptr = NULL;
for (bref = cd->xexceptionrefs; bref != NULL; bref = bref->next) {
- if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
- gen_resolvebranch(cd->mcodebase + bref->branchpos,
- bref->branchpos,
- xcodeptr - cd->mcodebase - (5 + 6));
- continue;
- }
-
gen_resolvebranch(cd->mcodebase + bref->branchpos,
bref->branchpos,
cd->mcodeptr - cd->mcodebase);
- MCODECHECK(100);
+ MCODECHECK(512);
- M_MOV_IMM(0, REG_ITMP2_XPC); /* 5 bytes */
+ M_MOV_IMM(0, REG_ITMP2_XPC);
dseg_adddata(cd, cd->mcodeptr);
- M_AADD_IMM32(bref->branchpos - 6, REG_ITMP2_XPC); /* 6 bytes */
+ M_AADD_IMM32(bref->branchpos - 6, REG_ITMP2_XPC);
if (xcodeptr != NULL) {
M_JMP_IMM((xcodeptr - cd->mcodeptr) - 5);
for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
/* check code segment size */
- MCODECHECK(100);
+ MCODECHECK(512);
/* Get machine code which is patched back in later. A */
/* `call rel32' is 5 bytes long. */
}
codegen_finish(m, cd, (ptrint) (cd->mcodeptr - cd->mcodebase));
+
+ /* everything's ok */
+
+ return true;
}
#define COMPILERSTUB_SIZE 12
-functionptr createcompilerstub(methodinfo *m)
+u1 *createcompilerstub(methodinfo *m)
{
u1 *s; /* memory to hold the stub */
codegendata *cd;
dump_release(dumpsize);
- return (functionptr) (ptrint) s;
+ return s;
}
static java_objectheader **(*callgetexceptionptrptr)() = builtin_get_exceptionptrptr;
#endif
-functionptr createnativestub(functionptr f, methodinfo *m, codegendata *cd,
- registerdata *rd, methoddesc *nmd)
+u1 *createnativestub(functionptr f, methodinfo *m, codegendata *cd,
+ registerdata *rd, methoddesc *nmd)
{
methoddesc *md;
s4 nativeparams;