Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: codegen.c 7513 2007-03-13 20:31:23Z twisti $
+ $Id: codegen.c 7579 2007-03-25 22:42:13Z twisti $
*/
#include "vmcore/utf8.h"
-/* codegen *********************************************************************
+/* codegen_emit ****************************************************************
Generates machine code.
void codegen_insert_phi_moves(jitdata *jd, basicblock *bptr);
#endif
-bool codegen(jitdata *jd)
+bool codegen_emit(jitdata *jd)
{
methodinfo *m;
codeinfo *code;
methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
builtintable_entry *bte;
methoddesc *md;
- s4 fieldtype;
- s4 varindex;
+ fieldinfo *fi;
+ unresolved_field *uf;
+ s4 fieldtype;
+ s4 varindex;
#if defined(ENABLE_SSA)
lsradata *ls;
bool last_cmd_was_goto;
else {
M_ALD(REG_ITMP1, REG_SP, cd->stackframesize * 4 + 4);
M_TEST(REG_ITMP1);
- M_BEQ(0);
- codegen_add_nullpointerexception_ref(cd);
+ M_BNE(6);
+ M_ALD_MEM(REG_ITMP1, EXCEPTION_HARDWARE_NULLPOINTER);
}
M_AST(REG_ITMP1, REG_SP, s1 * 4);
codegen_addpatchref(cd, PATCHER_aconst,
iptr->sx.val.c.ref, 0);
- if (opt_showdisassemble) {
- M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
- }
-
M_MOV_IMM(NULL, d);
} else {
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
- emit_nullpointer_check(cd, iptr, s1);
+ /* implicit null-pointer check */
M_ILD(d, s1, OFFSET(java_arrayheader, size));
emit_store_dst(jd, iptr, d);
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
- emit_array_checks(cd, iptr, s1, s2);
+ /* implicit null-pointer check */
+ emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
emit_movsbl_memindex_reg(cd, OFFSET(java_bytearray, data[0]),
s1, s2, 0, d);
emit_store_dst(jd, iptr, d);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
- emit_array_checks(cd, iptr, s1, s2);
+ /* implicit null-pointer check */
+ emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
emit_movzwl_memindex_reg(cd, OFFSET(java_chararray, data[0]),
s1, s2, 1, d);
emit_store_dst(jd, iptr, d);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
- emit_array_checks(cd, iptr, s1, s2);
+ /* implicit null-pointer check */
+ emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
emit_movswl_memindex_reg(cd, OFFSET(java_shortarray, data[0]),
s1, s2, 1, d);
emit_store_dst(jd, iptr, d);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
- emit_array_checks(cd, iptr, s1, s2);
+ /* implicit null-pointer check */
+ emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
emit_mov_memindex_reg(cd, OFFSET(java_intarray, data[0]),
s1, s2, 2, d);
emit_store_dst(jd, iptr, d);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
- emit_array_checks(cd, iptr, s1, s2);
+ /* implicit null-pointer check */
+ emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
var = VAROP(iptr->dst);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
- emit_array_checks(cd, iptr, s1, s2);
+ /* implicit null-pointer check */
+ emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
emit_flds_memindex(cd, OFFSET(java_floatarray, data[0]), s1, s2, 2);
emit_store_dst(jd, iptr, d);
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
- emit_array_checks(cd, iptr, s1, s2);
+ /* implicit null-pointer check */
+ emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
emit_fldl_memindex(cd, OFFSET(java_doublearray, data[0]), s1, s2,3);
emit_store_dst(jd, iptr, d);
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
- emit_array_checks(cd, iptr, s1, s2);
+ /* implicit null-pointer check */
+ emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
emit_mov_memindex_reg(cd, OFFSET(java_objectarray, data[0]),
s1, s2, 2, d);
emit_store_dst(jd, iptr, d);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- emit_array_checks(cd, iptr, s1, s2);
+ /* implicit null-pointer check */
+ emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
s3 = emit_load_s3(jd, iptr, REG_ITMP3);
if (s3 >= EBP) {
/* because EBP, ESI, EDI have no xH and xL nibbles */
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- emit_array_checks(cd, iptr, s1, s2);
+ /* implicit null-pointer check */
+ emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
s3 = emit_load_s3(jd, iptr, REG_ITMP3);
emit_movw_reg_memindex(cd, s3, OFFSET(java_chararray, data[0]),
s1, s2, 1);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- emit_array_checks(cd, iptr, s1, s2);
+ /* implicit null-pointer check */
+ emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
s3 = emit_load_s3(jd, iptr, REG_ITMP3);
emit_movw_reg_memindex(cd, s3, OFFSET(java_shortarray, data[0]),
s1, s2, 1);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- emit_array_checks(cd, iptr, s1, s2);
+ /* implicit null-pointer check */
+ emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
s3 = emit_load_s3(jd, iptr, REG_ITMP3);
emit_mov_reg_memindex(cd, s3, OFFSET(java_intarray, data[0]),
s1, s2, 2);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- emit_array_checks(cd, iptr, s1, s2);
+ /* implicit null-pointer check */
+ emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
var = VAROP(iptr->sx.s23.s3);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- emit_array_checks(cd, iptr, s1, s2);
+ /* implicit null-pointer check */
+ emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
s3 = emit_load_s3(jd, iptr, REG_FTMP1);
emit_fstps_memindex(cd, OFFSET(java_floatarray, data[0]), s1, s2,2);
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- emit_array_checks(cd, iptr, s1, s2);
+ /* implicit null-pointer check */
+ emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
s3 = emit_load_s3(jd, iptr, REG_FTMP1);
emit_fstpl_memindex(cd, OFFSET(java_doublearray, data[0]),
s1, s2, 3);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- emit_array_checks(cd, iptr, s1, s2);
+ /* implicit null-pointer check */
+ emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
s3 = emit_load_s3(jd, iptr, REG_ITMP3);
M_AST(s1, REG_SP, 0 * 4);
M_AST(s3, REG_SP, 1 * 4);
M_MOV_IMM(BUILTIN_canstore, REG_ITMP1);
M_CALL(REG_ITMP1);
- M_TEST(REG_RESULT);
- M_BEQ(0);
- codegen_add_arraystoreexception_ref(cd);
+ emit_exception_check(cd, iptr);
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);
- emit_array_checks(cd, iptr, s1, s2);
+ /* implicit null-pointer check */
+ emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
emit_movb_imm_memindex(cd, iptr->sx.s23.s3.constval,
OFFSET(java_bytearray, data[0]), s1, s2, 0);
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- emit_array_checks(cd, iptr, s1, s2);
+ /* implicit null-pointer check */
+ emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval,
OFFSET(java_chararray, data[0]), s1, s2, 1);
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- emit_array_checks(cd, iptr, s1, s2);
+ /* implicit null-pointer check */
+ emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval,
OFFSET(java_shortarray, data[0]), s1, s2, 1);
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- emit_array_checks(cd, iptr, s1, s2);
+ /* implicit null-pointer check */
+ emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
emit_mov_imm_memindex(cd, iptr->sx.s23.s3.constval,
OFFSET(java_intarray, data[0]), s1, s2, 2);
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- emit_array_checks(cd, iptr, s1, s2);
+ /* implicit null-pointer check */
+ emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
emit_mov_imm_memindex(cd,
(u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff),
OFFSET(java_longarray, data[0]), s1, s2, 3);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- emit_array_checks(cd, iptr, s1, s2);
+ /* implicit null-pointer check */
+ emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
emit_mov_imm_memindex(cd, 0,
OFFSET(java_objectarray, data[0]), s1, s2, 2);
break;
case ICMD_GETSTATIC: /* ... ==> ..., value */
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
- unresolved_field *uf = iptr->sx.s23.s3.uf;
-
+ uf = iptr->sx.s23.s3.uf;
fieldtype = uf->fieldref->parseddesc.fd->type;
+ disp = 0;
- codegen_addpatchref(cd, PATCHER_get_putstatic,
- iptr->sx.s23.s3.uf, 0);
-
- if (opt_showdisassemble) {
- M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
- }
-
- disp = 0;
+ codegen_addpatchref(cd, PATCHER_get_putstatic, uf, 0);
}
else {
- fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
-
+ fi = iptr->sx.s23.s3.fmiref->p.field;
fieldtype = fi->type;
+ disp = (ptrint) &(fi->value);
- if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
+ if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
-
- if (opt_showdisassemble) {
- M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
- }
- }
-
- disp = (ptrint) &(fi->value);
}
M_MOV_IMM(disp, REG_ITMP1);
case ICMD_PUTSTATIC: /* ..., value ==> ... */
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
- unresolved_field *uf = iptr->sx.s23.s3.uf;
-
+ uf = iptr->sx.s23.s3.uf;
fieldtype = uf->fieldref->parseddesc.fd->type;
+ disp = 0;
- codegen_addpatchref(cd, PATCHER_get_putstatic,
- iptr->sx.s23.s3.uf, 0);
-
- if (opt_showdisassemble) {
- M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
- }
-
- disp = 0;
-
+ codegen_addpatchref(cd, PATCHER_get_putstatic, uf, 0);
}
else {
- fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
-
+ fi = iptr->sx.s23.s3.fmiref->p.field;
fieldtype = fi->type;
+ disp = (ptrint) &(fi->value);
- if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
+ if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
-
- if (opt_showdisassemble) {
- M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
- }
- }
-
- disp = (ptrint) &(fi->value);
}
M_MOV_IMM(disp, REG_ITMP1);
/* following NOP) */
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
- unresolved_field *uf = iptr->sx.s23.s3.uf;
-
+ uf = iptr->sx.s23.s3.uf;
fieldtype = uf->fieldref->parseddesc.fd->type;
+ disp = 0;
- codegen_addpatchref(cd, PATCHER_get_putstatic,
- uf, 0);
-
- if (opt_showdisassemble) {
- M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
- }
-
- disp = 0;
-
+ codegen_addpatchref(cd, PATCHER_get_putstatic, uf, 0);
}
else {
- fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
-
+ fi = iptr->sx.s23.s3.fmiref->p.field;
fieldtype = fi->type;
+ disp = (ptrint) &(fi->value);
- if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
+ if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
-
- if (opt_showdisassemble) {
- M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
- }
- }
-
- disp = (ptrint) &(fi->value);
}
M_MOV_IMM(disp, REG_ITMP1);
codegen_addpatchref(cd, PATCHER_getfield,
iptr->sx.s23.s3.uf, 0);
- if (opt_showdisassemble) {
- M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
- }
-
disp = 0;
}
codegen_addpatchref(cd, PATCHER_putfield, uf, 0);
- if (opt_showdisassemble) {
- M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
- }
-
disp = 0;
}
codegen_addpatchref(cd, PATCHER_putfieldconst,
uf, 0);
- if (opt_showdisassemble) {
- M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
- }
-
disp = 0;
}
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
codegen_addpatchref(cd, PATCHER_athrow_areturn,
iptr->sx.s23.s2.uc, 0);
-
- if (opt_showdisassemble) {
- M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
- }
}
#endif /* ENABLE_VERIFIER */
codegen_insert_phi_moves(jd, bptr);
}
#endif
- M_JMP_IMM(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_br(cd, iptr->dst.block);
ALIGNCODENOP;
break;
case ICMD_JSR: /* ... ==> ... */
- M_JMP_IMM(0);
- codegen_addreference(cd, iptr->sx.s23.s3.jsrtarget.block);
+ emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
+ ALIGNCODENOP;
break;
case ICMD_IFNULL: /* ..., value ==> ... */
+ case ICMD_IFNONNULL:
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
M_TEST(s1);
- M_BEQ(0);
- codegen_addreference(cd, iptr->dst.block);
- break;
-
- case ICMD_IFNONNULL: /* ..., value ==> ... */
-
- s1 = emit_load_s1(jd, iptr, REG_ITMP1);
- M_TEST(s1);
- M_BNE(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, BRANCH_OPT_NONE);
break;
case ICMD_IFEQ: /* ..., value ==> ... */
+ case ICMD_IFLT:
+ case ICMD_IFLE:
+ case ICMD_IFNE:
+ case ICMD_IFGT:
+ case ICMD_IFGE:
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
M_CMP_IMM(iptr->sx.val.i, s1);
- M_BEQ(0);
- codegen_addreference(cd, iptr->dst.block);
- break;
-
- case ICMD_IFLT: /* ..., value ==> ... */
-
- s1 = emit_load_s1(jd, iptr, REG_ITMP1);
- M_CMP_IMM(iptr->sx.val.i, s1);
- M_BLT(0);
- codegen_addreference(cd, iptr->dst.block);
- break;
-
- case ICMD_IFLE: /* ..., value ==> ... */
-
- s1 = emit_load_s1(jd, iptr, REG_ITMP1);
- M_CMP_IMM(iptr->sx.val.i, s1);
- M_BLE(0);
- codegen_addreference(cd, iptr->dst.block);
- break;
-
- case ICMD_IFNE: /* ..., value ==> ... */
-
- s1 = emit_load_s1(jd, iptr, REG_ITMP1);
- M_CMP_IMM(iptr->sx.val.i, s1);
- M_BNE(0);
- codegen_addreference(cd, iptr->dst.block);
- break;
-
- case ICMD_IFGT: /* ..., value ==> ... */
-
- s1 = emit_load_s1(jd, iptr, REG_ITMP1);
- M_CMP_IMM(iptr->sx.val.i, s1);
- M_BGT(0);
- codegen_addreference(cd, iptr->dst.block);
- break;
-
- case ICMD_IFGE: /* ..., value ==> ... */
-
- s1 = emit_load_s1(jd, iptr, REG_ITMP1);
- M_CMP_IMM(iptr->sx.val.i, s1);
- M_BGE(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFEQ, BRANCH_OPT_NONE);
break;
case ICMD_IF_LEQ: /* ..., value ==> ... */
M_XOR_IMM(iptr->sx.val.l >> 32, REG_ITMP2);
M_OR(REG_ITMP2, REG_ITMP1);
}
- M_BEQ(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_beq(cd, iptr->dst.block);
break;
case ICMD_IF_LLT: /* ..., value ==> ... */
are too. */
s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
M_CMP_IMM(0, s1);
- M_BLT(0);
+ emit_blt(cd, iptr->dst.block);
}
else {
s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
- M_BLT(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_blt(cd, iptr->dst.block);
M_BGT(6 + 6);
M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
- M_BB(0);
+ emit_bult(cd, iptr->dst.block);
}
- codegen_addreference(cd, iptr->dst.block);
break;
case ICMD_IF_LLE: /* ..., value ==> ... */
s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
- M_BLT(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_blt(cd, iptr->dst.block);
M_BGT(6 + 6);
M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
- M_BBE(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_bule(cd, iptr->dst.block);
break;
case ICMD_IF_LNE: /* ..., value ==> ... */
M_XOR_IMM(iptr->sx.val.l >> 32, REG_ITMP2);
M_OR(REG_ITMP2, REG_ITMP1);
}
- M_BNE(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_bne(cd, iptr->dst.block);
break;
case ICMD_IF_LGT: /* ..., value ==> ... */
s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
- M_BGT(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_bgt(cd, iptr->dst.block);
M_BLT(6 + 6);
M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
- M_BA(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_bugt(cd, iptr->dst.block);
break;
case ICMD_IF_LGE: /* ..., value ==> ... */
64-bits are too. */
s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
M_CMP_IMM(0, s1);
- M_BGE(0);
+ emit_bge(cd, iptr->dst.block);
}
else {
s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
- M_BGT(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_bgt(cd, iptr->dst.block);
M_BLT(6 + 6);
M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
- M_BAE(0);
+ emit_buge(cd, iptr->dst.block);
}
- codegen_addreference(cd, iptr->dst.block);
break;
case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
- case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
+ case ICMD_IF_ICMPNE:
+ case ICMD_IF_ICMPLT:
+ case ICMD_IF_ICMPGT:
+ case ICMD_IF_ICMPGE:
+ case ICMD_IF_ICMPLE:
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
M_CMP(s2, s1);
- M_BEQ(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ICMPEQ, BRANCH_OPT_NONE);
+ break;
+
+ case ICMD_IF_ACMPEQ: /* ..., value, value ==> ... */
+ case ICMD_IF_ACMPNE:
+
+ s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+ s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+ M_CMP(s2, s1);
+ emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ACMPEQ, BRANCH_OPT_NONE);
break;
case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
M_INTMOVE(s1, REG_ITMP2);
M_XOR(s2, REG_ITMP2);
M_OR(REG_ITMP1, REG_ITMP2);
- M_BEQ(0);
- codegen_addreference(cd, iptr->dst.block);
- break;
-
- case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
- case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
-
- s1 = emit_load_s1(jd, iptr, REG_ITMP1);
- s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- M_CMP(s2, s1);
- M_BNE(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_beq(cd, iptr->dst.block);
break;
case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
M_INTMOVE(s1, REG_ITMP2);
M_XOR(s2, REG_ITMP2);
M_OR(REG_ITMP1, REG_ITMP2);
- M_BNE(0);
- codegen_addreference(cd, iptr->dst.block);
- break;
-
- case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
-
- s1 = emit_load_s1(jd, iptr, REG_ITMP1);
- s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- M_CMP(s2, s1);
- M_BLT(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_bne(cd, iptr->dst.block);
break;
case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
M_CMP(s2, s1);
- M_BLT(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_blt(cd, iptr->dst.block);
s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
M_BGT(2 + 6);
M_CMP(s2, s1);
- M_BB(0);
- codegen_addreference(cd, iptr->dst.block);
- break;
-
- case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
-
- s1 = emit_load_s1(jd, iptr, REG_ITMP1);
- s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- M_CMP(s2, s1);
- M_BGT(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_bult(cd, iptr->dst.block);
break;
case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
M_CMP(s2, s1);
- M_BGT(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_bgt(cd, iptr->dst.block);
s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
M_BLT(2 + 6);
M_CMP(s2, s1);
- M_BA(0);
- codegen_addreference(cd, iptr->dst.block);
- break;
-
- case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
-
- s1 = emit_load_s1(jd, iptr, REG_ITMP1);
- s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- M_CMP(s2, s1);
- M_BLE(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_bugt(cd, iptr->dst.block);
break;
case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
M_CMP(s2, s1);
- M_BLT(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_blt(cd, iptr->dst.block);
s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
M_BGT(2 + 6);
M_CMP(s2, s1);
- M_BBE(0);
- codegen_addreference(cd, iptr->dst.block);
- break;
-
- case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
-
- s1 = emit_load_s1(jd, iptr, REG_ITMP1);
- s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- M_CMP(s2, s1);
- M_BGE(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_bule(cd, iptr->dst.block);
break;
case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
M_CMP(s2, s1);
- M_BGT(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_bgt(cd, iptr->dst.block);
s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
M_BLT(2 + 6);
M_CMP(s2, s1);
- M_BAE(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_buge(cd, iptr->dst.block);
break;
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
codegen_addpatchref(cd, PATCHER_athrow_areturn,
iptr->sx.s23.s2.uc, 0);
-
- if (opt_showdisassemble) {
- M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
- }
}
#endif /* ENABLE_VERIFIER */
goto nowperformreturn;
i = i - l + 1;
/* range check */
- M_CMP_IMM(i - 1, REG_ITMP1);
- M_BA(0);
- codegen_addreference(cd, table[0].block); /* default target */
+ M_CMP_IMM(i - 1, REG_ITMP1);
+ emit_bugt(cd, table[0].block);
/* build jump table top down and use address of lowest entry */
while (--i >= 0) {
M_CMP_IMM(lookup->value, s1);
- M_BEQ(0);
- codegen_addreference(cd, lookup->target.block);
+ emit_beq(cd, lookup->target.block);
lookup++;
}
- M_JMP_IMM(0);
-
- codegen_addreference(cd, iptr->sx.s23.s3.lookupdefault.block);
+ emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
+ ALIGNCODENOP;
}
break;
M_MOV_IMM(disp, REG_ITMP1);
M_CALL(REG_ITMP1);
-
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- M_TEST(REG_RESULT);
- M_BEQ(0);
- codegen_add_fillinstacktrace_ref(cd);
- }
+ emit_exception_check(cd, iptr);
break;
case ICMD_INVOKESPECIAL:
- M_ALD(REG_ITMP1, REG_SP, 0);
- M_TEST(REG_ITMP1);
- M_BEQ(0);
- codegen_add_nullpointerexception_ref(cd);
-
+ M_ALD(REG_ITMP1, REG_SP, 0 * 4);
+ emit_nullpointer_check(cd, iptr, REG_ITMP1);
/* fall through */
case ICMD_INVOKESTATIC:
codegen_addpatchref(cd, PATCHER_invokestatic_special,
um, 0);
- if (opt_showdisassemble) {
- M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
- }
-
disp = 0;
d = md->returntype.type;
}
codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
- if (opt_showdisassemble) {
- M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
- }
-
s1 = 0;
d = md->returntype.type;
}
codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
- if (opt_showdisassemble) {
- M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
- }
-
s1 = 0;
s2 = 0;
d = md->returntype.type;
#endif
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
- /* calculate interface checkcast code size */
-
- 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 */);
-
- if (!super)
- s2 += (opt_showdisassemble ? 5 : 0);
-
- /* calculate class checkcast code size */
-
- s3 = 2; /* mov_membase_reg */
- CALCOFFSETBYTES(s3, s1, OFFSET(java_objectheader, vftbl));
-
- 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));
-
- a += 2;
- CALCOFFSETBYTES(a, REG_ITMP3, OFFSET(vftbl_t, diffval));
-
- a += 2;
-
- } 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 == NULL)
- s3 += (opt_showdisassemble ? 5 : 0);
-
/* if class is not resolved, check which code to call */
if (super == NULL) {
M_TEST(s1);
- M_BEQ(5 + (opt_showdisassemble ? 5 : 0) + 6 + 6 + s2 + 5 + s3);
+ emit_label_beq(cd, BRANCH_LABEL_1);
codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
iptr->sx.s23.s3.c.ref, 0);
- if (opt_showdisassemble) {
- M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
- }
-
M_MOV_IMM(0, REG_ITMP2); /* super->flags */
M_AND_IMM32(ACC_INTERFACE, REG_ITMP2);
- M_BEQ(s2 + 5);
+ emit_label_beq(cd, BRANCH_LABEL_2);
}
/* interface checkcast code */
if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
if (super != NULL) {
M_TEST(s1);
- M_BEQ(s2);
+ emit_label_beq(cd, BRANCH_LABEL_3);
}
M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
if (super == NULL) {
- codegen_addpatchref(cd,
- PATCHER_checkcast_instanceof_interface,
+ codegen_addpatchref(cd, PATCHER_checkcast_interface,
iptr->sx.s23.s3.c.ref,
0);
-
- if (opt_showdisassemble) {
- M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
- }
}
M_ILD32(REG_ITMP3,
REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
M_ISUB_IMM32(superindex, REG_ITMP3);
+ /* XXX do we need this one? */
M_TEST(REG_ITMP3);
- M_BLE(0);
- codegen_add_classcastexception_ref(cd, s1);
+ emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
+
M_ALD32(REG_ITMP3, REG_ITMP2,
OFFSET(vftbl_t, interfacetable[0]) -
superindex * sizeof(methodptr*));
M_TEST(REG_ITMP3);
- M_BEQ(0);
- codegen_add_classcastexception_ref(cd, s1);
+ emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
if (super == NULL)
- M_JMP_IMM(s3);
+ emit_label_br(cd, BRANCH_LABEL_4);
+ else
+ emit_label(cd, BRANCH_LABEL_3);
}
/* class checkcast code */
if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
- if (super != NULL) {
+ if (super == NULL) {
+ emit_label(cd, BRANCH_LABEL_2);
+ }
+ else {
M_TEST(s1);
- M_BEQ(s3);
+ emit_label_beq(cd, BRANCH_LABEL_5);
}
M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
codegen_addpatchref(cd, PATCHER_checkcast_class,
iptr->sx.s23.s3.c.ref,
0);
-
- if (opt_showdisassemble) {
- M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
- }
}
M_MOV_IMM(supervftbl, REG_ITMP3);
/* } */
M_CMP(REG_ITMP3, REG_ITMP2);
- M_BA(0); /* (u) REG_ITMP2 > (u) REG_ITMP3 -> jump */
- codegen_add_classcastexception_ref(cd, s1);
+ emit_classcast_check(cd, iptr, BRANCH_ULE, REG_ITMP3, s1);
+
+ if (super != NULL)
+ emit_label(cd, BRANCH_LABEL_5);
+ }
+
+ if (super == NULL) {
+ emit_label(cd, BRANCH_LABEL_1);
+ emit_label(cd, BRANCH_LABEL_4);
}
d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast,
iptr->sx.s23.s3.c.ref, 0);
-
- if (opt_showdisassemble) {
- M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
- }
}
M_AST_IMM(iptr->sx.s23.s3.c.cls, REG_SP, 1 * 4);
s1 = emit_load_s1(jd, iptr, REG_ITMP2);
M_TEST(REG_RESULT);
- M_BEQ(0);
- codegen_add_classcastexception_ref(cd, s1);
+ emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
d = codegen_reg_of_dst(jd, iptr, s1);
}
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
+
if (s1 == d) {
M_INTMOVE(s1, REG_ITMP1);
s1 = REG_ITMP1;
}
- /* calculate interface instanceof code size */
-
- s2 = 2; /* mov_membase_reg */
- CALCOFFSETBYTES(s2, s1, OFFSET(java_objectheader, vftbl));
-
- s2 += (2 + 4 /* mov_membase32_reg */ + 2 + 4 /* alu_imm32_reg */ +
- 2 /* test */ + 6 /* jcc */ + 2 + 4 /* mov_membase32_reg */ +
- 2 /* test */ + 6 /* jcc */ + 5 /* mov_imm_reg */);
-
- if (!super)
- s2 += (opt_showdisassemble ? 5 : 0);
-
- /* calculate class instanceof code size */
-
- s3 = 2; /* mov_membase_reg */
- CALCOFFSETBYTES(s3, s1, OFFSET(java_objectheader, vftbl));
- s3 += 5; /* mov_imm_reg */
- s3 += 2;
- CALCOFFSETBYTES(s3, REG_ITMP1, OFFSET(vftbl_t, baseval));
- s3 += 2;
- CALCOFFSETBYTES(s3, REG_ITMP2, OFFSET(vftbl_t, diffval));
- s3 += 2;
- CALCOFFSETBYTES(s3, REG_ITMP2, OFFSET(vftbl_t, baseval));
-
- s3 += (2 /* alu_reg_reg */ + 2 /* alu_reg_reg */ +
- 2 /* alu_reg_reg */ + 6 /* jcc */ + 5 /* mov_imm_reg */);
-
- if (!super)
- s3 += (opt_showdisassemble ? 5 : 0);
-
M_CLR(d);
/* if class is not resolved, check which code to call */
- if (!super) {
+ if (super == NULL) {
M_TEST(s1);
- M_BEQ(5 + (opt_showdisassemble ? 5 : 0) + 6 + 6 + s2 + 5 + s3);
+ emit_label_beq(cd, BRANCH_LABEL_1);
codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
iptr->sx.s23.s3.c.ref, 0);
- if (opt_showdisassemble) {
- M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
- }
-
M_MOV_IMM(0, REG_ITMP3); /* super->flags */
M_AND_IMM32(ACC_INTERFACE, REG_ITMP3);
- M_BEQ(s2 + 5);
+ emit_label_beq(cd, BRANCH_LABEL_2);
}
/* interface instanceof code */
- if (!super || (super->flags & ACC_INTERFACE)) {
- if (super) {
+ if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
+ if (super != NULL) {
M_TEST(s1);
- M_BEQ(s2);
+ emit_label_beq(cd, BRANCH_LABEL_3);
}
M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
- if (!super) {
- codegen_addpatchref(cd,
- PATCHER_checkcast_instanceof_interface,
+ if (super == NULL) {
+ codegen_addpatchref(cd, PATCHER_instanceof_interface,
iptr->sx.s23.s3.c.ref, 0);
-
- if (opt_showdisassemble) {
- M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
- }
}
M_ILD32(REG_ITMP3,
M_BEQ(5);
M_MOV_IMM(1, d);
- if (!super)
- M_JMP_IMM(s3);
+ if (super == NULL)
+ emit_label_br(cd, BRANCH_LABEL_4);
+ else
+ emit_label(cd, BRANCH_LABEL_3);
}
/* class instanceof code */
- if (!super || !(super->flags & ACC_INTERFACE)) {
- if (super) {
+ if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
+ if (super == NULL) {
+ emit_label(cd, BRANCH_LABEL_2);
+ }
+ else {
M_TEST(s1);
- M_BEQ(s3);
+ emit_label_beq(cd, BRANCH_LABEL_5);
}
M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
- if (!super) {
+ if (super == NULL) {
codegen_addpatchref(cd, PATCHER_instanceof_class,
iptr->sx.s23.s3.c.ref, 0);
-
- if (opt_showdisassemble) {
- M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
- }
}
M_MOV_IMM(supervftbl, REG_ITMP2);
M_CMP(REG_ITMP3, REG_ITMP1);
M_BA(5);
M_MOV_IMM(1, d);
+
+ if (super != NULL)
+ emit_label(cd, BRANCH_LABEL_5);
}
- emit_store_dst(jd, iptr, d);
+
+ if (super == NULL) {
+ emit_label(cd, BRANCH_LABEL_1);
+ emit_label(cd, BRANCH_LABEL_4);
}
- break;
+ emit_store_dst(jd, iptr, d);
+ }
break;
case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
codegen_addpatchref(cd, PATCHER_builtin_multianewarray,
iptr->sx.s23.s3.c.ref, 0);
- if (opt_showdisassemble) {
- M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
- }
-
disp = 0;
}
/* check for exception before result assignment */
- M_TEST(REG_RESULT);
- M_BEQ(0);
- codegen_add_fillinstacktrace_ref(cd);
+ emit_exception_check(cd, iptr);
s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
M_INTMOVE(REG_RESULT, s1);
dseg_createlinenumbertable(cd);
+ /* generate stubs */
- /* generate exception and patcher stubs */
-
- emit_exception_stubs(jd);
emit_patcher_stubs(jd);
REPLACEMENT_EMIT_STUBS(jd);
- codegen_finish(jd);
-
/* everything's ok */
return true;
/* get function address (this must happen before the stackframeinfo) */
#if !defined(WITH_STATIC_CLASSPATH)
- if (f == NULL) {
+ if (f == NULL)
codegen_addpatchref(cd, PATCHER_resolve_native, m, 0);
-
- if (opt_showdisassemble) {
- M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
- }
- }
#endif
M_AST_IMM((ptrint) f, REG_SP, 4 * 4);