X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Fcodegen-common.cpp;h=9b1dad8cdd3d5b9d443a96adca228a0d7e14a0a5;hb=67702ed5605e84f33724aeee9ccf5f82ea774084;hp=9920715b1c8d52b982c87f1cebc4db25c39afada;hpb=ba550ed57d3abaf63a64f70308d6a4164ee18835;p=cacao.git diff --git a/src/vm/jit/codegen-common.cpp b/src/vm/jit/codegen-common.cpp index 9920715b1..9b1dad8cd 100644 --- a/src/vm/jit/codegen-common.cpp +++ b/src/vm/jit/codegen-common.cpp @@ -1,6 +1,6 @@ /* src/vm/jit/codegen-common.cpp - architecture independent code generator stuff - Copyright (C) 1996-2005, 2006, 2007, 2008, 2009 + Copyright (C) 1996-2005, 2006, 2007, 2008, 2009, 2010 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO Copyright (C) 2009 Theobroma Systems Ltd. @@ -996,7 +996,7 @@ s4 codegen_reg_of_dst(jitdata *jd, instruction *iptr, s4 tempregnum) bool codegen_emit(jitdata *jd) { varinfo* var; - builtintable_entry* bte; + builtintable_entry* bte = 0; methoddesc* md; int32_t s1, s2, /*s3,*/ d; int32_t fieldtype; @@ -1250,6 +1250,13 @@ bool codegen_emit(jitdata *jd) emit_nullpointer_check(cd, iptr, s1); break; + case ICMD_BREAKPOINT: /* ... ==> ... */ + /* sx.val.anyptr = Breakpoint */ + + patcher_add_patch_ref(jd, PATCHER_breakpoint, iptr->sx.val.anyptr, 0); + PATCHER_NOPS; + break; + #if defined(ENABLE_SSA) case ICMD_GETEXCEPTION: @@ -1349,9 +1356,13 @@ bool codegen_emit(jitdata *jd) case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */ case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */ /* sx.val.i = constant */ + case ICMD_IMULPOW2: /* ..., value ==> ..., value * (2 ^ constant) */ + /* sx.val.i = constant */ case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */ case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */ /* sx.val.l = constant */ + case ICMD_LMULPOW2: /* ..., value ==> ..., value * (2 ^ constant) */ + /* sx.val.l = constant */ case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */ case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */ case ICMD_IDIVPOW2: /* ..., value ==> ..., value >> constant */ @@ -1496,16 +1507,22 @@ bool codegen_emit(jitdata *jd) #if defined(__I386__) // Generate architecture specific instructions. codegen_emit_instruction(jd, iptr); + break; #else + { + fieldinfo* fi; + patchref_t* pr; if (INSTRUCTION_IS_UNRESOLVED(iptr)) { unresolved_field* uf = iptr->sx.s23.s3.uf; fieldtype = uf->fieldref->parseddesc.fd->type; disp = dseg_add_unique_address(cd, 0); - patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp); + pr = patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp); + + fi = NULL; /* Silence compiler warning */ } else { - fieldinfo* fi = iptr->sx.s23.s3.fmiref->p.field; + fi = iptr->sx.s23.s3.fmiref->p.field; fieldtype = fi->type; disp = dseg_add_address(cd, fi->value); @@ -1514,13 +1531,18 @@ bool codegen_emit(jitdata *jd) patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz, 0); PROFILE_CYCLE_START; } + + pr = NULL; /* Silence compiler warning */ } +#if defined(USES_PATCHABLE_MEMORY_BARRIER) + codegen_emit_patchable_barrier(iptr, cd, pr, fi); +#endif + // XXX X86_64: Here We had this: /* This approach is much faster than moving the field address inline into a register. */ - // XXX ARM: M_DSEG_LOAD(REG_ITMP3, disp); M_ALD_DSEG(REG_ITMP1, disp); switch (fieldtype) { @@ -1529,13 +1551,20 @@ bool codegen_emit(jitdata *jd) M_ALD(d, REG_ITMP1, 0); break; case TYPE_INT: +#if defined(ENABLE_SOFTFLOAT) + case TYPE_FLT: +#endif d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); M_ILD(d, REG_ITMP1, 0); break; case TYPE_LNG: +#if defined(ENABLE_SOFTFLOAT) + case TYPE_DBL: +#endif d = codegen_reg_of_dst(jd, iptr, REG_LTMP23); M_LLD(d, REG_ITMP1, 0); break; +#if !defined(ENABLE_SOFTFLOAT) case TYPE_FLT: d = codegen_reg_of_dst(jd, iptr, REG_FTMP1); M_FLD(d, REG_ITMP1, 0); @@ -1544,26 +1573,38 @@ bool codegen_emit(jitdata *jd) d = codegen_reg_of_dst(jd, iptr, REG_FTMP1); M_DLD(d, REG_ITMP1, 0); break; +#endif + default: + // Silence compiler warning. + d = 0; } emit_store_dst(jd, iptr, d); -#endif break; + } +#endif case ICMD_PUTSTATIC: /* ..., value ==> ... */ #if defined(__I386__) // Generate architecture specific instructions. codegen_emit_instruction(jd, iptr); + break; #else + { + fieldinfo* fi; + patchref_t* pr; + if (INSTRUCTION_IS_UNRESOLVED(iptr)) { unresolved_field* uf = iptr->sx.s23.s3.uf; fieldtype = uf->fieldref->parseddesc.fd->type; disp = dseg_add_unique_address(cd, 0); - patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp); + pr = patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp); + + fi = NULL; /* Silence compiler warning */ } else { - fieldinfo* fi = iptr->sx.s23.s3.fmiref->p.field; + fi = iptr->sx.s23.s3.fmiref->p.field; fieldtype = fi->type; disp = dseg_add_address(cd, fi->value); @@ -1572,13 +1613,14 @@ bool codegen_emit(jitdata *jd) patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz, 0); PROFILE_CYCLE_START; } + + pr = NULL; /* Silence compiler warning */ } // XXX X86_64: Here We had this: /* This approach is much faster than moving the field address inline into a register. */ - // XXX ARM: M_DSEG_LOAD(REG_ITMP3, disp); M_ALD_DSEG(REG_ITMP1, disp); switch (fieldtype) { @@ -1587,13 +1629,20 @@ bool codegen_emit(jitdata *jd) M_AST(s1, REG_ITMP1, 0); break; case TYPE_INT: +#if defined(ENABLE_SOFTFLOAT) + case TYPE_FLT: +#endif s1 = emit_load_s1(jd, iptr, REG_ITMP2); M_IST(s1, REG_ITMP1, 0); break; case TYPE_LNG: +#if defined(ENABLE_SOFTFLOAT) + case TYPE_DBL: +#endif s1 = emit_load_s1(jd, iptr, REG_LTMP23); M_LST(s1, REG_ITMP1, 0); break; +#if !defined(ENABLE_SOFTFLOAT) case TYPE_FLT: s1 = emit_load_s1(jd, iptr, REG_FTMP2); M_FST(s1, REG_ITMP1, 0); @@ -1602,9 +1651,14 @@ bool codegen_emit(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_FTMP2); M_DST(s1, REG_ITMP1, 0); break; +#endif } +#if defined(USES_PATCHABLE_MEMORY_BARRIER) + codegen_emit_patchable_barrier(iptr, cd, pr, fi); #endif break; + } +#endif /* branch operations **********************************************/ @@ -1813,6 +1867,9 @@ bool codegen_emit(jitdata *jd) goto nowperformreturn; case ICMD_IRETURN: /* ..., retvalue ==> ... */ +#if defined(ENABLE_SOFTFLOAT) + case ICMD_FRETURN: +#endif REPLACEMENT_POINT_RETURN(cd, iptr); s1 = emit_load_s1(jd, iptr, REG_RESULT); @@ -1821,6 +1878,9 @@ bool codegen_emit(jitdata *jd) goto nowperformreturn; case ICMD_LRETURN: /* ..., retvalue ==> ... */ +#if defined(ENABLE_SOFTFLOAT) + case ICMD_DRETURN: +#endif REPLACEMENT_POINT_RETURN(cd, iptr); s1 = emit_load_s1(jd, iptr, REG_LRESULT); @@ -1828,21 +1888,29 @@ bool codegen_emit(jitdata *jd) emit_lmove(cd, s1, REG_LRESULT); goto nowperformreturn; +#if !defined(ENABLE_SOFTFLOAT) case ICMD_FRETURN: /* ..., retvalue ==> ... */ REPLACEMENT_POINT_RETURN(cd, iptr); s1 = emit_load_s1(jd, iptr, REG_FRESULT); - // XXX ARM: Here this was M_CAST_F2I(s1, REG_RESULT); +#if !defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS) emit_fmove(cd, s1, REG_FRESULT); +#else + M_CAST_F2I(s1, REG_RESULT); +#endif goto nowperformreturn; case ICMD_DRETURN: /* ..., retvalue ==> ... */ REPLACEMENT_POINT_RETURN(cd, iptr); s1 = emit_load_s1(jd, iptr, REG_FRESULT); - // XXX ARM: Here this was M_CAST_D2L(s1, REG_RESULT_PACKED); +#if !defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS) emit_dmove(cd, s1, REG_FRESULT); +#else + M_CAST_D2L(s1, REG_LRESULT); +#endif goto nowperformreturn; +#endif nowperformreturn: #if !defined(NDEBUG) @@ -1947,37 +2015,45 @@ gen_method: continue; if (!md->params[i].inmemory) { - assert(ARG_CNT > 0); - s1 = emit_load(jd, iptr, var, d); - switch (var->type) { case TYPE_ADR: case TYPE_INT: - assert(INT_ARG_CNT > 0); +#if defined(ENABLE_SOFTFLOAT) + case TYPE_FLT: +#endif + s1 = emit_load(jd, iptr, var, d); emit_imove(cd, s1, d); break; -#if 0 //XXX For ARM: -if (!md->params[s3].inmemory) { - s1 = emit_load(jd, iptr, var, REG_FTMP1); - if (IS_2_WORD_TYPE(var->type)) - M_CAST_D2L(s1, d); - else - M_CAST_F2I(s1, d); -} -#endif //XXX End of ARM! - case TYPE_LNG: +#if defined(ENABLE_SOFTFLOAT) + case TYPE_DBL: +#endif + s1 = emit_load(jd, iptr, var, d); emit_lmove(cd, s1, d); break; +#if !defined(ENABLE_SOFTFLOAT) case TYPE_FLT: +#if !defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS) + s1 = emit_load(jd, iptr, var, d); emit_fmove(cd, s1, d); +#else + s1 = emit_load(jd, iptr, var, REG_FTMP1); + M_CAST_F2I(s1, d); +#endif break; case TYPE_DBL: +#if !defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS) + s1 = emit_load(jd, iptr, var, d); emit_dmove(cd, s1, d); +#else + s1 = emit_load(jd, iptr, var, REG_FTMP1); + M_CAST_D2L(s1, d); +#endif break; +#endif } } else { @@ -1992,6 +2068,9 @@ if (!md->params[s3].inmemory) { break; case TYPE_INT: +#if defined(ENABLE_SOFTFLOAT) + case TYPE_FLT: +#endif #if SIZEOF_VOID_P == 4 s1 = emit_load(jd, iptr, var, REG_ITMP1); M_IST(s1, REG_SP, d); @@ -2001,12 +2080,16 @@ if (!md->params[s3].inmemory) { #endif case TYPE_LNG: +#if defined(ENABLE_SOFTFLOAT) + case TYPE_DBL: +#endif s1 = emit_load(jd, iptr, var, REG_LTMP12); // XXX Sparc64: Here this actually was: // M_STX(s1, REG_SP, JITSTACK + d); M_LST(s1, REG_SP, d); break; +#if !defined(ENABLE_SOFTFLOAT) case TYPE_FLT: #if SIZEOF_VOID_P == 4 s1 = emit_load(jd, iptr, var, REG_FTMP1); @@ -2022,6 +2105,7 @@ if (!md->params[s3].inmemory) { // M_DST(s1, REG_SP, JITSTACK + d); M_DST(s1, REG_SP, d); break; +#endif } } } @@ -2051,6 +2135,9 @@ if (!md->params[s3].inmemory) { switch (md->returntype.type) { case TYPE_INT: case TYPE_ADR: +#if defined(ENABLE_SOFTFLOAT) + case TYPE_FLT: +#endif s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT); // XXX Sparc64: This should actually be REG_RESULT_CALLER, fix this! emit_imove(cd, REG_RESULT, s1); @@ -2058,35 +2145,38 @@ if (!md->params[s3].inmemory) { break; case TYPE_LNG: +#if defined(ENABLE_SOFTFLOAT) + case TYPE_DBL: +#endif s1 = codegen_reg_of_dst(jd, iptr, REG_LRESULT); // XXX Sparc64: This should actually be REG_RESULT_CALLER, fix this! emit_lmove(cd, REG_LRESULT, s1); emit_store_dst(jd, iptr, s1); break; -#if 0 //XXX For ARM!!! #if !defined(ENABLE_SOFTFLOAT) - } else { - s1 = codegen_reg_of_dst(jd, iptr, REG_FTMP1); - if (IS_2_WORD_TYPE(d)) - M_CAST_L2D(REG_RESULT_PACKED, s1); - else - M_CAST_I2F(REG_RESULT, s1); - } -#endif /* !defined(ENABLE_SOFTFLOAT) */ -#endif //XXX End of ARM - case TYPE_FLT: +#if !defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS) s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT); emit_fmove(cd, REG_FRESULT, s1); +#else + s1 = codegen_reg_of_dst(jd, iptr, REG_FTMP1); + M_CAST_I2F(REG_RESULT, s1); +#endif emit_store_dst(jd, iptr, s1); break; case TYPE_DBL: +#if !defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS) s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT); emit_dmove(cd, REG_FRESULT, s1); +#else + s1 = codegen_reg_of_dst(jd, iptr, REG_FTMP1); + M_CAST_L2D(REG_LRESULT, s1); +#endif emit_store_dst(jd, iptr, s1); break; +#endif case TYPE_VOID: break;